From 9562e3e71435e0dcb2be7ddaa11896884929049b Mon Sep 17 00:00:00 2001 From: David Capello Date: Sat, 30 Oct 2010 20:37:31 -0300 Subject: [PATCH] Add resize support to Allegro library (Windows port is ready). + Add acknowledge_resize() function. + Add set_resize_callback() function and RESIZE_DISPLAY_EVENT structure. --- src/allegro/include/allegro/gfx.h | 2 + .../include/allegro/platform/aintwin.h | 1 + src/allegro/include/allegro/system.h | 11 +- src/allegro/src/allegro.c | 21 ++- src/allegro/src/graphics.c | 29 ++++ src/allegro/src/macosx/qzfull.m | 1 + src/allegro/src/macosx/qzwindow.m | 1 + src/allegro/src/macosx/system.m | 1 + src/allegro/src/misc/vbeaf.c | 1 + src/allegro/src/misc/vga.c | 1 + src/allegro/src/mouse.c | 4 +- src/allegro/src/win/wddfull.c | 3 + src/allegro/src/win/wddovl.c | 1 + src/allegro/src/win/wddwin.c | 147 ++++++++++++------ src/allegro/src/win/wgdi.c | 92 ++++++++--- src/allegro/src/win/wsystem.c | 9 ++ src/allegro/src/win/wwnd.c | 64 +++++++- src/allegro/src/x/xdga2.c | 2 + src/allegro/src/x/xgfxdrv.c | 2 + src/allegro/src/x/xsystem.c | 1 + src/main.cpp | 5 - src/modules/gui.cpp | 48 +++--- 22 files changed, 348 insertions(+), 99 deletions(-) diff --git a/src/allegro/include/allegro/gfx.h b/src/allegro/include/allegro/gfx.h index 6f2eafbb1..af8aa3eb9 100644 --- a/src/allegro/include/allegro/gfx.h +++ b/src/allegro/include/allegro/gfx.h @@ -106,6 +106,7 @@ typedef struct GFX_DRIVER /* creates and manages the screen bitmap */ AL_METHOD(void, restore_video_state, (void)); AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); AL_METHOD(GFX_MODE_LIST *, fetch_mode_list, (void)); + AL_METHOD(struct BITMAP *, acknowledge_resize, (void)); int w, h; /* physical (not virtual!) screen size */ int linear; /* true if video memory is linear */ long bank_size; /* bank size, in bytes */ @@ -410,6 +411,7 @@ AL_FUNC(int, get_color_conversion, (void)); AL_FUNC(void, request_refresh_rate, (int rate)); AL_FUNC(int, get_refresh_rate, (void)); AL_FUNC(int, set_gfx_mode, (int card, int w, int h, int v_w, int v_h)); +AL_FUNC(int, acknowledge_resize, (void)); AL_FUNC(int, scroll_screen, (int x, int y)); AL_FUNC(int, request_scroll, (int x, int y)); AL_FUNC(int, poll_scroll, (void)); diff --git a/src/allegro/include/allegro/platform/aintwin.h b/src/allegro/include/allegro/platform/aintwin.h index 85612db5b..6ccdc1eb6 100644 --- a/src/allegro/include/allegro/platform/aintwin.h +++ b/src/allegro/include/allegro/platform/aintwin.h @@ -77,6 +77,7 @@ AL_VAR(int, wnd_height); AL_VAR(int, wnd_sysmenu); AL_FUNCPTR(void, user_close_proc, (void)); +AL_FUNCPTR(void, user_resize_proc, (RESIZE_DISPLAY_EVENT *ev)); /* gfx synchronization */ diff --git a/src/allegro/include/allegro/system.h b/src/allegro/include/allegro/system.h index 3d3bb7f4a..0b3d64f66 100644 --- a/src/allegro/include/allegro/system.h +++ b/src/allegro/include/allegro/system.h @@ -32,6 +32,14 @@ struct BITMAP; struct GFX_VTABLE; struct GFX_MODE; +typedef struct RESIZE_DISPLAY_EVENT +{ + int old_w, old_h; + int new_w, new_h; + int is_maximized : 1; /* 1 if this event is because the user maximized the window */ + int is_restored : 1; /* 1 if this event is because the user restored the window */ +} RESIZE_DISPLAY_EVENT; + #define ALLEGRO_ERROR_SIZE 256 AL_ARRAY(char, allegro_id); @@ -95,7 +103,7 @@ AL_FUNC(void, allegro_exit, (void)); AL_PRINTFUNC(void, allegro_message, (AL_CONST char *msg, ...), 1, 2); AL_FUNC(void, get_executable_name, (char *output, int size)); AL_FUNC(int, set_close_button_callback, (AL_METHOD(void, proc, (void)))); - +AL_FUNC(int, set_resize_callback, (AL_METHOD(void, proc, (RESIZE_DISPLAY_EVENT *ev)))); AL_FUNC(void, check_cpu, (void)); @@ -207,6 +215,7 @@ typedef struct SYSTEM_DRIVER AL_METHOD(int, find_resource, (char *dest, AL_CONST char *resource, int size)); AL_METHOD(void, set_window_title, (AL_CONST char *name)); AL_METHOD(int, set_close_button_callback, (AL_METHOD(void, proc, (void)))); + AL_METHOD(int, set_resize_callback, (AL_METHOD(void, proc, (RESIZE_DISPLAY_EVENT *ev)))); AL_METHOD(void, message, (AL_CONST char *msg)); AL_METHOD(void, assert, (AL_CONST char *msg)); AL_METHOD(void, save_console_state, (void)); diff --git a/src/allegro/src/allegro.c b/src/allegro/src/allegro.c index 30dd39c97..40025a9c6 100644 --- a/src/allegro/src/allegro.c +++ b/src/allegro/src/allegro.c @@ -380,6 +380,9 @@ static int _install_allegro(int system_id, int *errno_ptr, int (*atexit_ptr)(voi /* disable close button */ set_close_button_callback(NULL); + /* disable resize */ + set_resize_callback(NULL); + /* detect CPU type */ check_cpu(); @@ -541,6 +544,22 @@ int set_close_button_callback(void (*proc)(void)) +/* set_resize_callback: + * Installs a callback function to be called when the window is + * resized. + */ +int set_resize_callback(void (*proc)(RESIZE_DISPLAY_EVENT *ev)) +{ + ASSERT(system_driver); + + if (system_driver->set_resize_callback) + return system_driver->set_resize_callback(proc); + + return -1; +} + + + /* debug_exit: * Closes the debugging output files. */ @@ -753,7 +772,7 @@ SYSTEM_DRIVER system_none = sys_none_exit, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, sys_no_driver, sys_no_driver, sys_no_driver, sys_no_driver }; diff --git a/src/allegro/src/graphics.c b/src/allegro/src/graphics.c index 049eee1f4..8bcf58d6a 100644 --- a/src/allegro/src/graphics.c +++ b/src/allegro/src/graphics.c @@ -613,6 +613,35 @@ int set_gfx_mode(int card, int w, int h, int v_w, int v_h) +int acknowledge_resize(void) +{ + ASSERT(system_driver); + ASSERT(gfx_driver); + + TRACE(PREFIX_I "acknowledge_resize init.\n"); + + if (gfx_driver->acknowledge_resize) { + BITMAP *new_screen = gfx_driver->acknowledge_resize(); + if (!new_screen) { + TRACE(PREFIX_I "acknowledge_resize failed.\n"); + return -1; + } + + TRACE(PREFIX_I "acknowledge_resize succeeded.\n"); + + screen = new_screen; + + if (_al_linker_mouse) + _al_linker_mouse->set_mouse_etc(); + + return 0; + } + + return 0; +} + + + /* _set_gfx_mode: * Called by set_gfx_mode(). Separated to make a clear difference between * the virtual GFX_SAFE driver and the rest. The allow_config parameter, diff --git a/src/allegro/src/macosx/qzfull.m b/src/allegro/src/macosx/qzfull.m index 33ce2a7cf..fb42e428d 100644 --- a/src/allegro/src/macosx/qzfull.m +++ b/src/allegro/src/macosx/qzfull.m @@ -77,6 +77,7 @@ GFX_DRIVER gfx_quartz_full = NULL, /* AL_METHOD(void, restore_video_state, (void)); */ NULL, /* AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); */ osx_qz_fetch_mode_list, /* AL_METHOD(int, fetch_mode_list, (void)); */ + NULL, /* acknowledge_resize */ 0, 0, /* physical (not virtual!) screen size */ TRUE, /* true if video memory is linear */ 0, /* bank size, in bytes */ diff --git a/src/allegro/src/macosx/qzwindow.m b/src/allegro/src/macosx/qzwindow.m index 137422f4b..cd687091a 100644 --- a/src/allegro/src/macosx/qzwindow.m +++ b/src/allegro/src/macosx/qzwindow.m @@ -88,6 +88,7 @@ GFX_DRIVER gfx_quartz_window = NULL, /* AL_METHOD(void, restore_video_state, (void)); */ NULL, /* AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); */ NULL, /* AL_METHOD(int, fetch_mode_list, (void)); */ + NULL, /* acknowledge_resize */ 0, 0, /* physical (not virtual!) screen size */ TRUE, /* true if video memory is linear */ 0, /* bank size, in bytes */ diff --git a/src/allegro/src/macosx/system.m b/src/allegro/src/macosx/system.m index 374734517..63981b9dc 100644 --- a/src/allegro/src/macosx/system.m +++ b/src/allegro/src/macosx/system.m @@ -98,6 +98,7 @@ SYSTEM_DRIVER system_macosx = osx_sys_find_resource, osx_sys_set_window_title, osx_sys_set_close_button_callback, + NULL, /* set_resize_callback */ osx_sys_message, NULL, /* AL_METHOD(void, assert, (AL_CONST char *msg)); */ NULL, /* AL_METHOD(void, save_console_state, (void)); */ diff --git a/src/allegro/src/misc/vbeaf.c b/src/allegro/src/misc/vbeaf.c index 0d8762500..5a6e2c261 100644 --- a/src/allegro/src/misc/vbeaf.c +++ b/src/allegro/src/misc/vbeaf.c @@ -160,6 +160,7 @@ GFX_DRIVER gfx_vbeaf = vbeaf_restore, NULL, /* AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); */ vbeaf_fetch_mode_list, /* fetch mode hook */ + NULL, /* acknowledge_resize */ 0, 0, FALSE, 0, 0, 0, 0, FALSE }; diff --git a/src/allegro/src/misc/vga.c b/src/allegro/src/misc/vga.c index a30f7ea52..809ed2d1f 100644 --- a/src/allegro/src/misc/vga.c +++ b/src/allegro/src/misc/vga.c @@ -63,6 +63,7 @@ GFX_DRIVER gfx_vga = _restore_vga_mode, NULL, /* AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); */ vga_fetch_mode_list, + NULL, /* acknowledge_resize */ 320, 200, TRUE, 0, 0, diff --git a/src/allegro/src/mouse.c b/src/allegro/src/mouse.c index 743abc661..9cae01b7f 100644 --- a/src/allegro/src/mouse.c +++ b/src/allegro/src/mouse.c @@ -1014,7 +1014,9 @@ static void set_mouse_etc(void) set_mouse_range(0, 0, SCREEN_W-1, SCREEN_H-1); set_mouse_speed(2, 2); - position_mouse(SCREEN_W/2, SCREEN_H/2); + + /* As now we support window resizing, it's not recommended to change the mouse position. */ + /*position_mouse(SCREEN_W/2, SCREEN_H/2);*/ } diff --git a/src/allegro/src/win/wddfull.c b/src/allegro/src/win/wddfull.c index f4ab6ee7a..2d41bb50b 100644 --- a/src/allegro/src/win/wddfull.c +++ b/src/allegro/src/win/wddfull.c @@ -56,6 +56,7 @@ GFX_DRIVER gfx_directx_accel = NULL, // AL_METHOD(void, restore_video_state, (void*)); NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); gfx_directx_fetch_mode_list, + NULL, /* acknowledge_resize */ 0, 0, // physical (not virtual!) screen size TRUE, // true if video memory is linear 0, // bank size, in bytes @@ -95,6 +96,7 @@ GFX_DRIVER gfx_directx_soft = NULL, // AL_METHOD(void, restore_video_state, (void*)); NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); gfx_directx_fetch_mode_list, + NULL, /* acknowledge_resize */ 0, 0, // physical (not virtual!) screen size TRUE, // true if video memory is linear 0, // bank size, in bytes @@ -129,6 +131,7 @@ GFX_DRIVER gfx_directx_safe = NULL, // AL_METHOD(void, restore_video_state, (void*)); NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); gfx_directx_fetch_mode_list, + NULL, /* acknowledge_resize */ 0, 0, // physical (not virtual!) screen size TRUE, // true if video memory is linear 0, // bank size, in bytes diff --git a/src/allegro/src/win/wddovl.c b/src/allegro/src/win/wddovl.c index 1fffcfb84..f528f6443 100644 --- a/src/allegro/src/win/wddovl.c +++ b/src/allegro/src/win/wddovl.c @@ -58,6 +58,7 @@ GFX_DRIVER gfx_directx_ovl = NULL, // AL_METHOD(void, restore_video_state, (void*)); NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); NULL, // AL_METHOD(int, fetch_mode_list, (void)); + NULL, /* acknowledge_resize */ 0, 0, // int w, h; /* physical (not virtual!) screen size */ TRUE, // int linear; /* true if video memory is linear */ 0, // long bank_size; /* bank size, in bytes */ diff --git a/src/allegro/src/win/wddwin.c b/src/allegro/src/win/wddwin.c index fbceaa581..39ebd2991 100644 --- a/src/allegro/src/win/wddwin.c +++ b/src/allegro/src/win/wddwin.c @@ -33,8 +33,12 @@ static void gfx_directx_set_palette_win(AL_CONST struct RGB *p, int from, int to static BITMAP *gfx_directx_create_video_bitmap_win(int width, int height); static void gfx_directx_destroy_video_bitmap_win(BITMAP *bmp); static int gfx_directx_show_video_bitmap_win(struct BITMAP *bmp); -static BITMAP *init_directx_win(int w, int h, int v_w, int v_h, int color_depth); +static BITMAP *gfx_directx_win_init(int w, int h, int v_w, int v_h, int color_depth); static void gfx_directx_win_exit(struct BITMAP *bmp); +static BITMAP *gfx_directx_acknowledge_resize(void); + +static BITMAP *_create_directx_forefront_bitmap(int w, int h, int color_depth); +static void _destroy_directx_forefront_bitmap(void); GFX_DRIVER gfx_directx_win = @@ -43,7 +47,7 @@ GFX_DRIVER gfx_directx_win = empty_string, empty_string, "DirectDraw window", - init_directx_win, + gfx_directx_win_init, gfx_directx_win_exit, NULL, // AL_METHOD(int, scroll, (int x, int y)); gfx_directx_sync, @@ -66,6 +70,7 @@ GFX_DRIVER gfx_directx_win = NULL, // AL_METHOD(void, restore_video_state, (void*)); NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); NULL, // AL_METHOD(int, fetch_mode_list, (void)); + gfx_directx_acknowledge_resize, 0, 0, // int w, h; TRUE, // int linear; 0, // long bank_size; @@ -649,14 +654,12 @@ static void gfx_directx_setup_driver_desc(void) -/* init_directx_win: +/* gfx_directx_win_init: * Initializes the driver. */ -static struct BITMAP *init_directx_win(int w, int h, int v_w, int v_h, int color_depth) +static struct BITMAP *gfx_directx_win_init(int w, int h, int v_w, int v_h, int color_depth) { - unsigned char *cmap; HRESULT hr; - int i; HWND allegro_wnd = win_get_window(); /* flipping is impossible in windowed mode */ @@ -705,6 +708,95 @@ static struct BITMAP *init_directx_win(int w, int h, int v_w, int v_h, int color if (FAILED(hr)) goto Error; + /* create forefront bitmap */ + if (!_create_directx_forefront_bitmap(w, h, color_depth)) + goto Error; + + /* connect to the system driver */ + win_gfx_driver = &win_gfx_driver_windowed; + + /* set default switching policy */ + set_display_switch_mode(SWITCH_PAUSE); + + _exit_critical(); + + return gfx_directx_forefront_bitmap; + + Error: + _exit_critical(); + + /* release the DirectDraw object */ + gfx_directx_win_exit(NULL); + + return NULL; +} + + + +/* gfx_directx_win_exit: + * Shuts down the driver. + */ +static void gfx_directx_win_exit(struct BITMAP *bmp) +{ + _enter_gfx_critical(); + + if (bmp) { + save_window_pos(); + clear_bitmap(bmp); + } + + /* disconnect from the system driver */ + win_gfx_driver = NULL; + + _destroy_directx_forefront_bitmap(); + + /* release the color conversion blitter */ + if (colorconv_blit) { + _release_colorconv_blitter(colorconv_blit); + colorconv_blit = NULL; + } + + _destroy_directx_forefront_bitmap(); + + gfx_directx_exit(NULL); + + _exit_gfx_critical(); +} + + + +static BITMAP *gfx_directx_acknowledge_resize(void) +{ + HWND allegro_wnd = win_get_window(); + int color_depth = bitmap_color_depth(screen); + int w, h; + RECT rc; + BITMAP *new_screen; + + GetClientRect(allegro_wnd, &rc); + w = rc.right; + h = rc.bottom; + if (w % 4) + w -= (w % 4); + + _enter_gfx_critical(); + + /* Re-create the screen */ + _destroy_directx_forefront_bitmap(); + new_screen = _create_directx_forefront_bitmap(w, h, color_depth); + + _exit_gfx_critical(); + + return new_screen; +} + + + +static BITMAP *_create_directx_forefront_bitmap(int w, int h, int color_depth) +{ + unsigned char *cmap; + int i; + /* create offscreen backbuffer */ if (create_offscreen(w, h, color_depth) != 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Windowed mode not supported")); @@ -766,42 +858,16 @@ static struct BITMAP *init_directx_win(int w, int h, int v_w, int v_h, int color ASSERT(_al_wd_dirty_lines); memset(_al_wd_dirty_lines, 0, (h+1) * sizeof(char)); - /* connect to the system driver */ - win_gfx_driver = &win_gfx_driver_windowed; - - /* set default switching policy */ - set_display_switch_mode(SWITCH_PAUSE); - - _exit_critical(); - return gfx_directx_forefront_bitmap; - Error: - _exit_critical(); - - /* release the DirectDraw object */ - gfx_directx_win_exit(NULL); - +Error: return NULL; } -/* gfx_directx_win_exit: - * Shuts down the driver. - */ -static void gfx_directx_win_exit(struct BITMAP *bmp) -{ - _enter_gfx_critical(); - - if (bmp) { - save_window_pos(); - clear_bitmap(bmp); - } - - /* disconnect from the system driver */ - win_gfx_driver = NULL; - +static void _destroy_directx_forefront_bitmap(void) +{ /* destroy dirty lines array */ if (_al_wd_dirty_lines) { _AL_FREE(_al_wd_dirty_lines); @@ -815,15 +881,4 @@ static void gfx_directx_win_exit(struct BITMAP *bmp) reused_offscreen_surface = FALSE; gfx_directx_forefront_bitmap = NULL; } - - /* release the color conversion blitter */ - if (colorconv_blit) { - _release_colorconv_blitter(colorconv_blit); - colorconv_blit = NULL; - } - - gfx_directx_exit(NULL); - - _exit_gfx_critical(); } - diff --git a/src/allegro/src/win/wgdi.c b/src/allegro/src/win/wgdi.c index 120616aac..d943bd258 100644 --- a/src/allegro/src/win/wgdi.c +++ b/src/allegro/src/win/wgdi.c @@ -72,6 +72,11 @@ static int gfx_gdi_set_mouse_sprite(struct BITMAP *sprite, int xfocus, int yfoc static int gfx_gdi_show_mouse(struct BITMAP *bmp, int x, int y); static void gfx_gdi_hide_mouse(void); static void gfx_gdi_move_mouse(int x, int y); +static BITMAP *gfx_gdi_acknowledge_resize(void); + +static BITMAP *_create_gdi_screen(int w, int h, int color_depth); +static void _destroy_gdi_screen(void); + GFX_DRIVER gfx_gdi = @@ -98,6 +103,7 @@ GFX_DRIVER gfx_gdi = NULL, // AL_METHOD(void, restore_video_state, (void*)); NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); NULL, // AL_METHOD(int, fetch_mode_list, (void)); + gfx_gdi_acknowledge_resize, 0, 0, // int w, h; TRUE, // int linear; 0, // long bank_size; @@ -489,19 +495,7 @@ static struct BITMAP *gfx_gdi_init(int w, int h, int v_w, int v_h, int color_dep goto Error; } - /* the last flag serves as an end of loop delimiter */ - gdi_dirty_lines = _AL_MALLOC_ATOMIC((h+1) * sizeof(char)); - ASSERT(gdi_dirty_lines); - memset(gdi_dirty_lines, 0, (h+1) * sizeof(char)); - gdi_dirty_lines[h] = 1; - - /* create the screen surface */ - screen_surf = _AL_MALLOC_ATOMIC(w * h * BYTES_PER_PIXEL(color_depth)); - gdi_screen = _make_bitmap(w, h, (unsigned long)screen_surf, &gfx_gdi, color_depth, w * BYTES_PER_PIXEL(color_depth)); - gdi_screen->write_bank = gfx_gdi_write_bank; - _screen_vtable.acquire = gfx_gdi_lock; - _screen_vtable.release = gfx_gdi_unlock; - _screen_vtable.unwrite_bank = gfx_gdi_unwrite_bank; + _create_gdi_screen(w, h, color_depth); /* create render timer */ vsync_event = CreateEvent(NULL, FALSE, FALSE, NULL); @@ -547,13 +541,7 @@ static void gfx_gdi_exit(struct BITMAP *bmp) /* disconnect from the system driver */ win_gfx_driver = NULL; - /* destroy dirty lines array */ - _AL_FREE(gdi_dirty_lines); - gdi_dirty_lines = NULL; - - /* destroy screen surface */ - _AL_FREE(screen_surf); - gdi_screen = NULL; + _destroy_gdi_screen(); /* destroy mouse bitmaps */ if (wgdi_mouse_sprite) { @@ -602,3 +590,67 @@ static void gfx_gdi_vsync(void) { WaitForSingleObject(vsync_event, INFINITE); } + + + +static BITMAP *gfx_gdi_acknowledge_resize(void) +{ + HWND allegro_wnd = win_get_window(); + int color_depth = bitmap_color_depth(screen); + int w, h; + RECT rc; + BITMAP *new_screen; + + GetClientRect(allegro_wnd, &rc); + w = rc.right; + h = rc.bottom; + if (w % 4) + w -= (w % 4); + + _enter_gfx_critical(); + + /* Re-create the screen */ + _destroy_gdi_screen(); + new_screen = _create_gdi_screen(w, h, color_depth); + + _exit_gfx_critical(); + + return new_screen; +} + + + +static BITMAP *_create_gdi_screen(int w, int h, int color_depth) +{ + gfx_gdi.w = w; + gfx_gdi.h = h; + + /* the last flag serves as an end of loop delimiter */ + gdi_dirty_lines = _AL_MALLOC_ATOMIC((h+1) * sizeof(char)); + ASSERT(gdi_dirty_lines); + memset(gdi_dirty_lines, 0, (h+1) * sizeof(char)); + gdi_dirty_lines[h] = 1; + + /* create the screen surface */ + screen_surf = _AL_MALLOC_ATOMIC(w * h * BYTES_PER_PIXEL(color_depth)); + gdi_screen = _make_bitmap(w, h, (unsigned long)screen_surf, &gfx_gdi, color_depth, w * BYTES_PER_PIXEL(color_depth)); + gdi_screen->write_bank = gfx_gdi_write_bank; + _screen_vtable.acquire = gfx_gdi_lock; + _screen_vtable.release = gfx_gdi_unlock; + _screen_vtable.unwrite_bank = gfx_gdi_unwrite_bank; + + return gdi_screen; +} + + + +static void _destroy_gdi_screen(void) +{ + /* destroy dirty lines array */ + _AL_FREE(gdi_dirty_lines); + gdi_dirty_lines = NULL; + + /* destroy screen surface */ + _AL_FREE(screen_surf); + gdi_screen = NULL; +} diff --git a/src/allegro/src/win/wsystem.c b/src/allegro/src/win/wsystem.c index 52a0035f0..c6516d36a 100644 --- a/src/allegro/src/win/wsystem.c +++ b/src/allegro/src/win/wsystem.c @@ -44,6 +44,7 @@ static void sys_directx_exit(void); static void sys_directx_get_executable_name(char *output, int size); static void sys_directx_set_window_title(AL_CONST char *name); static int sys_directx_set_close_button_callback(void (*proc)(void)); +static int sys_directx_set_resize_callback(void (*proc)(RESIZE_DISPLAY_EVENT *ev)); static void sys_directx_message(AL_CONST char *msg); static void sys_directx_assert(AL_CONST char *msg); static void sys_directx_save_console_state(void); @@ -68,6 +69,7 @@ SYSTEM_DRIVER system_directx = NULL, /* AL_METHOD(int, find_resource, (char *dest, char *resource, int size)); */ sys_directx_set_window_title, sys_directx_set_close_button_callback, + sys_directx_set_resize_callback, sys_directx_message, sys_directx_assert, sys_directx_save_console_state, @@ -298,6 +300,13 @@ static int sys_directx_set_close_button_callback(void (*proc)(void)) } +static int sys_directx_set_resize_callback(void (*proc)(RESIZE_DISPLAY_EVENT *ev)) +{ + user_resize_proc = proc; + return 0; +} + + /* sys_directx_message: * Displays a message. diff --git a/src/allegro/src/win/wwnd.c b/src/allegro/src/win/wwnd.c index 456cc57af..bdfbad09d 100644 --- a/src/allegro/src/win/wwnd.c +++ b/src/allegro/src/win/wwnd.c @@ -58,6 +58,13 @@ int gfx_crit_sect_nesting = 0; /* close button user hook */ void (*user_close_proc)(void) = NULL; +/* TRUE if the user resized the window and user_resize_proc hook + should be called. */ +static BOOL sizing = FALSE; + +/* resize user hook (called when the windows is resized */ +void (*user_resize_proc)(RESIZE_DISPLAY_EVENT *ev) = NULL; + /* window thread internals */ #define ALLEGRO_WND_CLASS "AllegroWindow" static HWND user_wnd = NULL; @@ -259,10 +266,61 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam, } break; - case WM_SIZE: + case WM_SIZE: { + int old_width = wnd_width; + int old_height = wnd_height; + wnd_width = LOWORD(lparam); wnd_height = HIWORD(lparam); - break; + + if (/* (wnd_width > 0 && wnd_height > 0) && */ + (sizing || (wparam == SIZE_MAXIMIZED || + wparam == SIZE_RESTORED))) { + sizing = FALSE; + if (user_resize_proc) { + RESIZE_DISPLAY_EVENT ev; + ev.old_w = old_width; + ev.old_h = old_height; + ev.new_w = wnd_width; + ev.new_h = wnd_height; + ev.is_maximized = (wparam == SIZE_MAXIMIZED) ? 1: 0; + ev.is_restored = (wparam == SIZE_RESTORED) ? 1: 0; + + (*user_resize_proc)(&ev); + } + } + break; + } + + case WM_SIZING: { + LPRECT rc = (LPRECT)lparam; + int w = (rc->right - rc->left); + int dw = (w % 4); + + switch (wparam) { + + case WMSZ_LEFT: + case WMSZ_TOPLEFT: + case WMSZ_BOTTOMLEFT: { + rc->left += dw; + break; + } + + case WMSZ_RIGHT: + case WMSZ_TOPRIGHT: + case WMSZ_BOTTOMRIGHT: { + rc->right -= dw; + break; + } + + case WMSZ_TOP: + case WMSZ_BOTTOM: + /* Ignore */ + break; + } + sizing = TRUE; + return TRUE; + } case WM_PAINT: if (!user_wnd_proc || win_gfx_driver) { @@ -454,7 +512,7 @@ static HWND create_directx_window(void) /* create the window now */ wnd = CreateWindowEx(WS_EX_APPWINDOW, ALLEGRO_WND_CLASS, wnd_title, - WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, + WS_OVERLAPPEDWINDOW, -100, -100, 0, 0, NULL, NULL, allegro_inst, NULL); if (!wnd) { diff --git a/src/allegro/src/x/xdga2.c b/src/allegro/src/x/xdga2.c index c7fb7ba09..ee86a6e6f 100644 --- a/src/allegro/src/x/xdga2.c +++ b/src/allegro/src/x/xdga2.c @@ -90,6 +90,7 @@ GFX_DRIVER gfx_xdga2 = NULL, NULL, NULL, _xdga2_fetch_mode_list, + NULL, /* acknowledge_resize */ 640, 480, TRUE, 0, 0, @@ -122,6 +123,7 @@ GFX_DRIVER gfx_xdga2_soft = NULL, NULL, NULL, _xdga2_fetch_mode_list, + NULL, /* acknowledge_resize */ 640, 480, TRUE, 0, 0, diff --git a/src/allegro/src/x/xgfxdrv.c b/src/allegro/src/x/xgfxdrv.c index 48990008e..0ce8c991a 100644 --- a/src/allegro/src/x/xgfxdrv.c +++ b/src/allegro/src/x/xgfxdrv.c @@ -51,6 +51,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 */ 320, 200, TRUE, 0, 0, @@ -90,6 +91,7 @@ static GFX_DRIVER gfx_xwin_fullscreen = NULL, NULL, NULL, _xwin_fetch_mode_list, + NULL, /* acknowledge_resize */ 320, 200, TRUE, 0, 0, diff --git a/src/allegro/src/x/xsystem.c b/src/allegro/src/x/xsystem.c index ada601977..379597cde 100644 --- a/src/allegro/src/x/xsystem.c +++ b/src/allegro/src/x/xsystem.c @@ -63,6 +63,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_message, NULL, /* assert */ NULL, /* save_console_state */ diff --git a/src/main.cpp b/src/main.cpp index 3bb68bb9c..bbfe221e4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,11 +42,6 @@ const char ase_ident[] = class Allegro { public: Allegro() { -#ifdef HAVE_RESIZE_PATCH - // resize window ability - allegro_resizable_window_flag = true; -#endif - allegro_init(); set_uformat(U_ASCII); install_timer(); diff --git a/src/modules/gui.cpp b/src/modules/gui.cpp index 94c1e4e4c..dde27cece 100644 --- a/src/modules/gui.cpp +++ b/src/modules/gui.cpp @@ -144,6 +144,10 @@ static std::vector* shortcuts = NULL; static bool ji_screen_created = false; static volatile int next_idle_flags = 0; + +static volatile int restored_width = 0; +static volatile int restored_height = 0; + static JList icon_buttons; /* default GUI screen configuration */ @@ -172,12 +176,15 @@ static void display_switch_in_callback() END_OF_STATIC_FUNCTION(display_switch_in_callback); -#ifdef HAVE_RESIZE_PATCH -static void resize_callback(void) +// Called when the window is resized +static void resize_callback(RESIZE_DISPLAY_EVENT *ev) { - next_idle_flags |= SYSTEM_WINDOW_RESIZE; + if (ev->is_maximized) { + restored_width = ev->old_w; + restored_height = ev->old_h; + } + next_idle_flags |= SYSTEM_WINDOW_RESIZE; } -#endif /** * Initializes GUI. @@ -294,8 +301,8 @@ gfx_done:; /* setup the standard jinete theme for widgets */ ji_set_theme(ase_theme = new SkinneableTheme()); - -#ifdef HAVE_RESIZE_PATCH + + // Setup the handler for window-resize events set_resize_callback(resize_callback); #ifdef ALLEGRO_WINDOWS @@ -303,7 +310,6 @@ gfx_done:; ShowWindow(win_get_window(), SW_MAXIMIZE); } #endif -#endif /* configure ji_screen */ gui_setup_screen(true); @@ -397,12 +403,7 @@ static void load_gui_config(int& w, int& h, int& bpp, bool& fullscreen, bool& ma fullscreen = get_config_bool("GfxMode", "FullScreen", false); screen_scaling = get_config_int("GfxMode", "Scale", 1); screen_scaling = MID(1, screen_scaling, 4); - -#if defined HAVE_RESIZE_PATCH && defined ALLEGRO_WINDOWS maximized = get_config_bool("GfxMode", "Maximized", false); -#else - maximized = false; -#endif // Avoid 8 bpp if (bpp == 8) @@ -411,9 +412,17 @@ static void load_gui_config(int& w, int& h, int& bpp, bool& fullscreen, bool& ma static void save_gui_config() { + bool is_maximized = false; + +#ifdef WIN32 + is_maximized = (GetWindowLong(win_get_window(), GWL_STYLE) & WS_MAXIMIZE ? true: false); +#endif + + set_config_bool("GfxMode", "Maximized", is_maximized); + if (screen) { - set_config_int("GfxMode", "Width", SCREEN_W); - set_config_int("GfxMode", "Height", SCREEN_H); + set_config_int("GfxMode", "Width", is_maximized ? restored_width: SCREEN_W); + set_config_int("GfxMode", "Height", is_maximized ? restored_height: SCREEN_H); set_config_int("GfxMode", "Depth", bitmap_color_depth(screen)); } @@ -421,11 +430,6 @@ static void save_gui_config() set_config_bool("GfxMode", "FullScreen", gfx_driver->windowed ? false: true); set_config_int("GfxMode", "Scale", screen_scaling); - -#if defined HAVE_RESIZE_PATCH && defined ALLEGRO_WINDOWS - set_config_bool("GfxMode", "Maximized", - GetWindowLong(win_get_window(), GWL_STYLE) & WS_MAXIMIZE ? true: false); -#endif } int get_screen_scaling() @@ -469,16 +473,16 @@ void gui_run() void gui_feedback() { -#ifdef HAVE_RESIZE_PATCH if (next_idle_flags & SYSTEM_WINDOW_RESIZE) { next_idle_flags ^= SYSTEM_WINDOW_RESIZE; - resize_screen(); + if (acknowledge_resize() < 0) + set_gfx_mode(GFX_AUTODETECT_WINDOWED, 320, 240, 0, 0); + gui_setup_screen(false); app_get_top_window()->remap_window(); jmanager_refresh_screen(); } -#endif /* menu stuff */ if (next_idle_flags & REBUILD_RECENT_LIST) {