diff --git a/programs/wineconsole/user.c b/programs/wineconsole/user.c index 86106c5565d..dc60ffdd610 100644 --- a/programs/wineconsole/user.c +++ b/programs/wineconsole/user.c @@ -778,6 +778,7 @@ static void WCUSER_Paint(const struct inner_data* data) { PAINTSTRUCT ps; + if (data->in_set_config) return; /* in order to avoid some flicker */ BeginPaint(data->hWnd, &ps); BitBlt(ps.hdc, 0, 0, data->curcfg.win_width * data->curcfg.cell_width, @@ -1329,6 +1330,10 @@ static LRESULT CALLBACK WCUSER_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM if (!HIWORD(lParam)) return DefWindowProcW(hWnd, uMsg, wParam, lParam); WCUSER_SetMenuDetails(data, GetSystemMenu(data->hWnd, FALSE)); break; + case WM_SIZE: + WINECON_ResizeWithContainer(data, LOWORD(lParam) / data->curcfg.cell_width, + HIWORD(lParam) / data->curcfg.cell_height); + break; default: return DefWindowProcW(hWnd, uMsg, wParam, lParam); } diff --git a/programs/wineconsole/winecon_private.h b/programs/wineconsole/winecon_private.h index a9a462a7c27..8f08ff4311e 100644 --- a/programs/wineconsole/winecon_private.h +++ b/programs/wineconsole/winecon_private.h @@ -60,6 +60,7 @@ struct inner_data { HANDLE hSynchro; /* waitable handle signalled by server when something in server has been modified */ HWND hWnd; /* handle of 'user' window or NULL for 'curses' */ INT nCmdShow; /* argument of WinMain */ + BOOL in_set_config; /* to handle re-entrant calls to WINECON_SetConfig */ int (*fnMainLoop)(struct inner_data* data); void (*fnPosCursor)(const struct inner_data* data); @@ -77,6 +78,7 @@ struct inner_data { /* from wineconsole.c */ extern void WINECON_Fatal(const char* msg); +extern void WINECON_ResizeWithContainer(struct inner_data* data, int width, int height); extern int WINECON_GetHistorySize(HANDLE hConIn); extern int WINECON_GetHistoryMode(HANDLE hConIn); extern BOOL WINECON_GetConsoleTitle(HANDLE hConIn, WCHAR* buffer, size_t len); diff --git a/programs/wineconsole/wineconsole.c b/programs/wineconsole/wineconsole.c index 0830d43a4b8..410d1636199 100644 --- a/programs/wineconsole/wineconsole.c +++ b/programs/wineconsole/wineconsole.c @@ -81,6 +81,34 @@ static void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm) data->fnRefresh(data, upd_tp, upd_bm); } +/****************************************************************** + * WINECON_ResizeWithContainer + * + * For console embedded in a container (e.g. user in a win32 window, or (n)curses + * in a TERM, perform resize of console (screen buffer and window) to fit in + * (new) container size. + */ +void WINECON_ResizeWithContainer(struct inner_data* data, int width, int height) +{ + struct config_data cfg; + + if (data->in_set_config) return; + + cfg = data->curcfg; + cfg.win_width = width; + cfg.win_height = height; + + /* auto size screen-buffer if it's now smaller than window */ + if (cfg.sb_width < cfg.win_width) cfg.sb_width = cfg.win_width; + if (cfg.sb_height < cfg.win_height) cfg.sb_height = cfg.win_height; + + /* and reset window pos so that we don't display outside of the screen-buffer */ + if (cfg.win_pos.X + cfg.win_width > cfg.sb_width) cfg.win_pos.X = cfg.sb_width - cfg.win_width; + if (cfg.win_pos.Y + cfg.win_height > cfg.sb_height) cfg.win_pos.Y = cfg.sb_height - cfg.win_height; + + WINECON_SetConfig(data, &cfg); +} + /****************************************************************** * WINECON_SetHistorySize * @@ -336,6 +364,8 @@ int WINECON_GrabChanges(struct inner_data* data) */ void WINECON_SetConfig(struct inner_data* data, const struct config_data* cfg) { + if (data->in_set_config) return; + data->in_set_config = TRUE; if (data->curcfg.cursor_size != cfg->cursor_size || data->curcfg.cursor_visible != cfg->cursor_visible) { @@ -467,6 +497,7 @@ void WINECON_SetConfig(struct inner_data* data, const struct config_data* cf * in order to get data correctly updated */ WINECON_GrabChanges(data); + data->in_set_config = FALSE; } /******************************************************************