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