X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/929aeac608c271b2448dffec29aeea85c69d6bff..00382e8b9834e58203507d0461884671b78ebc01:/src/w32fns.c diff --git a/src/w32fns.c b/src/w32fns.c index 5fab2c9a3d..4cbbe1d5a8 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -95,10 +95,6 @@ static HWND hourglass_hwnd = NULL; #define IDC_HAND MAKEINTRESOURCE(32649) #endif -/* Nonzero if using Windows. */ - -static int w32_in_use; - Lisp_Object Qsuppress_icon; Lisp_Object Qundefined_color; Lisp_Object Qcancel_timer; @@ -110,6 +106,7 @@ Lisp_Object Qalt; Lisp_Object Qctrl; Lisp_Object Qcontrol; Lisp_Object Qshift; +static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes; /* Prefix for system colors. */ @@ -135,6 +132,15 @@ static HWND track_mouse_window; #ifndef MONITOR_DEFAULT_TO_NEAREST #define MONITOR_DEFAULT_TO_NEAREST 2 #endif +#ifndef MONITORINFOF_PRIMARY +#define MONITORINFOF_PRIMARY 1 +#endif +#ifndef SM_XVIRTUALSCREEN +#define SM_XVIRTUALSCREEN 76 +#endif +#ifndef SM_YVIRTUALSCREEN +#define SM_YVIRTUALSCREEN 77 +#endif /* MinGW headers define MONITORINFO unconditionally, but MSVC ones don't. To avoid a compile error on one or the other, redefine with a new name. */ struct MONITOR_INFO @@ -145,6 +151,18 @@ struct MONITOR_INFO DWORD dwFlags; }; +#ifndef CCHDEVICENAME +#define CCHDEVICENAME 32 +#endif +struct MONITOR_INFO_EX +{ + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; + char szDevice[CCHDEVICENAME]; +}; + /* Reportedly, MSVC does not have this in its headers. */ #if defined (_MSC_VER) && _WIN32_WINNT < 0x0500 DECLARE_HANDLE(HMONITOR); @@ -161,6 +179,12 @@ typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, 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 (* MonitorEnum_Proc) + (IN HMONITOR monitor, IN HDC hdc, IN RECT *rcMonitor, IN LPARAM dwData); +typedef BOOL (WINAPI * EnumDisplayMonitors_Proc) + (IN HDC hdc, IN RECT *rcClip, IN MonitorEnum_Proc fnEnum, IN LPARAM dwData); TrackMouseEvent_Proc track_mouse_event_fn = NULL; ImmGetCompositionString_Proc get_composition_string_fn = NULL; @@ -169,6 +193,8 @@ ImmReleaseContext_Proc release_ime_context_fn = NULL; 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 @@ -239,37 +265,6 @@ HINSTANCE hinst = NULL; static unsigned int sound_type = 0xFFFFFFFF; #define MB_EMACS_SILENT (0xFFFFFFFF - 1) - -/* Error if we are not connected to MS-Windows. */ -void -check_w32 (void) -{ - if (! w32_in_use) - error ("MS-Windows not in use or not initialized"); -} - -/* Nonzero if we can use mouse menus. - You should not call this unless HAVE_MENUS is defined. */ - -int -have_menus_p (void) -{ - return w32_in_use; -} - -/* Extract a frame as a FRAME_PTR, defaulting to the selected frame - and checking validity for W32. */ - -FRAME_PTR -check_x_frame (Lisp_Object frame) -{ - struct frame *f = decode_live_frame (frame); - - if (! FRAME_W32_P (f)) - error ("Non-W32 frame used"); - return f; -} - /* Let the user specify a display with a frame. nil stands for the selected frame--or, if that is not a w32 frame, the first display on the list. */ @@ -282,7 +277,7 @@ check_x_display_info (Lisp_Object frame) struct frame *sf = XFRAME (selected_frame); if (FRAME_W32_P (sf) && FRAME_LIVE_P (sf)) - return FRAME_W32_DISPLAY_INFO (sf); + return FRAME_DISPLAY_INFO (sf); else return &one_w32_display_info; } @@ -290,13 +285,13 @@ check_x_display_info (Lisp_Object frame) return x_display_info_for_name (frame); else { - FRAME_PTR f; + struct frame *f; CHECK_LIVE_FRAME (frame); f = XFRAME (frame); if (! FRAME_W32_P (f)) error ("Non-W32 frame used"); - return FRAME_W32_DISPLAY_INFO (f); + return FRAME_DISPLAY_INFO (f); } } @@ -312,7 +307,7 @@ x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc) FOR_EACH_FRAME (tail, frame) { f = XFRAME (frame); - if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo) + if (!FRAME_W32_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo) continue; if (FRAME_W32_WINDOW (f) == wdesc) @@ -323,7 +318,7 @@ x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc) static Lisp_Object unwind_create_frame (Lisp_Object); -static Lisp_Object unwind_create_tip_frame (Lisp_Object); +static void unwind_create_tip_frame (Lisp_Object); static void my_create_window (struct frame *); static void my_create_tip_window (struct frame *); @@ -349,7 +344,7 @@ void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object); not Emacs's own window. */ void -x_real_positions (FRAME_PTR f, int *xptr, int *yptr) +x_real_positions (struct frame *f, int *xptr, int *yptr) { POINT pt; RECT rect; @@ -371,6 +366,66 @@ x_real_positions (FRAME_PTR f, int *xptr, int *yptr) *yptr = rect.top; } +/* Returns the window rectangle appropriate for the given fullscreen mode. + The normal rect parameter was the window's rectangle prior to entering + fullscreen mode. If multiple monitor support is available, the nearest + monitor to the window is chosen. */ + +void +w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, RECT *rect) +{ + struct MONITOR_INFO mi = { sizeof(mi) }; + if (monitor_from_window_fn && get_monitor_info_fn) + { + HMONITOR monitor = + monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST); + get_monitor_info_fn (monitor, &mi); + } + else + { + mi.rcMonitor.left = 0; + mi.rcMonitor.top = 0; + mi.rcMonitor.right = GetSystemMetrics (SM_CXSCREEN); + mi.rcMonitor.bottom = GetSystemMetrics (SM_CYSCREEN); + mi.rcWork.left = 0; + mi.rcWork.top = 0; + mi.rcWork.right = GetSystemMetrics (SM_CXMAXIMIZED); + mi.rcWork.bottom = GetSystemMetrics (SM_CYMAXIMIZED); + } + + switch (fsmode) + { + case FULLSCREEN_BOTH: + rect->left = mi.rcMonitor.left; + rect->top = mi.rcMonitor.top; + rect->right = mi.rcMonitor.right; + rect->bottom = mi.rcMonitor.bottom; + break; + case FULLSCREEN_MAXIMIZED: + rect->left = mi.rcWork.left; + rect->top = mi.rcWork.top; + rect->right = mi.rcWork.right; + rect->bottom = mi.rcWork.bottom; + break; + case FULLSCREEN_WIDTH: + rect->left = mi.rcWork.left; + rect->top = normal.top; + rect->right = mi.rcWork.right; + rect->bottom = normal.bottom; + break; + case FULLSCREEN_HEIGHT: + rect->left = normal.left; + rect->top = mi.rcWork.top; + rect->right = normal.right; + rect->bottom = mi.rcWork.bottom; + break; + case FULLSCREEN_NONE: + default: + *rect = normal; + break; + } +} + DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color, @@ -964,7 +1019,7 @@ x_to_w32_color (const char * colorname) } void -w32_regenerate_palette (FRAME_PTR f) +w32_regenerate_palette (struct frame *f) { struct w32_palette_entry * list; LOGPALETTE * log_palette; @@ -972,18 +1027,18 @@ w32_regenerate_palette (FRAME_PTR f) int i; /* don't bother trying to create palette if not supported */ - if (! FRAME_W32_DISPLAY_INFO (f)->has_palette) + if (! FRAME_DISPLAY_INFO (f)->has_palette) return; log_palette = (LOGPALETTE *) alloca (sizeof (LOGPALETTE) + - FRAME_W32_DISPLAY_INFO (f)->num_colors * sizeof (PALETTEENTRY)); + FRAME_DISPLAY_INFO (f)->num_colors * sizeof (PALETTEENTRY)); log_palette->palVersion = 0x300; - log_palette->palNumEntries = FRAME_W32_DISPLAY_INFO (f)->num_colors; + log_palette->palNumEntries = FRAME_DISPLAY_INFO (f)->num_colors; - list = FRAME_W32_DISPLAY_INFO (f)->color_list; + list = FRAME_DISPLAY_INFO (f)->color_list; for (i = 0; - i < FRAME_W32_DISPLAY_INFO (f)->num_colors; + i < FRAME_DISPLAY_INFO (f)->num_colors; i++, list = list->next) log_palette->palPalEntry[i] = list->entry; @@ -991,9 +1046,9 @@ w32_regenerate_palette (FRAME_PTR f) enter_crit (); - if (FRAME_W32_DISPLAY_INFO (f)->palette) - DeleteObject (FRAME_W32_DISPLAY_INFO (f)->palette); - FRAME_W32_DISPLAY_INFO (f)->palette = new_palette; + if (FRAME_DISPLAY_INFO (f)->palette) + DeleteObject (FRAME_DISPLAY_INFO (f)->palette); + FRAME_DISPLAY_INFO (f)->palette = new_palette; /* Realize display palette and garbage all frames. */ release_frame_dc (f, get_frame_dc (f)); @@ -1014,9 +1069,9 @@ w32_regenerate_palette (FRAME_PTR f) #if 0 /* Keep these around in case we ever want to track color usage. */ void -w32_map_color (FRAME_PTR f, COLORREF color) +w32_map_color (struct frame *f, COLORREF color) { - struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list; + struct w32_palette_entry * list = FRAME_DISPLAY_INFO (f)->color_list; if (NILP (Vw32_enable_palette)) return; @@ -1036,19 +1091,19 @@ w32_map_color (FRAME_PTR f, COLORREF color) list = xmalloc (sizeof (struct w32_palette_entry)); SET_W32_COLOR (list->entry, color); list->refcount = 1; - list->next = FRAME_W32_DISPLAY_INFO (f)->color_list; - FRAME_W32_DISPLAY_INFO (f)->color_list = list; - FRAME_W32_DISPLAY_INFO (f)->num_colors++; + list->next = FRAME_DISPLAY_INFO (f)->color_list; + FRAME_DISPLAY_INFO (f)->color_list = list; + FRAME_DISPLAY_INFO (f)->num_colors++; /* set flag that palette must be regenerated */ - FRAME_W32_DISPLAY_INFO (f)->regen_palette = TRUE; + FRAME_DISPLAY_INFO (f)->regen_palette = TRUE; } void -w32_unmap_color (FRAME_PTR f, COLORREF color) +w32_unmap_color (struct frame *f, COLORREF color) { - struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list; - struct w32_palette_entry **prev = &FRAME_W32_DISPLAY_INFO (f)->color_list; + struct w32_palette_entry * list = FRAME_DISPLAY_INFO (f)->color_list; + struct w32_palette_entry **prev = &FRAME_DISPLAY_INFO (f)->color_list; if (NILP (Vw32_enable_palette)) return; @@ -1062,7 +1117,7 @@ w32_unmap_color (FRAME_PTR f, COLORREF color) { *prev = list->next; xfree (list); - FRAME_W32_DISPLAY_INFO (f)->num_colors--; + FRAME_DISPLAY_INFO (f)->num_colors--; break; } else @@ -1073,7 +1128,7 @@ w32_unmap_color (FRAME_PTR f, COLORREF color) } /* set flag that palette must be regenerated */ - FRAME_W32_DISPLAY_INFO (f)->regen_palette = TRUE; + FRAME_DISPLAY_INFO (f)->regen_palette = TRUE; } #endif @@ -1098,7 +1153,7 @@ gamma_correct (struct frame *f, COLORREF *color) If ALLOC is nonzero, allocate a new colormap cell. */ int -w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc) +w32_defined_color (struct frame *f, const char *color, XColor *color_def, int alloc) { register Lisp_Object tem; COLORREF w32_color_ref; @@ -1169,7 +1224,7 @@ w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc) ARG says. */ int -x_decode_color (FRAME_PTR f, Lisp_Object arg, int def) +x_decode_color (struct frame *f, Lisp_Object arg, int def) { XColor cdef; @@ -1180,7 +1235,7 @@ x_decode_color (FRAME_PTR f, Lisp_Object arg, int def) else if (strcmp (SDATA (arg), "white") == 0) return WHITE_PIX_DEFAULT (f); - if ((FRAME_W32_DISPLAY_INFO (f)->n_planes * FRAME_W32_DISPLAY_INFO (f)->n_cbits) == 1) + if ((FRAME_DISPLAY_INFO (f)->n_planes * FRAME_DISPLAY_INFO (f)->n_cbits) == 1) return def; /* w32_defined_color is responsible for coping with failures @@ -1470,14 +1525,11 @@ x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) void -x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { set_frame_cursor_types (f, arg); - - /* Make sure the cursor gets redrawn. */ - cursor_type_changed = 1; } - + void x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { @@ -1585,7 +1637,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); do_pending_window_change (0); } - adjust_glyphs (f); + adjust_frame_glyphs (f); } @@ -1627,7 +1679,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) FRAME_TOOL_BAR_LINES (f) = nlines; resize_frame_windows (f, FRAME_LINES (f), 0); - adjust_glyphs (f); + adjust_frame_glyphs (f); /* We also have to make sure that the internal border at the top of the frame, below the menu bar or tool bar, is redrawn when the @@ -1700,10 +1752,10 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit) { /* Check for no change needed in this very common case before we do any consing. */ - if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->w32_id_name, + if (!strcmp (FRAME_DISPLAY_INFO (f)->w32_id_name, SDATA (f->name))) return; - name = build_string (FRAME_W32_DISPLAY_INFO (f)->w32_id_name); + name = build_string (FRAME_DISPLAY_INFO (f)->w32_id_name); } else CHECK_STRING (name); @@ -1721,11 +1773,9 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit) if (FRAME_W32_WINDOW (f)) { - if (STRING_MULTIBYTE (name)) - name = ENCODE_SYSTEM (name); - block_input (); - SetWindowText (FRAME_W32_WINDOW (f), SDATA (name)); + GUI_FN (SetWindowText) (FRAME_W32_WINDOW (f), + GUI_SDATA (GUI_ENCODE_SYSTEM (name))); unblock_input (); } } @@ -1734,7 +1784,7 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit) specified a name for the frame; the name will override any set by the redisplay code. */ void -x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { x_set_name (f, arg, 1); } @@ -1743,7 +1793,7 @@ x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) name; names set this way will never override names set by the user's lisp code. */ void -x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { x_set_name (f, arg, 0); } @@ -1767,11 +1817,9 @@ x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name) if (FRAME_W32_WINDOW (f)) { - if (STRING_MULTIBYTE (name)) - name = ENCODE_SYSTEM (name); - block_input (); - SetWindowText (FRAME_W32_WINDOW (f), SDATA (name)); + GUI_FN (SetWindowText) (FRAME_W32_WINDOW (f), + GUI_SDATA (GUI_ENCODE_SYSTEM (name))); unblock_input (); } } @@ -1842,16 +1890,11 @@ w32_init_class (HINSTANCE hinst) static HWND w32_createscrollbar (struct frame *f, struct scroll_bar * bar) { - return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE, - /* Position and size of scroll bar. */ - XINT (bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM, - XINT (bar->top), - XINT (bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, - XINT (bar->height), - FRAME_W32_WINDOW (f), - NULL, - hinst, - NULL)); + return CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE, + /* Position and size of scroll bar. */ + XINT (bar->left), XINT (bar->top), + XINT (bar->width), XINT (bar->height), + FRAME_W32_WINDOW (f), NULL, hinst, NULL); } static void @@ -3151,8 +3194,24 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) HIMC context; struct window *w; + /* Implementation note: The code below does something that + one shouldn't do: it accesses the window object from a + separate thread, while the main (a.k.a. "Lisp") thread + runs and can legitimately delete and even GC it. That is + why we are extra careful not to futz with a window that + is different from the one recorded when the system caret + coordinates were last modified. That is also why we are + careful not to move the IME window if the window + described by W was deleted, as indicated by its buffer + field being reset to nil. */ f = x_window_to_frame (dpyinfo, hwnd); + if (!(f && FRAME_LIVE_P (f))) + break; w = XWINDOW (FRAME_SELECTED_WINDOW (f)); + /* Punt if someone changed the frame's selected window + behind our back. */ + if (w != w32_system_caret_window) + break; form.dwStyle = CFS_RECT; form.ptCurrentPos.x = w32_system_caret_x; @@ -3160,12 +3219,16 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0); form.rcArea.top = (WINDOW_TOP_EDGE_Y (w) - + WINDOW_HEADER_LINE_HEIGHT (w)); + + w32_system_caret_hdr_height); form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w) - WINDOW_RIGHT_MARGIN_WIDTH (w) - WINDOW_RIGHT_FRINGE_WIDTH (w)); form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w) - - WINDOW_MODE_LINE_HEIGHT (w)); + - w32_system_caret_mode_height); + + /* Punt if the window was deleted behind our back. */ + if (!BUFFERP (w->contents)) + break; context = get_ime_context_fn (hwnd); @@ -3712,6 +3775,13 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Don't restrict the sizing of tip frames. */ if (hwnd == tip_window) return 0; + + /* Don't restrict the sizing of fullscreened frames, allowing them to be + flush with the sides of the screen. */ + f = x_window_to_frame (dpyinfo, hwnd); + if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE) + return 0; + { WINDOWPLACEMENT wp; LPWINDOWPOS lppos = (WINDOWPOS *) lParam; @@ -4046,12 +4116,7 @@ w32_window (struct frame *f, long window_prompting, int minibuffer_only) for the window manager, so GC relocation won't bother it. Elsewhere we specify the window name for the window manager. */ - - { - char *str = SSDATA (Vx_resource_name); - f->namebuf = xmalloc (strlen (str) + 1); - strcpy (f->namebuf, str); - } + f->namebuf = xstrdup (SSDATA (Vx_resource_name)); my_create_window (f); @@ -4104,9 +4169,6 @@ x_icon (struct frame *f, Lisp_Object parms) block_input (); - if (! EQ (icon_x, Qunbound)) - x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y)); - #if 0 /* TODO */ /* Start up iconic or window? */ x_wm_set_window_state @@ -4165,7 +4227,7 @@ unwind_create_frame (Lisp_Object frame) if (NILP (Fmemq (frame, Vframe_list))) { #ifdef GLYPH_DEBUG - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); + struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); #endif x_free_frame_resources (f); @@ -4182,10 +4244,16 @@ unwind_create_frame (Lisp_Object frame) return Qnil; } +static void +do_unwind_create_frame (Lisp_Object frame) +{ + unwind_create_frame (frame); +} + static void x_default_font_parameter (struct frame *f, Lisp_Object parms) { - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); + struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL, RES_TYPE_STRING); Lisp_Object font; @@ -4319,10 +4387,10 @@ This function is an internal primitive--use `make-frame' instead. */) if (! STRINGP (f->icon_name)) fset_icon_name (f, Qnil); -/* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */ +/* FRAME_DISPLAY_INFO (f) = dpyinfo; */ - /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */ - record_unwind_protect (unwind_create_frame, frame); + /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */ + record_unwind_protect (do_unwind_create_frame, frame); #ifdef GLYPH_DEBUG image_cache_refcount = FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; @@ -4338,7 +4406,7 @@ This function is an internal primitive--use `make-frame' instead. */) } else { - f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; + f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; f->output_data.w32->explicit_parent = 0; } @@ -4357,9 +4425,6 @@ This function is an internal primitive--use `make-frame' instead. */) specbind (Qx_resource_name, name); } - f->resx = dpyinfo->resx; - f->resy = dpyinfo->resy; - if (uniscribe_available) register_font_driver (&uniscribe_font_driver, f); register_font_driver (&w32font_driver, f); @@ -4436,7 +4501,7 @@ This function is an internal primitive--use `make-frame' instead. */) "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; - f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; + f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM); f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW); @@ -4459,7 +4524,7 @@ This function is an internal primitive--use `make-frame' instead. */) /* Now consider the frame official. */ f->terminal->reference_count++; - FRAME_W32_DISPLAY_INFO (f)->reference_count++; + FRAME_DISPLAY_INFO (f)->reference_count++; Vframe_list = Fcons (frame, Vframe_list); /* We need to do this after creating the window, so that the @@ -4543,7 +4608,7 @@ This function is an internal primitive--use `make-frame' instead. */) Lisp_Object x_get_focus_frame (struct frame *frame) { - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (frame); + struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame); Lisp_Object xfocus; if (! dpyinfo->w32_focus_frame) return Qnil; @@ -4552,22 +4617,13 @@ x_get_focus_frame (struct frame *frame) return xfocus; } -DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0, - doc: /* Give FRAME input focus, raising to foreground if necessary. */) - (Lisp_Object frame) -{ - x_focus_on_frame (check_x_frame (frame)); - return Qnil; -} - - DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0, doc: /* Internal function called by `color-defined-p', which see. \(Note that the Nextstep version of this function ignores FRAME.) */) (Lisp_Object color, Lisp_Object frame) { XColor foo; - FRAME_PTR f = check_x_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHECK_STRING (color); @@ -4582,17 +4638,14 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0, (Lisp_Object color, Lisp_Object frame) { XColor foo; - FRAME_PTR f = check_x_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHECK_STRING (color); if (w32_defined_color (f, SDATA (color), &foo, 0)) - return list3 (make_number ((GetRValue (foo.pixel) << 8) - | GetRValue (foo.pixel)), - make_number ((GetGValue (foo.pixel) << 8) - | GetGValue (foo.pixel)), - make_number ((GetBValue (foo.pixel) << 8) - | GetBValue (foo.pixel))); + return list3i ((GetRValue (foo.pixel) << 8) | GetRValue (foo.pixel), + (GetGValue (foo.pixel) << 8) | GetGValue (foo.pixel), + (GetBValue (foo.pixel) << 8) | GetBValue (foo.pixel)); else return Qnil; } @@ -4631,7 +4684,11 @@ DEFUN ("x-display-pixel-width", Fx_display_pixel_width, doc: /* Return the width in pixels of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). -If omitted or nil, that stands for the selected frame's display. */) +If omitted or nil, that stands for the selected frame's display. + +On \"multi-monitor\" setups this refers to the pixel width for all +physical monitors associated with DISPLAY. To get information for +each physical monitor, use `display-monitor-attributes-list'. */) (Lisp_Object display) { struct w32_display_info *dpyinfo = check_x_display_info (display); @@ -4644,7 +4701,11 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height, doc: /* Return the height in pixels of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). -If omitted or nil, that stands for the selected frame's display. */) +If omitted or nil, that stands for the selected frame's display. + +On \"multi-monitor\" setups this refers to the pixel height for all +physical monitors associated with DISPLAY. To get information for +each physical monitor, use `display-monitor-attributes-list'. */) (Lisp_Object display) { struct w32_display_info *dpyinfo = check_x_display_info (display); @@ -4718,9 +4779,7 @@ DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (Lisp_Object display) { - return Fcons (make_number (w32_major_version), - Fcons (make_number (w32_minor_version), - Fcons (make_number (w32_build_number), Qnil))); + return list3i (w32_major_version, w32_minor_version, w32_build_number); } DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0, @@ -4738,41 +4797,46 @@ DEFUN ("x-display-mm-height", Fx_display_mm_height, doc: /* Return the height in millimeters of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). -If omitted or nil, that stands for the selected frame's display. */) +If omitted or nil, that stands for the selected frame's display. + +On \"multi-monitor\" setups this refers to the height in millimeters for +all physical monitors associated with DISPLAY. To get information +for each physical monitor, use `display-monitor-attributes-list'. */) (Lisp_Object display) { struct w32_display_info *dpyinfo = check_x_display_info (display); HDC hdc; - int cap; - - hdc = GetDC (dpyinfo->root_window); - - cap = GetDeviceCaps (hdc, VERTSIZE); + double mm_per_pixel; - ReleaseDC (dpyinfo->root_window, hdc); + hdc = GetDC (NULL); + mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE) + / GetDeviceCaps (hdc, VERTRES)); + ReleaseDC (NULL, hdc); - return make_number (cap); + return make_number (x_display_pixel_height (dpyinfo) * mm_per_pixel + 0.5); } DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0, doc: /* Return the width in millimeters of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). -If omitted or nil, that stands for the selected frame's display. */) +If omitted or nil, that stands for the selected frame's display. + +On \"multi-monitor\" setups this refers to the width in millimeters for +all physical monitors associated with TERMINAL. To get information +for each physical monitor, use `display-monitor-attributes-list'. */) (Lisp_Object display) { struct w32_display_info *dpyinfo = check_x_display_info (display); - HDC hdc; - int cap; - - hdc = GetDC (dpyinfo->root_window); + double mm_per_pixel; - cap = GetDeviceCaps (hdc, HORZSIZE); + hdc = GetDC (NULL); + mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE) + / GetDeviceCaps (hdc, HORZRES)); + ReleaseDC (NULL, hdc); - ReleaseDC (dpyinfo->root_window, hdc); - - return make_number (cap); + return make_number (x_display_pixel_width (dpyinfo) * mm_per_pixel + 0.5); } DEFUN ("x-display-backing-store", Fx_display_backing_store, @@ -4824,6 +4888,202 @@ If omitted or nil, that stands for the selected frame's display. */) return Qnil; } +static BOOL CALLBACK +w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData) +{ + Lisp_Object *monitor_list = (Lisp_Object *) dwData; + + *monitor_list = Fcons (make_save_ptr (monitor), *monitor_list); + + return TRUE; +} + +static Lisp_Object +w32_display_monitor_attributes_list (void) +{ + Lisp_Object attributes_list = Qnil, primary_monitor_attributes = Qnil; + Lisp_Object monitor_list = Qnil, monitor_frames, rest, frame; + int i, n_monitors; + HMONITOR *monitors; + struct gcpro gcpro1, gcpro2, gcpro3; + + if (!(enum_display_monitors_fn && get_monitor_info_fn + && monitor_from_window_fn)) + return Qnil; + + if (!enum_display_monitors_fn (NULL, NULL, w32_monitor_enum, + (LPARAM) &monitor_list) + || NILP (monitor_list)) + return Qnil; + + n_monitors = 0; + for (rest = monitor_list; CONSP (rest); rest = XCDR (rest)) + n_monitors++; + + monitors = xmalloc (n_monitors * sizeof (*monitors)); + for (i = 0; i < n_monitors; i++) + { + monitors[i] = XSAVE_POINTER (XCAR (monitor_list), 0); + monitor_list = XCDR (monitor_list); + } + + monitor_frames = Fmake_vector (make_number (n_monitors), Qnil); + FOR_EACH_FRAME (rest, frame) + { + struct frame *f = XFRAME (frame); + + if (FRAME_W32_P (f) && !EQ (frame, tip_frame)) + { + HMONITOR monitor = + monitor_from_window_fn (FRAME_W32_WINDOW (f), + MONITOR_DEFAULT_TO_NEAREST); + + for (i = 0; i < n_monitors; i++) + if (monitors[i] == monitor) + break; + + if (i < n_monitors) + ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i))); + } + } + + GCPRO3 (attributes_list, primary_monitor_attributes, monitor_frames); + + for (i = 0; i < n_monitors; i++) + { + Lisp_Object geometry, workarea, name, attributes = Qnil; + HDC hdc; + int width_mm, height_mm; + struct MONITOR_INFO_EX mi; + + mi.cbSize = sizeof (mi); + if (!get_monitor_info_fn (monitors[i], (struct MONITOR_INFO *) &mi)) + continue; + + hdc = CreateDCA ("DISPLAY", mi.szDevice, NULL, NULL); + if (hdc == NULL) + continue; + width_mm = GetDeviceCaps (hdc, HORZSIZE); + height_mm = GetDeviceCaps (hdc, VERTSIZE); + DeleteDC (hdc); + + attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), + attributes); + + name = DECODE_SYSTEM (build_unibyte_string (mi.szDevice)); + + attributes = Fcons (Fcons (Qname, name), attributes); + + attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)), + attributes); + + workarea = list4i (mi.rcWork.left, mi.rcWork.top, + mi.rcWork.right - mi.rcWork.left, + mi.rcWork.bottom - mi.rcWork.top); + attributes = Fcons (Fcons (Qworkarea, workarea), attributes); + + geometry = list4i (mi.rcMonitor.left, mi.rcMonitor.top, + mi.rcMonitor.right - mi.rcMonitor.left, + mi.rcMonitor.bottom - mi.rcMonitor.top); + attributes = Fcons (Fcons (Qgeometry, geometry), attributes); + + if (mi.dwFlags & MONITORINFOF_PRIMARY) + primary_monitor_attributes = attributes; + else + attributes_list = Fcons (attributes, attributes_list); + } + + if (!NILP (primary_monitor_attributes)) + attributes_list = Fcons (primary_monitor_attributes, attributes_list); + + UNGCPRO; + + xfree (monitors); + + return attributes_list; +} + +static Lisp_Object +w32_display_monitor_attributes_list_fallback (struct w32_display_info *dpyinfo) +{ + Lisp_Object geometry, workarea, frames, rest, frame, attributes = Qnil; + HDC hdc; + double mm_per_pixel; + int pixel_width, pixel_height, width_mm, height_mm; + RECT workarea_rect; + + /* Fallback: treat (possibly) multiple physical monitors as if they + formed a single monitor as a whole. This should provide a + consistent result at least on single monitor environments. */ + attributes = Fcons (Fcons (Qname, build_string ("combined screen")), + attributes); + + frames = Qnil; + FOR_EACH_FRAME (rest, frame) + { + struct frame *f = XFRAME (frame); + + if (FRAME_W32_P (f) && !EQ (frame, tip_frame)) + frames = Fcons (frame, frames); + } + attributes = Fcons (Fcons (Qframes, frames), attributes); + + pixel_width = x_display_pixel_width (dpyinfo); + pixel_height = x_display_pixel_height (dpyinfo); + + hdc = GetDC (NULL); + mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE) + / GetDeviceCaps (hdc, HORZRES)); + width_mm = pixel_width * mm_per_pixel + 0.5; + mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE) + / GetDeviceCaps (hdc, VERTRES)); + height_mm = pixel_height * mm_per_pixel + 0.5; + ReleaseDC (NULL, hdc); + attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)), + attributes); + + /* GetSystemMetrics below may return 0 for Windows 95 or NT 4.0, but + we don't care. */ + geometry = list4i (GetSystemMetrics (SM_XVIRTUALSCREEN), + GetSystemMetrics (SM_YVIRTUALSCREEN), + pixel_width, pixel_height); + if (SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0)) + workarea = list4i (workarea_rect.left, workarea_rect.top, + workarea_rect.right - workarea_rect.left, + workarea_rect.bottom - workarea_rect.top); + else + workarea = geometry; + attributes = Fcons (Fcons (Qworkarea, workarea), attributes); + + attributes = Fcons (Fcons (Qgeometry, geometry), attributes); + + return list1 (attributes); +} + +DEFUN ("w32-display-monitor-attributes-list", Fw32_display_monitor_attributes_list, + Sw32_display_monitor_attributes_list, + 0, 1, 0, + doc: /* Return a list of physical monitor attributes on the W32 display DISPLAY. + +The optional argument DISPLAY specifies which display to ask about. +DISPLAY should be either a frame or a display name (a string). +If omitted or nil, that stands for the selected frame's display. + +Internal use only, use `display-monitor-attributes-list' instead. */) + (Lisp_Object display) +{ + struct w32_display_info *dpyinfo = check_x_display_info (display); + Lisp_Object attributes_list; + + block_input (); + attributes_list = w32_display_monitor_attributes_list (); + if (NILP (attributes_list)) + attributes_list = w32_display_monitor_attributes_list_fallback (dpyinfo); + unblock_input (); + + return attributes_list; +} + DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0, doc: /* Set the sound generated when the bell is rung. SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent @@ -4854,23 +5114,10 @@ SOUND is nil to use the normal beep. */) return sound; } - -int -x_pixel_width (register struct frame *f) -{ - return FRAME_PIXEL_WIDTH (f); -} - -int -x_pixel_height (register struct frame *f) -{ - return FRAME_PIXEL_HEIGHT (f); -} - int x_screen_planes (register struct frame *f) { - return FRAME_W32_DISPLAY_INFO (f)->n_planes; + return FRAME_DISPLAY_INFO (f)->n_planes; } /* Return the display structure for the display named NAME. @@ -4905,7 +5152,6 @@ x_display_info_for_name (Lisp_Object name) if (dpyinfo == 0) error ("Cannot connect to server %s", SDATA (name)); - w32_in_use = 1; XSETFASTINT (Vwindow_system_version, w32_major_version); return dpyinfo; @@ -4935,17 +5181,12 @@ terminate Emacs if we can't open the connection. /* If initialization has already been done, return now to avoid overwriting critical parts of one_w32_display_info. */ - if (w32_in_use) + if (window_system_available (NULL)) return Qnil; 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. */ { @@ -5004,8 +5245,6 @@ terminate Emacs if we can't open the connection. error ("Cannot connect to server %s", SDATA (display)); } - w32_in_use = 1; - XSETFASTINT (Vwindow_system_version, w32_major_version); return Qnil; } @@ -5089,7 +5328,7 @@ FRAME. Default is to change on the edit X window. */) (Lisp_Object prop, Lisp_Object value, Lisp_Object frame, Lisp_Object type, Lisp_Object format, Lisp_Object outer_p) { - struct frame *f = check_x_frame (frame); + struct frame *f = decode_window_system_frame (frame); Atom prop_atom; CHECK_STRING (prop); @@ -5115,7 +5354,7 @@ DEFUN ("x-delete-window-property", Fx_delete_window_property, FRAME nil or omitted means use the selected frame. Value is PROP. */) (Lisp_Object prop, Lisp_Object frame) { - struct frame *f = check_x_frame (frame); + struct frame *f = decode_window_system_frame (frame); Atom prop_atom; CHECK_STRING (prop); @@ -5151,7 +5390,7 @@ no value of TYPE (always string in the MS Windows case). */) (Lisp_Object prop, Lisp_Object frame, Lisp_Object type, Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p) { - struct frame *f = check_x_frame (frame); + struct frame *f = decode_window_system_frame (frame); Atom prop_atom; int rc; Lisp_Object prop_value = Qnil; @@ -5311,7 +5550,7 @@ Window tip_window; Lisp_Object last_show_tip_args; -static Lisp_Object +static void unwind_create_tip_frame (Lisp_Object frame) { Lisp_Object deleted; @@ -5322,8 +5561,6 @@ unwind_create_tip_frame (Lisp_Object frame) tip_window = NULL; tip_frame = Qnil; } - - return deleted; } @@ -5352,8 +5589,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object buffer; struct buffer *old_buffer; - check_w32 (); - /* Use this general default value to start with until we know if this frame has a specified name. */ Vx_resource_name = Vinvocation_name; @@ -5411,7 +5646,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ FRAME_KBOARD (f) = kb; - f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; + f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; f->output_data.w32->explicit_parent = 0; /* Set the name; the functions to which we pass f expect the name to @@ -5429,9 +5664,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, specbind (Qx_resource_name, name); } - f->resx = dpyinfo->resx; - f->resy = dpyinfo->resy; - if (uniscribe_available) register_font_driver (&uniscribe_font_driver, f); register_font_driver (&w32font_driver, f); @@ -5483,7 +5715,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, init_frame_faces (f); f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED; - f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; + f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; window_prompting = x_figure_window_size (f, parms, 0); @@ -5550,7 +5782,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, /* Now that the frame is official, it counts as a reference to its display. */ - FRAME_W32_DISPLAY_INFO (f)->reference_count++; + FRAME_DISPLAY_INFO (f)->reference_count++; f->terminal->reference_count++; /* It is now ok to make the frame official even if we get an error @@ -5597,8 +5829,8 @@ compute_tip_xy (struct frame *f, /* Default min and max values. */ min_x = 0; min_y = 0; - max_x = x_display_pixel_width (FRAME_W32_DISPLAY_INFO (f)); - max_y = x_display_pixel_height (FRAME_W32_DISPLAY_INFO (f)); + max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (f)); + max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f)); block_input (); GetCursorPos (&pt); @@ -5700,7 +5932,7 @@ Text larger than the specified size is clipped. */) GCPRO4 (string, parms, frame, timeout); CHECK_STRING (string); - f = check_x_frame (frame); + f = decode_window_system_frame (frame); if (NILP (timeout)) timeout = make_number (5); else @@ -5784,13 +6016,13 @@ Text larger than the specified size is clipped. */) /* Create a frame for the tooltip, and record it in the global variable tip_frame. */ - frame = x_create_tip_frame (FRAME_W32_DISPLAY_INFO (f), parms, string); + frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, string); f = XFRAME (frame); /* Set up the frame's root window. */ w = XWINDOW (FRAME_ROOT_WINDOW (f)); - wset_left_col (w, make_number (0)); - wset_top_line (w, make_number (0)); + w->left_col = 0; + w->top_line = 0; if (CONSP (Vx_max_tooltip_size) && INTEGERP (XCAR (Vx_max_tooltip_size)) @@ -5798,22 +6030,22 @@ Text larger than the specified size is clipped. */) && INTEGERP (XCDR (Vx_max_tooltip_size)) && XINT (XCDR (Vx_max_tooltip_size)) > 0) { - wset_total_cols (w, XCAR (Vx_max_tooltip_size)); - wset_total_lines (w, XCDR (Vx_max_tooltip_size)); + w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size)); + w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size)); } else { - wset_total_cols (w, make_number (80)); - wset_total_lines (w, make_number (40)); + w->total_cols = 80; + w->total_lines = 40; } - FRAME_TOTAL_COLS (f) = XINT (w->total_cols); - adjust_glyphs (f); + FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w); + adjust_frame_glyphs (f); w->pseudo_window_p = 1; /* Display the tooltip text in a temporary buffer. */ old_buffer = current_buffer; - set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer)); + set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents)); bset_truncate_lines (current_buffer, Qnil); clear_glyph_matrix (w->desired_matrix); clear_glyph_matrix (w->current_matrix); @@ -5829,7 +6061,7 @@ Text larger than the specified size is clipped. */) int row_width; /* Stop at the first empty row at the end. */ - if (!row->enabled_p || !row->displays_text_p) + if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row)) break; /* Let the row go over the full width of the frame. */ @@ -5875,9 +6107,9 @@ Text larger than the specified size is clipped. */) /* w->total_cols and FRAME_TOTAL_COLS want the width in columns, not in pixels. */ width /= WINDOW_FRAME_COLUMN_WIDTH (w); - wset_total_cols (w, make_number (width)); + w->total_cols = width; FRAME_TOTAL_COLS (f) = width; - adjust_glyphs (f); + adjust_frame_glyphs (f); w->pseudo_window_p = 1; clear_glyph_matrix (w->desired_matrix); clear_glyph_matrix (w->current_matrix); @@ -5890,7 +6122,7 @@ Text larger than the specified size is clipped. */) struct glyph *last; int row_width; - if (!row->enabled_p || !row->displays_text_p) + if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row)) break; row->full_width_p = 1; row_width = row->pixel_width; @@ -6011,14 +6243,6 @@ Value is t if tooltip was open, nil otherwise. */) #define FILE_NAME_COMBO_BOX cmb13 #define FILE_NAME_LIST lst1 -#ifdef NTGUI_UNICODE -#define GUISTR(x) (L ## x) -typedef wchar_t guichar_t; -#else /* !NTGUI_UNICODE */ -#define GUISTR(x) x -typedef char guichar_t; -#endif /* NTGUI_UNICODE */ - /* Callback for altering the behavior of the Open File dialog. Makes the Filename text field contain "Current Directory" and be read-only when "Directories" is selected in the filter. This @@ -6235,11 +6459,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) block_input (); file_details->lpfnHook = file_dialog_callback; -#ifdef NTGUI_UNICODE - file_opened = GetOpenFileNameW (file_details); -#else /* !NTGUI_UNICODE */ - file_opened = GetOpenFileNameA (file_details); -#endif /* NTGUI_UNICODE */ + file_opened = GUI_FN (GetOpenFileName) (file_details); unblock_input (); unbind_to (count, Qnil); } @@ -6248,11 +6468,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) { /* Get an Emacs string from the value Windows gave us. */ #ifdef NTGUI_UNICODE - filename = from_unicode ( - make_unibyte_string ( - (char*) filename_buf, - /* we get one of the two final 0 bytes for free. */ - 1 + sizeof (wchar_t) * wcslen (filename_buf))); + filename = from_unicode_buffer (filename_buf); #else /* !NTGUI_UNICODE */ dostounix_filename (filename_buf, 0); filename = DECODE_FILE (build_string (filename_buf)); @@ -6367,7 +6583,7 @@ screen saver if defined. If optional parameter FRAME is not specified, use selected frame. */) (Lisp_Object command, Lisp_Object frame) { - FRAME_PTR f = check_x_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHECK_NUMBER (command); @@ -6426,20 +6642,29 @@ an integer representing a ShowWindow flag: CHECK_STRING (document); /* Encode filename, current directory and parameters. */ - current_dir = ENCODE_FILE (BVAR (current_buffer, directory)); - document = ENCODE_FILE (document); + current_dir = BVAR (current_buffer, directory); + +#ifdef CYGWIN + current_dir = Fcygwin_convert_file_name_to_windows (current_dir, Qt); + if (STRINGP (document)) + document = Fcygwin_convert_file_name_to_windows (document, Qt); +#endif /* CYGWIN */ + + current_dir = GUI_ENCODE_FILE (current_dir); + if (STRINGP (document)) + document = GUI_ENCODE_FILE (document); if (STRINGP (parameters)) - parameters = ENCODE_SYSTEM (parameters); - - if ((int) ShellExecute (NULL, - (STRINGP (operation) ? - SDATA (operation) : NULL), - SDATA (document), - (STRINGP (parameters) ? - SDATA (parameters) : NULL), - SDATA (current_dir), - (INTEGERP (show_flag) ? - XINT (show_flag) : SW_SHOWDEFAULT)) + parameters = GUI_ENCODE_SYSTEM (parameters); + + if ((int) GUI_FN (ShellExecute) (NULL, + (STRINGP (operation) ? + GUI_SDATA (operation) : NULL), + GUI_SDATA (document), + (STRINGP (parameters) ? + GUI_SDATA (parameters) : NULL), + GUI_SDATA (current_dir), + (INTEGERP (show_flag) ? + XINT (show_flag) : SW_SHOWDEFAULT)) > 32) return Qt; errstr = w32_strerror (0); @@ -6808,6 +7033,7 @@ The following %-sequences are provided: } +#ifdef WINDOWSNT DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0, doc: /* Return storage information about the file system FILENAME is on. Value is a list of floats (TOTAL FREE AVAIL), where TOTAL is the total @@ -6903,6 +7129,8 @@ If the underlying system call fails, value is nil. */) return value; } +#endif /* WINDOWSNT */ + DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name, 0, 0, 0, doc: /* Return the name of Windows default printer device. */) @@ -7313,8 +7541,6 @@ void syms_of_w32fns (void) { globals_of_w32fns (); - /* This is zero if not using MS-Windows. */ - w32_in_use = 0; track_mouse_window = NULL; w32_visible_system_caret_hwnd = NULL; @@ -7330,6 +7556,10 @@ syms_of_w32fns (void) DEFSYM (Qcontrol, "control"); DEFSYM (Qshift, "shift"); DEFSYM (Qfont_param, "font-parameter"); + DEFSYM (Qgeometry, "geometry"); + DEFSYM (Qworkarea, "workarea"); + DEFSYM (Qmm_size, "mm-size"); + DEFSYM (Qframes, "frames"); /* This is the end of symbol initialization. */ @@ -7613,12 +7843,12 @@ only be necessary if the default setting causes problems. */); defsubr (&Sx_close_connection); defsubr (&Sx_display_list); defsubr (&Sx_synchronize); - defsubr (&Sx_focus_frame); /* W32 specific functions */ defsubr (&Sw32_define_rgb_color); defsubr (&Sw32_default_color_map); + defsubr (&Sw32_display_monitor_attributes_list); defsubr (&Sw32_send_sys_command); defsubr (&Sw32_shell_execute); defsubr (&Sw32_register_hot_key); @@ -7629,12 +7859,13 @@ only be necessary if the default setting causes problems. */); defsubr (&Sw32_window_exists_p); defsubr (&Sw32_battery_status); +#ifdef WINDOWSNT defsubr (&Sfile_system_info); +#endif + defsubr (&Sdefault_printer_name); defsubr (&Sset_message_beep); - check_window_system_func = check_w32; - hourglass_hwnd = NULL; defsubr (&Sx_show_tip); @@ -7677,6 +7908,10 @@ globals_of_w32fns (void) 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"); @@ -7775,6 +8010,9 @@ emacs_abort (void) #endif if (stderr_fd >= 0) write (stderr_fd, "\r\nBacktrace:\r\n", 14); +#ifdef CYGWIN +#define _open open +#endif errfile_fd = _open ("emacs_backtrace.txt", O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE); if (errfile_fd >= 0) { @@ -7810,3 +8048,15 @@ emacs_abort (void) } } } + +#ifdef NTGUI_UNICODE + +Lisp_Object +ntgui_encode_system (Lisp_Object str) +{ + Lisp_Object encoded; + to_unicode (str, &encoded); + return encoded; +} + +#endif /* NTGUI_UNICODE */