diff --git a/src/allegro/include/xalleg.h b/src/allegro/include/xalleg.h index c45baa6776..88e4b94a67 100644 --- a/src/allegro/include/xalleg.h +++ b/src/allegro/include/xalleg.h @@ -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, diff --git a/src/allegro/src/graphics.c b/src/allegro/src/graphics.c index 8bcf58d6a6..1ca7c88b86 100644 --- a/src/allegro/src/graphics.c +++ b/src/allegro/src/graphics.c @@ -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; diff --git a/src/allegro/src/x/xgfxdrv.c b/src/allegro/src/x/xgfxdrv.c index 0ce8c991a7..e2238f59b4 100644 --- a/src/allegro/src/x/xgfxdrv.c +++ b/src/allegro/src/x/xgfxdrv.c @@ -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); +} diff --git a/src/allegro/src/x/xsystem.c b/src/allegro/src/x/xsystem.c index 379597cde9..3bb0ea4a42 100644 --- a/src/allegro/src/x/xsystem.c +++ b/src/allegro/src/x/xsystem.c @@ -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. */ diff --git a/src/allegro/src/x/xwin.c b/src/allegro/src/x/xwin.c index 7e533cf3cf..56421c4ef5 100644 --- a/src/allegro/src/x/xwin.c +++ b/src/allegro/src/x/xwin.c @@ -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; + } } } diff --git a/src/allegro/src/x/xwin.h b/src/allegro/src/x/xwin.h index fdf5f1af12..9238a8a879 100644 --- a/src/allegro/src/x/xwin.h +++ b/src/allegro/src/x/xwin.h @@ -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));