209 |
|
{ |
210 |
|
D(bug("have_visual_for_depth(%d)\n", 1 << depth)); |
211 |
|
|
212 |
+ |
// 1-bit works always and uses default visual |
213 |
+ |
if (depth == VDEPTH_1BIT) { |
214 |
+ |
vis = DefaultVisual(x_display, screen); |
215 |
+ |
visualInfo.visualid = XVisualIDFromVisual(vis); |
216 |
+ |
int num = 0; |
217 |
+ |
XVisualInfo *vi = XGetVisualInfo(x_display, VisualIDMask, &visualInfo, &num); |
218 |
+ |
visualInfo = vi[0]; |
219 |
+ |
XFree(vi); |
220 |
+ |
xdepth = visualInfo.depth; |
221 |
+ |
color_class = visualInfo.c_class; |
222 |
+ |
D(bug(" found visual ID 0x%02x, depth %d\n", visualInfo.visualid, xdepth)); |
223 |
+ |
return true; |
224 |
+ |
} |
225 |
+ |
|
226 |
|
// Calculate minimum and maximum supported X depth |
227 |
|
int min_depth = 1, max_depth = 32; |
228 |
|
switch (depth) { |
215 |
– |
case VDEPTH_1BIT: // 1-bit works always and uses default visual |
216 |
– |
min_depth = max_depth = DefaultDepth(x_display, screen); |
217 |
– |
break; |
229 |
|
#ifdef ENABLE_VOSF |
230 |
|
case VDEPTH_2BIT: |
231 |
|
case VDEPTH_4BIT: // VOSF blitters can convert 2/4/8-bit -> 8/16/32-bit |
524 |
|
#ifdef ENABLE_VOSF |
525 |
|
else { |
526 |
|
if (the_host_buffer) { |
527 |
+ |
D(bug(" freeing the_host_buffer at %p\n", the_host_buffer)); |
528 |
|
free(the_host_buffer); |
529 |
|
the_host_buffer = NULL; |
530 |
|
} |
531 |
|
if (the_buffer) { |
532 |
+ |
D(bug(" freeing the_buffer at %p\n", the_buffer)); |
533 |
|
free(the_buffer); |
534 |
|
the_buffer = NULL; |
535 |
|
} |
536 |
|
if (the_buffer_copy) { |
537 |
+ |
D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy)); |
538 |
|
free(the_buffer_copy); |
539 |
|
the_buffer_copy = NULL; |
540 |
|
} |
593 |
|
wattr.colormap = (mode.depth == VDEPTH_1BIT ? DefaultColormap(x_display, screen) : cmap[0]); |
594 |
|
w = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth, |
595 |
|
InputOutput, vis, CWEventMask | CWBackPixel | CWBorderPixel | CWColormap, &wattr); |
596 |
+ |
D(bug(" window created\n")); |
597 |
|
|
598 |
|
// Set window name/class |
599 |
|
set_window_name(w, STR_WINDOW_TITLE); |
617 |
|
XFree(hints); |
618 |
|
} |
619 |
|
} |
620 |
+ |
D(bug(" window attributes set\n")); |
621 |
|
|
622 |
|
// Show window |
623 |
|
XMapWindow(x_display, w); |
624 |
|
wait_mapped(w); |
625 |
+ |
D(bug(" window mapped\n")); |
626 |
|
|
627 |
|
// 1-bit mode is big-endian; if the X server is little-endian, we can't |
628 |
|
// use SHM because that doesn't allow changing the image byte order |
633 |
|
|
634 |
|
// Create SHM image ("height + 2" for safety) |
635 |
|
img = XShmCreateImage(x_display, vis, mode.depth == VDEPTH_1BIT ? 1 : xdepth, mode.depth == VDEPTH_1BIT ? XYBitmap : ZPixmap, 0, &shminfo, width, height); |
636 |
+ |
D(bug(" shm image created\n")); |
637 |
|
shminfo.shmid = shmget(IPC_PRIVATE, (aligned_height + 2) * img->bytes_per_line, IPC_CREAT | 0777); |
638 |
|
the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0); |
639 |
|
shminfo.shmaddr = img->data = (char *)the_buffer_copy; |
654 |
|
have_shm = true; |
655 |
|
shmctl(shminfo.shmid, IPC_RMID, 0); |
656 |
|
} |
657 |
+ |
D(bug(" shm image attached\n")); |
658 |
|
} |
659 |
|
|
660 |
|
// Create normal X image if SHM doesn't work ("height + 2" for safety) |
662 |
|
int bytes_per_row = (mode.depth == VDEPTH_1BIT ? aligned_width/8 : TrivialBytesPerRow(aligned_width, DepthModeForPixelDepth(xdepth))); |
663 |
|
the_buffer_copy = (uint8 *)malloc((aligned_height + 2) * bytes_per_row); |
664 |
|
img = XCreateImage(x_display, vis, mode.depth == VDEPTH_1BIT ? 1 : xdepth, mode.depth == VDEPTH_1BIT ? XYBitmap : ZPixmap, 0, (char *)the_buffer_copy, aligned_width, aligned_height, 32, bytes_per_row); |
665 |
+ |
D(bug(" X image created\n")); |
666 |
|
} |
667 |
|
|
668 |
|
if (need_msb_image) { |
729 |
|
if (use_vosf) { |
730 |
|
// don't free() memory mapped buffers in driver_base dtor |
731 |
|
if (the_buffer != VM_MAP_FAILED) { |
732 |
+ |
D(bug(" releasing the_buffer at %p\n", the_buffer)); |
733 |
|
vm_release(the_buffer, the_buffer_size); |
734 |
|
the_buffer = NULL; |
735 |
|
} |
736 |
|
if (the_buffer_copy != VM_MAP_FAILED) { |
737 |
+ |
D(bug(" releasing the_buffer_copy at %p\n", the_buffer_copy)); |
738 |
|
vm_release(the_buffer_copy, the_buffer_size); |
739 |
|
the_buffer_copy = NULL; |
740 |
|
} |
741 |
|
} |
742 |
|
#endif |
743 |
< |
if (img) |
743 |
> |
if (img) { |
744 |
> |
if (!have_shm) |
745 |
> |
img->data = NULL; |
746 |
|
XDestroyImage(img); |
747 |
+ |
} |
748 |
|
if (have_shm) { |
749 |
|
shmdt(shminfo.shmaddr); |
750 |
|
shmctl(shminfo.shmid, IPC_RMID, 0); |
1364 |
|
// Open display for specified mode |
1365 |
|
static bool video_open(const video_mode &mode) |
1366 |
|
{ |
1367 |
+ |
D(bug("video_open()\n")); |
1368 |
+ |
|
1369 |
|
// Find best available X visual |
1370 |
|
if (!find_visual_for_depth(mode.depth)) { |
1371 |
|
ErrorAlert(STR_NO_XVISUAL_ERR); |
1664 |
|
// Close display |
1665 |
|
static void video_close(void) |
1666 |
|
{ |
1667 |
+ |
D(bug("video_close()\n")); |
1668 |
+ |
|
1669 |
|
// Stop redraw thread |
1670 |
|
#ifdef HAVE_PTHREADS |
1671 |
|
if (redraw_thread_active) { |
1681 |
|
// Unlock frame buffer |
1682 |
|
UNLOCK_FRAME_BUFFER; |
1683 |
|
XSync(x_display, false); |
1684 |
+ |
D(bug(" frame buffer unlocked\n")); |
1685 |
|
|
1686 |
|
#ifdef ENABLE_VOSF |
1687 |
|
if (use_vosf) { |