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

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

unix.superglobalmegacorp.com

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