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

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.14  root       26: #include "threaddep/thread.h"
1.1.1.3   root       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       root       32: #include "newcpu.h"
                     33: #include "keyboard.h"
                     34: #include "keybuf.h"
                     35: #include "gui.h"
                     36: #include "debug.h"
1.1.1.3   root       37: #include "picasso96.h"
1.1.1.18! root       38: #include "inputdevice.h"
1.1.1.3   root       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.12  root       68:        if (currprefs.x11_use_mitshm && shmavail) \
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;
1.1.1.16  root      241:            write_log ("MIT-SHM extension failed, trying fallback.\n");
1.1.1.5   root      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))
1.1.1.16  root      261:        write_log ("Possible bug here... graphics may look strange.\n");
1.1.1.3   root      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: {
1.1.1.14  root      285:     Screen *scr = ScreenOfDisplay (display, screen);
                    286:     int w = WidthOfScreen (scr);
                    287:     int h = HeightOfScreen (scr);
                    288:     int d = DefaultDepthOfScreen (scr);
1.1.1.5   root      289: #ifdef USE_VIDMODE_EXTENSION
1.1.1.14  root      290:     int i, best;
1.1.1.5   root      291:     if (vidmodeavail) {
                    292:        best = 0;
                    293:        for (i = 1; i < vidmodecount; i++) {
                    294:            if (allmodes[i]->hdisplay >= current_width
                    295:                && allmodes[i]->vdisplay >= current_height
                    296:                && allmodes[i]->hdisplay <= allmodes[best]->hdisplay
                    297:                && allmodes[i]->vdisplay <= allmodes[best]->vdisplay)
                    298:                best = i;
                    299:        }
                    300:        printf ("entering DGA mode: %dx%d (%d, %d)\n",
                    301:                allmodes[best]->hdisplay, allmodes[best]->vdisplay,
                    302:                current_width, current_height);
                    303:        XF86VidModeSwitchToMode (display, screen, allmodes[best]);
                    304:        XF86VidModeSetViewPort (display, screen, 0, 0);
                    305:     }
1.1.1.4   root      306: #endif
1.1.1.3   root      307:     XMoveWindow (display, mywin, 0, 0);
                    308:     XWarpPointer (display, None, rootwin, 0, 0, 0, 0, 0, 0);
1.1.1.5   root      309:     XF86DGADirectVideo (display, screen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb);
                    310:     XF86DGASetViewPort (display, screen, 0, 0);
1.1.1.14  root      311:     memset (fb_addr, 0, (w * h) * (d / 8));
1.1.1.3   root      312: }
                    313: 
                    314: static void enter_dga_mode (void)
                    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: {
1.1.1.14  root      337:     XF86DGADirectVideo (display, screen, 0);
                    338:     XUngrabPointer (display, CurrentTime);
                    339:     XUngrabKeyboard (display, CurrentTime);
1.1.1.3   root      340: #ifdef USE_VIDMODE_EXTENSION
1.1.1.5   root      341:     if (vidmodeavail)
                    342:        XF86VidModeSwitchToMode (display, screen, allmodes[0]);
1.1.1.3   root      343: #endif
                    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.16  root      426:        write_log ("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.12  root      447:     if (currprefs.x11_use_mitshm && shmavail)
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.16  root      522:            write_log ("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))
1.1.1.16  root      533:                write_log ("Whoops??\n");
1.1.1.5   root      534:            XParseColor (display, cmap, "#ffffff", &white);
                    535:            if (! XAllocColor (display, cmap, &white))
1.1.1.16  root      536:                write_log ("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:
1.1.1.16  root      545:            write_log ("Unsupported visual class (%d)\n", visualInfo.VI_CLASS);
1.1.1.3   root      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)) {
1.1.1.16  root      590:        write_log ("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)) {
1.1.1.16  root      594:        write_log ("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.16  root      601:        write_log (
1.1.1.3   root      602:                 "Xserver is running an old XFree86-DGA version"
                    603:                 " (%d.%d)\n", MajorVersion, MinorVersion);
1.1.1.16  root      604:        write_log ("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) {
1.1.1.16  root      609:        write_log ("UAE is not running as root, DGA extension disabled.\n");
1.1.1.5   root      610:        return 0;
                    611:     }
                    612:     if (! XF86DGAGetVideo (display, screen, &fb_addr, &fb_width, &fb_bank, &fb_mem)
                    613:        || fb_bank < fb_mem)
                    614:     {
1.1.1.16  root      615:        write_log ("Problems with DGA - disabling DGA extension.\n");
1.1.1.3   root      616:        return 0;
                    617:     }
1.1.1.16  root      618:     write_log ("DGA extension: addr:%X, width %d, bank size %d mem size %d\n",
1.1.1.5   root      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.16  root      636:        write_log ("Unable to query video extension version\n");
1.1.1.3   root      637:        return 0;
                    638:     }
1.1.1.5   root      639:     if (! XF86VidModeQueryExtension (display, &EventBase, &ErrorBase)) {
1.1.1.16  root      640:        write_log ("Unable to query video extension information\n");
1.1.1.3   root      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 */
1.1.1.16  root      646:        write_log ("Xserver is running an old XFree86-VidMode version (%d.%d)\n",
1.1.1.5   root      647:                 MajorVersion, MinorVersion);
1.1.1.16  root      648:        write_log ("Minimum required version is %d.%d\n",
1.1.1.3   root      649:                 VidMode_MINMAJOR, VidMode_MINMINOR);
                    650:        return 0;
                    651:     }
1.1.1.5   root      652:     if (! get_vidmodes ()) {
1.1.1.16  root      653:        write_log ("Error getting video mode information\n");
1.1.1.3   root      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)  {
1.1.1.16  root      677:        write_log ("Can't connect to X server %s\n", XDisplayName (display_name));
1.1.1.5   root      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.16  root      852:        write_log ("MIT-SHM extension not supported by X server.\n");
1.1.1.5   root      853:     }
1.1.1.3   root      854:     if (currprefs.color_mode > 5)
1.1.1.16  root      855:        write_log ("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.16  root      881:        write_log ("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.16  root      897:        write_log ("Your X server is feeling ill.\n");
1.1       root      898:        return 0;
                    899:     }
1.1.1.3   root      900: 
1.1.1.16  root      901:     write_log ("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: 
1.1.1.14  root      992: #if 0
1.1.1.5   root      993:     XCloseDisplay (display);
1.1.1.14  root      994: #endif
1.1.1.5   root      995:     dumpcustom ();
1.1       root      996: }
                    997: 
1.1.1.3   root      998: /* Decode KeySyms. This function knows about all keys that are common
1.1       root      999:  * between different keyboard languages. */
                   1000: static int kc_decode (KeySym ks)
                   1001: {
1.1.1.3   root     1002:     switch (ks) {
1.1       root     1003:      case XK_B: case XK_b: return AK_B;
                   1004:      case XK_C: case XK_c: return AK_C;
                   1005:      case XK_D: case XK_d: return AK_D;
                   1006:      case XK_E: case XK_e: return AK_E;
                   1007:      case XK_F: case XK_f: return AK_F;
                   1008:      case XK_G: case XK_g: return AK_G;
                   1009:      case XK_H: case XK_h: return AK_H;
                   1010:      case XK_I: case XK_i: return AK_I;
                   1011:      case XK_J: case XK_j: return AK_J;
                   1012:      case XK_K: case XK_k: return AK_K;
                   1013:      case XK_L: case XK_l: return AK_L;
                   1014:      case XK_N: case XK_n: return AK_N;
                   1015:      case XK_O: case XK_o: return AK_O;
                   1016:      case XK_P: case XK_p: return AK_P;
                   1017:      case XK_R: case XK_r: return AK_R;
                   1018:      case XK_S: case XK_s: return AK_S;
                   1019:      case XK_T: case XK_t: return AK_T;
                   1020:      case XK_U: case XK_u: return AK_U;
                   1021:      case XK_V: case XK_v: return AK_V;
                   1022:      case XK_X: case XK_x: return AK_X;
1.1.1.3   root     1023: 
1.1       root     1024:      case XK_0: return AK_0;
                   1025:      case XK_1: return AK_1;
                   1026:      case XK_2: return AK_2;
                   1027:      case XK_3: return AK_3;
                   1028:      case XK_4: return AK_4;
                   1029:      case XK_5: return AK_5;
                   1030:      case XK_6: return AK_6;
                   1031:      case XK_7: return AK_7;
                   1032:      case XK_8: return AK_8;
                   1033:      case XK_9: return AK_9;
1.1.1.3   root     1034: 
1.1       root     1035:        /* You never know which Keysyms might be missing on some workstation
                   1036:         * This #ifdef should be enough. */
                   1037: #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End)
                   1038:      case XK_KP_0: case XK_KP_Insert: return AK_NP0;
                   1039:      case XK_KP_1: case XK_KP_End: return AK_NP1;
                   1040:      case XK_KP_2: case XK_KP_Down: return AK_NP2;
                   1041:      case XK_KP_3: case XK_KP_Next: return AK_NP3;
                   1042:      case XK_KP_4: case XK_KP_Left: return AK_NP4;
                   1043:      case XK_KP_5: case XK_KP_Begin: return AK_NP5;
                   1044:      case XK_KP_6: case XK_KP_Right: return AK_NP6;
                   1045:      case XK_KP_7: case XK_KP_Home: return AK_NP7;
                   1046:      case XK_KP_8: case XK_KP_Up: return AK_NP8;
                   1047:      case XK_KP_9: case XK_KP_Prior: return AK_NP9;
                   1048: #else
                   1049:      case XK_KP_0: return AK_NP0;
                   1050:      case XK_KP_1: return AK_NP1;
                   1051:      case XK_KP_2: return AK_NP2;
                   1052:      case XK_KP_3: return AK_NP3;
                   1053:      case XK_KP_4: return AK_NP4;
                   1054:      case XK_KP_5: return AK_NP5;
                   1055:      case XK_KP_6: return AK_NP6;
                   1056:      case XK_KP_7: return AK_NP7;
                   1057:      case XK_KP_8: return AK_NP8;
                   1058:      case XK_KP_9: return AK_NP9;
                   1059: #endif
                   1060:      case XK_KP_Divide: return AK_NPDIV;
                   1061:      case XK_KP_Multiply: return AK_NPMUL;
                   1062:      case XK_KP_Subtract: return AK_NPSUB;
                   1063:      case XK_KP_Add: return AK_NPADD;
                   1064:      case XK_KP_Decimal: return AK_NPDEL;
                   1065:      case XK_KP_Enter: return AK_ENT;
                   1066: 
                   1067:      case XK_F1: return AK_F1;
                   1068:      case XK_F2: return AK_F2;
                   1069:      case XK_F3: return AK_F3;
                   1070:      case XK_F4: return AK_F4;
                   1071:      case XK_F5: return AK_F5;
                   1072:      case XK_F6: return AK_F6;
                   1073:      case XK_F7: return AK_F7;
                   1074:      case XK_F8: return AK_F8;
                   1075:      case XK_F9: return AK_F9;
                   1076:      case XK_F10: return AK_F10;
1.1.1.3   root     1077: 
1.1       root     1078:      case XK_BackSpace: return AK_BS;
                   1079:      case XK_Delete: return AK_DEL;
1.1.1.3   root     1080:      case XK_Control_L: return AK_CTRL;
                   1081:      case XK_Control_R: return AK_RCTRL;
1.1       root     1082:      case XK_Tab: return AK_TAB;
                   1083:      case XK_Alt_L: return AK_LALT;
                   1084:      case XK_Alt_R: return AK_RALT;
                   1085:      case XK_Meta_R: case XK_Hyper_R: return AK_RAMI;
                   1086:      case XK_Meta_L: case XK_Hyper_L: return AK_LAMI;
                   1087:      case XK_Return: return AK_RET;
                   1088:      case XK_space: return AK_SPC;
                   1089:      case XK_Shift_L: return AK_LSH;
                   1090:      case XK_Shift_R: return AK_RSH;
                   1091:      case XK_Escape: return AK_ESC;
                   1092: 
1.1.1.3   root     1093:      case XK_Insert: return AK_HELP;
                   1094:      case XK_Home: return AK_NPLPAREN;
                   1095:      case XK_End: return AK_NPRPAREN;
1.1       root     1096:      case XK_Caps_Lock: return AK_CAPSLOCK;
1.1.1.3   root     1097: 
1.1       root     1098:      case XK_Up: return AK_UP;
                   1099:      case XK_Down: return AK_DN;
                   1100:      case XK_Left: return AK_LF;
                   1101:      case XK_Right: return AK_RT;
1.1.1.3   root     1102: 
1.1.1.9   root     1103: #if 0
1.1       root     1104:      case XK_F11: return AK_BACKSLASH;
1.1.1.9   root     1105: #else
                   1106:      case XK_F11: frametime = 0; timeframes = 0; bogusframe = 1; break;
                   1107: #endif
1.1       root     1108: #ifdef XK_Page_Up /* These are missing occasionally */
                   1109:      case XK_Page_Up: return AK_RAMI;          /* PgUp mapped to right amiga */
                   1110:      case XK_Page_Down: return AK_LAMI;        /* PgDn mapped to left amiga */
                   1111: #endif
                   1112:     }
                   1113:     return -1;
                   1114: }
                   1115: 
1.1.1.5   root     1116: static int decode_fr (KeySym ks)
1.1       root     1117: {
                   1118:     switch(ks) {        /* FR specific */
                   1119:      case XK_A: case XK_a: return AK_Q;
1.1.1.3   root     1120:      case XK_M: case XK_m: return AK_SEMICOLON;
                   1121:      case XK_Q: case XK_q: return AK_A;
1.1       root     1122:      case XK_Y: case XK_y: return AK_Y;
1.1.1.2   root     1123:      case XK_W: case XK_w: return AK_Z;
                   1124:      case XK_Z: case XK_z: return AK_W;
1.1.1.6   root     1125: #if 0
1.1       root     1126:      case XK_bracketleft: return AK_LBRACKET;
                   1127:      case XK_bracketright: return AK_RBRACKET;
                   1128:      case XK_comma: return AK_M;
                   1129:      case XK_less: case XK_greater: return AK_LTGT;
                   1130:      case XK_period: return AK_COMMA;
                   1131:      case XK_parenright: return AK_MINUS;
                   1132:      case XK_equal: return AK_SLASH;
                   1133:      case XK_numbersign: return AK_NUMBERSIGN;
                   1134:      case XK_slash: return AK_PERIOD;
                   1135:      case XK_minus: return AK_EQUAL;
                   1136:      case XK_backslash: return AK_BACKSLASH;
1.1.1.6   root     1137: #else
                   1138:      /* not sure for this one: my X 3.3 server doesn't handle this key always
                   1139:       * correctly... But anyway, on new french keyboards, no more bracket key
                   1140:       * at this place. 
                   1141:       */
                   1142:      case XK_dead_circumflex:
                   1143:      case XK_dead_diaeresis: return AK_LBRACKET;
                   1144:      case XK_dollar:
                   1145:      case XK_sterling: return AK_RBRACKET;
                   1146:      case XK_comma: case XK_question: return AK_M;
                   1147:      case XK_less: case XK_greater: return AK_LTGT;
                   1148:      case XK_semicolon: case XK_period: return AK_COMMA;
                   1149:      case XK_parenright: case XK_degree: return AK_MINUS;
                   1150:      case XK_equal: case XK_plus: return AK_SLASH;
                   1151:      case XK_numbersign: return AK_NUMBERSIGN;
                   1152:      case XK_colon: case XK_slash: return AK_PERIOD;
                   1153:      case XK_minus: case XK_6: return AK_6;
                   1154:      case XK_ugrave: case XK_percent: return AK_QUOTE;
                   1155:      /* found a spare key - I hope it deserves this place. */
                   1156:      case XK_asterisk: case XK_mu: return AK_BACKSLASH;
                   1157:      case XK_exclam: case XK_section: return AK_EQUAL;
                   1158:      case XK_twosuperior: case XK_asciitilde: return AK_BACKQUOTE;
                   1159:      case XK_Multi_key: return AK_RAMI;
                   1160:      case XK_Mode_switch: return AK_RALT;
                   1161: #endif
1.1       root     1162:     }
                   1163: 
                   1164:     return -1;
                   1165: }
                   1166: 
1.1.1.5   root     1167: static int decode_us (KeySym ks)
1.1       root     1168: {
1.1.1.3   root     1169:     switch(ks) {       /* US specific */
1.1       root     1170:      case XK_A: case XK_a: return AK_A;
                   1171:      case XK_M: case XK_m: return AK_M;
                   1172:      case XK_Q: case XK_q: return AK_Q;
                   1173:      case XK_Y: case XK_y: return AK_Y;
1.1.1.2   root     1174:      case XK_W: case XK_w: return AK_W;
1.1       root     1175:      case XK_Z: case XK_z: return AK_Z;
                   1176:      case XK_bracketleft: return AK_LBRACKET;
                   1177:      case XK_bracketright: return AK_RBRACKET;
                   1178:      case XK_comma: return AK_COMMA;
                   1179:      case XK_period: return AK_PERIOD;
                   1180:      case XK_slash: return AK_SLASH;
                   1181:      case XK_semicolon: return AK_SEMICOLON;
                   1182:      case XK_minus: return AK_MINUS;
                   1183:      case XK_equal: return AK_EQUAL;
                   1184:        /* this doesn't work: */
                   1185:      case XK_quoteright: return AK_QUOTE;
                   1186:      case XK_quoteleft: return AK_BACKQUOTE;
                   1187:      case XK_backslash: return AK_BACKSLASH;
                   1188:     }
                   1189: 
                   1190:     return -1;
                   1191: }
                   1192: 
1.1.1.5   root     1193: static int decode_de (KeySym ks)
1.1       root     1194: {
                   1195:     switch(ks) {
                   1196:        /* DE specific */
                   1197:      case XK_A: case XK_a: return AK_A;
                   1198:      case XK_M: case XK_m: return AK_M;
                   1199:      case XK_Q: case XK_q: return AK_Q;
1.1.1.2   root     1200:      case XK_W: case XK_w: return AK_W;
1.1       root     1201:      case XK_Y: case XK_y: return AK_Z;
                   1202:      case XK_Z: case XK_z: return AK_Y;
                   1203:      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
                   1204:      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
                   1205:      case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
                   1206:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                   1207:      case XK_comma: return AK_COMMA;
                   1208:      case XK_period: return AK_PERIOD;
                   1209:      case XK_less: case XK_greater: return AK_LTGT;
                   1210:      case XK_numbersign: return AK_NUMBERSIGN;
                   1211:      case XK_ssharp: return AK_MINUS;
                   1212:      case XK_apostrophe: return AK_EQUAL;
                   1213:      case XK_asciicircum: return AK_BACKQUOTE;
                   1214:      case XK_minus: return AK_SLASH;
                   1215:     }
                   1216: 
                   1217:     return -1;
                   1218: }
                   1219: 
1.1.1.13  root     1220: static int decode_dk (KeySym ks)
                   1221: {
                   1222:     switch(ks) {
                   1223:        /* DK specific */
                   1224:     case XK_A: case XK_a: return AK_A;
                   1225:     case XK_M: case XK_m: return AK_M;
                   1226:     case XK_Q: case XK_q: return AK_Q;
                   1227:     case XK_W: case XK_w: return AK_W;
                   1228:     case XK_Y: case XK_y: return AK_Y;
                   1229:     case XK_Z: case XK_z: return AK_Z;
                   1230:     case XK_AE: case XK_ae: return AK_SEMICOLON;
                   1231:     case XK_Ooblique: case XK_oslash: return AK_QUOTE;
                   1232:     case XK_Aring: case XK_aring: return AK_LBRACKET;
                   1233:     case XK_apostrophe: case XK_asterisk: return AK_NUMBERSIGN;
                   1234:     case XK_dead_diaeresis: case XK_dead_circumflex: return AK_RBRACKET;
                   1235:     case XK_dead_acute: case XK_dead_grave: return AK_BACKSLASH;
                   1236:     case XK_onehalf: case XK_section: return AK_BACKQUOTE;
                   1237:     case XK_comma: return AK_COMMA;
                   1238:     case XK_period: return AK_PERIOD;
                   1239:     case XK_less: case XK_greater: return AK_LTGT;
                   1240:     case XK_numbersign: return AK_NUMBERSIGN;
                   1241:     case XK_plus: return AK_MINUS;
                   1242:     case XK_asciicircum: return AK_BACKQUOTE;
                   1243:     case XK_minus: return AK_SLASH;
                   1244:     }
                   1245: 
                   1246:     return -1;
                   1247: }
                   1248: 
1.1.1.5   root     1249: static int decode_se (KeySym ks)
1.1       root     1250: {
                   1251:     switch(ks) {
                   1252:        /* SE specific */
                   1253:      case XK_A: case XK_a: return AK_A;
                   1254:      case XK_M: case XK_m: return AK_M;
                   1255:      case XK_Q: case XK_q: return AK_Q;
1.1.1.2   root     1256:      case XK_W: case XK_w: return AK_W;
1.1       root     1257:      case XK_Y: case XK_y: return AK_Y;
                   1258:      case XK_Z: case XK_z: return AK_Z;
                   1259:      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
                   1260:      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
                   1261:      case XK_Aring: case XK_aring: return AK_LBRACKET;
                   1262:      case XK_comma: return AK_COMMA;
                   1263:      case XK_period: return AK_PERIOD;
                   1264:      case XK_minus: return AK_SLASH;
                   1265:      case XK_less: case XK_greater: return AK_LTGT;
                   1266:      case XK_plus: case XK_question: return AK_EQUAL;
                   1267:      case XK_at: case XK_onehalf: return AK_BACKQUOTE;
                   1268:      case XK_asciitilde: case XK_asciicircum: return AK_RBRACKET;
                   1269:      case XK_backslash: case XK_bar: return AK_MINUS;
1.1.1.3   root     1270: 
1.1       root     1271:      case XK_numbersign: return AK_NUMBERSIGN;
                   1272:     }
                   1273: 
                   1274:     return -1;
                   1275:  }
                   1276: 
1.1.1.5   root     1277: static int decode_it (KeySym ks)
1.1       root     1278: {
                   1279:     switch(ks) {
                   1280:        /* IT specific */
                   1281:      case XK_A: case XK_a: return AK_A;
                   1282:      case XK_M: case XK_m: return AK_M;
                   1283:      case XK_Q: case XK_q: return AK_Q;
1.1.1.2   root     1284:      case XK_W: case XK_w: return AK_W;
1.1       root     1285:      case XK_Y: case XK_y: return AK_Y;
                   1286:      case XK_Z: case XK_z: return AK_Z;
                   1287:      case XK_Ograve: case XK_ograve: return AK_SEMICOLON;
                   1288:      case XK_Agrave: case XK_agrave: return AK_QUOTE;
                   1289:      case XK_Egrave: case XK_egrave: return AK_LBRACKET;
                   1290:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                   1291:      case XK_comma: return AK_COMMA;
                   1292:      case XK_period: return AK_PERIOD;
                   1293:      case XK_less: case XK_greater: return AK_LTGT;
1.1.1.3   root     1294:      case XK_backslash: case XK_bar: return AK_BACKQUOTE;
                   1295:      case XK_apostrophe: return AK_MINUS;
1.1       root     1296:      case XK_Igrave: case XK_igrave: return AK_EQUAL;
                   1297:      case XK_minus: return AK_SLASH;
                   1298:      case XK_numbersign: return AK_NUMBERSIGN;
                   1299:     }
                   1300: 
                   1301:     return -1;
                   1302: }
                   1303: 
1.1.1.5   root     1304: static int decode_es (KeySym ks)
1.1.1.2   root     1305: {
                   1306:     switch(ks) {
                   1307:        /* ES specific */
                   1308:      case XK_A: case XK_a: return AK_A;
                   1309:      case XK_M: case XK_m: return AK_M;
                   1310:      case XK_Q: case XK_q: return AK_Q;
                   1311:      case XK_W: case XK_w: return AK_W;
                   1312:      case XK_Y: case XK_y: return AK_Y;
                   1313:      case XK_Z: case XK_z: return AK_Z;
                   1314:      case XK_ntilde: case XK_Ntilde: return AK_SEMICOLON;
                   1315: #ifdef XK_dead_acute
                   1316:      case XK_dead_acute: case XK_dead_diaeresis: return AK_QUOTE;
                   1317:      case XK_dead_grave: case XK_dead_circumflex: return AK_LBRACKET;
                   1318: #endif
                   1319:      case XK_plus: case XK_asterisk: return AK_RBRACKET;
                   1320:      case XK_comma: return AK_COMMA;
                   1321:      case XK_period: return AK_PERIOD;
                   1322:      case XK_less: case XK_greater: return AK_LTGT;
1.1.1.3   root     1323:      case XK_backslash: case XK_bar: return AK_BACKQUOTE;
                   1324:      case XK_apostrophe: return AK_MINUS;
1.1.1.2   root     1325:      case XK_Igrave: case XK_igrave: return AK_EQUAL;
                   1326:      case XK_minus: return AK_SLASH;
                   1327:      case XK_numbersign: return AK_NUMBERSIGN;
                   1328:     }
                   1329: 
                   1330:     return -1;
                   1331: }
                   1332: 
1.1.1.5   root     1333: static int keycode2amiga (XKeyEvent *event)
1.1       root     1334: {
                   1335:     KeySym ks;
                   1336:     int as;
                   1337:     int index = 0;
1.1.1.3   root     1338: 
1.1       root     1339:     do {
1.1.1.5   root     1340:        int hkreturn = -1, returnnow = 0;
                   1341:        ks = XLookupKeysym (event, index);
                   1342:        if (event->type == KeyPress) {
                   1343:            int i, j;
                   1344:            for (i = 0; hotkeys[i].syms[0] != 0; i++) {
                   1345:                for (j = 0; hotkeys[i].syms[j] != 0; j++) {
                   1346:                    if (ks == hotkeys[i].syms[j]) {
                   1347:                        hotkeys[i].mask &= ~(1 << j);
                   1348:                        if (hotkeys[i].mask == 0) {
                   1349:                            returnnow = 1;
                   1350:                            hkreturn = hotkeys[i].retval;
                   1351:                        }
                   1352:                    }
                   1353:                }
                   1354:            }
                   1355:        } else {
                   1356:            int i, j;
                   1357:            for (i = 0; hotkeys[i].syms[0] != 0; i++) {
                   1358:                for (j = 0; hotkeys[i].syms[j] != 0; j++) {
                   1359:                    if (ks == hotkeys[i].syms[j]) {
                   1360:                        hotkeys[i].mask |= (1 << j);
                   1361:                    }
                   1362:                }
                   1363:            }
                   1364:        }
                   1365:        if (returnnow)
                   1366:            return -2;
1.1       root     1367:        as = kc_decode (ks);
1.1.1.3   root     1368: 
                   1369:        if (as == -1) {
1.1.1.5   root     1370:            switch (currprefs.keyboard_lang) {
1.1       root     1371:            case KBD_LANG_FR:
1.1.1.5   root     1372:                as = decode_fr (ks);
1.1       root     1373:                break;
                   1374: 
1.1.1.3   root     1375:            case KBD_LANG_US:
1.1.1.5   root     1376:                as = decode_us (ks);
1.1       root     1377:                break;
1.1.1.3   root     1378: 
1.1       root     1379:             case KBD_LANG_DE:
1.1.1.5   root     1380:                as = decode_de (ks);
1.1       root     1381:                break;
1.1.1.3   root     1382: 
1.1.1.13  root     1383:             case KBD_LANG_DK:
                   1384:                as = decode_dk (ks);
                   1385:                break;
                   1386: 
1.1       root     1387:             case KBD_LANG_SE:
1.1.1.5   root     1388:                as = decode_se (ks);
1.1       root     1389:                break;
1.1.1.3   root     1390: 
1.1       root     1391:             case KBD_LANG_IT:
1.1.1.5   root     1392:                as = decode_it (ks);
1.1       root     1393:                break;
                   1394: 
1.1.1.2   root     1395:             case KBD_LANG_ES:
1.1.1.5   root     1396:                as = decode_es (ks);
1.1.1.2   root     1397:                break;
                   1398: 
1.1       root     1399:             default:
                   1400:                as = -1;
                   1401:                break;
                   1402:            }
                   1403:        }
1.1.1.5   root     1404:        if (-1 != as)
1.1       root     1405:                return as;
                   1406:        index++;
                   1407:     } while (ks != NoSymbol);
                   1408:     return -1;
                   1409: }
                   1410: 
                   1411: static struct timeval lastMotionTime;
                   1412: 
1.1.1.3   root     1413: static int refresh_necessary = 0;
                   1414: 
1.1.1.5   root     1415: void handle_events (void)
1.1       root     1416: {
                   1417:     newmousecounters = 0;
1.1.1.5   root     1418:     gui_handle_events ();
1.1.1.3   root     1419: 
1.1       root     1420:     for (;;) {
                   1421:        XEvent event;
                   1422: #if 0
1.1.1.5   root     1423:        if (! XCheckMaskEvent (display, eventmask, &event))
                   1424:            break;
1.1       root     1425: #endif
1.1.1.5   root     1426:        if (! XPending (display))
                   1427:            break;
                   1428: 
                   1429:        XNextEvent (display, &event);
1.1.1.3   root     1430: 
1.1.1.5   root     1431:        switch (event.type) {
1.1.1.3   root     1432:         case KeyPress: {
1.1.1.5   root     1433:             int i;
                   1434:             int kc = keycode2amiga ((XKeyEvent *)&event);
1.1       root     1435: 
1.1.1.5   root     1436:             if (kc == -2) {
                   1437:                 for (i = 0; hotkeys[i].syms[0] != 0; i++) {
                   1438:                     if (hotkeys[i].mask == 0) {
                   1439:                         if (hotkeys[i].handler != NULL)
                   1440:                             hotkeys[i].handler();
                   1441:                     }
                   1442:                 }
1.1       root     1443:                 break;
1.1.1.5   root     1444:             }
1.1       root     1445: 
1.1.1.5   root     1446:             if (kc == -1)
1.1       root     1447:                 break;
1.1.1.5   root     1448:             if (! keystate[kc]) {
                   1449:                 keystate[kc] = 1;
                   1450:                 record_key (kc << 1);
1.1       root     1451:             }
                   1452:             break;
                   1453:         }
1.1.1.3   root     1454:         case KeyRelease: {
1.1.1.5   root     1455:             int kc = keycode2amiga ((XKeyEvent *)&event);
                   1456:             if (kc < 0)
                   1457:                 break;
1.1       root     1458:             keystate[kc] = 0;
                   1459:             record_key ((kc << 1) | 1);
                   1460:             break;
                   1461:         }
                   1462:         case ButtonPress:
                   1463:            buttonstate[((XButtonEvent *)&event)->button-1] = 1;
                   1464:            break;
                   1465:         case ButtonRelease:
                   1466:            buttonstate[((XButtonEvent *)&event)->button-1] = 0;
                   1467:            break;
1.1.1.5   root     1468:         case MotionNotify:
                   1469:            if (dgamode) {
                   1470:                newmousecounters = 0;
                   1471:                lastmx += ((XMotionEvent *)&event)->x_root;
                   1472:                lastmy += ((XMotionEvent *)&event)->y_root;
                   1473:            } else if (grabbed) {
                   1474:                int realmove = 0;
1.1.1.12  root     1475:                int tx, ty,ttx,tty;
1.1.1.5   root     1476:                
                   1477:                tx = ((XMotionEvent *)&event)->x;
                   1478:                ty = ((XMotionEvent *)&event)->y;
                   1479: 
                   1480:                if (! event.xmotion.send_event) {
                   1481:                    newmousecounters = 0;
                   1482:                    lastmx += tx - oldx;
                   1483:                    lastmy += ty - oldy;
                   1484:                    realmove = 1;
                   1485: #undef ABS
                   1486: #define ABS(a) (((a)<0) ? -(a) : (a) )
                   1487:                    if (ABS(current_width / 2 - tx) > 3 * current_width / 8
                   1488:                        || ABS(current_height / 2 - ty) > 3 * current_height / 8) 
                   1489:                    {
                   1490: #undef ABS
                   1491:                        XEvent event;
1.1.1.12  root     1492:                        ttx = current_width / 2;
                   1493:                        tty = current_height / 2;
1.1.1.5   root     1494:                        event.type = MotionNotify;
                   1495:                        event.xmotion.display = display;
                   1496:                        event.xmotion.window = mywin;
1.1.1.12  root     1497:                        event.xmotion.x = ttx;
                   1498:                        event.xmotion.y = tty;
1.1.1.5   root     1499:                        XSendEvent (display, mywin, False,
                   1500:                                    PointerMotionMask, &event);
1.1.1.12  root     1501:                        XWarpPointer (display, None, mywin, 0, 0, 0, 0, ttx, tty);
1.1.1.5   root     1502:                    }
1.1.1.12  root     1503:                } else {
1.1.1.15  root     1504:                    tx=event.xmotion.x;
                   1505:                    ty=event.xmotion.y;
1.1.1.5   root     1506:                }
                   1507:                oldx = tx;
                   1508:                oldy = ty;
                   1509:            } else if (inwindow) {
                   1510:                lastmx = ((XMotionEvent *)&event)->x;
                   1511:                lastmy = ((XMotionEvent *)&event)->y;
1.1.1.6   root     1512:                if (! cursorOn && !currprefs.x11_hide_cursor) {
1.1.1.5   root     1513:                    XDefineCursor(display, mywin, xhairCursor);
                   1514:                    cursorOn = 1;
                   1515:                }
                   1516:                gettimeofday(&lastMotionTime, NULL);
                   1517:            }
                   1518:            break;
1.1       root     1519:         case EnterNotify:
                   1520:            newmousecounters = 1;
                   1521:            lastmx = ((XCrossingEvent *)&event)->x;
                   1522:            lastmy = ((XCrossingEvent *)&event)->y;
                   1523:            inwindow = 1;
                   1524:            break;
                   1525:         case LeaveNotify:
                   1526:            inwindow = 0;
                   1527:            break;
                   1528:         case FocusIn:
1.1.1.5   root     1529:            if (! autorepeatoff)
                   1530:                XAutoRepeatOff (display);
1.1       root     1531:            autorepeatoff = 1;
                   1532:            break;
                   1533:         case FocusOut:
                   1534:            if (autorepeatoff)
1.1.1.5   root     1535:                XAutoRepeatOn (display);
1.1       root     1536:            autorepeatoff = 0;
                   1537:            break;
                   1538:         case Expose:
1.1.1.3   root     1539:            refresh_necessary = 1;
1.1       root     1540:            break;
1.1.1.7   root     1541:          case ClientMessage:
                   1542:             if (event.xclient.data.l[0]==delete_win) {
                   1543:                uae_quit ();
                   1544:             }
                   1545:             break;
1.1       root     1546:        }
                   1547:     }
1.1.1.5   root     1548: 
                   1549: #if defined PICASSO96
                   1550:     if (! dgamode) {
                   1551:        if (screen_is_picasso && refresh_necessary) {
                   1552:            DO_PUTIMAGE (pic_dinfo.ximg, 0, 0, 0, 0,
                   1553:                         picasso_vidinfo.width, picasso_vidinfo.height);
                   1554:            refresh_necessary = 0;
                   1555:            memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines);
                   1556:        } else if (screen_is_picasso && picasso_has_invalid_lines) {
                   1557:            int i;
                   1558:            int strt = -1;
                   1559: 
                   1560:            picasso_invalid_lines[picasso_vidinfo.height] = 0;
                   1561:            for (i = picasso_invalid_start; i < picasso_invalid_stop + 2; i++) {
                   1562:                if (picasso_invalid_lines[i]) {
                   1563:                    picasso_invalid_lines[i] = 0;
                   1564:                    if (strt != -1)
                   1565:                        continue;
                   1566:                    strt = i;
                   1567:                } else {
                   1568:                    if (strt == -1)
                   1569:                        continue;
                   1570:                    DO_PUTIMAGE (pic_dinfo.ximg, 0, strt, 0, strt,
                   1571:                                 picasso_vidinfo.width, i - strt);
                   1572:                    strt = -1;
                   1573:                }
1.1.1.3   root     1574:            }
1.1.1.5   root     1575:            if (strt != -1)
                   1576:                abort ();
1.1.1.3   root     1577:        }
                   1578:     }
1.1.1.5   root     1579:     picasso_has_invalid_lines = 0;
                   1580:     picasso_invalid_start = picasso_vidinfo.height + 1;
                   1581:     picasso_invalid_stop = -1;
1.1.1.3   root     1582: #endif
1.1.1.5   root     1583:     
                   1584:     if (! dgamode) {
                   1585:        if (! screen_is_picasso && refresh_necessary) {
                   1586:            DO_PUTIMAGE (ami_dinfo.ximg, 0, 0, 0, 0, currprefs.gfx_width, currprefs.gfx_height);
                   1587:            refresh_necessary = 0;
                   1588:        }
1.1.1.6   root     1589:        if (cursorOn && !currprefs.x11_hide_cursor) {
1.1.1.5   root     1590:            struct timeval now;
                   1591:            int diff;
                   1592:            gettimeofday(&now, NULL);
                   1593:            diff = (now.tv_sec - lastMotionTime.tv_sec) * 1000000 +
                   1594:                (now.tv_usec - lastMotionTime.tv_usec);
                   1595:            if (diff > 1000000) {
                   1596:                XDefineCursor (display, mywin, blankCursor);
                   1597:                cursorOn = 0;
                   1598:            }
1.1       root     1599:        }
                   1600:     }
                   1601:     /* "Affengriff" */
1.1.1.6   root     1602:     if ((keystate[AK_CTRL] || keystate[AK_RCTRL]) && keystate[AK_LAMI] && keystate[AK_RAMI])
1.1.1.5   root     1603:        uae_reset ();
1.1       root     1604: }
                   1605: 
1.1.1.5   root     1606: int check_prefs_changed_gfx (void)
1.1       root     1607: {
1.1.1.5   root     1608:     if (changed_prefs.gfx_width != currprefs.gfx_width
                   1609:        || changed_prefs.gfx_height != currprefs.gfx_height)
                   1610:        fixup_prefs_dimensions (&changed_prefs);
                   1611: 
                   1612:     if (changed_prefs.gfx_width == currprefs.gfx_width
                   1613:        && changed_prefs.gfx_height == currprefs.gfx_height
                   1614:        && changed_prefs.gfx_lores == currprefs.gfx_lores
                   1615:        && changed_prefs.gfx_linedbl == currprefs.gfx_linedbl
                   1616:        && changed_prefs.gfx_correct_aspect == currprefs.gfx_correct_aspect
                   1617:        && changed_prefs.gfx_xcenter == currprefs.gfx_xcenter
                   1618:        && changed_prefs.gfx_ycenter == currprefs.gfx_ycenter
                   1619:        && changed_prefs.gfx_afullscreen == currprefs.gfx_afullscreen
                   1620:        && changed_prefs.gfx_pfullscreen == currprefs.gfx_pfullscreen)
                   1621:        return 0;
1.1.1.6   root     1622: 
                   1623:     graphics_subshutdown ();
                   1624:     currprefs.gfx_width = changed_prefs.gfx_width;
                   1625:     currprefs.gfx_height = changed_prefs.gfx_height;
                   1626:     currprefs.gfx_lores = changed_prefs.gfx_lores;
                   1627:     currprefs.gfx_linedbl = changed_prefs.gfx_linedbl;
                   1628:     currprefs.gfx_correct_aspect = changed_prefs.gfx_correct_aspect;
                   1629:     currprefs.gfx_xcenter = changed_prefs.gfx_xcenter;
                   1630:     currprefs.gfx_ycenter = changed_prefs.gfx_ycenter;
                   1631:     currprefs.gfx_afullscreen = changed_prefs.gfx_afullscreen;
                   1632:     currprefs.gfx_pfullscreen = changed_prefs.gfx_pfullscreen;
1.1.1.10  root     1633: 
                   1634:     gui_update_gfx ();
                   1635: 
1.1.1.6   root     1636:     graphics_subinit ();
                   1637: 
                   1638:     if (! inwindow)
                   1639:        XWarpPointer (display, None, mywin, 0, 0, 0, 0,
                   1640:                      current_width / 2, current_height / 2);
                   1641: 
                   1642:     notice_screen_contents_lost ();
                   1643:     init_row_map ();
                   1644:     if (screen_is_picasso)
                   1645:        picasso_enablescreen (1);
1.1.1.5   root     1646:     return 0;
1.1       root     1647: }
                   1648: 
1.1.1.5   root     1649: int debuggable (void)
1.1       root     1650: {
                   1651:     return 1;
                   1652: }
                   1653: 
1.1.1.5   root     1654: int needmousehack (void)
                   1655: {
1.1.1.13  root     1656:     if (dgamode || grabbed)
1.1.1.5   root     1657:        return 0;
                   1658:     else
                   1659:        return 1;
                   1660: }
                   1661: 
                   1662: void LED (int on)
1.1       root     1663: {
1.1.1.2   root     1664: #if 0 /* Maybe that is responsible for the joystick emulation problems on SunOS? */
1.1       root     1665:     static int last_on = -1;
                   1666:     XKeyboardControl control;
                   1667: 
1.1.1.5   root     1668:     if (last_on == on)
                   1669:        return;
1.1       root     1670:     last_on = on;
                   1671:     control.led = 1; /* implementation defined */
                   1672:     control.led_mode = on ? LedModeOn : LedModeOff;
                   1673:     XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
1.1.1.2   root     1674: #endif
1.1       root     1675: }
                   1676: 
1.1.1.3   root     1677: #ifdef PICASSO96
                   1678: 
                   1679: void DX_Invalidate (int first, int last)
                   1680: {
1.1.1.5   root     1681:     if (first > last)
                   1682:        return;
                   1683: 
                   1684:     picasso_has_invalid_lines = 1;
                   1685:     if (first < picasso_invalid_start)
                   1686:        picasso_invalid_start = first;
                   1687:     if (last > picasso_invalid_stop)
                   1688:        picasso_invalid_stop = last;
                   1689: 
                   1690:     while (first <= last) {
1.1.1.3   root     1691:        picasso_invalid_lines[first] = 1;
                   1692:        first++;
1.1.1.5   root     1693:     } 
1.1.1.3   root     1694: }
                   1695: 
                   1696: int DX_BitsPerCannon (void)
                   1697: {
                   1698:     return 8;
                   1699: }
                   1700: 
1.1.1.5   root     1701: void DX_SetPalette (int start, int count)
1.1.1.3   root     1702: {
1.1.1.5   root     1703:     if (! screen_is_picasso || picasso96_state.RGBFormat != RGBFB_CHUNKY)
1.1.1.3   root     1704:        return;
                   1705: 
1.1.1.5   root     1706:     if (picasso_vidinfo.pixbytes != 1) {
                   1707:        /* This is the case when we're emulating a 256 color display.  */
                   1708:        while (count-- > 0) {
                   1709:            int r = picasso96_state.CLUT[start].Red;
                   1710:            int g = picasso96_state.CLUT[start].Green;
                   1711:            int b = picasso96_state.CLUT[start].Blue;
                   1712:            picasso_vidinfo.clut[start++] = (doMask256 (r, red_bits, red_shift)
                   1713:                                             | doMask256 (g, green_bits, green_shift)
                   1714:                                             | doMask256 (b, blue_bits, blue_shift));
                   1715:        }
                   1716:        return;
                   1717:     }
                   1718:     
1.1.1.3   root     1719:     while (count-- > 0) {
                   1720:        XColor col = parsed_xcolors[start];
                   1721:        col.red = picasso96_state.CLUT[start].Red * 0x0101;
                   1722:        col.green = picasso96_state.CLUT[start].Green * 0x0101;
                   1723:        col.blue = picasso96_state.CLUT[start].Blue * 0x0101;
                   1724:        XStoreColor (display, cmap, &col);
                   1725:        XStoreColor (display, cmap2, &col);
                   1726:        start++;
                   1727:     }
                   1728: #ifdef USE_DGA_EXTENSION
1.1.1.5   root     1729:     if (dgamode) {
                   1730:        dga_colormap_installed ^= 1;
                   1731:        if (dga_colormap_installed == 1)
                   1732:            XF86DGAInstallColormap (display, screen, cmap2);
                   1733:        else
                   1734:            XF86DGAInstallColormap (display, screen, cmap);
                   1735:     }
1.1.1.3   root     1736: #endif
                   1737: }
                   1738: 
                   1739: #define MAX_SCREEN_MODES 11
                   1740: 
                   1741: static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280 };
                   1742: static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768, 864, 1024 };
                   1743: 
                   1744: int DX_FillResolutions (uae_u16 *ppixel_format)
                   1745: {
                   1746:     Screen *scr = ScreenOfDisplay (display, screen);
                   1747:     int i, count = 0;
                   1748:     int w = WidthOfScreen (scr);
                   1749:     int h = HeightOfScreen (scr);
1.1.1.5   root     1750:     int emulate_chunky = 0;
1.1.1.3   root     1751: 
1.1.1.5   root     1752:     picasso_vidinfo.rgbformat = (bit_unit == 8 ? RGBFB_CHUNKY
                   1753:                                 : bitdepth == 15 && bit_unit == 16 ? RGBFB_R5G5B5PC
                   1754:                                 : bitdepth == 16 && bit_unit == 16 ? RGBFB_R5G6B5PC
                   1755:                                 : bit_unit == 24 ? RGBFB_B8G8R8
                   1756:                                 : bit_unit == 32 ? RGBFB_B8G8R8A8
                   1757:                                 : RGBFB_NONE);
                   1758: 
                   1759:     *ppixel_format = 1 << picasso_vidinfo.rgbformat;
                   1760:     if (visualInfo.VI_CLASS == TrueColor && (bit_unit == 16 || bit_unit == 32))
                   1761:        *ppixel_format |= RGBFF_CHUNKY, emulate_chunky = 1;
1.1.1.3   root     1762: 
                   1763: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
1.1.1.5   root     1764:     if (dgaavail && vidmodeavail) {
                   1765:        for (i = 0; i < vidmodecount && count < MAX_PICASSO_MODES; i++) {
                   1766:            int j;
                   1767:            for (j = 0; j <= emulate_chunky && count < MAX_PICASSO_MODES; j++) {
                   1768:                DisplayModes[count].res.width = allmodes[i]->hdisplay;
                   1769:                DisplayModes[count].res.height = allmodes[i]->vdisplay;
                   1770:                DisplayModes[count].depth = j == 1 ? 1 : bit_unit >> 3;
                   1771:                DisplayModes[count].refresh = 75;
                   1772:                count++;
                   1773:            }
1.1.1.3   root     1774:        }
1.1.1.5   root     1775:     } else
1.1.1.3   root     1776: #endif
1.1.1.5   root     1777:     {
                   1778:        for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES; i++) {
                   1779:            int j;
                   1780:            for (j = 0; j <= emulate_chunky && count < MAX_PICASSO_MODES; j++) {
                   1781:                if (x_size_table[i] <= w && y_size_table[i] <= h) {
                   1782:                    if (x_size_table[i] > picasso_maxw)
                   1783:                        picasso_maxw = x_size_table[i];
                   1784:                    if (y_size_table[i] > picasso_maxh)
                   1785:                        picasso_maxh = y_size_table[i];
                   1786:                    DisplayModes[count].res.width = x_size_table[i];
                   1787:                    DisplayModes[count].res.height = y_size_table[i];
                   1788:                    DisplayModes[count].depth = j == 1 ? 1 : bit_unit >> 3;
                   1789:                    DisplayModes[count].refresh = 75;
                   1790:                    count++;
                   1791:                }
                   1792:            }
                   1793:        }
                   1794:     }
1.1.1.3   root     1795: 
                   1796:     return count;
                   1797: }
                   1798: 
                   1799: static void set_window_for_picasso (void)
                   1800: {
1.1.1.5   root     1801:     if (current_width == picasso_vidinfo.width && current_height == picasso_vidinfo.height)
                   1802:        return;
1.1.1.3   root     1803: 
1.1.1.17  root     1804:     graphics_subshutdown ();
1.1.1.5   root     1805:     current_width = picasso_vidinfo.width;
                   1806:     current_height = picasso_vidinfo.height;
1.1.1.17  root     1807:     graphics_subinit ();
1.1.1.3   root     1808: }
                   1809: 
1.1.1.5   root     1810: void gfx_set_picasso_modeinfo (int w, int h, int depth, int rgbfmt)
1.1.1.3   root     1811: {
                   1812:     picasso_vidinfo.width = w;
                   1813:     picasso_vidinfo.height = h;
                   1814:     picasso_vidinfo.depth = depth;
1.1.1.4   root     1815:     picasso_vidinfo.pixbytes = bit_unit >> 3;
1.1.1.3   root     1816: 
                   1817:     if (screen_is_picasso)
                   1818:        set_window_for_picasso ();
                   1819: }
                   1820: 
                   1821: void gfx_set_picasso_baseaddr (uaecptr a)
                   1822: {
                   1823: }
                   1824: 
                   1825: void gfx_set_picasso_state (int on)
                   1826: {
                   1827:     if (on == screen_is_picasso)
                   1828:        return;
1.1.1.5   root     1829:     graphics_subshutdown ();
1.1.1.3   root     1830:     screen_is_picasso = on;
1.1.1.5   root     1831:     if (on) {
                   1832:        current_width = picasso_vidinfo.width;
                   1833:        current_height = picasso_vidinfo.height;
                   1834:     } else {
                   1835:        current_width = gfxvidinfo.width;
                   1836:        current_height = gfxvidinfo.height;
                   1837:     }
                   1838:     graphics_subinit ();
1.1.1.3   root     1839:     if (on)
1.1.1.5   root     1840:        DX_SetPalette (0, 256);
                   1841: }
                   1842: 
                   1843: uae_u8 *gfx_lock_picasso (void)
                   1844: {
                   1845: #ifdef USE_DGA_EXTENSION
                   1846:     if (dgamode)
                   1847:        return fb_addr;
1.1.1.3   root     1848:     else
1.1.1.5   root     1849: #endif
                   1850:        return pic_dinfo.ximg->data;
                   1851: }
                   1852: void gfx_unlock_picasso (void)
                   1853: {
1.1.1.3   root     1854: }
1.1.1.5   root     1855: #endif
1.1.1.3   root     1856: 
1.1.1.5   root     1857: int lockscr (void)
1.1       root     1858: {
1.1.1.5   root     1859:     return 1;
1.1       root     1860: }
1.1.1.3   root     1861: 
1.1.1.5   root     1862: void unlockscr (void)
1.1.1.3   root     1863: {
                   1864: }
                   1865: 
1.1.1.5   root     1866: static void handle_mousegrab (void)
1.1.1.3   root     1867: {
1.1.1.5   root     1868:     if (grabbed) {
                   1869:        XUngrabPointer (display, CurrentTime);
                   1870:        XUndefineCursor (display, mywin);
                   1871:        grabbed = 0;
                   1872:     } else if (! dgamode) {
                   1873:        XGrabPointer (display, mywin, 1, 0, GrabModeAsync, GrabModeAsync,
                   1874:                      mywin, blankCursor, CurrentTime);
                   1875:        oldx = current_width / 2;
                   1876:        oldy = current_height / 2;
                   1877:        XWarpPointer (display, None, mywin, 0, 0, 0, 0, oldx, oldy);
                   1878:        grabbed = 1;
                   1879:     }
1.1.1.3   root     1880: }
1.1.1.5   root     1881: 
                   1882: static void handle_inhibit (void)
1.1.1.3   root     1883: {
1.1.1.6   root     1884:     toggle_inhibit_frame (IHF_SCROLLLOCK);
1.1.1.5   root     1885: }
                   1886: 
1.1.1.7   root     1887: #include "gensound.h"
                   1888: #include "sounddep/sound.h"
                   1889: #include "events.h"
                   1890: #include "audio.h"
                   1891: 
                   1892: static void handle_interpol (void)
                   1893: {
1.1.1.8   root     1894:     if (currprefs.sound_interpol == 0) {
                   1895:        currprefs.sound_interpol = 1;
                   1896:        printf ("Interpol on: rh\n");
                   1897:     }
                   1898:     else if (currprefs.sound_interpol == 1) {
                   1899:        currprefs.sound_interpol = 2;
                   1900:        printf ("Interpol on: crux\n");
1.1.1.7   root     1901:     }
1.1.1.8   root     1902:     else {
                   1903:        currprefs.sound_interpol = 0;
                   1904:        printf ("Interpol off\n");
                   1905:     }    
1.1.1.7   root     1906: }
                   1907: 
1.1.1.5   root     1908: static void framerate_up (void)
                   1909: {
1.1.1.7   root     1910:     if (currprefs.gfx_framerate < 20)
                   1911:        changed_prefs.gfx_framerate = currprefs.gfx_framerate + 1;
1.1.1.5   root     1912: }
                   1913: 
                   1914: static void framerate_down (void)
                   1915: {
1.1.1.7   root     1916:     if (currprefs.gfx_framerate > 1)
                   1917:        changed_prefs.gfx_framerate = currprefs.gfx_framerate - 1;
1.1.1.3   root     1918: }
1.1.1.6   root     1919: 
                   1920: static void handle_modeswitch (void)
                   1921: {
                   1922:     changed_prefs.gfx_afullscreen = changed_prefs.gfx_pfullscreen = !dgamode;
                   1923: }
                   1924: 
                   1925: void target_save_options (FILE *f, struct uae_prefs *p)
                   1926: {
                   1927:     fprintf (f, "x11.low_bandwidth=%s\n", p->x11_use_low_bandwidth ? "true" : "false");
                   1928:     fprintf (f, "x11.use_mitshm=%s\n", p->x11_use_mitshm ? "true" : "false");
                   1929:     fprintf (f, "x11.hide_cursor=%s\n", p->x11_hide_cursor ? "true" : "false");
                   1930: }
                   1931: 
                   1932: int target_parse_option (struct uae_prefs *p, char *option, char *value)
                   1933: {
                   1934:     return (cfgfile_yesno (option, value, "low_bandwidth", &p->x11_use_low_bandwidth)
                   1935:            || cfgfile_yesno (option, value, "use_mitshm", &p->x11_use_mitshm)
                   1936:            || cfgfile_yesno (option, value, "hide_cursor", &p->x11_hide_cursor));
                   1937: }

unix.superglobalmegacorp.com

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