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.40 by gbeauche, 2005-03-28T16:19:28Z vs.
Revision 1.47 by gbeauche, 2006-05-13T17:12:18Z

# 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 164 | Line 168 | static int num_x_video_modes;
168   #endif
169  
170   // Mutex to protect palette
171 < #ifdef HAVE_SPINLOCKS
168 < static spinlock_t x_palette_lock = SPIN_LOCK_UNLOCKED;
169 < #define LOCK_PALETTE spin_lock(&x_palette_lock)
170 < #define UNLOCK_PALETTE spin_unlock(&x_palette_lock)
171 < #elif defined(HAVE_PTHREADS)
171 > #if defined(HAVE_PTHREADS)
172   static pthread_mutex_t x_palette_lock = PTHREAD_MUTEX_INITIALIZER;
173   #define LOCK_PALETTE pthread_mutex_lock(&x_palette_lock)
174   #define UNLOCK_PALETTE pthread_mutex_unlock(&x_palette_lock)
175 + #elif defined(HAVE_SPINLOCKS)
176 + static spinlock_t x_palette_lock = SPIN_LOCK_UNLOCKED;
177 + #define LOCK_PALETTE spin_lock(&x_palette_lock)
178 + #define UNLOCK_PALETTE spin_unlock(&x_palette_lock)
179   #else
180   #define LOCK_PALETTE
181   #define UNLOCK_PALETTE
182   #endif
183  
184   // Mutex to protect frame buffer
185 < #ifdef HAVE_SPINLOCKS
182 < static spinlock_t frame_buffer_lock = SPIN_LOCK_UNLOCKED;
183 < #define LOCK_FRAME_BUFFER spin_lock(&frame_buffer_lock)
184 < #define UNLOCK_FRAME_BUFFER spin_unlock(&frame_buffer_lock)
185 < #elif defined(HAVE_PTHREADS)
185 > #if defined(HAVE_PTHREADS)
186   static pthread_mutex_t frame_buffer_lock = PTHREAD_MUTEX_INITIALIZER;
187   #define LOCK_FRAME_BUFFER pthread_mutex_lock(&frame_buffer_lock);
188   #define UNLOCK_FRAME_BUFFER pthread_mutex_unlock(&frame_buffer_lock);
189 + #elif defined(HAVE_SPINLOCKS)
190 + static spinlock_t frame_buffer_lock = SPIN_LOCK_UNLOCKED;
191 + #define LOCK_FRAME_BUFFER spin_lock(&frame_buffer_lock)
192 + #define UNLOCK_FRAME_BUFFER spin_unlock(&frame_buffer_lock)
193   #else
194   #define LOCK_FRAME_BUFFER
195   #define UNLOCK_FRAME_BUFFER
# Line 577 | Line 581 | static bool open_window(int width, int h
581          use_vosf = true;
582          // Allocate memory for frame buffer (SIZE is extended to page-boundary)
583          the_host_buffer = the_buffer_copy;
584 <        the_buffer_size = page_extend((aligned_height + 2) * (the_host_buffer_row_bytes = img->bytes_per_line));
584 >        the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line);
585          the_buffer = (uint8 *)vm_acquire(the_buffer_size);
586          the_buffer_copy = (uint8 *)malloc(the_buffer_size);
587          D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
# 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;
# Line 674 | 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_visual != FB_VISUAL_TRUECOLOR) {
700 >        if (fb_visual != FB_VISUAL_TRUECOLOR && fb_visual != FB_VISUAL_DIRECTCOLOR) {
701                  D(bug("[fbdev] visual '%s' not supported\n", fb_visual_str));
702                  return false;
703          }
# Line 706 | 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 717 | Line 740 | static bool open_fbdev(int width, int he
740          XDefineCursor(x_display, the_win, mac_cursor);
741  
742          // Init blitting routines
743 +        int bytes_per_row = TrivialBytesPerRow((width + 7) & ~7, DepthModeForPixelDepth(depth));
744   #if ENABLE_VOSF
745          // Extract current screen color masks (we are in True Color mode)
746          VisualFormat visualFormat;
# Line 741 | Line 765 | static bool open_fbdev(int width, int he
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_host_buffer_row_bytes = TrivialBytesPerRow((width + 7) & ~7, DepthModeForPixelDepth(visualFormat.depth));
746 <        the_buffer_size = page_extend((height + 2) * the_host_buffer_row_bytes);
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));
# Line 752 | Line 776 | static bool open_fbdev(int width, int he
776          // Set frame buffer base
777          D(bug("the_buffer = %p, use_vosf = %d\n", the_buffer, use_vosf));
778          screen_base = Host2MacAddr(the_buffer);
779 <        VModes[cur_mode].viRowBytes = TrivialBytesPerRow((width + 7) & ~7, DepthModeForPixelDepth(depth));
779 >        VModes[cur_mode].viRowBytes = bytes_per_row;
780          return true;
781   #else
782          ErrorAlert("SheepShaver has been compiled with DGA support disabled.");
# Line 760 | 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 834 | Line 858 | static bool open_dga(int width, int heig
858          if (use_vosf) {
859            // Allocate memory for frame buffer (SIZE is extended to page-boundary)
860            the_host_buffer = the_buffer;
861 <          the_buffer_size = page_extend((height + 2) * (the_host_buffer_row_bytes = bytes_per_row));
861 >          the_buffer_size = page_extend((height + 2) * bytes_per_row);
862            the_buffer_copy = (uint8 *)malloc(the_buffer_size);
863            the_buffer = (uint8 *)vm_acquire(the_buffer_size);
864            D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
# Line 855 | 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 943 | 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
951 <                if (!display_open) {
952 <                        is_fbdev_dga_mode = true;
953 <                        display_open = open_fbdev(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
954 <                }
955 < #endif
956 <                
957 <        }
958 <        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 >        if (display_open) {
1027 >                memset(the_buffer, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
1028 >                memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
1029 >        }
1030          return display_open;
1031   }
1032  
# Line 1004 | Line 1063 | static void close_window(void)
1063   }
1064  
1065   // Close FBDev mode
1066 < static void close_fbdev(void)
1066 > static void close_fbdev_dga(void)
1067   {
1068   #ifdef ENABLE_FBDEV_DGA
1010        XUngrabPointer(x_display, CurrentTime);
1011        XUngrabKeyboard(x_display, CurrentTime);
1012
1069          uint8 *fb_base;
1070 <        if (!use_vosf) {
1015 <                // don't free() the screen buffer in driver_base dtor
1070 >        if (!use_vosf)
1071                  fb_base = the_buffer;
1017                the_buffer = NULL;
1018        }
1072   #ifdef ENABLE_VOSF
1073 <        else {
1021 <                // don't free() the screen buffer in driver_base dtor
1073 >        else
1074                  fb_base = the_host_buffer;
1023                the_host_buffer = NULL;
1024        }
1075   #endif
1076          munmap(fb_base, fb_finfo.smem_len);
1077   #endif
1078   }
1079  
1080 + // Close XF86 DGA mode
1081 + static void close_xf86_dga(void)
1082 + {
1083 + #ifdef ENABLE_XF86_DGA
1084 +        XF86DGADirectVideo(x_display, screen, 0);
1085 + #endif
1086 + }
1087 +
1088   // Close DGA mode
1089   static void close_dga(void)
1090   {
1091          if (is_fbdev_dga_mode)
1092 <                return;
1092 >                close_fbdev_dga();
1093 >        else
1094 >                close_xf86_dga();
1095  
1036 #ifdef ENABLE_XF86_DGA
1037        XF86DGADirectVideo(x_display, screen, 0);
1096          XUngrabPointer(x_display, CurrentTime);
1097          XUngrabKeyboard(x_display, CurrentTime);
1040 #endif
1098  
1099   #ifdef ENABLE_XF86_VIDMODE
1100          if (has_vidmode)
1101                  XF86VidModeSwitchToMode(x_display, screen, x_video_modes[0]);
1102   #endif
1103  
1104 +        // Release fake image (it's not a normal XImage!)
1105 +        free(img);
1106 +        img = NULL;
1107 +
1108          if (!use_vosf) {
1109                  // don't free() the screen buffer in driver_base dtor
1110                  the_buffer = NULL;
# Line 1058 | Line 1119 | static void close_dga(void)
1119  
1120   static void close_display(void)
1121   {
1122 <        if (display_type == DIS_SCREEN) {
1123 <                if (is_fbdev_dga_mode)
1063 <                        close_fbdev();
1064 <                else
1065 <                        close_dga();
1066 <        }
1122 >        if (display_type == DIS_SCREEN)
1123 >                close_dga();
1124          else if (display_type == DIS_WINDOW)
1125                  close_window();
1126  
# Line 1293 | Line 1350 | static void add_window_modes(VideoInfo *
1350   static bool has_mode(int x, int y)
1351   {
1352   #ifdef ENABLE_XF86_VIDMODE
1353 <        for (int i=0; i<num_x_video_modes; i++)
1354 <                if (x_video_modes[i]->hdisplay >= x && x_video_modes[i]->vdisplay >= y)
1355 <                        return true;
1356 <        return false;
1357 < #else
1358 <        return DisplayWidth(x_display, screen) >= x && DisplayHeight(x_display, screen) >= y;
1353 >        if (has_vidmode) {
1354 >                for (int i=0; i<num_x_video_modes; i++)
1355 >                        if (x_video_modes[i]->hdisplay == x && x_video_modes[i]->vdisplay == y)
1356 >                                return true;
1357 >                return false;
1358 >        }
1359   #endif
1360 +        return DisplayWidth(x_display, screen) >= x && DisplayHeight(x_display, screen) >= y;
1361   }
1362  
1363   bool VideoInit(void)
# Line 1366 | Line 1424 | bool VideoInit(void)
1424          // VidMode available?
1425          int vm_event_base, vm_error_base;
1426          has_vidmode = XF86VidModeQueryExtension(x_display, &vm_event_base, &vm_error_base);
1427 <        if (has_vidmode)
1427 >        if (has_vidmode) {
1428 >                int vm_major_version, vm_minor_version;
1429 >                XF86VidModeQueryVersion(x_display, &vm_major_version, &vm_minor_version);
1430 >                D(bug("VidMode extension %d.%d available\n", vm_major_version, vm_minor_version));
1431                  XF86VidModeGetAllModeLines(x_display, screen, &num_x_video_modes, &x_video_modes);
1432 +        }
1433   #endif
1434  
1435   #ifdef ENABLE_FBDEV_DGA
# Line 1479 | Line 1541 | bool VideoInit(void)
1541   #endif
1542                  } else
1543                          add_custom_mode(p, display_type, default_width, default_height, default_mode, APPLE_CUSTOM);
1544 +
1545 +                // Add extra VidMode capable modes
1546 +                if (display_type == DIS_SCREEN) {
1547 +                        struct {
1548 +                                int w;
1549 +                                int h;
1550 +                                int apple_id;
1551 +                        }
1552 +                        video_modes[] = {
1553 +                                {  640,  480, APPLE_640x480   },
1554 +                                {  800,  600, APPLE_800x600   },
1555 +                                { 1024,  768, APPLE_1024x768  },
1556 +                                { 1152,  768, APPLE_1152x768  },
1557 +                                { 1152,  900, APPLE_1152x900  },
1558 +                                { 1280, 1024, APPLE_1280x1024 },
1559 +                                { 1600, 1200, APPLE_1600x1200 },
1560 +                                { 0, }
1561 +                        };
1562 +
1563 +                        for (int i = 0; video_modes[i].w != 0; i++) {
1564 +                                const int w = video_modes[i].w;
1565 +                                const int h = video_modes[i].h;
1566 +                                if (w >= default_width || h >= default_height)
1567 +                                        continue;
1568 +                                if (has_mode(w, h)) {
1569 + #ifdef ENABLE_VOSF
1570 +                                        if (is_fbdev_dga_mode) {
1571 +                                                for (unsigned int d = APPLE_1_BIT; d <= default_mode; d++)
1572 +                                                        if (find_visual_for_depth(d))
1573 +                                                                add_custom_mode(p, display_type, w, h, d, video_modes[i].apple_id);
1574 +                                        } else
1575 + #endif
1576 +                                                add_custom_mode(p, display_type, w, h, default_mode, video_modes[i].apple_id);
1577 +                                }
1578 +                        }
1579 +                }
1580          } else if (window_modes) {
1581                  for (unsigned int d = APPLE_1_BIT; d <= APPLE_32_BIT; d++)
1582                          if (find_visual_for_depth(d))
# Line 1547 | Line 1645 | bool VideoInit(void)
1645   #endif
1646  
1647          // Open window/screen
1648 <        if (!open_display())
1648 >        if (!open_display()) {
1649 >                ErrorAlert(GetString(STR_OPEN_WINDOW_ERR));
1650                  return false;
1651 +        }
1652  
1653   #if 0
1654          // Ignore errors from now on
# Line 1674 | Line 1774 | static void resume_emul(void)
1774          XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0);
1775          Window w = is_fbdev_dga_mode ? the_win : rootwin;
1776          XGrabKeyboard(x_display, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
1777 <        XGrabPointer(x_display, w, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
1777 >        XGrabPointer(x_display, w, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, is_fbdev_dga_mode ? w : None, None, CurrentTime);
1778          disable_mouse_accel();
1779   #ifdef ENABLE_XF86_DGA
1780          if (!is_fbdev_dga_mode) {
# Line 1691 | Line 1791 | static void resume_emul(void)
1791          if (use_vosf) {
1792                  LOCK_VOSF;
1793                  PFLAG_SET_ALL;
1694                UNLOCK_VOSF;
1794                  memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
1795 +                UNLOCK_VOSF;
1796          }
1797   #endif
1798          
# Line 2006 | Line 2106 | static void handle_events(void)
2106                                  if (use_vosf) {                 // VOSF refresh
2107                                          LOCK_VOSF;
2108                                          PFLAG_SET_ALL;
2109 +                                        memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
2110                                          UNLOCK_VOSF;
2111                                  }
2112 +                                else
2113   #endif
2114 <                                memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
2114 >                                        memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
2115                                  break;
2116                  }
2117          }
# Line 2126 | Line 2228 | void video_set_palette(void)
2228                  // We have to redraw everything because the interpretation of pixel values changed
2229                  LOCK_VOSF;
2230                  PFLAG_SET_ALL;
2231 +                if (display_type == DIS_SCREEN)
2232 +                        PFLAG_SET_VERY_DIRTY;
2233                  UNLOCK_VOSF;
2130                memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
2234          }
2235   #endif
2236  
# Line 2356 | Line 2459 | static void *redraw_func(void *arg)
2459                                          XDisplayLock();
2460   #if defined(ENABLE_XF86_DGA) || defined(ENABLE_FBDEV_DGA)
2461   #ifdef ENABLE_XF86_DGA
2462 <                                        if (is_fbdev_dga_mode)
2462 >                                        if (!is_fbdev_dga_mode)
2463                                                  XF86DGADirectVideo(x_display, screen, 0);
2464   #endif
2465                                          XUngrabPointer(x_display, CurrentTime);
# Line 2446 | Line 2549 | static void *redraw_func(void *arg)
2549          }
2550          return NULL;
2551   }
2552 +
2553 +
2554 + /*
2555 + *  Record dirty area from NQD
2556 + */
2557 +
2558 + void video_set_dirty_area(int x, int y, int w, int h)
2559 + {
2560 +        // TBD
2561 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines