- Sync with latest B2 video_vosf.h updates.

- Enable VidMode extension with FBDev DGA graphics.
- Factor out FBDev/XF86 DGA code.
- Fix pointer grab in fbdev DGA mode, thus fixing scrolling screens in
  lower VidModes.
- Only select VidModes that match the requested resolutions, exactly.
- Fix VideoQuitFullScreen() in non FBDev mode.
This commit is contained in:
gbeauche 2005-05-12 11:20:00 +00:00
parent 31f80e338b
commit 0bce152c20

View File

@ -577,7 +577,7 @@ static bool open_window(int width, int height)
use_vosf = true;
// Allocate memory for frame buffer (SIZE is extended to page-boundary)
the_host_buffer = the_buffer_copy;
the_buffer_size = page_extend((aligned_height + 2) * (the_host_buffer_row_bytes = img->bytes_per_line));
the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line);
the_buffer = (uint8 *)vm_acquire(the_buffer_size);
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
@ -633,10 +633,29 @@ static bool open_window(int width, int height)
return true;
}
// Open FBDev display
static bool open_fbdev(int width, int height)
// Open FBDev DGA display
static bool open_fbdev_dga(int width, int height)
{
#ifdef ENABLE_FBDEV_DGA
#ifdef ENABLE_XF86_VIDMODE
// Switch to best mode
if (has_vidmode) {
int best = -1;
for (int i = 0; i < num_x_video_modes; i++) {
if (x_video_modes[i]->hdisplay == width && x_video_modes[i]->vdisplay == height) {
best = i;
break;
}
};
assert(best != -1);
XF86VidModeSwitchToMode(x_display, screen, x_video_modes[best]);
XF86VidModeSetViewPort(x_display, screen, 0, 0);
D(bug("[fbdev] VideoMode %d: %d x %d @ %d\n", best,
x_video_modes[best]->hdisplay, x_video_modes[best]->vdisplay,
1000 * x_video_modes[best]->dotclock / (x_video_modes[best]->htotal * x_video_modes[best]->vtotal)));
}
#endif
if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo) != 0) {
D(bug("[fbdev] Can't get FSCREENINFO: %s\n", strerror(errno)));
return false;
@ -706,7 +725,7 @@ static bool open_fbdev(int width, int height)
GrabModeAsync, GrabModeAsync, CurrentTime);
XGrabPointer(x_display, the_win, True,
PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
GrabModeAsync, GrabModeAsync, the_win, None, CurrentTime);
disable_mouse_accel();
// Create no_cursor
@ -717,6 +736,7 @@ static bool open_fbdev(int width, int height)
XDefineCursor(x_display, the_win, mac_cursor);
// Init blitting routines
int bytes_per_row = TrivialBytesPerRow((width + 7) & ~7, DepthModeForPixelDepth(depth));
#if ENABLE_VOSF
// Extract current screen color masks (we are in True Color mode)
VisualFormat visualFormat;
@ -743,8 +763,7 @@ static bool open_fbdev(int width, int height)
// Allocate memory for frame buffer (SIZE is extended to page-boundary)
use_vosf = true;
the_host_buffer = the_buffer;
the_host_buffer_row_bytes = TrivialBytesPerRow((width + 7) & ~7, DepthModeForPixelDepth(visualFormat.depth));
the_buffer_size = page_extend((height + 2) * the_host_buffer_row_bytes);
the_buffer_size = page_extend((height + 2) * bytes_per_row);
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
the_buffer = (uint8 *)vm_acquire(the_buffer_size);
D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
@ -753,7 +772,7 @@ static bool open_fbdev(int width, int height)
// Set frame buffer base
D(bug("the_buffer = %p, use_vosf = %d\n", the_buffer, use_vosf));
screen_base = Host2MacAddr(the_buffer);
VModes[cur_mode].viRowBytes = TrivialBytesPerRow((width + 7) & ~7, DepthModeForPixelDepth(depth));
VModes[cur_mode].viRowBytes = bytes_per_row;
return true;
#else
ErrorAlert("SheepShaver has been compiled with DGA support disabled.");
@ -761,8 +780,8 @@ static bool open_fbdev(int width, int height)
#endif
}
// Open DGA display (!! should use X11 VidMode extensions to set mode)
static bool open_dga(int width, int height)
// Open XF86 DGA display (!! should use X11 VidMode extensions to set mode)
static bool open_xf86_dga(int width, int height)
{
if (is_fbdev_dga_mode)
return false;
@ -835,7 +854,7 @@ static bool open_dga(int width, int height)
if (use_vosf) {
// Allocate memory for frame buffer (SIZE is extended to page-boundary)
the_host_buffer = the_buffer;
the_buffer_size = page_extend((height + 2) * (the_host_buffer_row_bytes = bytes_per_row));
the_buffer_size = page_extend((height + 2) * bytes_per_row);
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
the_buffer = (uint8 *)vm_acquire(the_buffer_size);
D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
@ -856,6 +875,35 @@ static bool open_dga(int width, int height)
#endif
}
// Open DGA display
static bool open_dga(int width, int height)
{
bool display_open;
display_open = open_xf86_dga(width, height);
#ifdef ENABLE_FBDEV_DGA
// Try to fallback to FBDev DGA mode
if (!display_open) {
is_fbdev_dga_mode = true;
display_open = open_fbdev_dga(width, height);
}
#endif
// Common DGA display initialization
if (display_open) {
// Fake image to get display bounds in the refresh function
if ((img = (XImage *)malloc(sizeof(*img))) == NULL)
return false;
img->width = DisplayWidth(x_display, screen);
img->height = DisplayHeight(x_display, screen);
img->depth = is_fbdev_dga_mode ? xdepth : depth;
img->bytes_per_line = TrivialBytesPerRow(img->width, DepthModeForPixelDepth(img->depth));
}
return display_open;
}
static bool open_display(void)
{
D(bug("open_display()\n"));
@ -944,20 +992,18 @@ static bool open_display(void)
display_type = mode.viType;
depth = depth_of_video_mode(mode.viAppleMode);
bool display_open = false;
if (display_type == DIS_SCREEN) {
bool display_open;
switch (display_type) {
case DIS_SCREEN:
display_open = open_dga(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
#ifdef ENABLE_FBDEV_DGA
// Try to fallback to FBDev DGA mode
if (!display_open) {
is_fbdev_dga_mode = true;
display_open = open_fbdev(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
}
#endif
}
else if (display_type == DIS_WINDOW)
break;
case DIS_WINDOW:
display_open = open_window(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
break;
default:
display_open = false;
break;
}
#ifdef ENABLE_VOSF
if (use_vosf) {
@ -1011,46 +1057,48 @@ static void close_window(void)
}
// Close FBDev mode
static void close_fbdev(void)
static void close_fbdev_dga(void)
{
#ifdef ENABLE_FBDEV_DGA
XUngrabPointer(x_display, CurrentTime);
XUngrabKeyboard(x_display, CurrentTime);
uint8 *fb_base;
if (!use_vosf) {
// don't free() the screen buffer in driver_base dtor
if (!use_vosf)
fb_base = the_buffer;
the_buffer = NULL;
}
#ifdef ENABLE_VOSF
else {
// don't free() the screen buffer in driver_base dtor
else
fb_base = the_host_buffer;
the_host_buffer = NULL;
}
#endif
munmap(fb_base, fb_finfo.smem_len);
#endif
}
// Close XF86 DGA mode
static void close_xf86_dga(void)
{
#ifdef ENABLE_XF86_DGA
XF86DGADirectVideo(x_display, screen, 0);
#endif
}
// Close DGA mode
static void close_dga(void)
{
if (is_fbdev_dga_mode)
return;
close_fbdev_dga();
else
close_xf86_dga();
#ifdef ENABLE_XF86_DGA
XF86DGADirectVideo(x_display, screen, 0);
XUngrabPointer(x_display, CurrentTime);
XUngrabKeyboard(x_display, CurrentTime);
#endif
#ifdef ENABLE_XF86_VIDMODE
if (has_vidmode)
XF86VidModeSwitchToMode(x_display, screen, x_video_modes[0]);
#endif
// Release fake image (it's not a normal XImage!)
free(img);
img = NULL;
if (!use_vosf) {
// don't free() the screen buffer in driver_base dtor
the_buffer = NULL;
@ -1065,12 +1113,8 @@ static void close_dga(void)
static void close_display(void)
{
if (display_type == DIS_SCREEN) {
if (is_fbdev_dga_mode)
close_fbdev();
else
if (display_type == DIS_SCREEN)
close_dga();
}
else if (display_type == DIS_WINDOW)
close_window();
@ -1300,13 +1344,14 @@ static void add_window_modes(VideoInfo *&p, int window_modes, int mode)
static bool has_mode(int x, int y)
{
#ifdef ENABLE_XF86_VIDMODE
if (has_vidmode) {
for (int i=0; i<num_x_video_modes; i++)
if (x_video_modes[i]->hdisplay >= x && x_video_modes[i]->vdisplay >= y)
if (x_video_modes[i]->hdisplay == x && x_video_modes[i]->vdisplay == y)
return true;
return false;
#else
return DisplayWidth(x_display, screen) >= x && DisplayHeight(x_display, screen) >= y;
}
#endif
return DisplayWidth(x_display, screen) >= x && DisplayHeight(x_display, screen) >= y;
}
bool VideoInit(void)
@ -1373,8 +1418,12 @@ bool VideoInit(void)
// VidMode available?
int vm_event_base, vm_error_base;
has_vidmode = XF86VidModeQueryExtension(x_display, &vm_event_base, &vm_error_base);
if (has_vidmode)
if (has_vidmode) {
int vm_major_version, vm_minor_version;
XF86VidModeQueryVersion(x_display, &vm_major_version, &vm_minor_version);
D(bug("VidMode extension %d.%d available\n", vm_major_version, vm_minor_version));
XF86VidModeGetAllModeLines(x_display, screen, &num_x_video_modes, &x_video_modes);
}
#endif
#ifdef ENABLE_FBDEV_DGA
@ -1486,6 +1535,42 @@ bool VideoInit(void)
#endif
} else
add_custom_mode(p, display_type, default_width, default_height, default_mode, APPLE_CUSTOM);
// Add extra VidMode capable modes
if (display_type == DIS_SCREEN) {
struct {
int w;
int h;
int apple_id;
}
video_modes[] = {
{ 640, 480, APPLE_640x480 },
{ 800, 600, APPLE_800x600 },
{ 1024, 768, APPLE_1024x768 },
{ 1152, 768, APPLE_1152x768 },
{ 1152, 900, APPLE_1152x900 },
{ 1280, 1024, APPLE_1280x1024 },
{ 1600, 1200, APPLE_1600x1200 },
{ 0, }
};
for (int i = 0; video_modes[i].w != 0; i++) {
const int w = video_modes[i].w;
const int h = video_modes[i].h;
if (w >= default_width || h >= default_height)
continue;
if (has_mode(w, h)) {
#ifdef ENABLE_VOSF
if (is_fbdev_dga_mode) {
for (unsigned int d = APPLE_1_BIT; d <= default_mode; d++)
if (find_visual_for_depth(d))
add_custom_mode(p, display_type, w, h, d, video_modes[i].apple_id);
} else
#endif
add_custom_mode(p, display_type, w, h, default_mode, video_modes[i].apple_id);
}
}
}
} else if (window_modes) {
for (unsigned int d = APPLE_1_BIT; d <= APPLE_32_BIT; d++)
if (find_visual_for_depth(d))
@ -1681,7 +1766,7 @@ static void resume_emul(void)
XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0);
Window w = is_fbdev_dga_mode ? the_win : rootwin;
XGrabKeyboard(x_display, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
XGrabPointer(x_display, w, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
XGrabPointer(x_display, w, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, is_fbdev_dga_mode ? w : None, None, CurrentTime);
disable_mouse_accel();
#ifdef ENABLE_XF86_DGA
if (!is_fbdev_dga_mode) {
@ -2366,7 +2451,7 @@ static void *redraw_func(void *arg)
XDisplayLock();
#if defined(ENABLE_XF86_DGA) || defined(ENABLE_FBDEV_DGA)
#ifdef ENABLE_XF86_DGA
if (is_fbdev_dga_mode)
if (!is_fbdev_dga_mode)
XF86DGADirectVideo(x_display, screen, 0);
#endif
XUngrabPointer(x_display, CurrentTime);