Annotation of uae/src/xwin.c, revision 1.1.1.4

1.1.1.3   root        1:  /*
1.1       root        2:   * UAE - The Un*x Amiga Emulator
1.1.1.3   root        3:   *
1.1       root        4:   * X interface
1.1.1.3   root        5:   *
1.1       root        6:   * Copyright 1995, 1996 Bernd Schmidt
                      7:   * Copyright 1996 Ed Hanway, Andre Beck, Samuel Devulder, Bruno Coste
1.1.1.2   root        8:   * DGA support by Kai Kollmorgen
1.1       root        9:   */
                     10: 
                     11: #include "sysconfig.h"
                     12: #include "sysdeps.h"
                     13: 
                     14: #include <X11/Xlib.h>
                     15: #include <X11/Xutil.h>
                     16: #include <X11/keysym.h>
                     17: #include <X11/cursorfont.h>
                     18: 
                     19: #include <ctype.h>
                     20: #include <signal.h>
                     21: 
                     22: #include "config.h"
                     23: #include "options.h"
1.1.1.3   root       24: #include "threaddep/penguin.h"
                     25: #include "uae.h"
1.1       root       26: #include "memory.h"
                     27: #include "custom.h"
1.1.1.2   root       28: #include "readcpu.h"
1.1       root       29: #include "newcpu.h"
                     30: #include "xwin.h"
                     31: #include "keyboard.h"
                     32: #include "keybuf.h"
                     33: #include "gui.h"
                     34: #include "debug.h"
1.1.1.3   root       35: #include "picasso96.h"
                     36: 
                     37: #ifdef __cplusplus
                     38: #define VI_CLASS c_class
                     39: #else
                     40: #define VI_CLASS class
                     41: #endif
1.1       root       42: 
1.1.1.2   root       43: #ifdef USE_DGA_EXTENSION
1.1.1.3   root       44: 
                     45: #ifdef USE_VIDMODE_EXTENSION
                     46: #include <X11/extensions/xf86vmode.h>
                     47: #define VidMode_MINMAJOR 0
                     48: #define VidMode_MINMINOR 0
                     49: #endif
                     50: 
1.1.1.2   root       51: #include <X11/extensions/xf86dga.h>
                     52: #define DGA_MINMAJOR 0
                     53: #define DGA_MINMINOR 0
1.1.1.3   root       54: 
                     55: #elif SHM_SUPPORT_LINKS == 1
                     56: 
                     57: #include <sys/ipc.h>
                     58: #include <sys/shm.h>
                     59: #include <X11/extensions/XShm.h>
                     60: 
                     61: #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
                     62:     do { \
                     63:        if (currprefs.use_mitshm) \
                     64:             XShmPutImage (display, mywin, blackgc, IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT, 0); \
                     65:        else \
                     66:            XPutImage (display, mywin, blackgc, IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT); \
                     67:     } while (0)
                     68: #else
                     69: #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
                     70:     XPutImage (display, mywin, blackgc, IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT)
1.1.1.2   root       71: #endif
                     72: 
1.1       root       73: #ifdef __cplusplus
                     74: static RETSIGTYPE sigbrkhandler(...)
                     75: #else
                     76: static RETSIGTYPE sigbrkhandler(int foo)
                     77: #endif
                     78: {
                     79:     activate_debugger();
                     80: 
                     81: #if !defined(__unix) || defined(__NeXT__)
                     82:     signal(SIGINT, sigbrkhandler);
                     83: #endif
                     84: }
                     85: 
                     86: void setup_brkhandler(void)
                     87: {
                     88: #if defined(__unix) && !defined(__NeXT__)
                     89:     struct sigaction sa;
                     90:     sa.sa_handler = sigbrkhandler;
                     91:     sa.sa_flags = 0;
                     92: #ifdef SA_RESTART
                     93:     sa.sa_flags = SA_RESTART;
                     94: #endif
                     95:     sigemptyset(&sa.sa_mask);
                     96:     sigaction(SIGINT, &sa, NULL);
                     97: #else
                     98:     signal(SIGINT, sigbrkhandler);
1.1.1.2   root       99: #endif
1.1.1.3   root      100: }
1.1.1.2   root      101: 
1.1       root      102: static Display *display;
                    103: static int screen;
                    104: static Window rootwin, mywin;
                    105: 
1.1.1.3   root      106: static GC whitegc,blackgc,picassogc;
1.1       root      107: static XColor black,white;
1.1.1.3   root      108: static Colormap cmap, cmap2;
                    109: 
                    110: /* Kludge-O-Matic */
                    111: static int dga_colormap_installed;
1.1       root      112: 
                    113: static int need_dither;
                    114: 
1.1.1.3   root      115: static int screen_is_picasso;
                    116: static char picasso_invalid_lines[1201];
                    117: 
1.1       root      118: static int autorepeatoff = 0;
                    119: static char *image_mem;
1.1.1.3   root      120: static XImage *img, *picasso_img;
1.1       root      121: static Visual *vis;
                    122: static XVisualInfo visualInfo;
                    123: static int bitdepth, bit_unit;
                    124: static Cursor blankCursor, xhairCursor;
                    125: static int cursorOn;
1.1.1.3   root      126: static int inverse_byte_order = 0;
1.1       root      127: 
1.1.1.3   root      128: static int current_width, current_height;
1.1       root      129: 
1.1.1.2   root      130: static int x11_init_ok;
                    131: 
1.1       root      132:  /* Keyboard and mouse */
                    133: 
                    134: static int keystate[256];
                    135: 
                    136: static int inwindow;
                    137: const long int eventmask = (KeyPressMask|KeyReleaseMask|ButtonPressMask
                    138:                            |ButtonReleaseMask|PointerMotionMask
1.1.1.2   root      139: #ifndef USE_DGA_EXTENSION
1.1       root      140:                            |FocusChangeMask|EnterWindowMask
                    141:                            |ExposureMask
1.1.1.2   root      142:                            |LeaveWindowMask
                    143: #endif
                    144:                            );
1.1       root      145: 
1.1.1.3   root      146: static XImage *get_image (int w, int h, char **mem_p)
                    147: {
                    148:     XImage *new_img;
                    149:     char *p;
                    150: 
                    151: #if SHM_SUPPORT_LINKS == 1
                    152:     if (currprefs.use_mitshm) {
                    153:        XShmSegmentInfo *shminfo = xmalloc (sizeof (XShmSegmentInfo));
                    154: 
                    155:        printf ("Using MIT-SHM extension.\n");
                    156:        new_img = XShmCreateImage (display, vis, bitdepth, ZPixmap, 0, shminfo, w, h);
                    157: 
                    158:        shminfo->shmid = shmget (IPC_PRIVATE, h * new_img->bytes_per_line,
                    159:                                 IPC_CREAT | 0777);
                    160:        shminfo->shmaddr = new_img->data = (char *)shmat (shminfo->shmid, 0, 0);
                    161:        if (mem_p != 0)
                    162:            *mem_p = new_img->data;
                    163:        shminfo->readOnly = False;
                    164:        /* let the xserver attach */
                    165:        XShmAttach (display, shminfo);
                    166:        XSync (display,0);
                    167:        /* now deleting means making it temporary */
                    168:        shmctl (shminfo->shmid, IPC_RMID, 0);
                    169:        return new_img;
                    170:     }
                    171: #endif
                    172: 
                    173:     /* Question for people who know about X: Could we allocate the buffer
                    174:      * after creating the image and then do new_img->data = buffer, as above in
                    175:      * the SHM case?
                    176:      */
                    177:     printf ("Using normal image buffer.\n");
                    178:     p = (char *)xmalloc (h * w * ((bit_unit + 7) / 8)); /* ??? */
                    179:     if (mem_p != 0)
                    180:        *mem_p = p;
                    181:     new_img = XCreateImage (display, vis, bitdepth, ZPixmap, 0, p,
                    182:                            w, h, 32, 0);
                    183:     if (new_img->bytes_per_line != w * ((bit_unit + 7) / 8))
                    184:        fprintf (stderr, "Possible bug here... graphics may look strange.\n");
                    185: 
                    186:     return new_img;
                    187: }
                    188: 
                    189: #ifdef USE_DGA_EXTENSION
                    190: 
                    191: static int fb_bank, fb_banks, fb_mem;
                    192: static char *fb_addr;
                    193: static int fb_width;
1.1       root      194: 
1.1.1.3   root      195: static void switch_to_dga_mode (void)
                    196: {
                    197:     XF86DGADirectVideo(display, screen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb);
                    198:     XF86DGASetViewPort (display, screen, 0, 0);
                    199:     memset (fb_addr, 0, fb_mem * 1024);
                    200: }
                    201: 
                    202: 
                    203: #ifdef USE_VIDMODE_EXTENSION
                    204: static XF86VidModeModeInfo **allmodes;
                    205: static int vidmodecount;
                    206: 
                    207: static int get_vidmodes (void)
                    208: {
                    209:     return XF86VidModeGetAllModeLines (display, screen, &vidmodecount, &allmodes);
                    210: }
1.1.1.4 ! root      211: #endif
1.1.1.3   root      212: 
                    213: static void switch_to_best_mode (void)
                    214: {
1.1.1.4 ! root      215: #ifdef USE_VIDMODE_EXTENSION
1.1.1.3   root      216:     int i, best;
                    217:     best = 0;
                    218:     for (i = 1; i < vidmodecount; i++) {
                    219:        if (allmodes[i]->hdisplay >= current_width
                    220:            && allmodes[i]->vdisplay >= current_height
                    221:            && allmodes[i]->hdisplay <= allmodes[best]->hdisplay
                    222:            && allmodes[i]->vdisplay <= allmodes[best]->vdisplay)
                    223:            best = i;
                    224:     }
                    225:     printf ("entering DGA mode: %dx%d (%d, %d)\n",
                    226:            allmodes[best]->hdisplay, allmodes[best]->vdisplay,
                    227:            current_width, current_height);
                    228:     XF86VidModeSwitchToMode (display, screen, allmodes[best]);
                    229:     XF86VidModeSetViewPort (display, screen, 0, 0);
1.1.1.4 ! root      230: #endif
1.1.1.3   root      231:     XMoveWindow (display, mywin, 0, 0);
                    232:     XWarpPointer (display, None, rootwin, 0, 0, 0, 0, 0, 0);
                    233:     switch_to_dga_mode ();
                    234: }
                    235: 
                    236: static void enter_dga_mode (void)
                    237: {
                    238:     Screen *scr = ScreenOfDisplay (display, screen);
                    239:     int w = WidthOfScreen (scr);
                    240:     int h = HeightOfScreen (scr);
                    241: 
                    242:     XRaiseWindow (display, mywin);
                    243: 
                    244:     /* We want all the key presses */
                    245:     XGrabKeyboard (display, rootwin, 1, GrabModeAsync,
                    246:                   GrabModeAsync,  CurrentTime);
                    247: 
                    248:     /* and all the mouse moves */
                    249:     XGrabPointer (display, rootwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
                    250:                  GrabModeAsync, GrabModeAsync, None,  None, CurrentTime);
                    251: 
                    252:     XF86DGAGetVideo (display, screen, &fb_addr, &fb_width, &fb_bank, &fb_mem);
                    253:     fprintf (stderr, "addr:%X, width %d, bank size %d mem size %d\n",
                    254:             fb_addr, fb_width, fb_bank,fb_mem);
                    255: 
                    256:     if (fb_bank < fb_mem)
                    257:        fprintf (stderr, "banksize < memsize, must use XF86DGASetVidPage !\n");
                    258: 
                    259:     switch_to_best_mode ();
                    260: 
                    261:     gfxvidinfo.rowbytes = fb_width*gfxvidinfo.pixbytes;
                    262:     gfxvidinfo.bufmem = fb_addr;
                    263: }
                    264: 
                    265: static void leave_dga_mode (void)
                    266: {
                    267: #ifdef USE_VIDMODE_EXTENSION
                    268:     XF86VidModeSwitchToMode (display, screen, allmodes[0]);
                    269: #endif
                    270:     XF86DGADirectVideo (display, screen, 0);
                    271:     XUngrabPointer (display, CurrentTime);
                    272:     XUngrabKeyboard (display, CurrentTime);
                    273: }
                    274: 
                    275: #endif
                    276: static char *oldpixbuf;
1.1       root      277: 
                    278: void flush_line(int y)
                    279: {
1.1.1.2   root      280: #ifdef USE_DGA_EXTENSION
                    281:     if (need_dither) {
1.1.1.3   root      282:        char *addr = gfxvidinfo.linemem;
                    283:        if (addr == NULL)
                    284:            addr = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
                    285: 
                    286:        DitherLine((unsigned char *)(fb_addr + fb_width*y), (uae_u16 *)addr, 0, y,
                    287:                   gfxvidinfo.width, bit_unit);
1.1.1.2   root      288:     }
                    289: #else
1.1.1.3   root      290:     char *linebuf;
1.1       root      291:     int xs = 0, xe;
1.1.1.3   root      292:     int len;
1.1       root      293: 
1.1.1.3   root      294:     linebuf = gfxvidinfo.linemem;
                    295:     if (linebuf == NULL)
                    296:        linebuf = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
                    297: 
                    298:     xe = gfxvidinfo.width-1;
                    299: 
                    300:     if (currprefs.use_low_bandwidth) {
                    301:        char *src, *dst;
                    302:        switch(gfxvidinfo.pixbytes) {
                    303:         case 4:
                    304:            {
                    305:                uae_u32 *newp = (uae_u32 *)linebuf;
                    306:                uae_u32 *oldp = (uae_u32 *)((uae_u8 *)image_mem + y*img->bytes_per_line);
                    307:                while (newp[xs] == oldp[xs]) {
                    308:                    if (xs == xe)
                    309:                        return;
                    310:                    xs++;
                    311:                }
                    312:                while (newp[xe] == oldp[xe]) xe--;
                    313: 
                    314:                dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1       root      315:            }
1.1.1.3   root      316:            break;
                    317:         case 2:
                    318:            {
                    319:                uae_u16 *newp = (uae_u16 *)linebuf;
                    320:                uae_u16 *oldp = (uae_u16 *)((uae_u8 *)image_mem + y*img->bytes_per_line);
                    321:                while (newp[xs] == oldp[xs]) {
                    322:                    if (xs == xe)
                    323:                        return;
                    324:                    xs++;
                    325:                }
                    326:                while (newp[xe] == oldp[xe]) xe--;
                    327: 
                    328:                dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1       root      329:            }
1.1.1.3   root      330:            break;
                    331:         case 1:
                    332:            {
                    333:                uae_u8 *newp = (uae_u8 *)linebuf;
                    334:                uae_u8 *oldp = (uae_u8 *)((uae_u8 *)image_mem + y*img->bytes_per_line);
                    335:                while (newp[xs] == oldp[xs]) {
                    336:                    if (xs == xe)
                    337:                        return;
                    338:                    xs++;
                    339:                }
                    340:                while (newp[xe] == oldp[xe]) xe--;
1.1       root      341: 
1.1.1.3   root      342:                dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1       root      343:            }
1.1.1.3   root      344:            break;
1.1       root      345: 
1.1.1.3   root      346:         default:
                    347:            abort();
                    348:            break;
1.1       root      349:        }
                    350: 
                    351:        len = xe - xs + 1;
1.1.1.3   root      352:        memcpy (dst, src, len * gfxvidinfo.pixbytes);
                    353:     } else if (need_dither) {
                    354:        uae_u8 *target = (uae_u8 *)image_mem + img->bytes_per_line * y;
                    355:        len = currprefs.gfx_width;
                    356:        DitherLine(target, (uae_u16 *)linebuf, 0, y, gfxvidinfo.width, bit_unit);
                    357:     } else {
                    358:        fprintf(stderr, "Bug!\n");
                    359:        abort();
1.1       root      360:     }
1.1.1.2   root      361: 
1.1.1.3   root      362:     DO_PUTIMAGE (img, xs, y, xs, y, len, 1);
1.1.1.2   root      363: #endif
1.1       root      364: }
                    365: 
                    366: void flush_block (int ystart, int ystop)
                    367: {
1.1.1.2   root      368: #ifdef USE_DGA_EXTENSION
                    369: #else
1.1       root      370:     int len, xs = 0;
1.1.1.3   root      371: 
                    372:     len = gfxvidinfo.width;
                    373:     DO_PUTIMAGE (img, xs, ystart, 0, ystart, len, ystop - ystart + 1);
1.1.1.2   root      374: #endif
1.1       root      375: }
                    376: 
                    377: void flush_screen (int ystart, int ystop)
                    378: {
1.1.1.2   root      379: #ifdef USE_DGA_EXTENSION
                    380: #else
1.1.1.3   root      381: #if SHM_SUPPORT_LINKS == 1
                    382:     if (currprefs.use_mitshm) XSync(display, 0);
1.1       root      383: #endif
1.1.1.2   root      384: #endif
1.1       root      385: }
                    386: 
                    387: static __inline__ int bitsInMask(unsigned long mask)
                    388: {
                    389:     /* count bits in mask */
                    390:     int n = 0;
                    391:     while(mask) {
                    392:        n += mask&1;
                    393:        mask >>= 1;
                    394:     }
                    395:     return n;
                    396: }
                    397: 
                    398: static __inline__ int maskShift(unsigned long mask)
                    399: {
                    400:     /* determine how far mask is shifted */
                    401:     int n = 0;
                    402:     while(!(mask&1)) {
                    403:        n++;
                    404:        mask >>= 1;
                    405:     }
                    406:     return n;
                    407: }
                    408: 
1.1.1.3   root      409: static unsigned long pixel_return[256];
                    410: static XColor parsed_xcolors[256];
                    411: static int ncolors = 0;
                    412: 
                    413: static int blackval = 32767;
                    414: static int whiteval = 0;
                    415: 
1.1       root      416: static int get_color(int r, int g, int b, xcolnr *cnp)
                    417: {
1.1.1.3   root      418:     XColor *col = parsed_xcolors + ncolors;
1.1       root      419:     char str[10];
1.1.1.3   root      420: 
1.1       root      421:     sprintf(str, "rgb:%x/%x/%x", r, g, b);
1.1.1.3   root      422:     XParseColor(display, cmap, str, col);
                    423:     *cnp = col->pixel = pixel_return[ncolors];
                    424:     XStoreColor (display, cmap, col);
                    425:     XStoreColor (display, cmap2, col);
                    426: 
                    427:     if (r + g + b < blackval)
                    428:        blackval = r + g + b, black = *col;
                    429:     if (r + g + b > whiteval)
                    430:        whiteval = r + g + b, white = *col;
                    431: 
                    432:     ncolors++;
                    433:     return 1;
1.1       root      434: }
                    435: 
                    436: static int init_colors(void)
                    437: {
1.1.1.3   root      438:     int i;
                    439: 
1.1       root      440:     if (need_dither) {
1.1.1.3   root      441:        XAllocColorCells (display, cmap, 0, 0, 0, pixel_return, 256);
                    442:        XAllocColorCells (display, cmap2, 0, 0, 0, pixel_return, 256);
1.1       root      443:        if (bitdepth == 1)
                    444:            setup_greydither (1, get_color);
                    445:        else
                    446:            setup_dither (bitdepth, get_color);
1.1.1.3   root      447:     } else {
                    448:        if (bitdepth != 8 && bitdepth != 12 && bitdepth != 15
                    449:            && bitdepth != 16 && bitdepth != 24) {
                    450:            fprintf(stderr, "Unsupported bit depth (%d)\n", bitdepth);
                    451:            return 0;
1.1       root      452:        }
                    453: 
1.1.1.3   root      454:        switch (visualInfo.VI_CLASS) {
                    455:         case TrueColor:
                    456:            {
                    457:                int red_bits = bitsInMask(visualInfo.red_mask);
                    458:                int green_bits = bitsInMask(visualInfo.green_mask);
                    459:                int blue_bits = bitsInMask(visualInfo.blue_mask);
                    460:                int red_shift = maskShift(visualInfo.red_mask);
                    461:                int green_shift = maskShift(visualInfo.green_mask);
                    462:                int blue_shift = maskShift(visualInfo.blue_mask);
                    463:                alloc_colors64k(red_bits, green_bits, blue_bits, red_shift,
                    464:                                green_shift, blue_shift);
                    465:            }
                    466:            XParseColor(display, cmap, "#000000", &black);
                    467:            if (!XAllocColor(display, cmap, &black))
                    468:                fprintf(stderr, "Whoops??\n");
                    469:            XParseColor(display, cmap, "#ffffff", &white);
                    470:            if (!XAllocColor(display, cmap, &white))
                    471:                fprintf(stderr, "Whoops??\n");
                    472:            break;
                    473: 
                    474:         case GrayScale:
                    475:         case PseudoColor:
                    476:            XAllocColorCells (display, cmap, 0, 0, 0, pixel_return, 256);
                    477:            XAllocColorCells (display, cmap2, 0, 0, 0, pixel_return, 256);
                    478:            alloc_colors256(get_color);
                    479:            break;
                    480: 
                    481:         default:
                    482:            fprintf (stderr, "Unsupported visual class (%d)\n", visualInfo.VI_CLASS);
                    483:            return 0;
                    484:        }
                    485:     }
                    486:     switch (gfxvidinfo.pixbytes) {
                    487:      case 2:
                    488:        for (i = 0; i < 4096; i++)
                    489:            xcolors[i] = xcolors[i] * 0x00010001;
                    490:        gfxvidinfo.can_double = 1;
                    491:        break;
                    492:      case 1:
                    493:        for (i = 0; i < 4096; i++)
                    494:            xcolors[i] = xcolors[i] * 0x01010101;
                    495:        gfxvidinfo.can_double = 1;
1.1       root      496:        break;
                    497:      default:
1.1.1.3   root      498:        gfxvidinfo.can_double = 0;
                    499:        break;
1.1       root      500:     }
1.1.1.3   root      501:     if(inverse_byte_order)
                    502:        switch(gfxvidinfo.pixbytes) {
                    503:         case 4:
                    504:            for(i = 0; i < 4096; i++)
                    505:                xcolors[i] = ((((xcolors[i]>>0)&255) << 24)
                    506:                              | (((xcolors[i]>>8)&255) << 16)
                    507:                              | (((xcolors[i]>>16)&255) << 8)
                    508:                              | (((xcolors[i]>>24)&255) << 0));
                    509:            break;
                    510:         case 2:
                    511:            for (i = 0; i < 4096; i++)
                    512:                xcolors[i] = (xcolors[i]>>8) | ((xcolors[i]&255)<<8);
                    513:            break;
                    514:         default:
                    515:            break;
                    516:        }
1.1       root      517:     return 1;
                    518: }
                    519: 
1.1.1.3   root      520: int graphics_setup(void)
1.1       root      521: {
                    522:     char *display_name = 0;
1.1.1.2   root      523: #ifdef USE_DGA_EXTENSION
                    524:     int MajorVersion, MinorVersion;
                    525:     int EventBase, ErrorBase;
                    526:     if (geteuid()) {
                    527:        fprintf(stderr, "You must be root to use UAE with the DGA extensions.\n");
1.1.1.3   root      528:        return 0;
1.1       root      529:     }
1.1.1.2   root      530: #endif
1.1.1.3   root      531: 
1.1       root      532:     display = XOpenDisplay(display_name);
                    533:     if (display == 0)  {
                    534:        fprintf(stderr, "Can't connect to X server %s\n", XDisplayName(display_name));
                    535:        return 0;
                    536:     }
1.1.1.3   root      537: 
1.1.1.2   root      538: #ifdef USE_DGA_EXTENSION
1.1.1.3   root      539:     if (!XF86DGAQueryVersion (display, &MajorVersion, &MinorVersion)) {
1.1.1.2   root      540:        fprintf(stderr, "Unable to query video extension version\n");
1.1.1.3   root      541:        return 0;
1.1.1.2   root      542:     }
1.1.1.3   root      543: 
                    544:     if (!XF86DGAQueryExtension (display, &EventBase, &ErrorBase)) {
1.1.1.2   root      545:        fprintf(stderr, "Unable to query video extension information\n");
1.1.1.3   root      546:        return 0;
1.1.1.2   root      547:     }
1.1.1.3   root      548: 
1.1.1.2   root      549:     /* Fail if the extension version in the server is too old */
                    550:     if (MajorVersion < DGA_MINMAJOR ||
                    551:        (MajorVersion == DGA_MINMAJOR && MinorVersion < DGA_MINMINOR)) {
1.1.1.3   root      552:        fprintf (stderr,
                    553:                 "Xserver is running an old XFree86-DGA version"
                    554:                 " (%d.%d)\n", MajorVersion, MinorVersion);
                    555:        fprintf (stderr, "Minimum required version is %d.%d\n",
1.1.1.2   root      556:                DGA_MINMAJOR, DGA_MINMINOR);
1.1.1.3   root      557:        return 0;
                    558:     }
                    559: #ifdef USE_VIDMODE_EXTENSION
                    560:     if (!XF86VidModeQueryVersion (display, &MajorVersion, &MinorVersion)) {
                    561:        fprintf (stderr, "Unable to query video extension version\n");
                    562:        return 0;
                    563:     }
                    564: 
                    565:     if (!XF86VidModeQueryExtension (display, &EventBase, &ErrorBase)) {
                    566:        fprintf (stderr, "Unable to query video extension information\n");
                    567:        return 0;
                    568:     }
                    569: 
                    570:     /* Fail if the extension version in the server is too old */
                    571:     if (MajorVersion < VidMode_MINMAJOR ||
                    572:        (MajorVersion == VidMode_MINMAJOR && MinorVersion < VidMode_MINMINOR)) {
                    573:        fprintf (stderr,
                    574:                 "Xserver is running an old XFree86-VidMode version"
                    575:                 " (%d.%d)\n", MajorVersion, MinorVersion);
                    576:        fprintf (stderr, "Minimum required version is %d.%d\n",
                    577:                 VidMode_MINMAJOR, VidMode_MINMINOR);
                    578:        return 0;
                    579:     }
                    580:     if (!get_vidmodes ()) {
                    581:        fprintf (stderr, "Error getting video mode information\n");
                    582:        return 0;
1.1.1.2   root      583:     }
                    584: #endif
                    585:     
1.1.1.3   root      586: #endif
                    587: 
                    588:     {
                    589:        int local_byte_order;
                    590:        int x = 0x04030201;
                    591:        char *y=(char*)&x;
                    592: 
                    593:        local_byte_order = y[0] == 0x04 ? MSBFirst : LSBFirst;
                    594:        if (ImageByteOrder(display) != local_byte_order)
                    595:            inverse_byte_order = 1;
                    596:     }
                    597: 
                    598:     return 1;
                    599: }
                    600: 
                    601: static void fixup_prefs_dimensions (void)
                    602: {
                    603:     if (currprefs.gfx_width < 320)
                    604:        currprefs.gfx_width = 320;
                    605:     if (currprefs.gfx_height < 200)
                    606:        currprefs.gfx_height = 200;
                    607:     if (currprefs.gfx_height > 300 && ! currprefs.gfx_linedbl)
                    608:        currprefs.gfx_height = 300;
                    609:     if (currprefs.gfx_height > 600)
                    610:        currprefs.gfx_height = 600;
                    611: 
                    612:     currprefs.gfx_width += 7; /* X86.S wants multiples of 4 bytes, might be 8 in the future. */
                    613:     currprefs.gfx_width &= ~7;
                    614: }
                    615: 
                    616: int graphics_init(void)
                    617: {
                    618:     int i,j;
                    619:     XSetWindowAttributes wattr;
                    620:     XPixmapFormatValues *xpfvs;
                    621: 
                    622:     if (currprefs.color_mode > 5)
                    623:        fprintf(stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
                    624: 
                    625:     x11_init_ok = 0;
                    626:     need_dither = 0;
                    627:     screen_is_picasso = 0;
                    628: 
1.1       root      629:     screen = XDefaultScreen(display);
                    630:     rootwin = XRootWindow(display,screen);
1.1.1.3   root      631: 
1.1       root      632:     /* try for a 12 bit visual first, then a 16 bit, then a 24 bit, then 8 bit */
                    633:     if (XMatchVisualInfo(display, screen, 12, TrueColor, &visualInfo)) {
1.1.1.3   root      634:     } else if (XMatchVisualInfo(display, screen, 15, TrueColor, &visualInfo)) {
1.1       root      635:     } else if (XMatchVisualInfo(display, screen, 16, TrueColor, &visualInfo)) {
                    636:     } else if (XMatchVisualInfo(display, screen, 24, TrueColor, &visualInfo)) {
                    637:     } else if (XMatchVisualInfo(display, screen, 8, PseudoColor, &visualInfo)) {
                    638:        /* for our HP boxes */
                    639:     } else if (XMatchVisualInfo(display, screen, 8, GrayScale, &visualInfo)) {
                    640:     } else if (XMatchVisualInfo(display, screen, 4, PseudoColor, &visualInfo)) {
                    641:        /* VGA16 server. Argh. */
                    642:     } else if (XMatchVisualInfo(display, screen, 1, StaticGray, &visualInfo)) {
                    643:        /* Mono server. Yuk */
                    644:     } else {
                    645:        fprintf(stderr, "Can't obtain appropriate X visual.\n");
                    646:        return 0;
                    647:     }
                    648:     vis = visualInfo.visual;
                    649:     bitdepth = visualInfo.depth;
1.1.1.3   root      650: 
1.1       root      651:     /* We now have the bitdepth of the display, but that doesn't tell us yet
                    652:      * how many bits to use per pixel. The VGA16 server has a bitdepth of 4,
                    653:      * but uses 1 byte per pixel. */
                    654:     xpfvs = XListPixmapFormats(display, &i);
                    655:     for (j = 0; j < i && xpfvs->depth != bitdepth; j++, xpfvs++)
                    656:        ;
                    657:     if (j == i) {
                    658:        fprintf(stderr, "Your X server is feeling ill.\n");
                    659:        return 0;
                    660:     }
1.1.1.3   root      661: 
1.1       root      662:     bit_unit = xpfvs->bits_per_pixel;
                    663:     fprintf(stderr, "Using %d bit visual, %d bits per pixel\n", bitdepth, bit_unit);
                    664: 
1.1.1.3   root      665:     fixup_prefs_dimensions ();
1.1.1.2   root      666: 
1.1.1.3   root      667:     gfxvidinfo.width = currprefs.gfx_width;
                    668:     gfxvidinfo.height = currprefs.gfx_height;
1.1       root      669: 
                    670:     cmap = XCreateColormap(display, rootwin, vis, AllocNone);
1.1.1.3   root      671:     cmap2 = XCreateColormap(display, rootwin, vis, AllocNone);
1.1.1.2   root      672: #ifdef USE_DGA_EXTENSION
                    673:     wattr.override_redirect = 1;
                    674: #endif
1.1       root      675:     wattr.event_mask = eventmask;
1.1.1.3   root      676:     wattr.background_pixel = /*black.pixel*/0;
1.1       root      677:     wattr.backing_store = Always;
                    678:     wattr.backing_planes = bitdepth;
                    679:     wattr.border_pixmap = None;
1.1.1.3   root      680:     wattr.border_pixel = /*black.pixel*/0;
1.1       root      681:     wattr.colormap = cmap;
1.1.1.3   root      682: 
                    683:     mywin = XCreateWindow(display, rootwin, 0, 0, currprefs.gfx_width, currprefs.gfx_height, 0,
1.1       root      684:                          bitdepth, InputOutput, vis,
                    685:                          CWEventMask|CWBackPixel|CWBorderPixel|CWBackingStore
1.1.1.2   root      686:                          |CWBackingPlanes|CWColormap
                    687: #ifdef USE_DGA_EXTENSION
                    688:                          |CWOverrideRedirect
                    689: #endif
                    690:                          ,&wattr);
1.1.1.3   root      691: 
                    692:     current_width = currprefs.gfx_width;
                    693:     current_height = currprefs.gfx_height;
                    694: 
1.1.1.2   root      695:     XMapWindow(display, mywin);
                    696: #ifdef USE_DGA_EXTENSION
                    697:     XRaiseWindow(display, mywin);
                    698: #else
1.1       root      699:     XStoreName(display, mywin, "UAE");
1.1.1.2   root      700: #endif
1.1.1.3   root      701: 
                    702:     if (bitdepth < 8 || (bitdepth == 8 && currprefs.color_mode == 3)) {
1.1       root      703:        gfxvidinfo.pixbytes = 2;
1.1.1.3   root      704:        currprefs.use_low_bandwidth = 0;
1.1       root      705:        need_dither = 1;
                    706:     } else {
1.1.1.3   root      707:        gfxvidinfo.pixbytes = bit_unit >> 3;
1.1       root      708:     }
1.1.1.2   root      709: 
                    710: #ifdef USE_DGA_EXTENSION
1.1.1.3   root      711:     enter_dga_mode ();
                    712:     /*setuid(getuid());*/
1.1.1.2   root      713: #else
1.1.1.3   root      714: 
                    715:     img = get_image (currprefs.gfx_width, currprefs.gfx_height, &image_mem);
1.1.1.2   root      716: #endif
1.1.1.3   root      717: 
1.1       root      718:     if (need_dither) {
1.1.1.3   root      719:        gfxvidinfo.maxblocklines = 0;
                    720:        gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * currprefs.gfx_width;
                    721:        gfxvidinfo.linemem = (char *)malloc(gfxvidinfo.rowbytes);
                    722:     } else if (currprefs.use_low_bandwidth) {
                    723:        gfxvidinfo.maxblocklines = 0;
                    724:        gfxvidinfo.rowbytes = img->bytes_per_line;
                    725:        gfxvidinfo.linemem = gfxvidinfo.bufmem = (char *)malloc(gfxvidinfo.rowbytes);
1.1       root      726:     } else {
1.1.1.3   root      727:        gfxvidinfo.maxblocklines = 100; /* whatever... */
                    728: #ifndef USE_DGA_EXTENSION
1.1       root      729:        gfxvidinfo.rowbytes = img->bytes_per_line;
                    730:        gfxvidinfo.bufmem = image_mem;
1.1.1.2   root      731: #endif
1.1.1.3   root      732:        gfxvidinfo.linemem = NULL;
1.1       root      733:     }
                    734: 
                    735:     if (!init_colors())
                    736:        return 0;
                    737: 
1.1.1.3   root      738: #ifndef USE_DGA_EXTENSION
                    739:     blankCursor = XCreatePixmapCursor(display,
                    740:                                      XCreatePixmap(display, mywin, 1, 1, 1),
                    741:                                      XCreatePixmap(display, mywin, 1, 1, 1),
                    742:                                      &black, &white, 0, 0);
                    743:     xhairCursor = XCreateFontCursor(display, XC_crosshair);
                    744: 
                    745:     whitegc = XCreateGC(display,mywin,0,0);
                    746:     blackgc = XCreateGC(display,mywin,0,0);
                    747:     picassogc = XCreateGC (display,mywin,0,0);
                    748: 
                    749:     XSetForeground(display, blackgc, black.pixel);
                    750:     XSetForeground(display, whitegc, white.pixel);
                    751: #endif
                    752: 
1.1       root      753:     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
                    754:     for(i=0; i<256; i++)
                    755:        keystate[i] = 0;
1.1.1.3   root      756: 
                    757:     lastmx = lastmy = 0;
1.1       root      758:     newmousecounters = 0;
                    759:     inwindow = 0;
1.1.1.2   root      760: 
                    761: #ifndef USE_DGA_EXTENSION
1.1.1.3   root      762:     if (!currprefs.no_xhair)
                    763:        XDefineCursor(display, mywin, xhairCursor);
1.1       root      764:     else
1.1.1.3   root      765:        XDefineCursor(display, mywin, blankCursor);
1.1       root      766:     cursorOn = 1;
1.1.1.2   root      767: #else
1.1.1.3   root      768:     dga_colormap_installed = 0;
                    769:     XF86DGAInstallColormap (display, screen, cmap);
1.1.1.2   root      770: #endif
1.1.1.3   root      771: 
1.1.1.2   root      772:     return x11_init_ok = 1;
1.1       root      773: }
                    774: 
                    775: void graphics_leave(void)
                    776: {
1.1.1.2   root      777:     if (!x11_init_ok)
                    778:        return;
1.1.1.3   root      779: 
1.1       root      780:     if (autorepeatoff)
1.1.1.3   root      781:        XAutoRepeatOn(display);
1.1.1.2   root      782:     XFlush(display);
                    783:     XSync(display, 0);
                    784: #ifdef USE_DGA_EXTENSION
1.1.1.3   root      785:     leave_dga_mode ();
1.1.1.2   root      786:     dumpcustom();
                    787: #endif
1.1       root      788: }
                    789: 
1.1.1.3   root      790: /* Decode KeySyms. This function knows about all keys that are common
1.1       root      791:  * between different keyboard languages. */
                    792: static int kc_decode (KeySym ks)
                    793: {
1.1.1.3   root      794:     switch (ks) {
1.1       root      795:      case XK_B: case XK_b: return AK_B;
                    796:      case XK_C: case XK_c: return AK_C;
                    797:      case XK_D: case XK_d: return AK_D;
                    798:      case XK_E: case XK_e: return AK_E;
                    799:      case XK_F: case XK_f: return AK_F;
                    800:      case XK_G: case XK_g: return AK_G;
                    801:      case XK_H: case XK_h: return AK_H;
                    802:      case XK_I: case XK_i: return AK_I;
                    803:      case XK_J: case XK_j: return AK_J;
                    804:      case XK_K: case XK_k: return AK_K;
                    805:      case XK_L: case XK_l: return AK_L;
                    806:      case XK_N: case XK_n: return AK_N;
                    807:      case XK_O: case XK_o: return AK_O;
                    808:      case XK_P: case XK_p: return AK_P;
                    809:      case XK_R: case XK_r: return AK_R;
                    810:      case XK_S: case XK_s: return AK_S;
                    811:      case XK_T: case XK_t: return AK_T;
                    812:      case XK_U: case XK_u: return AK_U;
                    813:      case XK_V: case XK_v: return AK_V;
                    814:      case XK_X: case XK_x: return AK_X;
1.1.1.3   root      815: 
1.1       root      816:      case XK_0: return AK_0;
                    817:      case XK_1: return AK_1;
                    818:      case XK_2: return AK_2;
                    819:      case XK_3: return AK_3;
                    820:      case XK_4: return AK_4;
                    821:      case XK_5: return AK_5;
                    822:      case XK_6: return AK_6;
                    823:      case XK_7: return AK_7;
                    824:      case XK_8: return AK_8;
                    825:      case XK_9: return AK_9;
1.1.1.3   root      826: 
1.1       root      827:        /* You never know which Keysyms might be missing on some workstation
                    828:         * This #ifdef should be enough. */
                    829: #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End)
                    830:      case XK_KP_0: case XK_KP_Insert: return AK_NP0;
                    831:      case XK_KP_1: case XK_KP_End: return AK_NP1;
                    832:      case XK_KP_2: case XK_KP_Down: return AK_NP2;
                    833:      case XK_KP_3: case XK_KP_Next: return AK_NP3;
                    834:      case XK_KP_4: case XK_KP_Left: return AK_NP4;
                    835:      case XK_KP_5: case XK_KP_Begin: return AK_NP5;
                    836:      case XK_KP_6: case XK_KP_Right: return AK_NP6;
                    837:      case XK_KP_7: case XK_KP_Home: return AK_NP7;
                    838:      case XK_KP_8: case XK_KP_Up: return AK_NP8;
                    839:      case XK_KP_9: case XK_KP_Prior: return AK_NP9;
                    840: #else
                    841:      case XK_KP_0: return AK_NP0;
                    842:      case XK_KP_1: return AK_NP1;
                    843:      case XK_KP_2: return AK_NP2;
                    844:      case XK_KP_3: return AK_NP3;
                    845:      case XK_KP_4: return AK_NP4;
                    846:      case XK_KP_5: return AK_NP5;
                    847:      case XK_KP_6: return AK_NP6;
                    848:      case XK_KP_7: return AK_NP7;
                    849:      case XK_KP_8: return AK_NP8;
                    850:      case XK_KP_9: return AK_NP9;
                    851: #endif
                    852:      case XK_KP_Divide: return AK_NPDIV;
                    853:      case XK_KP_Multiply: return AK_NPMUL;
                    854:      case XK_KP_Subtract: return AK_NPSUB;
                    855:      case XK_KP_Add: return AK_NPADD;
                    856:      case XK_KP_Decimal: return AK_NPDEL;
                    857:      case XK_KP_Enter: return AK_ENT;
                    858: 
                    859:      case XK_F1: return AK_F1;
                    860:      case XK_F2: return AK_F2;
                    861:      case XK_F3: return AK_F3;
                    862:      case XK_F4: return AK_F4;
                    863:      case XK_F5: return AK_F5;
                    864:      case XK_F6: return AK_F6;
                    865:      case XK_F7: return AK_F7;
                    866:      case XK_F8: return AK_F8;
                    867:      case XK_F9: return AK_F9;
                    868:      case XK_F10: return AK_F10;
1.1.1.3   root      869: 
1.1       root      870:      case XK_BackSpace: return AK_BS;
                    871:      case XK_Delete: return AK_DEL;
1.1.1.3   root      872:      case XK_Control_L: return AK_CTRL;
                    873:      case XK_Control_R: return AK_RCTRL;
1.1       root      874:      case XK_Tab: return AK_TAB;
                    875:      case XK_Alt_L: return AK_LALT;
                    876:      case XK_Alt_R: return AK_RALT;
                    877:      case XK_Meta_R: case XK_Hyper_R: return AK_RAMI;
                    878:      case XK_Meta_L: case XK_Hyper_L: return AK_LAMI;
                    879:      case XK_Return: return AK_RET;
                    880:      case XK_space: return AK_SPC;
                    881:      case XK_Shift_L: return AK_LSH;
                    882:      case XK_Shift_R: return AK_RSH;
                    883:      case XK_Escape: return AK_ESC;
                    884: 
1.1.1.3   root      885:      case XK_Insert: return AK_HELP;
                    886:      case XK_Home: return AK_NPLPAREN;
                    887:      case XK_End: return AK_NPRPAREN;
1.1       root      888:      case XK_Caps_Lock: return AK_CAPSLOCK;
1.1.1.3   root      889: 
1.1       root      890:      case XK_Up: return AK_UP;
                    891:      case XK_Down: return AK_DN;
                    892:      case XK_Left: return AK_LF;
                    893:      case XK_Right: return AK_RT;
1.1.1.3   root      894: 
1.1       root      895:      case XK_F11: return AK_BACKSLASH;
1.1.1.2   root      896: #ifdef USE_DGA_EXTENSION
1.1.1.3   root      897:      case XK_F12:
                    898:        uae_quit();
                    899:        return -1;
1.1.1.2   root      900: #else
1.1       root      901:      case XK_F12: return AK_mousestuff;
1.1.1.2   root      902: #endif
1.1       root      903: #ifdef XK_F14
                    904:      case XK_F14:
                    905: #endif
                    906:      case XK_Scroll_Lock: return AK_inhibit;
                    907: 
                    908: #ifdef XK_Page_Up /* These are missing occasionally */
                    909:      case XK_Page_Up: return AK_RAMI;          /* PgUp mapped to right amiga */
                    910:      case XK_Page_Down: return AK_LAMI;        /* PgDn mapped to left amiga */
                    911: #endif
                    912:     }
                    913:     return -1;
                    914: }
                    915: 
                    916: static int decode_fr(KeySym ks)
                    917: {
                    918:     switch(ks) {        /* FR specific */
                    919:      case XK_A: case XK_a: return AK_Q;
1.1.1.3   root      920:      case XK_M: case XK_m: return AK_SEMICOLON;
                    921:      case XK_Q: case XK_q: return AK_A;
1.1       root      922:      case XK_Y: case XK_y: return AK_Y;
1.1.1.2   root      923:      case XK_W: case XK_w: return AK_Z;
                    924:      case XK_Z: case XK_z: return AK_W;
1.1       root      925:      case XK_bracketleft: return AK_LBRACKET;
                    926:      case XK_bracketright: return AK_RBRACKET;
                    927:      case XK_comma: return AK_M;
                    928:      case XK_less: case XK_greater: return AK_LTGT;
                    929:      case XK_period: return AK_COMMA;
                    930:      case XK_parenright: return AK_MINUS;
                    931:      case XK_equal: return AK_SLASH;
                    932:      case XK_numbersign: return AK_NUMBERSIGN;
                    933:      case XK_slash: return AK_PERIOD;
                    934:      case XK_minus: return AK_EQUAL;
                    935:      case XK_backslash: return AK_BACKSLASH;
                    936:     }
                    937: 
                    938:     return -1;
                    939: }
                    940: 
                    941: static int decode_us(KeySym ks)
                    942: {
1.1.1.3   root      943:     switch(ks) {       /* US specific */
1.1       root      944:      case XK_A: case XK_a: return AK_A;
                    945:      case XK_M: case XK_m: return AK_M;
                    946:      case XK_Q: case XK_q: return AK_Q;
                    947:      case XK_Y: case XK_y: return AK_Y;
1.1.1.2   root      948:      case XK_W: case XK_w: return AK_W;
1.1       root      949:      case XK_Z: case XK_z: return AK_Z;
                    950:      case XK_bracketleft: return AK_LBRACKET;
                    951:      case XK_bracketright: return AK_RBRACKET;
                    952:      case XK_comma: return AK_COMMA;
                    953:      case XK_period: return AK_PERIOD;
                    954:      case XK_slash: return AK_SLASH;
                    955:      case XK_semicolon: return AK_SEMICOLON;
                    956:      case XK_minus: return AK_MINUS;
                    957:      case XK_equal: return AK_EQUAL;
                    958:        /* this doesn't work: */
                    959:      case XK_quoteright: return AK_QUOTE;
                    960:      case XK_quoteleft: return AK_BACKQUOTE;
                    961:      case XK_backslash: return AK_BACKSLASH;
                    962:     }
                    963: 
                    964:     return -1;
                    965: }
                    966: 
                    967: static int decode_de(KeySym ks)
                    968: {
                    969:     switch(ks) {
                    970:        /* DE specific */
                    971:      case XK_A: case XK_a: return AK_A;
                    972:      case XK_M: case XK_m: return AK_M;
                    973:      case XK_Q: case XK_q: return AK_Q;
1.1.1.2   root      974:      case XK_W: case XK_w: return AK_W;
1.1       root      975:      case XK_Y: case XK_y: return AK_Z;
                    976:      case XK_Z: case XK_z: return AK_Y;
                    977:      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
                    978:      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
                    979:      case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
                    980:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                    981:      case XK_comma: return AK_COMMA;
                    982:      case XK_period: return AK_PERIOD;
                    983:      case XK_less: case XK_greater: return AK_LTGT;
                    984:      case XK_numbersign: return AK_NUMBERSIGN;
                    985:      case XK_ssharp: return AK_MINUS;
                    986:      case XK_apostrophe: return AK_EQUAL;
                    987:      case XK_asciicircum: return AK_BACKQUOTE;
                    988:      case XK_minus: return AK_SLASH;
                    989:     }
                    990: 
                    991:     return -1;
                    992: }
                    993: 
                    994: static int decode_se(KeySym ks)
                    995: {
                    996:     switch(ks) {
                    997:        /* SE specific */
                    998:      case XK_A: case XK_a: return AK_A;
                    999:      case XK_M: case XK_m: return AK_M;
                   1000:      case XK_Q: case XK_q: return AK_Q;
1.1.1.2   root     1001:      case XK_W: case XK_w: return AK_W;
1.1       root     1002:      case XK_Y: case XK_y: return AK_Y;
                   1003:      case XK_Z: case XK_z: return AK_Z;
                   1004:      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
                   1005:      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
                   1006:      case XK_Aring: case XK_aring: return AK_LBRACKET;
                   1007:      case XK_comma: return AK_COMMA;
                   1008:      case XK_period: return AK_PERIOD;
                   1009:      case XK_minus: return AK_SLASH;
                   1010:      case XK_less: case XK_greater: return AK_LTGT;
                   1011:      case XK_plus: case XK_question: return AK_EQUAL;
                   1012:      case XK_at: case XK_onehalf: return AK_BACKQUOTE;
                   1013:      case XK_asciitilde: case XK_asciicircum: return AK_RBRACKET;
                   1014:      case XK_backslash: case XK_bar: return AK_MINUS;
1.1.1.3   root     1015: 
1.1       root     1016:      case XK_numbersign: return AK_NUMBERSIGN;
                   1017:     }
                   1018: 
                   1019:     return -1;
                   1020:  }
                   1021: 
                   1022: static int decode_it(KeySym ks)
                   1023: {
                   1024:     switch(ks) {
                   1025:        /* IT specific */
                   1026:      case XK_A: case XK_a: return AK_A;
                   1027:      case XK_M: case XK_m: return AK_M;
                   1028:      case XK_Q: case XK_q: return AK_Q;
1.1.1.2   root     1029:      case XK_W: case XK_w: return AK_W;
1.1       root     1030:      case XK_Y: case XK_y: return AK_Y;
                   1031:      case XK_Z: case XK_z: return AK_Z;
                   1032:      case XK_Ograve: case XK_ograve: return AK_SEMICOLON;
                   1033:      case XK_Agrave: case XK_agrave: return AK_QUOTE;
                   1034:      case XK_Egrave: case XK_egrave: return AK_LBRACKET;
                   1035:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                   1036:      case XK_comma: return AK_COMMA;
                   1037:      case XK_period: return AK_PERIOD;
                   1038:      case XK_less: case XK_greater: return AK_LTGT;
1.1.1.3   root     1039:      case XK_backslash: case XK_bar: return AK_BACKQUOTE;
                   1040:      case XK_apostrophe: return AK_MINUS;
1.1       root     1041:      case XK_Igrave: case XK_igrave: return AK_EQUAL;
                   1042:      case XK_minus: return AK_SLASH;
                   1043:      case XK_numbersign: return AK_NUMBERSIGN;
                   1044:     }
                   1045: 
                   1046:     return -1;
                   1047: }
                   1048: 
1.1.1.2   root     1049: static int decode_es(KeySym ks)
                   1050: {
                   1051:     switch(ks) {
                   1052:        /* ES specific */
                   1053:      case XK_A: case XK_a: return AK_A;
                   1054:      case XK_M: case XK_m: return AK_M;
                   1055:      case XK_Q: case XK_q: return AK_Q;
                   1056:      case XK_W: case XK_w: return AK_W;
                   1057:      case XK_Y: case XK_y: return AK_Y;
                   1058:      case XK_Z: case XK_z: return AK_Z;
                   1059:      case XK_ntilde: case XK_Ntilde: return AK_SEMICOLON;
                   1060: #ifdef XK_dead_acute
                   1061:      case XK_dead_acute: case XK_dead_diaeresis: return AK_QUOTE;
                   1062:      case XK_dead_grave: case XK_dead_circumflex: return AK_LBRACKET;
                   1063: #endif
                   1064:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                   1065:      case XK_comma: return AK_COMMA;
                   1066:      case XK_period: return AK_PERIOD;
                   1067:      case XK_less: case XK_greater: return AK_LTGT;
1.1.1.3   root     1068:      case XK_backslash: case XK_bar: return AK_BACKQUOTE;
                   1069:      case XK_apostrophe: return AK_MINUS;
1.1.1.2   root     1070:      case XK_Igrave: case XK_igrave: return AK_EQUAL;
                   1071:      case XK_minus: return AK_SLASH;
                   1072:      case XK_numbersign: return AK_NUMBERSIGN;
                   1073:     }
                   1074: 
                   1075:     return -1;
                   1076: }
                   1077: 
1.1       root     1078: static int keycode2amiga(XKeyEvent *event)
                   1079: {
                   1080:     KeySym ks;
                   1081:     int as;
                   1082:     int index = 0;
1.1.1.3   root     1083: 
1.1       root     1084:     do {
                   1085:        ks = XLookupKeysym(event, index);
                   1086:        as = kc_decode (ks);
1.1.1.3   root     1087: 
                   1088:        if (as == -1) {
                   1089:            switch(currprefs.keyboard_lang) {
1.1       root     1090: 
                   1091:            case KBD_LANG_FR:
                   1092:                as = decode_fr(ks);
                   1093:                break;
                   1094: 
1.1.1.3   root     1095:            case KBD_LANG_US:
1.1       root     1096:                as = decode_us(ks);
                   1097:                break;
1.1.1.3   root     1098: 
1.1       root     1099:             case KBD_LANG_DE:
                   1100:                as = decode_de(ks);
                   1101:                break;
1.1.1.3   root     1102: 
1.1       root     1103:             case KBD_LANG_SE:
                   1104:                as = decode_se(ks);
                   1105:                break;
1.1.1.3   root     1106: 
1.1       root     1107:             case KBD_LANG_IT:
                   1108:                as = decode_it(ks);
                   1109:                break;
                   1110: 
1.1.1.2   root     1111:             case KBD_LANG_ES:
                   1112:                as = decode_es(ks);
                   1113:                break;
                   1114: 
1.1       root     1115:             default:
                   1116:                as = -1;
                   1117:                break;
                   1118:            }
                   1119:        }
                   1120:        if(-1 != as)
                   1121:                return as;
                   1122:        index++;
                   1123:     } while (ks != NoSymbol);
                   1124:     return -1;
                   1125: }
                   1126: 
                   1127: static struct timeval lastMotionTime;
                   1128: 
1.1.1.3   root     1129: static int refresh_necessary = 0;
                   1130: 
1.1       root     1131: void handle_events(void)
                   1132: {
                   1133:     newmousecounters = 0;
                   1134:     gui_handle_events();
1.1.1.3   root     1135: 
1.1       root     1136:     for (;;) {
                   1137:        XEvent event;
                   1138: #if 0
                   1139:        if (!XCheckMaskEvent(display, eventmask, &event)) break;
                   1140: #endif
                   1141:        if (!XPending(display)) break;
                   1142:        XNextEvent(display, &event);
1.1.1.3   root     1143: 
1.1       root     1144:        switch(event.type) {
1.1.1.3   root     1145:         case KeyPress: {
1.1       root     1146:             int kc = keycode2amiga((XKeyEvent *)&event);
                   1147:             if (kc == -1) break;
                   1148:             switch (kc) {
                   1149:              case AK_mousestuff:
                   1150:                 togglemouse();
                   1151:                 break;
                   1152: 
                   1153:              case AK_inhibit:
1.1.1.3   root     1154:                 toggle_inhibit_frame (0);
1.1       root     1155:                 break;
                   1156: 
                   1157:              default:
1.1.1.3   root     1158:                 if (!keystate[kc]) {
1.1       root     1159:                     keystate[kc] = 1;
                   1160:                     record_key (kc << 1);
                   1161:                 }
                   1162:                 break;
                   1163:             }
                   1164:             break;
                   1165:         }
1.1.1.3   root     1166:         case KeyRelease: {
1.1       root     1167:             int kc = keycode2amiga((XKeyEvent *)&event);
                   1168:             if (kc == -1) break;
                   1169:             keystate[kc] = 0;
                   1170:             record_key ((kc << 1) | 1);
                   1171:             break;
                   1172:         }
                   1173:         case ButtonPress:
                   1174:            buttonstate[((XButtonEvent *)&event)->button-1] = 1;
                   1175:            break;
                   1176:         case ButtonRelease:
                   1177:            buttonstate[((XButtonEvent *)&event)->button-1] = 0;
                   1178:            break;
1.1.1.2   root     1179: #ifndef USE_DGA_EXTENSION
1.1       root     1180:         case EnterNotify:
                   1181:            newmousecounters = 1;
                   1182:            lastmx = ((XCrossingEvent *)&event)->x;
                   1183:            lastmy = ((XCrossingEvent *)&event)->y;
                   1184:            inwindow = 1;
                   1185:            break;
                   1186:         case LeaveNotify:
                   1187:            inwindow = 0;
                   1188:            break;
                   1189:         case FocusIn:
                   1190:            if (!autorepeatoff)
                   1191:                XAutoRepeatOff(display);
                   1192:            autorepeatoff = 1;
                   1193:            break;
                   1194:         case FocusOut:
                   1195:            if (autorepeatoff)
                   1196:                XAutoRepeatOn(display);
                   1197:            autorepeatoff = 0;
                   1198:            break;
                   1199:         case MotionNotify:
1.1.1.3   root     1200:            if (inwindow) {
1.1       root     1201:                lastmx = ((XMotionEvent *)&event)->x;
                   1202:                lastmy = ((XMotionEvent *)&event)->y;
1.1.1.3   root     1203:                if(!cursorOn && !currprefs.no_xhair) {
1.1       root     1204:                    XDefineCursor(display, mywin, xhairCursor);
                   1205:                    cursorOn = 1;
                   1206:                }
                   1207:                gettimeofday(&lastMotionTime, NULL);
                   1208:            }
                   1209:            break;
                   1210:         case Expose:
1.1.1.3   root     1211:            refresh_necessary = 1;
1.1       root     1212:            break;
1.1.1.2   root     1213: #else
                   1214:         case MotionNotify:
                   1215:            newmousecounters = 0;
                   1216:            lastmx += ((XMotionEvent *)&event)->x_root;
                   1217:            lastmy += ((XMotionEvent *)&event)->y_root;
                   1218: #endif
1.1       root     1219:        }
                   1220:     }
1.1.1.3   root     1221: #if defined PICASSO96 && !defined USE_DGA_EXTENSION
                   1222:     if (screen_is_picasso && refresh_necessary) {
                   1223:        DO_PUTIMAGE (picasso_img, 0, 0, 0, 0,
                   1224:                     picasso_vidinfo.width, picasso_vidinfo.height);
                   1225:        refresh_necessary = 0;
                   1226:     } else if (screen_is_picasso) {
                   1227:        int i;
                   1228:        int strt = -1, stop = -1;
                   1229:        picasso_invalid_lines[picasso_vidinfo.height] = 0;
                   1230:        for (i = 0; i < picasso_vidinfo.height + 1; i++) {
                   1231:            if (picasso_invalid_lines[i]) {
                   1232:                picasso_invalid_lines[i] = 0;
                   1233:                if (strt != -1)
                   1234:                    continue;
                   1235:                strt = i;
                   1236:            } else {
                   1237:                if (strt == -1)
                   1238:                    continue;
                   1239:                DO_PUTIMAGE (picasso_img, 0, strt, 0, strt,
                   1240:                             picasso_vidinfo.width, i-strt);
                   1241:                strt = -1;
                   1242:            }
                   1243:        }
                   1244:     }
                   1245: #endif
1.1       root     1246: 
1.1.1.2   root     1247: #ifndef USE_DGA_EXTENSION
1.1.1.3   root     1248:     if (!screen_is_picasso && refresh_necessary) {
                   1249:        DO_PUTIMAGE (img, 0, 0, 0, 0, currprefs.gfx_width, currprefs.gfx_height);
                   1250:        refresh_necessary = 0;
1.1       root     1251:     }
1.1.1.3   root     1252:     if(cursorOn && !currprefs.no_xhair) {
1.1       root     1253:        struct timeval now;
                   1254:        int diff;
                   1255:        gettimeofday(&now, NULL);
1.1.1.3   root     1256:        diff = (now.tv_sec - lastMotionTime.tv_sec) * 1000000 +
1.1       root     1257:            (now.tv_usec - lastMotionTime.tv_usec);
                   1258:        if(diff > 1000000) {
                   1259:            XDefineCursor(display, mywin, blankCursor);
                   1260:            cursorOn = 0;
                   1261:        }
                   1262:     }
1.1.1.2   root     1263: #endif
1.1       root     1264:     /* "Affengriff" */
                   1265:     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
1.1.1.3   root     1266:        uae_reset();
1.1       root     1267: }
                   1268: 
                   1269: int debuggable(void)
                   1270: {
                   1271:     return 1;
                   1272: }
                   1273: 
                   1274: int needmousehack(void)
                   1275: {
1.1.1.2   root     1276: #ifdef USE_DGA_EXTENSION
                   1277:     return 0;
                   1278: #else
1.1       root     1279:     return 1;
1.1.1.2   root     1280: #endif
1.1       root     1281: }
                   1282: 
                   1283: void LED(int on)
                   1284: {
1.1.1.2   root     1285: #if 0 /* Maybe that is responsible for the joystick emulation problems on SunOS? */
1.1       root     1286:     static int last_on = -1;
                   1287:     XKeyboardControl control;
                   1288: 
                   1289:     if (last_on == on) return;
                   1290:     last_on = on;
                   1291:     control.led = 1; /* implementation defined */
                   1292:     control.led_mode = on ? LedModeOn : LedModeOff;
                   1293:     XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
1.1.1.2   root     1294: #endif
1.1       root     1295: }
                   1296: 
1.1.1.3   root     1297: void write_log (const char *buf)
                   1298: {
                   1299:     fprintf (stderr, buf);
                   1300: }
                   1301: 
                   1302: #ifdef PICASSO96
                   1303: 
                   1304: void DX_Invalidate (int first, int last)
                   1305: {
                   1306:     do {
                   1307:        picasso_invalid_lines[first] = 1;
                   1308:        first++;
                   1309:     } while (first <= last);
                   1310: }
                   1311: 
                   1312: int DX_BitsPerCannon (void)
                   1313: {
                   1314:     return 8;
                   1315: }
                   1316: 
                   1317: void DX_SetPalette(int start, int count)
                   1318: {
                   1319:     if (!screen_is_picasso || picasso_vidinfo.pixbytes != 1)
                   1320:        return;
                   1321: 
                   1322:     while (count-- > 0) {
                   1323:        XColor col = parsed_xcolors[start];
                   1324:        col.red = picasso96_state.CLUT[start].Red * 0x0101;
                   1325:        col.green = picasso96_state.CLUT[start].Green * 0x0101;
                   1326:        col.blue = picasso96_state.CLUT[start].Blue * 0x0101;
                   1327:        XStoreColor (display, cmap, &col);
                   1328:        XStoreColor (display, cmap2, &col);
                   1329:        start++;
                   1330:     }
                   1331: #ifdef USE_DGA_EXTENSION
                   1332:     dga_colormap_installed ^= 1;
                   1333:     if (dga_colormap_installed == 1)
                   1334:        XF86DGAInstallColormap(display, screen, cmap2);
                   1335:     else
                   1336:        XF86DGAInstallColormap(display, screen, cmap);
                   1337: #endif
                   1338: }
                   1339: 
                   1340: #define MAX_SCREEN_MODES 11
                   1341: 
                   1342: static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280 };
                   1343: static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768, 864, 1024 };
                   1344: 
                   1345: int DX_FillResolutions (uae_u16 *ppixel_format)
                   1346: {
                   1347:     Screen *scr = ScreenOfDisplay (display, screen);
                   1348:     int i, count = 0;
                   1349:     int w = WidthOfScreen (scr);
                   1350:     int h = HeightOfScreen (scr);
                   1351:     int maxw = 0, maxh = 0;
                   1352: 
                   1353:     *ppixel_format = (bit_unit == 8 ? RGBFF_CHUNKY
                   1354:                      : bitdepth == 15 && bit_unit == 16 ? RGBFF_R5G5B5PC
                   1355:                      : bitdepth == 16 && bit_unit == 16 ? RGBFF_R5G6B5PC
                   1356:                      : bit_unit == 24 ? RGBFF_B8G8R8
                   1357:                      : bit_unit == 32 ? RGBFF_B8G8R8A8
                   1358:                      : 0);
                   1359: 
                   1360: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
                   1361:     for (i = 0; i < vidmodecount && i < MAX_PICASSO_MODES ; i++) {
                   1362:        DisplayModes[i].res.width = allmodes[i]->hdisplay;
                   1363:        DisplayModes[i].res.height = allmodes[i]->vdisplay;
                   1364:        DisplayModes[i].depth = bit_unit >> 3;
                   1365:        DisplayModes[i].refresh = 75;
                   1366:     }
                   1367:     count = i;
                   1368: #else
                   1369:     for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES ; i++) {
                   1370:        if (x_size_table[i] <= w && y_size_table[i] <= h) {
                   1371:            if (x_size_table[i] > maxw)
                   1372:                maxw = x_size_table[i];
                   1373:            if (y_size_table[i] > maxh)
                   1374:                maxh = y_size_table[i];
                   1375:            DisplayModes[count].res.width = x_size_table[i];
                   1376:            DisplayModes[count].res.height = y_size_table[i];
                   1377:            DisplayModes[count].depth = bit_unit >> 3;
                   1378:            DisplayModes[count].refresh = 75;
                   1379:            count++;
                   1380:        }
                   1381:     }
                   1382: #endif
                   1383: 
                   1384: #ifndef USE_DGA_EXTENSION
                   1385:     picasso_img = get_image (maxw, maxh, 0);
                   1386: #endif
                   1387: 
                   1388:     return count;
                   1389: }
                   1390: 
                   1391: static void set_window_for_picasso (void)
                   1392: {
                   1393:     if (current_width != picasso_vidinfo.width || current_height != picasso_vidinfo.height) {
                   1394:        current_width = picasso_vidinfo.width;
                   1395:        current_height = picasso_vidinfo.height;
                   1396:        XResizeWindow (display, mywin, picasso_vidinfo.width,
                   1397:                       picasso_vidinfo.height);
                   1398: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
                   1399:        switch_to_best_mode ();
                   1400: #endif
                   1401:     }
                   1402:     DX_SetPalette (0, 256);
                   1403: }
                   1404: 
                   1405: static void set_window_for_amiga (void)
                   1406: {
                   1407:     int i;
                   1408: 
                   1409:     if (current_width != currprefs.gfx_width || current_height != currprefs.gfx_height) {
                   1410:        current_width = currprefs.gfx_width;
                   1411:        current_height = currprefs.gfx_height;
                   1412:        XResizeWindow (display, mywin, currprefs.gfx_width,
                   1413:                       currprefs.gfx_height);
                   1414: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
                   1415:        switch_to_best_mode ();
                   1416: #endif
                   1417:     }
                   1418: 
1.1.1.4 ! root     1419:     if (visualInfo.VI_CLASS != TrueColor)
1.1.1.3   root     1420:        for (i = 0; i < 256; i++) {
                   1421:            XStoreColor (display, cmap, parsed_xcolors + i);
                   1422:            XStoreColor (display, cmap2, parsed_xcolors + i);
                   1423:        }
                   1424: #ifdef USE_DGA_EXTENSION
                   1425:     dga_colormap_installed ^= 1;
                   1426:     if (dga_colormap_installed == 1)
                   1427:        XF86DGAInstallColormap(display, screen, cmap2);
                   1428:     else
                   1429:        XF86DGAInstallColormap(display, screen, cmap);
                   1430: #endif
                   1431: }
                   1432: 
                   1433: void gfx_set_picasso_modeinfo (int w, int h, int depth)
                   1434: {
                   1435:     picasso_vidinfo.width = w;
                   1436:     picasso_vidinfo.height = h;
                   1437:     picasso_vidinfo.depth = depth;
1.1.1.4 ! root     1438:     picasso_vidinfo.pixbytes = bit_unit >> 3;
1.1.1.3   root     1439: #ifdef USE_DGA_EXTENSION
1.1.1.4 ! root     1440:     picasso_vidinfo.rowbytes = fb_width * picasso_vidinfo.pixbytes;
1.1.1.3   root     1441: #else
                   1442:     picasso_vidinfo.rowbytes = picasso_img->bytes_per_line;
                   1443: #endif
                   1444:     picasso_vidinfo.extra_mem = 1;
                   1445: 
                   1446:     if (screen_is_picasso)
                   1447:        set_window_for_picasso ();
                   1448: }
                   1449: 
                   1450: void gfx_set_picasso_baseaddr (uaecptr a)
                   1451: {
                   1452: }
                   1453: 
                   1454: void gfx_set_picasso_state (int on)
                   1455: {
                   1456:     if (on == screen_is_picasso)
                   1457:        return;
                   1458:     screen_is_picasso = on;
                   1459:     if (on)
                   1460:        set_window_for_picasso ();
                   1461:     else
                   1462:        set_window_for_amiga ();
                   1463: }
                   1464: 
                   1465: void begindrawing (void)
1.1       root     1466: {
                   1467: }
1.1.1.3   root     1468: 
                   1469: void enddrawing (void)
                   1470: {
                   1471: }
                   1472: 
                   1473: uae_u8 *lockscr (void)
                   1474: {
                   1475: #ifdef USE_DGA_EXTENSION
                   1476:     return fb_addr;
                   1477: #else
                   1478:     return picasso_img->data;
                   1479: #endif
                   1480: }
                   1481: void unlockscr (void)
                   1482: {
                   1483: }
                   1484: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.