}
/******************************************************************
- * WINECON_NotifyWindowChange
+ * WINECON_ResizeWithContainer
*
- * Inform server that visible window on sb has changed
+ * 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_NotifyWindowChange(struct inner_data* data)
+void WINECON_ResizeWithContainer(struct inner_data* data, int width, int height)
{
- SERVER_START_REQ( set_console_output_info )
- {
- req->handle = wine_server_obj_handle( data->hConOut );
- req->win_left = data->curcfg.win_pos.X;
- req->win_top = data->curcfg.win_pos.Y;
- req->win_right = data->curcfg.win_pos.X + data->curcfg.win_width - 1;
- req->win_bottom = data->curcfg.win_pos.Y + data->curcfg.win_height - 1;
- req->mask = SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW;
- wine_server_call( req );
- }
- SERVER_END_REQ;
+ 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);
}
/******************************************************************
*
* A change occurs, try to figure out which
*/
-int WINECON_GrabChanges(struct inner_data* data)
+void WINECON_GrabChanges(struct inner_data* data)
{
struct console_renderer_event evts[256];
int i, num, ev_found;
else num = 0;
}
SERVER_END_REQ;
- if (!num) {WINE_WARN("hmm renderer signaled but no events available\n"); return 1;}
+ if (!num) {WINE_WARN("hmm renderer signaled but no events available\n"); return;}
/* FIXME: should do some event compression here (cursor pos, update) */
/* step 1: keep only last cursor pos event */
}
break;
case CONSOLE_RENDERER_EXIT_EVENT:
+ data->dying = TRUE;
WINE_TRACE(". Exit!!\n");
- return 0;
+ return;
default:
WINE_FIXME("Unknown event type (%d)\n", evts[i].event);
}
}
WINE_TRACE(".\n");
- return 1;
}
/******************************************************************
*/
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)
{
* The Change<A><B> actually modify the <B> dimension of <A>.
*/
#define TstSBfWidth() (data->curcfg.sb_width != cfg->sb_width)
-#define TstWinWidth() (data->curcfg.win_width != cfg->win_width)
+#define TstWinHPos() (data->curcfg.win_width != cfg->win_width || data->curcfg.win_pos.X != cfg->win_pos.X)
#define ChgSBfWidth() do {c.X = cfg->sb_width; \
c.Y = data->curcfg.sb_height;\
SetConsoleScreenBufferSize(data->hConOut, c);\
} while (0)
-#define ChgWinWidth() do {pos.Left = pos.Top = 0; \
- pos.Right = cfg->win_width - data->curcfg.win_width; \
+#define ChgWinHPos() do {pos.Left = cfg->win_pos.X - data->curcfg.win_pos.X; \
+ pos.Top = 0; \
+ pos.Right = pos.Left + cfg->win_width - data->curcfg.win_width; \
pos.Bottom = 0; \
SetConsoleWindowInfo(data->hConOut, FALSE, &pos);\
} while (0)
#define TstSBfHeight() (data->curcfg.sb_height != cfg->sb_height)
-#define TstWinHeight() (data->curcfg.win_height != cfg->win_height)
+#define TstWinVPos() (data->curcfg.win_height != cfg->win_height || data->curcfg.win_pos.Y != cfg->win_pos.Y)
/* since we're going to apply height after width is done, we use width as defined
* in cfg, and not in data->curcfg because if won't be updated yet */
#define ChgSBfHeight() do {c.X = cfg->sb_width; c.Y = cfg->sb_height; \
SetConsoleScreenBufferSize(data->hConOut, c); \
} while (0)
-#define ChgWinHeight() do {pos.Left = pos.Top = 0; \
+#define ChgWinVPos() do {pos.Left = 0; \
+ pos.Top = cfg->win_pos.Y - data->curcfg.win_pos.Y; \
pos.Right = 0; \
- pos.Bottom = cfg->win_height - data->curcfg.win_height; \
+ pos.Bottom = pos.Top + cfg->win_height - data->curcfg.win_height; \
SetConsoleWindowInfo(data->hConOut, FALSE, &pos);\
} while (0)
if (TstSBfWidth())
{
- if (TstWinWidth())
+ if (TstWinHPos())
{
/* we're changing both at the same time, do it in the right order */
if (cfg->sb_width >= data->curcfg.win_width)
{
- ChgSBfWidth(); ChgWinWidth();
+ ChgSBfWidth(); ChgWinHPos();
}
else
{
- ChgWinWidth(); ChgSBfWidth();
+ ChgWinHPos(); ChgSBfWidth();
}
}
else ChgSBfWidth();
}
- else if (TstWinWidth()) ChgWinWidth();
+ else if (TstWinHPos()) ChgWinHPos();
if (TstSBfHeight())
{
- if (TstWinHeight())
+ if (TstWinVPos())
{
if (cfg->sb_height >= data->curcfg.win_height)
{
- ChgSBfHeight(); ChgWinHeight();
+ ChgSBfHeight(); ChgWinVPos();
}
else
{
- ChgWinHeight(); ChgSBfHeight();
+ ChgWinVPos(); ChgSBfHeight();
}
}
else ChgSBfHeight();
}
- else if (TstWinHeight()) ChgWinHeight();
+ else if (TstWinVPos()) ChgWinVPos();
} while (0);
#undef TstSBfWidth
-#undef TstWinWidth
+#undef TstWinHPos
#undef ChgSBfWidth
-#undef ChgWinWidth
+#undef ChgWinHPos
#undef TstSBfHeight
-#undef TstWinHeight
+#undef TstWinVPos
#undef ChgSBfHeight
-#undef ChgWinHeight
+#undef ChgWinVPos
data->curcfg.exit_on_die = cfg->exit_on_die;
if (data->curcfg.edition_mode != cfg->edition_mode)
* in order to get data correctly updated
*/
WINECON_GrabChanges(data);
+ data->in_set_config = FALSE;
}
/******************************************************************
req->access = GENERIC_READ | GENERIC_WRITE;
req->attributes = 0;
req->pid = pid;
+ req->input_fd = -1;
ret = !wine_server_call_err( req );
data->hConIn = wine_server_ptr_handle( reply->handle_in );
req->access = GENERIC_WRITE|GENERIC_READ;
req->attributes = 0;
req->share = FILE_SHARE_READ|FILE_SHARE_WRITE;
+ req->fd = -1;
ret = !wine_server_call_err( req );
data->hConOut = wine_server_ptr_handle( reply->handle_out );
}
if (end == wci->ptr + 12) return IDS_CMD_INVALID_EVENT_ID;
wci->mode = from_event;
wci->ptr = end;
- wci->backend = WCUSER_InitBackend;
}
else if (strncmp(wci->ptr, "--backend=", 10) == 0)
{