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