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.4 by cebix, 1999-10-04T21:07:18Z vs.
Revision 1.10 by cebix, 1999-10-25T20:22:35Z

# 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 62 | Line 67 | enum {
67  
68   // Constants
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 115 | 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
122
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 142 | 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 233 | 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 260 | 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 313 | 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;
# Line 322 | Line 335 | static bool init_window(int width, int h
335          return true;
336   }
337  
338 < // Init DGA display
339 < static bool init_dga(int width, int height)
338 > // Init fbdev DGA display
339 > static bool init_fbdev_dga(char *in_fb_name)
340   {
341 < #if ENABLE_DGA
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;
468 > #else
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 XF86 DGA display
479 > static bool init_xf86_dga(int width, int height)
480 > {
481 > #if ENABLE_XF86_DGA
482          // Set relative mouse mode
483          ADBSetRelMouseMode(true);
484  
# Line 386 | 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 461 | 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 540 | 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 + #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);
# Line 560 | 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 610 | 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 618 | 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 690 | 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 707 | 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 721 | 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 745 | 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 755 | 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 822 | 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 948 | 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 988 | Line 1197 | static void handle_events(void)
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 1030 | Line 1239 | static void update_display(void)
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 <
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 1180 | 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 1194 | 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 1204 | 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