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

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

unix.superglobalmegacorp.com

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