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.6 by cebix, 1999-10-07T13:15:15Z vs.
Revision 1.7 by cebix, 1999-10-21T13:19:24Z

# 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
# Line 115 | 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
122
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 204 | Line 213 | static bool init_window(int width, int h
213          wattr.event_mask = eventmask = win_eventmask;
214          wattr.background_pixel = black_pixel;
215          wattr.border_pixel = black_pixel;
216 <        wattr.backing_store = NotUseful;
216 >        wattr.backing_store = Always;
217 >        wattr.backing_planes = xdepth;
218  
219          XSync(x_display, false);
220          the_win = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth,
221 <                InputOutput, vis, CWEventMask | CWBackPixel | CWBorderPixel | CWBackingStore, &wattr);
221 >                InputOutput, vis, CWEventMask | CWBackPixel | CWBorderPixel |
222 >                CWBackingStore | CWBackingPlanes, &wattr);
223          XSync(x_display, false);
224          XStoreName(x_display, the_win, GetString(STR_WINDOW_TITLE));
225          XMapRaised(x_display, the_win);
# Line 231 | 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 258 | 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 311 | 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;
329 + #else
330 +        VideoMonitor.mac_frame_base = MacFrameBaseMac;
331 + #endif
332 +        return true;
333 + }
334 +
335 + // Init fbdev DGA display
336 + static bool init_fbdev_dga(char *in_fb_name)
337 + {
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("fbdevices");
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, "%s %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 DGA display
478 < static bool init_dga(int width, int height)
477 > // Init XF86 DGA display
478 > static bool init_xf86_dga(int width, int height)
479   {
480 < #if ENABLE_DGA
480 > #if ENABLE_XF86_DGA
481          // Set relative mouse mode
482          ADBSetRelMouseMode(true);
483  
# Line 384 | 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 462 | 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 event_base, error_base;
637          if (XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
# Line 542 | 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 + #if ENABLE_FBDEV_DGA
711 +                else if (has_dga && sscanf(mode_str, "dga/%s", 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);
# Line 562 | 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 612 | 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 620 | 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 692 | 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 709 | 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 723 | 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 747 | 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 757 | 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 824 | 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 990 | Line 1182 | static void handle_events(void)
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 1032 | 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 1182 | 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 1196 | 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 1206 | 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