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

Comparing BasiliskII/src/Unix/video_x.cpp (file contents):
Revision 1.2 by cebix, 1999-10-03T16:20:08Z vs.
Revision 1.11 by cebix, 1999-11-03T10:56:30Z

# Line 48 | Line 48
48   #define DEBUG 1
49   #include "debug.h"
50  
51 < #if ENABLE_DGA
51 > #if ENABLE_XF86_DGA
52   #include <X11/extensions/xf86dga.h>
53   #endif
54  
55 + #if ENABLE_FBDEV_DGA
56 + #include <sys/mman.h>
57 + #endif
58 +
59 +
60  
61   // Display types
62   enum {
# Line 61 | Line 66 | enum {
66  
67  
68   // Constants
69 < const char KEYCODE_FILE_NAME[] = SHAREDIR "keycodes";
69 > const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes";
70 > const char FBDEVICES_FILE_NAME[] = DATADIR "/fbdevices";
71  
72  
73   // Global variables
74 < static int32 frame_skip;
74 > static int32 frame_skip;                                                        // Prefs items
75 > static int16 mouse_wheel_mode = 1;
76 > static int16 mouse_wheel_lines = 3;
77 >
78   static int display_type = DISPLAY_WINDOW;                       // See enum above
79   static uint8 *the_buffer;                                                       // Mac frame buffer
80   static bool redraw_thread_active = false;                       // Flag: Redraw thread installed
# Line 75 | Line 84 | static pthread_t redraw_thread;                                                //
84   static bool has_dga = false;                                            // Flag: Video DGA capable
85  
86   static bool ctrl_down = false;                                          // Flag: Ctrl key pressed
87 + static bool caps_on = false;                                            // Flag: Caps Lock on
88   static bool quit_full_screen = false;                           // Flag: DGA close requested from redraw thread
89   static bool emerg_quit = false;                                         // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread
90   static bool emul_suspended = false;                                     // Flag: Emulator suspended
# Line 114 | Line 124 | static uint8 *the_buffer_copy = NULL;
124   static uint8 the_cursor[64];                                            // Cursor image data
125   static bool have_shm = false;                                           // Flag: SHM extensions available
126  
127 < // Variables for DGA mode
127 > // Variables for XF86 DGA mode
128   static int current_dga_cmap;                                            // Number (0 or 1) of currently installed DGA colormap
129   static Window suspend_win;                                                      // "Suspend" window
130   static void *fb_save = NULL;                                            // Saved frame buffer for suspend
121
131   static pthread_mutex_t frame_buffer_lock = PTHREAD_MUTEX_INITIALIZER;   // Mutex to protect frame buffer
132  
133 + // Variables for fbdev DGA mode
134 + const char FBDEVICE_FILE_NAME[] = "/dev/fb";
135 + static int fbdev_fd;
136 +
137  
138   // Prototypes
139   static void *redraw_func(void *arg);
# Line 141 | Line 154 | extern void SysMountFirstFloppy(void);
154   // Set VideoMonitor according to video mode
155   void set_video_monitor(int width, int height, int bytes_per_row, bool native_byte_order)
156   {
157 <        int layout;
157 >        int layout = FLAYOUT_DIRECT;
158          switch (depth) {
159                  case 1:
160                          layout = FLAYOUT_DIRECT;
# Line 232 | Line 245 | static bool init_window(int width, int h
245                  XSetWMNormalHints(x_display, the_win, hints);
246                  XFree((char *)hints);
247          }
248 <
248 >        
249          // Try to create and attach SHM image
250          have_shm = false;
251          if (depth != 1 && XShmQueryExtension(x_display)) {
# Line 259 | Line 272 | static bool init_window(int width, int h
272                          shmctl(shminfo.shmid, IPC_RMID, 0);
273                  }
274          }
275 <
275 >        
276          // Create normal X image if SHM doesn't work ("height + 2" for safety)
277          if (!have_shm) {
278                  int bytes_per_row = width;
# Line 312 | Line 325 | static bool init_window(int width, int h
325   #else
326          set_video_monitor(width, height, img->bytes_per_line, img->bitmap_bit_order == LSBFirst);
327   #endif
328 +        
329 + #if REAL_ADDRESSING
330 +        VideoMonitor.mac_frame_base = (uint32)the_buffer;
331 +        MacFrameLayout = FLAYOUT_DIRECT;
332 + #else
333 +        VideoMonitor.mac_frame_base = MacFrameBaseMac;
334 + #endif
335 +        return true;
336 + }
337 +
338 + // Init fbdev DGA display
339 + static bool init_fbdev_dga(char *in_fb_name)
340 + {
341 + #if ENABLE_FBDEV_DGA
342 +        // Find the maximum depth available
343 +        int ndepths, max_depth(0);
344 +        int *depths = XListDepths(x_display, screen, &ndepths);
345 +        if (depths == NULL) {
346 +                printf("FATAL: Could not determine the maximal depth available\n");
347 +                return false;
348 +        } else {
349 +                while (ndepths-- > 0) {
350 +                        if (depths[ndepths] > max_depth)
351 +                                max_depth = depths[ndepths];
352 +                }
353 +        }
354 +        
355 +        // Get fbdevices file path from preferences
356 +        const char *fbd_path = PrefsFindString("fbdevicefile");
357 +        
358 +        // Open fbdevices file
359 +        FILE *fp = fopen(fbd_path ? fbd_path : FBDEVICES_FILE_NAME, "r");
360 +        if (fp == NULL) {
361 +                char str[256];
362 +                sprintf(str, GetString(STR_NO_FBDEVICE_FILE_ERR), fbd_path ? fbd_path : FBDEVICES_FILE_NAME, strerror(errno));
363 +                ErrorAlert(str);
364 +                return false;
365 +        }
366 +        
367 +        int fb_depth;           // supported depth
368 +        uint32 fb_offset;       // offset used for mmap(2)
369 +        char fb_name[20];
370 +        char line[256];
371 +        bool device_found = false;
372 +        while (fgets(line, 255, fp)) {
373 +                // Read line
374 +                int len = strlen(line);
375 +                if (len == 0)
376 +                        continue;
377 +                line[len - 1] = '\0';
378 +                
379 +                // Comments begin with "#" or ";"
380 +                if ((line[0] == '#') || (line[0] == ';') || (line[0] == '\0'))
381 +                        continue;
382 +                
383 +                if ((sscanf(line, "%19s %d %x", &fb_name, &fb_depth, &fb_offset) == 3)
384 +                && (strcmp(fb_name, in_fb_name) == 0) && (fb_depth == max_depth)) {
385 +                        device_found = true;
386 +                        break;
387 +                }
388 +        }
389 +        
390 +        // fbdevices file completely read
391 +        fclose(fp);
392 +        
393 +        // Frame buffer name not found ? Then, display warning
394 +        if (!device_found) {
395 +                char str[256];
396 +                sprintf(str, GetString(STR_FBDEV_NAME_ERR), in_fb_name, max_depth);
397 +                ErrorAlert(str);
398 +                return false;
399 +        }
400 +        
401 +        int width = DisplayWidth(x_display, screen);
402 +        int height = DisplayHeight(x_display, screen);
403 +        depth = fb_depth; // max_depth
404 +        
405 +        // Set relative mouse mode
406 +        ADBSetRelMouseMode(false);
407 +        
408 +        // Create window
409 +        XSetWindowAttributes wattr;
410 +        wattr.override_redirect = True;
411 +        wattr.backing_store             = NotUseful;
412 +        wattr.background_pixel  = white_pixel;
413 +        wattr.border_pixel              = black_pixel;
414 +        wattr.event_mask                = eventmask = dga_eventmask;
415 +        
416 +        XSync(x_display, false);
417 +        the_win = XCreateWindow(x_display, rootwin,
418 +                0, 0, width, height,
419 +                0, xdepth, InputOutput, vis,
420 +                CWEventMask|CWBackPixel|CWBorderPixel|CWOverrideRedirect|CWBackingStore,
421 +                &wattr);
422 +        XSync(x_display, false);
423 +        XMapRaised(x_display, the_win);
424 +        XSync(x_display, false);
425 +        
426 +        // Grab mouse and keyboard
427 +        XGrabKeyboard(x_display, the_win, True,
428 +                GrabModeAsync, GrabModeAsync, CurrentTime);
429 +        XGrabPointer(x_display, the_win, True,
430 +                PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
431 +                GrabModeAsync, GrabModeAsync, the_win, None, CurrentTime);
432 +        
433 +        // Set colormap
434 +        if (depth == 8) {
435 +                XSetWindowColormap(x_display, the_win, cmap[0]);
436 +                XSetWMColormapWindows(x_display, the_win, &the_win, 1);
437 +        }
438 +        
439 +        // Set VideoMonitor
440 +        int bytes_per_row = width;
441 +        switch (depth) {
442 +                case 1:
443 +                        bytes_per_row = ((width | 7) & ~7) >> 3;
444 +                        break;
445 +                case 15:
446 +                case 16:
447 +                        bytes_per_row *= 2;
448 +                        break;
449 +                case 24:
450 +                case 32:
451 +                        bytes_per_row *= 4;
452 +                        break;
453 +        }
454 +        
455 +        if ((the_buffer = (uint8 *) mmap(NULL, height * bytes_per_row, PROT_READ | PROT_WRITE, MAP_PRIVATE, fbdev_fd, fb_offset)) == MAP_FAILED) {
456 +                if ((the_buffer = (uint8 *) mmap(NULL, height * bytes_per_row, PROT_READ | PROT_WRITE, MAP_SHARED, fbdev_fd, fb_offset)) == MAP_FAILED) {
457 +                        char str[256];
458 +                        sprintf(str, GetString(STR_FBDEV_MMAP_ERR), strerror(errno));
459 +                        ErrorAlert(str);
460 +                        return false;
461 +                }
462 +        }
463 +        
464 +        set_video_monitor(width, height, bytes_per_row, true);
465   #if REAL_ADDRESSING
466          VideoMonitor.mac_frame_base = (uint32)the_buffer;
467          MacFrameLayout = FLAYOUT_DIRECT;
# Line 319 | Line 469 | static bool init_window(int width, int h
469          VideoMonitor.mac_frame_base = MacFrameBaseMac;
470   #endif
471          return true;
472 + #else
473 +        ErrorAlert("Basilisk II has been compiled with fbdev DGA support disabled.");
474 +        return false;
475 + #endif
476   }
477  
478 < // Init DGA display
479 < static bool init_dga(int width, int height)
478 > // Init XF86 DGA display
479 > static bool init_xf86_dga(int width, int height)
480   {
481 < #if ENABLE_DGA
481 > #if ENABLE_XF86_DGA
482          // Set relative mouse mode
483          ADBSetRelMouseMode(true);
484  
# Line 385 | Line 539 | static bool init_dga(int width, int heig
539   #endif
540          return true;
541   #else
542 <        ErrorAlert("Basilisk II has been compiled with DGA support disabled.");
542 >        ErrorAlert("Basilisk II has been compiled with XF86 DGA support disabled.");
543          return false;
544   #endif
545   }
# Line 460 | Line 614 | bool VideoInit(bool classic)
614          // Init keycode translation
615          keycode_init();
616  
617 +        // Read prefs
618 +        mouse_wheel_mode = PrefsFindInt16("mousewheelmode");
619 +        mouse_wheel_lines = PrefsFindInt16("mousewheellines");
620 +
621          // Find screen and root window
622          screen = XDefaultScreen(x_display);
623          rootwin = XRootWindow(x_display, screen);
624 <
624 >        
625          // Get screen depth
626          xdepth = DefaultDepth(x_display, screen);
627 <
628 < #if ENABLE_DGA
627 >        
628 > #if ENABLE_FBDEV_DGA
629 >        // Frame buffer name
630 >        char fb_name[20];
631 >        
632 >        // Could do fbdev dga ?
633 >        if ((fbdev_fd = open(FBDEVICE_FILE_NAME, O_RDWR)) != -1)
634 >                has_dga = true;
635 >        else
636 >                has_dga = false;
637 > #endif
638 >        
639 > #if ENABLE_XF86_DGA
640          // DGA available?
641 <        int dga_flags = 0;
642 <        XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
643 <        has_dga = dga_flags & XF86DGADirectPresent;
641 >        int event_base, error_base;
642 >        if (XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
643 >                int dga_flags = 0;
644 >                XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
645 >                has_dga = dga_flags & XF86DGADirectPresent;
646 >        } else
647 >                has_dga = false;
648   #endif
649  
650          // Find black and white colors
# Line 539 | Line 712 | bool VideoInit(bool classic)
712          if (mode_str) {
713                  if (sscanf(mode_str, "win/%d/%d", &width, &height) == 2)
714                          display_type = DISPLAY_WINDOW;
715 <                else if (has_dga && strcmp(mode_str, "dga") == 0) {
715 > #if ENABLE_FBDEV_DGA
716 >                else if (has_dga && sscanf(mode_str, "dga/%19s", fb_name) == 1) {
717 > #else
718 >                else if (has_dga && sscanf(mode_str, "dga/%d/%d", &width, &height) == 2) {
719 > #endif
720                          display_type = DISPLAY_DGA;
721 +                        if (width > DisplayWidth(x_display, screen))
722 +                                width = DisplayWidth(x_display, screen);
723 +                        if (height > DisplayHeight(x_display, screen))
724 +                                height = DisplayHeight(x_display, screen);
725 +                }
726 +                if (width <= 0)
727                          width = DisplayWidth(x_display, screen);
728 +                if (height <= 0)
729                          height = DisplayHeight(x_display, screen);
546                }
730          }
731  
732          // Initialize according to display type
# Line 553 | Line 736 | bool VideoInit(bool classic)
736                                  return false;
737                          break;
738                  case DISPLAY_DGA:
739 <                        if (!init_dga(width, height))
739 > #if ENABLE_FBDEV_DGA
740 >                        if (!init_fbdev_dga(fb_name))
741 > #else
742 >                        if (!init_xf86_dga(width, height))
743 > #endif
744                                  return false;
745                          break;
746          }
# Line 603 | Line 790 | void VideoExit(void)
790          if (x_display != NULL) {
791                  XSync(x_display, false);
792  
793 < #if ENABLE_DGA
793 > #if ENABLE_XF86_DGA
794                  if (display_type == DISPLAY_DGA) {
795                          XF86DGADirectVideo(x_display, screen, 0);
796                          XUngrabPointer(x_display, CurrentTime);
# Line 611 | Line 798 | void VideoExit(void)
798                  }
799   #endif
800  
801 + #if ENABLE_FBDEV_DGA
802 +                if (display_type == DISPLAY_DGA) {
803 +                        XUngrabPointer(x_display, CurrentTime);
804 +                        XUngrabKeyboard(x_display, CurrentTime);
805 +                        close(fbdev_fd);
806 +                }
807 + #endif
808 +                
809                  if (the_buffer_copy) {
810                          free(the_buffer_copy);
811                          the_buffer_copy = NULL;
# Line 683 | Line 878 | void video_set_palette(uint8 *pal)
878   *  Suspend/resume emulator
879   */
880  
881 < #if ENABLE_DGA
881 > #if ENABLE_XF86_DGA || ENABLE_FBDEV_DGA
882   static void suspend_emul(void)
883   {
884          if (display_type == DISPLAY_DGA) {
# Line 700 | Line 895 | static void suspend_emul(void)
895                          memcpy(fb_save, the_buffer, VideoMonitor.y * VideoMonitor.bytes_per_row);
896  
897                  // Close full screen display
898 + #if ENABLE_XF86_DGA
899                  XF86DGADirectVideo(x_display, screen, 0);
900 + #endif
901                  XUngrabPointer(x_display, CurrentTime);
902                  XUngrabKeyboard(x_display, CurrentTime);
903                  XUnmapWindow(x_display, the_win);
# Line 714 | Line 911 | static void suspend_emul(void)
911                  wattr.backing_store = Always;
912                  wattr.backing_planes = xdepth;
913                  wattr.colormap = DefaultColormap(x_display, screen);
914 +                
915                  XSync(x_display, false);
916                  suspend_win = XCreateWindow(x_display, rootwin, 0, 0, 512, 1, 0, xdepth,
917                          InputOutput, vis, CWEventMask | CWBackPixel | CWBorderPixel |
# Line 738 | Line 936 | static void resume_emul(void)
936          XSync(x_display, false);
937          XGrabKeyboard(x_display, rootwin, 1, GrabModeAsync, GrabModeAsync, CurrentTime);
938          XGrabPointer(x_display, rootwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
939 + #if ENABLE_XF86_DGA
940          XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse);
941          XF86DGASetViewPort(x_display, screen, 0, 0);
942 + #endif
943          XSync(x_display, false);
944  
945          // Restore frame buffer
# Line 748 | Line 948 | static void resume_emul(void)
948                  free(fb_save);
949                  fb_save = NULL;
950          }
951 +        
952          if (depth == 8)
953 + #if ENABLE_XF86_DGA
954                  XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);
955 + #endif
956  
957          // Unlock frame buffer (and continue MacOS thread)
958          pthread_mutex_unlock(&frame_buffer_lock);
# Line 815 | Line 1018 | static int kc_decode(KeySym ks)
1018                  case XK_period: case XK_greater: return 0x2f;
1019                  case XK_slash: case XK_question: return 0x2c;
1020  
1021 < #if ENABLE_DGA
1021 > #if ENABLE_XF86_DGA || ENABLE_FBDEV_DGA
1022                  case XK_Tab: if (ctrl_down) {suspend_emul(); return -1;} else return 0x30;
1023   #else
1024                  case XK_Tab: return 0x30;
# Line 941 | Line 1144 | static void handle_events(void)
1144                                  unsigned int button = ((XButtonEvent *)&event)->button;
1145                                  if (button < 4)
1146                                          ADBMouseDown(button - 1);
1147 +                                else if (button < 6) {  // Wheel mouse
1148 +                                        if (mouse_wheel_mode == 0) {
1149 +                                                int key = (button == 5) ? 0x79 : 0x74;  // Page up/down
1150 +                                                ADBKeyDown(key);
1151 +                                                ADBKeyUp(key);
1152 +                                        } else {
1153 +                                                int key = (button == 5) ? 0x3d : 0x3e;  // Cursor up/down
1154 +                                                for(int i=0; i<mouse_wheel_lines; i++) {
1155 +                                                        ADBKeyDown(key);
1156 +                                                        ADBKeyUp(key);
1157 +                                                }
1158 +                                        }
1159 +                                }
1160                                  break;
1161                          }
1162                          case ButtonRelease: {
# Line 968 | Line 1184 | static void handle_events(void)
1184                                          code = event2keycode((XKeyEvent *)&event);
1185                                  if (code != -1) {
1186                                          if (!emul_suspended) {
1187 <                                                ADBKeyDown(code);
1187 >                                                if (code == 0x39) {     // Caps Lock pressed
1188 >                                                        if (caps_on) {
1189 >                                                                ADBKeyUp(code);
1190 >                                                                caps_on = false;
1191 >                                                        } else {
1192 >                                                                ADBKeyDown(code);
1193 >                                                                caps_on = true;
1194 >                                                        }
1195 >                                                } else
1196 >                                                        ADBKeyDown(code);
1197                                                  if (code == 0x36)
1198                                                          ctrl_down = true;
1199                                          } else {
1200 < #if ENABLE_DGA
1200 > #if ENABLE_XF86_DGA || ENABLE_FBDEV_DGA
1201                                                  if (code == 0x31)
1202                                                          resume_emul();  // Space wakes us up
1203   #endif
# Line 987 | Line 1212 | static void handle_events(void)
1212                                          code = keycode_table[((XKeyEvent *)&event)->keycode & 0xff];
1213                                  } else
1214                                          code = event2keycode((XKeyEvent *)&event);
1215 <                                if (code != -1) {
1215 >                                if (code != -1 && code != 0x39) {       // Don't propagate Caps Lock releases
1216                                          ADBKeyUp(code);
1217                                          if (code == 0x36)
1218                                                  ctrl_down = false;
# Line 1013 | Line 1238 | static void update_display(void)
1238   {
1239          // In classic mode, copy the frame buffer from Mac RAM
1240          if (classic_mode)
1241 <                memcpy(the_buffer, Mac2HostAddr(0x3fa700), VideoMonitor.bytes_per_row * VideoMonitor.y);
1242 <
1241 >                Mac2Host_memcpy(the_buffer, 0x3fa700, VideoMonitor.bytes_per_row * VideoMonitor.y);
1242 >        
1243          // Incremental update code
1244          int wide = 0, high = 0, x1, x2, y1, y2, i, j;
1245          int bytes_per_row = VideoMonitor.bytes_per_row;
# Line 1133 | Line 1358 | static void update_display(void)
1358  
1359                  // Set new cursor image if it was changed
1360                  if (memcmp(the_cursor, Mac2HostAddr(0x844), 64)) {
1361 <                        memcpy(the_cursor, Mac2HostAddr(0x844), 64);
1361 >                        Mac2Host_memcpy(the_cursor, 0x844, 64);
1362                          memcpy(cursor_image->data, the_cursor, 32);
1363                          memcpy(cursor_mask_image->data, the_cursor+32, 32);
1364                          XFreeCursor(x_display, mac_cursor);
# Line 1164 | Line 1389 | static void *redraw_func(void *arg)
1389                  usleep(16667);
1390   #endif
1391  
1392 < #if ENABLE_DGA
1392 > #if ENABLE_XF86_DGA
1393                  // Quit DGA mode if requested
1394                  if (quit_full_screen) {
1395                          quit_full_screen = false;
# Line 1178 | Line 1403 | static void *redraw_func(void *arg)
1403                  }
1404   #endif
1405  
1406 + #if ENABLE_FBDEV_DGA
1407 +                // Quit DGA mode if requested
1408 +                if (quit_full_screen) {
1409 +                        quit_full_screen = false;
1410 +                        if (display_type == DISPLAY_DGA) {
1411 +                                XUngrabPointer(x_display, CurrentTime);
1412 +                                XUngrabKeyboard(x_display, CurrentTime);
1413 +                                XUnmapWindow(x_display, the_win);
1414 +                                XSync(x_display, false);
1415 +                        }
1416 +                }
1417 + #endif
1418                  // Handle X events
1419                  handle_events();
1420  
# Line 1188 | Line 1425 | static void *redraw_func(void *arg)
1425                          if (depth == 8) {
1426                                  XStoreColors(x_display, cmap[0], palette, 256);
1427                                  XStoreColors(x_display, cmap[1], palette, 256);
1428 < #if ENABLE_DGA
1428 >                                
1429 > #if ENABLE_XF86_DGA
1430                                  if (display_type == DISPLAY_DGA) {
1431                                          current_dga_cmap ^= 1;
1432                                          XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines