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.14 by gbeauche, 2004-04-11T10:46:32Z vs.
Revision 1.17 by gbeauche, 2004-04-18T23:17:54Z

# Line 32 | Line 32
32   #include <algorithm>
33  
34   #ifdef ENABLE_XF86_DGA
35 < #include <X11/extensions/xf86dga.h>
35 > # include <X11/extensions/xf86dga.h>
36   #endif
37  
38   #ifdef ENABLE_XF86_VIDMODE
# Line 63 | Line 63 | static int32 frame_skip;
63   static int16 mouse_wheel_mode;
64   static int16 mouse_wheel_lines;
65   static bool redraw_thread_active = false;       // Flag: Redraw thread installed
66 + static pthread_attr_t redraw_thread_attr;       // Redraw thread attributes
67   static pthread_t redraw_thread;                         // Redraw thread
68  
69   static bool local_X11;                                          // Flag: X server running on local machine?
# Line 125 | Line 126 | static uint8 *the_buffer_copy = NULL;          /
126   static uint32 the_buffer_size;                          // Size of allocated the_buffer
127  
128   // Variables for DGA mode
128 static char *dga_screen_base;
129 static int dga_fb_width;
129   static int current_dga_cmap;
130  
131   #ifdef ENABLE_XF86_VIDMODE
# Line 196 | Line 195 | static int palette_size(int mode)
195          }
196   }
197  
198 + // Return bits per pixel for requested depth
199 + static inline int bytes_per_pixel(int depth)
200 + {
201 +        int bpp;
202 +        switch (depth) {
203 +        case 8:
204 +                bpp = 1;
205 +                break;
206 +        case 15: case 16:
207 +                bpp = 2;
208 +                break;
209 +        case 24: case 32:
210 +                bpp = 4;
211 +                break;
212 +        default:
213 +                abort();
214 +        }
215 +        return bpp;
216 + }
217 +
218   // Map video_mode depth ID to numerical depth value
219   static inline int depth_of_video_mode(int mode)
220   {
221 <        int depth = -1;
221 >        int depth;
222          switch (mode) {
223          case APPLE_1_BIT:
224                  depth = 1;
# Line 349 | Line 368 | static void set_window_delete_protocol(W
368   }
369  
370   // Wait until window is mapped/unmapped
371 < void wait_mapped(Window w)
371 > static void wait_mapped(Window w)
372   {
373          XEvent e;
374          do {
# Line 357 | Line 376 | void wait_mapped(Window w)
376          } while ((e.type != MapNotify) || (e.xmap.event != w));
377   }
378  
379 < void wait_unmapped(Window w)
379 > static void wait_unmapped(Window w)
380   {
381          XEvent e;
382          do {
# Line 522 | Line 541 | static bool open_dga(int width, int heig
541          // Set relative mouse mode
542          ADBSetRelMouseMode(true);
543  
544 +        // Create window
545 +        XSetWindowAttributes wattr;
546 +        wattr.event_mask = eventmask = dga_eventmask;
547 +        wattr.override_redirect = True;
548 +        wattr.colormap = (depth == 1 ? DefaultColormap(x_display, screen) : cmap[0]);
549 +        the_win = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth,
550 +                InputOutput, vis, CWEventMask | CWOverrideRedirect |
551 +                (color_class == DirectColor ? CWColormap : 0), &wattr);
552 +
553 +        // Show window
554 +        XMapRaised(x_display, the_win);
555 +        wait_mapped(the_win);
556 +
557   #ifdef ENABLE_XF86_VIDMODE
558          // Switch to best mode
559          if (has_vidmode) {
# Line 538 | Line 570 | static bool open_dga(int width, int heig
570   #endif
571  
572          // Establish direct screen connection
573 +        XMoveResizeWindow(x_display, the_win, 0, 0, width, height);
574 +        XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0);
575          XGrabKeyboard(x_display, rootwin, True, GrabModeAsync, GrabModeAsync, CurrentTime);
576          XGrabPointer(x_display, rootwin, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
577 +
578 +        int v_width, v_bank, v_size;
579 +        XF86DGAGetVideo(x_display, screen, (char **)&the_buffer, &v_width, &v_bank, &v_size);
580          XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse);
581          XF86DGASetViewPort(x_display, screen, 0, 0);
582          XF86DGASetVidPage(x_display, screen, 0);
583  
584          // Set colormap
585 <        if (depth == 8)
585 >        if (!IsDirectMode(get_current_mode())) {
586 >                XSetWindowColormap(x_display, the_win, cmap[current_dga_cmap = 0]);
587                  XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);
588 +        }
589 +        XSync(x_display, false);
590  
591 <        // Set bytes per row
592 <        int bytes_per_row = TrivialBytesPerRow((dga_fb_width + 7) & ~7, DepthModeForPixelDepth(depth));
553 <
591 >        // Init blitting routines
592 >        int bytes_per_row = TrivialBytesPerRow((v_width + 7) & ~7, DepthModeForPixelDepth(depth));
593   #if ENABLE_VOSF
594          bool native_byte_order;
595   #ifdef WORDS_BIGENDIAN
# Line 569 | Line 608 | static bool open_dga(int width, int heig
608            the_buffer_size = page_extend((height + 2) * bytes_per_row);
609            the_buffer_copy = (uint8 *)malloc(the_buffer_size);
610            the_buffer = (uint8 *)vm_acquire(the_buffer_size);
611 +          D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
612          }
613   #else
614          use_vosf = false;
575        the_buffer = dga_screen_base;
615   #endif
616   #endif
578        screen_base = (uint32)the_buffer;
617  
618 +        // Set frame buffer base
619 +        D(bug("the_buffer = %p, use_vosf = %d\n", the_buffer, use_vosf));
620 +        screen_base = (uint32)the_buffer;
621          VModes[cur_mode].viRowBytes = bytes_per_row;
581        XSync(x_display, false);
622          return true;
623   #else
624          ErrorAlert("SheepShaver has been compiled with DGA support disabled.");
# Line 711 | Line 751 | static void close_window(void)
751          if (the_gc)
752                  XFreeGC(x_display, the_gc);
753  
714        // Close window
715        if (the_win) {
716                XUnmapWindow(x_display, the_win);
717                wait_unmapped(the_win);
718                XDestroyWindow(x_display, the_win);
719        }
720
754          XFlush(x_display);
755          XSync(x_display, false);
756   }
# Line 755 | Line 788 | static void close_display(void)
788          else if (display_type == DIS_WINDOW)
789                  close_window();
790  
791 +        // Close window
792 +        if (the_win) {
793 +                XUnmapWindow(x_display, the_win);
794 +                wait_unmapped(the_win);
795 +                XDestroyWindow(x_display, the_win);
796 +        }
797 +
798          // Free colormaps
799          if (cmap[0]) {
800                  XFreeColormap(x_display, cmap[0]);
# Line 871 | Line 911 | static void keycode_init(void)
911          }
912   }
913  
914 + // Find Apple mode matching best specified dimensions
915 + static int find_apple_resolution(int xsize, int ysize)
916 + {
917 +        int apple_id;
918 +        if (xsize < 800)
919 +                apple_id = APPLE_640x480;
920 +        else if (xsize < 1024)
921 +                apple_id = APPLE_800x600;
922 +        else if (xsize < 1152)
923 +                apple_id = APPLE_1024x768;
924 +        else if (xsize < 1280) {
925 +                if (ysize < 900)
926 +                        apple_id = APPLE_1152x768;
927 +                else
928 +                        apple_id = APPLE_1152x900;
929 +        }
930 +        else if (xsize < 1600)
931 +                apple_id = APPLE_1280x1024;
932 +        else
933 +                apple_id = APPLE_1600x1200;
934 +        return apple_id;
935 + }
936 +
937 + // Find mode in list of supported modes
938 + static int find_mode(int apple_mode, int apple_id, int type)
939 + {
940 +        for (VideoInfo *p = VModes; p->viType != DIS_INVALID; p++) {
941 +                if (p->viType == type && p->viAppleID == apple_id && p->viAppleMode == apple_mode)
942 +                        return p - VModes;
943 +        }
944 +        return -1;
945 + }
946 +
947   // Add mode to list of supported modes
948   static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, int apple_mode, int apple_id, int type)
949   {
# Line 891 | Line 964 | static void add_mode(VideoInfo *&p, uint
964                                  p->viXsize = 1024;
965                                  p->viYsize = 768;
966                                  break;
967 +                        case APPLE_1152x768:
968 +                                p->viXsize = 1152;
969 +                                p->viYsize = 768;
970 +                                break;
971                          case APPLE_1152x900:
972                                  p->viXsize = 1152;
973                                  p->viYsize = 900;
# Line 1037 | Line 1114 | bool VideoInit(void)
1114                          add_mode(p, screen_modes, 2, default_mode, APPLE_800x600, DIS_SCREEN);
1115                  if (has_mode(1024, 768))
1116                          add_mode(p, screen_modes, 4, default_mode, APPLE_1024x768, DIS_SCREEN);
1117 +                if (has_mode(1152, 768))
1118 +                        add_mode(p, screen_modes, 64, default_mode, APPLE_1152x768, DIS_SCREEN);
1119                  if (has_mode(1152, 900))
1120                          add_mode(p, screen_modes, 8, default_mode, APPLE_1152x900, DIS_SCREEN);
1121                  if (has_mode(1280, 1024))
# Line 1046 | Line 1125 | bool VideoInit(void)
1125          } else if (screen_modes) {
1126                  int xsize = DisplayWidth(x_display, screen);
1127                  int ysize = DisplayHeight(x_display, screen);
1128 <                int apple_id;
1050 <                if (xsize < 800)
1051 <                        apple_id = APPLE_640x480;
1052 <                else if (xsize < 1024)
1053 <                        apple_id = APPLE_800x600;
1054 <                else if (xsize < 1152)
1055 <                        apple_id = APPLE_1024x768;
1056 <                else if (xsize < 1280)
1057 <                        apple_id = APPLE_1152x900;
1058 <                else if (xsize < 1600)
1059 <                        apple_id = APPLE_1280x1024;
1060 <                else
1061 <                        apple_id = APPLE_1600x1200;
1128 >                int apple_id = find_apple_resolution(xsize, ysize);
1129                  p->viType = DIS_SCREEN;
1130                  p->viRowBytes = 0;
1131                  p->viXsize = xsize;
# Line 1075 | Line 1142 | bool VideoInit(void)
1142  
1143          // Find default mode (window 640x480)
1144          cur_mode = -1;
1145 <        for (p = VModes; p->viType != DIS_INVALID; p++) {
1146 <                if (p->viType == DIS_WINDOW
1147 <                        && p->viAppleID == APPLE_W_640x480
1148 <                        && p->viAppleMode == default_mode) {
1149 <                        cur_mode = p - VModes;
1150 <                        break;
1084 <                }
1145 >        if (has_dga && screen_modes) {
1146 >                int screen_width = DisplayWidth(x_display, screen);
1147 >                int screen_height = DisplayHeight(x_display, screen);
1148 >                int apple_id = find_apple_resolution(screen_width, screen_height);
1149 >                if (apple_id != -1)
1150 >                        cur_mode = find_mode(default_mode, apple_id, DIS_SCREEN);
1151          }
1152 +        if (cur_mode == -1)
1153 +                cur_mode = find_mode(default_mode, APPLE_W_640x480, DIS_WINDOW);
1154          assert(cur_mode != -1);
1155  
1156   #if DEBUG
# Line 1093 | Line 1161 | bool VideoInit(void)
1161          }
1162   #endif
1163  
1096 #ifdef ENABLE_XF86_DGA
1097        if (has_dga && screen_modes) {
1098                int v_bank, v_size;
1099                XF86DGAGetVideo(x_display, screen, &dga_screen_base, &dga_fb_width, &v_bank, &v_size);
1100                D(bug("DGA screen_base %p, v_width %d\n", dga_screen_base, dga_fb_width));
1101        }
1102 #endif
1103
1164          // Open window/screen
1165          if (!open_display())
1166                  return false;
# Line 1112 | Line 1172 | bool VideoInit(void)
1172  
1173          // Start periodic thread
1174          XSync(x_display, false);
1175 <        redraw_thread_active = (pthread_create(&redraw_thread, NULL, redraw_func, NULL) == 0);
1175 >        Set_pthread_attr(&redraw_thread_attr, 0);
1176 >        redraw_thread_active = (pthread_create(&redraw_thread, &redraw_thread_attr, redraw_func, NULL) == 0);
1177          D(bug("Redraw thread installed (%ld)\n", redraw_thread));
1178          return true;
1179   }
# Line 1475 | Line 1536 | static void handle_events(void)
1536                                  break;
1537                          }
1538  
1539 <                        // Mouse moved
1539 >                        // Mouse entered window
1540                          case EnterNotify:
1541 <                                ADBMouseMoved(((XMotionEvent *)&event)->x, ((XMotionEvent *)&event)->y);
1541 >                                if (event.xcrossing.mode != NotifyGrab && event.xcrossing.mode != NotifyUngrab)
1542 >                                        ADBMouseMoved(event.xmotion.x, event.xmotion.y);
1543                                  break;
1544 +
1545 +                        // Mouse moved
1546                          case MotionNotify:
1547 <                                ADBMouseMoved(((XMotionEvent *)&event)->x, ((XMotionEvent *)&event)->y);
1547 >                                ADBMouseMoved(event.xmotion.x, event.xmotion.y);
1548                                  break;
1549  
1550                          // Keyboard
# Line 1548 | Line 1612 | void VideoVBL(void)
1612   */
1613  
1614   #if 0
1551 // Rectangle blitting
1552 static void accl_bitblt(accl_params *p)
1553 {
1554        D(bug("accl_bitblt\n"));
1555
1556        // Get blitting parameters
1557        int16 src_X = p->src_rect[1] - p->src_bounds[1];
1558        int16 src_Y = p->src_rect[0] - p->src_bounds[0];
1559        int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
1560        int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
1561        int16 width = p->dest_rect[3] - p->dest_rect[1] - 1;
1562        int16 height = p->dest_rect[2] - p->dest_rect[0] - 1;
1563        D(bug(" src X %d, src Y %d, dest X %d, dest Y %d\n", src_X, src_Y, dest_X, dest_Y));
1564        D(bug(" width %d, height %d\n", width, height));
1565
1566        // And perform the blit
1567        bitblt_hook(src_X, src_Y, dest_X, dest_Y, width, height);
1568 }
1569
1570 static bool accl_bitblt_hook(accl_params *p)
1571 {
1572        D(bug("accl_draw_hook %p\n", p));
1573
1574        // Check if we can accelerate this bitblt
1575        if (p->src_base_addr == screen_base && p->dest_base_addr == screen_base &&
1576                display_type == DIS_SCREEN && bitblt_hook != NULL &&
1577                ((uint32 *)p)[0x18 >> 2] + ((uint32 *)p)[0x128 >> 2] == 0 &&
1578                ((uint32 *)p)[0x130 >> 2] == 0 &&
1579                p->transfer_mode == 0 &&
1580                p->src_row_bytes > 0 && ((uint32 *)p)[0x15c >> 2] > 0) {
1581
1582                // Yes, set function pointer
1583                p->draw_proc = accl_bitblt;
1584                return true;
1585        }
1586        return false;
1587 }
1588
1615   // Rectangle filling/inversion
1616   static void accl_fillrect8(accl_params *p)
1617   {
# Line 1663 | Line 1689 | static bool accl_fillrect_hook(accl_para
1689          return false;
1690   }
1691  
1692 + static struct accl_hook_info fillrect_hook_info = {accl_fillrect_hook, accl_sync_hook, ACCL_FILLRECT};
1693 + #endif
1694 +
1695 + // Rectangle blitting
1696 + // TODO: optimize for VOSF and target pixmap == screen
1697 + void NQD_bitblt(uint32 arg)
1698 + {
1699 +        D(bug("accl_bitblt %08x\n", arg));
1700 +        accl_params *p = (accl_params *)arg;
1701 +
1702 +        // Get blitting parameters
1703 +        int16 src_X = p->src_rect[1] - p->src_bounds[1];
1704 +        int16 src_Y = p->src_rect[0] - p->src_bounds[0];
1705 +        int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
1706 +        int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
1707 +        int16 width = p->dest_rect[3] - p->dest_rect[1];
1708 +        int16 height = p->dest_rect[2] - p->dest_rect[0];
1709 +        D(bug(" src addr %08x, dest addr %08x\n", p->src_base_addr, p->dest_base_addr));
1710 +        D(bug(" src X %d, src Y %d, dest X %d, dest Y %d\n", src_X, src_Y, dest_X, dest_Y));
1711 +        D(bug(" width %d, height %d\n", width, height));
1712 +
1713 +        // And perform the blit
1714 +        const int bpp = bytes_per_pixel(p->src_pixel_size);
1715 +        width *= bpp;
1716 +        if (p->src_row_bytes > 0) {
1717 +                const int src_row_bytes = p->src_row_bytes;
1718 +                const int dst_row_bytes = p->dest_row_bytes;
1719 +                uint8 *src = (uint8 *)p->src_base_addr + (src_Y * src_row_bytes) + (src_X * bpp);
1720 +                uint8 *dst = (uint8 *)p->dest_base_addr + (dest_Y * dst_row_bytes) + (dest_X * bpp);
1721 +                for (int i = 0; i < height; i++) {
1722 +                        memcpy(dst, src, width);
1723 +                        src += src_row_bytes;
1724 +                        dst += dst_row_bytes;
1725 +                }
1726 +        }
1727 +        else {
1728 +                const int src_row_bytes = -p->src_row_bytes;
1729 +                const int dst_row_bytes = -p->dest_row_bytes;
1730 +                uint8 *src = (uint8 *)p->src_base_addr + ((src_Y + height - 1) * src_row_bytes) + (src_X * bpp);
1731 +                uint8 *dst = (uint8 *)p->dest_base_addr + ((dest_Y + height - 1) * dst_row_bytes) + (dest_X * bpp);
1732 +                for (int i = height - 1; i >= 0; i--) {
1733 +                        memcpy(dst, src, width);
1734 +                        src -= src_row_bytes;
1735 +                        dst -= dst_row_bytes;
1736 +                }
1737 +        }
1738 + }
1739 +
1740 + bool NQD_bitblt_hook(uint32 arg)
1741 + {
1742 +        D(bug("accl_draw_hook %08x\n", arg));
1743 +        accl_params *p = (accl_params *)arg;
1744 +
1745 +        // Check if we can accelerate this bitblt
1746 +        if (((uint32 *)p)[0x18 >> 2] + ((uint32 *)p)[0x128 >> 2] == 0 &&
1747 +                ((uint32 *)p)[0x130 >> 2] == 0 &&
1748 +                p->src_pixel_size >= 8 && p->src_pixel_size == p->dest_pixel_size &&
1749 +                ((p->src_row_bytes ^ p->dest_row_bytes) >> 31) == 0 &&
1750 +                p->transfer_mode == 0 &&
1751 +                ((uint32 *)p)[0x15c >> 2] > 0) {
1752 +
1753 +                // Yes, set function pointer
1754 +                p->draw_proc = NativeTVECT(NATIVE_BITBLT);
1755 +                return true;
1756 +        }
1757 +        return false;
1758 + }
1759 +
1760   // Wait for graphics operation to finish
1761 < static bool accl_sync_hook(void *arg)
1761 > bool NQD_sync_hook(uint32 arg)
1762   {
1763 <        D(bug("accl_sync_hook %p\n", arg));
1670 <        if (sync_hook != NULL)
1671 <                sync_hook();
1763 >        D(bug("accl_sync_hook %08x\n", arg));
1764          return true;
1765   }
1766  
1675 static struct accl_hook_info bitblt_hook_info = {accl_bitblt_hook, accl_sync_hook, ACCL_BITBLT};
1676 static struct accl_hook_info fillrect_hook_info = {accl_fillrect_hook, accl_sync_hook, ACCL_FILLRECT};
1677 #endif
1678
1767   void VideoInstallAccel(void)
1768   {
1769          // Install acceleration hooks
1770          if (PrefsFindBool("gfxaccel")) {
1771                  D(bug("Video: Installing acceleration hooks\n"));
1772 < //!!    NQDMisc(6, &bitblt_hook_info);
1772 >                uint32 base;
1773 >
1774 >                SheepVar bitblt_hook_info(sizeof(accl_hook_info));
1775 >                base = bitblt_hook_info.addr();
1776 >                WriteMacInt32(base + 0, NativeTVECT(NATIVE_BITBLT_HOOK));
1777 >                WriteMacInt32(base + 4, NativeTVECT(NATIVE_SYNC_HOOK));
1778 >                WriteMacInt32(base + 8, ACCL_BITBLT);
1779 > #if defined(__powerpc__) // Temporary hack until it's fixed for e.g. little-endian & 64-bit platforms
1780 >                NQDMisc(6, bitblt_hook_info.ptr());
1781 > #endif
1782 >
1783   //              NQDMisc(6, &fillrect_hook_info);
1784          }
1785   }
# Line 1999 | Line 2097 | static void *redraw_func(void *arg)
2097                                          XF86DGADirectVideo(x_display, screen, 0);
2098                                          XUngrabPointer(x_display, CurrentTime);
2099                                          XUngrabKeyboard(x_display, CurrentTime);
2100 +                                        XUnmapWindow(x_display, the_win);
2101 +                                        wait_unmapped(the_win);
2102 +                                        XDestroyWindow(x_display, the_win);
2103   #endif
2104                                          XSync(x_display, false);
2105                                          XDisplayUnlock();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines