ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/video_x.cpp
(Generate patch)

Comparing SheepShaver/src/Unix/video_x.cpp (file contents):
Revision 1.39 by gbeauche, 2005-03-28T09:05:28Z vs.
Revision 1.43 by gbeauche, 2005-06-22T12:24:36Z

# Line 53 | Line 53
53   # include <X11/extensions/xf86vmode.h>
54   #endif
55  
56 + #ifdef ENABLE_FBDEV_DGA
57 + # include <sys/mman.h>
58 + #endif
59 +
60   #include "main.h"
61   #include "adb.h"
62   #include "prefs.h"
# Line 633 | Line 637 | static bool open_window(int width, int h
637          return true;
638   }
639  
640 < // Open FBDev display
641 < static bool open_fbdev(int width, int height)
640 > // Open FBDev DGA display
641 > static bool open_fbdev_dga(int width, int height)
642   {
643   #ifdef ENABLE_FBDEV_DGA
644 + #ifdef ENABLE_XF86_VIDMODE
645 +        // Switch to best mode
646 +        if (has_vidmode) {
647 +                int best = -1;
648 +                for (int i = 0; i < num_x_video_modes; i++) {
649 +                        if (x_video_modes[i]->hdisplay == width && x_video_modes[i]->vdisplay == height) {
650 +                                best = i;
651 +                                break;
652 +                        }
653 +                };
654 +                assert(best != -1);
655 +                XF86VidModeSwitchToMode(x_display, screen, x_video_modes[best]);
656 +                XF86VidModeSetViewPort(x_display, screen, 0, 0);
657 +                D(bug("[fbdev] VideoMode %d: %d x %d @ %d\n", best,
658 +                          x_video_modes[best]->hdisplay, x_video_modes[best]->vdisplay,
659 +                          1000 * x_video_modes[best]->dotclock / (x_video_modes[best]->htotal * x_video_modes[best]->vtotal)));
660 +        }
661 + #endif
662 +
663          if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo) != 0) {
664                  D(bug("[fbdev] Can't get FSCREENINFO: %s\n", strerror(errno)));
665                  return false;
666          }
667          D(bug("[fbdev] Device ID: %s\n", fb_finfo.id));
668          D(bug("[fbdev] smem_start: %p [%d bytes]\n", fb_finfo.smem_start, fb_finfo.smem_len));
669 +
670          int fb_type = fb_finfo.type;
671          const char *fb_type_str = NULL;
672          switch (fb_type) {
# Line 654 | Line 678 | static bool open_fbdev(int width, int he
678          default:                                                        fb_type_str = "<unknown>";                              break;
679          }
680          D(bug("[fbdev] type: %s\n", fb_type_str));
681 +
682 +        if (fb_type != FB_TYPE_PACKED_PIXELS) {
683 +                D(bug("[fbdev] type '%s' not supported\n", fb_type_str));
684 +                return false;
685 +        }
686 +
687          int fb_visual = fb_finfo.visual;
688          const char *fb_visual_str;
689          switch (fb_visual) {
# Line 667 | Line 697 | static bool open_fbdev(int width, int he
697          }
698          D(bug("[fbdev] visual: %s\n", fb_visual_str));
699  
700 <        if (fb_type != FB_TYPE_PACKED_PIXELS) {
701 <                D(bug("[fbdev] type %s not supported\n", fb_type_str));
700 >        if (fb_visual != FB_VISUAL_TRUECOLOR) {
701 >                D(bug("[fbdev] visual '%s' not supported\n", fb_visual_str));
702                  return false;
703          }
704          
# Line 686 | Line 716 | static bool open_fbdev(int width, int he
716          XSetWindowAttributes wattr;
717          wattr.event_mask = eventmask = dga_eventmask;
718          wattr.override_redirect = True;
689        wattr.colormap = (depth == 1 ? DefaultColormap(x_display, screen) : cmap[0]);
719          the_win = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth,
720 <                                                        InputOutput, vis, CWEventMask | CWOverrideRedirect |
721 <                                                        (color_class == DirectColor ? CWColormap : 0), &wattr);
720 >                                                        InputOutput, DefaultVisual(x_display, screen),
721 >                                                        CWEventMask | CWOverrideRedirect, &wattr);
722  
723          // Show window
724          XMapRaised(x_display, the_win);
# Line 700 | Line 729 | static bool open_fbdev(int width, int he
729                                    GrabModeAsync, GrabModeAsync, CurrentTime);
730          XGrabPointer(x_display, the_win, True,
731                                   PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
732 <                                 GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
732 >                                 GrabModeAsync, GrabModeAsync, the_win, None, CurrentTime);
733          disable_mouse_accel();
734  
735          // Create no_cursor
# Line 713 | Line 742 | static bool open_fbdev(int width, int he
742          // Init blitting routines
743          int bytes_per_row = TrivialBytesPerRow((width + 7) & ~7, DepthModeForPixelDepth(depth));
744   #if ENABLE_VOSF
745 <        bool native_byte_order;
746 < #ifdef WORDS_BIGENDIAN
747 <        native_byte_order = (XImageByteOrder(x_display) == MSBFirst);
748 < #else
749 <        native_byte_order = (XImageByteOrder(x_display) == LSBFirst);
750 < #endif
751 < #if REAL_ADDRESSING || DIRECT_ADDRESSING
745 >        // Extract current screen color masks (we are in True Color mode)
746 >        VisualFormat visualFormat;
747 >        visualFormat.depth = xdepth = DefaultDepth(x_display, screen);
748 >        XMatchVisualInfo(x_display, screen, xdepth, TrueColor, &visualInfo);
749 >        assert(visualFormat.depth == visualInfo.depth);
750 >        visualFormat.Rmask = visualInfo.red_mask;
751 >        visualFormat.Gmask = visualInfo.green_mask;
752 >        visualFormat.Bmask = visualInfo.blue_mask;
753 >        D(bug("[fbdev] %d bpp, (%08x,%08x,%08x)\n",
754 >                  visualFormat.depth,
755 >                  visualFormat.Rmask, visualFormat.Gmask, visualFormat.Bmask));
756 >        D(bug("[fbdev] Mac depth %d bpp\n", depth));
757 >
758          // Screen_blitter_init() returns TRUE if VOSF is mandatory
759          // i.e. the framebuffer update function is not Blit_Copy_Raw
760 <        use_vosf = Screen_blitter_init(visualFormat, native_byte_order, depth);
761 <        
727 <        if (use_vosf) {
728 <          // Allocate memory for frame buffer (SIZE is extended to page-boundary)
729 <          the_host_buffer = the_buffer;
730 <          the_buffer_size = page_extend((height + 2) * bytes_per_row);
731 <          the_buffer_copy = (uint8 *)malloc(the_buffer_size);
732 <          the_buffer = (uint8 *)vm_acquire(the_buffer_size);
733 <          D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
734 <        }
760 > #ifdef WORDS_BIGENDIAN
761 >        const bool native_byte_order = (XImageByteOrder(x_display) == MSBFirst);
762   #else
763 <        use_vosf = false;
763 >        const bool native_byte_order = (XImageByteOrder(x_display) == LSBFirst);
764   #endif
765 +        Screen_blitter_init(visualFormat, native_byte_order, depth);
766 +        
767 +        // Allocate memory for frame buffer (SIZE is extended to page-boundary)
768 +        use_vosf = true;
769 +        the_host_buffer = the_buffer;
770 +        the_buffer_size = page_extend((height + 2) * bytes_per_row);
771 +        the_buffer_copy = (uint8 *)malloc(the_buffer_size);
772 +        the_buffer = (uint8 *)vm_acquire(the_buffer_size);
773 +        D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
774   #endif
775  
776          // Set frame buffer base
# Line 748 | Line 784 | static bool open_fbdev(int width, int he
784   #endif
785   }
786  
787 < // Open DGA display (!! should use X11 VidMode extensions to set mode)
788 < static bool open_dga(int width, int height)
787 > // Open XF86 DGA display (!! should use X11 VidMode extensions to set mode)
788 > static bool open_xf86_dga(int width, int height)
789   {
790          if (is_fbdev_dga_mode)
791                  return false;
# Line 843 | Line 879 | static bool open_dga(int width, int heig
879   #endif
880   }
881  
882 + // Open DGA display
883 + static bool open_dga(int width, int height)
884 + {
885 +        bool display_open;
886 +
887 +        display_open = open_xf86_dga(width, height);
888 + #ifdef ENABLE_FBDEV_DGA
889 +        // Try to fallback to FBDev DGA mode
890 +        if (!display_open) {
891 +                is_fbdev_dga_mode = true;
892 +                display_open = open_fbdev_dga(width, height);
893 +        }
894 + #endif
895 +
896 +        // Common DGA display initialization
897 +        if (display_open) {
898 +
899 +                // Fake image to get display bounds in the refresh function
900 +                if ((img = (XImage *)malloc(sizeof(*img))) == NULL)
901 +                        return false;
902 +                img->width = DisplayWidth(x_display, screen);
903 +                img->height = DisplayHeight(x_display, screen);
904 +                img->depth = is_fbdev_dga_mode ? xdepth : depth;
905 +                img->bytes_per_line = TrivialBytesPerRow(img->width, DepthModeForPixelDepth(img->depth));
906 +        }
907 +
908 +        return display_open;
909 + }
910 +
911   static bool open_display(void)
912   {
913          D(bug("open_display()\n"));
# Line 858 | Line 923 | static bool open_display(void)
923          }
924  
925          // Build up visualFormat structure
926 +        visualFormat.fullscreen = (display_type == DIS_SCREEN);
927          visualFormat.depth = visualInfo.depth;
928          visualFormat.Rmask = visualInfo.red_mask;
929          visualFormat.Gmask = visualInfo.green_mask;
# Line 930 | Line 996 | static bool open_display(void)
996          display_type = mode.viType;
997          depth = depth_of_video_mode(mode.viAppleMode);
998  
999 <        bool display_open = false;
1000 <        if (display_type == DIS_SCREEN) {
999 >        bool display_open;
1000 >        switch (display_type) {
1001 >        case DIS_SCREEN:
1002                  display_open = open_dga(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
1003 < #ifdef ENABLE_FBDEV_DGA
1004 <                // Try to fallback to FBDev DGA mode
938 <                if (!display_open) {
939 <                        is_fbdev_dga_mode = true;
940 <                        display_open = open_fbdev(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
941 <                }
942 < #endif
943 <                
944 <        }
945 <        else if (display_type == DIS_WINDOW)
1003 >                break;
1004 >        case DIS_WINDOW:
1005                  display_open = open_window(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
1006 +                break;
1007 +        default:
1008 +                display_open = false;
1009 +                break;
1010 +        }
1011  
1012   #ifdef ENABLE_VOSF
1013          if (use_vosf) {
1014                  // Initialize the VOSF system
1015 +                LOCK_VOSF;
1016                  if (!video_vosf_init()) {
1017                          ErrorAlert(GetString(STR_VOSF_INIT_ERR));
1018 +                        UNLOCK_VOSF;
1019                          return false;
1020                  }
1021 +                UNLOCK_VOSF;
1022          }
1023   #endif
1024 <        
1024 >
1025 >        // Zero screen buffers, viRowBytes is initialized at this stage
1026 >        memset(the_buffer, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
1027 >        memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
1028          return display_open;
1029   }
1030  
# Line 991 | Line 1061 | static void close_window(void)
1061   }
1062  
1063   // Close FBDev mode
1064 < static void close_fbdev(void)
1064 > static void close_fbdev_dga(void)
1065   {
1066   #ifdef ENABLE_FBDEV_DGA
997        XUngrabPointer(x_display, CurrentTime);
998        XUngrabKeyboard(x_display, CurrentTime);
999
1067          uint8 *fb_base;
1068 <        if (!use_vosf) {
1002 <                // don't free() the screen buffer in driver_base dtor
1068 >        if (!use_vosf)
1069                  fb_base = the_buffer;
1004                the_buffer = NULL;
1005        }
1070   #ifdef ENABLE_VOSF
1071 <        else {
1008 <                // don't free() the screen buffer in driver_base dtor
1071 >        else
1072                  fb_base = the_host_buffer;
1010                the_host_buffer = NULL;
1011        }
1073   #endif
1074          munmap(fb_base, fb_finfo.smem_len);
1075   #endif
1076   }
1077  
1078 + // Close XF86 DGA mode
1079 + static void close_xf86_dga(void)
1080 + {
1081 + #ifdef ENABLE_XF86_DGA
1082 +        XF86DGADirectVideo(x_display, screen, 0);
1083 + #endif
1084 + }
1085 +
1086   // Close DGA mode
1087   static void close_dga(void)
1088   {
1089          if (is_fbdev_dga_mode)
1090 <                return;
1090 >                close_fbdev_dga();
1091 >        else
1092 >                close_xf86_dga();
1093  
1023 #ifdef ENABLE_XF86_DGA
1024        XF86DGADirectVideo(x_display, screen, 0);
1094          XUngrabPointer(x_display, CurrentTime);
1095          XUngrabKeyboard(x_display, CurrentTime);
1027 #endif
1096  
1097   #ifdef ENABLE_XF86_VIDMODE
1098          if (has_vidmode)
1099                  XF86VidModeSwitchToMode(x_display, screen, x_video_modes[0]);
1100   #endif
1101  
1102 +        // Release fake image (it's not a normal XImage!)
1103 +        free(img);
1104 +        img = NULL;
1105 +
1106          if (!use_vosf) {
1107                  // don't free() the screen buffer in driver_base dtor
1108                  the_buffer = NULL;
# Line 1045 | Line 1117 | static void close_dga(void)
1117  
1118   static void close_display(void)
1119   {
1120 <        if (display_type == DIS_SCREEN) {
1121 <                if (is_fbdev_dga_mode)
1050 <                        close_fbdev();
1051 <                else
1052 <                        close_dga();
1053 <        }
1120 >        if (display_type == DIS_SCREEN)
1121 >                close_dga();
1122          else if (display_type == DIS_WINDOW)
1123                  close_window();
1124  
# Line 1280 | Line 1348 | static void add_window_modes(VideoInfo *
1348   static bool has_mode(int x, int y)
1349   {
1350   #ifdef ENABLE_XF86_VIDMODE
1351 <        for (int i=0; i<num_x_video_modes; i++)
1352 <                if (x_video_modes[i]->hdisplay >= x && x_video_modes[i]->vdisplay >= y)
1353 <                        return true;
1354 <        return false;
1355 < #else
1356 <        return DisplayWidth(x_display, screen) >= x && DisplayHeight(x_display, screen) >= y;
1351 >        if (has_vidmode) {
1352 >                for (int i=0; i<num_x_video_modes; i++)
1353 >                        if (x_video_modes[i]->hdisplay == x && x_video_modes[i]->vdisplay == y)
1354 >                                return true;
1355 >                return false;
1356 >        }
1357   #endif
1358 +        return DisplayWidth(x_display, screen) >= x && DisplayHeight(x_display, screen) >= y;
1359   }
1360  
1361   bool VideoInit(void)
# Line 1353 | Line 1422 | bool VideoInit(void)
1422          // VidMode available?
1423          int vm_event_base, vm_error_base;
1424          has_vidmode = XF86VidModeQueryExtension(x_display, &vm_event_base, &vm_error_base);
1425 <        if (has_vidmode)
1425 >        if (has_vidmode) {
1426 >                int vm_major_version, vm_minor_version;
1427 >                XF86VidModeQueryVersion(x_display, &vm_major_version, &vm_minor_version);
1428 >                D(bug("VidMode extension %d.%d available\n", vm_major_version, vm_minor_version));
1429                  XF86VidModeGetAllModeLines(x_display, screen, &num_x_video_modes, &x_video_modes);
1430 +        }
1431   #endif
1432  
1433   #ifdef ENABLE_FBDEV_DGA
# Line 1458 | Line 1531 | bool VideoInit(void)
1531                                          add_custom_mode(p, display_type, default_width, default_height, d, APPLE_CUSTOM);
1532                                  }
1533                          }
1534 + #ifdef ENABLE_VOSF
1535 +                } else if (display_type == DIS_SCREEN && is_fbdev_dga_mode) {
1536 +                        for (unsigned int d = APPLE_1_BIT; d <= default_mode; d++)
1537 +                                if (find_visual_for_depth(d))
1538 +                                        add_custom_mode(p, display_type, default_width, default_height, d, APPLE_CUSTOM);
1539 + #endif
1540                  } else
1541                          add_custom_mode(p, display_type, default_width, default_height, default_mode, APPLE_CUSTOM);
1542 +
1543 +                // Add extra VidMode capable modes
1544 +                if (display_type == DIS_SCREEN) {
1545 +                        struct {
1546 +                                int w;
1547 +                                int h;
1548 +                                int apple_id;
1549 +                        }
1550 +                        video_modes[] = {
1551 +                                {  640,  480, APPLE_640x480   },
1552 +                                {  800,  600, APPLE_800x600   },
1553 +                                { 1024,  768, APPLE_1024x768  },
1554 +                                { 1152,  768, APPLE_1152x768  },
1555 +                                { 1152,  900, APPLE_1152x900  },
1556 +                                { 1280, 1024, APPLE_1280x1024 },
1557 +                                { 1600, 1200, APPLE_1600x1200 },
1558 +                                { 0, }
1559 +                        };
1560 +
1561 +                        for (int i = 0; video_modes[i].w != 0; i++) {
1562 +                                const int w = video_modes[i].w;
1563 +                                const int h = video_modes[i].h;
1564 +                                if (w >= default_width || h >= default_height)
1565 +                                        continue;
1566 +                                if (has_mode(w, h)) {
1567 + #ifdef ENABLE_VOSF
1568 +                                        if (is_fbdev_dga_mode) {
1569 +                                                for (unsigned int d = APPLE_1_BIT; d <= default_mode; d++)
1570 +                                                        if (find_visual_for_depth(d))
1571 +                                                                add_custom_mode(p, display_type, w, h, d, video_modes[i].apple_id);
1572 +                                        } else
1573 + #endif
1574 +                                                add_custom_mode(p, display_type, w, h, default_mode, video_modes[i].apple_id);
1575 +                                }
1576 +                        }
1577 +                }
1578          } else if (window_modes) {
1579                  for (unsigned int d = APPLE_1_BIT; d <= APPLE_32_BIT; d++)
1580                          if (find_visual_for_depth(d))
# Line 1655 | Line 1770 | static void resume_emul(void)
1770          XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0);
1771          Window w = is_fbdev_dga_mode ? the_win : rootwin;
1772          XGrabKeyboard(x_display, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
1773 <        XGrabPointer(x_display, w, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
1773 >        XGrabPointer(x_display, w, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, is_fbdev_dga_mode ? w : None, None, CurrentTime);
1774          disable_mouse_accel();
1775   #ifdef ENABLE_XF86_DGA
1776          if (!is_fbdev_dga_mode) {
# Line 1672 | Line 1787 | static void resume_emul(void)
1787          if (use_vosf) {
1788                  LOCK_VOSF;
1789                  PFLAG_SET_ALL;
1675                UNLOCK_VOSF;
1790                  memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
1791 +                UNLOCK_VOSF;
1792          }
1793   #endif
1794          
# Line 1987 | Line 2102 | static void handle_events(void)
2102                                  if (use_vosf) {                 // VOSF refresh
2103                                          LOCK_VOSF;
2104                                          PFLAG_SET_ALL;
2105 +                                        memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
2106                                          UNLOCK_VOSF;
2107                                  }
2108 +                                else
2109   #endif
2110 <                                memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
2110 >                                        memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
2111                                  break;
2112                  }
2113          }
# Line 2107 | Line 2224 | void video_set_palette(void)
2224                  // We have to redraw everything because the interpretation of pixel values changed
2225                  LOCK_VOSF;
2226                  PFLAG_SET_ALL;
2227 +                if (display_type == DIS_SCREEN)
2228 +                        PFLAG_SET_VERY_DIRTY;
2229                  UNLOCK_VOSF;
2111                memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
2230          }
2231   #endif
2232  
# Line 2337 | Line 2455 | static void *redraw_func(void *arg)
2455                                          XDisplayLock();
2456   #if defined(ENABLE_XF86_DGA) || defined(ENABLE_FBDEV_DGA)
2457   #ifdef ENABLE_XF86_DGA
2458 <                                        if (is_fbdev_dga_mode)
2458 >                                        if (!is_fbdev_dga_mode)
2459                                                  XF86DGADirectVideo(x_display, screen, 0);
2460   #endif
2461                                          XUngrabPointer(x_display, CurrentTime);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines