140 |
|
static Visual *vis; |
141 |
|
static int color_class; |
142 |
|
|
143 |
+ |
static bool x_native_byte_order; // XImage has native byte order? |
144 |
|
static int rshift, rloss, gshift, gloss, bshift, bloss; // Pixel format of DirectColor/TrueColor modes |
145 |
|
|
146 |
|
static Colormap cmap[2] = {0, 0}; // Colormaps for indexed modes (DGA needs two of them) |
147 |
|
|
148 |
< |
static XColor x_palette[256]; // Color palette to be used as CLUT and gamma table |
148 |
> |
static XColor x_palette[256]; // Color palette to be used as CLUT and gamma table |
149 |
|
static bool x_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors |
150 |
|
|
151 |
|
#ifdef ENABLE_FBDEV_DGA |
255 |
|
} |
256 |
|
|
257 |
|
// Map RGB color to pixel value (this only works in TrueColor/DirectColor visuals) |
258 |
< |
static inline uint32 map_rgb(uint8 red, uint8 green, uint8 blue) |
258 |
> |
static inline uint32 map_rgb(uint8 red, uint8 green, uint8 blue, bool fix_byte_order = false) |
259 |
|
{ |
260 |
< |
return ((red >> rloss) << rshift) | ((green >> gloss) << gshift) | ((blue >> bloss) << bshift); |
260 |
> |
uint32 val = ((red >> rloss) << rshift) | ((green >> gloss) << gshift) | ((blue >> bloss) << bshift); |
261 |
> |
if (fix_byte_order && !x_native_byte_order) { |
262 |
> |
// We have to fix byte order in the ExpandMap[] |
263 |
> |
// NOTE: this is only an optimization since Screen_blitter_init() |
264 |
> |
// could be arranged to choose an NBO or OBO (with |
265 |
> |
// byteswapping) Blit_Expand_X_To_Y() function |
266 |
> |
switch (visualFormat.depth) { |
267 |
> |
case 15: case 16: |
268 |
> |
val = do_byteswap_16(val); |
269 |
> |
break; |
270 |
> |
case 24: case 32: |
271 |
> |
val = do_byteswap_32(val); |
272 |
> |
break; |
273 |
> |
} |
274 |
> |
} |
275 |
> |
return val; |
276 |
|
} |
277 |
|
|
278 |
|
// Do we have a visual for handling the specified Mac depth? If so, set the |
558 |
|
int mouse_last_x, mouse_last_y; // Last mouse position (for relative mode) |
559 |
|
}; |
560 |
|
|
561 |
+ |
class driver_dga; |
562 |
+ |
static void update_display_dga_vosf(driver_dga *drv); |
563 |
+ |
|
564 |
+ |
class driver_dga : public driver_base { |
565 |
+ |
friend void update_display_dga_vosf(driver_dga *drv); |
566 |
+ |
|
567 |
+ |
public: |
568 |
+ |
driver_dga(X11_monitor_desc &monitor); |
569 |
+ |
~driver_dga(); |
570 |
+ |
|
571 |
+ |
void suspend(void); |
572 |
+ |
void resume(void); |
573 |
+ |
|
574 |
+ |
protected: |
575 |
+ |
struct FakeXImage { |
576 |
+ |
int width, height; // size of image |
577 |
+ |
int depth; // depth of image |
578 |
+ |
int bytes_per_line; // accelerator to next line |
579 |
+ |
|
580 |
+ |
FakeXImage(int w, int h, int d) |
581 |
+ |
: width(w), height(h), depth(d) |
582 |
+ |
{ bytes_per_line = TrivialBytesPerRow(width, DepthModeForPixelDepth(depth)); } |
583 |
+ |
}; |
584 |
+ |
FakeXImage *img; |
585 |
+ |
|
586 |
+ |
private: |
587 |
+ |
Window suspend_win; // "Suspend" information window |
588 |
+ |
void *fb_save; // Saved frame buffer for suspend/resume |
589 |
+ |
}; |
590 |
+ |
|
591 |
|
static driver_base *drv = NULL; // Pointer to currently used driver object |
592 |
|
|
593 |
|
#ifdef ENABLE_VOSF |
781 |
|
use_vosf = true; |
782 |
|
// Allocate memory for frame buffer (SIZE is extended to page-boundary) |
783 |
|
the_host_buffer = the_buffer_copy; |
784 |
< |
the_host_buffer_row_bytes = img->bytes_per_line; |
739 |
< |
the_buffer_size = page_extend((aligned_height + 2) * the_host_buffer_row_bytes); |
784 |
> |
the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line); |
785 |
|
the_buffer = (uint8 *)vm_acquire_mac(the_buffer_size); |
786 |
|
the_buffer_copy = (uint8 *)malloc(the_buffer_size); |
787 |
|
D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); |
803 |
|
XDefineCursor(x_display, w, mac_cursor); |
804 |
|
|
805 |
|
// Init blitting routines |
761 |
– |
bool native_byte_order; |
762 |
– |
#ifdef WORDS_BIGENDIAN |
763 |
– |
native_byte_order = (XImageByteOrder(x_display) == MSBFirst); |
764 |
– |
#else |
765 |
– |
native_byte_order = (XImageByteOrder(x_display) == LSBFirst); |
766 |
– |
#endif |
806 |
|
#ifdef ENABLE_VOSF |
807 |
< |
Screen_blitter_init(visualFormat, native_byte_order, depth_of_video_mode(mode)); |
807 |
> |
Screen_blitter_init(visualFormat, x_native_byte_order, depth_of_video_mode(mode)); |
808 |
|
#endif |
809 |
|
|
810 |
|
// Set frame buffer base |
811 |
< |
set_mac_frame_buffer(monitor, mode.depth, native_byte_order); |
811 |
> |
set_mac_frame_buffer(monitor, mode.depth, x_native_byte_order); |
812 |
|
|
813 |
|
// Everything went well |
814 |
|
init_ok = true; |
923 |
|
* DGA display driver base class |
924 |
|
*/ |
925 |
|
|
887 |
– |
class driver_dga : public driver_base { |
888 |
– |
public: |
889 |
– |
driver_dga(X11_monitor_desc &monitor); |
890 |
– |
~driver_dga(); |
891 |
– |
|
892 |
– |
void suspend(void); |
893 |
– |
void resume(void); |
894 |
– |
|
895 |
– |
private: |
896 |
– |
Window suspend_win; // "Suspend" information window |
897 |
– |
void *fb_save; // Saved frame buffer for suspend/resume |
898 |
– |
}; |
899 |
– |
|
926 |
|
driver_dga::driver_dga(X11_monitor_desc &m) |
927 |
< |
: driver_base(m), suspend_win(0), fb_save(NULL) |
927 |
> |
: driver_base(m), suspend_win(0), fb_save(NULL), img(NULL) |
928 |
|
{ |
929 |
|
} |
930 |
|
|
932 |
|
{ |
933 |
|
XUngrabPointer(x_display, CurrentTime); |
934 |
|
XUngrabKeyboard(x_display, CurrentTime); |
935 |
+ |
|
936 |
+ |
if (img) |
937 |
+ |
delete img; |
938 |
|
} |
939 |
|
|
940 |
|
// Suspend emulation |
1160 |
|
if (use_vosf) { |
1161 |
|
// Allocate memory for frame buffer (SIZE is extended to page-boundary) |
1162 |
|
the_host_buffer = the_buffer; |
1163 |
< |
the_host_buffer_row_bytes = bytes_per_row; |
1135 |
< |
the_buffer_size = page_extend((height + 2) * the_host_buffer_row_bytes); |
1163 |
> |
the_buffer_size = page_extend((height + 2) * bytes_per_row); |
1164 |
|
the_buffer_copy = (uint8 *)malloc(the_buffer_size); |
1165 |
|
the_buffer = (uint8 *)vm_acquire_mac(the_buffer_size); |
1166 |
+ |
|
1167 |
+ |
// Fake image for DGA/VOSF mode to know about display bounds |
1168 |
+ |
img = new FakeXImage(width, height, depth_of_video_mode(mode)); |
1169 |
|
} |
1170 |
|
#else |
1171 |
|
use_vosf = false; |
1289 |
|
// Init blitting routines |
1290 |
|
int bytes_per_row = TrivialBytesPerRow((v_width + 7) & ~7, mode.depth); |
1291 |
|
#if ENABLE_VOSF |
1261 |
– |
bool native_byte_order; |
1262 |
– |
#ifdef WORDS_BIGENDIAN |
1263 |
– |
native_byte_order = (XImageByteOrder(x_display) == MSBFirst); |
1264 |
– |
#else |
1265 |
– |
native_byte_order = (XImageByteOrder(x_display) == LSBFirst); |
1266 |
– |
#endif |
1292 |
|
#if REAL_ADDRESSING || DIRECT_ADDRESSING |
1293 |
|
// Screen_blitter_init() returns TRUE if VOSF is mandatory |
1294 |
|
// i.e. the framebuffer update function is not Blit_Copy_Raw |
1295 |
< |
use_vosf = Screen_blitter_init(visualFormat, native_byte_order, depth_of_video_mode(mode)); |
1295 |
> |
use_vosf = Screen_blitter_init(visualFormat, x_native_byte_order, depth_of_video_mode(mode)); |
1296 |
|
|
1297 |
|
if (use_vosf) { |
1298 |
|
// Allocate memory for frame buffer (SIZE is extended to page-boundary) |
1299 |
|
the_host_buffer = the_buffer; |
1300 |
< |
the_host_buffer_row_bytes = bytes_per_row; |
1276 |
< |
the_buffer_size = page_extend((height + 2) * the_host_buffer_row_bytes); |
1300 |
> |
the_buffer_size = page_extend((height + 2) * bytes_per_row); |
1301 |
|
the_buffer_copy = (uint8 *)malloc(the_buffer_size); |
1302 |
|
the_buffer = (uint8 *)vm_acquire_mac(the_buffer_size); |
1303 |
+ |
|
1304 |
+ |
// Fake image for DGA/VOSF mode to know about display bounds |
1305 |
+ |
img = new FakeXImage((v_width + 7) & ~7, height, depth_of_video_mode(mode)); |
1306 |
|
} |
1307 |
|
#else |
1308 |
|
use_vosf = false; |
1441 |
|
return false; |
1442 |
|
} |
1443 |
|
|
1444 |
+ |
// Determine the byte order of an XImage content |
1445 |
+ |
#ifdef WORDS_BIGENDIAN |
1446 |
+ |
x_native_byte_order = (XImageByteOrder(x_display) == MSBFirst); |
1447 |
+ |
#else |
1448 |
+ |
x_native_byte_order = (XImageByteOrder(x_display) == LSBFirst); |
1449 |
+ |
#endif |
1450 |
+ |
|
1451 |
|
// Build up visualFormat structure |
1452 |
|
visualFormat.fullscreen = (display_type == DISPLAY_DGA); |
1453 |
|
visualFormat.depth = visualInfo.depth; |
1515 |
|
// Load gray ramp to 8->16/32 expand map |
1516 |
|
if (!IsDirectMode(mode) && xdepth > 8) |
1517 |
|
for (int i=0; i<256; i++) |
1518 |
< |
ExpandMap[i] = map_rgb(i, i, i); |
1518 |
> |
ExpandMap[i] = map_rgb(i, i, i, true); |
1519 |
|
#endif |
1520 |
|
|
1521 |
|
// Create display driver object of requested type |
1560 |
|
LOCK_FRAME_BUFFER; |
1561 |
|
|
1562 |
|
// Start redraw/input thread |
1563 |
< |
#ifdef HAVE_PTHREADS |
1563 |
> |
#ifdef USE_PTHREADS_SERVICES |
1564 |
|
redraw_thread_cancel = false; |
1565 |
|
Set_pthread_attr(&redraw_thread_attr, 0); |
1566 |
|
redraw_thread_active = (pthread_create(&redraw_thread, &redraw_thread_attr, redraw_func, NULL) == 0); |
1756 |
|
D(bug("video_close()\n")); |
1757 |
|
|
1758 |
|
// Stop redraw thread |
1759 |
< |
#ifdef HAVE_PTHREADS |
1759 |
> |
#ifdef USE_PTHREADS_SERVICES |
1760 |
|
if (redraw_thread_active) { |
1761 |
|
redraw_thread_cancel = true; |
1762 |
|
redraw_thread_cancel_ack = false; |
1884 |
|
if (!IsDirectMode(mode) && xdepth > 8) { |
1885 |
|
for (int i=0; i<256; i++) { |
1886 |
|
int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) |
1887 |
< |
ExpandMap[i] = map_rgb(pal[c*3+0], pal[c*3+1], pal[c*3+2]); |
1887 |
> |
ExpandMap[i] = map_rgb(pal[c*3+0], pal[c*3+1], pal[c*3+2], true); |
1888 |
|
} |
1889 |
|
|
1890 |
|
// We have to redraw everything because the interpretation of pixel values changed |
2505 |
|
tick_counter = 0; |
2506 |
|
if (mainBuffer.dirty) { |
2507 |
|
LOCK_VOSF; |
2508 |
< |
update_display_dga_vosf(); |
2508 |
> |
update_display_dga_vosf(static_cast<driver_dga *>(drv)); |
2509 |
|
UNLOCK_VOSF; |
2510 |
|
} |
2511 |
|
} |
2607 |
|
const int VIDEO_REFRESH_HZ = 60; |
2608 |
|
const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; |
2609 |
|
|
2610 |
< |
#ifdef HAVE_PTHREADS |
2610 |
> |
#ifdef USE_PTHREADS_SERVICES |
2611 |
|
static void *redraw_func(void *arg) |
2612 |
|
{ |
2613 |
|
int fd = ConnectionNumber(x_display); |
2648 |
|
} |
2649 |
|
|
2650 |
|
uint64 end = GetTicks_usec(); |
2651 |
< |
D(bug("%Ld refreshes in %Ld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); |
2651 |
> |
D(bug("%lld refreshes in %lld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); |
2652 |
|
|
2653 |
|
redraw_thread_cancel_ack = true; |
2654 |
|
return NULL; |