|
|
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.2 root 8: * DGA support by Kai Kollmorgen
1.1 root 9: */
10:
11: #include "sysconfig.h"
12: #include "sysdeps.h"
13:
14: #include <X11/Xlib.h>
15: #include <X11/Xutil.h>
16: #include <X11/keysym.h>
17: #include <X11/cursorfont.h>
18:
19: #include <ctype.h>
20: #include <signal.h>
21:
22: #include "config.h"
23: #include "options.h"
1.1.1.3 root 24: #include "threaddep/penguin.h"
25: #include "uae.h"
1.1 root 26: #include "memory.h"
27: #include "custom.h"
1.1.1.2 root 28: #include "readcpu.h"
1.1 root 29: #include "newcpu.h"
30: #include "xwin.h"
31: #include "keyboard.h"
32: #include "keybuf.h"
33: #include "gui.h"
34: #include "debug.h"
1.1.1.3 root 35: #include "picasso96.h"
36:
37: #ifdef __cplusplus
38: #define VI_CLASS c_class
39: #else
40: #define VI_CLASS class
41: #endif
1.1 root 42:
1.1.1.2 root 43: #ifdef USE_DGA_EXTENSION
1.1.1.3 root 44:
45: #ifdef USE_VIDMODE_EXTENSION
46: #include <X11/extensions/xf86vmode.h>
47: #define VidMode_MINMAJOR 0
48: #define VidMode_MINMINOR 0
49: #endif
50:
1.1.1.2 root 51: #include <X11/extensions/xf86dga.h>
52: #define DGA_MINMAJOR 0
53: #define DGA_MINMINOR 0
1.1.1.3 root 54:
55: #elif SHM_SUPPORT_LINKS == 1
56:
57: #include <sys/ipc.h>
58: #include <sys/shm.h>
59: #include <X11/extensions/XShm.h>
60:
61: #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
62: do { \
63: if (currprefs.use_mitshm) \
64: XShmPutImage (display, mywin, blackgc, IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT, 0); \
65: else \
66: XPutImage (display, mywin, blackgc, IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT); \
67: } while (0)
68: #else
69: #define DO_PUTIMAGE(IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT) \
70: XPutImage (display, mywin, blackgc, IMG, SRCX, SRCY, DSTX, DSTY, WIDTH, HEIGHT)
1.1.1.2 root 71: #endif
72:
1.1 root 73: #ifdef __cplusplus
74: static RETSIGTYPE sigbrkhandler(...)
75: #else
76: static RETSIGTYPE sigbrkhandler(int foo)
77: #endif
78: {
79: activate_debugger();
80:
81: #if !defined(__unix) || defined(__NeXT__)
82: signal(SIGINT, sigbrkhandler);
83: #endif
84: }
85:
86: void setup_brkhandler(void)
87: {
88: #if defined(__unix) && !defined(__NeXT__)
89: struct sigaction sa;
90: sa.sa_handler = sigbrkhandler;
91: sa.sa_flags = 0;
92: #ifdef SA_RESTART
93: sa.sa_flags = SA_RESTART;
94: #endif
95: sigemptyset(&sa.sa_mask);
96: sigaction(SIGINT, &sa, NULL);
97: #else
98: signal(SIGINT, sigbrkhandler);
1.1.1.2 root 99: #endif
1.1.1.3 root 100: }
1.1.1.2 root 101:
1.1 root 102: static Display *display;
103: static int screen;
104: static Window rootwin, mywin;
105:
1.1.1.3 root 106: static GC whitegc,blackgc,picassogc;
1.1 root 107: static XColor black,white;
1.1.1.3 root 108: static Colormap cmap, cmap2;
109:
110: /* Kludge-O-Matic */
111: static int dga_colormap_installed;
1.1 root 112:
113: static int need_dither;
114:
1.1.1.3 root 115: static int screen_is_picasso;
116: static char picasso_invalid_lines[1201];
117:
1.1 root 118: static int autorepeatoff = 0;
119: static char *image_mem;
1.1.1.3 root 120: static XImage *img, *picasso_img;
1.1 root 121: static Visual *vis;
122: static XVisualInfo visualInfo;
123: static int bitdepth, bit_unit;
124: static Cursor blankCursor, xhairCursor;
125: static int cursorOn;
1.1.1.3 root 126: static int inverse_byte_order = 0;
1.1 root 127:
1.1.1.3 root 128: static int current_width, current_height;
1.1 root 129:
1.1.1.2 root 130: static int x11_init_ok;
131:
1.1 root 132: /* Keyboard and mouse */
133:
134: static int keystate[256];
135:
136: static int inwindow;
137: const long int eventmask = (KeyPressMask|KeyReleaseMask|ButtonPressMask
138: |ButtonReleaseMask|PointerMotionMask
1.1.1.2 root 139: #ifndef USE_DGA_EXTENSION
1.1 root 140: |FocusChangeMask|EnterWindowMask
141: |ExposureMask
1.1.1.2 root 142: |LeaveWindowMask
143: #endif
144: );
1.1 root 145:
1.1.1.3 root 146: static XImage *get_image (int w, int h, char **mem_p)
147: {
148: XImage *new_img;
149: char *p;
150:
151: #if SHM_SUPPORT_LINKS == 1
152: if (currprefs.use_mitshm) {
153: XShmSegmentInfo *shminfo = xmalloc (sizeof (XShmSegmentInfo));
154:
155: printf ("Using MIT-SHM extension.\n");
156: new_img = XShmCreateImage (display, vis, bitdepth, ZPixmap, 0, shminfo, w, h);
157:
158: shminfo->shmid = shmget (IPC_PRIVATE, h * new_img->bytes_per_line,
159: IPC_CREAT | 0777);
160: shminfo->shmaddr = new_img->data = (char *)shmat (shminfo->shmid, 0, 0);
161: if (mem_p != 0)
162: *mem_p = new_img->data;
163: shminfo->readOnly = False;
164: /* let the xserver attach */
165: XShmAttach (display, shminfo);
166: XSync (display,0);
167: /* now deleting means making it temporary */
168: shmctl (shminfo->shmid, IPC_RMID, 0);
169: return new_img;
170: }
171: #endif
172:
173: /* Question for people who know about X: Could we allocate the buffer
174: * after creating the image and then do new_img->data = buffer, as above in
175: * the SHM case?
176: */
177: printf ("Using normal image buffer.\n");
178: p = (char *)xmalloc (h * w * ((bit_unit + 7) / 8)); /* ??? */
179: if (mem_p != 0)
180: *mem_p = p;
181: new_img = XCreateImage (display, vis, bitdepth, ZPixmap, 0, p,
182: w, h, 32, 0);
183: if (new_img->bytes_per_line != w * ((bit_unit + 7) / 8))
184: fprintf (stderr, "Possible bug here... graphics may look strange.\n");
185:
186: return new_img;
187: }
188:
189: #ifdef USE_DGA_EXTENSION
190:
191: static int fb_bank, fb_banks, fb_mem;
192: static char *fb_addr;
193: static int fb_width;
1.1 root 194:
1.1.1.3 root 195: static void switch_to_dga_mode (void)
196: {
197: XF86DGADirectVideo(display, screen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb);
198: XF86DGASetViewPort (display, screen, 0, 0);
199: memset (fb_addr, 0, fb_mem * 1024);
200: }
201:
202:
203: #ifdef USE_VIDMODE_EXTENSION
204: static XF86VidModeModeInfo **allmodes;
205: static int vidmodecount;
206:
207: static int get_vidmodes (void)
208: {
209: return XF86VidModeGetAllModeLines (display, screen, &vidmodecount, &allmodes);
210: }
1.1.1.4 ! root 211: #endif
1.1.1.3 root 212:
213: static void switch_to_best_mode (void)
214: {
1.1.1.4 ! root 215: #ifdef USE_VIDMODE_EXTENSION
1.1.1.3 root 216: int i, best;
217: best = 0;
218: for (i = 1; i < vidmodecount; i++) {
219: if (allmodes[i]->hdisplay >= current_width
220: && allmodes[i]->vdisplay >= current_height
221: && allmodes[i]->hdisplay <= allmodes[best]->hdisplay
222: && allmodes[i]->vdisplay <= allmodes[best]->vdisplay)
223: best = i;
224: }
225: printf ("entering DGA mode: %dx%d (%d, %d)\n",
226: allmodes[best]->hdisplay, allmodes[best]->vdisplay,
227: current_width, current_height);
228: XF86VidModeSwitchToMode (display, screen, allmodes[best]);
229: XF86VidModeSetViewPort (display, screen, 0, 0);
1.1.1.4 ! root 230: #endif
1.1.1.3 root 231: XMoveWindow (display, mywin, 0, 0);
232: XWarpPointer (display, None, rootwin, 0, 0, 0, 0, 0, 0);
233: switch_to_dga_mode ();
234: }
235:
236: static void enter_dga_mode (void)
237: {
238: Screen *scr = ScreenOfDisplay (display, screen);
239: int w = WidthOfScreen (scr);
240: int h = HeightOfScreen (scr);
241:
242: XRaiseWindow (display, mywin);
243:
244: /* We want all the key presses */
245: XGrabKeyboard (display, rootwin, 1, GrabModeAsync,
246: GrabModeAsync, CurrentTime);
247:
248: /* and all the mouse moves */
249: XGrabPointer (display, rootwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
250: GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
251:
252: XF86DGAGetVideo (display, screen, &fb_addr, &fb_width, &fb_bank, &fb_mem);
253: fprintf (stderr, "addr:%X, width %d, bank size %d mem size %d\n",
254: fb_addr, fb_width, fb_bank,fb_mem);
255:
256: if (fb_bank < fb_mem)
257: fprintf (stderr, "banksize < memsize, must use XF86DGASetVidPage !\n");
258:
259: switch_to_best_mode ();
260:
261: gfxvidinfo.rowbytes = fb_width*gfxvidinfo.pixbytes;
262: gfxvidinfo.bufmem = fb_addr;
263: }
264:
265: static void leave_dga_mode (void)
266: {
267: #ifdef USE_VIDMODE_EXTENSION
268: XF86VidModeSwitchToMode (display, screen, allmodes[0]);
269: #endif
270: XF86DGADirectVideo (display, screen, 0);
271: XUngrabPointer (display, CurrentTime);
272: XUngrabKeyboard (display, CurrentTime);
273: }
274:
275: #endif
276: static char *oldpixbuf;
1.1 root 277:
278: void flush_line(int y)
279: {
1.1.1.2 root 280: #ifdef USE_DGA_EXTENSION
281: if (need_dither) {
1.1.1.3 root 282: char *addr = gfxvidinfo.linemem;
283: if (addr == NULL)
284: addr = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
285:
286: DitherLine((unsigned char *)(fb_addr + fb_width*y), (uae_u16 *)addr, 0, y,
287: gfxvidinfo.width, bit_unit);
1.1.1.2 root 288: }
289: #else
1.1.1.3 root 290: char *linebuf;
1.1 root 291: int xs = 0, xe;
1.1.1.3 root 292: int len;
1.1 root 293:
1.1.1.3 root 294: linebuf = gfxvidinfo.linemem;
295: if (linebuf == NULL)
296: linebuf = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
297:
298: xe = gfxvidinfo.width-1;
299:
300: if (currprefs.use_low_bandwidth) {
301: char *src, *dst;
302: switch(gfxvidinfo.pixbytes) {
303: case 4:
304: {
305: uae_u32 *newp = (uae_u32 *)linebuf;
306: uae_u32 *oldp = (uae_u32 *)((uae_u8 *)image_mem + y*img->bytes_per_line);
307: while (newp[xs] == oldp[xs]) {
308: if (xs == xe)
309: return;
310: xs++;
311: }
312: while (newp[xe] == oldp[xe]) xe--;
313:
314: dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1 root 315: }
1.1.1.3 root 316: break;
317: case 2:
318: {
319: uae_u16 *newp = (uae_u16 *)linebuf;
320: uae_u16 *oldp = (uae_u16 *)((uae_u8 *)image_mem + y*img->bytes_per_line);
321: while (newp[xs] == oldp[xs]) {
322: if (xs == xe)
323: return;
324: xs++;
325: }
326: while (newp[xe] == oldp[xe]) xe--;
327:
328: dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1 root 329: }
1.1.1.3 root 330: break;
331: case 1:
332: {
333: uae_u8 *newp = (uae_u8 *)linebuf;
334: uae_u8 *oldp = (uae_u8 *)((uae_u8 *)image_mem + y*img->bytes_per_line);
335: while (newp[xs] == oldp[xs]) {
336: if (xs == xe)
337: return;
338: xs++;
339: }
340: while (newp[xe] == oldp[xe]) xe--;
1.1 root 341:
1.1.1.3 root 342: dst = (char *)(oldp + xs); src = (char *)(newp + xs);
1.1 root 343: }
1.1.1.3 root 344: break;
1.1 root 345:
1.1.1.3 root 346: default:
347: abort();
348: break;
1.1 root 349: }
350:
351: len = xe - xs + 1;
1.1.1.3 root 352: memcpy (dst, src, len * gfxvidinfo.pixbytes);
353: } else if (need_dither) {
354: uae_u8 *target = (uae_u8 *)image_mem + img->bytes_per_line * y;
355: len = currprefs.gfx_width;
356: DitherLine(target, (uae_u16 *)linebuf, 0, y, gfxvidinfo.width, bit_unit);
357: } else {
358: fprintf(stderr, "Bug!\n");
359: abort();
1.1 root 360: }
1.1.1.2 root 361:
1.1.1.3 root 362: DO_PUTIMAGE (img, xs, y, xs, y, len, 1);
1.1.1.2 root 363: #endif
1.1 root 364: }
365:
366: void flush_block (int ystart, int ystop)
367: {
1.1.1.2 root 368: #ifdef USE_DGA_EXTENSION
369: #else
1.1 root 370: int len, xs = 0;
1.1.1.3 root 371:
372: len = gfxvidinfo.width;
373: DO_PUTIMAGE (img, xs, ystart, 0, ystart, len, ystop - ystart + 1);
1.1.1.2 root 374: #endif
1.1 root 375: }
376:
377: void flush_screen (int ystart, int ystop)
378: {
1.1.1.2 root 379: #ifdef USE_DGA_EXTENSION
380: #else
1.1.1.3 root 381: #if SHM_SUPPORT_LINKS == 1
382: if (currprefs.use_mitshm) XSync(display, 0);
1.1 root 383: #endif
1.1.1.2 root 384: #endif
1.1 root 385: }
386:
387: static __inline__ int bitsInMask(unsigned long mask)
388: {
389: /* count bits in mask */
390: int n = 0;
391: while(mask) {
392: n += mask&1;
393: mask >>= 1;
394: }
395: return n;
396: }
397:
398: static __inline__ int maskShift(unsigned long mask)
399: {
400: /* determine how far mask is shifted */
401: int n = 0;
402: while(!(mask&1)) {
403: n++;
404: mask >>= 1;
405: }
406: return n;
407: }
408:
1.1.1.3 root 409: static unsigned long pixel_return[256];
410: static XColor parsed_xcolors[256];
411: static int ncolors = 0;
412:
413: static int blackval = 32767;
414: static int whiteval = 0;
415:
1.1 root 416: static int get_color(int r, int g, int b, xcolnr *cnp)
417: {
1.1.1.3 root 418: XColor *col = parsed_xcolors + ncolors;
1.1 root 419: char str[10];
1.1.1.3 root 420:
1.1 root 421: sprintf(str, "rgb:%x/%x/%x", r, g, b);
1.1.1.3 root 422: XParseColor(display, cmap, str, col);
423: *cnp = col->pixel = pixel_return[ncolors];
424: XStoreColor (display, cmap, col);
425: XStoreColor (display, cmap2, col);
426:
427: if (r + g + b < blackval)
428: blackval = r + g + b, black = *col;
429: if (r + g + b > whiteval)
430: whiteval = r + g + b, white = *col;
431:
432: ncolors++;
433: return 1;
1.1 root 434: }
435:
436: static int init_colors(void)
437: {
1.1.1.3 root 438: int i;
439:
1.1 root 440: if (need_dither) {
1.1.1.3 root 441: XAllocColorCells (display, cmap, 0, 0, 0, pixel_return, 256);
442: XAllocColorCells (display, cmap2, 0, 0, 0, pixel_return, 256);
1.1 root 443: if (bitdepth == 1)
444: setup_greydither (1, get_color);
445: else
446: setup_dither (bitdepth, get_color);
1.1.1.3 root 447: } else {
448: if (bitdepth != 8 && bitdepth != 12 && bitdepth != 15
449: && bitdepth != 16 && bitdepth != 24) {
450: fprintf(stderr, "Unsupported bit depth (%d)\n", bitdepth);
451: return 0;
1.1 root 452: }
453:
1.1.1.3 root 454: switch (visualInfo.VI_CLASS) {
455: case TrueColor:
456: {
457: int red_bits = bitsInMask(visualInfo.red_mask);
458: int green_bits = bitsInMask(visualInfo.green_mask);
459: int blue_bits = bitsInMask(visualInfo.blue_mask);
460: int red_shift = maskShift(visualInfo.red_mask);
461: int green_shift = maskShift(visualInfo.green_mask);
462: int blue_shift = maskShift(visualInfo.blue_mask);
463: alloc_colors64k(red_bits, green_bits, blue_bits, red_shift,
464: green_shift, blue_shift);
465: }
466: XParseColor(display, cmap, "#000000", &black);
467: if (!XAllocColor(display, cmap, &black))
468: fprintf(stderr, "Whoops??\n");
469: XParseColor(display, cmap, "#ffffff", &white);
470: if (!XAllocColor(display, cmap, &white))
471: fprintf(stderr, "Whoops??\n");
472: break;
473:
474: case GrayScale:
475: case PseudoColor:
476: XAllocColorCells (display, cmap, 0, 0, 0, pixel_return, 256);
477: XAllocColorCells (display, cmap2, 0, 0, 0, pixel_return, 256);
478: alloc_colors256(get_color);
479: break;
480:
481: default:
482: fprintf (stderr, "Unsupported visual class (%d)\n", visualInfo.VI_CLASS);
483: return 0;
484: }
485: }
486: switch (gfxvidinfo.pixbytes) {
487: case 2:
488: for (i = 0; i < 4096; i++)
489: xcolors[i] = xcolors[i] * 0x00010001;
490: gfxvidinfo.can_double = 1;
491: break;
492: case 1:
493: for (i = 0; i < 4096; i++)
494: xcolors[i] = xcolors[i] * 0x01010101;
495: gfxvidinfo.can_double = 1;
1.1 root 496: break;
497: default:
1.1.1.3 root 498: gfxvidinfo.can_double = 0;
499: break;
1.1 root 500: }
1.1.1.3 root 501: if(inverse_byte_order)
502: switch(gfxvidinfo.pixbytes) {
503: case 4:
504: for(i = 0; i < 4096; i++)
505: xcolors[i] = ((((xcolors[i]>>0)&255) << 24)
506: | (((xcolors[i]>>8)&255) << 16)
507: | (((xcolors[i]>>16)&255) << 8)
508: | (((xcolors[i]>>24)&255) << 0));
509: break;
510: case 2:
511: for (i = 0; i < 4096; i++)
512: xcolors[i] = (xcolors[i]>>8) | ((xcolors[i]&255)<<8);
513: break;
514: default:
515: break;
516: }
1.1 root 517: return 1;
518: }
519:
1.1.1.3 root 520: int graphics_setup(void)
1.1 root 521: {
522: char *display_name = 0;
1.1.1.2 root 523: #ifdef USE_DGA_EXTENSION
524: int MajorVersion, MinorVersion;
525: int EventBase, ErrorBase;
526: if (geteuid()) {
527: fprintf(stderr, "You must be root to use UAE with the DGA extensions.\n");
1.1.1.3 root 528: return 0;
1.1 root 529: }
1.1.1.2 root 530: #endif
1.1.1.3 root 531:
1.1 root 532: display = XOpenDisplay(display_name);
533: if (display == 0) {
534: fprintf(stderr, "Can't connect to X server %s\n", XDisplayName(display_name));
535: return 0;
536: }
1.1.1.3 root 537:
1.1.1.2 root 538: #ifdef USE_DGA_EXTENSION
1.1.1.3 root 539: if (!XF86DGAQueryVersion (display, &MajorVersion, &MinorVersion)) {
1.1.1.2 root 540: fprintf(stderr, "Unable to query video extension version\n");
1.1.1.3 root 541: return 0;
1.1.1.2 root 542: }
1.1.1.3 root 543:
544: if (!XF86DGAQueryExtension (display, &EventBase, &ErrorBase)) {
1.1.1.2 root 545: fprintf(stderr, "Unable to query video extension information\n");
1.1.1.3 root 546: return 0;
1.1.1.2 root 547: }
1.1.1.3 root 548:
1.1.1.2 root 549: /* Fail if the extension version in the server is too old */
550: if (MajorVersion < DGA_MINMAJOR ||
551: (MajorVersion == DGA_MINMAJOR && MinorVersion < DGA_MINMINOR)) {
1.1.1.3 root 552: fprintf (stderr,
553: "Xserver is running an old XFree86-DGA version"
554: " (%d.%d)\n", MajorVersion, MinorVersion);
555: fprintf (stderr, "Minimum required version is %d.%d\n",
1.1.1.2 root 556: DGA_MINMAJOR, DGA_MINMINOR);
1.1.1.3 root 557: return 0;
558: }
559: #ifdef USE_VIDMODE_EXTENSION
560: if (!XF86VidModeQueryVersion (display, &MajorVersion, &MinorVersion)) {
561: fprintf (stderr, "Unable to query video extension version\n");
562: return 0;
563: }
564:
565: if (!XF86VidModeQueryExtension (display, &EventBase, &ErrorBase)) {
566: fprintf (stderr, "Unable to query video extension information\n");
567: return 0;
568: }
569:
570: /* Fail if the extension version in the server is too old */
571: if (MajorVersion < VidMode_MINMAJOR ||
572: (MajorVersion == VidMode_MINMAJOR && MinorVersion < VidMode_MINMINOR)) {
573: fprintf (stderr,
574: "Xserver is running an old XFree86-VidMode version"
575: " (%d.%d)\n", MajorVersion, MinorVersion);
576: fprintf (stderr, "Minimum required version is %d.%d\n",
577: VidMode_MINMAJOR, VidMode_MINMINOR);
578: return 0;
579: }
580: if (!get_vidmodes ()) {
581: fprintf (stderr, "Error getting video mode information\n");
582: return 0;
1.1.1.2 root 583: }
584: #endif
585:
1.1.1.3 root 586: #endif
587:
588: {
589: int local_byte_order;
590: int x = 0x04030201;
591: char *y=(char*)&x;
592:
593: local_byte_order = y[0] == 0x04 ? MSBFirst : LSBFirst;
594: if (ImageByteOrder(display) != local_byte_order)
595: inverse_byte_order = 1;
596: }
597:
598: return 1;
599: }
600:
601: static void fixup_prefs_dimensions (void)
602: {
603: if (currprefs.gfx_width < 320)
604: currprefs.gfx_width = 320;
605: if (currprefs.gfx_height < 200)
606: currprefs.gfx_height = 200;
607: if (currprefs.gfx_height > 300 && ! currprefs.gfx_linedbl)
608: currprefs.gfx_height = 300;
609: if (currprefs.gfx_height > 600)
610: currprefs.gfx_height = 600;
611:
612: currprefs.gfx_width += 7; /* X86.S wants multiples of 4 bytes, might be 8 in the future. */
613: currprefs.gfx_width &= ~7;
614: }
615:
616: int graphics_init(void)
617: {
618: int i,j;
619: XSetWindowAttributes wattr;
620: XPixmapFormatValues *xpfvs;
621:
622: if (currprefs.color_mode > 5)
623: fprintf(stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
624:
625: x11_init_ok = 0;
626: need_dither = 0;
627: screen_is_picasso = 0;
628:
1.1 root 629: screen = XDefaultScreen(display);
630: rootwin = XRootWindow(display,screen);
1.1.1.3 root 631:
1.1 root 632: /* try for a 12 bit visual first, then a 16 bit, then a 24 bit, then 8 bit */
633: if (XMatchVisualInfo(display, screen, 12, TrueColor, &visualInfo)) {
1.1.1.3 root 634: } else if (XMatchVisualInfo(display, screen, 15, TrueColor, &visualInfo)) {
1.1 root 635: } else if (XMatchVisualInfo(display, screen, 16, TrueColor, &visualInfo)) {
636: } else if (XMatchVisualInfo(display, screen, 24, TrueColor, &visualInfo)) {
637: } else if (XMatchVisualInfo(display, screen, 8, PseudoColor, &visualInfo)) {
638: /* for our HP boxes */
639: } else if (XMatchVisualInfo(display, screen, 8, GrayScale, &visualInfo)) {
640: } else if (XMatchVisualInfo(display, screen, 4, PseudoColor, &visualInfo)) {
641: /* VGA16 server. Argh. */
642: } else if (XMatchVisualInfo(display, screen, 1, StaticGray, &visualInfo)) {
643: /* Mono server. Yuk */
644: } else {
645: fprintf(stderr, "Can't obtain appropriate X visual.\n");
646: return 0;
647: }
648: vis = visualInfo.visual;
649: bitdepth = visualInfo.depth;
1.1.1.3 root 650:
1.1 root 651: /* We now have the bitdepth of the display, but that doesn't tell us yet
652: * how many bits to use per pixel. The VGA16 server has a bitdepth of 4,
653: * but uses 1 byte per pixel. */
654: xpfvs = XListPixmapFormats(display, &i);
655: for (j = 0; j < i && xpfvs->depth != bitdepth; j++, xpfvs++)
656: ;
657: if (j == i) {
658: fprintf(stderr, "Your X server is feeling ill.\n");
659: return 0;
660: }
1.1.1.3 root 661:
1.1 root 662: bit_unit = xpfvs->bits_per_pixel;
663: fprintf(stderr, "Using %d bit visual, %d bits per pixel\n", bitdepth, bit_unit);
664:
1.1.1.3 root 665: fixup_prefs_dimensions ();
1.1.1.2 root 666:
1.1.1.3 root 667: gfxvidinfo.width = currprefs.gfx_width;
668: gfxvidinfo.height = currprefs.gfx_height;
1.1 root 669:
670: cmap = XCreateColormap(display, rootwin, vis, AllocNone);
1.1.1.3 root 671: cmap2 = XCreateColormap(display, rootwin, vis, AllocNone);
1.1.1.2 root 672: #ifdef USE_DGA_EXTENSION
673: wattr.override_redirect = 1;
674: #endif
1.1 root 675: wattr.event_mask = eventmask;
1.1.1.3 root 676: wattr.background_pixel = /*black.pixel*/0;
1.1 root 677: wattr.backing_store = Always;
678: wattr.backing_planes = bitdepth;
679: wattr.border_pixmap = None;
1.1.1.3 root 680: wattr.border_pixel = /*black.pixel*/0;
1.1 root 681: wattr.colormap = cmap;
1.1.1.3 root 682:
683: mywin = XCreateWindow(display, rootwin, 0, 0, currprefs.gfx_width, currprefs.gfx_height, 0,
1.1 root 684: bitdepth, InputOutput, vis,
685: CWEventMask|CWBackPixel|CWBorderPixel|CWBackingStore
1.1.1.2 root 686: |CWBackingPlanes|CWColormap
687: #ifdef USE_DGA_EXTENSION
688: |CWOverrideRedirect
689: #endif
690: ,&wattr);
1.1.1.3 root 691:
692: current_width = currprefs.gfx_width;
693: current_height = currprefs.gfx_height;
694:
1.1.1.2 root 695: XMapWindow(display, mywin);
696: #ifdef USE_DGA_EXTENSION
697: XRaiseWindow(display, mywin);
698: #else
1.1 root 699: XStoreName(display, mywin, "UAE");
1.1.1.2 root 700: #endif
1.1.1.3 root 701:
702: if (bitdepth < 8 || (bitdepth == 8 && currprefs.color_mode == 3)) {
1.1 root 703: gfxvidinfo.pixbytes = 2;
1.1.1.3 root 704: currprefs.use_low_bandwidth = 0;
1.1 root 705: need_dither = 1;
706: } else {
1.1.1.3 root 707: gfxvidinfo.pixbytes = bit_unit >> 3;
1.1 root 708: }
1.1.1.2 root 709:
710: #ifdef USE_DGA_EXTENSION
1.1.1.3 root 711: enter_dga_mode ();
712: /*setuid(getuid());*/
1.1.1.2 root 713: #else
1.1.1.3 root 714:
715: img = get_image (currprefs.gfx_width, currprefs.gfx_height, &image_mem);
1.1.1.2 root 716: #endif
1.1.1.3 root 717:
1.1 root 718: if (need_dither) {
1.1.1.3 root 719: gfxvidinfo.maxblocklines = 0;
720: gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * currprefs.gfx_width;
721: gfxvidinfo.linemem = (char *)malloc(gfxvidinfo.rowbytes);
722: } else if (currprefs.use_low_bandwidth) {
723: gfxvidinfo.maxblocklines = 0;
724: gfxvidinfo.rowbytes = img->bytes_per_line;
725: gfxvidinfo.linemem = gfxvidinfo.bufmem = (char *)malloc(gfxvidinfo.rowbytes);
1.1 root 726: } else {
1.1.1.3 root 727: gfxvidinfo.maxblocklines = 100; /* whatever... */
728: #ifndef USE_DGA_EXTENSION
1.1 root 729: gfxvidinfo.rowbytes = img->bytes_per_line;
730: gfxvidinfo.bufmem = image_mem;
1.1.1.2 root 731: #endif
1.1.1.3 root 732: gfxvidinfo.linemem = NULL;
1.1 root 733: }
734:
735: if (!init_colors())
736: return 0;
737:
1.1.1.3 root 738: #ifndef USE_DGA_EXTENSION
739: blankCursor = XCreatePixmapCursor(display,
740: XCreatePixmap(display, mywin, 1, 1, 1),
741: XCreatePixmap(display, mywin, 1, 1, 1),
742: &black, &white, 0, 0);
743: xhairCursor = XCreateFontCursor(display, XC_crosshair);
744:
745: whitegc = XCreateGC(display,mywin,0,0);
746: blackgc = XCreateGC(display,mywin,0,0);
747: picassogc = XCreateGC (display,mywin,0,0);
748:
749: XSetForeground(display, blackgc, black.pixel);
750: XSetForeground(display, whitegc, white.pixel);
751: #endif
752:
1.1 root 753: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
754: for(i=0; i<256; i++)
755: keystate[i] = 0;
1.1.1.3 root 756:
757: lastmx = lastmy = 0;
1.1 root 758: newmousecounters = 0;
759: inwindow = 0;
1.1.1.2 root 760:
761: #ifndef USE_DGA_EXTENSION
1.1.1.3 root 762: if (!currprefs.no_xhair)
763: XDefineCursor(display, mywin, xhairCursor);
1.1 root 764: else
1.1.1.3 root 765: XDefineCursor(display, mywin, blankCursor);
1.1 root 766: cursorOn = 1;
1.1.1.2 root 767: #else
1.1.1.3 root 768: dga_colormap_installed = 0;
769: XF86DGAInstallColormap (display, screen, cmap);
1.1.1.2 root 770: #endif
1.1.1.3 root 771:
1.1.1.2 root 772: return x11_init_ok = 1;
1.1 root 773: }
774:
775: void graphics_leave(void)
776: {
1.1.1.2 root 777: if (!x11_init_ok)
778: return;
1.1.1.3 root 779:
1.1 root 780: if (autorepeatoff)
1.1.1.3 root 781: XAutoRepeatOn(display);
1.1.1.2 root 782: XFlush(display);
783: XSync(display, 0);
784: #ifdef USE_DGA_EXTENSION
1.1.1.3 root 785: leave_dga_mode ();
1.1.1.2 root 786: dumpcustom();
787: #endif
1.1 root 788: }
789:
1.1.1.3 root 790: /* Decode KeySyms. This function knows about all keys that are common
1.1 root 791: * between different keyboard languages. */
792: static int kc_decode (KeySym ks)
793: {
1.1.1.3 root 794: switch (ks) {
1.1 root 795: case XK_B: case XK_b: return AK_B;
796: case XK_C: case XK_c: return AK_C;
797: case XK_D: case XK_d: return AK_D;
798: case XK_E: case XK_e: return AK_E;
799: case XK_F: case XK_f: return AK_F;
800: case XK_G: case XK_g: return AK_G;
801: case XK_H: case XK_h: return AK_H;
802: case XK_I: case XK_i: return AK_I;
803: case XK_J: case XK_j: return AK_J;
804: case XK_K: case XK_k: return AK_K;
805: case XK_L: case XK_l: return AK_L;
806: case XK_N: case XK_n: return AK_N;
807: case XK_O: case XK_o: return AK_O;
808: case XK_P: case XK_p: return AK_P;
809: case XK_R: case XK_r: return AK_R;
810: case XK_S: case XK_s: return AK_S;
811: case XK_T: case XK_t: return AK_T;
812: case XK_U: case XK_u: return AK_U;
813: case XK_V: case XK_v: return AK_V;
814: case XK_X: case XK_x: return AK_X;
1.1.1.3 root 815:
1.1 root 816: case XK_0: return AK_0;
817: case XK_1: return AK_1;
818: case XK_2: return AK_2;
819: case XK_3: return AK_3;
820: case XK_4: return AK_4;
821: case XK_5: return AK_5;
822: case XK_6: return AK_6;
823: case XK_7: return AK_7;
824: case XK_8: return AK_8;
825: case XK_9: return AK_9;
1.1.1.3 root 826:
1.1 root 827: /* You never know which Keysyms might be missing on some workstation
828: * This #ifdef should be enough. */
829: #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End)
830: case XK_KP_0: case XK_KP_Insert: return AK_NP0;
831: case XK_KP_1: case XK_KP_End: return AK_NP1;
832: case XK_KP_2: case XK_KP_Down: return AK_NP2;
833: case XK_KP_3: case XK_KP_Next: return AK_NP3;
834: case XK_KP_4: case XK_KP_Left: return AK_NP4;
835: case XK_KP_5: case XK_KP_Begin: return AK_NP5;
836: case XK_KP_6: case XK_KP_Right: return AK_NP6;
837: case XK_KP_7: case XK_KP_Home: return AK_NP7;
838: case XK_KP_8: case XK_KP_Up: return AK_NP8;
839: case XK_KP_9: case XK_KP_Prior: return AK_NP9;
840: #else
841: case XK_KP_0: return AK_NP0;
842: case XK_KP_1: return AK_NP1;
843: case XK_KP_2: return AK_NP2;
844: case XK_KP_3: return AK_NP3;
845: case XK_KP_4: return AK_NP4;
846: case XK_KP_5: return AK_NP5;
847: case XK_KP_6: return AK_NP6;
848: case XK_KP_7: return AK_NP7;
849: case XK_KP_8: return AK_NP8;
850: case XK_KP_9: return AK_NP9;
851: #endif
852: case XK_KP_Divide: return AK_NPDIV;
853: case XK_KP_Multiply: return AK_NPMUL;
854: case XK_KP_Subtract: return AK_NPSUB;
855: case XK_KP_Add: return AK_NPADD;
856: case XK_KP_Decimal: return AK_NPDEL;
857: case XK_KP_Enter: return AK_ENT;
858:
859: case XK_F1: return AK_F1;
860: case XK_F2: return AK_F2;
861: case XK_F3: return AK_F3;
862: case XK_F4: return AK_F4;
863: case XK_F5: return AK_F5;
864: case XK_F6: return AK_F6;
865: case XK_F7: return AK_F7;
866: case XK_F8: return AK_F8;
867: case XK_F9: return AK_F9;
868: case XK_F10: return AK_F10;
1.1.1.3 root 869:
1.1 root 870: case XK_BackSpace: return AK_BS;
871: case XK_Delete: return AK_DEL;
1.1.1.3 root 872: case XK_Control_L: return AK_CTRL;
873: case XK_Control_R: return AK_RCTRL;
1.1 root 874: case XK_Tab: return AK_TAB;
875: case XK_Alt_L: return AK_LALT;
876: case XK_Alt_R: return AK_RALT;
877: case XK_Meta_R: case XK_Hyper_R: return AK_RAMI;
878: case XK_Meta_L: case XK_Hyper_L: return AK_LAMI;
879: case XK_Return: return AK_RET;
880: case XK_space: return AK_SPC;
881: case XK_Shift_L: return AK_LSH;
882: case XK_Shift_R: return AK_RSH;
883: case XK_Escape: return AK_ESC;
884:
1.1.1.3 root 885: case XK_Insert: return AK_HELP;
886: case XK_Home: return AK_NPLPAREN;
887: case XK_End: return AK_NPRPAREN;
1.1 root 888: case XK_Caps_Lock: return AK_CAPSLOCK;
1.1.1.3 root 889:
1.1 root 890: case XK_Up: return AK_UP;
891: case XK_Down: return AK_DN;
892: case XK_Left: return AK_LF;
893: case XK_Right: return AK_RT;
1.1.1.3 root 894:
1.1 root 895: case XK_F11: return AK_BACKSLASH;
1.1.1.2 root 896: #ifdef USE_DGA_EXTENSION
1.1.1.3 root 897: case XK_F12:
898: uae_quit();
899: return -1;
1.1.1.2 root 900: #else
1.1 root 901: case XK_F12: return AK_mousestuff;
1.1.1.2 root 902: #endif
1.1 root 903: #ifdef XK_F14
904: case XK_F14:
905: #endif
906: case XK_Scroll_Lock: return AK_inhibit;
907:
908: #ifdef XK_Page_Up /* These are missing occasionally */
909: case XK_Page_Up: return AK_RAMI; /* PgUp mapped to right amiga */
910: case XK_Page_Down: return AK_LAMI; /* PgDn mapped to left amiga */
911: #endif
912: }
913: return -1;
914: }
915:
916: static int decode_fr(KeySym ks)
917: {
918: switch(ks) { /* FR specific */
919: case XK_A: case XK_a: return AK_Q;
1.1.1.3 root 920: case XK_M: case XK_m: return AK_SEMICOLON;
921: case XK_Q: case XK_q: return AK_A;
1.1 root 922: case XK_Y: case XK_y: return AK_Y;
1.1.1.2 root 923: case XK_W: case XK_w: return AK_Z;
924: case XK_Z: case XK_z: return AK_W;
1.1 root 925: case XK_bracketleft: return AK_LBRACKET;
926: case XK_bracketright: return AK_RBRACKET;
927: case XK_comma: return AK_M;
928: case XK_less: case XK_greater: return AK_LTGT;
929: case XK_period: return AK_COMMA;
930: case XK_parenright: return AK_MINUS;
931: case XK_equal: return AK_SLASH;
932: case XK_numbersign: return AK_NUMBERSIGN;
933: case XK_slash: return AK_PERIOD;
934: case XK_minus: return AK_EQUAL;
935: case XK_backslash: return AK_BACKSLASH;
936: }
937:
938: return -1;
939: }
940:
941: static int decode_us(KeySym ks)
942: {
1.1.1.3 root 943: switch(ks) { /* US specific */
1.1 root 944: case XK_A: case XK_a: return AK_A;
945: case XK_M: case XK_m: return AK_M;
946: case XK_Q: case XK_q: return AK_Q;
947: case XK_Y: case XK_y: return AK_Y;
1.1.1.2 root 948: case XK_W: case XK_w: return AK_W;
1.1 root 949: case XK_Z: case XK_z: return AK_Z;
950: case XK_bracketleft: return AK_LBRACKET;
951: case XK_bracketright: return AK_RBRACKET;
952: case XK_comma: return AK_COMMA;
953: case XK_period: return AK_PERIOD;
954: case XK_slash: return AK_SLASH;
955: case XK_semicolon: return AK_SEMICOLON;
956: case XK_minus: return AK_MINUS;
957: case XK_equal: return AK_EQUAL;
958: /* this doesn't work: */
959: case XK_quoteright: return AK_QUOTE;
960: case XK_quoteleft: return AK_BACKQUOTE;
961: case XK_backslash: return AK_BACKSLASH;
962: }
963:
964: return -1;
965: }
966:
967: static int decode_de(KeySym ks)
968: {
969: switch(ks) {
970: /* DE specific */
971: case XK_A: case XK_a: return AK_A;
972: case XK_M: case XK_m: return AK_M;
973: case XK_Q: case XK_q: return AK_Q;
1.1.1.2 root 974: case XK_W: case XK_w: return AK_W;
1.1 root 975: case XK_Y: case XK_y: return AK_Z;
976: case XK_Z: case XK_z: return AK_Y;
977: case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
978: case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
979: case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
980: case XK_plus: case XK_asterisk: return AK_RBRACKET;
981: case XK_comma: return AK_COMMA;
982: case XK_period: return AK_PERIOD;
983: case XK_less: case XK_greater: return AK_LTGT;
984: case XK_numbersign: return AK_NUMBERSIGN;
985: case XK_ssharp: return AK_MINUS;
986: case XK_apostrophe: return AK_EQUAL;
987: case XK_asciicircum: return AK_BACKQUOTE;
988: case XK_minus: return AK_SLASH;
989: }
990:
991: return -1;
992: }
993:
994: static int decode_se(KeySym ks)
995: {
996: switch(ks) {
997: /* SE specific */
998: case XK_A: case XK_a: return AK_A;
999: case XK_M: case XK_m: return AK_M;
1000: case XK_Q: case XK_q: return AK_Q;
1.1.1.2 root 1001: case XK_W: case XK_w: return AK_W;
1.1 root 1002: case XK_Y: case XK_y: return AK_Y;
1003: case XK_Z: case XK_z: return AK_Z;
1004: case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
1005: case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
1006: case XK_Aring: case XK_aring: return AK_LBRACKET;
1007: case XK_comma: return AK_COMMA;
1008: case XK_period: return AK_PERIOD;
1009: case XK_minus: return AK_SLASH;
1010: case XK_less: case XK_greater: return AK_LTGT;
1011: case XK_plus: case XK_question: return AK_EQUAL;
1012: case XK_at: case XK_onehalf: return AK_BACKQUOTE;
1013: case XK_asciitilde: case XK_asciicircum: return AK_RBRACKET;
1014: case XK_backslash: case XK_bar: return AK_MINUS;
1.1.1.3 root 1015:
1.1 root 1016: case XK_numbersign: return AK_NUMBERSIGN;
1017: }
1018:
1019: return -1;
1020: }
1021:
1022: static int decode_it(KeySym ks)
1023: {
1024: switch(ks) {
1025: /* IT specific */
1026: case XK_A: case XK_a: return AK_A;
1027: case XK_M: case XK_m: return AK_M;
1028: case XK_Q: case XK_q: return AK_Q;
1.1.1.2 root 1029: case XK_W: case XK_w: return AK_W;
1.1 root 1030: case XK_Y: case XK_y: return AK_Y;
1031: case XK_Z: case XK_z: return AK_Z;
1032: case XK_Ograve: case XK_ograve: return AK_SEMICOLON;
1033: case XK_Agrave: case XK_agrave: return AK_QUOTE;
1034: case XK_Egrave: case XK_egrave: return AK_LBRACKET;
1035: case XK_plus: case XK_asterisk: return AK_RBRACKET;
1036: case XK_comma: return AK_COMMA;
1037: case XK_period: return AK_PERIOD;
1038: case XK_less: case XK_greater: return AK_LTGT;
1.1.1.3 root 1039: case XK_backslash: case XK_bar: return AK_BACKQUOTE;
1040: case XK_apostrophe: return AK_MINUS;
1.1 root 1041: case XK_Igrave: case XK_igrave: return AK_EQUAL;
1042: case XK_minus: return AK_SLASH;
1043: case XK_numbersign: return AK_NUMBERSIGN;
1044: }
1045:
1046: return -1;
1047: }
1048:
1.1.1.2 root 1049: static int decode_es(KeySym ks)
1050: {
1051: switch(ks) {
1052: /* ES specific */
1053: case XK_A: case XK_a: return AK_A;
1054: case XK_M: case XK_m: return AK_M;
1055: case XK_Q: case XK_q: return AK_Q;
1056: case XK_W: case XK_w: return AK_W;
1057: case XK_Y: case XK_y: return AK_Y;
1058: case XK_Z: case XK_z: return AK_Z;
1059: case XK_ntilde: case XK_Ntilde: return AK_SEMICOLON;
1060: #ifdef XK_dead_acute
1061: case XK_dead_acute: case XK_dead_diaeresis: return AK_QUOTE;
1062: case XK_dead_grave: case XK_dead_circumflex: return AK_LBRACKET;
1063: #endif
1064: case XK_plus: case XK_asterisk: return AK_RBRACKET;
1065: case XK_comma: return AK_COMMA;
1066: case XK_period: return AK_PERIOD;
1067: case XK_less: case XK_greater: return AK_LTGT;
1.1.1.3 root 1068: case XK_backslash: case XK_bar: return AK_BACKQUOTE;
1069: case XK_apostrophe: return AK_MINUS;
1.1.1.2 root 1070: case XK_Igrave: case XK_igrave: return AK_EQUAL;
1071: case XK_minus: return AK_SLASH;
1072: case XK_numbersign: return AK_NUMBERSIGN;
1073: }
1074:
1075: return -1;
1076: }
1077:
1.1 root 1078: static int keycode2amiga(XKeyEvent *event)
1079: {
1080: KeySym ks;
1081: int as;
1082: int index = 0;
1.1.1.3 root 1083:
1.1 root 1084: do {
1085: ks = XLookupKeysym(event, index);
1086: as = kc_decode (ks);
1.1.1.3 root 1087:
1088: if (as == -1) {
1089: switch(currprefs.keyboard_lang) {
1.1 root 1090:
1091: case KBD_LANG_FR:
1092: as = decode_fr(ks);
1093: break;
1094:
1.1.1.3 root 1095: case KBD_LANG_US:
1.1 root 1096: as = decode_us(ks);
1097: break;
1.1.1.3 root 1098:
1.1 root 1099: case KBD_LANG_DE:
1100: as = decode_de(ks);
1101: break;
1.1.1.3 root 1102:
1.1 root 1103: case KBD_LANG_SE:
1104: as = decode_se(ks);
1105: break;
1.1.1.3 root 1106:
1.1 root 1107: case KBD_LANG_IT:
1108: as = decode_it(ks);
1109: break;
1110:
1.1.1.2 root 1111: case KBD_LANG_ES:
1112: as = decode_es(ks);
1113: break;
1114:
1.1 root 1115: default:
1116: as = -1;
1117: break;
1118: }
1119: }
1120: if(-1 != as)
1121: return as;
1122: index++;
1123: } while (ks != NoSymbol);
1124: return -1;
1125: }
1126:
1127: static struct timeval lastMotionTime;
1128:
1.1.1.3 root 1129: static int refresh_necessary = 0;
1130:
1.1 root 1131: void handle_events(void)
1132: {
1133: newmousecounters = 0;
1134: gui_handle_events();
1.1.1.3 root 1135:
1.1 root 1136: for (;;) {
1137: XEvent event;
1138: #if 0
1139: if (!XCheckMaskEvent(display, eventmask, &event)) break;
1140: #endif
1141: if (!XPending(display)) break;
1142: XNextEvent(display, &event);
1.1.1.3 root 1143:
1.1 root 1144: switch(event.type) {
1.1.1.3 root 1145: case KeyPress: {
1.1 root 1146: int kc = keycode2amiga((XKeyEvent *)&event);
1147: if (kc == -1) break;
1148: switch (kc) {
1149: case AK_mousestuff:
1150: togglemouse();
1151: break;
1152:
1153: case AK_inhibit:
1.1.1.3 root 1154: toggle_inhibit_frame (0);
1.1 root 1155: break;
1156:
1157: default:
1.1.1.3 root 1158: if (!keystate[kc]) {
1.1 root 1159: keystate[kc] = 1;
1160: record_key (kc << 1);
1161: }
1162: break;
1163: }
1164: break;
1165: }
1.1.1.3 root 1166: case KeyRelease: {
1.1 root 1167: int kc = keycode2amiga((XKeyEvent *)&event);
1168: if (kc == -1) break;
1169: keystate[kc] = 0;
1170: record_key ((kc << 1) | 1);
1171: break;
1172: }
1173: case ButtonPress:
1174: buttonstate[((XButtonEvent *)&event)->button-1] = 1;
1175: break;
1176: case ButtonRelease:
1177: buttonstate[((XButtonEvent *)&event)->button-1] = 0;
1178: break;
1.1.1.2 root 1179: #ifndef USE_DGA_EXTENSION
1.1 root 1180: case EnterNotify:
1181: newmousecounters = 1;
1182: lastmx = ((XCrossingEvent *)&event)->x;
1183: lastmy = ((XCrossingEvent *)&event)->y;
1184: inwindow = 1;
1185: break;
1186: case LeaveNotify:
1187: inwindow = 0;
1188: break;
1189: case FocusIn:
1190: if (!autorepeatoff)
1191: XAutoRepeatOff(display);
1192: autorepeatoff = 1;
1193: break;
1194: case FocusOut:
1195: if (autorepeatoff)
1196: XAutoRepeatOn(display);
1197: autorepeatoff = 0;
1198: break;
1199: case MotionNotify:
1.1.1.3 root 1200: if (inwindow) {
1.1 root 1201: lastmx = ((XMotionEvent *)&event)->x;
1202: lastmy = ((XMotionEvent *)&event)->y;
1.1.1.3 root 1203: if(!cursorOn && !currprefs.no_xhair) {
1.1 root 1204: XDefineCursor(display, mywin, xhairCursor);
1205: cursorOn = 1;
1206: }
1207: gettimeofday(&lastMotionTime, NULL);
1208: }
1209: break;
1210: case Expose:
1.1.1.3 root 1211: refresh_necessary = 1;
1.1 root 1212: break;
1.1.1.2 root 1213: #else
1214: case MotionNotify:
1215: newmousecounters = 0;
1216: lastmx += ((XMotionEvent *)&event)->x_root;
1217: lastmy += ((XMotionEvent *)&event)->y_root;
1218: #endif
1.1 root 1219: }
1220: }
1.1.1.3 root 1221: #if defined PICASSO96 && !defined USE_DGA_EXTENSION
1222: if (screen_is_picasso && refresh_necessary) {
1223: DO_PUTIMAGE (picasso_img, 0, 0, 0, 0,
1224: picasso_vidinfo.width, picasso_vidinfo.height);
1225: refresh_necessary = 0;
1226: } else if (screen_is_picasso) {
1227: int i;
1228: int strt = -1, stop = -1;
1229: picasso_invalid_lines[picasso_vidinfo.height] = 0;
1230: for (i = 0; i < picasso_vidinfo.height + 1; i++) {
1231: if (picasso_invalid_lines[i]) {
1232: picasso_invalid_lines[i] = 0;
1233: if (strt != -1)
1234: continue;
1235: strt = i;
1236: } else {
1237: if (strt == -1)
1238: continue;
1239: DO_PUTIMAGE (picasso_img, 0, strt, 0, strt,
1240: picasso_vidinfo.width, i-strt);
1241: strt = -1;
1242: }
1243: }
1244: }
1245: #endif
1.1 root 1246:
1.1.1.2 root 1247: #ifndef USE_DGA_EXTENSION
1.1.1.3 root 1248: if (!screen_is_picasso && refresh_necessary) {
1249: DO_PUTIMAGE (img, 0, 0, 0, 0, currprefs.gfx_width, currprefs.gfx_height);
1250: refresh_necessary = 0;
1.1 root 1251: }
1.1.1.3 root 1252: if(cursorOn && !currprefs.no_xhair) {
1.1 root 1253: struct timeval now;
1254: int diff;
1255: gettimeofday(&now, NULL);
1.1.1.3 root 1256: diff = (now.tv_sec - lastMotionTime.tv_sec) * 1000000 +
1.1 root 1257: (now.tv_usec - lastMotionTime.tv_usec);
1258: if(diff > 1000000) {
1259: XDefineCursor(display, mywin, blankCursor);
1260: cursorOn = 0;
1261: }
1262: }
1.1.1.2 root 1263: #endif
1.1 root 1264: /* "Affengriff" */
1265: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
1.1.1.3 root 1266: uae_reset();
1.1 root 1267: }
1268:
1269: int debuggable(void)
1270: {
1271: return 1;
1272: }
1273:
1274: int needmousehack(void)
1275: {
1.1.1.2 root 1276: #ifdef USE_DGA_EXTENSION
1277: return 0;
1278: #else
1.1 root 1279: return 1;
1.1.1.2 root 1280: #endif
1.1 root 1281: }
1282:
1283: void LED(int on)
1284: {
1.1.1.2 root 1285: #if 0 /* Maybe that is responsible for the joystick emulation problems on SunOS? */
1.1 root 1286: static int last_on = -1;
1287: XKeyboardControl control;
1288:
1289: if (last_on == on) return;
1290: last_on = on;
1291: control.led = 1; /* implementation defined */
1292: control.led_mode = on ? LedModeOn : LedModeOff;
1293: XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
1.1.1.2 root 1294: #endif
1.1 root 1295: }
1296:
1.1.1.3 root 1297: void write_log (const char *buf)
1298: {
1299: fprintf (stderr, buf);
1300: }
1301:
1302: #ifdef PICASSO96
1303:
1304: void DX_Invalidate (int first, int last)
1305: {
1306: do {
1307: picasso_invalid_lines[first] = 1;
1308: first++;
1309: } while (first <= last);
1310: }
1311:
1312: int DX_BitsPerCannon (void)
1313: {
1314: return 8;
1315: }
1316:
1317: void DX_SetPalette(int start, int count)
1318: {
1319: if (!screen_is_picasso || picasso_vidinfo.pixbytes != 1)
1320: return;
1321:
1322: while (count-- > 0) {
1323: XColor col = parsed_xcolors[start];
1324: col.red = picasso96_state.CLUT[start].Red * 0x0101;
1325: col.green = picasso96_state.CLUT[start].Green * 0x0101;
1326: col.blue = picasso96_state.CLUT[start].Blue * 0x0101;
1327: XStoreColor (display, cmap, &col);
1328: XStoreColor (display, cmap2, &col);
1329: start++;
1330: }
1331: #ifdef USE_DGA_EXTENSION
1332: dga_colormap_installed ^= 1;
1333: if (dga_colormap_installed == 1)
1334: XF86DGAInstallColormap(display, screen, cmap2);
1335: else
1336: XF86DGAInstallColormap(display, screen, cmap);
1337: #endif
1338: }
1339:
1340: #define MAX_SCREEN_MODES 11
1341:
1342: static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280 };
1343: static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768, 864, 1024 };
1344:
1345: int DX_FillResolutions (uae_u16 *ppixel_format)
1346: {
1347: Screen *scr = ScreenOfDisplay (display, screen);
1348: int i, count = 0;
1349: int w = WidthOfScreen (scr);
1350: int h = HeightOfScreen (scr);
1351: int maxw = 0, maxh = 0;
1352:
1353: *ppixel_format = (bit_unit == 8 ? RGBFF_CHUNKY
1354: : bitdepth == 15 && bit_unit == 16 ? RGBFF_R5G5B5PC
1355: : bitdepth == 16 && bit_unit == 16 ? RGBFF_R5G6B5PC
1356: : bit_unit == 24 ? RGBFF_B8G8R8
1357: : bit_unit == 32 ? RGBFF_B8G8R8A8
1358: : 0);
1359:
1360: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
1361: for (i = 0; i < vidmodecount && i < MAX_PICASSO_MODES ; i++) {
1362: DisplayModes[i].res.width = allmodes[i]->hdisplay;
1363: DisplayModes[i].res.height = allmodes[i]->vdisplay;
1364: DisplayModes[i].depth = bit_unit >> 3;
1365: DisplayModes[i].refresh = 75;
1366: }
1367: count = i;
1368: #else
1369: for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES ; i++) {
1370: if (x_size_table[i] <= w && y_size_table[i] <= h) {
1371: if (x_size_table[i] > maxw)
1372: maxw = x_size_table[i];
1373: if (y_size_table[i] > maxh)
1374: maxh = y_size_table[i];
1375: DisplayModes[count].res.width = x_size_table[i];
1376: DisplayModes[count].res.height = y_size_table[i];
1377: DisplayModes[count].depth = bit_unit >> 3;
1378: DisplayModes[count].refresh = 75;
1379: count++;
1380: }
1381: }
1382: #endif
1383:
1384: #ifndef USE_DGA_EXTENSION
1385: picasso_img = get_image (maxw, maxh, 0);
1386: #endif
1387:
1388: return count;
1389: }
1390:
1391: static void set_window_for_picasso (void)
1392: {
1393: if (current_width != picasso_vidinfo.width || current_height != picasso_vidinfo.height) {
1394: current_width = picasso_vidinfo.width;
1395: current_height = picasso_vidinfo.height;
1396: XResizeWindow (display, mywin, picasso_vidinfo.width,
1397: picasso_vidinfo.height);
1398: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
1399: switch_to_best_mode ();
1400: #endif
1401: }
1402: DX_SetPalette (0, 256);
1403: }
1404:
1405: static void set_window_for_amiga (void)
1406: {
1407: int i;
1408:
1409: if (current_width != currprefs.gfx_width || current_height != currprefs.gfx_height) {
1410: current_width = currprefs.gfx_width;
1411: current_height = currprefs.gfx_height;
1412: XResizeWindow (display, mywin, currprefs.gfx_width,
1413: currprefs.gfx_height);
1414: #if defined USE_DGA_EXTENSION && defined USE_VIDMODE_EXTENSION
1415: switch_to_best_mode ();
1416: #endif
1417: }
1418:
1.1.1.4 ! root 1419: if (visualInfo.VI_CLASS != TrueColor)
1.1.1.3 root 1420: for (i = 0; i < 256; i++) {
1421: XStoreColor (display, cmap, parsed_xcolors + i);
1422: XStoreColor (display, cmap2, parsed_xcolors + i);
1423: }
1424: #ifdef USE_DGA_EXTENSION
1425: dga_colormap_installed ^= 1;
1426: if (dga_colormap_installed == 1)
1427: XF86DGAInstallColormap(display, screen, cmap2);
1428: else
1429: XF86DGAInstallColormap(display, screen, cmap);
1430: #endif
1431: }
1432:
1433: void gfx_set_picasso_modeinfo (int w, int h, int depth)
1434: {
1435: picasso_vidinfo.width = w;
1436: picasso_vidinfo.height = h;
1437: picasso_vidinfo.depth = depth;
1.1.1.4 ! root 1438: picasso_vidinfo.pixbytes = bit_unit >> 3;
1.1.1.3 root 1439: #ifdef USE_DGA_EXTENSION
1.1.1.4 ! root 1440: picasso_vidinfo.rowbytes = fb_width * picasso_vidinfo.pixbytes;
1.1.1.3 root 1441: #else
1442: picasso_vidinfo.rowbytes = picasso_img->bytes_per_line;
1443: #endif
1444: picasso_vidinfo.extra_mem = 1;
1445:
1446: if (screen_is_picasso)
1447: set_window_for_picasso ();
1448: }
1449:
1450: void gfx_set_picasso_baseaddr (uaecptr a)
1451: {
1452: }
1453:
1454: void gfx_set_picasso_state (int on)
1455: {
1456: if (on == screen_is_picasso)
1457: return;
1458: screen_is_picasso = on;
1459: if (on)
1460: set_window_for_picasso ();
1461: else
1462: set_window_for_amiga ();
1463: }
1464:
1465: void begindrawing (void)
1.1 root 1466: {
1467: }
1.1.1.3 root 1468:
1469: void enddrawing (void)
1470: {
1471: }
1472:
1473: uae_u8 *lockscr (void)
1474: {
1475: #ifdef USE_DGA_EXTENSION
1476: return fb_addr;
1477: #else
1478: return picasso_img->data;
1479: #endif
1480: }
1481: void unlockscr (void)
1482: {
1483: }
1484: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.