Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

Display_x.i

Go to the documentation of this file.
00001 /*
00002  *  Display_x.i - C64 graphics display, emulator window handling,
00003  *                X specific stuff
00004  *
00005  *  Frodo (C) 1994-1997 Christian Bauer
00006  *  X11 stuff by Bernd Schmidt/Lutz Vieweg
00007  */
00008 
00009 #include "CmdPipe.h"
00010 #include "SAM.h"
00011 #include "C64.h"
00012 
00013 #include <X11/Xlib.h>
00014 #include <X11/Xutil.h>
00015 #include <X11/keysym.h>
00016 #include <X11/cursorfont.h>
00017 
00018 #if defined(X_USE_SHM)
00019 #include <sys/ipc.h>
00020 #include <sys/shm.h>
00021 #include <X11/extensions/XShm.h>
00022 static XShmSegmentInfo shminfo;
00023 #endif
00024 
00025 static Display *display;
00026 static int screen;
00027 static Window rootwin, mywin;
00028 
00029 static GC black_gc, led_gc;
00030 static XColor black, fill_gray, shine_gray, shadow_gray, red, green;
00031 static Colormap cmap;
00032 static Font led_font;
00033 
00034 static XImage *img;
00035 static Visual *vis;
00036 static XVisualInfo visualInfo;
00037 static int bitdepth;
00038 static char *bufmem;
00039 static int hsize;
00040 
00041 // For LED error blinking
00042 static C64Display *c64_disp;
00043 static struct sigaction pulse_sa;
00044 static itimerval pulse_tv;
00045 
00046 // Keyboard and joystick
00047 static int keystate[256];
00048 static int joystate = 0xFF;
00049 static bool num_locked = false;
00050 
00051 static const long int eventmask = (KeyPressMask|KeyReleaseMask|FocusChangeMask|ExposureMask);
00052 
00053 
00054 /*
00055   C64 keyboard matrix:
00056 
00057     Bit 7   6   5   4   3   2   1   0
00058   0    CUD  F5  F3  F1  F7 CLR RET DEL
00059   1    SHL  E   S   Z   4   A   W   3
00060   2     X   T   F   C   6   D   R   5
00061   3     V   U   H   B   8   G   Y   7
00062   4     N   O   K   M   0   J   I   9
00063   5     ,   @   :   .   -   L   P   +
00064   6     /   ^   =  SHR HOM  ;   *   
00065   7    R/S  Q   C= SPC  2  CTL  <-  1
00066 */
00067 
00068 #define MATRIX(a,b) (((a) << 3) | (b))
00069 
00070 #define KEY_F9 512
00071 #define KEY_F10 513
00072 #define KEY_F11 514
00073 #define KEY_F12 515
00074 
00075 #ifdef SUN
00076 #define KEY_FIRE 58
00077 #define KEY_JU 135
00078 #define KEY_JD 7
00079 #define KEY_JL 130
00080 #define KEY_JR 2
00081 #else
00082 #define KEY_FIRE 516
00083 #define KEY_JU 517
00084 #define KEY_JD 518
00085 #define KEY_JL 519
00086 #define KEY_JR 520
00087 #endif
00088 
00089 #define KEY_JUL 521
00090 #define KEY_JUR 522
00091 #define KEY_JDL 523
00092 #define KEY_JDR 524
00093 
00094 #define KEY_KP_PLUS 525
00095 #define KEY_KP_MINUS 526
00096 #define KEY_KP_MULT 527
00097 #define KEY_NUM_LOCK 528
00098 
00099 
00100 #define ThePrefs (TheC64->ThePrefs)
00101 
00102 /*
00103  *  Decode KeySyms. This function knows about all keys that
00104  *  are common between different keyboard languages.
00105  */
00106 
00107 static int kc_decode(KeySym ks)
00108 {
00109         switch (ks) {      
00110                 case XK_A: case XK_a: return MATRIX(1,2);
00111                 case XK_B: case XK_b: return MATRIX(3,4);
00112                 case XK_C: case XK_c: return MATRIX(2,4);
00113                 case XK_D: case XK_d: return MATRIX(2,2);
00114                 case XK_E: case XK_e: return MATRIX(1,6);
00115                 case XK_F: case XK_f: return MATRIX(2,5);
00116                 case XK_G: case XK_g: return MATRIX(3,2);
00117                 case XK_H: case XK_h: return MATRIX(3,5);
00118                 case XK_I: case XK_i: return MATRIX(4,1);
00119                 case XK_J: case XK_j: return MATRIX(4,2);
00120                 case XK_K: case XK_k: return MATRIX(4,5);
00121                 case XK_L: case XK_l: return MATRIX(5,2);
00122                 case XK_M: case XK_m: return MATRIX(4,4);
00123                 case XK_N: case XK_n: return MATRIX(4,7);
00124                 case XK_O: case XK_o: return MATRIX(4,6);
00125                 case XK_P: case XK_p: return MATRIX(5,1);
00126                 case XK_Q: case XK_q: return MATRIX(7,6);
00127                 case XK_R: case XK_r: return MATRIX(2,1);
00128                 case XK_S: case XK_s: return MATRIX(1,5);
00129                 case XK_T: case XK_t: return MATRIX(2,6);
00130                 case XK_U: case XK_u: return MATRIX(3,6);
00131                 case XK_V: case XK_v: return MATRIX(3,7);
00132                 case XK_W: case XK_w: return MATRIX(1,1);
00133                 case XK_X: case XK_x: return MATRIX(2,7);
00134                 case XK_Y: case XK_y: return MATRIX(3,1);
00135                 case XK_Z: case XK_z: return MATRIX(1,4);
00136 
00137                 case XK_0: return MATRIX(4,3);
00138                 case XK_1: return MATRIX(7,0);
00139                 case XK_2: return MATRIX(7,3);
00140                 case XK_3: return MATRIX(1,0);
00141                 case XK_4: return MATRIX(1,3);
00142                 case XK_5: return MATRIX(2,0);
00143                 case XK_6: return MATRIX(2,3);
00144                 case XK_7: return MATRIX(3,0);
00145                 case XK_8: return MATRIX(3,3);
00146                 case XK_9: return MATRIX(4,0);
00147 
00148                 case XK_space: return MATRIX(7,4);
00149                 case XK_grave: return MATRIX(7,1);
00150                 case XK_backslash: return MATRIX(6,6);
00151                 case XK_comma: return MATRIX(5,7);
00152                 case XK_period: return MATRIX(5,4);
00153 
00154                 case XK_Escape: return MATRIX(7,7);
00155                 case XK_Return: return MATRIX(0,1);
00156                 case XK_BackSpace: case XK_Delete: return MATRIX(0,0);
00157                 case XK_Insert: return MATRIX(6,3);
00158                 case XK_Home: case XK_Help: return MATRIX(6,3);
00159                 case XK_End: return MATRIX(6,0);
00160 #ifdef __hpux
00161                 case XK_Prior: return MATRIX(6,0);
00162                 case XK_Next: return MATRIX(6,5);
00163 #else
00164                 case XK_Page_Up: return MATRIX(6,0);
00165                 case XK_Page_Down: return MATRIX(6,5);
00166 #endif
00167                 case XK_Control_L: return MATRIX(7,2);
00168                 case XK_Control_R: return MATRIX(7,5);
00169                 case XK_Shift_L: return MATRIX(1,7);
00170                 case XK_Shift_R: return MATRIX(6,4);
00171                 case XK_Alt_L: return MATRIX(7,5);
00172                 case XK_Alt_R: return MATRIX(7,5);
00173 
00174                 case XK_Up: return MATRIX(0,7)| 0x80;
00175                 case XK_Down: return MATRIX(0,7);
00176                 case XK_Left: return MATRIX(0,2) | 0x80;
00177                 case XK_Right: return MATRIX(0,2);
00178 
00179                 case XK_F1: return MATRIX(0,4);
00180                 case XK_F2: return MATRIX(0,4) | 0x80;
00181                 case XK_F3: return MATRIX(0,5);
00182                 case XK_F4: return MATRIX(0,5) | 0x80;
00183                 case XK_F5: return MATRIX(0,6);
00184                 case XK_F6: return MATRIX(0,6) | 0x80;
00185                 case XK_F7: return MATRIX(0,3);
00186                 case XK_F8: return MATRIX(0,3) | 0x80;
00187 
00188                 case XK_F9: return KEY_F9;
00189                 case XK_F10: return KEY_F10;
00190                 case XK_F11: return KEY_F11;
00191                 case XK_F12: return KEY_F12;
00192 
00193                 /* You never know which Keysyms might be missing on some workstation
00194                  * This #ifdef should be enough. */
00195 #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End)
00196                 case XK_KP_0: case XK_KP_Insert: return KEY_FIRE;
00197                 case XK_KP_1: case XK_KP_End: return KEY_JDL;
00198                 case XK_KP_2: case XK_KP_Down: return KEY_JD;
00199                 case XK_KP_3: case XK_KP_Next: return KEY_JDR;
00200                 case XK_KP_4: case XK_KP_Left: return KEY_JL;
00201                 case XK_KP_5: case XK_KP_Begin: return KEY_FIRE;
00202                 case XK_KP_6: case XK_KP_Right: return KEY_JR;
00203                 case XK_KP_7: case XK_KP_Home: return KEY_JUL;
00204                 case XK_KP_8: case XK_KP_Up: return KEY_JU;
00205                 case XK_KP_9: case XK_KP_Prior: return KEY_JUR;
00206 #else
00207                 case XK_KP_0: return KEY_FIRE;
00208                 case XK_KP_1: return KEY_JDL;
00209                 case XK_KP_2: return KEY_JD;
00210                 case XK_KP_3: return KEY_JDR;
00211                 case XK_KP_4: return KEY_JL;
00212                 case XK_KP_5: return KEY_FIRE;
00213                 case XK_KP_6: return KEY_JR;
00214                 case XK_KP_7: return KEY_JUL;
00215                 case XK_KP_8: return KEY_JU;
00216                 case XK_KP_9: return KEY_JUR;
00217 #endif
00218 
00219                 case XK_KP_Add: return KEY_KP_PLUS;
00220                 case XK_KP_Subtract: return KEY_KP_MINUS;
00221                 case XK_KP_Multiply: return KEY_KP_MULT;
00222                 case XK_KP_Divide: return MATRIX(6,7);
00223                 case XK_KP_Enter: return MATRIX(0,1);
00224 
00225 #ifdef SUN
00226                 case XK_Num_Lock: return KEY_NUM_LOCK;
00227 #endif
00228         }
00229         return -1;
00230 }
00231 
00232 static int decode_us(KeySym ks)
00233 {
00234         switch(ks) {    /* US specific */       
00235                 case XK_minus: return MATRIX(5,0);
00236                 case XK_equal: return MATRIX(5,3);
00237                 case XK_bracketleft: return MATRIX(5,6);
00238                 case XK_bracketright: return MATRIX(6,1);
00239                 case XK_semicolon: return MATRIX(5,5);
00240                 case XK_apostrophe: return MATRIX(6,2);
00241                 case XK_slash: return MATRIX(6,7);
00242         }
00243 
00244         return -1;
00245 }
00246 
00247 static int decode_de(KeySym ks)
00248 {
00249         switch(ks) {    /* DE specific */
00250                 case XK_ssharp: return MATRIX(5,0);
00251                 case XK_apostrophe: return MATRIX(5,3);
00252                 case XK_Udiaeresis: case XK_udiaeresis: return MATRIX(5,6);
00253                 case XK_plus: return MATRIX(6,1);
00254                 case XK_Odiaeresis: case XK_odiaeresis: return MATRIX(5,5);
00255                 case XK_Adiaeresis: case XK_adiaeresis: return MATRIX(6,2);
00256                 case XK_numbersign: return MATRIX(6,5);
00257                 case XK_less: case XK_greater: return MATRIX(6,0);
00258                 case XK_minus: return MATRIX(6,7);
00259         }
00260 
00261         return -1;
00262 }
00263 
00264 static int keycode2c64(XKeyEvent *event)
00265 {
00266         KeySym ks;
00267         int as;
00268         int index = 0;
00269 
00270         do {
00271                 ks = XLookupKeysym(event, index);
00272                 as = kc_decode(ks);
00273        
00274                 if (as == -1)
00275                         as = KBD_LANG == 0 ? decode_us(ks) : decode_de(ks);
00276                 if (as != -1)
00277                         return as;
00278                 index++;
00279         } while (ks != NoSymbol);
00280 
00281         return -1;
00282 }
00283 
00284 
00285 /*
00286  *  Display constructor: Draw Speedometer/LEDs in window
00287  */
00288 
00289 C64Display::C64Display(C64 *the_c64) : TheC64(the_c64)
00290 {
00291         int i;
00292         char str[16];
00293 
00294         quit_requested = false;
00295 
00296         // LEDs off
00297         for (i=0; i<4; i++)
00298                 led_state[i] = old_led_state[i] = LED_OFF;
00299 
00300         // Draw speedometer/LEDs
00301         led_gc = XCreateGC(display, mywin, 0, 0);
00302         XSetFont(display, led_gc, led_font);
00303 
00304         XSetForeground(display, led_gc, fill_gray.pixel);
00305         XFillRectangle(display, mywin, led_gc, 0, DISPLAY_Y, DISPLAY_X-1, 16);
00306 
00307         XSetForeground(display, led_gc, shine_gray.pixel);
00308         XDrawLine(display, mywin, led_gc, 0, DISPLAY_Y, DISPLAY_X-1, DISPLAY_Y);
00309         for (i=0; i<5; i++)
00310                 XDrawLine(display, mywin, led_gc, DISPLAY_X*i/5, DISPLAY_Y, DISPLAY_X*i/5, DISPLAY_Y+14);
00311         for (i=2; i<6; i++) {
00312                 XDrawLine(display, mywin, led_gc, DISPLAY_X*i/5-23, DISPLAY_Y+11, DISPLAY_X*i/5-9, DISPLAY_Y+11);
00313                 XDrawLine(display, mywin, led_gc, DISPLAY_X*i/5-9, DISPLAY_Y+11, DISPLAY_X*i/5-9, DISPLAY_Y+5);
00314         }
00315 
00316         XSetForeground(display, led_gc, shadow_gray.pixel);
00317         XDrawLine(display, mywin, led_gc, 0, DISPLAY_Y+15, DISPLAY_X-1, DISPLAY_Y+15);
00318         for (i=1; i<6; i++)
00319                 XDrawLine(display, mywin, led_gc, DISPLAY_X*i/5-1, DISPLAY_Y+1, DISPLAY_X*i/5-1, DISPLAY_Y+15);
00320         for (i=2; i<6; i++) {
00321                 XDrawLine(display, mywin, led_gc, DISPLAY_X*i/5-24, DISPLAY_Y+11, DISPLAY_X*i/5-24, DISPLAY_Y+4);
00322                 XDrawLine(display, mywin, led_gc, DISPLAY_X*i/5-24, DISPLAY_Y+4, DISPLAY_X*i/5-9, DISPLAY_Y+4);
00323         }
00324 
00325         for (i=0; i<4; i++) {
00326                 sprintf(str, "Drive %d", i+8);
00327                 XSetForeground(display, led_gc, black.pixel);
00328                 XDrawString(display, mywin, led_gc, DISPLAY_X*(i+1)/5+8, DISPLAY_Y+12, str, strlen(str));
00329                 draw_led(i, LED_OFF);
00330         }
00331 
00332         // Start timer for LED error blinking
00333         c64_disp = this;
00334         pulse_sa.sa_handler = pulse_handler;
00335         pulse_sa.sa_flags = 0;
00336         sigemptyset(&pulse_sa.sa_mask);
00337         sigaction(SIGALRM, &pulse_sa, NULL);
00338         pulse_tv.it_interval.tv_sec = 0;
00339         pulse_tv.it_interval.tv_usec = 400000;
00340         pulse_tv.it_value.tv_sec = 0;
00341         pulse_tv.it_value.tv_usec = 400000;
00342         setitimer(ITIMER_REAL, &pulse_tv, NULL);
00343 }
00344 
00345 
00346 /*
00347  *  Display destructor
00348  */
00349 
00350 C64Display::~C64Display()
00351 {
00352         XAutoRepeatOn(display);
00353         XSync(display, 0);
00354 }
00355 
00356 
00357 /*
00358  *  Prefs may have changed
00359  */
00360 
00361 void C64Display::NewPrefs(Prefs *prefs)
00362 {
00363 }
00364 
00365 
00366 /*
00367  *  Connect to X server and open window
00368  */
00369 
00370 int init_graphics(void)
00371 {
00372         int i;
00373         char *display_name = 0;
00374         XSetWindowAttributes wattr;
00375         XSizeHints *hints;
00376         XColor exact_color;
00377         int pixbytes;
00378 
00379         display = XOpenDisplay(display_name);
00380         if (display == 0)  {
00381                 fprintf(stderr, "Can't connect to X server %s\n", XDisplayName(display_name));
00382                 return 0;
00383         }
00384 
00385         screen = XDefaultScreen(display);
00386         rootwin = XRootWindow(display, screen);
00387 #if 1
00388         if (XMatchVisualInfo(display, screen, 16, TrueColor, &visualInfo)) {
00389         } else if (XMatchVisualInfo(display, screen, 24, TrueColor, &visualInfo)) {
00390         } else 
00391 #endif
00392         if (XMatchVisualInfo(display, screen, 8, PseudoColor, &visualInfo)) {
00393                 /* for our HP boxes */
00394         } else if (XMatchVisualInfo(display, screen, 8, GrayScale, &visualInfo)) {
00395         } else {
00396                 fprintf(stderr, "Can't obtain appropriate X visual\n");
00397                 return 0;
00398         }
00399 
00400         vis = visualInfo.visual;
00401         bitdepth = visualInfo.depth;
00402         pixbytes = (bitdepth == 24 || bitdepth == 32 ? 4 : bitdepth == 12 || bitdepth == 16 ? 2 : 1);
00403         fprintf(stderr, "Using %d bit visual\n", bitdepth);
00404 
00405         hsize = (DISPLAY_X + 3) & ~3;
00406 
00407 #if defined(X_USE_SHM)
00408         img = XShmCreateImage(display, vis, bitdepth, ZPixmap, 0, &shminfo,
00409                               hsize, DISPLAY_Y);
00410         
00411         shminfo.shmid = shmget(IPC_PRIVATE, DISPLAY_Y * img->bytes_per_line,
00412                                IPC_CREAT | 0777);
00413         shminfo.shmaddr = img->data = bufmem = (char *)shmat(shminfo.shmid, 0, 0);
00414         shminfo.readOnly = False;
00415         XShmAttach(display, &shminfo);
00416         XSync(display,0);
00417         /* now deleting means making it temporary */
00418         shmctl(shminfo.shmid, IPC_RMID, 0);
00419 #else
00420         bufmem = (char *)malloc(pixbytes * hsize * DISPLAY_Y);
00421         img = XCreateImage(display, vis, bitdepth, ZPixmap, 0, bufmem, hsize, DISPLAY_Y, 32, 0);
00422 #endif
00423 
00424         cmap = XCreateColormap(display, rootwin, vis, AllocNone);
00425 
00426         XParseColor(display, cmap, "#000000", &black);
00427         if (!XAllocColor(display, cmap, &black))
00428                 fprintf(stderr, "Whoops??\n");
00429 
00430         wattr.event_mask = eventmask;
00431         wattr.background_pixel = black.pixel;
00432         wattr.backing_store = Always;
00433         wattr.backing_planes = bitdepth;
00434         wattr.border_pixmap = None;
00435         wattr.border_pixel = black.pixel;
00436         wattr.colormap = cmap;
00437 
00438         mywin = XCreateWindow(display, rootwin, 0, 0, DISPLAY_X, DISPLAY_Y + 16, 0,
00439                                                   bitdepth, InputOutput, vis,
00440                                                   CWEventMask|CWBackPixel|CWBorderPixel|CWBackingStore
00441                                                   |CWBackingPlanes|CWColormap,
00442                                                   &wattr);
00443         XMapWindow(display, mywin);
00444         XStoreName(display, mywin, "Frodo");
00445 
00446         if ((hints = XAllocSizeHints()) != NULL) {
00447                 hints->min_width = DISPLAY_X;
00448                 hints->max_width = DISPLAY_X;
00449                 hints->min_height = DISPLAY_Y + 16;
00450                 hints->max_height = DISPLAY_Y + 16;
00451                 hints->flags = PMinSize | PMaxSize;
00452                 XSetWMNormalHints(display, mywin, hints);
00453                 XFree((char *)hints);
00454         }
00455 
00456         black_gc = XCreateGC(display,mywin, 0, 0);
00457         XSetForeground(display, black_gc, black.pixel);
00458 
00459         // Allocate colors for speedometer/LEDs
00460         if (!XAllocNamedColor(display, cmap, "rgb:d0/d0/d0", &fill_gray, &exact_color))
00461                 return 0;
00462         if (!XAllocNamedColor(display, cmap, "rgb:e8/e8/e8", &shine_gray, &exact_color))
00463                 return 0;
00464         if (!XAllocNamedColor(display, cmap, "rgb:98/98/98", &shadow_gray, &exact_color))
00465                 return 0;
00466         if (!XAllocNamedColor(display, cmap, "rgb:f0/00/00", &red, &exact_color))
00467                 return 0;
00468         if (!XAllocNamedColor(display, cmap, "rgb:00/f0/00", &green, &exact_color))
00469                 return 0;
00470 
00471         // Load font for speedometer/LED labels
00472         led_font = XLoadFont(display, "-*-helvetica-medium-r-*-*-10-*");
00473 
00474         for(i=0; i<256; i++)
00475                 keystate[i] = 0;
00476 
00477         return 1;       
00478 }
00479 
00480 
00481 /*
00482  *  Redraw bitmap
00483  */
00484 
00485 void C64Display::Update(void)
00486 {
00487         // Update C64 display
00488         XSync(display, 0);
00489 #if defined(X_USE_SHM)
00490         XShmPutImage(display, mywin, black_gc, img, 0, 0, 0, 0, DISPLAY_X, DISPLAY_Y, 0);
00491 #else
00492         XPutImage(display, mywin, black_gc, img, 0, 0, 0, 0, DISPLAY_X, DISPLAY_Y);
00493 #endif
00494 
00495         // Update drive LEDs
00496         for (int i=0; i<4; i++)
00497                 if (led_state[i] != old_led_state[i]) {
00498                         draw_led(i, led_state[i]);
00499                         old_led_state[i] = led_state[i];
00500                 }
00501 }
00502 
00503 
00504 /*
00505  *  Draw one drive LED
00506  */
00507 
00508 void C64Display::draw_led(int num, int state)
00509 {
00510         switch (state) {
00511                 case LED_OFF:
00512                 case LED_ERROR_OFF:
00513                         XSetForeground(display, led_gc, black.pixel);
00514                         break;
00515                 case LED_ON:
00516                         XSetForeground(display, led_gc, green.pixel);
00517                         break;
00518                 case LED_ERROR_ON:
00519                         XSetForeground(display, led_gc, red.pixel);
00520                         break;
00521         }
00522         XFillRectangle(display, mywin, led_gc, DISPLAY_X*(num+2)/5-23, DISPLAY_Y+5, 14, 6);
00523 }
00524 
00525 
00526 /*
00527  *  LED error blink
00528  */
00529 
00530 void C64Display::pulse_handler(int)
00531 {
00532         for (int i=0; i<4; i++)
00533                 switch (c64_disp->led_state[i]) {
00534                         case LED_ERROR_ON:
00535                                 c64_disp->led_state[i] = LED_ERROR_OFF;
00536                                 break;
00537                         case LED_ERROR_OFF:
00538                                 c64_disp->led_state[i] = LED_ERROR_ON;
00539                                 break;
00540                 }
00541 }
00542 
00543 
00544 /*
00545  *  Draw speedometer
00546  */
00547 
00548 void C64Display::Speedometer(int speed)
00549 {
00550         static int delay = 0;
00551 
00552         if (delay >= 20) {
00553                 char str[16];
00554                 sprintf(str, "%d%%", speed);
00555                 XSetForeground(display, led_gc, fill_gray.pixel);
00556                 XFillRectangle(display,mywin, led_gc, 1, DISPLAY_Y+1, DISPLAY_X/5-2, 14);
00557                 XSetForeground(display, led_gc, black.pixel);
00558                 XDrawString(display, mywin, led_gc, 24, DISPLAY_Y+12, str, strlen(str));
00559                 delay = 0;
00560         } else
00561                 delay++;
00562 }
00563 
00564 
00565 /*
00566  *  Return pointer to bitmap data
00567  */
00568 
00569 uint8 *C64Display::BitmapBase(void)
00570 {
00571         return (uint8 *)bufmem;
00572 }
00573 
00574 
00579 int C64Display::BitmapXMod() const
00580 {
00581         return hsize;
00582 }
00583 
00584 
00585 /*
00586  *  Poll the keyboard
00587  */
00588 
00589 void C64Display::PollKeyboard(uint8 *key_matrix, uint8 *rev_matrix, uint8 *joystick)
00590 {
00591         static bool auto_rep = true;
00592         for(;;) {
00593                 XEvent event;
00594                 if (!XCheckMaskEvent(display, eventmask, &event)) 
00595                         break;
00596        
00597                 switch(event.type) {
00598 
00599                         case KeyPress: {                
00600                                 int kc = keycode2c64((XKeyEvent *)&event);
00601                                 if (kc == -1)
00602                                         break;
00603                                 switch (kc) {
00604 
00605                                         case KEY_F9:    // F9: Invoke SAM
00606                                                 SAM(TheC64);
00607                                                 break;
00608 
00609                                         case KEY_F10:   // F10: Quit
00610                                                 quit_requested = true;
00611                                                 break;
00612 
00613                                         case KEY_F11:   // F11: NMI (Restore)
00614                                                 TheC64->NMI();
00615                                                 break;
00616 
00617                                         case KEY_F12:   // F12: Reset
00618                                                 TheC64->Reset();
00619                                                 break;
00620 
00621                                         case KEY_NUM_LOCK:      // NumLock: Toggle joyport
00622                                                 num_locked = true;
00623                                                 break;
00624 
00625                                         case KEY_FIRE:
00626                                                 joystate &= ~0x10;
00627                                                 break;
00628                                         case KEY_JD:
00629                                                 joystate &= ~0x02;
00630                                                 break;
00631                                         case KEY_JU:
00632                                                 joystate &= ~0x01;
00633                                                 break;
00634                                         case KEY_JL:
00635                                                 joystate &= ~0x04;
00636                                                 break;
00637                                         case KEY_JR:
00638                                                 joystate &= ~0x08;
00639                                                 break;
00640                                         case KEY_JUL:
00641                                                 joystate &= ~0x05;
00642                                                 break;
00643                                         case KEY_JUR:
00644                                                 joystate &= ~0x09;
00645                                                 break;
00646                                         case KEY_JDL:
00647                                                 joystate &= ~0x06;
00648                                                 break;
00649                                         case KEY_JDR:
00650                                                 joystate &= ~0x0a;
00651                                                 break;
00652 
00653                                         case KEY_KP_PLUS:       // '+' on keypad: Increase SkipFrames
00654                                                 ThePrefs.SkipFrames++;
00655                                                 break;
00656 
00657                                         case KEY_KP_MINUS:      // '-' on keypad: Decrease SkipFrames
00658                                                 if (ThePrefs.SkipFrames > 1)
00659                                                         ThePrefs.SkipFrames--;
00660                                                 break;
00661 
00662                                         case KEY_KP_MULT:       // '*' on keypad: Toggle speed limiter
00663                                                 ThePrefs.LimitSpeed = !ThePrefs.LimitSpeed;
00664                                                 break;
00665 
00666                                         default:
00667                                                 if (keystate[kc])
00668                                                         break;
00669                                                 keystate[kc] = 1;
00670                                                 int c64_byte, c64_bit, shifted;
00671                                                 c64_byte = kc >> 3;
00672                                                 c64_bit = kc & 7;
00673                                                 shifted = kc & 128;
00674                                                 c64_byte &= 7;
00675                                                 if (shifted) {
00676                                                         key_matrix[6] &= 0xef;
00677                                                         rev_matrix[4] &= 0xbf;
00678                                                 }
00679                                                 key_matrix[c64_byte] &= ~(1 << c64_bit);
00680                                                 rev_matrix[c64_bit] &= ~(1 << c64_byte);
00681                                                 break;
00682                                 }
00683                                 break;
00684                         }
00685 
00686                         case KeyRelease: {           
00687                                 int kc = keycode2c64((XKeyEvent *)&event);
00688                                 if (kc == -1)
00689                                         break;
00690                                 switch (kc) {
00691 
00692                                         case KEY_NUM_LOCK:
00693                                                 num_locked = false;
00694                                                 break;
00695 
00696                                         case KEY_FIRE:
00697                                                 joystate |= 0x10;
00698                                                 break;
00699                                         case KEY_JD:
00700                                                 joystate |= 0x02;
00701                                                 break;
00702                                         case KEY_JU:
00703                                                 joystate |= 0x01;
00704                                                 break;
00705                                         case KEY_JL:
00706                                                 joystate |= 0x04;
00707                                                 break;
00708                                         case KEY_JR:
00709                                                 joystate |= 0x08;
00710                                                 break;
00711                                         case KEY_JUL:
00712                                                 joystate |= 0x05;
00713                                                 break;
00714                                         case KEY_JUR:
00715                                                 joystate |= 0x09;
00716                                                 break;
00717                                         case KEY_JDL:
00718                                                 joystate |= 0x06;
00719                                                 break;
00720                                         case KEY_JDR:
00721                                                 joystate |= 0x0a;
00722                                                 break;
00723 
00724                                         default:
00725                                                 if (!keystate[kc])
00726                                                         break;
00727                                                 keystate[kc] = 0;
00728                                                 int c64_byte, c64_bit, shifted;
00729                                                 c64_byte = kc >> 3;
00730                                                 c64_bit = kc & 7;
00731                                                 shifted = kc & 128;
00732                                                 c64_byte &= 7;
00733                                                 if (shifted) {
00734                                                         key_matrix[6] |= 0x10;
00735                                                         rev_matrix[4] |= 0x40;
00736                                                 }
00737                                                 key_matrix[c64_byte] |= (1 << c64_bit);
00738                                                 rev_matrix[c64_bit] |= (1 << c64_byte);
00739                                                 break;
00740                                 }
00741                         }
00742 
00743                         case FocusIn:
00744                                 if (auto_rep) {
00745                                         XAutoRepeatOff(display);
00746                                         auto_rep = false;
00747                                 }
00748                                 break;
00749 
00750                         case FocusOut:
00751                                 if (!auto_rep) {
00752                                         XAutoRepeatOn(display);
00753                                         auto_rep = true;
00754                                 }
00755                                 break;
00756                 }
00757         }
00758         *joystick = joystate;
00759 }
00760 
00761 
00762 /*
00763  *  Check if NumLock is down (for switching the joystick keyboard emulation)
00764  */
00765 
00766 bool C64Display::NumLock(void)
00767 {
00768         return num_locked;
00769 }
00770 
00771 
00772 /*
00773  *  Allocate C64 colors
00774  */
00775 
00776 void C64Display::InitColors(uint8 *colors)
00777 {
00778         int i;
00779         XColor col;
00780         char str[20];
00781 
00782         for (i=0; i< 256; i++) {
00783                 sprintf(str, "rgb:%x/%x/%x", palette_red[i & 0x0f], palette_green[i & 0x0f], palette_blue[i & 0x0f]);
00784                 XParseColor(display, cmap, str, &col);
00785                 if (XAllocColor(display, cmap, &col))
00786                         colors[i] = col.pixel;
00787                 else
00788                         fprintf(stderr, "Couldn't get all colors\n");
00789         }
00790 }
00791 
00792 
00793 /*
00794  *  Show a requester (error message)
00795  */
00796 
00797 long int ShowRequester(char *a,char *b,char *)
00798 {
00799         printf("%s: %s\n", a, b);
00800         return 1;
00801 }

Generated on Tue Feb 8 04:07:51 2005 for E32frodo by doxygen 1.3.3