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.8 by gbeauche, 2003-12-27T10:37:30Z

# 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 <errno.h>
30   #include <pthread.h>
31  
32 < #include "sysdeps.h"
32 > #ifdef ENABLE_XF86_DGA
33 > #include <X11/extensions/xf86dga.h>
34 > #endif
35 >
36 > #ifdef ENABLE_XF86_VIDMODE
37 > # include <X11/extensions/xf86vmode.h>
38 > #endif
39 >
40   #include "main.h"
41   #include "adb.h"
42   #include "prefs.h"
# Line 38 | Line 48
48   #define DEBUG 0
49   #include "debug.h"
50  
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
51  
52 + // Constants
53 + const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes";
54  
55   // Global variables
56   static int32 frame_skip;
57 + static int16 mouse_wheel_mode;
58 + static int16 mouse_wheel_lines;
59   static bool redraw_thread_active = false;       // Flag: Redraw thread installed
60   static pthread_t redraw_thread;                         // Redraw thread
61  
62 + static bool local_X11;                                          // Flag: X server running on local machine?
63   static volatile bool thread_stop_req = false;
64   static volatile bool thread_stop_ack = false;   // Acknowledge for thread_stop_req
65  
# Line 73 | Line 81 | static bool emerg_quit = false;                                // Fl
81   static bool emul_suspended = false;                     // Flag: emulator suspended
82   static Window suspend_win;                                      // "Suspend" window
83   static void *fb_save = NULL;                            // Saved frame buffer for suspend
84 + static bool use_keycodes = false;                       // Flag: Use keycodes rather than keysyms
85 + static int keycode_table[256];                          // X keycode -> Mac keycode translation table
86  
87   // X11 variables
88   static int screen;                                                      // Screen number
# Line 118 | Line 128 | static int num_x_video_modes;
128   static void *redraw_func(void *arg);
129  
130  
131 < // From main_linux.cpp
131 > // From main_unix.cpp
132 > extern char *x_display_name;
133   extern Display *x_display;
134  
135   // From sys_unix.cpp
# Line 157 | Line 168 | static bool open_window(int width, int h
168          // Set absolute mouse mode
169          ADBSetRelMouseMode(false);
170  
160        // Read frame skip prefs
161        frame_skip = PrefsFindInt32("frameskip");
162        if (frame_skip == 0)
163                frame_skip = 1;
164
171          // Create window
172          XSetWindowAttributes wattr;
173          wattr.event_mask = eventmask = win_eventmask;
# Line 195 | Line 201 | static bool open_window(int width, int h
201                  XFree((char *)hints);
202          }
203  
204 +        // 1-bit mode is big-endian; if the X server is little-endian, we can't
205 +        // use SHM because that doesn't allow changing the image byte order
206 +        bool need_msb_image = (depth == 1 && XImageByteOrder(x_display) == LSBFirst);
207 +
208          // Try to create and attach SHM image
209          have_shm = false;
210 <        if (depth != 1 && XShmQueryExtension(x_display)) {
210 >        if (local_X11 && !need_msb_image && XShmQueryExtension(x_display)) {
211  
212                  // Create SHM image ("height + 2" for safety)
213 <                img = XShmCreateImage(x_display, vis, depth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height);
213 >                img = XShmCreateImage(x_display, vis, depth == 1 ? 1 : xdepth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height);
214                  shminfo.shmid = shmget(IPC_PRIVATE, (height + 2) * img->bytes_per_line, IPC_CREAT | 0777);
215                  the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0);
216                  shminfo.shmaddr = img->data = (char *)the_buffer_copy;
# Line 528 | Line 538 | static void close_display(void)
538   *  Initialization
539   */
540  
541 + // Init keycode translation table
542 + static void keycode_init(void)
543 + {
544 +        bool use_kc = PrefsFindBool("keycodes");
545 +        if (use_kc) {
546 +
547 +                // Get keycode file path from preferences
548 +                const char *kc_path = PrefsFindString("keycodefile");
549 +
550 +                // Open keycode table
551 +                FILE *f = fopen(kc_path ? kc_path : KEYCODE_FILE_NAME, "r");
552 +                if (f == NULL) {
553 +                        char str[256];
554 +                        sprintf(str, GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno));
555 +                        WarningAlert(str);
556 +                        return;
557 +                }
558 +
559 +                // Default translation table
560 +                for (int i=0; i<256; i++)
561 +                        keycode_table[i] = -1;
562 +
563 +                // Search for server vendor string, then read keycodes
564 +                const char *vendor = ServerVendor(x_display);
565 +                bool vendor_found = false;
566 +                char line[256];
567 +                while (fgets(line, 255, f)) {
568 +                        // Read line
569 +                        int len = strlen(line);
570 +                        if (len == 0)
571 +                                continue;
572 +                        line[len-1] = 0;
573 +
574 +                        // Comments begin with "#" or ";"
575 +                        if (line[0] == '#' || line[0] == ';' || line[0] == 0)
576 +                                continue;
577 +
578 +                        if (vendor_found) {
579 +                                // Read keycode
580 +                                int x_code, mac_code;
581 +                                if (sscanf(line, "%d %d", &x_code, &mac_code) == 2)
582 +                                        keycode_table[x_code & 0xff] = mac_code;
583 +                                else
584 +                                        break;
585 +                        } else {
586 +                                // Search for vendor string
587 +                                if (strstr(vendor, line) == vendor)
588 +                                        vendor_found = true;
589 +                        }
590 +                }
591 +
592 +                // Keycode file completely read
593 +                fclose(f);
594 +                use_keycodes = vendor_found;
595 +
596 +                // Vendor not found? Then display warning
597 +                if (!vendor_found) {
598 +                        char str[256];
599 +                        sprintf(str, GetString(STR_KEYCODE_VENDOR_WARN), vendor, kc_path ? kc_path : KEYCODE_FILE_NAME);
600 +                        WarningAlert(str);
601 +                        return;
602 +                }
603 +        }
604 + }
605 +
606   static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, long apple_mode, long apple_id, int type)
607   {
608          if (allow & test) {
# Line 597 | Line 672 | bool VideoInit(void)
672          mainBuffer.pageInfo = NULL;
673   #endif
674          
675 +        // Check if X server runs on local machine
676 +        local_X11 = (strncmp(XDisplayName(x_display_name), ":", 1) == 0)
677 +                 || (strncmp(XDisplayName(x_display_name), "unix:", 5) == 0);
678 +    
679 +        // Init keycode translation
680 +        keycode_init();
681 +
682 +        // Read frame skip prefs
683 +        frame_skip = PrefsFindInt32("frameskip");
684 +        if (frame_skip == 0)
685 +                frame_skip = 1;
686 +
687 +        // Read mouse wheel prefs
688 +        mouse_wheel_mode = PrefsFindInt32("mousewheelmode");
689 +        mouse_wheel_lines = PrefsFindInt32("mousewheellines");
690 +
691          // Init variables
692          private_data = NULL;
693          cur_mode = 0;   // Window 640x480
# Line 612 | Line 703 | bool VideoInit(void)
703   #ifdef ENABLE_XF86_DGA
704          // DGA available?
705      int event_base, error_base;
706 <    if (XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
706 >    if (local_X11 && XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
707                  int dga_flags = 0;
708                  XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
709                  has_dga = dga_flags & XF86DGADirectPresent;
# Line 1068 | Line 1159 | static int kc_decode(KeySym ks)
1159          return -1;
1160   }
1161  
1162 < static int event2keycode(XKeyEvent *ev)
1162 > static int event2keycode(XKeyEvent &ev)
1163   {
1164          KeySym ks;
1165          int as;
1166          int i = 0;
1167  
1168          do {
1169 <                ks = XLookupKeysym(ev, i++);
1169 >                ks = XLookupKeysym(&ev, i++);
1170                  as = kc_decode(ks);
1171                  if (as != -1)
1172                          return as;
# Line 1099 | Line 1190 | static void handle_events(void)
1190                                  unsigned int button = ((XButtonEvent *)&event)->button;
1191                                  if (button < 4)
1192                                          ADBMouseDown(button - 1);
1193 +                                else if (button < 6) {  // Wheel mouse
1194 +                                        if (mouse_wheel_mode == 0) {
1195 +                                                int key = (button == 5) ? 0x79 : 0x74;  // Page up/down
1196 +                                                ADBKeyDown(key);
1197 +                                                ADBKeyUp(key);
1198 +                                        } else {
1199 +                                                int key = (button == 5) ? 0x3d : 0x3e;  // Cursor up/down
1200 +                                                for(int i=0; i<mouse_wheel_lines; i++) {
1201 +                                                        ADBKeyDown(key);
1202 +                                                        ADBKeyUp(key);
1203 +                                                }
1204 +                                        }
1205 +                                }
1206                                  break;
1207                          }
1208                          case ButtonRelease: {
# Line 1118 | Line 1222 | static void handle_events(void)
1222  
1223                          // Keyboard
1224                          case KeyPress: {
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                                          if (!emul_suspended) {
1230                                                  ADBKeyDown(code);
1231                                                  if (code == 0x36)
# Line 1132 | Line 1238 | static void handle_events(void)
1238                                  break;
1239                          }
1240                          case KeyRelease: {
1241 <                                int code;
1242 <                                if ((code = event2keycode((XKeyEvent *)&event)) != -1) {
1241 >                                int code = event2keycode(event.xkey);
1242 >                                if (use_keycodes && code != 1)
1243 >                                        code = keycode_table[event.xkey.keycode & 0xff];
1244 >                                if (code != -1) {
1245                                          ADBKeyUp(code);
1246                                          if (code == 0x36)
1247                                                  ctrl_down = false;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines