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.8 by cebix, 1999-10-21T16:07:36Z

# 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
# Line 75 | Line 81 | static pthread_t redraw_thread;                                                //
81   static bool has_dga = false;                                            // Flag: Video DGA capable
82  
83   static bool ctrl_down = false;                                          // Flag: Ctrl key pressed
84 + static bool caps_on = false;                                            // Flag: Caps Lock on
85   static bool quit_full_screen = false;                           // Flag: DGA close requested from redraw thread
86   static bool emerg_quit = false;                                         // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread
87   static bool emul_suspended = false;                                     // Flag: Emulator suspended
# Line 114 | Line 121 | static uint8 *the_buffer_copy = NULL;
121   static uint8 the_cursor[64];                                            // Cursor image data
122   static bool have_shm = false;                                           // Flag: SHM extensions available
123  
124 < // Variables for DGA mode
124 > // Variables for XF86 DGA mode
125   static int current_dga_cmap;                                            // Number (0 or 1) of currently installed DGA colormap
126   static Window suspend_win;                                                      // "Suspend" window
127   static void *fb_save = NULL;                                            // Saved frame buffer for suspend
121
128   static pthread_mutex_t frame_buffer_lock = PTHREAD_MUTEX_INITIALIZER;   // Mutex to protect frame buffer
129  
130 + // Variables for fbdev DGA mode
131 + const char FBDEVICE_FILE_NAME[] = "/dev/fb";
132 + static int fbdev_fd;
133 +
134  
135   // Prototypes
136   static void *redraw_func(void *arg);
# Line 141 | Line 151 | extern void SysMountFirstFloppy(void);
151   // Set VideoMonitor according to video mode
152   void set_video_monitor(int width, int height, int bytes_per_row, bool native_byte_order)
153   {
154 <        int layout;
154 >        int layout = FLAYOUT_DIRECT;
155          switch (depth) {
156                  case 1:
157                          layout = FLAYOUT_DIRECT;
# Line 232 | Line 242 | static bool init_window(int width, int h
242                  XSetWMNormalHints(x_display, the_win, hints);
243                  XFree((char *)hints);
244          }
245 <
245 >        
246          // Try to create and attach SHM image
247          have_shm = false;
248          if (depth != 1 && XShmQueryExtension(x_display)) {
# Line 259 | Line 269 | static bool init_window(int width, int h
269                          shmctl(shminfo.shmid, IPC_RMID, 0);
270                  }
271          }
272 <
272 >        
273          // Create normal X image if SHM doesn't work ("height + 2" for safety)
274          if (!have_shm) {
275                  int bytes_per_row = width;
# Line 312 | Line 322 | static bool init_window(int width, int h
322   #else
323          set_video_monitor(width, height, img->bytes_per_line, img->bitmap_bit_order == LSBFirst);
324   #endif
325 +        
326   #if REAL_ADDRESSING
327          VideoMonitor.mac_frame_base = (uint32)the_buffer;
328          MacFrameLayout = FLAYOUT_DIRECT;
# Line 321 | Line 332 | static bool init_window(int width, int h
332          return true;
333   }
334  
335 < // Init DGA display
336 < static bool init_dga(int width, int height)
335 > // Init fbdev DGA display
336 > static bool init_fbdev_dga(char *in_fb_name)
337   {
338 < #if ENABLE_DGA
338 > #if ENABLE_FBDEV_DGA
339 >        // Find the maximum depth available
340 >        int ndepths, max_depth(0);
341 >        int *depths = XListDepths(x_display, screen, &ndepths);
342 >        if (depths == NULL) {
343 >                fprintf(stderr, "Error: could not determine the maximal depth available\n");
344 >                return false;
345 >        } else {
346 >                while (ndepths-- > 0) {
347 >                        if (depths[ndepths] > max_depth)
348 >                                max_depth = depths[ndepths];
349 >                }
350 >        }
351 >        
352 >        // Get fbdevices file path from preferences
353 >        const char *fbd_path = PrefsFindString("fbdevicefile");
354 >        
355 >        // Open fbdevices file
356 >        FILE *fp = fopen(fbd_path ? fbd_path : FBDEVICES_FILE_NAME, "r");
357 >        if (fp == NULL) {
358 >                char str[256];
359 >                sprintf(str, GetString(STR_NO_FBDEVICE_FILE_ERR), fbd_path ? fbd_path : FBDEVICES_FILE_NAME, strerror(errno));
360 >                ErrorAlert(str);
361 >                return false;
362 >        }
363 >        
364 >        int fb_depth;           // supported depth
365 >        uint32 fb_offset;       // offset used for mmap(2)
366 >        char fb_name[20];
367 >        char line[256];
368 >        bool device_found = false;
369 >        while (fgets(line, 255, fp)) {
370 >                // Read line
371 >                int len = strlen(line);
372 >                if (len == 0)
373 >                        continue;
374 >                line[len - 1] = '\0';
375 >                
376 >                // Comments begin with "#" or ";"
377 >                if ((line[0] == '#') || (line[0] == ';') || (line[0] == '\0'))
378 >                        continue;
379 >                
380 >                if ((sscanf(line, "%19s %d %x", &fb_name, &fb_depth, &fb_offset) == 3)
381 >                && (strcmp(fb_name, in_fb_name) == 0) && (fb_depth == max_depth)) {
382 >                        device_found = true;
383 >                        break;
384 >                }
385 >        }
386 >        
387 >        // fbdevices file completely read
388 >        fclose(fp);
389 >        
390 >        // Frame buffer name not found ? Then, display warning
391 >        if (!device_found) {
392 >                char str[256];
393 >                sprintf(str, GetString(STR_FBDEV_NAME_ERR), in_fb_name, max_depth);
394 >                ErrorAlert(str);
395 >                return false;
396 >        }
397 >        
398 >        int width = DisplayWidth(x_display, screen);
399 >        int height = DisplayHeight(x_display, screen);
400 >        depth = fb_depth; // max_depth
401 >        
402 >        // Set relative mouse mode
403 >        ADBSetRelMouseMode(false);
404 >        
405 >        // Create window
406 >        XSetWindowAttributes wattr;
407 >        wattr.override_redirect = True;
408 >        wattr.backing_store             = NotUseful;
409 >        wattr.background_pixel  = white_pixel;
410 >        wattr.border_pixel              = black_pixel;
411 >        wattr.event_mask                = eventmask = dga_eventmask;
412 >        
413 >        XSync(x_display, false);
414 >        the_win = XCreateWindow(x_display, rootwin,
415 >                0, 0, width, height,
416 >                0, xdepth, InputOutput, vis,
417 >                CWEventMask|CWBackPixel|CWBorderPixel|CWOverrideRedirect|CWBackingStore,
418 >                &wattr);
419 >        XSync(x_display, false);
420 >        XMapRaised(x_display, the_win);
421 >        XSync(x_display, false);
422 >        
423 >        // Grab mouse and keyboard
424 >        XGrabKeyboard(x_display, the_win, True,
425 >                GrabModeAsync, GrabModeAsync, CurrentTime);
426 >        XGrabPointer(x_display, the_win, True,
427 >                PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
428 >                GrabModeAsync, GrabModeAsync, the_win, None, CurrentTime);
429 >        
430 >        // Set colormap
431 >        if (depth == 8) {
432 >                XSetWindowColormap(x_display, the_win, cmap[current_dga_cmap = 0]);
433 >                XSetWMColormapWindows(x_display, the_win, &the_win, 1);
434 >        }
435 >        
436 >        // Set VideoMonitor
437 >        int bytes_per_row = width;
438 >        switch (depth) {
439 >                case 1:
440 >                        bytes_per_row = ((width | 7) & ~7) >> 3;
441 >                        break;
442 >                case 15:
443 >                case 16:
444 >                        bytes_per_row *= 2;
445 >                        break;
446 >                case 24:
447 >                case 32:
448 >                        bytes_per_row *= 4;
449 >                        break;
450 >        }
451 >        
452 >        if ((the_buffer = (uint8 *) mmap(NULL, height * bytes_per_row, PROT_READ | PROT_WRITE, MAP_PRIVATE, fbdev_fd, fb_offset)) == MAP_FAILED) {
453 >                if ((the_buffer = (uint8 *) mmap(NULL, height * bytes_per_row, PROT_READ | PROT_WRITE, MAP_SHARED, fbdev_fd, fb_offset)) == MAP_FAILED) {
454 >                        char str[256];
455 >                        sprintf(str, GetString(STR_FBDEV_MMAP_ERR), strerror(errno));
456 >                        ErrorAlert(str);
457 >                        return false;
458 >                }
459 >        }
460 >        
461 >        set_video_monitor(width, height, bytes_per_row, true);
462 > #if REAL_ADDRESSING
463 >        VideoMonitor.mac_frame_base = (uint32)the_buffer;
464 >        MacFrameLayout = FLAYOUT_DIRECT;
465 > #else
466 >        VideoMonitor.mac_frame_base = MacFrameBaseMac;
467 > #endif
468 >        
469 >        printf("FbDev DGA with %s in %d-bit mode enabled\n", fb_name, fb_depth);
470 >        return true;
471 > #else
472 >        ErrorAlert("Basilisk II has been compiled with fbdev DGA support disabled.");
473 >        return false;
474 > #endif
475 > }
476 >
477 > // Init XF86 DGA display
478 > static bool init_xf86_dga(int width, int height)
479 > {
480 > #if ENABLE_XF86_DGA
481          // Set relative mouse mode
482          ADBSetRelMouseMode(true);
483  
# Line 385 | Line 538 | static bool init_dga(int width, int heig
538   #endif
539          return true;
540   #else
541 <        ErrorAlert("Basilisk II has been compiled with DGA support disabled.");
541 >        ErrorAlert("Basilisk II has been compiled with XF86 DGA support disabled.");
542          return false;
543   #endif
544   }
# Line 463 | Line 616 | bool VideoInit(bool classic)
616          // Find screen and root window
617          screen = XDefaultScreen(x_display);
618          rootwin = XRootWindow(x_display, screen);
619 <
619 >        
620          // Get screen depth
621          xdepth = DefaultDepth(x_display, screen);
622 <
623 < #if ENABLE_DGA
622 >        
623 > #if ENABLE_FBDEV_DGA
624 >        // Frame buffer name
625 >        char fb_name[20];
626 >        
627 >        // Could do fbdev dga ?
628 >        if ((fbdev_fd = open(FBDEVICE_FILE_NAME, O_RDWR)) != -1)
629 >                has_dga = true;
630 >        else
631 >                has_dga = false;
632 > #endif
633 >        
634 > #if ENABLE_XF86_DGA
635          // DGA available?
636 <        int dga_flags = 0;
637 <        XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
638 <        has_dga = dga_flags & XF86DGADirectPresent;
636 >        int event_base, error_base;
637 >        if (XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
638 >                int dga_flags = 0;
639 >                XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
640 >                has_dga = dga_flags & XF86DGADirectPresent;
641 >        } else
642 >                has_dga = false;
643   #endif
644  
645          // Find black and white colors
# Line 539 | Line 707 | bool VideoInit(bool classic)
707          if (mode_str) {
708                  if (sscanf(mode_str, "win/%d/%d", &width, &height) == 2)
709                          display_type = DISPLAY_WINDOW;
710 <                else if (has_dga && strcmp(mode_str, "dga") == 0) {
710 > #if ENABLE_FBDEV_DGA
711 >                else if (has_dga && sscanf(mode_str, "dga/%19s", fb_name) == 1) {
712 > #else
713 >                else if (has_dga && sscanf(mode_str, "dga/%d/%d", &width, &height) == 2) {
714 > #endif
715                          display_type = DISPLAY_DGA;
716 +                        if (width > DisplayWidth(x_display, screen))
717 +                                width = DisplayWidth(x_display, screen);
718 +                        if (height > DisplayHeight(x_display, screen))
719 +                                height = DisplayHeight(x_display, screen);
720 +                }
721 +                if (width <= 0)
722                          width = DisplayWidth(x_display, screen);
723 +                if (height <= 0)
724                          height = DisplayHeight(x_display, screen);
546                }
725          }
726  
727          // Initialize according to display type
# Line 553 | Line 731 | bool VideoInit(bool classic)
731                                  return false;
732                          break;
733                  case DISPLAY_DGA:
734 <                        if (!init_dga(width, height))
734 > #if ENABLE_FBDEV_DGA
735 >                        if (!init_fbdev_dga(fb_name))
736 > #else
737 >                        if (!init_xf86_dga(width, height))
738 > #endif
739                                  return false;
740                          break;
741          }
# Line 603 | Line 785 | void VideoExit(void)
785          if (x_display != NULL) {
786                  XSync(x_display, false);
787  
788 < #if ENABLE_DGA
788 > #if ENABLE_XF86_DGA
789                  if (display_type == DISPLAY_DGA) {
790                          XF86DGADirectVideo(x_display, screen, 0);
791                          XUngrabPointer(x_display, CurrentTime);
# Line 611 | Line 793 | void VideoExit(void)
793                  }
794   #endif
795  
796 + #if ENABLE_FBDEV_DGA
797 +                if (display_type == DISPLAY_DGA) {
798 +                        XUngrabPointer(x_display, CurrentTime);
799 +                        XUngrabKeyboard(x_display, CurrentTime);
800 +                        close(fbdev_fd);
801 +                }
802 + #endif
803 +                
804                  if (the_buffer_copy) {
805                          free(the_buffer_copy);
806                          the_buffer_copy = NULL;
# Line 683 | Line 873 | void video_set_palette(uint8 *pal)
873   *  Suspend/resume emulator
874   */
875  
876 < #if ENABLE_DGA
876 > #if ENABLE_XF86_DGA || ENABLE_FBDEV_DGA
877   static void suspend_emul(void)
878   {
879          if (display_type == DISPLAY_DGA) {
# Line 700 | Line 890 | static void suspend_emul(void)
890                          memcpy(fb_save, the_buffer, VideoMonitor.y * VideoMonitor.bytes_per_row);
891  
892                  // Close full screen display
893 + #if ENABLE_XF86_DGA
894                  XF86DGADirectVideo(x_display, screen, 0);
895 + #endif
896                  XUngrabPointer(x_display, CurrentTime);
897                  XUngrabKeyboard(x_display, CurrentTime);
898                  XUnmapWindow(x_display, the_win);
# Line 714 | Line 906 | static void suspend_emul(void)
906                  wattr.backing_store = Always;
907                  wattr.backing_planes = xdepth;
908                  wattr.colormap = DefaultColormap(x_display, screen);
909 +                
910                  XSync(x_display, false);
911                  suspend_win = XCreateWindow(x_display, rootwin, 0, 0, 512, 1, 0, xdepth,
912                          InputOutput, vis, CWEventMask | CWBackPixel | CWBorderPixel |
# Line 738 | Line 931 | static void resume_emul(void)
931          XSync(x_display, false);
932          XGrabKeyboard(x_display, rootwin, 1, GrabModeAsync, GrabModeAsync, CurrentTime);
933          XGrabPointer(x_display, rootwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
934 + #if ENABLE_XF86_DGA
935          XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse);
936          XF86DGASetViewPort(x_display, screen, 0, 0);
937 + #endif
938          XSync(x_display, false);
939  
940          // Restore frame buffer
# Line 748 | Line 943 | static void resume_emul(void)
943                  free(fb_save);
944                  fb_save = NULL;
945          }
946 +        
947          if (depth == 8)
948 + #if ENABLE_XF86_DGA
949                  XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);
950 + #endif
951 + #if ENABLE_FBDEV_DGA
952 +                XSetWindowColormap(x_display, the_win, cmap[current_dga_cmap]);
953 + #endif
954  
955          // Unlock frame buffer (and continue MacOS thread)
956          pthread_mutex_unlock(&frame_buffer_lock);
# Line 815 | Line 1016 | static int kc_decode(KeySym ks)
1016                  case XK_period: case XK_greater: return 0x2f;
1017                  case XK_slash: case XK_question: return 0x2c;
1018  
1019 < #if ENABLE_DGA
1019 > #if ENABLE_XF86_DGA || ENABLE_FBDEV_DGA
1020                  case XK_Tab: if (ctrl_down) {suspend_emul(); return -1;} else return 0x30;
1021   #else
1022                  case XK_Tab: return 0x30;
# Line 968 | Line 1169 | static void handle_events(void)
1169                                          code = event2keycode((XKeyEvent *)&event);
1170                                  if (code != -1) {
1171                                          if (!emul_suspended) {
1172 <                                                ADBKeyDown(code);
1172 >                                                if (code == 0x39) {     // Caps Lock pressed
1173 >                                                        if (caps_on) {
1174 >                                                                ADBKeyUp(code);
1175 >                                                                caps_on = false;
1176 >                                                        } else {
1177 >                                                                ADBKeyDown(code);
1178 >                                                                caps_on = true;
1179 >                                                        }
1180 >                                                } else
1181 >                                                        ADBKeyDown(code);
1182                                                  if (code == 0x36)
1183                                                          ctrl_down = true;
1184                                          } else {
1185 < #if ENABLE_DGA
1185 > #if ENABLE_XF86_DGA || ENABLE_FBDEV_DGA
1186                                                  if (code == 0x31)
1187                                                          resume_emul();  // Space wakes us up
1188   #endif
# Line 987 | Line 1197 | static void handle_events(void)
1197                                          code = keycode_table[((XKeyEvent *)&event)->keycode & 0xff];
1198                                  } else
1199                                          code = event2keycode((XKeyEvent *)&event);
1200 <                                if (code != -1) {
1200 >                                if (code != -1 && code != 0x39) {       // Don't propagate Caps Lock releases
1201                                          ADBKeyUp(code);
1202                                          if (code == 0x36)
1203                                                  ctrl_down = false;
# Line 1014 | Line 1224 | static void update_display(void)
1224          // In classic mode, copy the frame buffer from Mac RAM
1225          if (classic_mode)
1226                  memcpy(the_buffer, Mac2HostAddr(0x3fa700), VideoMonitor.bytes_per_row * VideoMonitor.y);
1227 <
1227 >        
1228          // Incremental update code
1229          int wide = 0, high = 0, x1, x2, y1, y2, i, j;
1230          int bytes_per_row = VideoMonitor.bytes_per_row;
# Line 1164 | Line 1374 | static void *redraw_func(void *arg)
1374                  usleep(16667);
1375   #endif
1376  
1377 < #if ENABLE_DGA
1377 > #if ENABLE_XF86_DGA
1378                  // Quit DGA mode if requested
1379                  if (quit_full_screen) {
1380                          quit_full_screen = false;
# Line 1178 | Line 1388 | static void *redraw_func(void *arg)
1388                  }
1389   #endif
1390  
1391 + #if ENABLE_FBDEV_DGA
1392 +                // Quit DGA mode if requested
1393 +                if (quit_full_screen) {
1394 +                        quit_full_screen = false;
1395 +                        if (display_type == DISPLAY_DGA) {
1396 +                                XUngrabPointer(x_display, CurrentTime);
1397 +                                XUngrabKeyboard(x_display, CurrentTime);
1398 +                                XUnmapWindow(x_display, the_win);
1399 +                                XSync(x_display, false);
1400 +                        }
1401 +                }
1402 + #endif
1403                  // Handle X events
1404                  handle_events();
1405  
# Line 1188 | Line 1410 | static void *redraw_func(void *arg)
1410                          if (depth == 8) {
1411                                  XStoreColors(x_display, cmap[0], palette, 256);
1412                                  XStoreColors(x_display, cmap[1], palette, 256);
1413 < #if ENABLE_DGA
1413 >                                
1414 > #if ENABLE_XF86_DGA
1415                                  if (display_type == DISPLAY_DGA) {
1416                                          current_dga_cmap ^= 1;
1417                                          XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);
1418                                  }
1419   #endif
1420 +                                
1421 + #if ENABLE_FBDEV_DGA
1422 +                                if (display_type == DISPLAY_DGA)
1423 +                                        XSetWindowColormap(x_display, the_win, cmap[current_dga_cmap]);
1424 + #endif
1425                          }
1426                  }
1427                  pthread_mutex_unlock(&palette_lock);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines