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