X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/9cda66e432f4f17a9aa150a56de389df5577c914..21bf394d7d1065a886c486f00c614ca905db1ed5:/src/w32fns.c diff --git a/src/w32fns.c b/src/w32fns.c index b8c445a3a3..79011f9afc 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -277,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; } @@ -291,7 +291,7 @@ check_x_display_info (Lisp_Object 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); } } @@ -307,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) @@ -1027,18 +1027,18 @@ w32_regenerate_palette (struct frame *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; @@ -1046,9 +1046,9 @@ w32_regenerate_palette (struct frame *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)); @@ -1071,7 +1071,7 @@ w32_regenerate_palette (struct frame *f) void 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; @@ -1091,19 +1091,19 @@ w32_map_color (struct frame *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 (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; @@ -1117,7 +1117,7 @@ w32_unmap_color (struct frame *f, COLORREF color) { *prev = list->next; xfree (list); - FRAME_W32_DISPLAY_INFO (f)->num_colors--; + FRAME_DISPLAY_INFO (f)->num_colors--; break; } else @@ -1128,7 +1128,7 @@ w32_unmap_color (struct frame *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 @@ -1235,7 +1235,7 @@ x_decode_color (struct frame *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 @@ -1383,6 +1383,17 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) horizontal_drag_cursor = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow); + if (!NILP (Vx_window_vertical_drag_shape)) + { + CHECK_NUMBER (Vx_window_vertical_drag_shape); + vertical_drag_cursor + = XCreateFontCursor (FRAME_X_DISPLAY (f), + XINT (Vx_window_vertical_drag_shape)); + } + else + vertical_drag_cursor + = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_v_double_arrow); + /* Check and report errors with the above calls. */ x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s"); x_uncatch_errors (FRAME_W32_DISPLAY (f), count); @@ -1623,6 +1634,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) nlines = 0; FRAME_MENU_BAR_LINES (f) = 0; + FRAME_MENU_BAR_HEIGHT (f) = 0; if (nlines) FRAME_EXTERNAL_MENU_BAR (f) = 1; else @@ -1634,24 +1646,25 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) /* Adjust the frame size so that the client (text) dimensions remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being set correctly. */ - x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); + x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1); do_pending_window_change (0); } - adjust_glyphs (f); + adjust_frame_glyphs (f); } /* Set the number of lines used for the tool bar of frame F to VALUE. - VALUE not an integer, or < 0 means set the lines to zero. OLDVAL - is the old number of tool bar lines. This function changes the - height of all windows on frame F to match the new tool bar height. - The frame's height doesn't change. */ + VALUE not an integer, or < 0 means set the lines to zero. OLDVAL is + the old number of tool bar lines (and is unused). This function may + change the height of all windows on frame F to match the new tool bar + height. By design, the frame's height doesn't change (but maybe it + should if we don't get enough space otherwise). */ void x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) { int delta, nlines, root_height; - Lisp_Object root_window; + int unit = FRAME_LINE_HEIGHT (f); /* Treat tool bars like menu bars. */ if (FRAME_MINIBUF_ONLY_P (f)) @@ -1664,22 +1677,28 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) nlines = 0; /* Make sure we redisplay all windows in this frame. */ - ++windows_or_buffers_changed; + windows_or_buffers_changed = 23; - delta = nlines - FRAME_TOOL_BAR_LINES (f); + /* DELTA is in pixels now. */ + delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit; - /* Don't resize the tool-bar to more than we have room for. */ - root_window = FRAME_ROOT_WINDOW (f); - root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window)); - if (root_height - delta < 1) + /* Don't resize the tool-bar to more than we have room for. FIXME: + This must use window_sizable eventually !!!!!!!!!!!! */ + if (delta > 0) { - delta = root_height - 1; - nlines = FRAME_TOOL_BAR_LINES (f) + delta; + root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f))); + if (root_height - delta < unit) + { + delta = root_height - unit; + nlines = (root_height / unit) + min (1, (root_height % unit)); + } } FRAME_TOOL_BAR_LINES (f) = nlines; - resize_frame_windows (f, FRAME_LINES (f), 0); - adjust_glyphs (f); + FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); + ++windows_or_buffers_changed; + resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1); + 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 @@ -1687,7 +1706,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) below the tool bar if one is displayed, but is below the menu bar if there isn't a tool bar. The tool bar draws into the area below the menu bar. */ - if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0) + if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0) { clear_frame (f); clear_current_matrices (f); @@ -1700,7 +1719,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) { int height = FRAME_INTERNAL_BORDER_WIDTH (f); int width = FRAME_PIXEL_WIDTH (f); - int y = nlines * FRAME_LINE_HEIGHT (f); + int y = nlines * unit; block_input (); { @@ -1740,7 +1759,7 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit) /* If we're switching from explicit to implicit, we had better update the mode lines and thereby update the title. */ if (f->explicit_name && NILP (name)) - update_mode_lines = 1; + update_mode_lines = 25; f->explicit_name = ! NILP (name); } @@ -1752,10 +1771,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); @@ -1808,7 +1827,7 @@ x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name) if (EQ (name, f->title)) return; - update_mode_lines = 1; + update_mode_lines = 26; fset_title (f, name); @@ -1890,16 +1909,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 @@ -1953,7 +1967,7 @@ w32_createwindow (struct frame *f) SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f)); SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f)); SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f)); - SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width); + SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f)); SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f)); /* Enable drag-n-drop. */ @@ -3229,6 +3243,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) - WINDOW_RIGHT_MARGIN_WIDTH (w) - WINDOW_RIGHT_FRINGE_WIDTH (w)); form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w) + - WINDOW_BOTTOM_DIVIDER_WIDTH (w) - w32_system_caret_mode_height); /* Punt if the window was deleted behind our back. */ @@ -3778,7 +3793,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_WINDOWPOSCHANGING: /* Don't restrict the sizing of tip frames. */ - if (hwnd == tip_window) + if (frame_resize_pixelwise || hwnd == tip_window) return 0; /* Don't restrict the sizing of fullscreened frames, allowing them to be @@ -4232,7 +4247,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); @@ -4258,7 +4273,7 @@ do_unwind_create_frame (Lisp_Object 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; @@ -4392,9 +4407,9 @@ 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. */ + /* 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 = @@ -4411,7 +4426,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; } @@ -4457,6 +4472,10 @@ This function is an internal primitive--use `make-frame' instead. */) /* Default internalBorderWidth to 0 on Windows to match other programs. */ x_default_parameter (f, parameters, Qinternal_border_width, make_number (0), "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER); + x_default_parameter (f, parameters, Qright_divider_width, make_number (0), + NULL, NULL, RES_TYPE_NUMBER); + x_default_parameter (f, parameters, Qbottom_divider_width, make_number (0), + NULL, NULL, RES_TYPE_NUMBER); x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright, "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL); @@ -4486,6 +4505,20 @@ This function is an internal primitive--use `make-frame' instead. */) happen. */ init_frame_faces (f); + /* PXW: This is a duplicate from below. We have to do it here since + otherwise x_set_tool_bar_lines will work with the character sizes + installed by init_frame_faces while the frame's pixel size is still + calculated from a character size of 1 and we subsequently hit the + eassert (height >= 0) assertion in window_box_height. The + non-pixelwise code apparently worked around this because it had one + frame line vs one toolbar line which left us with a zero root + window height which was obviously wrong as well ... */ + width = FRAME_TEXT_WIDTH (f); + height = FRAME_TEXT_HEIGHT (f); + FRAME_TEXT_HEIGHT (f) = 0; + SET_FRAME_WIDTH (f, 0); + change_frame_size (f, width, height, 1, 0, 0, 1); + /* The X resources controlling the menu-bar and tool-bar are processed specially at startup, and reflected in the mode variables; ignore them here. */ @@ -4506,7 +4539,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); @@ -4514,6 +4547,7 @@ This function is an internal primitive--use `make-frame' instead. */) f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND); f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT); f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE); + f->output_data.w32->vertical_drag_cursor = w32_load_cursor (IDC_SIZENS); f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor; @@ -4529,7 +4563,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 @@ -4551,12 +4585,11 @@ This function is an internal primitive--use `make-frame' instead. */) /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. Change will not be effected unless different from the current FRAME_LINES (f). */ - width = FRAME_COLS (f); - height = FRAME_LINES (f); - - FRAME_LINES (f) = 0; - SET_FRAME_COLS (f, 0); - change_frame_size (f, height, width, 1, 0, 0); + width = FRAME_TEXT_WIDTH (f); + height = FRAME_TEXT_HEIGHT (f); + FRAME_TEXT_HEIGHT (f) = 0; + SET_FRAME_WIDTH (f, 0); + change_frame_size (f, width, height, 1, 0, 0, 1); /* Tell the server what size and position, etc, we want, and how badly we want them. This should be done after we have the menu @@ -4613,7 +4646,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; @@ -4622,15 +4655,6 @@ 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 (decode_window_system_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.) */) @@ -5131,7 +5155,7 @@ SOUND is nil to use the normal beep. */) 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. @@ -5140,20 +5164,13 @@ x_screen_planes (register struct frame *f) struct w32_display_info * x_display_info_for_name (Lisp_Object name) { - Lisp_Object names; struct w32_display_info *dpyinfo; CHECK_STRING (name); - for (dpyinfo = &one_w32_display_info, names = w32_display_name_list; - dpyinfo && !NILP (w32_display_name_list); - dpyinfo = dpyinfo->next, names = XCDR (names)) - { - Lisp_Object tem; - tem = Fstring_equal (XCAR (XCAR (names)), name); - if (!NILP (tem)) - return dpyinfo; - } + for (dpyinfo = &one_w32_display_info; dpyinfo; dpyinfo = dpyinfo->next) + if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name))) + return dpyinfo; /* Use this general default value to start with. */ Vx_resource_name = Vinvocation_name; @@ -5201,11 +5218,6 @@ terminate Emacs if we can't open the connection. 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. */ { @@ -5293,11 +5305,11 @@ DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0, doc: /* Return the list of display names that Emacs has connections to. */) (void) { - Lisp_Object tail, result; + Lisp_Object result = Qnil; + struct w32_display_info *wdi; - result = Qnil; - for (tail = w32_display_name_list; CONSP (tail); tail = XCDR (tail)) - result = Fcons (XCAR (XCAR (tail)), result); + for (wdi = x_display_list; wdi; wdi = wdi->next) + result = Fcons (XCAR (wdi->name_list_element), result); return result; } @@ -5486,7 +5498,10 @@ show_hourglass (struct atimer *timer) f = SELECTED_FRAME (); if (!FRAME_W32_P (f)) - return; + { + unblock_input (); + return; + } w32_show_hourglass (f); unblock_input (); @@ -5665,7 +5680,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 @@ -5712,6 +5727,10 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, x_default_parameter (f, parms, Qinternal_border_width, make_number (1), "internalBorderWidth", "internalBorderWidth", RES_TYPE_NUMBER); + x_default_parameter (f, parms, Qright_divider_width, make_number (0), + NULL, NULL, RES_TYPE_NUMBER); + x_default_parameter (f, parms, Qbottom_divider_width, make_number (0), + NULL, NULL, RES_TYPE_NUMBER); /* Also do the stuff which must be set before the window exists. */ x_default_parameter (f, parms, Qforeground_color, build_string ("black"), @@ -5734,7 +5753,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); @@ -5756,14 +5775,14 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, x_default_parameter (f, parms, Qcursor_type, Qbox, "cursorType", "CursorType", RES_TYPE_SYMBOL); - /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. - Change will not be effected unless different from the current - FRAME_LINES (f). */ + /* Dimensions, especially FRAME_LINES (f), must be done via + change_frame_size. Change will not be effected unless different + from the current FRAME_LINES (f). */ width = FRAME_COLS (f); height = FRAME_LINES (f); FRAME_LINES (f) = 0; SET_FRAME_COLS (f, 0); - change_frame_size (f, height, width, 1, 0, 0); + change_frame_size (f, width, height, 1, 0, 0, 0); /* Add `tooltip' frame parameter's default value. */ if (NILP (Fframe_parameter (frame, Qtooltip))) @@ -5801,7 +5820,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 @@ -5848,8 +5867,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); @@ -6021,6 +6040,10 @@ Text larger than the specified size is clipped. */) parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms); if (NILP (Fassq (Qinternal_border_width, parms))) parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms); + if (NILP (Fassq (Qright_divider_width, parms))) + parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms); + if (NILP (Fassq (Qbottom_divider_width, parms))) + parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms); if (NILP (Fassq (Qborder_width, parms))) parms = Fcons (Fcons (Qborder_width, make_number (1)), parms); if (NILP (Fassq (Qborder_color, parms))) @@ -6035,13 +6058,15 @@ 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)); w->left_col = 0; w->top_line = 0; + w->pixel_left = 0; + w->pixel_top = 0; if (CONSP (Vx_max_tooltip_size) && INTEGERP (XCAR (Vx_max_tooltip_size)) @@ -6058,8 +6083,11 @@ Text larger than the specified size is clipped. */) w->total_lines = 40; } + w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f); + w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f); + FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w); - adjust_glyphs (f); + adjust_frame_glyphs (f); w->pseudo_window_p = 1; /* Display the tooltip text in a temporary buffer. */ @@ -6123,12 +6151,18 @@ Text larger than the specified size is clipped. */) width of the frame. */ if (seen_reversed_p) { - /* w->total_cols and FRAME_TOTAL_COLS want the width in columns, + /* PXW: Why do we do the pixel-to-cols conversion only if + seen_reversed_p holds? Don't we have to set other fields of + the window/frame structure? + + w->total_cols and FRAME_TOTAL_COLS want the width in columns, not in pixels. */ + w->pixel_width = width; width /= WINDOW_FRAME_COLUMN_WIDTH (w); w->total_cols = width; FRAME_TOTAL_COLS (f) = width; - adjust_glyphs (f); + SET_FRAME_WIDTH (f, width); + adjust_frame_glyphs (f); w->pseudo_window_p = 1; clear_glyph_matrix (w->desired_matrix); clear_glyph_matrix (w->current_matrix); @@ -6157,16 +6191,15 @@ Text larger than the specified size is clipped. */) } } - /* Round up the height to an integral multiple of FRAME_LINE_HEIGHT. */ - if (height % FRAME_LINE_HEIGHT (f) != 0) - height += FRAME_LINE_HEIGHT (f) - height % FRAME_LINE_HEIGHT (f); /* Add the frame's internal border to the width and height the w32 window should have. */ height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); /* Move the tooltip window where the mouse pointer is. Resize and - show it. */ + show it. + + PXW: This should use the frame's pixel coordinates. */ compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y); { @@ -6942,6 +6975,29 @@ This is a direct interface to the Windows API FindWindow function. */) return Qt; } +DEFUN ("w32-frame-rect", Fw32_frame_rect, Sw32_frame_rect, 0, 2, 0, + doc: /* Return boundary rectangle of FRAME in screen coordinates. +FRAME must be a live frame and defaults to the selected one. + +The boundary rectangle is a list of four elements, specifying the left, +top, right and bottom screen coordinates of FRAME including menu and +title bar and decorations. Optional argument CLIENT non-nil means to +return the boundaries of the client rectangle which excludes menu and +title bar and decorations. */) + (Lisp_Object frame, Lisp_Object client) +{ + struct frame *f = decode_live_frame (frame); + RECT rect; + + if (!NILP (client)) + GetClientRect (FRAME_W32_WINDOW (f), &rect); + else + GetWindowRect (FRAME_W32_WINDOW (f), &rect); + + return list4 (make_number (rect.left), make_number (rect.top), + make_number (rect.right), make_number (rect.bottom)); +} + DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0, doc: /* Get power status information from Windows system. @@ -7533,6 +7589,8 @@ frame_parm_handler w32_frame_parm_handlers[] = x_set_icon_name, x_set_icon_type, x_set_internal_border_width, + x_set_right_divider_width, + x_set_bottom_divider_width, x_set_menu_bar_lines, x_set_mouse_color, x_explicitly_set_name, @@ -7784,6 +7842,13 @@ or when you set the mouse color. */); This variable takes effect when you create a new frame or when you set the mouse color. */); Vx_window_horizontal_drag_shape = Qnil; + + DEFVAR_LISP ("x-window-vertical-drag-cursor", + Vx_window_vertical_drag_shape, + doc: /* Pointer shape to use for indicating a window can be dragged vertically. +This variable takes effect when you create a new frame +or when you set the mouse color. */); + Vx_window_vertical_drag_shape = Qnil; #endif DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel, @@ -7862,7 +7927,6 @@ 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 */ @@ -7877,6 +7941,7 @@ only be necessary if the default setting causes problems. */); defsubr (&Sw32_reconstruct_hot_key); defsubr (&Sw32_toggle_lock_key); defsubr (&Sw32_window_exists_p); + defsubr (&Sw32_frame_rect); defsubr (&Sw32_battery_status); #ifdef WINDOWSNT @@ -7904,61 +7969,35 @@ only be necessary if the default setting causes problems. */); #endif } + -/* - globals_of_w32fns is used to initialize those global variables that - must always be initialized on startup even when the global variable - initialized is non zero (see the function main in emacs.c). - globals_of_w32fns is called from syms_of_w32fns when the global - variable initialized is 0 and directly from main when initialized - is non zero. - */ -void -globals_of_w32fns (void) -{ - HMODULE user32_lib = GetModuleHandle ("user32.dll"); - /* - TrackMouseEvent not available in all versions of Windows, so must load - it dynamically. Do it once, here, instead of every time it is used. - */ - track_mouse_event_fn = (TrackMouseEvent_Proc) - GetProcAddress (user32_lib, "TrackMouseEvent"); - - monitor_from_point_fn = (MonitorFromPoint_Proc) - 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"); - get_composition_string_fn = (ImmGetCompositionString_Proc) - GetProcAddress (imm32_lib, "ImmGetCompositionStringW"); - get_ime_context_fn = (ImmGetContext_Proc) - GetProcAddress (imm32_lib, "ImmGetContext"); - release_ime_context_fn = (ImmReleaseContext_Proc) - GetProcAddress (imm32_lib, "ImmReleaseContext"); - set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc) - GetProcAddress (imm32_lib, "ImmSetCompositionWindow"); - } - DEFVAR_INT ("w32-ansi-code-page", - w32_ansi_code_page, - doc: /* The ANSI code page used by the system. */); - w32_ansi_code_page = GetACP (); - - if (os_subtype == OS_NT) - w32_unicode_gui = 1; - else - w32_unicode_gui = 0; +/* Crashing and reporting backtrace. */ - /* MessageBox does not work without this when linked to comctl32.dll 6.0. */ - InitCommonControls (); +#ifndef CYGWIN +static LONG CALLBACK my_exception_handler (EXCEPTION_POINTERS *); +static LPTOP_LEVEL_EXCEPTION_FILTER prev_exception_handler; +#endif +static DWORD except_code; +static PVOID except_addr; - syms_of_w32uniscribe (); +#ifndef CYGWIN +/* This handler records the exception code and the address where it + was triggered so that this info could be included in the backtrace. + Without that, the backtrace in some cases has no information + whatsoever about the offending code, and looks as if the top-level + exception handler in the MinGW startup code di the one that + crashed. */ +static LONG CALLBACK +my_exception_handler (EXCEPTION_POINTERS * exception_data) +{ + except_code = exception_data->ExceptionRecord->ExceptionCode; + except_addr = exception_data->ExceptionRecord->ExceptionAddress; + + if (prev_exception_handler) + return prev_exception_handler (exception_data); + return EXCEPTION_EXECUTE_HANDLER; } +#endif typedef USHORT (WINAPI * CaptureStackBackTrace_proc) (ULONG, ULONG, PVOID *, PULONG); @@ -8015,21 +8054,32 @@ emacs_abort (void) if (i) { + int errfile_fd = -1; + int j; + char buf[sizeof ("\r\nException at this address:\r\n\r\n") + + 2 * INT_BUFSIZE_BOUND (void *)]; #ifdef CYGWIN int stderr_fd = 2; #else HANDLE errout = GetStdHandle (STD_ERROR_HANDLE); int stderr_fd = -1; -#endif - int errfile_fd = -1; - int j; -#ifndef CYGWIN if (errout && errout != INVALID_HANDLE_VALUE) stderr_fd = _open_osfhandle ((intptr_t)errout, O_APPEND | O_BINARY); #endif + + /* We use %p, not 0x%p, as %p produces a leading "0x" on XP, + but not on Windows 7. addr2line doesn't mind a missing + "0x", but will be confused by an extra one. */ + if (except_addr) + sprintf (buf, "\r\nException 0x%lx at this address:\r\n%p\r\n", + except_code, except_addr); if (stderr_fd >= 0) - write (stderr_fd, "\r\nBacktrace:\r\n", 14); + { + if (except_addr) + write (stderr_fd, buf, strlen (buf)); + write (stderr_fd, "\r\nBacktrace:\r\n", 14); + } #ifdef CYGWIN #define _open open #endif @@ -8037,17 +8087,17 @@ emacs_abort (void) if (errfile_fd >= 0) { lseek (errfile_fd, 0L, SEEK_END); + if (except_addr) + write (errfile_fd, buf, strlen (buf)); write (errfile_fd, "\r\nBacktrace:\r\n", 14); } for (j = 0; j < i; j++) { - char buf[INT_BUFSIZE_BOUND (void *)]; - /* stack[] gives the return addresses, whereas we want the address of the call, so decrease each address by approximate size of 1 CALL instruction. */ - sprintf (buf, "0x%p\r\n", (char *)stack[j] - sizeof(void *)); + sprintf (buf, "%p\r\n", (char *)stack[j] - sizeof(void *)); if (stderr_fd >= 0) write (stderr_fd, buf, strlen (buf)); if (errfile_fd >= 0) @@ -8069,6 +8119,72 @@ emacs_abort (void) } } + + +/* Initialization. */ + +/* + globals_of_w32fns is used to initialize those global variables that + must always be initialized on startup even when the global variable + initialized is non zero (see the function main in emacs.c). + globals_of_w32fns is called from syms_of_w32fns when the global + variable initialized is 0 and directly from main when initialized + is non zero. + */ +void +globals_of_w32fns (void) +{ + HMODULE user32_lib = GetModuleHandle ("user32.dll"); + /* + TrackMouseEvent not available in all versions of Windows, so must load + it dynamically. Do it once, here, instead of every time it is used. + */ + track_mouse_event_fn = (TrackMouseEvent_Proc) + GetProcAddress (user32_lib, "TrackMouseEvent"); + + monitor_from_point_fn = (MonitorFromPoint_Proc) + 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"); + get_composition_string_fn = (ImmGetCompositionString_Proc) + GetProcAddress (imm32_lib, "ImmGetCompositionStringW"); + get_ime_context_fn = (ImmGetContext_Proc) + GetProcAddress (imm32_lib, "ImmGetContext"); + release_ime_context_fn = (ImmReleaseContext_Proc) + GetProcAddress (imm32_lib, "ImmReleaseContext"); + set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc) + GetProcAddress (imm32_lib, "ImmSetCompositionWindow"); + } + + except_code = 0; + except_addr = 0; +#ifndef CYGWIN + prev_exception_handler = SetUnhandledExceptionFilter (my_exception_handler); +#endif + + DEFVAR_INT ("w32-ansi-code-page", + w32_ansi_code_page, + doc: /* The ANSI code page used by the system. */); + w32_ansi_code_page = GetACP (); + + if (os_subtype == OS_NT) + w32_unicode_gui = 1; + else + w32_unicode_gui = 0; + + /* MessageBox does not work without this when linked to comctl32.dll 6.0. */ + InitCommonControls (); + + syms_of_w32uniscribe (); +} + #ifdef NTGUI_UNICODE Lisp_Object