Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
windows: emit SIGWINCH when the console size changes
Browse files Browse the repository at this point in the history
  • Loading branch information
piscisaureus committed Aug 15, 2012
1 parent 2b090b5 commit d99586f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/uv-private/uv-win.h
Expand Up @@ -65,6 +65,7 @@ typedef intptr_t ssize_t;
*/
#define SIGHUP 1
#define SIGKILL 9
#define SIGWINCH 28

/*
* Guids and typedefs for winsock extension functions
Expand Down
8 changes: 8 additions & 0 deletions src/win/signal.c
Expand Up @@ -169,6 +169,10 @@ static uv_err_t uv__signal_register(int signum) {
case SIGHUP:
return uv__signal_register_control_handler();

case SIGWINCH:
/* SIGWINCH is generated in tty.c. No need to register anything. */
return uv_ok_;

default:
/* Unsupported signal */
return uv__new_artificial_error(UV_ENOTSUP);
Expand All @@ -183,6 +187,10 @@ static uv_err_t uv__signal_unregister(int signum) {
case SIGHUP:
return uv__signal_unregister_control_handler();

case SIGWINCH:
/* SIGWINCH is generated in tty.c. No need to unregister anything. */
return uv_ok_;

default:
/* Unsupported signal */
return uv__new_artificial_error(UV_ENOTSUP);
Expand Down
59 changes: 57 additions & 2 deletions src/win/tty.c
Expand Up @@ -44,6 +44,7 @@


static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info);
static void uv_tty_update_virtual_window_light(COORD size);


/* Null uv_buf_t */
Expand Down Expand Up @@ -489,7 +490,16 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
}
records_left--;

/* Ignore events that are not keyboard events */
/* If the window was resized, recompute the virtual window size. This */
/* will trigger a SIGWINCH signal if the window size changed in an */
/* interesting meaningful way. */
if (handle->last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
uv_tty_update_virtual_window_light(
handle->last_input_record.Event.WindowBufferSizeEvent.dwSize);
continue;
}

/* Ignore other events that are not key or resize events. */
if (handle->last_input_record.EventType != KEY_EVENT) {
continue;
}
Expand Down Expand Up @@ -798,9 +808,16 @@ int uv_tty_read_stop(uv_tty_t* handle) {
}


/*
* "Full" version of the virtual window update code. It takes into account
* both the buffer size and the window height.
*/
static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) {
uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1;
int old_virtual_width = uv_tty_virtual_width;
int old_virtual_height = uv_tty_virtual_height;

uv_tty_virtual_width = info->dwSize.X;
uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1;

/* Recompute virtual window offset row. */
if (uv_tty_virtual_offset == -1) {
Expand All @@ -818,6 +835,44 @@ static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) {
if (uv_tty_virtual_offset < 0) {
uv_tty_virtual_offset = 0;
}

/* If the virtual window size changed, emit a SIGWINCH signal. Don't emit */
/* if this was the first time the virtual window size was computed. */
if (old_virtual_width != -1 && old_virtual_height != -1 &&
(uv_tty_virtual_width != old_virtual_width ||
uv_tty_virtual_height != old_virtual_height)) {
uv__signal_dispatch(SIGWINCH);
}
}


/*
* "Light" version of the virtual window update code; it only takes the screen
* buffer size into account. The window height is not updated except if the
* buffer height is lower than the size of the virtual window.
*/
static void uv_tty_update_virtual_window_light(COORD size) {
int old_virtual_width = uv_tty_virtual_width;
int old_virtual_height = uv_tty_virtual_height;

/* We can't reasonably update the height if it has never been initialized. */
/* Therefore, don't try. */
if (old_virtual_height == -1) {
return;
}

uv_tty_virtual_width = size.X;

if (size.Y < uv_tty_virtual_height) {
uv_tty_virtual_height = size.Y;
uv_tty_virtual_offset = 0;
}

/* If the virtual window size changed, emit a SIGWINCH signal. */
if (uv_tty_virtual_width != old_virtual_width ||
uv_tty_virtual_height != old_virtual_height) {
uv__signal_dispatch(SIGWINCH);
}
}


Expand Down

0 comments on commit d99586f

Please sign in to comment.