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