all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* 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.