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