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

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

unix.superglobalmegacorp.com

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