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