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

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.5   root        8:   * Copyright 1998 Marcus Sundberg
1.1.1.2   root        9:   * DGA support by Kai Kollmorgen
1.1.1.5   root       10:   * X11/DGA merge, hotkeys and grabmouse by Marcus Sundberg
1.1       root       11:   */
                     12: 
                     13: #include "sysconfig.h"
                     14: #include "sysdeps.h"
                     15: 
                     16: #include <X11/Xlib.h>
                     17: #include <X11/Xutil.h>
                     18: #include <X11/keysym.h>
                     19: #include <X11/cursorfont.h>
                     20: 
                     21: #include <ctype.h>
                     22: #include <signal.h>
                     23: 
                     24: #include "config.h"
                     25: #include "options.h"
1.1.1.3   root       26: #include "threaddep/penguin.h"
                     27: #include "uae.h"
1.1       root       28: #include "memory.h"
1.1.1.6 ! root       29: #include "xwin.h"
1.1       root       30: #include "custom.h"
1.1.1.6 ! root       31: #include "drawing.h"
1.1.1.2   root       32: #include "readcpu.h"
1.1       root       33: #include "newcpu.h"
                     34: #include "keyboard.h"
                     35: #include "keybuf.h"
                     36: #include "gui.h"
                     37: #include "debug.h"
1.1.1.3   root       38: #include "picasso96.h"
                     39: 
                     40: #ifdef __cplusplus
                     41: #define VI_CLASS c_class
                     42: #else
                     43: #define VI_CLASS class
                     44: #endif
1.1       root       45: 
1.1.1.2   root       46: #ifdef USE_DGA_EXTENSION
1.1.1.3   root       47: 
                     48: #ifdef USE_VIDMODE_EXTENSION
                     49: #include <X11/extensions/xf86vmode.h>
                     50: #define VidMode_MINMAJOR 0
                     51: #define VidMode_MINMINOR 0
                     52: #endif
                     53: 
1.1.1.2   root       54: #include <X11/extensions/xf86dga.h>
                     55: #define DGA_MINMAJOR 0
                     56: #define DGA_MINMINOR 0
1.1.1.3   root       57: 
1.1.1.5   root       58: #endif /* USE_DGA_EXTENSION */
                     59: 
                     60: #if SHM_SUPPORT_LINKS == 1
1.1.1.3   root       61: 
                     62: #include <sys/ipc.h>
                     63: #include <sys/shm.h>
                     64: #include <X11/extensions/XShm.h>
                     65: 
                     66: #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
                     67:     do { \
1.1.1.6 ! root       68:        if (currprefs.x11_use_mitshm) \
1.1.1.5   root       69:             XShmPutImage (display, mywin, mygc, (IMG), (SRCX), (SRCY), (DSTX), (DSTY), (WIDTH), (HEIGHT), 0); \
1.1.1.3   root       70:        else \
1.1.1.5   root       71:            XPutImage (display, mywin, mygc, (IMG), (SRCX), (SRCY), (DSTX), (DSTY), (WIDTH), (HEIGHT)); \
1.1.1.3   root       72:     } while (0)
                     73: #else
                     74: #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
1.1.1.5   root       75:     XPutImage (display, mywin, mygc, (IMG), (SRCX), (SRCY), (DSTX), (DSTY), (WIDTH), (HEIGHT))
1.1.1.2   root       76: #endif
                     77: 
1.1       root       78: #ifdef __cplusplus
                     79: static RETSIGTYPE sigbrkhandler(...)
                     80: #else
1.1.1.5   root       81: static RETSIGTYPE sigbrkhandler (int foo)
1.1       root       82: #endif
                     83: {
                     84:     activate_debugger();
                     85: 
                     86: #if !defined(__unix) || defined(__NeXT__)
1.1.1.5   root       87:     signal (SIGINT, sigbrkhandler);
1.1       root       88: #endif
                     89: }
                     90: 
1.1.1.5   root       91: void setup_brkhandler (void)
1.1       root       92: {
                     93: #if defined(__unix) && !defined(__NeXT__)
                     94:     struct sigaction sa;
                     95:     sa.sa_handler = sigbrkhandler;
                     96:     sa.sa_flags = 0;
                     97: #ifdef SA_RESTART
                     98:     sa.sa_flags = SA_RESTART;
                     99: #endif
1.1.1.5   root      100:     sigemptyset (&sa.sa_mask);
                    101:     sigaction (SIGINT, &sa, NULL);
1.1       root      102: #else
1.1.1.5   root      103:     signal (SIGINT, sigbrkhandler);
1.1.1.2   root      104: #endif
1.1.1.3   root      105: }
1.1.1.2   root      106: 
1.1.1.5   root      107: struct disp_info {
                    108:     XImage *ximg;
                    109:     char *image_mem;
                    110: #if SHM_SUPPORT_LINKS == 1
                    111:     XShmSegmentInfo shminfo;
                    112: #endif
                    113: };
                    114: 
1.1       root      115: static Display *display;
                    116: static int screen;
                    117: static Window rootwin, mywin;
                    118: 
1.1.1.5   root      119: static GC mygc;
                    120: static XColor black, white;
1.1.1.3   root      121: static Colormap cmap, cmap2;
1.1.1.5   root      122: static int red_bits, green_bits, blue_bits;
                    123: static int red_shift, green_shift, blue_shift;
1.1.1.3   root      124: 
1.1.1.5   root      125: /* Kludge-O-Matic.
                    126:  * Unfortunately the X server loses colormap changes in DGA mode. Switching
                    127:  * back and forth between two identical colormaps fixes this problem.  */
1.1.1.3   root      128: static int dga_colormap_installed;
1.1       root      129: 
                    130: static int need_dither;
                    131: 
1.1.1.3   root      132: static int screen_is_picasso;
                    133: static char picasso_invalid_lines[1201];
1.1.1.5   root      134: static int picasso_has_invalid_lines;
                    135: static int picasso_invalid_start, picasso_invalid_stop;
                    136: static int picasso_maxw = 0, picasso_maxh = 0;
1.1.1.3   root      137: 
1.1       root      138: static int autorepeatoff = 0;
1.1.1.5   root      139: static struct disp_info ami_dinfo, pic_dinfo;
1.1       root      140: static Visual *vis;
                    141: static XVisualInfo visualInfo;
                    142: static int bitdepth, bit_unit;
                    143: static Cursor blankCursor, xhairCursor;
                    144: static int cursorOn;
1.1.1.3   root      145: static int inverse_byte_order = 0;
1.1       root      146: 
1.1.1.3   root      147: static int current_width, current_height;
1.1       root      148: 
1.1.1.2   root      149: static int x11_init_ok;
1.1.1.5   root      150: static int dgaavail = 0, vidmodeavail = 0, shmavail = 0;
                    151: static int dgamode;
1.1.1.2   root      152: 
1.1.1.6 ! root      153: /* Keyboard and mouse */
1.1       root      154: 
                    155: static int keystate[256];
                    156: 
1.1.1.5   root      157: static int oldx, oldy;
                    158: static int grabbed;
                    159: 
                    160: struct uae_hotkeys {
                    161:     KeySym syms[4];
                    162:     void (*handler)(void);
                    163:     int retval;
                    164:     int mask;
                    165: };
                    166: 
1.1.1.6 ! root      167: static void handle_modeswitch (void);
1.1.1.5   root      168: static void handle_mousegrab (void);
                    169: static void handle_inhibit (void);
                    170: static void framerate_up (void);
                    171: static void framerate_down (void);
                    172: 
                    173: 
                    174: static struct uae_hotkeys hotkeys[] = {
1.1.1.6 ! root      175: #ifdef USE_DGA_EXTENSION  
        !           176:     {{ XK_F12, XK_s, 0 }, handle_modeswitch, -1, 0 },
        !           177: #endif
        !           178:     {{ XK_F12, XK_q, 0 }, uae_quit, -1, 0 },
        !           179:     {{ XK_F12, XK_m, 0 }, togglemouse, -1, 0 },
        !           180:     {{ XK_F12, XK_g, 0 }, handle_mousegrab, -1, 0 },
        !           181:     {{ XK_F12, XK_i, 0 }, handle_inhibit, -1, 0 },
        !           182:     {{ XK_F12, XK_KP_Add, 0 }, framerate_up, -1, 0 },
        !           183:     {{ XK_F12, XK_KP_Subtract, 0 }, framerate_down, -1, 0 },
        !           184:     {{ XK_Scroll_Lock, 0 }, handle_inhibit, -1, 0 },
        !           185:     {{ 0 }, NULL, -1, 0 } /* List must be terminated */
1.1.1.5   root      186: };
                    187: 
1.1       root      188: static int inwindow;
1.1.1.5   root      189: #define EVENTMASK (KeyPressMask|KeyReleaseMask|ButtonPressMask \
                    190:                   |ButtonReleaseMask|PointerMotionMask \
                    191:                   |FocusChangeMask|EnterWindowMask \
                    192:                   |ExposureMask |LeaveWindowMask)
                    193: #define DGA_EVENTMASK (KeyPressMask|KeyReleaseMask|ButtonPressMask \
                    194:                       |ButtonReleaseMask|PointerMotionMask)
                    195: 
                    196: #if SHM_SUPPORT_LINKS == 1
                    197: /* Hack to detect shm-failure, probably due to displaying on a
                    198:  * remote server. */
                    199: static int shmerror;
                    200: static int (*oldshmerrorhandler) (Display *, XErrorEvent *);
                    201: 
                    202: static int shmerrorhandler (Display *dsp, XErrorEvent *ev)
                    203: {
                    204:     if (ev->error_code == BadAccess)
                    205:        shmerror=1;
                    206:     else
                    207:        (*oldshmerrorhandler) (dsp, ev);
                    208:     return 0;
                    209: }
1.1.1.2   root      210: #endif
1.1       root      211: 
1.1.1.5   root      212: static void get_image (int w, int h, struct disp_info *dispi)
1.1.1.3   root      213: {
                    214:     XImage *new_img;
                    215:     char *p;
                    216: 
                    217: #if SHM_SUPPORT_LINKS == 1
1.1.1.6 ! root      218:     if (currprefs.x11_use_mitshm && shmavail) {
1.1.1.5   root      219:        XShmSegmentInfo *shminfo = &dispi->shminfo;
1.1.1.3   root      220: 
                    221:        new_img = XShmCreateImage (display, vis, bitdepth, ZPixmap, 0, shminfo, w, h);
                    222: 
                    223:        shminfo->shmid = shmget (IPC_PRIVATE, h * new_img->bytes_per_line,
                    224:                                 IPC_CREAT | 0777);
                    225:        shminfo->shmaddr = new_img->data = (char *)shmat (shminfo->shmid, 0, 0);
1.1.1.5   root      226:        dispi->image_mem = new_img->data;
1.1.1.3   root      227:        shminfo->readOnly = False;
1.1.1.5   root      228:        /* Try to let the Xserver attach */
                    229:        shmerror = 0;
                    230:        oldshmerrorhandler = XSetErrorHandler (shmerrorhandler);
1.1.1.3   root      231:        XShmAttach (display, shminfo);
1.1.1.5   root      232:        XSync (display, 0);
                    233:        XSetErrorHandler (oldshmerrorhandler);
                    234:        if (shmerror) {
                    235:            shmdt (shminfo->shmaddr);
                    236:            XDestroyImage (new_img);
                    237:            shminfo->shmid = -1;
                    238:            shmavail = 0;
                    239:            fprintf (stderr, "MIT-SHM extension failed, trying fallback.\n");
                    240:        } else {
                    241:            /* now deleting means making it temporary */
                    242:            shmctl (shminfo->shmid, IPC_RMID, 0);
                    243:            dispi->ximg = new_img;
                    244:            printf ("Using MIT-SHM extension.\n");
                    245:            return;
                    246:        }
1.1.1.3   root      247:     }
                    248: #endif
                    249: 
                    250:     /* Question for people who know about X: Could we allocate the buffer
                    251:      * after creating the image and then do new_img->data = buffer, as above in
                    252:      * the SHM case?
                    253:      */
                    254:     printf ("Using normal image buffer.\n");
                    255:     p = (char *)xmalloc (h * w * ((bit_unit + 7) / 8)); /* ??? */
                    256:     new_img = XCreateImage (display, vis, bitdepth, ZPixmap, 0, p,
                    257:                            w, h, 32, 0);
                    258:     if (new_img->bytes_per_line != w * ((bit_unit + 7) / 8))
                    259:        fprintf (stderr, "Possible bug here... graphics may look strange.\n");
                    260: 
1.1.1.5   root      261:     dispi->image_mem = p;
                    262:     dispi->ximg = new_img;
1.1.1.3   root      263: }
                    264: 
                    265: #ifdef USE_VIDMODE_EXTENSION
                    266: static XF86VidModeModeInfo **allmodes;
                    267: static int vidmodecount;
                    268: 
                    269: static int get_vidmodes (void)
                    270: {
                    271:     return XF86VidModeGetAllModeLines (display, screen, &vidmodecount, &allmodes);
                    272: }
1.1.1.4   root      273: #endif
1.1.1.3   root      274: 
1.1.1.5   root      275: #ifdef USE_DGA_EXTENSION
                    276: 
                    277: static int fb_bank, fb_banks, fb_mem;
                    278: static char *fb_addr;
                    279: static int fb_width;
                    280: 
1.1.1.3   root      281: static void switch_to_best_mode (void)
                    282: {
                    283:     int i, best;
1.1.1.5   root      284: #ifdef USE_VIDMODE_EXTENSION
                    285:     if (vidmodeavail) {
                    286:        best = 0;
                    287:        for (i = 1; i < vidmodecount; i++) {
                    288:            if (allmodes[i]->hdisplay >= current_width
                    289:                && allmodes[i]->vdisplay >= current_height
                    290:                && allmodes[i]->hdisplay <= allmodes[best]->hdisplay
                    291:                && allmodes[i]->vdisplay <= allmodes[best]->vdisplay)
                    292:                best = i;
                    293:        }
                    294:        printf ("entering DGA mode: %dx%d (%d, %d)\n",
                    295:                allmodes[best]->hdisplay, allmodes[best]->vdisplay,
                    296:                current_width, current_height);
                    297:        XF86VidModeSwitchToMode (display, screen, allmodes[best]);
                    298:        XF86VidModeSetViewPort (display, screen, 0, 0);
                    299:     }
1.1.1.4   root      300: #endif
1.1.1.3   root      301:     XMoveWindow (display, mywin, 0, 0);
                    302:     XWarpPointer (display, None, rootwin, 0, 0, 0, 0, 0, 0);
1.1.1.5   root      303:     XF86DGADirectVideo (display, screen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb);
                    304:     XF86DGASetViewPort (display, screen, 0, 0);
                    305:     memset (fb_addr, 0, fb_mem * 1024);
1.1.1.3   root      306: }
                    307: 
                    308: static void enter_dga_mode (void)
                    309: {
                    310:     Screen *scr = ScreenOfDisplay (display, screen);
                    311:     int w = WidthOfScreen (scr);
                    312:     int h = HeightOfScreen (scr);
                    313: 
                    314:     XRaiseWindow (display, mywin);
                    315: 
                    316:     /* We want all the key presses */
                    317:     XGrabKeyboard (display, rootwin, 1, GrabModeAsync,
                    318:                   GrabModeAsync,  CurrentTime);
                    319: 
                    320:     /* and all the mouse moves */
                    321:     XGrabPointer (display, rootwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
                    322:                  GrabModeAsync, GrabModeAsync, None,  None, CurrentTime);
                    323: 
                    324:     switch_to_best_mode ();
                    325: 
                    326:     gfxvidinfo.rowbytes = fb_width*gfxvidinfo.pixbytes;
                    327:     gfxvidinfo.bufmem = fb_addr;
1.1.1.5   root      328:     gfxvidinfo.linemem = 0;
                    329:     gfxvidinfo.emergmem = malloc (gfxvidinfo.rowbytes);
                    330:     gfxvidinfo.maxblocklines = 10000;
1.1.1.3   root      331: }
                    332: 
                    333: static void leave_dga_mode (void)
                    334: {
                    335: #ifdef USE_VIDMODE_EXTENSION
1.1.1.5   root      336:     if (vidmodeavail)
                    337:        XF86VidModeSwitchToMode (display, screen, allmodes[0]);
1.1.1.3   root      338: #endif
                    339:     XF86DGADirectVideo (display, screen, 0);
                    340:     XUngrabPointer (display, CurrentTime);
                    341:     XUngrabKeyboard (display, CurrentTime);
                    342: }
                    343: #endif
1.1.1.5   root      344: 
1.1.1.3   root      345: static char *oldpixbuf;
1.1       root      346: 
1.1.1.5   root      347: void flush_line (int y)
1.1       root      348: {
1.1.1.5   root      349:     char *linebuf = gfxvidinfo.linemem;
                    350:     int xs, xe;
1.1.1.3   root      351:     int len;
1.1       root      352: 
1.1.1.3   root      353:     if (linebuf == NULL)
                    354:        linebuf = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
                    355: 
1.1.1.5   root      356: #ifdef USE_DGA_EXTENSION
                    357:     if (dgamode && need_dither) {
                    358:        DitherLine ((unsigned char *)(fb_addr + fb_width*y),
                    359:                    (uae_u16 *)linebuf, 0, y, gfxvidinfo.width, bit_unit);
                    360:        return;
                    361:     }
                    362: #endif
                    363:     xs = 0;
                    364:     xe = gfxvidinfo.width - 1;
1.1.1.3   root      365: 
1.1.1.6 ! root      366:     if (currprefs.x11_use_low_bandwidth) {
1.1.1.3   root      367:        char *src, *dst;
1.1.1.5   root      368:        switch (gfxvidinfo.pixbytes) {
1.1.1.3   root      369:         case 4:
                    370:            {
                    371:                uae_u32 *newp = (uae_u32 *)linebuf;
1.1.1.5   root      372:                uae_u32 *oldp = (uae_u32 *)((uae_u8 *)ami_dinfo.image_mem + y*ami_dinfo.ximg->bytes_per_line);
1.1.1.3   root      373:                while (newp[xs] == oldp[xs]) {
                    374:                    if (xs == xe)
                    375:                        return;
                    376:                    xs++;
                    377:                }
                    378:                while (newp[xe] == oldp[xe]) xe--;
                    379: 
                    380:                dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1       root      381:            }
1.1.1.3   root      382:            break;
                    383:         case 2:
                    384:            {
                    385:                uae_u16 *newp = (uae_u16 *)linebuf;
1.1.1.5   root      386:                uae_u16 *oldp = (uae_u16 *)((uae_u8 *)ami_dinfo.image_mem + y*ami_dinfo.ximg->bytes_per_line);
1.1.1.3   root      387:                while (newp[xs] == oldp[xs]) {
                    388:                    if (xs == xe)
                    389:                        return;
                    390:                    xs++;
                    391:                }
                    392:                while (newp[xe] == oldp[xe]) xe--;
                    393: 
                    394:                dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1       root      395:            }
1.1.1.3   root      396:            break;
                    397:         case 1:
                    398:            {
                    399:                uae_u8 *newp = (uae_u8 *)linebuf;
1.1.1.5   root      400:                uae_u8 *oldp = (uae_u8 *)((uae_u8 *)ami_dinfo.image_mem + y*ami_dinfo.ximg->bytes_per_line);
1.1.1.3   root      401:                while (newp[xs] == oldp[xs]) {
                    402:                    if (xs == xe)
                    403:                        return;
                    404:                    xs++;
                    405:                }
                    406:                while (newp[xe] == oldp[xe]) xe--;
1.1       root      407: 
1.1.1.3   root      408:                dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1       root      409:            }
1.1.1.3   root      410:            break;
1.1       root      411: 
1.1.1.3   root      412:         default:
1.1.1.5   root      413:            abort ();
1.1.1.3   root      414:            break;
1.1       root      415:        }
                    416: 
                    417:        len = xe - xs + 1;
1.1.1.3   root      418:        memcpy (dst, src, len * gfxvidinfo.pixbytes);
                    419:     } else if (need_dither) {
1.1.1.5   root      420:        uae_u8 *target = (uae_u8 *)ami_dinfo.image_mem + ami_dinfo.ximg->bytes_per_line * y;
1.1.1.3   root      421:        len = currprefs.gfx_width;
1.1.1.5   root      422:        DitherLine (target, (uae_u16 *)linebuf, 0, y, gfxvidinfo.width, bit_unit);
1.1.1.3   root      423:     } else {
1.1.1.5   root      424:        fprintf (stderr, "Bug!\n");
1.1.1.3   root      425:        abort();
1.1       root      426:     }
1.1.1.2   root      427: 
1.1.1.5   root      428:     DO_PUTIMAGE (ami_dinfo.ximg, xs, y, xs, y, len, 1);
1.1       root      429: }
                    430: 
                    431: void flush_block (int ystart, int ystop)
                    432: {
1.1.1.5   root      433:     if (dgamode)
                    434:        return;
1.1.1.3   root      435: 
1.1.1.5   root      436:     DO_PUTIMAGE (ami_dinfo.ximg, 0, ystart, 0, ystart, gfxvidinfo.width, ystop - ystart + 1);
1.1       root      437: }
                    438: 
                    439: void flush_screen (int ystart, int ystop)
                    440: {
1.1.1.5   root      441:     if (dgamode)
                    442:        return;
                    443: 
1.1.1.3   root      444: #if SHM_SUPPORT_LINKS == 1
1.1.1.6 ! root      445:     if (currprefs.x11_use_mitshm)
1.1.1.5   root      446:        XSync (display, 0);
1.1.1.2   root      447: #endif
1.1       root      448: }
                    449: 
1.1.1.5   root      450: static __inline__ int bitsInMask (unsigned long mask)
1.1       root      451: {
                    452:     /* count bits in mask */
                    453:     int n = 0;
1.1.1.5   root      454:     while (mask) {
                    455:        n += mask & 1;
1.1       root      456:        mask >>= 1;
                    457:     }
                    458:     return n;
                    459: }
                    460: 
1.1.1.5   root      461: static __inline__ int maskShift (unsigned long mask)
1.1       root      462: {
                    463:     /* determine how far mask is shifted */
                    464:     int n = 0;
1.1.1.5   root      465:     while (!(mask & 1)) {
1.1       root      466:        n++;
                    467:        mask >>= 1;
                    468:     }
                    469:     return n;
                    470: }
                    471: 
1.1.1.3   root      472: static unsigned long pixel_return[256];
                    473: static XColor parsed_xcolors[256];
                    474: static int ncolors = 0;
                    475: 
                    476: static int blackval = 32767;
                    477: static int whiteval = 0;
                    478: 
1.1.1.5   root      479: static int get_color (int r, int g, int b, xcolnr *cnp)
1.1       root      480: {
1.1.1.3   root      481:     XColor *col = parsed_xcolors + ncolors;
1.1       root      482:     char str[10];
1.1.1.3   root      483: 
1.1.1.5   root      484:     sprintf (str, "rgb:%x/%x/%x", r, g, b);
                    485:     XParseColor (display, cmap, str, col);
1.1.1.3   root      486:     *cnp = col->pixel = pixel_return[ncolors];
                    487:     XStoreColor (display, cmap, col);
                    488:     XStoreColor (display, cmap2, col);
                    489: 
                    490:     if (r + g + b < blackval)
                    491:        blackval = r + g + b, black = *col;
                    492:     if (r + g + b > whiteval)
                    493:        whiteval = r + g + b, white = *col;
                    494: 
                    495:     ncolors++;
                    496:     return 1;
1.1       root      497: }
                    498: 
1.1.1.5   root      499: static int init_colors (void)
1.1       root      500: {
1.1.1.3   root      501:     int i;
                    502: 
1.1.1.5   root      503:     if (visualInfo.VI_CLASS == TrueColor) {
                    504:        red_bits = bitsInMask (visualInfo.red_mask);
                    505:        green_bits = bitsInMask (visualInfo.green_mask);
                    506:        blue_bits = bitsInMask (visualInfo.blue_mask);
                    507:        red_shift = maskShift (visualInfo.red_mask);
                    508:        green_shift = maskShift (visualInfo.green_mask);
                    509:        blue_shift = maskShift (visualInfo.blue_mask);
                    510:     }
                    511: 
1.1       root      512:     if (need_dither) {
                    513:        if (bitdepth == 1)
                    514:            setup_greydither (1, get_color);
                    515:        else
                    516:            setup_dither (bitdepth, get_color);
1.1.1.3   root      517:     } else {
                    518:        if (bitdepth != 8 && bitdepth != 12 && bitdepth != 15
                    519:            && bitdepth != 16 && bitdepth != 24) {
1.1.1.5   root      520:            fprintf (stderr, "Unsupported bit depth (%d)\n", bitdepth);
1.1.1.3   root      521:            return 0;
1.1       root      522:        }
                    523: 
1.1.1.3   root      524:        switch (visualInfo.VI_CLASS) {
                    525:         case TrueColor:
1.1.1.5   root      526:            alloc_colors64k (red_bits, green_bits, blue_bits, red_shift,
                    527:                             green_shift, blue_shift);
                    528: 
                    529:            XParseColor (display, cmap, "#000000", &black);
                    530:            if (! XAllocColor (display, cmap, &black))
                    531:                fprintf (stderr, "Whoops??\n");
                    532:            XParseColor (display, cmap, "#ffffff", &white);
                    533:            if (! XAllocColor (display, cmap, &white))
                    534:                fprintf (stderr, "Whoops??\n");
1.1.1.3   root      535:            break;
                    536: 
                    537:         case GrayScale:
                    538:         case PseudoColor:
1.1.1.5   root      539:            alloc_colors256 (get_color);
1.1.1.3   root      540:            break;
                    541: 
                    542:         default:
                    543:            fprintf (stderr, "Unsupported visual class (%d)\n", visualInfo.VI_CLASS);
                    544:            return 0;
                    545:        }
                    546:     }
                    547:     switch (gfxvidinfo.pixbytes) {
                    548:      case 2:
                    549:        for (i = 0; i < 4096; i++)
                    550:            xcolors[i] = xcolors[i] * 0x00010001;
                    551:        gfxvidinfo.can_double = 1;
                    552:        break;
                    553:      case 1:
                    554:        for (i = 0; i < 4096; i++)
                    555:            xcolors[i] = xcolors[i] * 0x01010101;
                    556:        gfxvidinfo.can_double = 1;
1.1       root      557:        break;
                    558:      default:
1.1.1.3   root      559:        gfxvidinfo.can_double = 0;
                    560:        break;
1.1       root      561:     }
1.1.1.5   root      562:     if (inverse_byte_order)
                    563:        switch (gfxvidinfo.pixbytes) {
1.1.1.3   root      564:         case 4:
                    565:            for(i = 0; i < 4096; i++)
                    566:                xcolors[i] = ((((xcolors[i]>>0)&255) << 24)
                    567:                              | (((xcolors[i]>>8)&255) << 16)
                    568:                              | (((xcolors[i]>>16)&255) << 8)
                    569:                              | (((xcolors[i]>>24)&255) << 0));
                    570:            break;
                    571:         case 2:
                    572:            for (i = 0; i < 4096; i++)
                    573:                xcolors[i] = (xcolors[i]>>8) | ((xcolors[i]&255)<<8);
                    574:            break;
                    575:         default:
                    576:            break;
                    577:        }
1.1       root      578:     return 1;
                    579: }
                    580: 
1.1.1.5   root      581: static int dga_available (void)
1.1       root      582: {
1.1.1.2   root      583: #ifdef USE_DGA_EXTENSION
                    584:     int MajorVersion, MinorVersion;
                    585:     int EventBase, ErrorBase;
1.1.1.3   root      586: 
1.1.1.5   root      587:     if (! XF86DGAQueryVersion (display, &MajorVersion, &MinorVersion)) {
                    588:        fprintf (stderr, "Unable to query video extension version\n");
1.1.1.3   root      589:        return 0;
1.1.1.2   root      590:     }
1.1.1.5   root      591:     if (! XF86DGAQueryExtension (display, &EventBase, &ErrorBase)) {
                    592:        fprintf (stderr, "Unable to query video extension information\n");
1.1.1.3   root      593:        return 0;
1.1.1.2   root      594:     }
                    595:     /* Fail if the extension version in the server is too old */
1.1.1.5   root      596:     if (MajorVersion < DGA_MINMAJOR
                    597:        || (MajorVersion == DGA_MINMAJOR && MinorVersion < DGA_MINMINOR))
                    598:     {
1.1.1.3   root      599:        fprintf (stderr,
                    600:                 "Xserver is running an old XFree86-DGA version"
                    601:                 " (%d.%d)\n", MajorVersion, MinorVersion);
                    602:        fprintf (stderr, "Minimum required version is %d.%d\n",
1.1.1.5   root      603:                 DGA_MINMAJOR, DGA_MINMINOR);
                    604:        return 0;
                    605:     }
                    606:     if (geteuid () != 0) {
                    607:        fprintf (stderr, "UAE is not running as root, DGA extension disabled.\n");
                    608:        return 0;
                    609:     }
                    610:     if (! XF86DGAGetVideo (display, screen, &fb_addr, &fb_width, &fb_bank, &fb_mem)
                    611:        || fb_bank < fb_mem)
                    612:     {
                    613:        fprintf (stderr, "Problems with DGA - disabling DGA extension.\n");
1.1.1.3   root      614:        return 0;
                    615:     }
1.1.1.5   root      616:     fprintf (stderr, "DGA extension: addr:%X, width %d, bank size %d mem size %d\n",
                    617:             fb_addr, fb_width, fb_bank, fb_mem);
                    618: 
                    619:     return 1;
                    620: #else
                    621:     return 0;
                    622: #endif
                    623: }
                    624: 
                    625: static int vid_mode_available (void)
                    626: {
1.1.1.3   root      627: #ifdef USE_VIDMODE_EXTENSION
1.1.1.5   root      628:     int MajorVersion, MinorVersion;
                    629:     int EventBase, ErrorBase;
                    630: 
                    631:     if (! dgaavail)
                    632:        return 0;
                    633:     if (! XF86VidModeQueryVersion (display, &MajorVersion, &MinorVersion)) {
1.1.1.3   root      634:        fprintf (stderr, "Unable to query video extension version\n");
                    635:        return 0;
                    636:     }
1.1.1.5   root      637:     if (! XF86VidModeQueryExtension (display, &EventBase, &ErrorBase)) {
1.1.1.3   root      638:        fprintf (stderr, "Unable to query video extension information\n");
                    639:        return 0;
                    640:     }
1.1.1.5   root      641:     if (MajorVersion < VidMode_MINMAJOR
                    642:        || (MajorVersion == VidMode_MINMAJOR && MinorVersion < VidMode_MINMINOR)) {
                    643:        /* Fail if the extension version in the server is too old */
                    644:        fprintf (stderr, "Xserver is running an old XFree86-VidMode version (%d.%d)\n",
                    645:                 MajorVersion, MinorVersion);
1.1.1.3   root      646:        fprintf (stderr, "Minimum required version is %d.%d\n",
                    647:                 VidMode_MINMAJOR, VidMode_MINMINOR);
                    648:        return 0;
                    649:     }
1.1.1.5   root      650:     if (! get_vidmodes ()) {
1.1.1.3   root      651:        fprintf (stderr, "Error getting video mode information\n");
                    652:        return 0;
1.1.1.2   root      653:     }
1.1.1.5   root      654:     return 1;
                    655: #else
                    656:     return 0;
1.1.1.2   root      657: #endif
1.1.1.5   root      658: }
                    659: 
                    660: static int shm_available (void)
                    661: {
                    662: #if SHM_SUPPORT_LINKS == 1
                    663:     if (XShmQueryExtension (display))
                    664:        return 1;
1.1.1.3   root      665: #endif
1.1.1.5   root      666:     return 0;
                    667: }
                    668: 
                    669: int graphics_setup (void)
                    670: {
                    671:     char *display_name = 0;
                    672: 
                    673:     display = XOpenDisplay (display_name);
                    674:     if (display == 0)  {
                    675:        fprintf (stderr, "Can't connect to X server %s\n", XDisplayName (display_name));
                    676:        return 0;
                    677:     }
                    678: 
                    679:     shmavail = shm_available ();
                    680:     dgaavail = dga_available ();
                    681:     vidmodeavail = vid_mode_available ();
1.1.1.3   root      682: 
                    683:     {
                    684:        int local_byte_order;
                    685:        int x = 0x04030201;
                    686:        char *y=(char*)&x;
                    687: 
                    688:        local_byte_order = y[0] == 0x04 ? MSBFirst : LSBFirst;
                    689:        if (ImageByteOrder(display) != local_byte_order)
                    690:            inverse_byte_order = 1;
                    691:     }
                    692: 
                    693:     return 1;
                    694: }
                    695: 
1.1.1.5   root      696: static void lock_window_size (void)
1.1.1.3   root      697: {
1.1.1.5   root      698:     XSizeHints hint;
1.1.1.3   root      699: 
1.1.1.5   root      700:     hint.flags  = PMinSize | PMaxSize;
                    701:     hint.min_width = current_width;
                    702:     hint.min_height = current_height;
                    703:     hint.max_width = current_width;
                    704:     hint.max_height = current_height;
                    705:     XSetWMNormalHints (display, mywin, &hint);
1.1.1.3   root      706: }
                    707: 
1.1.1.5   root      708: static void init_dispinfo (struct disp_info *disp)
                    709: {
                    710: #if SHM_SUPPORT_LINKS == 1
                    711:     disp->shminfo.shmid = -1;
                    712: #endif
                    713:     disp->ximg = 0;
                    714: }
                    715: 
                    716: static void graphics_subinit (void)
1.1.1.3   root      717: {
1.1.1.6 ! root      718:     int i, j;
1.1.1.3   root      719:     XSetWindowAttributes wattr;
1.1.1.5   root      720:     unsigned long valuemask;
                    721: 
                    722:     dgamode = screen_is_picasso ? currprefs.gfx_pfullscreen : currprefs.gfx_afullscreen;
                    723:     dgamode = dgamode && dgaavail;
                    724: 
                    725:     wattr.background_pixel = /*black.pixel*/0;
                    726:     wattr.backing_store = Always;
                    727:     wattr.backing_planes = bitdepth;
                    728:     wattr.border_pixmap = None;
                    729:     wattr.border_pixel = /*black.pixel*/0;
                    730:     wattr.colormap = cmap;
                    731:     valuemask = (CWEventMask | CWBackPixel | CWBorderPixel
                    732:                 | CWBackingStore | CWBackingPlanes | CWColormap);
                    733: 
                    734:     if (dgamode) {
                    735:        wattr.event_mask = DGA_EVENTMASK;
                    736:        wattr.override_redirect = 1;
                    737:        valuemask |= CWOverrideRedirect;
                    738:     } else
                    739:        wattr.event_mask = EVENTMASK;
                    740: 
                    741:     XSync (display, 0);
                    742:     mywin = XCreateWindow (display, rootwin, 0, 0, current_width, current_height,
                    743:                           0, bitdepth, InputOutput, vis, valuemask, &wattr);
                    744:     XSync (display, 0);
                    745: 
                    746:     XStoreName (display, mywin, "UAE");
                    747:     XMapRaised (display, mywin);
                    748:     XSync (display, 0);
                    749:     mygc = XCreateGC (display, mywin, 0, 0);
                    750: 
                    751:     if (dgamode) {
                    752: #ifdef USE_DGA_EXTENSION
                    753:        enter_dga_mode ();
                    754:        /*setuid(getuid());*/
                    755:        picasso_vidinfo.rowbytes = fb_width * picasso_vidinfo.pixbytes;
                    756: #endif
                    757:     } else {
                    758:        get_image (current_width, current_height, &ami_dinfo);
                    759:        if (screen_is_picasso) {
                    760:            get_image (current_width, current_height, &pic_dinfo);
                    761:            picasso_vidinfo.rowbytes = pic_dinfo.ximg->bytes_per_line;
                    762:        }
                    763:     }
                    764: 
                    765:     picasso_vidinfo.extra_mem = 1;
                    766: 
                    767:     if (need_dither) {
                    768:        gfxvidinfo.maxblocklines = 0;
                    769:        gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * currprefs.gfx_width;
                    770:        gfxvidinfo.linemem = (char *)malloc (gfxvidinfo.rowbytes);
                    771:     } else if (! dgamode) {
                    772:        gfxvidinfo.emergmem = 0;
                    773:        gfxvidinfo.linemem = 0;
                    774:        gfxvidinfo.bufmem = ami_dinfo.image_mem;
                    775:        gfxvidinfo.rowbytes = ami_dinfo.ximg->bytes_per_line;
1.1.1.6 ! root      776:        if (currprefs.x11_use_low_bandwidth) {
1.1.1.5   root      777:            gfxvidinfo.maxblocklines = 0;
                    778:            gfxvidinfo.rowbytes = ami_dinfo.ximg->bytes_per_line;
                    779:            gfxvidinfo.linemem = (char *)malloc (gfxvidinfo.rowbytes);
                    780:        } else {
                    781:            gfxvidinfo.maxblocklines = 100; /* whatever... */
                    782:        }
                    783:     }
                    784: 
                    785:     if (visualInfo.VI_CLASS != TrueColor && ! screen_is_picasso) {
                    786:        int i;
                    787:        for (i = 0; i < 256; i++)
                    788:            XStoreColor (display, cmap, parsed_xcolors + i);
                    789:     }
                    790: 
                    791: #ifdef USE_DGA_EXTENSION
                    792:     if (dgamode) {
                    793:        dga_colormap_installed = 0;
                    794:        XF86DGAInstallColormap (display, screen, cmap2);
                    795:        XF86DGAInstallColormap (display, screen, cmap);
                    796:     }
                    797: #endif
                    798: 
                    799:     if (! dgamode) {
1.1.1.6 ! root      800:        if (! currprefs.x11_hide_cursor)
1.1.1.5   root      801:            XDefineCursor (display, mywin, xhairCursor);
                    802:        else
                    803:            XDefineCursor (display, mywin, blankCursor);
                    804:        cursorOn = 1;
                    805:     }
                    806: 
                    807:     if (screen_is_picasso) {
                    808:        picasso_has_invalid_lines = 0;
                    809:        picasso_invalid_start = picasso_vidinfo.height + 1;
                    810:        picasso_invalid_stop = -1;
                    811:        memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines);
                    812:     }
1.1.1.6 ! root      813: 
        !           814:     lastmx = lastmy = 0;
        !           815:     newmousecounters = 0;
        !           816:     inwindow = 0;
        !           817:     for (i = 0; hotkeys[i].syms[0] != 0; i++) {
        !           818:        hotkeys[i].mask = 0;
        !           819:        for (j = 0; hotkeys[i].syms[j] != 0; j++)
        !           820:            hotkeys[i].mask |= (1 << j);
        !           821:     }
1.1.1.5   root      822: }
                    823: 
                    824: int graphics_init (void)
                    825: {
                    826:     int i,j;
1.1.1.3   root      827:     XPixmapFormatValues *xpfvs;
                    828: 
1.1.1.6 ! root      829:     if (currprefs.x11_use_mitshm && ! shmavail) {
1.1.1.5   root      830:        fprintf (stderr, "MIT-SHM extension not supported by X server.\n");
                    831:     }
1.1.1.3   root      832:     if (currprefs.color_mode > 5)
1.1.1.5   root      833:        fprintf (stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
1.1.1.3   root      834: 
                    835:     x11_init_ok = 0;
                    836:     need_dither = 0;
                    837:     screen_is_picasso = 0;
1.1.1.5   root      838:     dgamode = 0;
                    839: 
                    840:     init_dispinfo (&ami_dinfo);
                    841:     init_dispinfo (&pic_dinfo);
1.1.1.3   root      842: 
1.1.1.5   root      843:     screen = XDefaultScreen (display);
                    844:     rootwin = XRootWindow (display, screen);
1.1.1.3   root      845: 
1.1       root      846:     /* try for a 12 bit visual first, then a 16 bit, then a 24 bit, then 8 bit */
1.1.1.5   root      847:     if (XMatchVisualInfo (display, screen, 12, TrueColor, &visualInfo)) {
                    848:     } else if (XMatchVisualInfo (display, screen, 15, TrueColor, &visualInfo)) {
                    849:     } else if (XMatchVisualInfo (display, screen, 16, TrueColor, &visualInfo)) {
                    850:     } else if (XMatchVisualInfo (display, screen, 24, TrueColor, &visualInfo)) {
                    851:     } else if (XMatchVisualInfo (display, screen, 8, PseudoColor, &visualInfo)) {
1.1       root      852:        /* for our HP boxes */
1.1.1.5   root      853:     } else if (XMatchVisualInfo (display, screen, 8, GrayScale, &visualInfo)) {
                    854:     } else if (XMatchVisualInfo (display, screen, 4, PseudoColor, &visualInfo)) {
1.1       root      855:        /* VGA16 server. Argh. */
1.1.1.5   root      856:     } else if (XMatchVisualInfo (display, screen, 1, StaticGray, &visualInfo)) {
1.1       root      857:        /* Mono server. Yuk */
                    858:     } else {
1.1.1.5   root      859:        fprintf (stderr, "Can't obtain appropriate X visual.\n");
1.1       root      860:        return 0;
                    861:     }
                    862:     vis = visualInfo.visual;
                    863:     bitdepth = visualInfo.depth;
1.1.1.3   root      864: 
1.1       root      865:     /* We now have the bitdepth of the display, but that doesn't tell us yet
                    866:      * how many bits to use per pixel. The VGA16 server has a bitdepth of 4,
                    867:      * but uses 1 byte per pixel. */
1.1.1.5   root      868:     xpfvs = XListPixmapFormats (display, &i);
                    869:     for (j = 0; j < i && xpfvs[j].depth != bitdepth; j++)
1.1       root      870:        ;
1.1.1.5   root      871:     if (j < i)
                    872:        bit_unit = xpfvs[j].bits_per_pixel;
                    873:     XFree (xpfvs);
1.1       root      874:     if (j == i) {
1.1.1.5   root      875:        fprintf (stderr, "Your X server is feeling ill.\n");
1.1       root      876:        return 0;
                    877:     }
1.1.1.3   root      878: 
1.1.1.5   root      879:     fprintf (stderr, "Using %d bit visual, %d bits per pixel\n", bitdepth, bit_unit);
1.1       root      880: 
1.1.1.5   root      881:     fixup_prefs_dimensions (&currprefs);
1.1.1.2   root      882: 
1.1.1.3   root      883:     gfxvidinfo.width = currprefs.gfx_width;
                    884:     gfxvidinfo.height = currprefs.gfx_height;
                    885:     current_width = currprefs.gfx_width;
                    886:     current_height = currprefs.gfx_height;
1.1.1.5   root      887:     
                    888:     cmap = XCreateColormap (display, rootwin, vis, AllocNone);
                    889:     cmap2 = XCreateColormap (display, rootwin, vis, AllocNone);
                    890:     if (visualInfo.VI_CLASS == GrayScale || visualInfo.VI_CLASS == PseudoColor) {
                    891:        XAllocColorCells (display, cmap, 0, 0, 0, pixel_return, 1 << bitdepth);
                    892:        XAllocColorCells (display, cmap2, 0, 0, 0, pixel_return, 1 << bitdepth);
                    893:     }
1.1.1.3   root      894: 
                    895:     if (bitdepth < 8 || (bitdepth == 8 && currprefs.color_mode == 3)) {
1.1       root      896:        gfxvidinfo.pixbytes = 2;
1.1.1.6 ! root      897:        currprefs.x11_use_low_bandwidth = 0;
1.1       root      898:        need_dither = 1;
                    899:     } else {
1.1.1.3   root      900:        gfxvidinfo.pixbytes = bit_unit >> 3;
1.1       root      901:     }
1.1.1.2   root      902: 
1.1.1.5   root      903:     if (! init_colors ())
1.1       root      904:        return 0;
                    905: 
1.1.1.5   root      906:     blankCursor = XCreatePixmapCursor (display,
                    907:                                       XCreatePixmap (display, rootwin, 1, 1, 1),
                    908:                                       XCreatePixmap (display, rootwin, 1, 1, 1),
                    909:                                       &black, &white, 0, 0);
                    910:     xhairCursor = XCreateFontCursor (display, XC_crosshair);
1.1.1.3   root      911: 
1.1.1.5   root      912:     graphics_subinit ();
1.1.1.3   root      913: 
1.1       root      914:     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
1.1.1.5   root      915:     for (i = 0; i < 256; i++)
1.1       root      916:        keystate[i] = 0;
1.1.1.5   root      917:     grabbed = 0;
1.1.1.3   root      918: 
1.1.1.2   root      919:     return x11_init_ok = 1;
1.1       root      920: }
                    921: 
1.1.1.5   root      922: static void destroy_dinfo (struct disp_info *dinfo)
1.1       root      923: {
1.1.1.5   root      924:     if (dinfo->ximg == NULL)
1.1.1.2   root      925:        return;
1.1.1.5   root      926: #if SHM_SUPPORT_LINKS == 1
                    927:     if (dinfo->shminfo.shmid != -1)
                    928:        shmdt (dinfo->shminfo.shmaddr);
                    929:     dinfo->shminfo.shmid = -1;
                    930: #endif
                    931:     XDestroyImage (dinfo->ximg);
                    932:     dinfo->ximg = NULL;
                    933: }
1.1.1.3   root      934: 
1.1.1.5   root      935: static void graphics_subshutdown (void)
                    936: {
                    937:     XSync (display, 0);
1.1.1.2   root      938: #ifdef USE_DGA_EXTENSION
1.1.1.5   root      939:     if (dgamode)
                    940:        leave_dga_mode ();
1.1.1.2   root      941: #endif
1.1.1.5   root      942: 
                    943:     destroy_dinfo (&ami_dinfo);
                    944:     destroy_dinfo (&pic_dinfo);
                    945: 
                    946:     XDestroyWindow (display, mywin);
                    947: 
                    948:     if (gfxvidinfo.linemem != NULL)
                    949:        free (gfxvidinfo.linemem);
                    950:     if (gfxvidinfo.emergmem != NULL)
                    951:        free (gfxvidinfo.emergmem);
                    952: }
                    953: 
                    954: void graphics_leave (void)
                    955: {
                    956:     if (! x11_init_ok)
                    957:        return;
                    958: 
                    959:     graphics_subshutdown ();
                    960:     
                    961:     if (autorepeatoff)
                    962:        XAutoRepeatOn (display);
                    963: 
                    964:     XFlush (display);
                    965:     XSync (display, 0);
                    966: 
                    967:     XFreeColormap (display, cmap);
                    968:     XFreeColormap (display, cmap2);
                    969: 
                    970:     XCloseDisplay (display);
                    971:     dumpcustom ();
1.1       root      972: }
                    973: 
1.1.1.3   root      974: /* Decode KeySyms. This function knows about all keys that are common
1.1       root      975:  * between different keyboard languages. */
                    976: static int kc_decode (KeySym ks)
                    977: {
1.1.1.3   root      978:     switch (ks) {
1.1       root      979:      case XK_B: case XK_b: return AK_B;
                    980:      case XK_C: case XK_c: return AK_C;
                    981:      case XK_D: case XK_d: return AK_D;
                    982:      case XK_E: case XK_e: return AK_E;
                    983:      case XK_F: case XK_f: return AK_F;
                    984:      case XK_G: case XK_g: return AK_G;
                    985:      case XK_H: case XK_h: return AK_H;
                    986:      case XK_I: case XK_i: return AK_I;
                    987:      case XK_J: case XK_j: return AK_J;
                    988:      case XK_K: case XK_k: return AK_K;
                    989:      case XK_L: case XK_l: return AK_L;
                    990:      case XK_N: case XK_n: return AK_N;
                    991:      case XK_O: case XK_o: return AK_O;
                    992:      case XK_P: case XK_p: return AK_P;
                    993:      case XK_R: case XK_r: return AK_R;
                    994:      case XK_S: case XK_s: return AK_S;
                    995:      case XK_T: case XK_t: return AK_T;
                    996:      case XK_U: case XK_u: return AK_U;
                    997:      case XK_V: case XK_v: return AK_V;
                    998:      case XK_X: case XK_x: return AK_X;
1.1.1.3   root      999: 
1.1       root     1000:      case XK_0: return AK_0;
                   1001:      case XK_1: return AK_1;
                   1002:      case XK_2: return AK_2;
                   1003:      case XK_3: return AK_3;
                   1004:      case XK_4: return AK_4;
                   1005:      case XK_5: return AK_5;
                   1006:      case XK_6: return AK_6;
                   1007:      case XK_7: return AK_7;
                   1008:      case XK_8: return AK_8;
                   1009:      case XK_9: return AK_9;
1.1.1.3   root     1010: 
1.1       root     1011:        /* You never know which Keysyms might be missing on some workstation
                   1012:         * This #ifdef should be enough. */
                   1013: #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End)
                   1014:      case XK_KP_0: case XK_KP_Insert: return AK_NP0;
                   1015:      case XK_KP_1: case XK_KP_End: return AK_NP1;
                   1016:      case XK_KP_2: case XK_KP_Down: return AK_NP2;
                   1017:      case XK_KP_3: case XK_KP_Next: return AK_NP3;
                   1018:      case XK_KP_4: case XK_KP_Left: return AK_NP4;
                   1019:      case XK_KP_5: case XK_KP_Begin: return AK_NP5;
                   1020:      case XK_KP_6: case XK_KP_Right: return AK_NP6;
                   1021:      case XK_KP_7: case XK_KP_Home: return AK_NP7;
                   1022:      case XK_KP_8: case XK_KP_Up: return AK_NP8;
                   1023:      case XK_KP_9: case XK_KP_Prior: return AK_NP9;
                   1024: #else
                   1025:      case XK_KP_0: return AK_NP0;
                   1026:      case XK_KP_1: return AK_NP1;
                   1027:      case XK_KP_2: return AK_NP2;
                   1028:      case XK_KP_3: return AK_NP3;
                   1029:      case XK_KP_4: return AK_NP4;
                   1030:      case XK_KP_5: return AK_NP5;
                   1031:      case XK_KP_6: return AK_NP6;
                   1032:      case XK_KP_7: return AK_NP7;
                   1033:      case XK_KP_8: return AK_NP8;
                   1034:      case XK_KP_9: return AK_NP9;
                   1035: #endif
                   1036:      case XK_KP_Divide: return AK_NPDIV;
                   1037:      case XK_KP_Multiply: return AK_NPMUL;
                   1038:      case XK_KP_Subtract: return AK_NPSUB;
                   1039:      case XK_KP_Add: return AK_NPADD;
                   1040:      case XK_KP_Decimal: return AK_NPDEL;
                   1041:      case XK_KP_Enter: return AK_ENT;
                   1042: 
                   1043:      case XK_F1: return AK_F1;
                   1044:      case XK_F2: return AK_F2;
                   1045:      case XK_F3: return AK_F3;
                   1046:      case XK_F4: return AK_F4;
                   1047:      case XK_F5: return AK_F5;
                   1048:      case XK_F6: return AK_F6;
                   1049:      case XK_F7: return AK_F7;
                   1050:      case XK_F8: return AK_F8;
                   1051:      case XK_F9: return AK_F9;
                   1052:      case XK_F10: return AK_F10;
1.1.1.3   root     1053: 
1.1       root     1054:      case XK_BackSpace: return AK_BS;
                   1055:      case XK_Delete: return AK_DEL;
1.1.1.3   root     1056:      case XK_Control_L: return AK_CTRL;
                   1057:      case XK_Control_R: return AK_RCTRL;
1.1       root     1058:      case XK_Tab: return AK_TAB;
                   1059:      case XK_Alt_L: return AK_LALT;
                   1060:      case XK_Alt_R: return AK_RALT;
                   1061:      case XK_Meta_R: case XK_Hyper_R: return AK_RAMI;
                   1062:      case XK_Meta_L: case XK_Hyper_L: return AK_LAMI;
                   1063:      case XK_Return: return AK_RET;
                   1064:      case XK_space: return AK_SPC;
                   1065:      case XK_Shift_L: return AK_LSH;
                   1066:      case XK_Shift_R: return AK_RSH;
                   1067:      case XK_Escape: return AK_ESC;
                   1068: 
1.1.1.3   root     1069:      case XK_Insert: return AK_HELP;
                   1070:      case XK_Home: return AK_NPLPAREN;
                   1071:      case XK_End: return AK_NPRPAREN;
1.1       root     1072:      case XK_Caps_Lock: return AK_CAPSLOCK;
1.1.1.3   root     1073: 
1.1       root     1074:      case XK_Up: return AK_UP;
                   1075:      case XK_Down: return AK_DN;
                   1076:      case XK_Left: return AK_LF;
                   1077:      case XK_Right: return AK_RT;
1.1.1.3   root     1078: 
1.1       root     1079:      case XK_F11: return AK_BACKSLASH;
                   1080: #ifdef XK_Page_Up /* These are missing occasionally */
                   1081:      case XK_Page_Up: return AK_RAMI;          /* PgUp mapped to right amiga */
                   1082:      case XK_Page_Down: return AK_LAMI;        /* PgDn mapped to left amiga */
                   1083: #endif
                   1084:     }
                   1085:     return -1;
                   1086: }
                   1087: 
1.1.1.5   root     1088: static int decode_fr (KeySym ks)
1.1       root     1089: {
                   1090:     switch(ks) {        /* FR specific */
                   1091:      case XK_A: case XK_a: return AK_Q;
1.1.1.3   root     1092:      case XK_M: case XK_m: return AK_SEMICOLON;
                   1093:      case XK_Q: case XK_q: return AK_A;
1.1       root     1094:      case XK_Y: case XK_y: return AK_Y;
1.1.1.2   root     1095:      case XK_W: case XK_w: return AK_Z;
                   1096:      case XK_Z: case XK_z: return AK_W;
1.1.1.6 ! root     1097: #if 0
1.1       root     1098:      case XK_bracketleft: return AK_LBRACKET;
                   1099:      case XK_bracketright: return AK_RBRACKET;
                   1100:      case XK_comma: return AK_M;
                   1101:      case XK_less: case XK_greater: return AK_LTGT;
                   1102:      case XK_period: return AK_COMMA;
                   1103:      case XK_parenright: return AK_MINUS;
                   1104:      case XK_equal: return AK_SLASH;
                   1105:      case XK_numbersign: return AK_NUMBERSIGN;
                   1106:      case XK_slash: return AK_PERIOD;
                   1107:      case XK_minus: return AK_EQUAL;
                   1108:      case XK_backslash: return AK_BACKSLASH;
1.1.1.6 ! root     1109: #else
        !          1110:      /* not sure for this one: my X 3.3 server doesn't handle this key always
        !          1111:       * correctly... But anyway, on new french keyboards, no more bracket key
        !          1112:       * at this place. 
        !          1113:       */
        !          1114:      case XK_dead_circumflex:
        !          1115:      case XK_dead_diaeresis: return AK_LBRACKET;
        !          1116:      case XK_dollar:
        !          1117:      case XK_sterling: return AK_RBRACKET;
        !          1118:      case XK_comma: case XK_question: return AK_M;
        !          1119:      case XK_less: case XK_greater: return AK_LTGT;
        !          1120:      case XK_semicolon: case XK_period: return AK_COMMA;
        !          1121:      case XK_parenright: case XK_degree: return AK_MINUS;
        !          1122:      case XK_equal: case XK_plus: return AK_SLASH;
        !          1123:      case XK_numbersign: return AK_NUMBERSIGN;
        !          1124:      case XK_colon: case XK_slash: return AK_PERIOD;
        !          1125:      case XK_minus: case XK_6: return AK_6;
        !          1126:      case XK_ugrave: case XK_percent: return AK_QUOTE;
        !          1127:      /* found a spare key - I hope it deserves this place. */
        !          1128:      case XK_asterisk: case XK_mu: return AK_BACKSLASH;
        !          1129:      case XK_exclam: case XK_section: return AK_EQUAL;
        !          1130:      case XK_twosuperior: case XK_asciitilde: return AK_BACKQUOTE;
        !          1131:      case XK_Multi_key: return AK_RAMI;
        !          1132:      case XK_Mode_switch: return AK_RALT;
        !          1133: #endif
1.1       root     1134:     }
                   1135: 
                   1136:     return -1;
                   1137: }
                   1138: 
1.1.1.5   root     1139: static int decode_us (KeySym ks)
1.1       root     1140: {
1.1.1.3   root     1141:     switch(ks) {       /* US specific */
1.1       root     1142:      case XK_A: case XK_a: return AK_A;
                   1143:      case XK_M: case XK_m: return AK_M;
                   1144:      case XK_Q: case XK_q: return AK_Q;
                   1145:      case XK_Y: case XK_y: return AK_Y;
1.1.1.2   root     1146:      case XK_W: case XK_w: return AK_W;
1.1       root     1147:      case XK_Z: case XK_z: return AK_Z;
                   1148:      case XK_bracketleft: return AK_LBRACKET;
                   1149:      case XK_bracketright: return AK_RBRACKET;
                   1150:      case XK_comma: return AK_COMMA;
                   1151:      case XK_period: return AK_PERIOD;
                   1152:      case XK_slash: return AK_SLASH;
                   1153:      case XK_semicolon: return AK_SEMICOLON;
                   1154:      case XK_minus: return AK_MINUS;
                   1155:      case XK_equal: return AK_EQUAL;
                   1156:        /* this doesn't work: */
                   1157:      case XK_quoteright: return AK_QUOTE;
                   1158:      case XK_quoteleft: return AK_BACKQUOTE;
                   1159:      case XK_backslash: return AK_BACKSLASH;
                   1160:     }
                   1161: 
                   1162:     return -1;
                   1163: }
                   1164: 
1.1.1.5   root     1165: static int decode_de (KeySym ks)
1.1       root     1166: {
                   1167:     switch(ks) {
                   1168:        /* DE specific */
                   1169:      case XK_A: case XK_a: return AK_A;
                   1170:      case XK_M: case XK_m: return AK_M;
                   1171:      case XK_Q: case XK_q: return AK_Q;
1.1.1.2   root     1172:      case XK_W: case XK_w: return AK_W;
1.1       root     1173:      case XK_Y: case XK_y: return AK_Z;
                   1174:      case XK_Z: case XK_z: return AK_Y;
                   1175:      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
                   1176:      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
                   1177:      case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
                   1178:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                   1179:      case XK_comma: return AK_COMMA;
                   1180:      case XK_period: return AK_PERIOD;
                   1181:      case XK_less: case XK_greater: return AK_LTGT;
                   1182:      case XK_numbersign: return AK_NUMBERSIGN;
                   1183:      case XK_ssharp: return AK_MINUS;
                   1184:      case XK_apostrophe: return AK_EQUAL;
                   1185:      case XK_asciicircum: return AK_BACKQUOTE;
                   1186:      case XK_minus: return AK_SLASH;
                   1187:     }
                   1188: 
                   1189:     return -1;
                   1190: }
                   1191: 
1.1.1.5   root     1192: static int decode_se (KeySym ks)
1.1       root     1193: {
                   1194:     switch(ks) {
                   1195:        /* SE specific */
                   1196:      case XK_A: case XK_a: return AK_A;
                   1197:      case XK_M: case XK_m: return AK_M;
                   1198:      case XK_Q: case XK_q: return AK_Q;
1.1.1.2   root     1199:      case XK_W: case XK_w: return AK_W;
1.1       root     1200:      case XK_Y: case XK_y: return AK_Y;
                   1201:      case XK_Z: case XK_z: return AK_Z;
                   1202:      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
                   1203:      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
                   1204:      case XK_Aring: case XK_aring: return AK_LBRACKET;
                   1205:      case XK_comma: return AK_COMMA;
                   1206:      case XK_period: return AK_PERIOD;
                   1207:      case XK_minus: return AK_SLASH;
                   1208:      case XK_less: case XK_greater: return AK_LTGT;
                   1209:      case XK_plus: case XK_question: return AK_EQUAL;
                   1210:      case XK_at: case XK_onehalf: return AK_BACKQUOTE;
                   1211:      case XK_asciitilde: case XK_asciicircum: return AK_RBRACKET;
                   1212:      case XK_backslash: case XK_bar: return AK_MINUS;
1.1.1.3   root     1213: 
1.1       root     1214:      case XK_numbersign: return AK_NUMBERSIGN;
                   1215:     }
                   1216: 
                   1217:     return -1;
                   1218:  }
                   1219: 
1.1.1.5   root     1220: static int decode_it (KeySym ks)
1.1       root     1221: {
                   1222:     switch(ks) {
                   1223:        /* IT specific */
                   1224:      case XK_A: case XK_a: return AK_A;
                   1225:      case XK_M: case XK_m: return AK_M;
                   1226:      case XK_Q: case XK_q: return AK_Q;
1.1.1.2   root     1227:      case XK_W: case XK_w: return AK_W;
1.1       root     1228:      case XK_Y: case XK_y: return AK_Y;
                   1229:      case XK_Z: case XK_z: return AK_Z;
                   1230:      case XK_Ograve: case XK_ograve: return AK_SEMICOLON;
                   1231:      case XK_Agrave: case XK_agrave: return AK_QUOTE;
                   1232:      case XK_Egrave: case XK_egrave: return AK_LBRACKET;
                   1233:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                   1234:      case XK_comma: return AK_COMMA;
                   1235:      case XK_period: return AK_PERIOD;
                   1236:      case XK_less: case XK_greater: return AK_LTGT;
1.1.1.3   root     1237:      case XK_backslash: case XK_bar: return AK_BACKQUOTE;
                   1238:      case XK_apostrophe: return AK_MINUS;
1.1       root     1239:      case XK_Igrave: case XK_igrave: return AK_EQUAL;
                   1240:      case XK_minus: return AK_SLASH;
                   1241:      case XK_numbersign: return AK_NUMBERSIGN;
                   1242:     }
                   1243: 
                   1244:     return -1;
                   1245: }
                   1246: 
1.1.1.5   root     1247: static int decode_es (KeySym ks)
1.1.1.2   root     1248: {
                   1249:     switch(ks) {
                   1250:        /* ES specific */
                   1251:      case XK_A: case XK_a: return AK_A;
                   1252:      case XK_M: case XK_m: return AK_M;
                   1253:      case XK_Q: case XK_q: return AK_Q;
                   1254:      case XK_W: case XK_w: return AK_W;
                   1255:      case XK_Y: case XK_y: return AK_Y;
                   1256:      case XK_Z: case XK_z: return AK_Z;
                   1257:      case XK_ntilde: case XK_Ntilde: return AK_SEMICOLON;
                   1258: #ifdef XK_dead_acute
                   1259:      case XK_dead_acute: case XK_dead_diaeresis: return AK_QUOTE;
                   1260:      case XK_dead_grave: case XK_dead_circumflex: return AK_LBRACKET;
                   1261: #endif
                   1262:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                   1263:      case XK_comma: return AK_COMMA;
                   1264:      case XK_period: return AK_PERIOD;
                   1265:      case XK_less: case XK_greater: return AK_LTGT;
1.1.1.3   root     1266:      case XK_backslash: case XK_bar: return AK_BACKQUOTE;
                   1267:      case XK_apostrophe: return AK_MINUS;
1.1.1.2   root     1268:      case XK_Igrave: case XK_igrave: return AK_EQUAL;
                   1269:      case XK_minus: return AK_SLASH;
                   1270:      case XK_numbersign: return AK_NUMBERSIGN;
                   1271:     }
                   1272: 
                   1273:     return -1;
                   1274: }
                   1275: 
1.1.1.5   root     1276: static int keycode2amiga (XKeyEvent *event)
1.1       root     1277: {
                   1278:     KeySym ks;
                   1279:     int as;
                   1280:     int index = 0;
1.1.1.3   root     1281: 
1.1       root     1282:     do {
1.1.1.5   root     1283:        int hkreturn = -1, returnnow = 0;
                   1284:        ks = XLookupKeysym (event, index);
                   1285:        if (event->type == KeyPress) {
                   1286:            int i, j;
                   1287:            for (i = 0; hotkeys[i].syms[0] != 0; i++) {
                   1288:                for (j = 0; hotkeys[i].syms[j] != 0; j++) {
                   1289:                    if (ks == hotkeys[i].syms[j]) {
                   1290:                        hotkeys[i].mask &= ~(1 << j);
                   1291:                        if (hotkeys[i].mask == 0) {
                   1292:                            returnnow = 1;
                   1293:                            hkreturn = hotkeys[i].retval;
                   1294:                        }
                   1295:                    }
                   1296:                }
                   1297:            }
                   1298:        } else {
                   1299:            int i, j;
                   1300:            for (i = 0; hotkeys[i].syms[0] != 0; i++) {
                   1301:                for (j = 0; hotkeys[i].syms[j] != 0; j++) {
                   1302:                    if (ks == hotkeys[i].syms[j]) {
                   1303:                        hotkeys[i].mask |= (1 << j);
                   1304:                    }
                   1305:                }
                   1306:            }
                   1307:        }
                   1308:        if (returnnow)
                   1309:            return -2;
1.1       root     1310:        as = kc_decode (ks);
1.1.1.3   root     1311: 
                   1312:        if (as == -1) {
1.1.1.5   root     1313:            switch (currprefs.keyboard_lang) {
1.1       root     1314:            case KBD_LANG_FR:
1.1.1.5   root     1315:                as = decode_fr (ks);
1.1       root     1316:                break;
                   1317: 
1.1.1.3   root     1318:            case KBD_LANG_US:
1.1.1.5   root     1319:                as = decode_us (ks);
1.1       root     1320:                break;
1.1.1.3   root     1321: 
1.1       root     1322:             case KBD_LANG_DE:
1.1.1.5   root     1323:                as = decode_de (ks);
1.1       root     1324:                break;
1.1.1.3   root     1325: 
1.1       root     1326:             case KBD_LANG_SE:
1.1.1.5   root     1327:                as = decode_se (ks);
1.1       root     1328:                break;
1.1.1.3   root     1329: 
1.1       root     1330:             case KBD_LANG_IT:
1.1.1.5   root     1331:                as = decode_it (ks);
1.1       root     1332:                break;
                   1333: 
1.1.1.2   root     1334:             case KBD_LANG_ES:
1.1.1.5   root     1335:                as = decode_es (ks);
1.1.1.2   root     1336:                break;
                   1337: 
1.1       root     1338:             default:
                   1339:                as = -1;
                   1340:                break;
                   1341:            }
                   1342:        }
1.1.1.5   root     1343:        if (-1 != as)
1.1       root     1344:                return as;
                   1345:        index++;
                   1346:     } while (ks != NoSymbol);
                   1347:     return -1;
                   1348: }
                   1349: 
                   1350: static struct timeval lastMotionTime;
                   1351: 
1.1.1.3   root     1352: static int refresh_necessary = 0;
                   1353: 
1.1.1.5   root     1354: void handle_events (void)
1.1       root     1355: {
                   1356:     newmousecounters = 0;
1.1.1.5   root     1357:     gui_handle_events ();
1.1.1.3   root     1358: 
1.1       root     1359:     for (;;) {
                   1360:        XEvent event;
                   1361: #if 0
1.1.1.5   root     1362:        if (! XCheckMaskEvent (display, eventmask, &event))
                   1363:            break;
1.1       root     1364: #endif
1.1.1.5   root     1365:        if (! XPending (display))
                   1366:            break;
                   1367: 
                   1368:        XNextEvent (display, &event);
1.1.1.3   root     1369: 
1.1.1.5   root     1370:        switch (event.type) {
1.1.1.3   root     1371:         case KeyPress: {
1.1.1.5   root     1372:             int i;
                   1373:             int kc = keycode2amiga ((XKeyEvent *)&event);
1.1       root     1374: 
1.1.1.5   root     1375:             if (kc == -2) {
                   1376:                 for (i = 0; hotkeys[i].syms[0] != 0; i++) {
                   1377:                     if (hotkeys[i].mask == 0) {
                   1378:                         if (hotkeys[i].handler != NULL)
                   1379:                             hotkeys[i].handler();
                   1380:                     }
                   1381:                 }
1.1       root     1382:                 break;
1.1.1.5   root     1383:             }
1.1       root     1384: 
1.1.1.5   root     1385:             if (kc == -1)
1.1       root     1386:                 break;
1.1.1.5   root     1387:             if (! keystate[kc]) {
                   1388:                 keystate[kc] = 1;
                   1389:                 record_key (kc << 1);
1.1       root     1390:             }
                   1391:             break;
                   1392:         }
1.1.1.3   root     1393:         case KeyRelease: {
1.1.1.5   root     1394:             int kc = keycode2amiga ((XKeyEvent *)&event);
                   1395:             if (kc < 0)
                   1396:                 break;
1.1       root     1397:             keystate[kc] = 0;
                   1398:             record_key ((kc << 1) | 1);
                   1399:             break;
                   1400:         }
                   1401:         case ButtonPress:
                   1402:            buttonstate[((XButtonEvent *)&event)->button-1] = 1;
                   1403:            break;
                   1404:         case ButtonRelease:
                   1405:            buttonstate[((XButtonEvent *)&event)->button-1] = 0;
                   1406:            break;
1.1.1.5   root     1407:         case MotionNotify:
                   1408:            if (dgamode) {
                   1409:                newmousecounters = 0;
                   1410:                lastmx += ((XMotionEvent *)&event)->x_root;
                   1411:                lastmy += ((XMotionEvent *)&event)->y_root;
                   1412:            } else if (grabbed) {
                   1413:                int realmove = 0;
                   1414:                int tx, ty;
                   1415:                
                   1416:                tx = ((XMotionEvent *)&event)->x;
                   1417:                ty = ((XMotionEvent *)&event)->y;
                   1418: 
                   1419:                if (! event.xmotion.send_event) {
                   1420:                    newmousecounters = 0;
                   1421:                    lastmx += tx - oldx;
                   1422:                    lastmy += ty - oldy;
                   1423:                    realmove = 1;
                   1424: #undef ABS
                   1425: #define ABS(a) (((a)<0) ? -(a) : (a) )
                   1426:                    if (ABS(current_width / 2 - tx) > 3 * current_width / 8
                   1427:                        || ABS(current_height / 2 - ty) > 3 * current_height / 8) 
                   1428:                    {
                   1429: #undef ABS
                   1430:                        XEvent event;
                   1431:                        tx = current_width / 2;
                   1432:                        ty = current_height / 2;
                   1433:                        event.type = MotionNotify;
                   1434:                        event.xmotion.display = display;
                   1435:                        event.xmotion.window = mywin;
                   1436:                        event.xmotion.x = tx;
                   1437:                        event.xmotion.y = ty;
                   1438:                        XSendEvent (display, mywin, False,
                   1439:                                    PointerMotionMask, &event);
                   1440:                        XWarpPointer (display, None, mywin, 0, 0, 0, 0, tx, ty);
                   1441:                    }
                   1442:                }
                   1443:                oldx = tx;
                   1444:                oldy = ty;
                   1445:            } else if (inwindow) {
                   1446:                lastmx = ((XMotionEvent *)&event)->x;
                   1447:                lastmy = ((XMotionEvent *)&event)->y;
1.1.1.6 ! root     1448:                if (! cursorOn && !currprefs.x11_hide_cursor) {
1.1.1.5   root     1449:                    XDefineCursor(display, mywin, xhairCursor);
                   1450:                    cursorOn = 1;
                   1451:                }
                   1452:                gettimeofday(&lastMotionTime, NULL);
                   1453:            }
                   1454: 
                   1455:             if (ievent_alive) {
                   1456:                 if (lastmx < 0)
                   1457:                     lastmx = 0;
                   1458:                 if (lastmx > current_width)
                   1459:                     lastmx = current_width;
                   1460:                 if (lastmy < 0)
                   1461:                     lastmy = 0;
                   1462:                 if (lastmy > current_height)
                   1463:                     lastmy = current_height;
                   1464:             }
                   1465:            break;
1.1       root     1466:         case EnterNotify:
                   1467:            newmousecounters = 1;
                   1468:            lastmx = ((XCrossingEvent *)&event)->x;
                   1469:            lastmy = ((XCrossingEvent *)&event)->y;
                   1470:            inwindow = 1;
                   1471:            break;
                   1472:         case LeaveNotify:
                   1473:            inwindow = 0;
                   1474:            break;
                   1475:         case FocusIn:
1.1.1.5   root     1476:            if (! autorepeatoff)
                   1477:                XAutoRepeatOff (display);
1.1       root     1478:            autorepeatoff = 1;
                   1479:            break;
                   1480:         case FocusOut:
                   1481:            if (autorepeatoff)
1.1.1.5   root     1482:                XAutoRepeatOn (display);
1.1       root     1483:            autorepeatoff = 0;
                   1484:            break;
                   1485:         case Expose:
1.1.1.3   root     1486:            refresh_necessary = 1;
1.1       root     1487:            break;
                   1488:        }
                   1489:     }
1.1.1.5   root     1490: 
                   1491: #if defined PICASSO96
                   1492:     if (! dgamode) {
                   1493:        if (screen_is_picasso && refresh_necessary) {
                   1494:            DO_PUTIMAGE (pic_dinfo.ximg, 0, 0, 0, 0,
                   1495:                         picasso_vidinfo.width, picasso_vidinfo.height);
                   1496:            refresh_necessary = 0;
                   1497:            memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines);
                   1498:        } else if (screen_is_picasso && picasso_has_invalid_lines) {
                   1499:            int i;
                   1500:            int strt = -1;
                   1501: 
                   1502:            picasso_invalid_lines[picasso_vidinfo.height] = 0;
                   1503:            for (i = picasso_invalid_start; i < picasso_invalid_stop + 2; i++) {
                   1504:                if (picasso_invalid_lines[i]) {
                   1505:                    picasso_invalid_lines[i] = 0;
                   1506:                    if (strt != -1)
                   1507:                        continue;
                   1508:                    strt = i;
                   1509:                } else {
                   1510:                    if (strt == -1)
                   1511:                        continue;
                   1512:                    DO_PUTIMAGE (pic_dinfo.ximg, 0, strt, 0, strt,
                   1513:                                 picasso_vidinfo.width, i - strt);
                   1514:                    strt = -1;
                   1515:                }
1.1.1.3   root     1516:            }
1.1.1.5   root     1517:            if (strt != -1)
                   1518:                abort ();
1.1.1.3   root     1519:        }
                   1520:     }
1.1.1.5   root     1521:     picasso_has_invalid_lines = 0;
                   1522:     picasso_invalid_start = picasso_vidinfo.height + 1;
                   1523:     picasso_invalid_stop = -1;
1.1.1.3   root     1524: #endif
1.1.1.5   root     1525:     
                   1526:     if (! dgamode) {
                   1527:        if (! screen_is_picasso && refresh_necessary) {
                   1528:            DO_PUTIMAGE (ami_dinfo.ximg, 0, 0, 0, 0, currprefs.gfx_width, currprefs.gfx_height);
                   1529:            refresh_necessary = 0;
                   1530:        }
1.1.1.6 ! root     1531:        if (cursorOn && !currprefs.x11_hide_cursor) {
1.1.1.5   root     1532:            struct timeval now;
                   1533:            int diff;
                   1534:            gettimeofday(&now, NULL);
                   1535:            diff = (now.tv_sec - lastMotionTime.tv_sec) * 1000000 +
                   1536:                (now.tv_usec - lastMotionTime.tv_usec);
                   1537:            if (diff > 1000000) {
                   1538:                XDefineCursor (display, mywin, blankCursor);
                   1539:                cursorOn = 0;
                   1540:            }
1.1       root     1541:        }
                   1542:     }
                   1543:     /* "Affengriff" */
1.1.1.6 ! root     1544:     if ((keystate[AK_CTRL] || keystate[AK_RCTRL]) && keystate[AK_LAMI] && keystate[AK_RAMI])
1.1.1.5   root     1545:        uae_reset ();
1.1       root     1546: }
                   1547: 
1.1.1.5   root     1548: int check_prefs_changed_gfx (void)
1.1       root     1549: {
1.1.1.5   root     1550:     if (changed_prefs.gfx_width != currprefs.gfx_width
                   1551:        || changed_prefs.gfx_height != currprefs.gfx_height)
                   1552:        fixup_prefs_dimensions (&changed_prefs);
                   1553: 
                   1554:     if (changed_prefs.gfx_width == currprefs.gfx_width
                   1555:        && changed_prefs.gfx_height == currprefs.gfx_height
                   1556:        && changed_prefs.gfx_lores == currprefs.gfx_lores
                   1557:        && changed_prefs.gfx_linedbl == currprefs.gfx_linedbl
                   1558:        && changed_prefs.gfx_correct_aspect == currprefs.gfx_correct_aspect
                   1559:        && changed_prefs.gfx_xcenter == currprefs.gfx_xcenter
                   1560:        && changed_prefs.gfx_ycenter == currprefs.gfx_ycenter
                   1561:        && changed_prefs.gfx_afullscreen == currprefs.gfx_afullscreen
                   1562:        && changed_prefs.gfx_pfullscreen == currprefs.gfx_pfullscreen)
                   1563:        return 0;
1.1.1.6 ! root     1564: 
        !          1565:     graphics_subshutdown ();
        !          1566:     currprefs.gfx_width = changed_prefs.gfx_width;
        !          1567:     currprefs.gfx_height = changed_prefs.gfx_height;
        !          1568:     currprefs.gfx_lores = changed_prefs.gfx_lores;
        !          1569:     currprefs.gfx_linedbl = changed_prefs.gfx_linedbl;
        !          1570:     currprefs.gfx_correct_aspect = changed_prefs.gfx_correct_aspect;
        !          1571:     currprefs.gfx_xcenter = changed_prefs.gfx_xcenter;
        !          1572:     currprefs.gfx_ycenter = changed_prefs.gfx_ycenter;
        !          1573:     currprefs.gfx_afullscreen = changed_prefs.gfx_afullscreen;
        !          1574:     currprefs.gfx_pfullscreen = changed_prefs.gfx_pfullscreen;
        !          1575:     graphics_subinit ();
        !          1576: 
        !          1577:     if (! inwindow)
        !          1578:        XWarpPointer (display, None, mywin, 0, 0, 0, 0,
        !          1579:                      current_width / 2, current_height / 2);
        !          1580: 
        !          1581:     notice_screen_contents_lost ();
        !          1582:     init_row_map ();
        !          1583:     if (screen_is_picasso)
        !          1584:        picasso_enablescreen (1);
1.1.1.5   root     1585:     return 0;
1.1       root     1586: }
                   1587: 
1.1.1.5   root     1588: int debuggable (void)
1.1       root     1589: {
                   1590:     return 1;
                   1591: }
                   1592: 
1.1.1.5   root     1593: int needmousehack (void)
                   1594: {
                   1595:     if (dgamode)
                   1596:        return 0;
                   1597:     else
                   1598:        return 1;
                   1599: }
                   1600: 
                   1601: void LED (int on)
1.1       root     1602: {
1.1.1.2   root     1603: #if 0 /* Maybe that is responsible for the joystick emulation problems on SunOS? */
1.1       root     1604:     static int last_on = -1;
                   1605:     XKeyboardControl control;
                   1606: 
1.1.1.5   root     1607:     if (last_on == on)
                   1608:        return;
1.1       root     1609:     last_on = on;
                   1610:     control.led = 1; /* implementation defined */
                   1611:     control.led_mode = on ? LedModeOn : LedModeOff;
                   1612:     XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
1.1.1.2   root     1613: #endif
1.1       root     1614: }
                   1615: 
1.1.1.3   root     1616: #ifdef PICASSO96
                   1617: 
                   1618: void DX_Invalidate (int first, int last)
                   1619: {
1.1.1.5   root     1620:     if (first > last)
                   1621:        return;
                   1622: 
                   1623:     picasso_has_invalid_lines = 1;
                   1624:     if (first < picasso_invalid_start)
                   1625:        picasso_invalid_start = first;
                   1626:     if (last > picasso_invalid_stop)
                   1627:        picasso_invalid_stop = last;
                   1628: 
                   1629:     while (first <= last) {
1.1.1.3   root     1630:        picasso_invalid_lines[first] = 1;
                   1631:        first++;
1.1.1.5   root     1632:     } 
1.1.1.3   root     1633: }
                   1634: 
                   1635: int DX_BitsPerCannon (void)
                   1636: {
                   1637:     return 8;
                   1638: }
                   1639: 
1.1.1.5   root     1640: void DX_SetPalette (int start, int count)
1.1.1.3   root     1641: {
1.1.1.5   root     1642:     if (! screen_is_picasso || picasso96_state.RGBFormat != RGBFB_CHUNKY)
1.1.1.3   root     1643:        return;
                   1644: 
1.1.1.5   root     1645:     if (picasso_vidinfo.pixbytes != 1) {
                   1646:        /* This is the case when we're emulating a 256 color display.  */
                   1647:        while (count-- > 0) {
                   1648:            int r = picasso96_state.CLUT[start].Red;
                   1649:            int g = picasso96_state.CLUT[start].Green;
                   1650:            int b = picasso96_state.CLUT[start].Blue;
                   1651:            picasso_vidinfo.clut[start++] = (doMask256 (r, red_bits, red_shift)
                   1652:                                             | doMask256 (g, green_bits, green_shift)
                   1653:                                             | doMask256 (b, blue_bits, blue_shift));
                   1654:        }
                   1655:        return;
                   1656:     }
                   1657:     
1.1.1.3   root     1658:     while (count-- > 0) {
                   1659:        XColor col = parsed_xcolors[start];
                   1660:        col.red = picasso96_state.CLUT[start].Red * 0x0101;
                   1661:        col.green = picasso96_state.CLUT[start].Green * 0x0101;
                   1662:        col.blue = picasso96_state.CLUT[start].Blue * 0x0101;
                   1663:        XStoreColor (display, cmap, &col);
                   1664:        XStoreColor (display, cmap2, &col);
                   1665:        start++;
                   1666:     }
                   1667: #ifdef USE_DGA_EXTENSION
1.1.1.5   root     1668:     if (dgamode) {
                   1669:        dga_colormap_installed ^= 1;
                   1670:        if (dga_colormap_installed == 1)
                   1671:            XF86DGAInstallColormap (display, screen, cmap2);
                   1672:        else
                   1673:            XF86DGAInstallColormap (display, screen, cmap);
                   1674:     }
1.1.1.3   root     1675: #endif
                   1676: }
                   1677: 
                   1678: #define MAX_SCREEN_MODES 11
                   1679: 
                   1680: static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280 };
                   1681: static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768, 864, 1024 };
                   1682: 
                   1683: int DX_FillResolutions (uae_u16 *ppixel_format)
                   1684: {
                   1685:     Screen *scr = ScreenOfDisplay (display, screen);
                   1686:     int i, count = 0;
                   1687:     int w = WidthOfScreen (scr);
                   1688:     int h = HeightOfScreen (scr);
1.1.1.5   root     1689:     int emulate_chunky = 0;
1.1.1.3   root     1690: 
1.1.1.5   root     1691:     picasso_vidinfo.rgbformat = (bit_unit == 8 ? RGBFB_CHUNKY
                   1692:                                 : bitdepth == 15 && bit_unit == 16 ? RGBFB_R5G5B5PC
                   1693:                                 : bitdepth == 16 && bit_unit == 16 ? RGBFB_R5G6B5PC
                   1694:                                 : bit_unit == 24 ? RGBFB_B8G8R8
                   1695:                                 : bit_unit == 32 ? RGBFB_B8G8R8A8
                   1696:                                 : RGBFB_NONE);
                   1697: 
                   1698:     *ppixel_format = 1 << picasso_vidinfo.rgbformat;
                   1699:     if (visualInfo.VI_CLASS == TrueColor && (bit_unit == 16 || bit_unit == 32))
                   1700:        *ppixel_format |= RGBFF_CHUNKY, emulate_chunky = 1;
1.1.1.3   root     1701: 
                   1702: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
1.1.1.5   root     1703:     if (dgaavail && vidmodeavail) {
                   1704:        for (i = 0; i < vidmodecount && count < MAX_PICASSO_MODES; i++) {
                   1705:            int j;
                   1706:            for (j = 0; j <= emulate_chunky && count < MAX_PICASSO_MODES; j++) {
                   1707:                DisplayModes[count].res.width = allmodes[i]->hdisplay;
                   1708:                DisplayModes[count].res.height = allmodes[i]->vdisplay;
                   1709:                DisplayModes[count].depth = j == 1 ? 1 : bit_unit >> 3;
                   1710:                DisplayModes[count].refresh = 75;
                   1711:                count++;
                   1712:            }
1.1.1.3   root     1713:        }
1.1.1.5   root     1714:     } else
1.1.1.3   root     1715: #endif
1.1.1.5   root     1716:     {
                   1717:        for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES; i++) {
                   1718:            int j;
                   1719:            for (j = 0; j <= emulate_chunky && count < MAX_PICASSO_MODES; j++) {
                   1720:                if (x_size_table[i] <= w && y_size_table[i] <= h) {
                   1721:                    if (x_size_table[i] > picasso_maxw)
                   1722:                        picasso_maxw = x_size_table[i];
                   1723:                    if (y_size_table[i] > picasso_maxh)
                   1724:                        picasso_maxh = y_size_table[i];
                   1725:                    DisplayModes[count].res.width = x_size_table[i];
                   1726:                    DisplayModes[count].res.height = y_size_table[i];
                   1727:                    DisplayModes[count].depth = j == 1 ? 1 : bit_unit >> 3;
                   1728:                    DisplayModes[count].refresh = 75;
                   1729:                    count++;
                   1730:                }
                   1731:            }
                   1732:        }
                   1733:     }
1.1.1.3   root     1734: 
                   1735:     return count;
                   1736: }
                   1737: 
                   1738: static void set_window_for_picasso (void)
                   1739: {
1.1.1.5   root     1740:     if (current_width == picasso_vidinfo.width && current_height == picasso_vidinfo.height)
                   1741:        return;
1.1.1.3   root     1742: 
1.1.1.5   root     1743:     current_width = picasso_vidinfo.width;
                   1744:     current_height = picasso_vidinfo.height;
                   1745:     XResizeWindow (display, mywin, current_width, current_height);
1.1.1.3   root     1746: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
1.1.1.5   root     1747:     if (dgamode && vidmodeavail)
1.1.1.3   root     1748:        switch_to_best_mode ();
                   1749: #endif
                   1750: }
                   1751: 
1.1.1.5   root     1752: void gfx_set_picasso_modeinfo (int w, int h, int depth, int rgbfmt)
1.1.1.3   root     1753: {
                   1754:     picasso_vidinfo.width = w;
                   1755:     picasso_vidinfo.height = h;
                   1756:     picasso_vidinfo.depth = depth;
1.1.1.4   root     1757:     picasso_vidinfo.pixbytes = bit_unit >> 3;
1.1.1.3   root     1758: 
                   1759:     if (screen_is_picasso)
                   1760:        set_window_for_picasso ();
                   1761: }
                   1762: 
                   1763: void gfx_set_picasso_baseaddr (uaecptr a)
                   1764: {
                   1765: }
                   1766: 
                   1767: void gfx_set_picasso_state (int on)
                   1768: {
                   1769:     if (on == screen_is_picasso)
                   1770:        return;
1.1.1.5   root     1771:     graphics_subshutdown ();
1.1.1.3   root     1772:     screen_is_picasso = on;
1.1.1.5   root     1773:     if (on) {
                   1774:        current_width = picasso_vidinfo.width;
                   1775:        current_height = picasso_vidinfo.height;
                   1776:     } else {
                   1777:        current_width = gfxvidinfo.width;
                   1778:        current_height = gfxvidinfo.height;
                   1779:     }
                   1780:     graphics_subinit ();
1.1.1.3   root     1781:     if (on)
1.1.1.5   root     1782:        DX_SetPalette (0, 256);
                   1783: }
                   1784: 
                   1785: uae_u8 *gfx_lock_picasso (void)
                   1786: {
                   1787: #ifdef USE_DGA_EXTENSION
                   1788:     if (dgamode)
                   1789:        return fb_addr;
1.1.1.3   root     1790:     else
1.1.1.5   root     1791: #endif
                   1792:        return pic_dinfo.ximg->data;
                   1793: }
                   1794: void gfx_unlock_picasso (void)
                   1795: {
1.1.1.3   root     1796: }
1.1.1.5   root     1797: #endif
1.1.1.3   root     1798: 
1.1.1.5   root     1799: int lockscr (void)
1.1       root     1800: {
1.1.1.5   root     1801:     return 1;
1.1       root     1802: }
1.1.1.3   root     1803: 
1.1.1.5   root     1804: void unlockscr (void)
1.1.1.3   root     1805: {
                   1806: }
                   1807: 
1.1.1.5   root     1808: static void handle_mousegrab (void)
1.1.1.3   root     1809: {
1.1.1.5   root     1810:     if (grabbed) {
                   1811:        XUngrabPointer (display, CurrentTime);
                   1812:        XUndefineCursor (display, mywin);
                   1813:        grabbed = 0;
                   1814:     } else if (! dgamode) {
                   1815:        XGrabPointer (display, mywin, 1, 0, GrabModeAsync, GrabModeAsync,
                   1816:                      mywin, blankCursor, CurrentTime);
                   1817:        oldx = current_width / 2;
                   1818:        oldy = current_height / 2;
                   1819:        XWarpPointer (display, None, mywin, 0, 0, 0, 0, oldx, oldy);
                   1820:        grabbed = 1;
                   1821:     }
1.1.1.3   root     1822: }
1.1.1.5   root     1823: 
                   1824: static void handle_inhibit (void)
1.1.1.3   root     1825: {
1.1.1.6 ! root     1826:     toggle_inhibit_frame (IHF_SCROLLLOCK);
1.1.1.5   root     1827: }
                   1828: 
                   1829: static void framerate_up (void)
                   1830: {
                   1831:     if (currprefs.framerate < 20)
                   1832:        changed_prefs.framerate = currprefs.framerate + 1;
                   1833: }
                   1834: 
                   1835: static void framerate_down (void)
                   1836: {
                   1837:     if (currprefs.framerate > 1)
                   1838:        changed_prefs.framerate = currprefs.framerate - 1;
1.1.1.3   root     1839: }
1.1.1.6 ! root     1840: 
        !          1841: static void handle_modeswitch (void)
        !          1842: {
        !          1843:     changed_prefs.gfx_afullscreen = changed_prefs.gfx_pfullscreen = !dgamode;
        !          1844: }
        !          1845: 
        !          1846: void target_save_options (FILE *f, struct uae_prefs *p)
        !          1847: {
        !          1848:     fprintf (f, "x11.low_bandwidth=%s\n", p->x11_use_low_bandwidth ? "true" : "false");
        !          1849:     fprintf (f, "x11.use_mitshm=%s\n", p->x11_use_mitshm ? "true" : "false");
        !          1850:     fprintf (f, "x11.hide_cursor=%s\n", p->x11_hide_cursor ? "true" : "false");
        !          1851: }
        !          1852: 
        !          1853: int target_parse_option (struct uae_prefs *p, char *option, char *value)
        !          1854: {
        !          1855:     return (cfgfile_yesno (option, value, "low_bandwidth", &p->x11_use_low_bandwidth)
        !          1856:            || cfgfile_yesno (option, value, "use_mitshm", &p->x11_use_mitshm)
        !          1857:            || cfgfile_yesno (option, value, "hide_cursor", &p->x11_hide_cursor));
        !          1858: }

unix.superglobalmegacorp.com

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