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