/* Graphical user interface functions for the Microsoft W32 API.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
#include <shellapi.h>
#include <ctype.h>
#include <winspool.h>
+#include <objbase.h>
#include <dlgs.h>
#define FILE_NAME_TEXT_FIELD edt1
static HWND w32_visible_system_caret_hwnd;
+/* From w32menu.c */
+extern HMENU current_popup_menu;
+static int menubar_in_use = 0;
+
\f
/* Error if we are not connected to MS-Windows. */
void
POINT pt;
RECT rect;
- GetClientRect(FRAME_W32_WINDOW(f), &rect);
- AdjustWindowRect(&rect, f->output_data.w32->dwStyle, FRAME_EXTERNAL_MENU_BAR(f));
+ /* Get the bounds of the WM window. */
+ GetWindowRect (FRAME_W32_WINDOW (f), &rect);
- pt.x = rect.left;
- pt.y = rect.top;
+ pt.x = 0;
+ pt.y = 0;
- ClientToScreen (FRAME_W32_WINDOW(f), &pt);
+ /* Convert (0, 0) in the client area to screen co-ordinates. */
+ ClientToScreen (FRAME_W32_WINDOW (f), &pt);
/* Remember x_pixels_diff and y_pixels_diff. */
f->x_pixels_diff = pt.x - rect.left;
f->y_pixels_diff = pt.y - rect.top;
- *xptr = pt.x;
- *yptr = pt.y;
+ *xptr = rect.left;
+ *yptr = rect.top;
}
\f
below the menu bar. */
if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
{
- updating_frame = f;
- clear_frame ();
+ clear_frame (f);
clear_current_matrices (f);
- updating_frame = NULL;
}
/* If the tool bar gets smaller, the internal border below it
/* Produced by complete_deferred_msg; just ignore. */
break;
case WM_EMACS_CREATEWINDOW:
+ /* Initialize COM for this window. Even though we don't use it,
+ some third party shell extensions can cause it to be used in
+ system dialogs, which causes a crash if it is not initialized.
+ This is a known bug in Windows, which was fixed long ago, but
+ the patch for XP is not publically available until XP SP3,
+ and older versions will never be patched. */
+ CoInitialize (NULL);
w32_createwindow ((struct frame *) msg.wParam);
if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
abort ();
return 0;
case WM_MOUSEWHEEL:
+ case WM_DROPFILES:
wmsg.dwModifiers = w32_get_modifiers ();
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
signal_user_input ();
return 0;
- case WM_DROPFILES:
+ case WM_MOUSEHWHEEL:
wmsg.dwModifiers = w32_get_modifiers ();
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
signal_user_input ();
- return 0;
+ /* Non-zero must be returned when WM_MOUSEHWHEEL messages are
+ handled, to prevent the system trying to handle it by faking
+ scroll bar events. */
+ return 1;
case WM_TIMER:
/* Flush out saved messages if necessary. */
KillTimer (hwnd, menu_free_timer);
menu_free_timer = 0;
f = x_window_to_frame (dpyinfo, hwnd);
- if (!f->output_data.w32->menu_command_in_progress)
+ /* If a popup menu is active, don't wipe its strings. */
+ if (menubar_in_use
+ && current_popup_menu == NULL)
{
/* Free memory used by owner-drawn and help-echo strings. */
w32_free_menu_strings (hwnd);
f->output_data.w32->menubar_active = 0;
+ menubar_in_use = 0;
}
}
return 0;
if (find_deferred_msg (hwnd, msg) != NULL)
abort ();
+ menubar_in_use = 1;
+
return send_deferred_msg (&msg_buf, hwnd, msg, wParam, lParam);
}
case WM_EXITMENULOOP:
f = x_window_to_frame (dpyinfo, hwnd);
- /* If a menu command is not already in progress, check again
- after a short delay, since Windows often (always?) sends the
- WM_EXITMENULOOP before the corresponding WM_COMMAND message. */
- if (f && !f->output_data.w32->menu_command_in_progress)
+ /* If a menu is still active, check again after a short delay,
+ since Windows often (always?) sends the WM_EXITMENULOOP
+ before the corresponding WM_COMMAND message.
+ Don't do this if a popup menu is active, since it is only
+ menubar menus that require cleaning up in this way.
+ */
+ if (f && menubar_in_use && current_popup_menu == NULL)
menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
goto dflt;
}
goto command;
case WM_COMMAND:
+ menubar_in_use = 0;
f = x_window_to_frame (dpyinfo, hwnd);
if (f && HIWORD (wParam) == 0)
{
- f->output_data.w32->menu_command_in_progress = 1;
if (menu_free_timer)
{
KillTimer (hwnd, menu_free_timer);
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
goto dflt;
+ case WM_DESTROY:
+ CoUninitialize ();
+ return 0;
+
case WM_CLOSE:
wmsg.dwModifiers = w32_get_modifiers ();
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
display = Qnil;
dpyinfo = check_x_display_info (display);
#ifdef MULTI_KBOARD
- kb = dpyinfo->kboard;
+ kb = dpyinfo->terminal->kboard;
#else
kb = &the_only_kboard;
#endif
/* By default, make scrollbars the system standard width. */
FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
+ f->terminal = dpyinfo->terminal;
+ f->terminal->reference_count++;
+
f->output_method = output_w32;
f->output_data.w32 =
(struct w32_output *) xmalloc (sizeof (struct w32_output));
/* Must have been Qnil. */
;
}
+
+ /* Initialize `default-minibuffer-frame' in case this is the first
+ frame on this terminal. */
+ if (FRAME_HAS_MINIBUF_P (f)
+ && (!FRAMEP (kb->Vdefault_minibuffer_frame)
+ || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
+ kb->Vdefault_minibuffer_frame = frame;
+
+ /* All remaining specified parameters, which have not been "used"
+ by x_get_arg and friends, now go in the misc. alist of the frame. */
+ for (tem = parameters; !NILP (tem); tem = XCDR (tem))
+ if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+ f->param_alist = Fcons (XCAR (tem), f->param_alist);
+
+ store_frame_param (f, Qwindow_system, Qw32);
+
UNGCPRO;
/* Make sure windows on this frame appear in calls to next-window
if (! NILP (xrm_string))
CHECK_STRING (xrm_string);
+#if 0
if (! EQ (Vwindow_system, intern ("w32")))
error ("Not using Microsoft Windows");
+#endif
/* Allow color mapping to be defined externally; first look in user's
HOME directory, then in Emacs etc dir for a file called rgb.txt. */
Vx_resource_name = Vinvocation_name;
#ifdef MULTI_KBOARD
- kb = dpyinfo->kboard;
+ kb = dpyinfo->terminal->kboard;
#else
kb = &the_only_kboard;
#endif
the frame is live, as per FRAME_LIVE_P. If we get a signal
from this point on, x_destroy_window might screw up reference
counts etc. */
+ f->terminal = dpyinfo->terminal;
+ f->terminal->reference_count++;
f->output_method = output_w32;
f->output_data.w32 =
(struct w32_output *) xmalloc (sizeof (struct w32_output));
Qnil));
}
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qw32), Qnil));
+
f->no_split = 1;
UNGCPRO;
doc: /* Show STRING in a \"tooltip\" window on frame FRAME.
A tooltip window is a small window displaying a string.
+This is an internal function; Lisp code should call `tooltip-show'.
+
FRAME nil or omitted means use the selected frame.
PARMS is an optional list of frame parameters which can be
/* Apparently NT4 crashes if you give it an unexpected size.
I'm not sure about Windows 9x, so play it safe. */
if (w32_major_version > 4 && w32_major_version < 95)
- file_details->lStructSize = sizeof (new_file_details);
+ file_details->lStructSize = sizeof (NEWOPENFILENAME);
else
- file_details->lStructSize = sizeof (file_details);
+ file_details->lStructSize = sizeof (OPENFILENAME);
file_details->hwndOwner = FRAME_W32_WINDOW (f);
/* Undocumented Bug in Common File Dialog: