* w32 fullscreen mode using frame attribute
@ 2009-11-13 8:52 Erik Charlebois
0 siblings, 0 replies; only message in thread
From: Erik Charlebois @ 2009-11-13 8:52 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 114 bytes --]
Fixed up my previous patch to honor the fullscreen frame attribute to
control fullscreening.
--
Erik Charlebois
[-- Attachment #1.2: Type: text/html, Size: 150 bytes --]
[-- Attachment #2: w32_set_fullscreen.patch --]
[-- Type: application/octet-stream, Size: 12154 bytes --]
From 7643ad83171b6959ae001c9c628ac5aec7d2c0c6 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Fri, 13 Nov 2009 00:17:12 -0800
Subject: [PATCH] 2009-11-13 Erik Charlebois <erikcharlebois@gmail.com>
* w32fns.c (w32_set_fullscreen): Hook for fullscreen frame attribute.
(w32_monitor_info): Callback context for monitor enumeration.
(w32_enum_monitors): Callback for monitor enumerator.
(w32_wnd_proc): Handle WM_DISPLAYCHANGE when fullscreen for monitor and
resolution changes. Handle WM_EMACS_SETWINDOWPOS differently in
fullscreen.
* w32term.h (w32_output): Added state to track fullscreen windows.
* w32term.c (w32_create_terminal): Add change hook for fullsreen frame
attribute.
---
src/w32fns.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/w32term.c | 2 +-
src/w32term.h | 13 ++++
3 files changed, 208 insertions(+), 4 deletions(-)
diff --git a/src/w32fns.c b/src/w32fns.c
index a99e094..de98cd6 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -257,8 +257,14 @@ typedef HWND (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context);
typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
IN COMPOSITIONFORM *form);
typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
+typedef HMONITOR (WINAPI * MonitorFromWindow_Proc)
+ (IN HWND hwnd, IN DWORD dwFlags);
typedef BOOL (WINAPI * GetMonitorInfo_Proc)
(IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
+typedef BOOL (CALLBACK * MONITOR_ENUM_PROC)(HMONITOR, HDC, LPRECT, LPARAM);
+typedef BOOL (WINAPI * EnumDisplayMonitors_Proc)
+ (IN HDC hdc, IN LPCRECT lprcClip, IN MONITOR_ENUM_PROC lpfnEnum,
+ IN LPARAM dwData);
TrackMouseEvent_Proc track_mouse_event_fn = NULL;
ClipboardSequence_Proc clipboard_sequence_fn = NULL;
@@ -267,7 +273,9 @@ ImmGetContext_Proc get_ime_context_fn = NULL;
ImmReleaseContext_Proc release_ime_context_fn = NULL;
ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
MonitorFromPoint_Proc monitor_from_point_fn = NULL;
+MonitorFromWindow_Proc monitor_from_window_fn = NULL;
GetMonitorInfo_Proc get_monitor_info_fn = NULL;
+EnumDisplayMonitors_Proc enum_display_monitors_fn = NULL;
extern AppendMenuW_Proc unicode_append_menu;
@@ -471,6 +479,74 @@ x_real_positions (f, xptr, yptr)
*yptr = rect.top;
}
+
+void
+w32_set_fullscreen(f)
+ struct frame *f;
+{
+#ifdef HAVE_WINDOW_SYSTEM
+ if (f)
+ {
+ HWND hwnd = FRAME_W32_WINDOW(f);
+ if (f->want_fullscreen != FULLSCREEN_BOTH && f->output_data.w32->fullscreen)
+ {
+ /* Restore the window style and placement. */
+ f->output_data.w32->fullscreen = 0;
+ if (f->output_data.w32->window_placement.showCmd == SW_HIDE)
+ {
+ SetWindowLong(hwnd, GWL_STYLE, f->output_data.w32->dwStyle | WS_CLIPCHILDREN);
+ SetWindowPos(hwnd, HWND_TOP, 30, 30, 640, 480,
+ SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+ }
+ else
+ {
+ SetWindowLong(hwnd, GWL_STYLE, f->output_data.w32->style);
+ SetWindowPlacement(hwnd, &f->output_data.w32->window_placement);
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+ }
+ }
+ else if (f->want_fullscreen == FULLSCREEN_BOTH
+ && !f->output_data.w32->fullscreen)
+ {
+ /* Save the window style and placement. */
+ struct MONITOR_INFO info;
+ RECT monitor_rect;
+ monitor_rect.left = 0;
+ monitor_rect.right = GetSystemMetrics(SM_CXSCREEN);
+ monitor_rect.top = 0;
+ monitor_rect.bottom = GetSystemMetrics(SM_CYSCREEN);
+
+ f->output_data.w32->fullscreen = 1;
+ f->output_data.w32->window_placement.length =
+ sizeof(WINDOWPLACEMENT);
+ GetWindowPlacement(hwnd, &f->output_data.w32->window_placement);
+
+ f->output_data.w32->style = GetWindowLong(hwnd, GWL_STYLE);
+ SetWindowLong(hwnd, GWL_STYLE,
+ ( f->output_data.w32->style
+ & (~(WS_CAPTION | WS_THICKFRAME))));
+
+ /* If multiple monitor support is available, make the window fullscreen
+ on the appropriate screen. */
+ if (monitor_from_window_fn && get_monitor_info_fn)
+ {
+ f->output_data.w32->monitor =
+ monitor_from_window_fn(hwnd, MONITOR_DEFAULT_TO_NEAREST);
+ info.cbSize = sizeof(struct MONITOR_INFO);
+ get_monitor_info_fn(f->output_data.w32->monitor, &info);
+ monitor_rect = info.rcMonitor;
+ }
+
+ SetWindowPos(FRAME_W32_WINDOW(f), HWND_TOP, monitor_rect.left,
+ monitor_rect.top, monitor_rect.right - monitor_rect.left,
+ monitor_rect.bottom - monitor_rect.top,
+ SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+ }
+ }
+#endif
+}
+
\f
DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
@@ -2748,6 +2824,32 @@ post_character_message (hwnd, msg, wParam, lParam, modifiers)
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
}
+
+struct w32_monitor_info
+{
+ HMONITOR seeking;
+ int found;
+};
+
+
+static BOOL CALLBACK
+w32_enum_monitors (hMonitor, hdcMonitor, lprcMonitor, dwData)
+ HMONITOR hMonitor;
+ HDC hdcMonitor;
+ LPRECT lprcMonitor;
+ LPARAM dwData;
+{
+ struct w32_monitor_info* minfo =
+ (struct w32_monitor_info*) dwData;
+ if (minfo->seeking == hMonitor)
+ {
+ minfo->found = 1;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
/* Main window procedure */
LRESULT CALLBACK
@@ -2809,6 +2911,59 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
release_frame_dc (f, get_frame_dc (f));
}
return 0;
+ case WM_DISPLAYCHANGE:
+ f = x_window_to_frame(dpyinfo, hwnd);
+ if (f && f->output_data.w32->fullscreen)
+ {
+ /* If multiple monitor support is available, check if the monitor
+ the window was fullscreened on still exists. If not, kick it out
+ of fullscreen and let Windows reposition it. */
+ if (monitor_from_window_fn && get_monitor_info_fn &&
+ enum_display_monitors_fn)
+ {
+ struct w32_monitor_info minfo = { f->output_data.w32->monitor, 0 };
+ enum_display_monitors_fn(NULL, NULL, w32_enum_monitors,
+ (LPARAM) &minfo);
+ if (!minfo.found)
+ {
+ f->output_data.w32->fullscreen = 0;
+
+ if (f->output_data.w32->window_placement.showCmd == SW_HIDE)
+ {
+ SetWindowLong(hwnd, GWL_STYLE, f->output_data.w32->dwStyle | WS_CLIPCHILDREN);
+ SetWindowPos(hwnd, HWND_TOP, 30, 30, 640, 480,
+ SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+ }
+ else
+ {
+ SetWindowLong(hwnd, GWL_STYLE, f->output_data.w32->style);
+ SetWindowPlacement(hwnd, &f->output_data.w32->window_placement);
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+ }
+ }
+ else
+ {
+ /* The monitor still exists. Resize to fullscreen to account for
+ a possible resolution change. */
+ struct MONITOR_INFO info;
+ info.cbSize = sizeof(struct MONITOR_INFO);
+ get_monitor_info_fn(f->output_data.w32->monitor, &info);
+ SetWindowPos(hwnd, HWND_TOP, info.rcMonitor.left,
+ info.rcMonitor.top, info.rcMonitor.right - info.rcMonitor.left,
+ info.rcMonitor.bottom - info.rcMonitor.top,
+ SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+ }
+ }
+ else
+ {
+ /* Resize to fullscreen to account for resolution change. */
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN),
+ GetSystemMetrics(SM_CYSCREEN),
+ SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+ }
+ }
+ return 0;
case WM_PAINT:
{
PAINTSTRUCT paintStruct;
@@ -3887,9 +4042,41 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
case WM_EMACS_SETWINDOWPOS:
{
- WINDOWPOS * pos = (WINDOWPOS *) wParam;
- return SetWindowPos (hwnd, pos->hwndInsertAfter,
- pos->x, pos->y, pos->cx, pos->cy, pos->flags);
+ f = x_window_to_frame(dpyinfo, hwnd);
+ if (f && f->output_data.w32->fullscreen)
+ {
+ SetWindowLong(hwnd, GWL_STYLE,
+ ( f->output_data.w32->style
+ & (~(WS_CAPTION | WS_THICKFRAME))));
+
+ /* Force the window to be fullscreen. This will cause frame
+ position and size changes to be ignored. It also keeps the
+ window correctly fullscreen when the menu or scroll bars are
+ toggled. */
+ if (monitor_from_window_fn && get_monitor_info_fn &&
+ enum_display_monitors_fn)
+ {
+ struct MONITOR_INFO info;
+ info.cbSize = sizeof(struct MONITOR_INFO);
+ get_monitor_info_fn(f->output_data.w32->monitor, &info);
+ SetWindowPos(hwnd, HWND_TOP, info.rcMonitor.left,
+ info.rcMonitor.top, info.rcMonitor.right - info.rcMonitor.left,
+ info.rcMonitor.bottom - info.rcMonitor.top,
+ SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+ }
+ else
+ {
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN),
+ GetSystemMetrics(SM_CYSCREEN),
+ SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+ }
+ }
+ else
+ {
+ WINDOWPOS * pos = (WINDOWPOS *) wParam;
+ return SetWindowPos (hwnd, pos->hwndInsertAfter,
+ pos->x, pos->y, pos->cx, pos->cy, pos->flags);
+ }
}
case WM_EMACS_DESTROYWINDOW:
@@ -7311,8 +7498,12 @@ globals_of_w32fns ()
monitor_from_point_fn = (MonitorFromPoint_Proc)
GetProcAddress (user32_lib, "MonitorFromPoint");
+ monitor_from_window_fn = (MonitorFromWindow_Proc)
+ GetProcAddress (user32_lib, "MonitorFromWindow");
get_monitor_info_fn = (GetMonitorInfo_Proc)
GetProcAddress (user32_lib, "GetMonitorInfoA");
+ enum_display_monitors_fn = (EnumDisplayMonitors_Proc)
+ GetProcAddress (user32_lib, "EnumDisplayMonitors");
{
HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
diff --git a/src/w32term.c b/src/w32term.c
index 008042c..b7a234e 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -6162,7 +6162,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
terminal->mouse_position_hook = w32_mouse_position;
terminal->frame_rehighlight_hook = w32_frame_rehighlight;
terminal->frame_raise_lower_hook = w32_frame_raise_lower;
- // terminal->fullscreen_hook = XTfullscreen_hook;
+ terminal->fullscreen_hook = w32_set_fullscreen;
terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
diff --git a/src/w32term.h b/src/w32term.h
index 8181d61..d4e3b9a 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -78,6 +78,7 @@ struct w32_palette_entry {
};
extern void w32_regenerate_palette(struct frame *f);
+extern void w32_set_fullscreen(struct frame *f);
\f
/* For each display (currently only one on w32), we have a structure that
@@ -372,6 +373,18 @@ struct w32_output
/* The background for which the above relief GCs were set up.
They are changed only when a different background is involved. */
unsigned long relief_background;
+
+ /* Nonzero means the frame is in fullscreen mode. */
+ char fullscreen;
+
+ /* Window placement prior to the frame going fullscreen. */
+ WINDOWPLACEMENT window_placement;
+
+ /* Window style in place when the frame went fullscreen. */
+ DWORD style;
+
+ /* Monitor that the frame is fullscreen on. */
+ HMONITOR monitor;
};
extern struct w32_output w32term_display;
--
1.6.4.msysgit.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2009-11-13 8:52 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-13 8:52 w32 fullscreen mode using frame attribute Erik Charlebois
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.