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