unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#13053: PATCH: Fullscreen frame support on Windows
@ 2012-12-02  2:57 Erik Charlebois
  2012-12-02 17:38 ` Eli Zaretskii
  0 siblings, 1 reply; 6+ messages in thread
From: Erik Charlebois @ 2012-12-02  2:57 UTC (permalink / raw)
  To: 13053

[-- Attachment #1: Type: text/plain, Size: 13849 bytes --]

I've kept this patch going for a few years; probably time I get it in for
real. I have not signed the FSF copyright assignment. If someone could give
me some guidance on that (I'm Canadian), I'd appreciate it.

This patch adds fullscreen frame support to Windows so that setting the
frame parameter 'fullscreen to 'fullboth makes the frame take up the entire
screen, with no window decoration and covering the taskbar. The function:

(defun toggle-fullscreen ()
  "Toggle full screen on X11"
  (interactive)
  (set-frame-parameter
   nil 'fullscreen
   (when (not (frame-parameter nil 'fullscreen)) 'fullboth)))

now has the same behavior on X11 and Windows. There's a bit of added
complexity to support multiple monitors and resolution changes correctly.



2012-12-01  Erik Charlebois  <erikcharlebois@gmail.com>

        * src/w32fns.c: Add w32_set_fullscreen for switching to
        fullscreen. Handle WM_DISPLAYCHANGE for changes in resolution
        and monitor configuration. Handle frame-parameter 'fullscreen
        changes by possibly going to fullscreen.
        * src/w32term.h: Add state to w32_output for tracking monitor
        and window placement.
        * src/w32term.c: Use w32_set_fullscreen for fullscreen_hook.




=== modified file 'src/w32fns.c'
*** src/w32fns.c 2012-11-21 04:47:55 +0000
--- src/w32fns.c 2012-12-01 23:11:52 +0000
*************** typedef HWND (WINAPI * ImmSetComposition
*** 162,167 ****
--- 162,173 ----
  typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD
flags);
  typedef BOOL (WINAPI * GetMonitorInfo_Proc)
    (IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
+ typedef HMONITOR (WINAPI * MonitorFromWindow_Proc)
+   (IN HWND hwnd, IN DWORD dwFlags);
+ 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;
  ImmGetCompositionString_Proc get_composition_string_fn = NULL;
*************** ImmReleaseContext_Proc release_ime_conte
*** 170,175 ****
--- 176,183 ----
  ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
  MonitorFromPoint_Proc monitor_from_point_fn = NULL;
  GetMonitorInfo_Proc get_monitor_info_fn = NULL;
+ MonitorFromWindow_Proc monitor_from_window_fn = NULL;
+ EnumDisplayMonitors_Proc enum_display_monitors_fn = NULL;

  #ifdef NTGUI_UNICODE
  #define unicode_append_menu AppendMenuW
*************** x_real_positions (FRAME_PTR f, int *xptr
*** 372,377 ****
--- 380,454 ----
    *yptr = rect.top;
  }

+
+ void
+ w32_set_fullscreen (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
+ }
+


  DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
*************** post_character_message (HWND hwnd, UINT
*** 2706,2711 ****
--- 2783,2810 ----
    my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
  }

+
+ struct w32_monitor_info
+ {
+     HMONITOR seeking;
+     int found;
+ };
+
+
+ static BOOL
+ w32_enum_monitors (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 */

  static LRESULT CALLBACK
*************** w32_wnd_proc (HWND hwnd, UINT msg, WPARA
*** 2763,2768 ****
--- 2862,2926 ----
      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;
*************** w32_wnd_proc (HWND hwnd, UINT msg, WPARA
*** 3861,3869 ****

      case WM_EMACS_SETWINDOWPOS:
        {
! WINDOWPOS * pos = (WINDOWPOS *) wParam;
! return SetWindowPos (hwnd, pos->hwndInsertAfter,
!      pos->x, pos->y, pos->cx, pos->cy, pos->flags);
        }

      case WM_EMACS_DESTROYWINDOW:
--- 4019,4061 ----

      case WM_EMACS_SETWINDOWPOS:
        {
!         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);
!                 return 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
!               {
!                 return 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:
*************** globals_of_w32fns (void)
*** 7685,7690 ****
--- 7877,7886 ----
      GetProcAddress (user32_lib, "MonitorFromPoint");
    get_monitor_info_fn = (GetMonitorInfo_Proc)
      GetProcAddress (user32_lib, "GetMonitorInfoA");
+   monitor_from_window_fn = (MonitorFromWindow_Proc)
+     GetProcAddress (user32_lib, "MonitorFromWindow");
+   enum_display_monitors_fn = (EnumDisplayMonitors_Proc)
+     GetProcAddress (user32_lib, "EnumDisplayMonitors");

    {
      HMODULE imm32_lib = GetModuleHandle ("imm32.dll");

=== modified file 'src/w32term.c'
*** src/w32term.c 2012-12-01 02:38:11 +0000
--- src/w32term.c 2012-12-01 22:56:36 +0000
*************** w32_create_terminal (struct w32_display_
*** 6211,6217 ****
    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->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;
--- 6211,6217 ----
    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 = 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;

=== modified file 'src/w32term.h'
*** src/w32term.h 2012-11-23 15:39:48 +0000
--- src/w32term.h 2012-12-01 22:57:00 +0000
*************** struct w32_palette_entry {
*** 71,76 ****
--- 71,77 ----
  };

  extern void w32_regenerate_palette (struct frame *f);
+ extern void w32_set_fullscreen (struct frame *f);


  /* For each display (currently only one on w32), we have a structure that
*************** struct w32_output
*** 361,366 ****
--- 362,379 ----
    /* 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;

[-- Attachment #2: Type: text/html, Size: 20745 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#13053: PATCH: Fullscreen frame support on Windows
  2012-12-02  2:57 bug#13053: PATCH: Fullscreen frame support on Windows Erik Charlebois
@ 2012-12-02 17:38 ` Eli Zaretskii
  2012-12-02 20:05   ` Glenn Morris
  0 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2012-12-02 17:38 UTC (permalink / raw)
  To: Erik Charlebois; +Cc: 13053

> Date: Sat, 1 Dec 2012 21:57:54 -0500
> From: Erik Charlebois <erikcharlebois@gmail.com>
> 
> I've kept this patch going for a few years; probably time I get it in for
> real. I have not signed the FSF copyright assignment. If someone could give
> me some guidance on that (I'm Canadian), I'd appreciate it.
> 
> This patch adds fullscreen frame support to Windows so that setting the
> frame parameter 'fullscreen to 'fullboth makes the frame take up the entire
> screen, with no window decoration and covering the taskbar. The function:
> 
> (defun toggle-fullscreen ()
>   "Toggle full screen on X11"
>   (interactive)
>   (set-frame-parameter
>    nil 'fullscreen
>    (when (not (frame-parameter nil 'fullscreen)) 'fullboth)))
> 
> now has the same behavior on X11 and Windows. There's a bit of added
> complexity to support multiple monitors and resolution changes correctly.

Thanks.  Since this is a substantial contribution, I looked in the FSF
copyright assignment records before even trying to read the changes.
I don't find your name on file there.  If you are willing to sign
legal papers, I'll ask Stefan or Chong to send you the paperwork
off-list.  Then we can consider your contribution.

Thanks again for working on this.





^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#13053: PATCH: Fullscreen frame support on Windows
  2012-12-02 17:38 ` Eli Zaretskii
@ 2012-12-02 20:05   ` Glenn Morris
  2012-12-03 10:17     ` Chong Yidong
  0 siblings, 1 reply; 6+ messages in thread
From: Glenn Morris @ 2012-12-02 20:05 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 13053

Eli Zaretskii wrote:

> Thanks.  Since this is a substantial contribution, I looked in the FSF
> copyright assignment records before even trying to read the changes.
> I don't find your name on file there.  If you are willing to sign
> legal papers, I'll ask Stefan or Chong to send you the paperwork
> off-list.

If you can read the file recording existing assignments (I assume you
were looking at /gd/gnuorg/copyright.list), then you yourself can read
and send the necessary form. There's no need for the head maintainers to
do it. The normal form is /gd/gnuorg/Copyright/request-assign.future.





^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#13053: PATCH: Fullscreen frame support on Windows
  2012-12-02 20:05   ` Glenn Morris
@ 2012-12-03 10:17     ` Chong Yidong
  2016-02-24  5:59       ` Lars Ingebrigtsen
  0 siblings, 1 reply; 6+ messages in thread
From: Chong Yidong @ 2012-12-03 10:17 UTC (permalink / raw)
  To: Glenn Morris; +Cc: 13053

Glenn Morris <rgm@gnu.org> writes:

>> Thanks.  Since this is a substantial contribution, I looked in the FSF
>> copyright assignment records before even trying to read the changes.
>> I don't find your name on file there.  If you are willing to sign
>> legal papers, I'll ask Stefan or Chong to send you the paperwork
>> off-list.
>
> If you can read the file recording existing assignments (I assume you
> were looking at /gd/gnuorg/copyright.list), then you yourself can read
> and send the necessary form. There's no need for the head maintainers to
> do it. The normal form is /gd/gnuorg/Copyright/request-assign.future.

Yeah.  Anyhow, I've just sent the form to Erik.





^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#13053: PATCH: Fullscreen frame support on Windows
  2012-12-03 10:17     ` Chong Yidong
@ 2016-02-24  5:59       ` Lars Ingebrigtsen
  2016-02-24 10:15         ` martin rudalics
  0 siblings, 1 reply; 6+ messages in thread
From: Lars Ingebrigtsen @ 2016-02-24  5:59 UTC (permalink / raw)
  To: Chong Yidong; +Cc: 13053

Chong Yidong <cyd@gnu.org> writes:

> Glenn Morris <rgm@gnu.org> writes:
>
>>> Thanks.  Since this is a substantial contribution, I looked in the FSF
>>> copyright assignment records before even trying to read the changes.
>>> I don't find your name on file there.  If you are willing to sign
>>> legal papers, I'll ask Stefan or Chong to send you the paperwork
>>> off-list.
>>
>> If you can read the file recording existing assignments (I assume you
>> were looking at /gd/gnuorg/copyright.list), then you yourself can read
>> and send the necessary form. There's no need for the head maintainers to
>> do it. The normal form is /gd/gnuorg/Copyright/request-assign.future.
>
> Yeah.  Anyhow, I've just sent the form to Erik.

If I'm reading the patch and the w32fns source right, this has been
applied now, and I'm closing this bug report.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#13053: PATCH: Fullscreen frame support on Windows
  2016-02-24  5:59       ` Lars Ingebrigtsen
@ 2016-02-24 10:15         ` martin rudalics
  0 siblings, 0 replies; 6+ messages in thread
From: martin rudalics @ 2016-02-24 10:15 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 13053

 > If I'm reading the patch and the w32fns source right, this has been
 > applied now, and I'm closing this bug report.

It has not been applied.  But since Erik apparently disappeared there's
not much we can do about this anyway.

martin





^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-02-24 10:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-02  2:57 bug#13053: PATCH: Fullscreen frame support on Windows Erik Charlebois
2012-12-02 17:38 ` Eli Zaretskii
2012-12-02 20:05   ` Glenn Morris
2012-12-03 10:17     ` Chong Yidong
2016-02-24  5:59       ` Lars Ingebrigtsen
2016-02-24 10:15         ` martin rudalics

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).