|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * X interface
5: *
6: * Copyright 1995, 1996 Bernd Schmidt
1.1.1.2 ! root 7: * Copyright 1996 Ed Hanway, Andre Beck, Samuel Devulder, Bruno Coste
1.1 root 8: */
9:
1.1.1.2 ! root 10: #include "sysconfig.h"
! 11: #include "sysdeps.h"
! 12:
1.1 root 13: #include <X11/Xlib.h>
14: #include <X11/Xutil.h>
15: #include <X11/keysym.h>
16: #include <X11/cursorfont.h>
17:
18: #ifndef DONT_WANT_SHM
19: #include <sys/ipc.h>
20: #include <sys/shm.h>
21: #include <X11/extensions/XShm.h>
22: #endif
23:
24: #include "config.h"
25: #include "options.h"
26: #include "memory.h"
27: #include "custom.h"
28: #include "newcpu.h"
29: #include "xwin.h"
30: #include "keyboard.h"
31: #include "keybuf.h"
1.1.1.2 ! root 32: #include "gui.h"
1.1 root 33:
34: static Display *display;
35: static int screen;
36: static Window rootwin, mywin;
37:
38: static GC whitegc,blackgc;
39: static XColor black,white;
40: static Colormap cmap;
41:
42: static XImage *img;
43: static Visual *vis;
44: static XVisualInfo visualInfo;
45: static int bitdepth;
46: #ifndef DONT_WANT_SHM
47: static XShmSegmentInfo shminfo;
48: #endif
49: static Cursor blankCursor, xhairCursor;
1.1.1.2 ! root 50: static int cursorOn;
! 51:
! 52: xcolnr xcolors[4096];
1.1 root 53:
54: /* Keyboard and mouse */
55:
1.1.1.2 ! root 56: static int keystate[256];
1.1 root 57:
1.1.1.2 ! root 58: int buttonstate[3];
1.1 root 59: int lastmx, lastmy;
1.1.1.2 ! root 60: int newmousecounters;
! 61:
! 62: static int inwindow;
1.1 root 63: const long int eventmask = (KeyPressMask|KeyReleaseMask|ButtonPressMask
64: |ButtonReleaseMask|PointerMotionMask
65: |FocusChangeMask|EnterWindowMask
1.1.1.2 ! root 66: |ExposureMask
1.1 root 67: |LeaveWindowMask);
68:
1.1.1.2 ! root 69: static int vsize, hsize, hpixels;
! 70: static char *oldpixbuf;
! 71:
! 72: struct vidbuf_description gfxvidinfo;
1.1 root 73:
1.1.1.2 ! root 74: void flush_line(int y)
1.1 root 75: {
1.1.1.2 ! root 76: int xs = 0, xe = hsize - 1;
! 77: int len;
! 78: char *linebuf = y*gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
! 79:
! 80: #ifndef LOW_BANDWIDTH
! 81: fprintf(stderr, "Bug!\n");
1.1 root 82: #endif
1.1.1.2 ! root 83:
! 84: switch(bitdepth) {
! 85: case 24: case 32:
! 86: {
! 87: int *newp = (int *)linebuf;
! 88: int *oldp = (int *)(oldpixbuf + y*gfxvidinfo.rowbytes);
! 89: while (newp[xs] == oldp[xs]) {
! 90: if (xs == xe)
! 91: return;
! 92: xs++;
! 93: }
! 94: while (newp[xe] == oldp[xe]) xe--;
1.1 root 95:
1.1.1.2 ! root 96: memcpy (oldp + xs, newp + xs, 4 * (xe - xs + 1));
! 97: }
! 98: break;
! 99: case 16: case 12:
! 100: {
! 101: short *newp = (short *)linebuf;
! 102: short *oldp = (short *)(oldpixbuf + y*gfxvidinfo.rowbytes);
! 103: while (newp[xs] == oldp[xs]) {
! 104: if (xs == xe)
! 105: return;
! 106: xs++;
! 107: }
! 108: while (newp[xe] == oldp[xe]) xe--;
! 109:
! 110: memcpy (oldp + xs, newp + xs, 2 * (xe - xs + 1));
! 111: }
! 112: break;
! 113: case 8:
! 114: {
! 115: char *newp = (char *)linebuf;
! 116: char *oldp = (char *)(oldpixbuf + y*gfxvidinfo.rowbytes);
! 117: while (newp[xs] == oldp[xs]) {
! 118: if (xs == xe)
! 119: return;
! 120: xs++;
! 121: }
! 122: while (newp[xe] == oldp[xe]) xe--;
! 123:
! 124: memcpy (oldp + xs, newp + xs, 1 * (xe - xs + 1));
! 125: }
! 126: break;
! 127: }
! 128:
! 129: len = xe - xs + 1;
1.1 root 130:
131: #ifdef DONT_WANT_SHM
1.1.1.2 ! root 132: XPutImage(display, mywin, blackgc, img, xs, y, xs, y, len, 1);
1.1 root 133: #else
1.1.1.2 ! root 134: XShmPutImage(display, mywin, blackgc, img, xs, y, xs, y, len, 1, 0);
1.1 root 135: #endif
136: }
137:
1.1.1.2 ! root 138: void flush_block (int ystart, int ystop)
1.1 root 139: {
1.1.1.2 ! root 140: int len, xs;
! 141: if (use_lores) {
! 142: len = 320;
! 143: xs = prev_max_diwstop - 328;
! 144: } else {
! 145: len = hpixels;
! 146: xs = 0;
! 147: }
1.1 root 148: #ifdef DONT_WANT_SHM
1.1.1.2 ! root 149: XPutImage(display, mywin, blackgc, img, xs, ystart, 0, ystart, len,
! 150: ystop - ystart + 1);
1.1 root 151: #else
1.1.1.2 ! root 152: XShmPutImage(display, mywin, blackgc, img, xs, ystart, 0, ystart, len,
! 153: ystop - ystart + 1, 0);
1.1 root 154: #endif
155: }
156:
1.1.1.2 ! root 157: void flush_screen (int ystart, int ystop)
1.1 root 158: {
1.1.1.2 ! root 159: #ifndef DONT_WANT_SHM
! 160: XSync(display, 0);
1.1 root 161: #endif
162: }
163:
164: #ifndef DONT_WANT_SHM
165: static void initShm(int depth)
166: {
167: img = XShmCreateImage(display, vis, depth,
1.1.1.2 ! root 168: ZPixmap, 0, &shminfo, hsize, vsize);
1.1 root 169:
1.1.1.2 ! root 170: shminfo.shmid = shmget(IPC_PRIVATE, vsize * img->bytes_per_line,
! 171: IPC_CREAT | 0777);
1.1 root 172: shminfo.shmaddr = img->data = (char *)shmat(shminfo.shmid, 0, 0);
173: shminfo.readOnly = False;
174: /* let the xserver attach */
175: XShmAttach(display, &shminfo);
176: /* NOW ! */
177: XSync(display,0);
178: /* now deleting means making it temporary */
179: shmctl(shminfo.shmid, IPC_RMID, 0);
180:
1.1.1.2 ! root 181: gfxvidinfo.bufmem = img->data;
! 182: gfxvidinfo.rowbytes = img->bytes_per_line;
1.1 root 183: }
184: #endif
185:
186: static __inline__ int bitsInMask(unsigned long mask)
187: {
188: /* count bits in mask */
189: int n = 0;
190: while(mask) {
191: n += mask&1;
192: mask >>= 1;
193: }
194: return n;
195: }
196:
197: static __inline__ int maskShift(unsigned long mask)
198: {
199: /* determine how far mask is shifted */
200: int n = 0;
201: while(!(mask&1)) {
202: n++;
203: mask >>= 1;
204: }
205: return n;
206: }
207:
1.1.1.2 ! root 208: static int get_color(int r, int g, int b, xcolnr *cnp)
1.1 root 209: {
1.1.1.2 ! root 210: XColor col;
! 211: char str[10];
! 212: sprintf(str, "rgb:%x/%x/%x", r, g, b);
! 213: XParseColor(display, cmap, str, &col);
! 214: if (XAllocColor(display, cmap, &col)) {
! 215: *cnp = col.pixel;
! 216: return 1;
! 217: }
! 218: return 0;
1.1 root 219: }
220:
1.1.1.2 ! root 221: static int init_colors(void)
1.1 root 222: {
1.1.1.2 ! root 223: if (visualInfo.depth != 8 && visualInfo.depth != 12
! 224: && visualInfo.depth != 16 && visualInfo.depth != 24) {
1.1 root 225: fprintf(stderr, "Unsupported bit depth (%d)\n", visualInfo.depth);
1.1.1.2 ! root 226: return 0;
1.1 root 227: }
228:
229: #ifdef __cplusplus
1.1.1.2 ! root 230: switch(visualInfo.c_class)
1.1 root 231: #else
1.1.1.2 ! root 232: switch(visualInfo.class)
1.1 root 233: #endif
1.1.1.2 ! root 234: {
1.1 root 235: case TrueColor:
236: {
237: int red_bits = bitsInMask(visualInfo.red_mask);
238: int green_bits = bitsInMask(visualInfo.green_mask);
239: int blue_bits = bitsInMask(visualInfo.blue_mask);
240: int red_shift = maskShift(visualInfo.red_mask);
241: int green_shift = maskShift(visualInfo.green_mask);
242: int blue_shift = maskShift(visualInfo.blue_mask);
1.1.1.2 ! root 243: alloc_colors64k(red_bits, green_bits, blue_bits, red_shift,
! 244: green_shift, blue_shift);
1.1 root 245: }
246: break;
247:
248: case GrayScale:
249: case PseudoColor:
1.1.1.2 ! root 250: alloc_colors256(get_color);
1.1 root 251: break;
252:
253: default:
254: #ifdef __cplusplus
1.1.1.2 ! root 255: fprintf(stderr, "Unsupported visual class (%d)\n", visualInfo.c_class);
1.1 root 256: #else
1.1.1.2 ! root 257: fprintf(stderr, "Unsupported visual class (%d)\n", visualInfo.class);
1.1 root 258: #endif
1.1.1.2 ! root 259: return 0;
1.1 root 260: }
1.1.1.2 ! root 261: return 1;
1.1 root 262: }
263:
1.1.1.2 ! root 264: int graphics_init(void)
1.1 root 265: {
266: int i;
267: char *display_name = 0;
268: XSetWindowAttributes wattr;
269:
1.1.1.2 ! root 270: if (screen_res < 3) {
! 271: #ifdef LOW_BANDWIDTH
! 272: fprintf(stderr, "Low resolution mode not supported with LOW_BANDWIDTH.\n");
! 273: return 0;
! 274: #else
! 275: fprintf(stderr, "Low resolution mode selected. Forcing 320x300.\n");
! 276: #endif
! 277: }
! 278:
1.1 root 279: display = XOpenDisplay(display_name);
280: if (display == 0) {
281: fprintf(stderr, "Can't connect to X server %s\n", XDisplayName(display_name));
1.1.1.2 ! root 282: return 0;
1.1 root 283: }
284: screen = XDefaultScreen(display);
285: rootwin = XRootWindow(display,screen);
1.1.1.2 ! root 286:
1.1 root 287: /* try for a 12 bit visual first, then a 16 bit, then a 24 bit, then 8 bit */
288: if (XMatchVisualInfo(display, screen, 12, TrueColor, &visualInfo)) {
289: } else if (XMatchVisualInfo(display, screen, 16, TrueColor, &visualInfo)) {
290: } else if (XMatchVisualInfo(display, screen, 24, TrueColor, &visualInfo)) {
291: } else if (XMatchVisualInfo(display, screen, 8, PseudoColor, &visualInfo)) {
1.1.1.2 ! root 292: /* for our HP boxes */
1.1 root 293: } else if (XMatchVisualInfo(display, screen, 8, GrayScale, &visualInfo)) {
294: } else {
295: fprintf(stderr, "Can't obtain appropriate X visual\n");
1.1.1.2 ! root 296: return 0;
1.1 root 297: }
298:
299: vis = visualInfo.visual;
300: bitdepth = visualInfo.depth;
301:
1.1.1.2 ! root 302: gfxvidinfo.pixbytes = (bitdepth == 24 || bitdepth == 32 ? 4
! 303: : bitdepth == 12 || bitdepth == 16 ? 2
! 304: : 1);
! 305: vsize = dont_want_aspect ? numscrlines : 2*numscrlines;
! 306: hsize = use_lores ? 400 : 800;
! 307: hpixels = use_lores ? 320 : 796;
1.1 root 308: fprintf(stderr, "Using %d bit visual\n", bitdepth);
309:
310: cmap = XCreateColormap(display, rootwin, vis, AllocNone);
311: XParseColor(display, cmap, "#000000", &black);
312: if (!XAllocColor(display, cmap, &black))
313: fprintf(stderr, "Whoops??\n");
314: XParseColor(display, cmap, "#ffffff", &white);
315: if (!XAllocColor(display, cmap, &white))
316: fprintf(stderr, "Whoops??\n");
317:
318: wattr.event_mask = eventmask;
319: wattr.background_pixel = black.pixel;
320: wattr.backing_store = Always;
321: wattr.backing_planes = bitdepth;
322: wattr.border_pixmap = None;
323: wattr.border_pixel = black.pixel;
324: wattr.colormap = cmap;
325:
1.1.1.2 ! root 326: mywin = XCreateWindow(display, rootwin, 0, 0, hpixels, vsize, 0,
1.1 root 327: bitdepth, InputOutput, vis,
328: CWEventMask|CWBackPixel|CWBorderPixel|CWBackingStore
329: |CWBackingPlanes|CWColormap,
330: &wattr);
331: XMapWindow(display,mywin);
1.1.1.2 ! root 332: XStoreName(display, mywin, "UAE");
1.1 root 333:
334: blankCursor = XCreatePixmapCursor(display,
335: XCreatePixmap(display, mywin, 1, 1, 1),
336: XCreatePixmap(display, mywin, 1, 1, 1),
337: &black, &white, 0, 0);
338: xhairCursor = XCreateFontCursor(display, XC_crosshair);
339:
340: whitegc = XCreateGC(display,mywin,0,0);
341: blackgc = XCreateGC(display,mywin,0,0);
342:
343: XSetForeground(display,blackgc,black.pixel);
344: XSetForeground(display,whitegc,white.pixel);
345:
346: #ifdef DONT_WANT_SHM
1.1.1.2 ! root 347: gfxvidinfo.rowbytes = hsize * gfxvidinfo.pixbytes;
! 348: gfxvidinfo.bufmem = (char *)malloc(gfxvidinfo.rowbytes * vsize);
! 349: img = XCreateImage(display, vis, bitdepth, ZPixmap, 0, gfxvidinfo.bufmem,
! 350: hsize, vsize, 32, 0);
1.1 root 351: #else
352: initShm (bitdepth);
353: #endif
1.1.1.2 ! root 354: #ifdef LOW_BANDWIDTH
! 355: gfxvidinfo.maxblocklines = 0;
! 356: oldpixbuf = (char *)malloc(gfxvidinfo.rowbytes * vsize);
! 357: #else
! 358: gfxvidinfo.maxblocklines = 100; /* whatever... */
! 359: #endif
! 360:
! 361: if (!init_colors())
! 362: return 0;
! 363:
! 364: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
! 365: for(i=0; i<256; i++)
! 366: keystate[i] = 0;
1.1 root 367:
1.1.1.2 ! root 368: lastmx = lastmy = 0;
! 369: newmousecounters = 0;
! 370: inwindow = 0;
! 371:
! 372: if (use_xhair)
1.1 root 373: XDefineCursor(display, mywin, xhairCursor);
1.1.1.2 ! root 374: else
! 375: XDefineCursor(display, mywin, blankCursor);
! 376: cursorOn = 1;
! 377: return 1;
1.1 root 378: }
379:
380: void graphics_leave(void)
381: {
382: XAutoRepeatOn(display);
383: }
384:
385: /* Decode KeySyms. This function knows about all keys that are common
386: * between different keyboard languages. */
387: static int kc_decode (KeySym ks)
388: {
389: switch (ks) {
390: case XK_B: case XK_b: return AK_B;
391: case XK_C: case XK_c: return AK_C;
392: case XK_D: case XK_d: return AK_D;
393: case XK_E: case XK_e: return AK_E;
394: case XK_F: case XK_f: return AK_F;
395: case XK_G: case XK_g: return AK_G;
396: case XK_H: case XK_h: return AK_H;
397: case XK_I: case XK_i: return AK_I;
398: case XK_J: case XK_j: return AK_J;
399: case XK_K: case XK_k: return AK_K;
400: case XK_L: case XK_l: return AK_L;
401: case XK_N: case XK_n: return AK_N;
402: case XK_O: case XK_o: return AK_O;
403: case XK_P: case XK_p: return AK_P;
404: case XK_R: case XK_r: return AK_R;
405: case XK_S: case XK_s: return AK_S;
406: case XK_T: case XK_t: return AK_T;
407: case XK_U: case XK_u: return AK_U;
408: case XK_V: case XK_v: return AK_V;
409: case XK_W: case XK_w: return AK_W;
410: case XK_X: case XK_x: return AK_X;
411:
412: case XK_0: return AK_0;
413: case XK_1: return AK_1;
414: case XK_2: return AK_2;
415: case XK_3: return AK_3;
416: case XK_4: return AK_4;
417: case XK_5: return AK_5;
418: case XK_6: return AK_6;
419: case XK_7: return AK_7;
420: case XK_8: return AK_8;
421: case XK_9: return AK_9;
422:
1.1.1.2 ! root 423: /* You never know which Keysyms might be missing on some workstation
! 424: * This #ifdef should be enough. */
! 425: #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End)
! 426: case XK_KP_0: case XK_KP_Insert: return AK_NP0;
! 427: case XK_KP_1: case XK_KP_End: return AK_NP1;
! 428: case XK_KP_2: case XK_KP_Down: return AK_NP2;
! 429: case XK_KP_3: case XK_KP_Next: return AK_NP3;
! 430: case XK_KP_4: case XK_KP_Left: return AK_NP4;
! 431: case XK_KP_5: case XK_KP_Begin: return AK_NP5;
! 432: case XK_KP_6: case XK_KP_Right: return AK_NP6;
! 433: case XK_KP_7: case XK_KP_Home: return AK_NP7;
! 434: case XK_KP_8: case XK_KP_Up: return AK_NP8;
! 435: case XK_KP_9: case XK_KP_Prior: return AK_NP9;
! 436: #else
1.1 root 437: case XK_KP_0: return AK_NP0;
438: case XK_KP_1: return AK_NP1;
439: case XK_KP_2: return AK_NP2;
440: case XK_KP_3: return AK_NP3;
441: case XK_KP_4: return AK_NP4;
442: case XK_KP_5: return AK_NP5;
443: case XK_KP_6: return AK_NP6;
444: case XK_KP_7: return AK_NP7;
445: case XK_KP_8: return AK_NP8;
446: case XK_KP_9: return AK_NP9;
1.1.1.2 ! root 447: #endif
! 448: case XK_KP_Divide: return AK_NPDIV;
! 449: case XK_KP_Multiply: return AK_NPMUL;
! 450: case XK_KP_Subtract: return AK_NPSUB;
! 451: case XK_KP_Add: return AK_NPADD;
! 452: case XK_KP_Decimal: return AK_NPDEL;
! 453: case XK_KP_Enter: return AK_ENT;
! 454:
1.1 root 455: case XK_F1: return AK_F1;
456: case XK_F2: return AK_F2;
457: case XK_F3: return AK_F3;
458: case XK_F4: return AK_F4;
459: case XK_F5: return AK_F5;
460: case XK_F6: return AK_F6;
461: case XK_F7: return AK_F7;
462: case XK_F8: return AK_F8;
463: case XK_F9: return AK_F9;
464: case XK_F10: return AK_F10;
465:
1.1.1.2 ! root 466: case XK_BackSpace: return AK_BS;
! 467: case XK_Delete: return AK_DEL;
! 468: case XK_Control_L: case XK_Control_R: return AK_CTRL;
1.1 root 469: case XK_Tab: return AK_TAB;
1.1.1.2 ! root 470: case XK_Alt_L: return AK_LALT;
! 471: case XK_Alt_R: return AK_RALT;
! 472: case XK_Meta_R: case XK_Hyper_R: return AK_RAMI;
! 473: case XK_Meta_L: case XK_Hyper_L: return AK_LAMI;
1.1 root 474: case XK_Return: return AK_RET;
475: case XK_space: return AK_SPC;
476: case XK_Shift_L: return AK_LSH;
477: case XK_Shift_R: return AK_RSH;
478: case XK_Escape: return AK_ESC;
479:
1.1.1.2 ! root 480: case XK_Insert: return AK_BACKSLASH;
! 481: case XK_End: return AK_HELP;
! 482: case XK_Caps_Lock: return AK_CAPSLOCK;
! 483:
1.1 root 484: case XK_Up: return AK_UP;
485: case XK_Down: return AK_DN;
486: case XK_Left: return AK_LF;
487: case XK_Right: return AK_RT;
488:
489: case XK_F11: return AK_BACKSLASH;
490: case XK_F12: return AK_mousestuff;
1.1.1.2 ! root 491: #ifdef XK_F14
! 492: case XK_F14:
! 493: #endif
1.1 root 494: case XK_Scroll_Lock: return AK_inhibit;
495:
496: #ifdef XK_Page_Up /* These are missing occasionally */
497: case XK_Page_Up: return AK_RAMI; /* PgUp mapped to right amiga */
498: case XK_Page_Down: return AK_LAMI; /* PgDn mapped to left amiga */
499: #endif
500: }
501: return -1;
502: }
503:
1.1.1.2 ! root 504: static int decode_fr(KeySym ks)
! 505: {
! 506: switch(ks) { /* FR specific */
! 507: case XK_A: case XK_a: return AK_Q;
! 508: case XK_M: case XK_m: return AK_SEMICOLON;
! 509: case XK_Q: case XK_q: return AK_A;
! 510: case XK_Y: case XK_y: return AK_Y;
! 511: case XK_Z: case XK_z: return AK_Z;
! 512: case XK_bracketleft: return AK_LBRACKET;
! 513: case XK_bracketright: return AK_RBRACKET;
! 514: case XK_comma: return AK_M;
! 515: case XK_less: case XK_greater: return AK_LTGT;
! 516: case XK_period: return AK_COMMA;
! 517: case XK_parenright: return AK_MINUS;
! 518: case XK_equal: return AK_SLASH;
! 519: case XK_numbersign: return AK_NUMBERSIGN;
! 520: case XK_slash: return AK_PERIOD;
! 521: case XK_minus: return AK_EQUAL;
! 522: case XK_backslash: return AK_BACKSLASH;
! 523: }
! 524:
! 525: return -1;
! 526: }
! 527:
1.1 root 528: static int decode_us(KeySym ks)
529: {
530: switch(ks) { /* US specific */
1.1.1.2 ! root 531: case XK_A: case XK_a: return AK_A;
! 532: case XK_M: case XK_m: return AK_M;
! 533: case XK_Q: case XK_q: return AK_Q;
1.1 root 534: case XK_Y: case XK_y: return AK_Y;
535: case XK_Z: case XK_z: return AK_Z;
536: case XK_bracketleft: return AK_LBRACKET;
537: case XK_bracketright: return AK_RBRACKET;
538: case XK_comma: return AK_COMMA;
539: case XK_period: return AK_PERIOD;
540: case XK_slash: return AK_SLASH;
541: case XK_semicolon: return AK_SEMICOLON;
542: case XK_minus: return AK_MINUS;
543: case XK_equal: return AK_EQUAL;
544: /* this doesn't work: */
1.1.1.2 ! root 545: case XK_quoteright: return AK_QUOTE;
! 546: case XK_quoteleft: return AK_BACKQUOTE;
! 547: case XK_backslash: return AK_NUMBERSIGN;
1.1 root 548: }
549:
550: return -1;
551: }
552:
553: static int decode_de(KeySym ks)
554: {
555: switch(ks) {
556: /* DE specific */
1.1.1.2 ! root 557: case XK_A: case XK_a: return AK_A;
! 558: case XK_M: case XK_m: return AK_M;
! 559: case XK_Q: case XK_q: return AK_Q;
1.1 root 560: case XK_Y: case XK_y: return AK_Z;
561: case XK_Z: case XK_z: return AK_Y;
562: case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
563: case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
564: case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
565: case XK_plus: case XK_asterisk: return AK_RBRACKET;
566: case XK_comma: return AK_COMMA;
567: case XK_period: return AK_PERIOD;
568: case XK_less: case XK_greater: return AK_LTGT;
569: case XK_numbersign: return AK_NUMBERSIGN;
570: case XK_ssharp: return AK_MINUS;
571: case XK_apostrophe: return AK_EQUAL;
1.1.1.2 ! root 572: case XK_asciicircum: return AK_BACKQUOTE;
! 573: case XK_minus: return AK_SLASH;
! 574: }
! 575:
! 576: return -1;
! 577: }
! 578:
! 579: static int decode_se(KeySym ks)
! 580: {
! 581: switch(ks) {
! 582: /* SE specific */
! 583: case XK_A: case XK_a: return AK_A;
! 584: case XK_M: case XK_m: return AK_M;
! 585: case XK_Q: case XK_q: return AK_Q;
! 586: case XK_Y: case XK_y: return AK_Y;
! 587: case XK_Z: case XK_z: return AK_Z;
! 588: case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
! 589: case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
! 590: case XK_Aring: case XK_aring: return AK_LBRACKET;
! 591: case XK_comma: return AK_COMMA;
! 592: case XK_period: return AK_PERIOD;
! 593: case XK_minus: return AK_SLASH;
! 594: case XK_less: case XK_greater: return AK_LTGT;
! 595: case XK_plus: case XK_question: return AK_EQUAL;
! 596: case XK_at: case XK_onehalf: return AK_BACKQUOTE;
! 597: case XK_asciitilde: case XK_asciicircum: return AK_RBRACKET;
! 598: case XK_backslash: case XK_bar: return AK_MINUS;
! 599:
! 600: case XK_numbersign: return AK_NUMBERSIGN;
! 601: }
! 602:
! 603: return -1;
! 604: }
! 605:
! 606: static int decode_it(KeySym ks)
! 607: {
! 608: switch(ks) {
! 609: /* IT specific */
! 610: case XK_A: case XK_a: return AK_A;
! 611: case XK_M: case XK_m: return AK_M;
! 612: case XK_Q: case XK_q: return AK_Q;
! 613: case XK_Y: case XK_y: return AK_Y;
! 614: case XK_Z: case XK_z: return AK_Z;
! 615: case XK_Ograve: case XK_ograve: return AK_SEMICOLON;
! 616: case XK_Agrave: case XK_agrave: return AK_QUOTE;
! 617: case XK_Egrave: case XK_egrave: return AK_LBRACKET;
! 618: case XK_plus: case XK_asterisk: return AK_RBRACKET;
! 619: case XK_comma: return AK_COMMA;
! 620: case XK_period: return AK_PERIOD;
! 621: case XK_less: case XK_greater: return AK_LTGT;
! 622: case XK_backslash: case XK_bar: return AK_BACKQUOTE;
! 623: case XK_apostrophe: return AK_MINUS;
! 624: case XK_Igrave: case XK_igrave: return AK_EQUAL;
! 625: case XK_minus: return AK_SLASH;
! 626: case XK_numbersign: return AK_NUMBERSIGN;
1.1 root 627: }
628:
629: return -1;
630: }
631:
632: static int keycode2amiga(XKeyEvent *event)
633: {
634: KeySym ks;
635: int as;
636: int index = 0;
637:
638: do {
639: ks = XLookupKeysym(event, index);
640: as = kc_decode (ks);
641:
642: if (as == -1) {
643: switch(keyboard_lang) {
1.1.1.2 ! root 644:
! 645: case KBD_LANG_FR:
! 646: as = decode_fr(ks);
! 647: break;
! 648:
! 649: case KBD_LANG_US:
1.1 root 650: as = decode_us(ks);
651: break;
652:
653: case KBD_LANG_DE:
654: as = decode_de(ks);
655: break;
656:
1.1.1.2 ! root 657: case KBD_LANG_SE:
! 658: as = decode_se(ks);
! 659: break;
! 660:
! 661: case KBD_LANG_IT:
! 662: as = decode_it(ks);
! 663: break;
! 664:
1.1 root 665: default:
666: as = -1;
667: break;
668: }
669: }
670: if(-1 != as)
671: return as;
672: index++;
673: } while (ks != NoSymbol);
674: return -1;
675: }
676:
677: static struct timeval lastMotionTime;
678:
679: void handle_events(void)
680: {
1.1.1.2 ! root 681: int repeat, refresh = 0;
! 682: newmousecounters = 0;
! 683: gui_handle_events();
! 684:
1.1 root 685: do {
686: XEvent event;
687: if (!XCheckMaskEvent(display, eventmask, &event)) break;
1.1.1.2 ! root 688: repeat = 0;
1.1 root 689:
690: switch(event.type) {
691: case KeyPress: {
692: int kc = keycode2amiga((XKeyEvent *)&event);
693: if (kc == -1) break;
694: switch (kc) {
695: case AK_mousestuff:
1.1.1.2 ! root 696: togglemouse();
1.1 root 697: break;
698:
699: case AK_inhibit:
700: inhibit_frame ^= 1;
701: break;
702:
703: default:
704: if (!keystate[kc]) {
1.1.1.2 ! root 705: keystate[kc] = 1;
1.1 root 706: record_key (kc << 1);
707: }
708: break;
709: }
710: break;
711: }
712: case KeyRelease: {
713: int kc = keycode2amiga((XKeyEvent *)&event);
714: if (kc == -1) break;
1.1.1.2 ! root 715: keystate[kc] = 0;
1.1 root 716: record_key ((kc << 1) | 1);
717: break;
718: }
719: case ButtonPress:
1.1.1.2 ! root 720: buttonstate[((XButtonEvent *)&event)->button-1] = 1;
1.1 root 721: break;
722: case ButtonRelease:
1.1.1.2 ! root 723: buttonstate[((XButtonEvent *)&event)->button-1] = 0;
1.1 root 724: break;
725: case EnterNotify:
1.1.1.2 ! root 726: newmousecounters = 1;
1.1 root 727: lastmx = ((XCrossingEvent *)&event)->x;
728: lastmy = ((XCrossingEvent *)&event)->y;
1.1.1.2 ! root 729: repeat = 1;
! 730: inwindow = 1;
1.1 root 731: break;
732: case LeaveNotify:
1.1.1.2 ! root 733: inwindow = 0;
! 734: repeat = 1;
1.1 root 735: break;
736: case FocusIn:
737: XAutoRepeatOff(display);
1.1.1.2 ! root 738: repeat = 1;
1.1 root 739: break;
740: case FocusOut:
741: XAutoRepeatOn(display);
1.1.1.2 ! root 742: repeat = 1;
1.1 root 743: break;
744: case MotionNotify:
745: if (inwindow) {
746: lastmx = ((XMotionEvent *)&event)->x;
747: lastmy = ((XMotionEvent *)&event)->y;
1.1.1.2 ! root 748: if(!cursorOn && use_xhair) {
1.1 root 749: XDefineCursor(display, mywin, xhairCursor);
1.1.1.2 ! root 750: cursorOn = 1;
1.1 root 751: }
752: gettimeofday(&lastMotionTime, NULL);
753: }
1.1.1.2 ! root 754: repeat = 1;
! 755: break;
! 756: case Expose:
! 757: refresh = 1;
! 758: repeat = 1;
1.1 root 759: break;
760: }
761: } while (repeat);
1.1.1.2 ! root 762:
! 763: #ifdef DONT_WANT_SHM
! 764: if(refresh)
! 765: XPutImage(display, mywin, blackgc, img, 0, 0, 0, 0, hpixels, vsize);
! 766: #else
! 767: if(refresh)
! 768: XShmPutImage(display, mywin, blackgc, img, 0, 0, 0, 0, hpixels, vsize, 0);
! 769: #endif
! 770: if(cursorOn && use_xhair) {
1.1 root 771: struct timeval now;
772: int diff;
773: gettimeofday(&now, NULL);
774: diff = (now.tv_sec - lastMotionTime.tv_sec) * 1000000 +
775: (now.tv_usec - lastMotionTime.tv_usec);
776: if(diff > 1000000) {
777: XDefineCursor(display, mywin, blankCursor);
1.1.1.2 ! root 778: cursorOn = 0;
1.1 root 779: }
780: }
781:
782: /* "Affengriff" */
783: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
784: MC68000_reset();
785: }
786:
1.1.1.2 ! root 787: int debuggable(void)
1.1 root 788: {
1.1.1.2 ! root 789: return 1;
1.1 root 790: }
791:
1.1.1.2 ! root 792: int needmousehack(void)
1.1 root 793: {
1.1.1.2 ! root 794: return 1;
1.1 root 795: }
796:
797: void LED(int on)
798: {
1.1.1.2 ! root 799: XKeyboardControl control;
! 800: control.led = 1; /* implementation defined */
! 801: control.led_mode = on ? LedModeOn : LedModeOff;
! 802: XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
1.1 root 803: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.