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.1 by cebix, 1999-10-03T14:16:25Z vs.
Revision 1.9 by cebix, 1999-10-21T16:40:49Z

# 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[] = "/usr/local/lib/basilisk_ii_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 >                printf("FATAL: 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[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 >        return true;
469 > #else
470 >        ErrorAlert("Basilisk II has been compiled with fbdev DGA support disabled.");
471 >        return false;
472 > #endif
473 > }
474 >
475 > // Init XF86 DGA display
476 > static bool init_xf86_dga(int width, int height)
477 > {
478 > #if ENABLE_XF86_DGA
479          // Set relative mouse mode
480          ADBSetRelMouseMode(true);
481  
# Line 385 | Line 536 | static bool init_dga(int width, int heig
536   #endif
537          return true;
538   #else
539 <        ErrorAlert("Basilisk II has been compiled with DGA support disabled.");
539 >        ErrorAlert("Basilisk II has been compiled with XF86 DGA support disabled.");
540          return false;
541   #endif
542   }
# Line 463 | Line 614 | bool VideoInit(bool classic)
614          // Find screen and root window
615          screen = XDefaultScreen(x_display);
616          rootwin = XRootWindow(x_display, screen);
617 <
617 >        
618          // Get screen depth
619          xdepth = DefaultDepth(x_display, screen);
620 <
621 < #if ENABLE_DGA
620 >        
621 > #if ENABLE_FBDEV_DGA
622 >        // Frame buffer name
623 >        char fb_name[20];
624 >        
625 >        // Could do fbdev dga ?
626 >        if ((fbdev_fd = open(FBDEVICE_FILE_NAME, O_RDWR)) != -1)
627 >                has_dga = true;
628 >        else
629 >                has_dga = false;
630 > #endif
631 >        
632 > #if ENABLE_XF86_DGA
633          // DGA available?
634 <        int dga_flags = 0;
635 <        XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
636 <        has_dga = dga_flags & XF86DGADirectPresent;
634 >        int event_base, error_base;
635 >        if (XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
636 >                int dga_flags = 0;
637 >                XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
638 >                has_dga = dga_flags & XF86DGADirectPresent;
639 >        } else
640 >                has_dga = false;
641   #endif
642  
643          // Find black and white colors
# Line 539 | Line 705 | bool VideoInit(bool classic)
705          if (mode_str) {
706                  if (sscanf(mode_str, "win/%d/%d", &width, &height) == 2)
707                          display_type = DISPLAY_WINDOW;
708 <                else if (has_dga && strcmp(mode_str, "dga") == 0) {
708 > #if ENABLE_FBDEV_DGA
709 >                else if (has_dga && sscanf(mode_str, "dga/%19s", fb_name) == 1) {
710 > #else
711 >                else if (has_dga && sscanf(mode_str, "dga/%d/%d", &width, &height) == 2) {
712 > #endif
713                          display_type = DISPLAY_DGA;
714 +                        if (width > DisplayWidth(x_display, screen))
715 +                                width = DisplayWidth(x_display, screen);
716 +                        if (height > DisplayHeight(x_display, screen))
717 +                                height = DisplayHeight(x_display, screen);
718 +                }
719 +                if (width <= 0)
720                          width = DisplayWidth(x_display, screen);
721 +                if (height <= 0)
722                          height = DisplayHeight(x_display, screen);
546                }
723          }
724  
725          // Initialize according to display type
# Line 553 | Line 729 | bool VideoInit(bool classic)
729                                  return false;
730                          break;
731                  case DISPLAY_DGA:
732 <                        if (!init_dga(width, height))
732 > #if ENABLE_FBDEV_DGA
733 >                        if (!init_fbdev_dga(fb_name))
734 > #else
735 >                        if (!init_xf86_dga(width, height))
736 > #endif
737                                  return false;
738                          break;
739          }
# Line 603 | Line 783 | void VideoExit(void)
783          if (x_display != NULL) {
784                  XSync(x_display, false);
785  
786 < #if ENABLE_DGA
786 > #if ENABLE_XF86_DGA
787                  if (display_type == DISPLAY_DGA) {
788                          XF86DGADirectVideo(x_display, screen, 0);
789                          XUngrabPointer(x_display, CurrentTime);
# Line 611 | Line 791 | void VideoExit(void)
791                  }
792   #endif
793  
794 + #if ENABLE_FBDEV_DGA
795 +                if (display_type == DISPLAY_DGA) {
796 +                        XUngrabPointer(x_display, CurrentTime);
797 +                        XUngrabKeyboard(x_display, CurrentTime);
798 +                        close(fbdev_fd);
799 +                }
800 + #endif
801 +                
802                  if (the_buffer_copy) {
803                          free(the_buffer_copy);
804                          the_buffer_copy = NULL;
# Line 683 | Line 871 | void video_set_palette(uint8 *pal)
871   *  Suspend/resume emulator
872   */
873  
874 < #if ENABLE_DGA
874 > #if ENABLE_XF86_DGA || ENABLE_FBDEV_DGA
875   static void suspend_emul(void)
876   {
877          if (display_type == DISPLAY_DGA) {
# Line 700 | Line 888 | static void suspend_emul(void)
888                          memcpy(fb_save, the_buffer, VideoMonitor.y * VideoMonitor.bytes_per_row);
889  
890                  // Close full screen display
891 + #if ENABLE_XF86_DGA
892                  XF86DGADirectVideo(x_display, screen, 0);
893 + #endif
894                  XUngrabPointer(x_display, CurrentTime);
895                  XUngrabKeyboard(x_display, CurrentTime);
896                  XUnmapWindow(x_display, the_win);
# Line 714 | Line 904 | static void suspend_emul(void)
904                  wattr.backing_store = Always;
905                  wattr.backing_planes = xdepth;
906                  wattr.colormap = DefaultColormap(x_display, screen);
907 +                
908                  XSync(x_display, false);
909                  suspend_win = XCreateWindow(x_display, rootwin, 0, 0, 512, 1, 0, xdepth,
910                          InputOutput, vis, CWEventMask | CWBackPixel | CWBorderPixel |
# Line 738 | Line 929 | static void resume_emul(void)
929          XSync(x_display, false);
930          XGrabKeyboard(x_display, rootwin, 1, GrabModeAsync, GrabModeAsync, CurrentTime);
931          XGrabPointer(x_display, rootwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
932 + #if ENABLE_XF86_DGA
933          XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse);
934          XF86DGASetViewPort(x_display, screen, 0, 0);
935 + #endif
936          XSync(x_display, false);
937  
938          // Restore frame buffer
# Line 748 | Line 941 | static void resume_emul(void)
941                  free(fb_save);
942                  fb_save = NULL;
943          }
944 +        
945          if (depth == 8)
946 + #if ENABLE_XF86_DGA
947                  XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);
948 + #endif
949  
950          // Unlock frame buffer (and continue MacOS thread)
951          pthread_mutex_unlock(&frame_buffer_lock);
# Line 815 | Line 1011 | static int kc_decode(KeySym ks)
1011                  case XK_period: case XK_greater: return 0x2f;
1012                  case XK_slash: case XK_question: return 0x2c;
1013  
1014 < #if ENABLE_DGA
1014 > #if ENABLE_XF86_DGA || ENABLE_FBDEV_DGA
1015                  case XK_Tab: if (ctrl_down) {suspend_emul(); return -1;} else return 0x30;
1016   #else
1017                  case XK_Tab: return 0x30;
# Line 968 | Line 1164 | static void handle_events(void)
1164                                          code = event2keycode((XKeyEvent *)&event);
1165                                  if (code != -1) {
1166                                          if (!emul_suspended) {
1167 <                                                ADBKeyDown(code);
1167 >                                                if (code == 0x39) {     // Caps Lock pressed
1168 >                                                        if (caps_on) {
1169 >                                                                ADBKeyUp(code);
1170 >                                                                caps_on = false;
1171 >                                                        } else {
1172 >                                                                ADBKeyDown(code);
1173 >                                                                caps_on = true;
1174 >                                                        }
1175 >                                                } else
1176 >                                                        ADBKeyDown(code);
1177                                                  if (code == 0x36)
1178                                                          ctrl_down = true;
1179                                          } else {
1180 < #if ENABLE_DGA
1180 > #if ENABLE_XF86_DGA || ENABLE_FBDEV_DGA
1181                                                  if (code == 0x31)
1182                                                          resume_emul();  // Space wakes us up
1183   #endif
# Line 987 | Line 1192 | static void handle_events(void)
1192                                          code = keycode_table[((XKeyEvent *)&event)->keycode & 0xff];
1193                                  } else
1194                                          code = event2keycode((XKeyEvent *)&event);
1195 <                                if (code != -1) {
1195 >                                if (code != -1 && code != 0x39) {       // Don't propagate Caps Lock releases
1196                                          ADBKeyUp(code);
1197                                          if (code == 0x36)
1198                                                  ctrl_down = false;
# Line 1014 | Line 1219 | static void update_display(void)
1219          // In classic mode, copy the frame buffer from Mac RAM
1220          if (classic_mode)
1221                  memcpy(the_buffer, Mac2HostAddr(0x3fa700), VideoMonitor.bytes_per_row * VideoMonitor.y);
1222 <
1222 >        
1223          // Incremental update code
1224          int wide = 0, high = 0, x1, x2, y1, y2, i, j;
1225          int bytes_per_row = VideoMonitor.bytes_per_row;
# Line 1164 | Line 1369 | static void *redraw_func(void *arg)
1369                  usleep(16667);
1370   #endif
1371  
1372 < #if ENABLE_DGA
1372 > #if ENABLE_XF86_DGA
1373                  // Quit DGA mode if requested
1374                  if (quit_full_screen) {
1375                          quit_full_screen = false;
# Line 1178 | Line 1383 | static void *redraw_func(void *arg)
1383                  }
1384   #endif
1385  
1386 + #if ENABLE_FBDEV_DGA
1387 +                // Quit DGA mode if requested
1388 +                if (quit_full_screen) {
1389 +                        quit_full_screen = false;
1390 +                        if (display_type == DISPLAY_DGA) {
1391 +                                XUngrabPointer(x_display, CurrentTime);
1392 +                                XUngrabKeyboard(x_display, CurrentTime);
1393 +                                XUnmapWindow(x_display, the_win);
1394 +                                XSync(x_display, false);
1395 +                        }
1396 +                }
1397 + #endif
1398                  // Handle X events
1399                  handle_events();
1400  
# Line 1188 | Line 1405 | static void *redraw_func(void *arg)
1405                          if (depth == 8) {
1406                                  XStoreColors(x_display, cmap[0], palette, 256);
1407                                  XStoreColors(x_display, cmap[1], palette, 256);
1408 < #if ENABLE_DGA
1408 >                                
1409 > #if ENABLE_XF86_DGA
1410                                  if (display_type == DISPLAY_DGA) {
1411                                          current_dga_cmap ^= 1;
1412                                          XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines