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

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.1.19  root       11:   * Copyright 2003-2004 Richard Drummond
1.1       root       12:   */
                     13: 
                     14: #include "sysconfig.h"
                     15: #include "sysdeps.h"
                     16: 
                     17: #include <X11/Xlib.h>
                     18: #include <X11/Xutil.h>
                     19: #include <X11/keysym.h>
                     20: #include <X11/cursorfont.h>
                     21: 
                     22: #include <ctype.h>
                     23: #include <signal.h>
                     24: 
                     25: #include "options.h"
1.1.1.14  root       26: #include "threaddep/thread.h"
1.1.1.3   root       27: #include "uae.h"
1.1       root       28: #include "memory.h"
1.1.1.6   root       29: #include "xwin.h"
1.1       root       30: #include "custom.h"
1.1.1.6   root       31: #include "drawing.h"
1.1       root       32: #include "newcpu.h"
                     33: #include "keyboard.h"
                     34: #include "keybuf.h"
                     35: #include "gui.h"
                     36: #include "debug.h"
1.1.1.3   root       37: #include "picasso96.h"
1.1.1.18  root       38: #include "inputdevice.h"
1.1.1.19  root       39: #include "hotkeys.h"
1.1.1.3   root       40: 
                     41: #ifdef __cplusplus
                     42: #define VI_CLASS c_class
                     43: #else
                     44: #define VI_CLASS class
                     45: #endif
1.1       root       46: 
1.1.1.2   root       47: #ifdef USE_DGA_EXTENSION
1.1.1.3   root       48: 
                     49: #ifdef USE_VIDMODE_EXTENSION
                     50: #include <X11/extensions/xf86vmode.h>
                     51: #define VidMode_MINMAJOR 0
                     52: #define VidMode_MINMINOR 0
                     53: #endif
                     54: 
1.1.1.2   root       55: #include <X11/extensions/xf86dga.h>
                     56: #define DGA_MINMAJOR 0
                     57: #define DGA_MINMINOR 0
1.1.1.3   root       58: 
1.1.1.5   root       59: #endif /* USE_DGA_EXTENSION */
                     60: 
                     61: #if SHM_SUPPORT_LINKS == 1
1.1.1.3   root       62: 
                     63: #include <sys/ipc.h>
                     64: #include <sys/shm.h>
                     65: #include <X11/extensions/XShm.h>
                     66: 
                     67: #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
                     68:     do { \
1.1.1.12  root       69:        if (currprefs.x11_use_mitshm && shmavail) \
1.1.1.5   root       70:             XShmPutImage (display, mywin, mygc, (IMG), (SRCX), (SRCY), (DSTX), (DSTY), (WIDTH), (HEIGHT), 0); \
1.1.1.3   root       71:        else \
1.1.1.5   root       72:            XPutImage (display, mywin, mygc, (IMG), (SRCX), (SRCY), (DSTX), (DSTY), (WIDTH), (HEIGHT)); \
1.1.1.3   root       73:     } while (0)
                     74: #else
                     75: #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
1.1.1.5   root       76:     XPutImage (display, mywin, mygc, (IMG), (SRCX), (SRCY), (DSTX), (DSTY), (WIDTH), (HEIGHT))
1.1.1.2   root       77: #endif
                     78: 
1.1       root       79: #ifdef __cplusplus
                     80: static RETSIGTYPE sigbrkhandler(...)
                     81: #else
1.1.1.5   root       82: static RETSIGTYPE sigbrkhandler (int foo)
1.1       root       83: #endif
                     84: {
                     85:     activate_debugger();
                     86: 
                     87: #if !defined(__unix) || defined(__NeXT__)
1.1.1.5   root       88:     signal (SIGINT, sigbrkhandler);
1.1       root       89: #endif
                     90: }
                     91: 
1.1.1.5   root       92: void setup_brkhandler (void)
1.1       root       93: {
                     94: #if defined(__unix) && !defined(__NeXT__)
                     95:     struct sigaction sa;
                     96:     sa.sa_handler = sigbrkhandler;
                     97:     sa.sa_flags = 0;
                     98: #ifdef SA_RESTART
                     99:     sa.sa_flags = SA_RESTART;
                    100: #endif
1.1.1.5   root      101:     sigemptyset (&sa.sa_mask);
                    102:     sigaction (SIGINT, &sa, NULL);
1.1       root      103: #else
1.1.1.5   root      104:     signal (SIGINT, sigbrkhandler);
1.1.1.2   root      105: #endif
1.1.1.3   root      106: }
1.1.1.2   root      107: 
1.1.1.5   root      108: struct disp_info {
                    109:     XImage *ximg;
                    110:     char *image_mem;
                    111: #if SHM_SUPPORT_LINKS == 1
                    112:     XShmSegmentInfo shminfo;
                    113: #endif
                    114: };
                    115: 
1.1       root      116: static Display *display;
                    117: static int screen;
                    118: static Window rootwin, mywin;
1.1.1.7   root      119: static Atom delete_win;
1.1       root      120: 
1.1.1.5   root      121: static GC mygc;
                    122: static XColor black, white;
1.1.1.3   root      123: static Colormap cmap, cmap2;
1.1.1.5   root      124: static int red_bits, green_bits, blue_bits;
                    125: static int red_shift, green_shift, blue_shift;
1.1.1.3   root      126: 
1.1.1.5   root      127: /* Kludge-O-Matic.
                    128:  * Unfortunately the X server loses colormap changes in DGA mode. Switching
                    129:  * back and forth between two identical colormaps fixes this problem.  */
1.1.1.3   root      130: static int dga_colormap_installed;
1.1       root      131: 
                    132: static int need_dither;
                    133: 
1.1.1.3   root      134: static char picasso_invalid_lines[1201];
1.1.1.5   root      135: static int picasso_has_invalid_lines;
                    136: static int picasso_invalid_start, picasso_invalid_stop;
                    137: static int picasso_maxw = 0, picasso_maxh = 0;
1.1.1.3   root      138: 
1.1       root      139: static int autorepeatoff = 0;
1.1.1.5   root      140: static struct disp_info ami_dinfo, pic_dinfo;
1.1       root      141: static Visual *vis;
                    142: static XVisualInfo visualInfo;
                    143: static int bitdepth, bit_unit;
                    144: static Cursor blankCursor, xhairCursor;
                    145: static int cursorOn;
1.1.1.3   root      146: static int inverse_byte_order = 0;
1.1       root      147: 
1.1.1.3   root      148: static int current_width, current_height;
1.1       root      149: 
1.1.1.2   root      150: static int x11_init_ok;
1.1.1.5   root      151: static int dgaavail = 0, vidmodeavail = 0, shmavail = 0;
                    152: static int dgamode;
                    153: static int grabbed;
                    154: 
1.1.1.19  root      155: void toggle_mousegrab (void);
                    156: void framerate_up (void);
                    157: void framerate_down (void);
                    158: int xkeysym2amiga (int);
                    159: struct uae_hotkeyseq *get_x11_default_hotkeys (void);
1.1.1.5   root      160: 
1.1.1.19  root      161: int pause_emulation;
1.1.1.5   root      162: 
1.1.1.19  root      163: static int oldx, oldy;
1.1       root      164: static int inwindow;
1.1.1.19  root      165: 
1.1.1.5   root      166: #define EVENTMASK (KeyPressMask|KeyReleaseMask|ButtonPressMask \
                    167:                   |ButtonReleaseMask|PointerMotionMask \
                    168:                   |FocusChangeMask|EnterWindowMask \
                    169:                   |ExposureMask |LeaveWindowMask)
                    170: #define DGA_EVENTMASK (KeyPressMask|KeyReleaseMask|ButtonPressMask \
                    171:                       |ButtonReleaseMask|PointerMotionMask)
                    172: 
                    173: #if SHM_SUPPORT_LINKS == 1
                    174: /* Hack to detect shm-failure, probably due to displaying on a
                    175:  * remote server. */
                    176: static int shmerror;
                    177: static int (*oldshmerrorhandler) (Display *, XErrorEvent *);
                    178: 
                    179: static int shmerrorhandler (Display *dsp, XErrorEvent *ev)
                    180: {
                    181:     if (ev->error_code == BadAccess)
                    182:        shmerror=1;
                    183:     else
                    184:        (*oldshmerrorhandler) (dsp, ev);
                    185:     return 0;
                    186: }
1.1.1.2   root      187: #endif
1.1       root      188: 
1.1.1.5   root      189: static void get_image (int w, int h, struct disp_info *dispi)
1.1.1.3   root      190: {
                    191:     XImage *new_img;
                    192:     char *p;
                    193: 
                    194: #if SHM_SUPPORT_LINKS == 1
1.1.1.6   root      195:     if (currprefs.x11_use_mitshm && shmavail) {
1.1.1.5   root      196:        XShmSegmentInfo *shminfo = &dispi->shminfo;
1.1.1.3   root      197: 
                    198:        new_img = XShmCreateImage (display, vis, bitdepth, ZPixmap, 0, shminfo, w, h);
                    199: 
                    200:        shminfo->shmid = shmget (IPC_PRIVATE, h * new_img->bytes_per_line,
                    201:                                 IPC_CREAT | 0777);
                    202:        shminfo->shmaddr = new_img->data = (char *)shmat (shminfo->shmid, 0, 0);
1.1.1.5   root      203:        dispi->image_mem = new_img->data;
1.1.1.3   root      204:        shminfo->readOnly = False;
1.1.1.5   root      205:        /* Try to let the Xserver attach */
                    206:        shmerror = 0;
                    207:        oldshmerrorhandler = XSetErrorHandler (shmerrorhandler);
1.1.1.3   root      208:        XShmAttach (display, shminfo);
1.1.1.5   root      209:        XSync (display, 0);
                    210:        XSetErrorHandler (oldshmerrorhandler);
                    211:        if (shmerror) {
                    212:            shmdt (shminfo->shmaddr);
                    213:            XDestroyImage (new_img);
                    214:            shminfo->shmid = -1;
                    215:            shmavail = 0;
1.1.1.16  root      216:            write_log ("MIT-SHM extension failed, trying fallback.\n");
1.1.1.5   root      217:        } else {
                    218:            /* now deleting means making it temporary */
                    219:            shmctl (shminfo->shmid, IPC_RMID, 0);
                    220:            dispi->ximg = new_img;
1.1.1.19  root      221:            write_log ("Using MIT-SHM extension.\n");
1.1.1.5   root      222:            return;
                    223:        }
1.1.1.3   root      224:     }
                    225: #endif
                    226: 
                    227:     /* Question for people who know about X: Could we allocate the buffer
                    228:      * after creating the image and then do new_img->data = buffer, as above in
                    229:      * the SHM case?
                    230:      */
1.1.1.19  root      231:     write_log ("Using normal image buffer.\n");
1.1.1.3   root      232:     p = (char *)xmalloc (h * w * ((bit_unit + 7) / 8)); /* ??? */
                    233:     new_img = XCreateImage (display, vis, bitdepth, ZPixmap, 0, p,
                    234:                            w, h, 32, 0);
                    235:     if (new_img->bytes_per_line != w * ((bit_unit + 7) / 8))
1.1.1.16  root      236:        write_log ("Possible bug here... graphics may look strange.\n");
1.1.1.3   root      237: 
1.1.1.5   root      238:     dispi->image_mem = p;
                    239:     dispi->ximg = new_img;
1.1.1.3   root      240: }
                    241: 
                    242: #ifdef USE_VIDMODE_EXTENSION
                    243: static XF86VidModeModeInfo **allmodes;
                    244: static int vidmodecount;
                    245: 
1.1.1.21  root      246: static int sortfn (const void *a, const void *b)
                    247: {
                    248:     XF86VidModeInfo **ppa = a, *ppb = b;
                    249:     XF86VidModeInfo *pa = *ppa, *pb = *ppb;
                    250:     if (pa->hdisplay != pb->hdisplay)
                    251:        return pa->hdisplay - pb->hdisplay;
                    252:     return pa->vdisplay - pb->vdisplay;
                    253: }
                    254: 
1.1.1.3   root      255: static int get_vidmodes (void)
                    256: {
1.1.1.21  root      257:     int i;
                    258:     
                    259:     if (!XF86VidModeGetAllModeLines (display, screen, &vidmodecount, &allmodes))
                    260:        return 0;
                    261: 
                    262:     qsort (allmodes, vidmodecount, sizeof *allmode, sortfn);
                    263: 
                    264:     gfx_fullscreen_modes = sizeof (struct uae_rect) * vidmodecount;
                    265:     n_fullscreen_modes = vidmodecount;
                    266:     for (i = 0; i < vidmodecount; i++) {
                    267:        gfx_fullscreen_modes[i].w = allmodes[i].hdisplay;
                    268:        gfx_fullscreen_modes[i].h = allmodes[i].vdisplay;
                    269:     }
1.1.1.3   root      270: }
1.1.1.4   root      271: #endif
1.1.1.3   root      272: 
1.1.1.5   root      273: #ifdef USE_DGA_EXTENSION
                    274: 
                    275: static int fb_bank, fb_banks, fb_mem;
                    276: static char *fb_addr;
                    277: static int fb_width;
                    278: 
1.1.1.3   root      279: static void switch_to_best_mode (void)
                    280: {
1.1.1.14  root      281:     Screen *scr = ScreenOfDisplay (display, screen);
                    282:     int w = WidthOfScreen (scr);
                    283:     int h = HeightOfScreen (scr);
                    284:     int d = DefaultDepthOfScreen (scr);
1.1.1.5   root      285: #ifdef USE_VIDMODE_EXTENSION
1.1.1.14  root      286:     int i, best;
1.1.1.5   root      287:     if (vidmodeavail) {
                    288:        best = 0;
                    289:        for (i = 1; i < vidmodecount; i++) {
                    290:            if (allmodes[i]->hdisplay >= current_width
                    291:                && allmodes[i]->vdisplay >= current_height
                    292:                && allmodes[i]->hdisplay <= allmodes[best]->hdisplay
                    293:                && allmodes[i]->vdisplay <= allmodes[best]->vdisplay)
                    294:                best = i;
                    295:        }
1.1.1.19  root      296:        write_log ("entering DGA mode: %dx%d (%d, %d)\n",
1.1.1.5   root      297:                allmodes[best]->hdisplay, allmodes[best]->vdisplay,
                    298:                current_width, current_height);
                    299:        XF86VidModeSwitchToMode (display, screen, allmodes[best]);
                    300:        XF86VidModeSetViewPort (display, screen, 0, 0);
                    301:     }
1.1.1.4   root      302: #endif
1.1.1.3   root      303:     XMoveWindow (display, mywin, 0, 0);
                    304:     XWarpPointer (display, None, rootwin, 0, 0, 0, 0, 0, 0);
1.1.1.5   root      305:     XF86DGADirectVideo (display, screen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb);
                    306:     XF86DGASetViewPort (display, screen, 0, 0);
1.1.1.14  root      307:     memset (fb_addr, 0, (w * h) * (d / 8));
1.1.1.3   root      308: }
                    309: 
                    310: static void enter_dga_mode (void)
                    311: {
                    312:     XRaiseWindow (display, mywin);
                    313: 
                    314:     /* We want all the key presses */
                    315:     XGrabKeyboard (display, rootwin, 1, GrabModeAsync,
                    316:                   GrabModeAsync,  CurrentTime);
                    317: 
                    318:     /* and all the mouse moves */
                    319:     XGrabPointer (display, rootwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
                    320:                  GrabModeAsync, GrabModeAsync, None,  None, CurrentTime);
                    321: 
                    322:     switch_to_best_mode ();
                    323: 
                    324:     gfxvidinfo.rowbytes = fb_width*gfxvidinfo.pixbytes;
                    325:     gfxvidinfo.bufmem = fb_addr;
1.1.1.5   root      326:     gfxvidinfo.linemem = 0;
                    327:     gfxvidinfo.emergmem = malloc (gfxvidinfo.rowbytes);
                    328:     gfxvidinfo.maxblocklines = 10000;
1.1.1.3   root      329: }
                    330: 
                    331: static void leave_dga_mode (void)
                    332: {
1.1.1.14  root      333:     XF86DGADirectVideo (display, screen, 0);
                    334:     XUngrabPointer (display, CurrentTime);
                    335:     XUngrabKeyboard (display, CurrentTime);
1.1.1.3   root      336: #ifdef USE_VIDMODE_EXTENSION
1.1.1.5   root      337:     if (vidmodeavail)
                    338:        XF86VidModeSwitchToMode (display, screen, allmodes[0]);
1.1.1.3   root      339: #endif
                    340: }
                    341: #endif
1.1.1.5   root      342: 
1.1.1.3   root      343: static char *oldpixbuf;
1.1       root      344: 
1.1.1.5   root      345: void flush_line (int y)
1.1       root      346: {
1.1.1.5   root      347:     char *linebuf = gfxvidinfo.linemem;
                    348:     int xs, xe;
1.1.1.3   root      349:     int len;
1.1       root      350: 
1.1.1.3   root      351:     if (linebuf == NULL)
                    352:        linebuf = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
                    353: 
1.1.1.5   root      354: #ifdef USE_DGA_EXTENSION
                    355:     if (dgamode && need_dither) {
                    356:        DitherLine ((unsigned char *)(fb_addr + fb_width*y),
                    357:                    (uae_u16 *)linebuf, 0, y, gfxvidinfo.width, bit_unit);
                    358:        return;
                    359:     }
                    360: #endif
                    361:     xs = 0;
                    362:     xe = gfxvidinfo.width - 1;
1.1.1.3   root      363: 
1.1.1.6   root      364:     if (currprefs.x11_use_low_bandwidth) {
1.1.1.3   root      365:        char *src, *dst;
1.1.1.5   root      366:        switch (gfxvidinfo.pixbytes) {
1.1.1.3   root      367:         case 4:
                    368:            {
                    369:                uae_u32 *newp = (uae_u32 *)linebuf;
1.1.1.5   root      370:                uae_u32 *oldp = (uae_u32 *)((uae_u8 *)ami_dinfo.image_mem + y*ami_dinfo.ximg->bytes_per_line);
1.1.1.3   root      371:                while (newp[xs] == oldp[xs]) {
                    372:                    if (xs == xe)
                    373:                        return;
                    374:                    xs++;
                    375:                }
                    376:                while (newp[xe] == oldp[xe]) xe--;
                    377: 
                    378:                dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1       root      379:            }
1.1.1.3   root      380:            break;
                    381:         case 2:
                    382:            {
                    383:                uae_u16 *newp = (uae_u16 *)linebuf;
1.1.1.5   root      384:                uae_u16 *oldp = (uae_u16 *)((uae_u8 *)ami_dinfo.image_mem + y*ami_dinfo.ximg->bytes_per_line);
1.1.1.3   root      385:                while (newp[xs] == oldp[xs]) {
                    386:                    if (xs == xe)
                    387:                        return;
                    388:                    xs++;
                    389:                }
                    390:                while (newp[xe] == oldp[xe]) xe--;
                    391: 
                    392:                dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1       root      393:            }
1.1.1.3   root      394:            break;
                    395:         case 1:
                    396:            {
                    397:                uae_u8 *newp = (uae_u8 *)linebuf;
1.1.1.5   root      398:                uae_u8 *oldp = (uae_u8 *)((uae_u8 *)ami_dinfo.image_mem + y*ami_dinfo.ximg->bytes_per_line);
1.1.1.3   root      399:                while (newp[xs] == oldp[xs]) {
                    400:                    if (xs == xe)
                    401:                        return;
                    402:                    xs++;
                    403:                }
                    404:                while (newp[xe] == oldp[xe]) xe--;
1.1       root      405: 
1.1.1.3   root      406:                dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1       root      407:            }
1.1.1.3   root      408:            break;
1.1       root      409: 
1.1.1.3   root      410:         default:
1.1.1.5   root      411:            abort ();
1.1.1.3   root      412:            break;
1.1       root      413:        }
                    414: 
                    415:        len = xe - xs + 1;
1.1.1.3   root      416:        memcpy (dst, src, len * gfxvidinfo.pixbytes);
                    417:     } else if (need_dither) {
1.1.1.5   root      418:        uae_u8 *target = (uae_u8 *)ami_dinfo.image_mem + ami_dinfo.ximg->bytes_per_line * y;
1.1.1.20  root      419:        len = gfxvidinfo.width;
1.1.1.5   root      420:        DitherLine (target, (uae_u16 *)linebuf, 0, y, gfxvidinfo.width, bit_unit);
1.1.1.3   root      421:     } else {
1.1.1.16  root      422:        write_log ("Bug!\n");
1.1.1.3   root      423:        abort();
1.1       root      424:     }
1.1.1.2   root      425: 
1.1.1.5   root      426:     DO_PUTIMAGE (ami_dinfo.ximg, xs, y, xs, y, len, 1);
1.1       root      427: }
                    428: 
                    429: void flush_block (int ystart, int ystop)
                    430: {
1.1.1.5   root      431:     if (dgamode)
                    432:        return;
1.1.1.3   root      433: 
1.1.1.5   root      434:     DO_PUTIMAGE (ami_dinfo.ximg, 0, ystart, 0, ystart, gfxvidinfo.width, ystop - ystart + 1);
1.1       root      435: }
                    436: 
                    437: void flush_screen (int ystart, int ystop)
                    438: {
1.1.1.5   root      439:     if (dgamode)
                    440:        return;
                    441: 
1.1.1.3   root      442: #if SHM_SUPPORT_LINKS == 1
1.1.1.12  root      443:     if (currprefs.x11_use_mitshm && shmavail)
1.1.1.5   root      444:        XSync (display, 0);
1.1.1.2   root      445: #endif
1.1       root      446: }
                    447: 
1.1.1.19  root      448: void flush_clear_screen (void)
                    449: {
                    450:     flush_screen(0,0);
                    451: }
                    452: 
1.1.1.8   root      453: STATIC_INLINE int bitsInMask (unsigned long mask)
1.1       root      454: {
                    455:     /* count bits in mask */
                    456:     int n = 0;
1.1.1.5   root      457:     while (mask) {
                    458:        n += mask & 1;
1.1       root      459:        mask >>= 1;
                    460:     }
                    461:     return n;
                    462: }
                    463: 
1.1.1.8   root      464: STATIC_INLINE int maskShift (unsigned long mask)
1.1       root      465: {
                    466:     /* determine how far mask is shifted */
                    467:     int n = 0;
1.1.1.5   root      468:     while (!(mask & 1)) {
1.1       root      469:        n++;
                    470:        mask >>= 1;
                    471:     }
                    472:     return n;
                    473: }
                    474: 
1.1.1.3   root      475: static unsigned long pixel_return[256];
                    476: static XColor parsed_xcolors[256];
                    477: static int ncolors = 0;
                    478: 
                    479: static int blackval = 32767;
                    480: static int whiteval = 0;
                    481: 
1.1.1.5   root      482: static int get_color (int r, int g, int b, xcolnr *cnp)
1.1       root      483: {
1.1.1.3   root      484:     XColor *col = parsed_xcolors + ncolors;
1.1       root      485:     char str[10];
1.1.1.3   root      486: 
1.1.1.5   root      487:     sprintf (str, "rgb:%x/%x/%x", r, g, b);
                    488:     XParseColor (display, cmap, str, col);
1.1.1.3   root      489:     *cnp = col->pixel = pixel_return[ncolors];
                    490:     XStoreColor (display, cmap, col);
                    491:     XStoreColor (display, cmap2, col);
                    492: 
                    493:     if (r + g + b < blackval)
                    494:        blackval = r + g + b, black = *col;
                    495:     if (r + g + b > whiteval)
                    496:        whiteval = r + g + b, white = *col;
                    497: 
                    498:     ncolors++;
                    499:     return 1;
1.1       root      500: }
                    501: 
1.1.1.5   root      502: static int init_colors (void)
1.1       root      503: {
1.1.1.3   root      504:     int i;
                    505: 
1.1.1.5   root      506:     if (visualInfo.VI_CLASS == TrueColor) {
                    507:        red_bits = bitsInMask (visualInfo.red_mask);
                    508:        green_bits = bitsInMask (visualInfo.green_mask);
                    509:        blue_bits = bitsInMask (visualInfo.blue_mask);
                    510:        red_shift = maskShift (visualInfo.red_mask);
                    511:        green_shift = maskShift (visualInfo.green_mask);
                    512:        blue_shift = maskShift (visualInfo.blue_mask);
                    513:     }
                    514: 
1.1       root      515:     if (need_dither) {
                    516:        if (bitdepth == 1)
                    517:            setup_greydither (1, get_color);
                    518:        else
                    519:            setup_dither (bitdepth, get_color);
1.1.1.3   root      520:     } else {
                    521:        if (bitdepth != 8 && bitdepth != 12 && bitdepth != 15
                    522:            && bitdepth != 16 && bitdepth != 24) {
1.1.1.16  root      523:            write_log ("Unsupported bit depth (%d)\n", bitdepth);
1.1.1.3   root      524:            return 0;
1.1       root      525:        }
                    526: 
1.1.1.3   root      527:        switch (visualInfo.VI_CLASS) {
                    528:         case TrueColor:
1.1.1.5   root      529:            alloc_colors64k (red_bits, green_bits, blue_bits, red_shift,
                    530:                             green_shift, blue_shift);
                    531: 
                    532:            XParseColor (display, cmap, "#000000", &black);
                    533:            if (! XAllocColor (display, cmap, &black))
1.1.1.16  root      534:                write_log ("Whoops??\n");
1.1.1.5   root      535:            XParseColor (display, cmap, "#ffffff", &white);
                    536:            if (! XAllocColor (display, cmap, &white))
1.1.1.16  root      537:                write_log ("Whoops??\n");
1.1.1.3   root      538:            break;
                    539: 
                    540:         case GrayScale:
                    541:         case PseudoColor:
1.1.1.5   root      542:            alloc_colors256 (get_color);
1.1.1.3   root      543:            break;
                    544: 
                    545:         default:
1.1.1.16  root      546:            write_log ("Unsupported visual class (%d)\n", visualInfo.VI_CLASS);
1.1.1.3   root      547:            return 0;
                    548:        }
                    549:     }
                    550:     switch (gfxvidinfo.pixbytes) {
                    551:      case 2:
                    552:        for (i = 0; i < 4096; i++)
                    553:            xcolors[i] = xcolors[i] * 0x00010001;
                    554:        gfxvidinfo.can_double = 1;
                    555:        break;
                    556:      case 1:
                    557:        for (i = 0; i < 4096; i++)
                    558:            xcolors[i] = xcolors[i] * 0x01010101;
                    559:        gfxvidinfo.can_double = 1;
1.1       root      560:        break;
                    561:      default:
1.1.1.3   root      562:        gfxvidinfo.can_double = 0;
                    563:        break;
1.1       root      564:     }
1.1.1.5   root      565:     if (inverse_byte_order)
                    566:        switch (gfxvidinfo.pixbytes) {
1.1.1.3   root      567:         case 4:
                    568:            for(i = 0; i < 4096; i++)
                    569:                xcolors[i] = ((((xcolors[i]>>0)&255) << 24)
                    570:                              | (((xcolors[i]>>8)&255) << 16)
                    571:                              | (((xcolors[i]>>16)&255) << 8)
                    572:                              | (((xcolors[i]>>24)&255) << 0));
                    573:            break;
                    574:         case 2:
                    575:            for (i = 0; i < 4096; i++)
                    576:                xcolors[i] = (xcolors[i]>>8) | ((xcolors[i]&255)<<8);
                    577:            break;
                    578:         default:
                    579:            break;
                    580:        }
1.1       root      581:     return 1;
                    582: }
                    583: 
1.1.1.5   root      584: static int dga_available (void)
1.1       root      585: {
1.1.1.2   root      586: #ifdef USE_DGA_EXTENSION
                    587:     int MajorVersion, MinorVersion;
                    588:     int EventBase, ErrorBase;
1.1.1.3   root      589: 
1.1.1.5   root      590:     if (! XF86DGAQueryVersion (display, &MajorVersion, &MinorVersion)) {
1.1.1.16  root      591:        write_log ("Unable to query video extension version\n");
1.1.1.3   root      592:        return 0;
1.1.1.2   root      593:     }
1.1.1.5   root      594:     if (! XF86DGAQueryExtension (display, &EventBase, &ErrorBase)) {
1.1.1.16  root      595:        write_log ("Unable to query video extension information\n");
1.1.1.3   root      596:        return 0;
1.1.1.2   root      597:     }
                    598:     /* Fail if the extension version in the server is too old */
1.1.1.5   root      599:     if (MajorVersion < DGA_MINMAJOR
                    600:        || (MajorVersion == DGA_MINMAJOR && MinorVersion < DGA_MINMINOR))
                    601:     {
1.1.1.16  root      602:        write_log (
1.1.1.3   root      603:                 "Xserver is running an old XFree86-DGA version"
                    604:                 " (%d.%d)\n", MajorVersion, MinorVersion);
1.1.1.16  root      605:        write_log ("Minimum required version is %d.%d\n",
1.1.1.5   root      606:                 DGA_MINMAJOR, DGA_MINMINOR);
                    607:        return 0;
                    608:     }
                    609:     if (geteuid () != 0) {
1.1.1.16  root      610:        write_log ("UAE is not running as root, DGA extension disabled.\n");
1.1.1.5   root      611:        return 0;
                    612:     }
                    613:     if (! XF86DGAGetVideo (display, screen, &fb_addr, &fb_width, &fb_bank, &fb_mem)
                    614:        || fb_bank < fb_mem)
                    615:     {
1.1.1.16  root      616:        write_log ("Problems with DGA - disabling DGA extension.\n");
1.1.1.3   root      617:        return 0;
                    618:     }
1.1.1.16  root      619:     write_log ("DGA extension: addr:%X, width %d, bank size %d mem size %d\n",
1.1.1.5   root      620:             fb_addr, fb_width, fb_bank, fb_mem);
                    621: 
                    622:     return 1;
                    623: #else
                    624:     return 0;
                    625: #endif
                    626: }
                    627: 
                    628: static int vid_mode_available (void)
                    629: {
1.1.1.3   root      630: #ifdef USE_VIDMODE_EXTENSION
1.1.1.5   root      631:     int MajorVersion, MinorVersion;
                    632:     int EventBase, ErrorBase;
                    633: 
                    634:     if (! dgaavail)
                    635:        return 0;
                    636:     if (! XF86VidModeQueryVersion (display, &MajorVersion, &MinorVersion)) {
1.1.1.16  root      637:        write_log ("Unable to query video extension version\n");
1.1.1.3   root      638:        return 0;
                    639:     }
1.1.1.5   root      640:     if (! XF86VidModeQueryExtension (display, &EventBase, &ErrorBase)) {
1.1.1.16  root      641:        write_log ("Unable to query video extension information\n");
1.1.1.3   root      642:        return 0;
                    643:     }
1.1.1.5   root      644:     if (MajorVersion < VidMode_MINMAJOR
                    645:        || (MajorVersion == VidMode_MINMAJOR && MinorVersion < VidMode_MINMINOR)) {
                    646:        /* Fail if the extension version in the server is too old */
1.1.1.16  root      647:        write_log ("Xserver is running an old XFree86-VidMode version (%d.%d)\n",
1.1.1.5   root      648:                 MajorVersion, MinorVersion);
1.1.1.16  root      649:        write_log ("Minimum required version is %d.%d\n",
1.1.1.3   root      650:                 VidMode_MINMAJOR, VidMode_MINMINOR);
                    651:        return 0;
                    652:     }
1.1.1.5   root      653:     if (! get_vidmodes ()) {
1.1.1.16  root      654:        write_log ("Error getting video mode information\n");
1.1.1.3   root      655:        return 0;
1.1.1.2   root      656:     }
1.1.1.5   root      657:     return 1;
                    658: #else
                    659:     return 0;
1.1.1.2   root      660: #endif
1.1.1.5   root      661: }
                    662: 
                    663: static int shm_available (void)
                    664: {
                    665: #if SHM_SUPPORT_LINKS == 1
                    666:     if (XShmQueryExtension (display))
                    667:        return 1;
1.1.1.3   root      668: #endif
1.1.1.5   root      669:     return 0;
                    670: }
                    671: 
                    672: int graphics_setup (void)
                    673: {
                    674:     char *display_name = 0;
                    675: 
                    676:     display = XOpenDisplay (display_name);
                    677:     if (display == 0)  {
1.1.1.16  root      678:        write_log ("Can't connect to X server %s\n", XDisplayName (display_name));
1.1.1.5   root      679:        return 0;
                    680:     }
                    681: 
                    682:     shmavail = shm_available ();
                    683:     dgaavail = dga_available ();
                    684:     vidmodeavail = vid_mode_available ();
1.1.1.3   root      685: 
                    686:     {
                    687:        int local_byte_order;
                    688:        int x = 0x04030201;
                    689:        char *y=(char*)&x;
                    690: 
                    691:        local_byte_order = y[0] == 0x04 ? MSBFirst : LSBFirst;
                    692:        if (ImageByteOrder(display) != local_byte_order)
                    693:            inverse_byte_order = 1;
                    694:     }
                    695: 
                    696:     return 1;
                    697: }
                    698: 
1.1.1.5   root      699: static void lock_window_size (void)
1.1.1.3   root      700: {
1.1.1.5   root      701:     XSizeHints hint;
1.1.1.3   root      702: 
1.1.1.5   root      703:     hint.flags  = PMinSize | PMaxSize;
                    704:     hint.min_width = current_width;
                    705:     hint.min_height = current_height;
                    706:     hint.max_width = current_width;
                    707:     hint.max_height = current_height;
                    708:     XSetWMNormalHints (display, mywin, &hint);
1.1.1.3   root      709: }
                    710: 
1.1.1.5   root      711: static void init_dispinfo (struct disp_info *disp)
                    712: {
                    713: #if SHM_SUPPORT_LINKS == 1
                    714:     disp->shminfo.shmid = -1;
                    715: #endif
                    716:     disp->ximg = 0;
                    717: }
                    718: 
1.1.1.19  root      719: static void reset_cursor (void)
                    720: {
                    721:     if (! dgamode) {
                    722:        if (! currprefs.x11_hide_cursor)
                    723:            XDefineCursor (display, mywin, xhairCursor);
                    724:        else
                    725:            XDefineCursor (display, mywin, blankCursor);
                    726:        cursorOn = 1;
                    727:     }
                    728: }
                    729: 
1.1.1.21  root      730: int graphics_subinit (void)
1.1.1.3   root      731: {
1.1.1.6   root      732:     int i, j;
1.1.1.3   root      733:     XSetWindowAttributes wattr;
1.1.1.7   root      734:     XClassHint classhint;
                    735:     XWMHints *hints;
1.1.1.5   root      736:     unsigned long valuemask;
                    737: 
1.1.1.20  root      738:     if (screen_is_picasso) {
                    739:        // Set height, width for Picasso gfx
                    740:        current_width  = picasso_vidinfo.width;
                    741:        current_height = picasso_vidinfo.height;
                    742:        dgamode = currprefs.gfx_pfullscreen && dgaavail;
                    743:        curr_gfx = 0;
                    744:     } else {
                    745:        // Set height, width for Amiga gfx
                    746:        dgamode = currprefs.gfx_afullscreen && dgaavail;
                    747:        if (dgamode)
                    748:            curr_gfx = &currprefs.gfx_f;
                    749:        else
                    750:            curr_gfx = &currprefs.gfx_w;
                    751:            
                    752:        current_width  = curr_gfx->width;
                    753:        current_height = curr_gfx->height;
                    754:     }
                    755:     if (!screen_is_picasso) {
                    756:        gfxvidinfo.width  = current_width;
                    757:        gfxvidinfo.height = current_height;
                    758:     }
1.1.1.5   root      759: 
                    760:     wattr.background_pixel = /*black.pixel*/0;
                    761:     wattr.backing_store = Always;
                    762:     wattr.backing_planes = bitdepth;
                    763:     wattr.border_pixmap = None;
                    764:     wattr.border_pixel = /*black.pixel*/0;
                    765:     wattr.colormap = cmap;
                    766:     valuemask = (CWEventMask | CWBackPixel | CWBorderPixel
                    767:                 | CWBackingStore | CWBackingPlanes | CWColormap);
                    768: 
                    769:     if (dgamode) {
                    770:        wattr.event_mask = DGA_EVENTMASK;
                    771:        wattr.override_redirect = 1;
                    772:        valuemask |= CWOverrideRedirect;
                    773:     } else
                    774:        wattr.event_mask = EVENTMASK;
                    775: 
                    776:     XSync (display, 0);
1.1.1.7   root      777:     delete_win = XInternAtom(display, "WM_DELETE_WINDOW", False);
1.1.1.5   root      778:     mywin = XCreateWindow (display, rootwin, 0, 0, current_width, current_height,
                    779:                           0, bitdepth, InputOutput, vis, valuemask, &wattr);
1.1.1.7   root      780:     XSetWMProtocols (display, mywin, &delete_win, 1);
1.1.1.5   root      781:     XSync (display, 0);
                    782: 
                    783:     XStoreName (display, mywin, "UAE");
1.1.1.7   root      784:     XSetIconName (display, mywin, "UAE Screen");
                    785: 
                    786:     /* set class hint */
                    787:     classhint.res_name = "UAE";
                    788:     classhint.res_class = "UAEScreen";
1.1.1.21  root      789:     XSetClassHint (display, mywin, &classhint);
1.1.1.19  root      790: 
1.1.1.7   root      791:     hints = XAllocWMHints();
                    792:     /* Set window group leader to self to become an application
                    793:      * that can be hidden by e.g. WindowMaker.
                    794:      * Would be more useful if we could find out what the
                    795:      * (optional) GTK+ window ID is :-/ */
                    796:     hints->window_group = mywin;
                    797:     hints->flags = WindowGroupHint;
1.1.1.21  root      798:     XSetWMHints (display, mywin, hints);
                    799:     XFree (hints);
1.1.1.7   root      800: 
1.1.1.5   root      801:     XMapRaised (display, mywin);
                    802:     XSync (display, 0);
                    803:     mygc = XCreateGC (display, mywin, 0, 0);
                    804: 
                    805:     if (dgamode) {
                    806: #ifdef USE_DGA_EXTENSION
                    807:        enter_dga_mode ();
                    808:        /*setuid(getuid());*/
                    809:        picasso_vidinfo.rowbytes = fb_width * picasso_vidinfo.pixbytes;
                    810: #endif
                    811:     } else {
                    812:        get_image (current_width, current_height, &ami_dinfo);
                    813:        if (screen_is_picasso) {
                    814:            get_image (current_width, current_height, &pic_dinfo);
                    815:            picasso_vidinfo.rowbytes = pic_dinfo.ximg->bytes_per_line;
                    816:        }
                    817:     }
                    818: 
                    819:     picasso_vidinfo.extra_mem = 1;
                    820: 
                    821:     if (need_dither) {
                    822:        gfxvidinfo.maxblocklines = 0;
1.1.1.20  root      823:        gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * current_width;
1.1.1.5   root      824:        gfxvidinfo.linemem = (char *)malloc (gfxvidinfo.rowbytes);
                    825:     } else if (! dgamode) {
                    826:        gfxvidinfo.emergmem = 0;
                    827:        gfxvidinfo.linemem = 0;
                    828:        gfxvidinfo.bufmem = ami_dinfo.image_mem;
                    829:        gfxvidinfo.rowbytes = ami_dinfo.ximg->bytes_per_line;
1.1.1.6   root      830:        if (currprefs.x11_use_low_bandwidth) {
1.1.1.5   root      831:            gfxvidinfo.maxblocklines = 0;
                    832:            gfxvidinfo.rowbytes = ami_dinfo.ximg->bytes_per_line;
                    833:            gfxvidinfo.linemem = (char *)malloc (gfxvidinfo.rowbytes);
                    834:        } else {
                    835:            gfxvidinfo.maxblocklines = 100; /* whatever... */
                    836:        }
                    837:     }
                    838: 
                    839:     if (visualInfo.VI_CLASS != TrueColor && ! screen_is_picasso) {
                    840:        int i;
                    841:        for (i = 0; i < 256; i++)
                    842:            XStoreColor (display, cmap, parsed_xcolors + i);
                    843:     }
                    844: 
                    845: #ifdef USE_DGA_EXTENSION
                    846:     if (dgamode) {
                    847:        dga_colormap_installed = 0;
                    848:        XF86DGAInstallColormap (display, screen, cmap2);
                    849:        XF86DGAInstallColormap (display, screen, cmap);
                    850:     }
                    851: #endif
                    852: 
1.1.1.19  root      853:     reset_cursor ();
1.1.1.5   root      854: 
                    855:     if (screen_is_picasso) {
                    856:        picasso_has_invalid_lines = 0;
                    857:        picasso_invalid_start = picasso_vidinfo.height + 1;
                    858:        picasso_invalid_stop = -1;
                    859:        memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines);
                    860:     }
1.1.1.6   root      861: 
                    862:     inwindow = 0;
1.1.1.19  root      863:     inputdevice_release_all_keys ();
                    864:     reset_hotkeys ();
1.1.1.21  root      865: 
                    866:     XWarpPointer (display, None, mywin, 0, 0, 0, 0,
                    867:                  current_width / 2, current_height / 2);
                    868:     return 1;
1.1.1.19  root      869: }
                    870: 
                    871: static int get_best_visual (XVisualInfo *vi)
                    872: {
                    873:     screen = XDefaultScreen (display);
                    874:     rootwin = XRootWindow (display, screen);
                    875: 
                    876:     /* try for a 12 bit visual first, then a 16 bit, then a 24 bit, then 8 bit */
                    877:     if (XMatchVisualInfo (display, screen, 12, TrueColor, vi)) {
                    878:     } else if (XMatchVisualInfo (display, screen, 15, TrueColor, vi)) {
                    879:     } else if (XMatchVisualInfo (display, screen, 16, TrueColor, vi)) {
                    880:     } else if (XMatchVisualInfo (display, screen, 24, TrueColor, vi)) {
                    881:     } else if (XMatchVisualInfo (display, screen, 8, PseudoColor, vi)) {
                    882:        /* for our HP boxes */
                    883:     } else if (XMatchVisualInfo (display, screen, 8, GrayScale, vi)) {
                    884:     } else if (XMatchVisualInfo (display, screen, 4, PseudoColor, vi)) {
                    885:        /* VGA16 server. Argh. */
                    886:     } else if (XMatchVisualInfo (display, screen, 1, StaticGray, vi)) {
                    887:        /* Mono server. Yuk */
                    888:     } else {
                    889:        write_log ("Can't obtain appropriate X visual.\n");
                    890:        return 0;
1.1.1.6   root      891:     }
1.1.1.19  root      892:     return 1;
                    893: }
                    894: 
                    895: static int get_visual_bit_unit (XVisualInfo *vi, int bitdepth)
                    896: {
                    897:     int bit_unit = 0;
                    898:     XPixmapFormatValues *xpfvs;
                    899:     int i,j;
                    900: 
                    901:     /* We now have the bitdepth of the display, but that doesn't tell us yet
                    902:      * how many bits to use per pixel. The VGA16 server has a bitdepth of 4,
                    903:      * but uses 1 byte per pixel. */
                    904:     xpfvs = XListPixmapFormats (display, &i);
                    905:     for (j = 0; j < i && xpfvs[j].depth != bitdepth; j++)
                    906:        ;
                    907:     if (j < i)
                    908:        bit_unit = xpfvs[j].bits_per_pixel;
                    909:     XFree (xpfvs);
                    910:     if (j == i) {
                    911:        write_log ("Your X server is feeling ill.\n");
                    912:     }
                    913: 
                    914:     return bit_unit;
1.1.1.5   root      915: }
                    916: 
                    917: int graphics_init (void)
                    918: {
                    919:     int i,j;
1.1.1.3   root      920:     XPixmapFormatValues *xpfvs;
                    921: 
1.1.1.6   root      922:     if (currprefs.x11_use_mitshm && ! shmavail) {
1.1.1.16  root      923:        write_log ("MIT-SHM extension not supported by X server.\n");
1.1.1.5   root      924:     }
1.1.1.3   root      925:     if (currprefs.color_mode > 5)
1.1.1.16  root      926:        write_log ("Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
1.1.1.3   root      927: 
                    928:     x11_init_ok = 0;
                    929:     need_dither = 0;
                    930:     screen_is_picasso = 0;
1.1.1.5   root      931:     dgamode = 0;
                    932: 
                    933:     init_dispinfo (&ami_dinfo);
                    934:     init_dispinfo (&pic_dinfo);
1.1.1.3   root      935: 
1.1.1.5   root      936:     screen = XDefaultScreen (display);
                    937:     rootwin = XRootWindow (display, screen);
1.1.1.3   root      938: 
1.1.1.19  root      939:     if (!get_best_visual (&visualInfo)) return 0;
                    940: 
1.1       root      941:     vis = visualInfo.visual;
                    942:     bitdepth = visualInfo.depth;
1.1.1.3   root      943: 
1.1.1.19  root      944:     if (!(bit_unit = get_visual_bit_unit (&visualInfo, bitdepth))) return 0;
1.1.1.3   root      945: 
1.1.1.16  root      946:     write_log ("Using %d bit visual, %d bits per pixel\n", bitdepth, bit_unit);
1.1       root      947: 
1.1.1.21  root      948:     fixup_prefs_dimensions (&currprefs.gfx_w, gfx_windowed_modes, n_windowed_modes);
                    949:     fixup_prefs_dimensions (&currprefs.gfx_f, gfx_fullscreen_modes, n_fullscreen_modes);
1.1.1.19  root      950: 
1.1.1.5   root      951:     cmap = XCreateColormap (display, rootwin, vis, AllocNone);
                    952:     cmap2 = XCreateColormap (display, rootwin, vis, AllocNone);
                    953:     if (visualInfo.VI_CLASS == GrayScale || visualInfo.VI_CLASS == PseudoColor) {
                    954:        XAllocColorCells (display, cmap, 0, 0, 0, pixel_return, 1 << bitdepth);
                    955:        XAllocColorCells (display, cmap2, 0, 0, 0, pixel_return, 1 << bitdepth);
                    956:     }
1.1.1.3   root      957: 
                    958:     if (bitdepth < 8 || (bitdepth == 8 && currprefs.color_mode == 3)) {
1.1       root      959:        gfxvidinfo.pixbytes = 2;
1.1.1.6   root      960:        currprefs.x11_use_low_bandwidth = 0;
1.1       root      961:        need_dither = 1;
1.1.1.21  root      962:        picasso_vidinfo.pixbytes = 1 /* ??? */;
1.1       root      963:     } else {
1.1.1.3   root      964:        gfxvidinfo.pixbytes = bit_unit >> 3;
1.1.1.21  root      965:        picasso_vidinfo.pixbytes = bit_unit >> 3;
1.1       root      966:     }
1.1.1.2   root      967: 
1.1.1.5   root      968:     if (! init_colors ())
1.1       root      969:        return 0;
                    970: 
1.1.1.5   root      971:     blankCursor = XCreatePixmapCursor (display,
                    972:                                       XCreatePixmap (display, rootwin, 1, 1, 1),
                    973:                                       XCreatePixmap (display, rootwin, 1, 1, 1),
                    974:                                       &black, &white, 0, 0);
                    975:     xhairCursor = XCreateFontCursor (display, XC_crosshair);
1.1.1.3   root      976: 
1.1.1.5   root      977:     graphics_subinit ();
1.1.1.3   root      978: 
1.1.1.5   root      979:     grabbed = 0;
1.1.1.3   root      980: 
1.1.1.2   root      981:     return x11_init_ok = 1;
1.1       root      982: }
                    983: 
1.1.1.5   root      984: static void destroy_dinfo (struct disp_info *dinfo)
1.1       root      985: {
1.1.1.5   root      986:     if (dinfo->ximg == NULL)
1.1.1.2   root      987:        return;
1.1.1.5   root      988: #if SHM_SUPPORT_LINKS == 1
                    989:     if (dinfo->shminfo.shmid != -1)
                    990:        shmdt (dinfo->shminfo.shmaddr);
                    991:     dinfo->shminfo.shmid = -1;
                    992: #endif
                    993:     XDestroyImage (dinfo->ximg);
                    994:     dinfo->ximg = NULL;
                    995: }
1.1.1.3   root      996: 
1.1.1.21  root      997: void graphics_subshutdown (int final)
1.1.1.5   root      998: {
                    999:     XSync (display, 0);
1.1.1.2   root     1000: #ifdef USE_DGA_EXTENSION
1.1.1.5   root     1001:     if (dgamode)
                   1002:        leave_dga_mode ();
1.1.1.2   root     1003: #endif
1.1.1.5   root     1004: 
                   1005:     destroy_dinfo (&ami_dinfo);
                   1006:     destroy_dinfo (&pic_dinfo);
                   1007: 
1.1.1.19  root     1008:     if (mywin) {
                   1009:        XDestroyWindow (display, mywin);
                   1010:        mywin = 0;
                   1011:     }
1.1.1.5   root     1012: 
                   1013:     if (gfxvidinfo.linemem != NULL)
                   1014:        free (gfxvidinfo.linemem);
                   1015:     if (gfxvidinfo.emergmem != NULL)
                   1016:        free (gfxvidinfo.emergmem);
                   1017: }
                   1018: 
                   1019: void graphics_leave (void)
                   1020: {
                   1021:     if (! x11_init_ok)
                   1022:        return;
                   1023: 
1.1.1.21  root     1024:     graphics_subshutdown (1);
1.1.1.19  root     1025: 
1.1.1.5   root     1026:     if (autorepeatoff)
                   1027:        XAutoRepeatOn (display);
                   1028: 
                   1029:     XFlush (display);
                   1030:     XSync (display, 0);
                   1031: 
                   1032:     XFreeColormap (display, cmap);
                   1033:     XFreeColormap (display, cmap2);
                   1034: 
1.1.1.14  root     1035: #if 0
1.1.1.5   root     1036:     XCloseDisplay (display);
1.1.1.14  root     1037: #endif
1.1.1.5   root     1038:     dumpcustom ();
1.1       root     1039: }
                   1040: 
                   1041: static struct timeval lastMotionTime;
                   1042: 
1.1.1.3   root     1043: static int refresh_necessary = 0;
                   1044: 
1.1.1.5   root     1045: void handle_events (void)
1.1       root     1046: {
1.1.1.5   root     1047:     gui_handle_events ();
1.1.1.3   root     1048: 
1.1       root     1049:     for (;;) {
                   1050:        XEvent event;
                   1051: #if 0
1.1.1.5   root     1052:        if (! XCheckMaskEvent (display, eventmask, &event))
                   1053:            break;
1.1       root     1054: #endif
1.1.1.5   root     1055:        if (! XPending (display))
                   1056:            break;
                   1057: 
                   1058:        XNextEvent (display, &event);
1.1.1.3   root     1059: 
1.1.1.5   root     1060:        switch (event.type) {
1.1.1.19  root     1061:         case KeyPress:
1.1.1.3   root     1062:         case KeyRelease: {
1.1.1.19  root     1063:            int state = (event.type == KeyPress);
                   1064:            KeySym keysym;
                   1065:            int index = 0;
                   1066:            int ievent, amiga_keycode;
                   1067:            do {
                   1068:                keysym = XLookupKeysym ((XKeyEvent *)&event, index);
                   1069:                if ((ievent = match_hotkey_sequence (keysym, state))) {
                   1070:                    handle_hotkey_event (ievent, state);
                   1071:                    break;
                   1072:                } else
                   1073:                    if ((amiga_keycode = xkeysym2amiga (keysym)) >= 0) {
                   1074:                        inputdevice_do_keyboard (amiga_keycode, state);
                   1075:                        break;
                   1076:                    }
                   1077:                index++;
                   1078:            } while (keysym != NoSymbol);
                   1079:            break;
1.1       root     1080:         }
                   1081:         case ButtonPress:
1.1.1.19  root     1082:         case ButtonRelease: {
                   1083:            int state = (event.type == ButtonPress);
                   1084:            int buttonno = -1;
                   1085:            switch ((int)((XButtonEvent *)&event)->button) {
                   1086:                case 1:  buttonno = 0; break;
                   1087:                case 2:  buttonno = 2; break;
                   1088:                case 3:  buttonno = 1; break;
                   1089:                /* buttons 4 and 5 report mousewheel events */
                   1090:                case 4:  if (state) record_key (0x7a << 1); break;
                   1091:                case 5:  if (state) record_key (0x7b << 1); break;
                   1092:            }
                   1093:            if (buttonno >=0)
                   1094:                setmousebuttonstate(0, buttonno, state);
1.1       root     1095:            break;
1.1.1.19  root     1096:         }
1.1.1.5   root     1097:         case MotionNotify:
                   1098:            if (dgamode) {
1.1.1.19  root     1099:                int tx = ((XMotionEvent *)&event)->x_root;
                   1100:                int ty = ((XMotionEvent *)&event)->y_root;
                   1101:                setmousestate (0, 0, tx, 0);
                   1102:                setmousestate (0, 1, ty, 0);
1.1.1.5   root     1103:            } else if (grabbed) {
                   1104:                int realmove = 0;
1.1.1.12  root     1105:                int tx, ty,ttx,tty;
1.1.1.19  root     1106: 
1.1.1.5   root     1107:                tx = ((XMotionEvent *)&event)->x;
                   1108:                ty = ((XMotionEvent *)&event)->y;
                   1109:                if (! event.xmotion.send_event) {
1.1.1.19  root     1110:                    setmousestate (0, 0, tx - oldx, 0);
                   1111:                    setmousestate (0, 1, ty - oldy, 0);
1.1.1.5   root     1112:                    realmove = 1;
                   1113: #undef ABS
                   1114: #define ABS(a) (((a)<0) ? -(a) : (a) )
                   1115:                    if (ABS(current_width / 2 - tx) > 3 * current_width / 8
1.1.1.19  root     1116:                        || ABS(current_height / 2 - ty) > 3 * current_height / 8)
1.1.1.5   root     1117:                    {
                   1118: #undef ABS
                   1119:                        XEvent event;
1.1.1.12  root     1120:                        ttx = current_width / 2;
                   1121:                        tty = current_height / 2;
1.1.1.5   root     1122:                        event.type = MotionNotify;
                   1123:                        event.xmotion.display = display;
                   1124:                        event.xmotion.window = mywin;
1.1.1.12  root     1125:                        event.xmotion.x = ttx;
                   1126:                        event.xmotion.y = tty;
1.1.1.5   root     1127:                        XSendEvent (display, mywin, False,
                   1128:                                    PointerMotionMask, &event);
1.1.1.12  root     1129:                        XWarpPointer (display, None, mywin, 0, 0, 0, 0, ttx, tty);
1.1.1.5   root     1130:                    }
1.1.1.12  root     1131:                } else {
1.1.1.19  root     1132:                    tx = event.xmotion.x;
                   1133:                    ty = event.xmotion.y;
1.1.1.5   root     1134:                }
                   1135:                oldx = tx;
                   1136:                oldy = ty;
                   1137:            } else if (inwindow) {
1.1.1.19  root     1138:                int tx = ((XMotionEvent *)&event)->x;
                   1139:                int ty = ((XMotionEvent *)&event)->y;
                   1140:                setmousestate(0, 0, tx, 1);
                   1141:                setmousestate(0, 1, ty, 1);
1.1.1.6   root     1142:                if (! cursorOn && !currprefs.x11_hide_cursor) {
1.1.1.5   root     1143:                    XDefineCursor(display, mywin, xhairCursor);
                   1144:                    cursorOn = 1;
                   1145:                }
                   1146:                gettimeofday(&lastMotionTime, NULL);
                   1147:            }
                   1148:            break;
1.1       root     1149:         case EnterNotify:
1.1.1.19  root     1150:            {
                   1151:                int tx = ((XCrossingEvent *)&event)->x;
                   1152:                int ty = ((XCrossingEvent *)&event)->y;
                   1153:                setmousestate (0, 0, tx, 1);
                   1154:                setmousestate (0, 1, ty, 1);
                   1155:            }
1.1       root     1156:            inwindow = 1;
                   1157:            break;
                   1158:         case LeaveNotify:
                   1159:            inwindow = 0;
                   1160:            break;
                   1161:         case FocusIn:
1.1.1.5   root     1162:            if (! autorepeatoff)
                   1163:                XAutoRepeatOff (display);
1.1       root     1164:            autorepeatoff = 1;
                   1165:            break;
                   1166:         case FocusOut:
                   1167:            if (autorepeatoff)
1.1.1.5   root     1168:                XAutoRepeatOn (display);
1.1       root     1169:            autorepeatoff = 0;
                   1170:            break;
                   1171:         case Expose:
1.1.1.3   root     1172:            refresh_necessary = 1;
1.1       root     1173:            break;
1.1.1.19  root     1174:         case ClientMessage:
                   1175:            if (((Atom)event.xclient.data.l[0]) == delete_win) {
1.1.1.7   root     1176:                uae_quit ();
1.1.1.19  root     1177:            }
                   1178:            break;
1.1       root     1179:        }
                   1180:     }
1.1.1.5   root     1181: 
                   1182: #if defined PICASSO96
                   1183:     if (! dgamode) {
                   1184:        if (screen_is_picasso && refresh_necessary) {
                   1185:            DO_PUTIMAGE (pic_dinfo.ximg, 0, 0, 0, 0,
                   1186:                         picasso_vidinfo.width, picasso_vidinfo.height);
                   1187:            refresh_necessary = 0;
                   1188:            memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines);
                   1189:        } else if (screen_is_picasso && picasso_has_invalid_lines) {
                   1190:            int i;
                   1191:            int strt = -1;
                   1192: 
                   1193:            picasso_invalid_lines[picasso_vidinfo.height] = 0;
                   1194:            for (i = picasso_invalid_start; i < picasso_invalid_stop + 2; i++) {
                   1195:                if (picasso_invalid_lines[i]) {
                   1196:                    picasso_invalid_lines[i] = 0;
                   1197:                    if (strt != -1)
                   1198:                        continue;
                   1199:                    strt = i;
                   1200:                } else {
                   1201:                    if (strt == -1)
                   1202:                        continue;
                   1203:                    DO_PUTIMAGE (pic_dinfo.ximg, 0, strt, 0, strt,
                   1204:                                 picasso_vidinfo.width, i - strt);
                   1205:                    strt = -1;
                   1206:                }
1.1.1.3   root     1207:            }
1.1.1.5   root     1208:            if (strt != -1)
                   1209:                abort ();
1.1.1.3   root     1210:        }
                   1211:     }
1.1.1.5   root     1212:     picasso_has_invalid_lines = 0;
                   1213:     picasso_invalid_start = picasso_vidinfo.height + 1;
                   1214:     picasso_invalid_stop = -1;
1.1.1.3   root     1215: #endif
1.1.1.19  root     1216: 
1.1.1.5   root     1217:     if (! dgamode) {
                   1218:        if (! screen_is_picasso && refresh_necessary) {
1.1.1.20  root     1219:            DO_PUTIMAGE (ami_dinfo.ximg, 0, 0, 0, 0, current_width, current_height);
1.1.1.5   root     1220:            refresh_necessary = 0;
                   1221:        }
1.1.1.6   root     1222:        if (cursorOn && !currprefs.x11_hide_cursor) {
1.1.1.5   root     1223:            struct timeval now;
                   1224:            int diff;
                   1225:            gettimeofday(&now, NULL);
                   1226:            diff = (now.tv_sec - lastMotionTime.tv_sec) * 1000000 +
                   1227:                (now.tv_usec - lastMotionTime.tv_usec);
                   1228:            if (diff > 1000000) {
                   1229:                XDefineCursor (display, mywin, blankCursor);
                   1230:                cursorOn = 0;
                   1231:            }
1.1       root     1232:        }
                   1233:     }
                   1234: }
                   1235: 
1.1.1.5   root     1236: int debuggable (void)
1.1       root     1237: {
                   1238:     return 1;
                   1239: }
                   1240: 
1.1.1.5   root     1241: int needmousehack (void)
                   1242: {
1.1.1.13  root     1243:     if (dgamode || grabbed)
1.1.1.5   root     1244:        return 0;
                   1245:     else
                   1246:        return 1;
                   1247: }
                   1248: 
1.1.1.19  root     1249: int mousehack_allowed (void)
                   1250: {
                   1251:     return 1;
                   1252: }
                   1253: 
1.1.1.5   root     1254: void LED (int on)
1.1       root     1255: {
1.1.1.2   root     1256: #if 0 /* Maybe that is responsible for the joystick emulation problems on SunOS? */
1.1       root     1257:     static int last_on = -1;
                   1258:     XKeyboardControl control;
                   1259: 
1.1.1.5   root     1260:     if (last_on == on)
                   1261:        return;
1.1       root     1262:     last_on = on;
                   1263:     control.led = 1; /* implementation defined */
                   1264:     control.led_mode = on ? LedModeOn : LedModeOff;
                   1265:     XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
1.1.1.2   root     1266: #endif
1.1       root     1267: }
                   1268: 
1.1.1.3   root     1269: #ifdef PICASSO96
                   1270: 
                   1271: void DX_Invalidate (int first, int last)
                   1272: {
1.1.1.5   root     1273:     if (first > last)
                   1274:        return;
                   1275: 
                   1276:     picasso_has_invalid_lines = 1;
                   1277:     if (first < picasso_invalid_start)
                   1278:        picasso_invalid_start = first;
                   1279:     if (last > picasso_invalid_stop)
                   1280:        picasso_invalid_stop = last;
                   1281: 
                   1282:     while (first <= last) {
1.1.1.3   root     1283:        picasso_invalid_lines[first] = 1;
                   1284:        first++;
1.1.1.19  root     1285:     }
1.1.1.3   root     1286: }
                   1287: 
                   1288: int DX_BitsPerCannon (void)
                   1289: {
                   1290:     return 8;
                   1291: }
                   1292: 
1.1.1.19  root     1293: static int palette_update_start=256;
                   1294: static int palette_update_end=0;
                   1295: 
                   1296: static void DX_SetPalette_real (int start, int count)
1.1.1.3   root     1297: {
1.1.1.5   root     1298:     if (! screen_is_picasso || picasso96_state.RGBFormat != RGBFB_CHUNKY)
1.1.1.3   root     1299:        return;
                   1300: 
1.1.1.5   root     1301:     if (picasso_vidinfo.pixbytes != 1) {
                   1302:        /* This is the case when we're emulating a 256 color display.  */
                   1303:        while (count-- > 0) {
                   1304:            int r = picasso96_state.CLUT[start].Red;
                   1305:            int g = picasso96_state.CLUT[start].Green;
                   1306:            int b = picasso96_state.CLUT[start].Blue;
                   1307:            picasso_vidinfo.clut[start++] = (doMask256 (r, red_bits, red_shift)
                   1308:                                             | doMask256 (g, green_bits, green_shift)
                   1309:                                             | doMask256 (b, blue_bits, blue_shift));
                   1310:        }
                   1311:        return;
                   1312:     }
1.1.1.19  root     1313: 
1.1.1.3   root     1314:     while (count-- > 0) {
                   1315:        XColor col = parsed_xcolors[start];
                   1316:        col.red = picasso96_state.CLUT[start].Red * 0x0101;
                   1317:        col.green = picasso96_state.CLUT[start].Green * 0x0101;
                   1318:        col.blue = picasso96_state.CLUT[start].Blue * 0x0101;
                   1319:        XStoreColor (display, cmap, &col);
                   1320:        XStoreColor (display, cmap2, &col);
                   1321:        start++;
                   1322:     }
                   1323: #ifdef USE_DGA_EXTENSION
1.1.1.5   root     1324:     if (dgamode) {
                   1325:        dga_colormap_installed ^= 1;
                   1326:        if (dga_colormap_installed == 1)
                   1327:            XF86DGAInstallColormap (display, screen, cmap2);
                   1328:        else
                   1329:            XF86DGAInstallColormap (display, screen, cmap);
                   1330:     }
1.1.1.3   root     1331: #endif
                   1332: }
1.1.1.19  root     1333: void DX_SetPalette (int start, int count)
                   1334: {
                   1335:    DX_SetPalette_real (start, count);
                   1336: }
1.1.1.3   root     1337: 
1.1.1.19  root     1338: static void DX_SetPalette_delayed (int start, int count)
                   1339: {
                   1340:     if (bit_unit!=8) {
                   1341:        DX_SetPalette_real(start,count);
                   1342:        return;
                   1343:     }
                   1344:     if (start<palette_update_start)
                   1345:        palette_update_start=start;
                   1346:     if (start+count>palette_update_end)
                   1347:        palette_update_end=start+count;
                   1348: }
1.1.1.3   root     1349: 
1.1.1.19  root     1350: void DX_SetPalette_vsync(void)
                   1351: {
                   1352:   if (palette_update_end>palette_update_start) {
                   1353:     DX_SetPalette_real(palette_update_start,
                   1354:                       palette_update_end-palette_update_start);
                   1355:     palette_update_end=0;
                   1356:     palette_update_start=256;
                   1357:   }
                   1358: }
                   1359: 
                   1360: int DX_Fill (int dstx, int dsty, int width, int height, uae_u32 color, RGBFTYPE rgbtype)
                   1361: {
                   1362:     /* not implemented yet */
                   1363:     return 0;
                   1364: }
                   1365: 
                   1366: int DX_Blit (int srcx, int srcy, int dstx, int dsty, int width, int height, BLIT_OPCODE opcode)
                   1367: {
                   1368:     /* not implemented yet */
                   1369:     return 0;
                   1370: }
                   1371: 
                   1372: #define MAX_SCREEN_MODES 12
                   1373: 
                   1374: static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280, 1280 };
                   1375: static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768,  864,  960,  1024 };
1.1.1.3   root     1376: 
                   1377: int DX_FillResolutions (uae_u16 *ppixel_format)
                   1378: {
                   1379:     Screen *scr = ScreenOfDisplay (display, screen);
                   1380:     int i, count = 0;
                   1381:     int w = WidthOfScreen (scr);
                   1382:     int h = HeightOfScreen (scr);
1.1.1.5   root     1383:     int emulate_chunky = 0;
1.1.1.3   root     1384: 
1.1.1.19  root     1385:     /* we now need to find display depth first */
                   1386:     XVisualInfo vi;
                   1387:     if (!get_best_visual (&vi)) return 0;
                   1388:     bitdepth = vi.depth;
                   1389:     bit_unit = get_visual_bit_unit (&vi, bitdepth);
                   1390: 
                   1391:     if (ImageByteOrder (display) == LSBFirst) {
1.1.1.5   root     1392:     picasso_vidinfo.rgbformat = (bit_unit == 8 ? RGBFB_CHUNKY
                   1393:                                 : bitdepth == 15 && bit_unit == 16 ? RGBFB_R5G5B5PC
                   1394:                                 : bitdepth == 16 && bit_unit == 16 ? RGBFB_R5G6B5PC
                   1395:                                 : bit_unit == 24 ? RGBFB_B8G8R8
                   1396:                                 : bit_unit == 32 ? RGBFB_B8G8R8A8
                   1397:                                 : RGBFB_NONE);
1.1.1.19  root     1398:     } else {
                   1399:     picasso_vidinfo.rgbformat = (bit_unit == 8 ? RGBFB_CHUNKY
                   1400:                                 : bitdepth == 15 && bit_unit == 16 ? RGBFB_R5G5B5
                   1401:                                 : bitdepth == 16 && bit_unit == 16 ? RGBFB_R5G6B5
                   1402:                                 : bit_unit == 24 ? RGBFB_R8G8B8
                   1403:                                 : bit_unit == 32 ? RGBFB_A8R8G8B8
                   1404:                                 : RGBFB_NONE);
                   1405:     }
1.1.1.5   root     1406: 
                   1407:     *ppixel_format = 1 << picasso_vidinfo.rgbformat;
1.1.1.19  root     1408:     if (vi.VI_CLASS == TrueColor && (bit_unit == 16 || bit_unit == 32))
1.1.1.5   root     1409:        *ppixel_format |= RGBFF_CHUNKY, emulate_chunky = 1;
1.1.1.3   root     1410: 
                   1411: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
1.1.1.5   root     1412:     if (dgaavail && vidmodeavail) {
                   1413:        for (i = 0; i < vidmodecount && count < MAX_PICASSO_MODES; i++) {
                   1414:            int j;
                   1415:            for (j = 0; j <= emulate_chunky && count < MAX_PICASSO_MODES; j++) {
                   1416:                DisplayModes[count].res.width = allmodes[i]->hdisplay;
                   1417:                DisplayModes[count].res.height = allmodes[i]->vdisplay;
                   1418:                DisplayModes[count].depth = j == 1 ? 1 : bit_unit >> 3;
                   1419:                DisplayModes[count].refresh = 75;
                   1420:                count++;
                   1421:            }
1.1.1.3   root     1422:        }
1.1.1.5   root     1423:     } else
1.1.1.3   root     1424: #endif
1.1.1.5   root     1425:     {
                   1426:        for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES; i++) {
                   1427:            int j;
                   1428:            for (j = 0; j <= emulate_chunky && count < MAX_PICASSO_MODES; j++) {
                   1429:                if (x_size_table[i] <= w && y_size_table[i] <= h) {
                   1430:                    if (x_size_table[i] > picasso_maxw)
                   1431:                        picasso_maxw = x_size_table[i];
                   1432:                    if (y_size_table[i] > picasso_maxh)
                   1433:                        picasso_maxh = y_size_table[i];
                   1434:                    DisplayModes[count].res.width = x_size_table[i];
                   1435:                    DisplayModes[count].res.height = y_size_table[i];
                   1436:                    DisplayModes[count].depth = j == 1 ? 1 : bit_unit >> 3;
                   1437:                    DisplayModes[count].refresh = 75;
                   1438:                    count++;
                   1439:                }
                   1440:            }
                   1441:        }
                   1442:     }
1.1.1.3   root     1443: 
                   1444:     return count;
                   1445: }
                   1446: 
1.1.1.5   root     1447: uae_u8 *gfx_lock_picasso (void)
                   1448: {
                   1449: #ifdef USE_DGA_EXTENSION
                   1450:     if (dgamode)
                   1451:        return fb_addr;
1.1.1.3   root     1452:     else
1.1.1.5   root     1453: #endif
                   1454:        return pic_dinfo.ximg->data;
                   1455: }
1.1.1.19  root     1456: 
1.1.1.5   root     1457: void gfx_unlock_picasso (void)
                   1458: {
1.1.1.3   root     1459: }
1.1.1.5   root     1460: #endif
1.1.1.3   root     1461: 
1.1.1.5   root     1462: int lockscr (void)
1.1       root     1463: {
1.1.1.5   root     1464:     return 1;
1.1       root     1465: }
1.1.1.3   root     1466: 
1.1.1.5   root     1467: void unlockscr (void)
1.1.1.3   root     1468: {
                   1469: }
                   1470: 
1.1.1.19  root     1471: void toggle_mousegrab (void)
1.1.1.3   root     1472: {
1.1.1.5   root     1473:     if (grabbed) {
                   1474:        XUngrabPointer (display, CurrentTime);
                   1475:        XUndefineCursor (display, mywin);
1.1.1.19  root     1476:        reset_cursor ();
1.1.1.5   root     1477:        grabbed = 0;
                   1478:     } else if (! dgamode) {
                   1479:        XGrabPointer (display, mywin, 1, 0, GrabModeAsync, GrabModeAsync,
                   1480:                      mywin, blankCursor, CurrentTime);
                   1481:        oldx = current_width / 2;
                   1482:        oldy = current_height / 2;
                   1483:        XWarpPointer (display, None, mywin, 0, 0, 0, 0, oldx, oldy);
                   1484:        grabbed = 1;
                   1485:     }
1.1.1.3   root     1486: }
1.1.1.5   root     1487: 
1.1.1.19  root     1488: void framerate_up (void)
                   1489: {
                   1490:     if (currprefs.gfx_framerate < 20)
                   1491:        changed_prefs.gfx_framerate = currprefs.gfx_framerate + 1;
                   1492: }
                   1493: 
                   1494: void framerate_down (void)
                   1495: {
                   1496:     if (currprefs.gfx_framerate > 1)
                   1497:        changed_prefs.gfx_framerate = currprefs.gfx_framerate - 1;
                   1498: }
                   1499: 
                   1500: int is_fullscreen (void)
                   1501: {
                   1502: #ifdef USE_DGA_EXTENSION
                   1503:     return dgamode;
                   1504: #else
                   1505:     return 0;
                   1506: #endif
                   1507: }
                   1508: 
                   1509: void toggle_fullscreen (void)
                   1510: {
                   1511: #ifdef USE_DGA_EXTENSION
                   1512:     changed_prefs.gfx_afullscreen = changed_prefs.gfx_pfullscreen = !dgamode;
                   1513: #endif
                   1514: }
                   1515: 
                   1516: void screenshot (int type)
                   1517: {
                   1518:     write_log ("Screenshot not implemented yet\n");
                   1519: }
                   1520: 
                   1521: /*
                   1522:  * Mouse inputdevice functions
                   1523:  */
                   1524: 
                   1525: /* Hardwire for 3 axes and 3 buttons
                   1526:  * There is no 3rd axis as such - mousewheel events are
                   1527:  * supplied by X on buttons 4 and 5.
                   1528:  */
                   1529: #define MAX_BUTTONS     3
                   1530: #define MAX_AXES        3
                   1531: #define FIRST_AXIS      0
                   1532: #define FIRST_BUTTON    MAX_AXES
                   1533: 
                   1534: static int init_mouse (void)
                   1535: {
                   1536:    return 1;
                   1537: }
                   1538: 
                   1539: static void close_mouse (void)
                   1540: {
                   1541:    return;
                   1542: }
                   1543: 
1.1.1.20  root     1544: static int acquire_mouse (unsigned int num, int flags)
1.1.1.19  root     1545: {
                   1546:    return 1;
                   1547: }
                   1548: 
1.1.1.20  root     1549: static void unacquire_mouse (unsigned int num)
1.1.1.19  root     1550: {
                   1551:    return;
                   1552: }
                   1553: 
1.1.1.22! root     1554: static int get_mouse_num (void)
1.1.1.19  root     1555: {
                   1556:     return 1;
                   1557: }
                   1558: 
1.1.1.20  root     1559: static const char *get_mouse_name (unsigned int mouse)
1.1.1.3   root     1560: {
1.1.1.19  root     1561:     return 0;
1.1.1.5   root     1562: }
                   1563: 
1.1.1.22! root     1564: static int get_mouse_widget_num (unsigned int mouse)
1.1.1.19  root     1565: {
                   1566:     return MAX_AXES + MAX_BUTTONS;
                   1567: }
1.1.1.7   root     1568: 
1.1.1.20  root     1569: static int get_mouse_widget_first (unsigned int mouse, int type)
1.1.1.7   root     1570: {
1.1.1.19  root     1571:     switch (type) {
                   1572:        case IDEV_WIDGET_BUTTON:
                   1573:            return FIRST_BUTTON;
                   1574:        case IDEV_WIDGET_AXIS:
                   1575:            return FIRST_AXIS;
1.1.1.8   root     1576:     }
1.1.1.19  root     1577:     return -1;
                   1578: }
                   1579: 
1.1.1.20  root     1580: static int get_mouse_widget_type (unsigned int mouse, unsigned int num, char *name, uae_u32 *code)
1.1.1.19  root     1581: {
                   1582:     if (num >= MAX_AXES && num < MAX_AXES + MAX_BUTTONS) {
                   1583:        if (name)
                   1584:            sprintf (name, "Button %d", num + 1 + MAX_AXES);
                   1585:        return IDEV_WIDGET_BUTTON;
                   1586:     } else if (num < MAX_AXES) {
                   1587:        if (name)
                   1588:            sprintf (name, "Axis %d", num + 1);
                   1589:        return IDEV_WIDGET_AXIS;
1.1.1.7   root     1590:     }
1.1.1.19  root     1591:     return IDEV_WIDGET_NONE;
1.1.1.7   root     1592: }
                   1593: 
1.1.1.19  root     1594: static void read_mouse (void)
1.1.1.5   root     1595: {
1.1.1.19  root     1596:     /* We handle mouse input in handle_events() */
1.1.1.5   root     1597: }
                   1598: 
1.1.1.19  root     1599: struct inputdevice_functions inputdevicefunc_mouse = {
                   1600:     init_mouse, close_mouse, acquire_mouse, unacquire_mouse, read_mouse,
                   1601:     get_mouse_num, get_mouse_name,
                   1602:     get_mouse_widget_num, get_mouse_widget_type,
                   1603:     get_mouse_widget_first
                   1604: };
                   1605: 
                   1606: /*
                   1607:  * Keyboard inputdevice functions
                   1608:  */
1.1.1.22! root     1609: static int get_kb_num (void)
1.1.1.5   root     1610: {
1.1.1.19  root     1611:     return 1;
1.1.1.3   root     1612: }
1.1.1.6   root     1613: 
1.1.1.20  root     1614: static const char *get_kb_name (unsigned int kb)
1.1.1.6   root     1615: {
1.1.1.20  root     1616:     return "Default keyboard";
1.1.1.19  root     1617: }
                   1618: 
1.1.1.22! root     1619: static int get_kb_widget_num (unsigned int kb)
1.1.1.19  root     1620: {
                   1621:     return 255; // fix me
                   1622: }
                   1623: 
1.1.1.20  root     1624: static int get_kb_widget_first (unsigned int kb, int type)
1.1.1.19  root     1625: {
                   1626:     return 0;
1.1.1.6   root     1627: }
                   1628: 
1.1.1.20  root     1629: static int get_kb_widget_type (unsigned int kb, unsigned int num, char *name, uae_u32 *code)
1.1.1.19  root     1630: {
                   1631:     // fix me
                   1632:     *code = num;
                   1633:     return IDEV_WIDGET_KEY;
                   1634: }
                   1635: 
                   1636: static int keyhack (int scancode, int pressed, int num)
                   1637: {
                   1638:     return scancode;
                   1639: }
                   1640: 
                   1641: static void read_kb (void)
                   1642: {
                   1643: }
                   1644: static int init_kb (void)
                   1645: {
1.1.1.20  root     1646:     set_default_hotkeys (get_x11_default_hotkeys());
1.1.1.19  root     1647:     return 1;
                   1648: }
                   1649: 
                   1650: static void close_kb (void)
                   1651: {
                   1652: }
                   1653: 
1.1.1.20  root     1654: static int acquire_kb (unsigned int num, int flags)
1.1.1.19  root     1655: {
                   1656:     return 1;
                   1657: }
                   1658: 
1.1.1.20  root     1659: static void unacquire_kb (unsigned int num)
1.1.1.19  root     1660: {
                   1661: }
                   1662: 
                   1663: /*
                   1664:  * Default inputdevice config for X11 mouse
                   1665:  */
                   1666: void input_get_default_mouse (struct uae_input_device *uid)
                   1667: {
                   1668:     /* Supports only one mouse */
                   1669:     uid[0].eventid[ID_AXIS_OFFSET + 0][0]   = INPUTEVENT_MOUSE1_HORIZ;
                   1670:     uid[0].eventid[ID_AXIS_OFFSET + 1][0]   = INPUTEVENT_MOUSE1_VERT;
                   1671:     uid[0].eventid[ID_AXIS_OFFSET + 2][0]   = INPUTEVENT_MOUSE1_WHEEL;
                   1672:     uid[0].eventid[ID_BUTTON_OFFSET + 0][0] = INPUTEVENT_JOY1_FIRE_BUTTON;
                   1673:     uid[0].eventid[ID_BUTTON_OFFSET + 1][0] = INPUTEVENT_JOY1_2ND_BUTTON;
                   1674:     uid[0].eventid[ID_BUTTON_OFFSET + 2][0] = INPUTEVENT_JOY1_3RD_BUTTON;
                   1675:     uid[0].enabled = 1;
                   1676: }
                   1677: 
                   1678: struct inputdevice_functions inputdevicefunc_keyboard =
                   1679: {
                   1680:     init_kb, close_kb, acquire_kb, unacquire_kb,
                   1681:     read_kb, get_kb_num, get_kb_name, get_kb_widget_num,
                   1682:     get_kb_widget_type, get_kb_widget_first
                   1683: };
                   1684: 
                   1685: int getcapslockstate (void)
                   1686: {
                   1687:     return 0;
                   1688: }
                   1689: 
                   1690: void setcapslockstate (int state)
                   1691: {
                   1692: }
                   1693: 
                   1694: /*
                   1695:  * Handle gfx cfgfile options
                   1696:  */
1.1.1.21  root     1697: void target_save_options (FILE *f, const struct uae_prefs *p)
1.1.1.6   root     1698: {
                   1699:     fprintf (f, "x11.low_bandwidth=%s\n", p->x11_use_low_bandwidth ? "true" : "false");
                   1700:     fprintf (f, "x11.use_mitshm=%s\n", p->x11_use_mitshm ? "true" : "false");
                   1701:     fprintf (f, "x11.hide_cursor=%s\n", p->x11_hide_cursor ? "true" : "false");
                   1702: }
                   1703: 
1.1.1.21  root     1704: int target_parse_option (struct uae_prefs *p, const char *option, const char *value)
1.1.1.6   root     1705: {
                   1706:     return (cfgfile_yesno (option, value, "low_bandwidth", &p->x11_use_low_bandwidth)
                   1707:            || cfgfile_yesno (option, value, "use_mitshm", &p->x11_use_mitshm)
                   1708:            || cfgfile_yesno (option, value, "hide_cursor", &p->x11_hide_cursor));
                   1709: }
1.1.1.19  root     1710: 
                   1711: void target_default_options (struct uae_prefs *p)
                   1712: {
                   1713:     p->x11_use_low_bandwidth = 0;
                   1714:     p->x11_use_mitshm = 1;
                   1715:     p->x11_hide_cursor = 1;
                   1716: }

unix.superglobalmegacorp.com

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