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