Add resize support for X11 port.

This commit is contained in:
David Capello 2010-10-30 20:30:47 -07:00
parent 9562e3e714
commit 920f6275d5
6 changed files with 139 additions and 48 deletions

View File

@ -139,7 +139,9 @@ extern struct _xwin_type
#endif
void (*close_button_callback)(void);
void (*resize_callback)(RESIZE_DISPLAY_EVENT *ev);
/* These are at the end of the struct to maintain ABI compatibility with
* allegro-4.2.0 (if and only if compiled with the same configuration).
* Notice that IMHO apps really should not be using _xwin, but we export it,

View File

@ -621,7 +621,13 @@ int acknowledge_resize(void)
TRACE(PREFIX_I "acknowledge_resize init.\n");
if (gfx_driver->acknowledge_resize) {
BITMAP *new_screen = gfx_driver->acknowledge_resize();
BITMAP *new_screen;
/* Hide the mouse from current "screen" */
if (_mouse_installed)
show_mouse(NULL);
new_screen = gfx_driver->acknowledge_resize();
if (!new_screen) {
TRACE(PREFIX_I "acknowledge_resize failed.\n");
return -1;

View File

@ -23,6 +23,7 @@
static BITMAP *_xwin_gfxdrv_init(int w, int h, int vw, int vh, int color_depth);
static void _xwin_gfxdrv_exit(BITMAP *bmp);
static BITMAP *_xwin_acknowledge_resize(void);
static GFX_DRIVER gfx_xwin =
@ -51,7 +52,7 @@ static GFX_DRIVER gfx_xwin =
NULL, NULL,
NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a));
NULL,
NULL, /* acknowledge_resize */
_xwin_acknowledge_resize,
320, 200,
TRUE,
0, 0,
@ -143,3 +144,19 @@ static BITMAP *_xwin_fullscreen_gfxdrv_init(int w, int h, int vw, int vh, int co
{
return _xwin_create_screen(&gfx_xwin_fullscreen, w, h, vw, vh, color_depth, TRUE);
}
static BITMAP *_xwin_acknowledge_resize(void)
{
int color_depth = bitmap_color_depth(screen);
XWindowAttributes getattr;
int w, h;
XGetWindowAttributes(_xwin.display, _xwin.wm_window, &getattr);
w = getattr.width;
h = getattr.height;
return _xwin_rebuild_screen(w, h, color_depth);
}

View File

@ -39,6 +39,7 @@ static int _xwin_sysdrv_init(void);
static void _xwin_sysdrv_exit(void);
static void _xwin_sysdrv_set_window_title(AL_CONST char *name);
static int _xwin_sysdrv_set_close_button_callback(void (*proc)(void));
static int _xwin_sysdrv_set_resize_callback(void (*proc)(RESIZE_DISPLAY_EVENT *ev));
static void _xwin_sysdrv_message(AL_CONST char *msg);
static int _xwin_sysdrv_display_switch_mode(int mode);
static int _xwin_sysdrv_desktop_color_depth(void);
@ -63,7 +64,7 @@ SYSTEM_DRIVER system_xwin =
_unix_find_resource,
_xwin_sysdrv_set_window_title,
_xwin_sysdrv_set_close_button_callback,
NULL, /* set_resize_callback */
_xwin_sysdrv_set_resize_callback,
_xwin_sysdrv_message,
NULL, /* assert */
NULL, /* save_console_state */
@ -278,6 +279,15 @@ static int _xwin_sysdrv_set_close_button_callback(void (*proc)(void))
static int _xwin_sysdrv_set_resize_callback(void (*proc)(RESIZE_DISPLAY_EVENT *ev))
{
_xwin.resize_callback = proc;
return 0;
}
/* _xwin_sysdrv_message:
* Displays a message. Uses xmessage if possible, and stdout if not.
*/

View File

@ -143,6 +143,7 @@ struct _xwin_type _xwin =
#endif
NULL, /* window close hook */
NULL, /* window resize hook */
#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE
0, /* orig_modeinfo */
#endif
@ -185,6 +186,8 @@ static void _xwin_private_setup_driver_desc(GFX_DRIVER *drv);
static BITMAP *_xwin_private_create_screen(GFX_DRIVER *drv, int w, int h,
int vw, int vh, int depth, int fullscreen);
static void _xwin_private_destroy_screen(void);
static void _xwin_private_destroy_screen_data(void);
static BITMAP *_xwin_private_create_screen_data(GFX_DRIVER *drv, int w, int h);
static BITMAP *_xwin_private_create_screen_bitmap(GFX_DRIVER *drv,
unsigned char *frame_buffer,
int bytes_per_buffer_line);
@ -847,42 +850,15 @@ static BITMAP *_xwin_private_create_screen(GFX_DRIVER *drv, int w, int h,
XWarpPointer(_xwin.display, None, _xwin.window, 0, 0, 0, 0, w / 2, h / 2);
}
else {
XSizeHints *hints = XAllocSizeHints();;
/* Resize managed window. */
XResizeWindow(_xwin.display, _xwin.wm_window, w, h);
/* Set size and position hints for Window Manager. */
if (hints) {
hints->flags = PMinSize | PMaxSize | PBaseSize;
hints->min_width = hints->max_width = hints->base_width = w;
hints->min_height = hints->max_height = hints->base_height = h;
XSetWMNormalHints(_xwin.display, _xwin.wm_window, hints);
XFree(hints);
}
/* Map the window managed window. */
XMapWindow(_xwin.display, _xwin.wm_window);
_xwin_wait_mapped(_xwin.wm_window);
}
/* Create XImage with the size of virtual screen. */
if (_xwin_private_create_ximage(vw, vh) != 0) {
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not create XImage"));
return 0;
}
/* Prepare visual for further use. */
_xwin_private_prepare_visual();
/* Test that frame buffer is fast (can be accessed directly). */
_xwin.fast_visual_depth = _xwin_private_fast_visual_depth();
/* Create screen bitmap from frame buffer. */
return _xwin_private_create_screen_bitmap(drv,
(unsigned char *)_xwin.ximage->data + _xwin.ximage->xoffset,
_xwin.ximage->bytes_per_line);
return _xwin_private_create_screen_data(drv, vw, vh);
}
BITMAP *_xwin_create_screen(GFX_DRIVER *drv, int w, int h,
@ -905,22 +881,7 @@ BITMAP *_xwin_create_screen(GFX_DRIVER *drv, int w, int h,
*/
static void _xwin_private_destroy_screen(void)
{
if (_xwin.buffer_line != 0) {
_AL_FREE(_xwin.buffer_line);
_xwin.buffer_line = 0;
}
if (_xwin.screen_line != 0) {
_AL_FREE(_xwin.screen_line);
_xwin.screen_line = 0;
}
if (_xwin.screen_data != 0) {
_AL_FREE(_xwin.screen_data);
_xwin.screen_data = 0;
}
_xwin_private_destroy_ximage();
_xwin_private_destroy_screen_data();
if (_xwin.mouse_grabbed) {
XUngrabPointer(_xwin.display, CurrentTime);
@ -956,6 +917,26 @@ static void _xwin_private_destroy_screen(void)
(*_xwin_window_defaultor)();
}
static void _xwin_private_destroy_screen_data(void)
{
if (_xwin.buffer_line != 0) {
_AL_FREE(_xwin.buffer_line);
_xwin.buffer_line = 0;
}
if (_xwin.screen_line != 0) {
_AL_FREE(_xwin.screen_line);
_xwin.screen_line = 0;
}
if (_xwin.screen_data != 0) {
_AL_FREE(_xwin.screen_data);
_xwin.screen_data = 0;
}
_xwin_private_destroy_ximage();
}
void _xwin_destroy_screen(void)
{
XLOCK();
@ -965,6 +946,59 @@ void _xwin_destroy_screen(void)
static BITMAP *_xwin_private_rebuild_screen(int w, int h, int color_depth)
{
_xwin_private_destroy_screen_data();
/* Save dimensions. */
_xwin.window_width = w;
_xwin.window_height = h;
_xwin.screen_width = w;
_xwin.screen_height = h;
_xwin.screen_depth = color_depth;
_xwin.virtual_width = w;
_xwin.virtual_height = h;
/* Resize the (real) window */
XResizeWindow(_xwin.display, _xwin.window, w, h);
return _xwin_private_create_screen_data(gfx_driver, w, h);
}
BITMAP *_xwin_rebuild_screen(int w, int h, int color_depth)
{
BITMAP *new_screen;
XLOCK();
new_screen = _xwin_private_rebuild_screen(w, h, color_depth);
XUNLOCK();
return new_screen;
}
static BITMAP *_xwin_private_create_screen_data(GFX_DRIVER *drv, int w, int h)
{
/* Create XImage with the size of virtual screen. */
if (_xwin_private_create_ximage(w, h) != 0) {
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not create XImage"));
return NULL;
}
/* Prepare visual for further use. */
_xwin_private_prepare_visual();
/* Test that frame buffer is fast (can be accessed directly). */
_xwin.fast_visual_depth = _xwin_private_fast_visual_depth();
/* Create screen bitmap from frame buffer. */
return _xwin_private_create_screen_bitmap(drv,
(unsigned char *)_xwin.ximage->data + _xwin.ximage->xoffset,
_xwin.ximage->bytes_per_line);
}
/* _xwin_create_screen_bitmap:
* Create screen bitmap from frame buffer.
*/
@ -2428,6 +2462,27 @@ static void _xwin_private_process_event(XEvent *event)
_xwin.close_button_callback();
}
break;
case ConfigureNotify: {
int old_width = _xwin.window_width;
int old_height = _xwin.window_height;
int new_width = event->xconfigure.width;
int new_height = event->xconfigure.height;
if (_xwin.resize_callback &&
((old_width != new_width) ||
(old_height != new_height))) {
RESIZE_DISPLAY_EVENT ev;
ev.old_w = old_width;
ev.old_h = old_height;
ev.new_w = new_width;
ev.new_h = new_height;
ev.is_maximized = 0;
ev.is_restored = 0;
_xwin.resize_callback(&ev);
}
break;
}
}
}

View File

@ -39,6 +39,7 @@ AL_FUNC(void, _xwin_destroy_window, (void));
AL_FUNC(BITMAP*, _xwin_create_screen, (GFX_DRIVER *drv, int w, int h,
int vw, int vh, int depth, int fullscreen));
AL_FUNC(void, _xwin_destroy_screen, (void));
AL_FUNC(BITMAP *, _xwin_rebuild_screen, (int w, int h, int color_depth));
AL_FUNC(void, _xwin_set_palette_range, (AL_CONST PALETTE p, int from, int to, int vsync));
AL_FUNC(void, _xwin_flush_buffers, (void));
AL_FUNC(void, _xwin_vsync, (void));