ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/video_x.cpp
(Generate patch)

Comparing SheepShaver/src/Unix/video_x.cpp (file contents):
Revision 1.3 by gbeauche, 2003-05-22T22:12:05Z vs.
Revision 1.6 by gbeauche, 2003-11-21T17:01:33Z

# Line 18 | Line 18
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  
21 + #include "sysdeps.h"
22 +
23   #include <X11/Xlib.h>
24   #include <X11/Xutil.h>
25   #include <X11/keysym.h>
26   #include <X11/extensions/XShm.h>
27   #include <sys/ipc.h>
28   #include <sys/shm.h>
29 < #include <pthread.h>
29 > #include <errno.h>
30 >
31 > #ifdef HAVE_PTHREADS
32 > # include <pthread.h>
33 > #endif
34 >
35 > #ifdef ENABLE_XF86_DGA
36 > #include <X11/extensions/xf86dga.h>
37 > #endif
38 >
39 > #ifdef ENABLE_XF86_VIDMODE
40 > # include <X11/extensions/xf86vmode.h>
41 > #endif
42  
29 #include "sysdeps.h"
43   #include "main.h"
44   #include "adb.h"
45   #include "prefs.h"
# Line 38 | Line 51
51   #define DEBUG 0
52   #include "debug.h"
53  
41 #ifdef ENABLE_XF86_DGA
42 #include <X11/extensions/xf86dga.h>
43 #endif
44
45 #ifdef ENABLE_XF86_VIDMODE
46 #include <X11/extensions/xf86vmode.h>
47 #endif
54  
55 + // Constants
56 + const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes";
57  
58   // Global variables
59   static int32 frame_skip;
60   static bool redraw_thread_active = false;       // Flag: Redraw thread installed
61   static pthread_t redraw_thread;                         // Redraw thread
62  
63 + static bool local_X11;                                          // Flag: X server running on local machine?
64   static volatile bool thread_stop_req = false;
65   static volatile bool thread_stop_ack = false;   // Acknowledge for thread_stop_req
66  
# Line 73 | Line 82 | static bool emerg_quit = false;                                // Fl
82   static bool emul_suspended = false;                     // Flag: emulator suspended
83   static Window suspend_win;                                      // "Suspend" window
84   static void *fb_save = NULL;                            // Saved frame buffer for suspend
85 + static bool use_keycodes = false;                       // Flag: Use keycodes rather than keysyms
86 + static int keycode_table[256];                          // X keycode -> Mac keycode translation table
87  
88   // X11 variables
89   static int screen;                                                      // Screen number
# Line 118 | Line 129 | static int num_x_video_modes;
129   static void *redraw_func(void *arg);
130  
131  
132 < // From main_linux.cpp
132 > // From main_unix.cpp
133 > extern char *x_display_name;
134   extern Display *x_display;
135  
136   // From sys_unix.cpp
# Line 195 | Line 207 | static bool open_window(int width, int h
207                  XFree((char *)hints);
208          }
209  
210 +        // 1-bit mode is big-endian; if the X server is little-endian, we can't
211 +        // use SHM because that doesn't allow changing the image byte order
212 +        bool need_msb_image = (depth == 1 && XImageByteOrder(x_display) == LSBFirst);
213 +
214          // Try to create and attach SHM image
215          have_shm = false;
216 <        if (depth != 1 && XShmQueryExtension(x_display)) {
216 >        if (local_X11 && !need_msb_image && XShmQueryExtension(x_display)) {
217  
218                  // Create SHM image ("height + 2" for safety)
219 <                img = XShmCreateImage(x_display, vis, depth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height);
219 >                img = XShmCreateImage(x_display, vis, depth == 1 ? 1 : xdepth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height);
220                  shminfo.shmid = shmget(IPC_PRIVATE, (height + 2) * img->bytes_per_line, IPC_CREAT | 0777);
221                  the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0);
222                  shminfo.shmaddr = img->data = (char *)the_buffer_copy;
# Line 528 | Line 544 | static void close_display(void)
544   *  Initialization
545   */
546  
547 + // Init keycode translation table
548 + static void keycode_init(void)
549 + {
550 +        bool use_kc = PrefsFindBool("keycodes");
551 +        if (use_kc) {
552 +
553 +                // Get keycode file path from preferences
554 +                const char *kc_path = PrefsFindString("keycodefile");
555 +
556 +                // Open keycode table
557 +                FILE *f = fopen(kc_path ? kc_path : KEYCODE_FILE_NAME, "r");
558 +                if (f == NULL) {
559 +                        char str[256];
560 +                        sprintf(str, GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno));
561 +                        WarningAlert(str);
562 +                        return;
563 +                }
564 +
565 +                // Default translation table
566 +                for (int i=0; i<256; i++)
567 +                        keycode_table[i] = -1;
568 +
569 +                // Search for server vendor string, then read keycodes
570 +                const char *vendor = ServerVendor(x_display);
571 +                bool vendor_found = false;
572 +                char line[256];
573 +                while (fgets(line, 255, f)) {
574 +                        // Read line
575 +                        int len = strlen(line);
576 +                        if (len == 0)
577 +                                continue;
578 +                        line[len-1] = 0;
579 +
580 +                        // Comments begin with "#" or ";"
581 +                        if (line[0] == '#' || line[0] == ';' || line[0] == 0)
582 +                                continue;
583 +
584 +                        if (vendor_found) {
585 +                                // Read keycode
586 +                                int x_code, mac_code;
587 +                                if (sscanf(line, "%d %d", &x_code, &mac_code) == 2)
588 +                                        keycode_table[x_code & 0xff] = mac_code;
589 +                                else
590 +                                        break;
591 +                        } else {
592 +                                // Search for vendor string
593 +                                if (strstr(vendor, line) == vendor)
594 +                                        vendor_found = true;
595 +                        }
596 +                }
597 +
598 +                // Keycode file completely read
599 +                fclose(f);
600 +                use_keycodes = vendor_found;
601 +
602 +                // Vendor not found? Then display warning
603 +                if (!vendor_found) {
604 +                        char str[256];
605 +                        sprintf(str, GetString(STR_KEYCODE_VENDOR_WARN), vendor, kc_path ? kc_path : KEYCODE_FILE_NAME);
606 +                        WarningAlert(str);
607 +                        return;
608 +                }
609 +        }
610 + }
611 +
612   static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, long apple_mode, long apple_id, int type)
613   {
614          if (allow & test) {
# Line 597 | Line 678 | bool VideoInit(void)
678          mainBuffer.pageInfo = NULL;
679   #endif
680          
681 +        // Check if X server runs on local machine
682 +        local_X11 = (strncmp(XDisplayName(x_display_name), ":", 1) == 0)
683 +                 || (strncmp(XDisplayName(x_display_name), "unix:", 5) == 0);
684 +    
685 +        // Init keycode translation
686 +        keycode_init();
687 +
688          // Init variables
689          private_data = NULL;
690          cur_mode = 0;   // Window 640x480
# Line 612 | Line 700 | bool VideoInit(void)
700   #ifdef ENABLE_XF86_DGA
701          // DGA available?
702      int event_base, error_base;
703 <    if (XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
703 >    if (local_X11 && XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
704                  int dga_flags = 0;
705                  XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
706                  has_dga = dga_flags & XF86DGADirectPresent;
# Line 1068 | Line 1156 | static int kc_decode(KeySym ks)
1156          return -1;
1157   }
1158  
1159 < static int event2keycode(XKeyEvent *ev)
1159 > static int event2keycode(XKeyEvent &ev)
1160   {
1161          KeySym ks;
1162          int as;
1163          int i = 0;
1164  
1165          do {
1166 <                ks = XLookupKeysym(ev, i++);
1166 >                ks = XLookupKeysym(&ev, i++);
1167                  as = kc_decode(ks);
1168                  if (as != -1)
1169                          return as;
# Line 1118 | Line 1206 | static void handle_events(void)
1206  
1207                          // Keyboard
1208                          case KeyPress: {
1209 <                                int code;
1210 <                                if ((code = event2keycode((XKeyEvent *)&event)) != -1) {
1209 >                                int code = event2keycode(event.xkey);
1210 >                                if (use_keycodes && code != -1)
1211 >                                        code = keycode_table[event.xkey.keycode & 0xff];
1212 >                                if (code != -1) {
1213                                          if (!emul_suspended) {
1214                                                  ADBKeyDown(code);
1215                                                  if (code == 0x36)
# Line 1132 | Line 1222 | static void handle_events(void)
1222                                  break;
1223                          }
1224                          case KeyRelease: {
1225 <                                int code;
1226 <                                if ((code = event2keycode((XKeyEvent *)&event)) != -1) {
1225 >                                int code = event2keycode(event.xkey);
1226 >                                if (use_keycodes && code != 1)
1227 >                                        code = keycode_table[event.xkey.keycode & 0xff];
1228 >                                if (code != -1) {
1229                                          ADBKeyUp(code);
1230                                          if (code == 0x36)
1231                                                  ctrl_down = false;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines