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.3 by cebix, 1999-10-03T19:43:28Z 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[] = SHAREDIR "/keycodes";
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 142 | 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 233 | 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 260 | 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 313 | 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 +                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;
# Line 320 | Line 466 | static bool init_window(int width, int h
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 DGA display
476 < static bool init_dga(int width, int height)
475 > // Init XF86 DGA display
476 > static bool init_xf86_dga(int width, int height)
477   {
478 < #if ENABLE_DGA
478 > #if ENABLE_XF86_DGA
479          // Set relative mouse mode
480          ADBSetRelMouseMode(true);
481  
# Line 386 | 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 464 | 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 540 | 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 + #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);
# Line 560 | 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 610 | 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 618 | 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 690 | 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 707 | 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 721 | 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 745 | 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 755 | 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 822 | 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 988 | Line 1177 | static void handle_events(void)
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 1030 | 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 1180 | 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 1194 | 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 1204 | 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