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

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

unix.superglobalmegacorp.com

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