X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d0cfb71f2e0a5a4cd231b3139f013a1908bfaefa..aab1fcdf812a7ebd32b8312c05ffcdd1bf610d2b:/src/w32term.c diff --git a/src/w32term.c b/src/w32term.c index 36ae4d7797..03a9af12ea 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -109,9 +109,10 @@ struct w32_display_info *x_display_list; Lisp_Object w32_display_name_list; -#if _WIN32_WINNT < 0x0500 +#if _WIN32_WINNT < 0x0500 && !defined(_W64) /* Pre Windows 2000, this was not available, but define it here so - that Emacs compiled on such a platform will run on newer versions. */ + that Emacs compiled on such a platform will run on newer versions. + MinGW64 (_W64) defines these unconditionally, so avoid redefining. */ typedef struct tagWCRANGE { @@ -142,6 +143,15 @@ BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD); #define WS_EX_LAYERED 0x80000 #endif +/* SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN are not defined on 95 and + NT4. */ +#ifndef SM_CXVIRTUALSCREEN +#define SM_CXVIRTUALSCREEN 78 +#endif +#ifndef SM_CYVIRTUALSCREEN +#define SM_CYVIRTUALSCREEN 79 +#endif + /* This is a frame waiting to be autoraised, within w32_read_socket. */ struct frame *pending_autoraise_frame; @@ -150,6 +160,9 @@ HWND w32_system_caret_hwnd; int w32_system_caret_height; int w32_system_caret_x; int w32_system_caret_y; +struct window *w32_system_caret_window; +int w32_system_caret_hdr_height; +int w32_system_caret_mode_height; DWORD dwWindowsThreadId = 0; HANDLE hWindowsThread = NULL; DWORD dwMainThreadId = 0; @@ -168,7 +181,7 @@ int w32_keyboard_codepage; /* Where the mouse was last time we reported a mouse event. */ static RECT last_mouse_glyph; -static FRAME_PTR last_mouse_glyph_frame; +static struct frame *last_mouse_glyph_frame; /* The scroll bar in which the last motion event occurred. @@ -191,11 +204,7 @@ static Time last_mouse_movement_time; /* Incremented by w32_read_socket whenever it really tries to read events. */ -#ifdef __STDC__ static int volatile input_signal_count; -#else -static int input_signal_count; -#endif #ifdef CYGWIN int w32_message_fd = -1; @@ -240,6 +249,7 @@ static void my_set_focus (struct frame *, HWND); #endif static void my_set_foreground_window (HWND); static void my_destroy_window (struct frame *, HWND); +static void w32fullscreen_hook (struct frame *); #ifdef GLYPH_DEBUG static void x_check_font (struct frame *, struct font *); @@ -440,7 +450,7 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y, /* Draw a filled rectangle at the specified position. */ void -w32_fill_rect (FRAME_PTR f, HDC hdc, COLORREF pix, RECT *lprect) +w32_fill_rect (struct frame *f, HDC hdc, COLORREF pix, RECT *lprect) { HBRUSH hb; @@ -450,7 +460,7 @@ w32_fill_rect (FRAME_PTR f, HDC hdc, COLORREF pix, RECT *lprect) } void -w32_clear_window (FRAME_PTR f) +w32_clear_window (struct frame *f) { RECT rect; HDC hdc = get_frame_dc (f); @@ -518,18 +528,24 @@ x_set_frame_alpha (struct frame *f) int x_display_pixel_height (struct w32_display_info *dpyinfo) { - HDC dc = GetDC (NULL); - int pixels = GetDeviceCaps (dc, VERTRES); - ReleaseDC (NULL, dc); + int pixels = GetSystemMetrics (SM_CYVIRTUALSCREEN); + + if (pixels == 0) + /* Fallback for Windows 95 or NT 4.0. */ + pixels = GetSystemMetrics (SM_CYSCREEN); + return pixels; } int x_display_pixel_width (struct w32_display_info *dpyinfo) { - HDC dc = GetDC (NULL); - int pixels = GetDeviceCaps (dc, HORZRES); - ReleaseDC (NULL, dc); + int pixels = GetSystemMetrics (SM_CXVIRTUALSCREEN); + + if (pixels == 0) + /* Fallback for Windows 95 or NT 4.0. */ + pixels = GetSystemMetrics (SM_CXSCREEN); + return pixels; } @@ -561,8 +577,7 @@ x_update_begin (struct frame *f) } -/* Start update of window W. Set the global variable updated_window - to the window being updated and set output_cursor to the cursor +/* Start update of window W. Set output_cursor to the cursor position of W. */ static void @@ -577,7 +592,6 @@ x_update_window_begin (struct window *w) SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0); } - updated_window = w; set_output_cursor (&w->cursor); block_input (); @@ -648,7 +662,7 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1) } -/* End update of window W (which is equal to updated_window). +/* End update of window W. Draw vertical borders between horizontally adjacent windows, and display W's cursor if CURSOR_ON_P is non-zero. @@ -698,8 +712,6 @@ x_update_window_end (struct window *w, int cursor_on_p, { SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0); } - - updated_window = NULL; } @@ -717,9 +729,8 @@ x_update_end (struct frame *f) } -/* This function is called from various places in xdisp.c whenever a - complete update has been performed. The global variable - updated_window is not available here. */ +/* This function is called from various places in xdisp.c + whenever a complete update has been performed. */ static void w32_frame_up_to_date (struct frame *f) @@ -731,15 +742,13 @@ w32_frame_up_to_date (struct frame *f) /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay arrow bitmaps, or clear the fringes if no bitmaps are required - before DESIRED_ROW is made current. The window being updated is - found in updated_window. This function is called from + before DESIRED_ROW is made current. This function is called from update_window_line only if it is known that there are differences between bitmaps to be drawn between current row and DESIRED_ROW. */ static void -x_after_update_window_line (struct glyph_row *desired_row) +x_after_update_window_line (struct window *w, struct glyph_row *desired_row) { - struct window *w = updated_window; struct frame *f; int width, height; @@ -750,7 +759,7 @@ x_after_update_window_line (struct glyph_row *desired_row) /* When a window has disappeared, make sure that no rest of full-width rows stays visible in the internal border. Could - check here if updated_window is the leftmost/rightmost window, + check here if updated window is the leftmost/rightmost window, but I guess it's not worth doing since vertically split windows are almost never used, internal border is rarely set, and the overhead is very small. */ @@ -2344,7 +2353,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s) static void x_draw_glyph_string (struct glyph_string *s) { - int relief_drawn_p = 0; + bool relief_drawn_p = 0; /* If S draws into the background of its successor, draw the background of the successor first so that S can draw into it. @@ -2790,7 +2799,6 @@ x_scroll_run (struct window *w, struct run *run) block_input (); /* Cursor off. Will be switched on again in x_update_window_end. */ - updated_window = w; x_clear_cursor (w); { @@ -2896,9 +2904,15 @@ x_focus_changed (int type, int state, struct w32_display_info *dpyinfo, && CONSP (Vframe_list) && !NILP (XCDR (Vframe_list))) { - bufp->kind = FOCUS_IN_EVENT; - XSETFRAME (bufp->frame_or_window, frame); + bufp->arg = Qt; + } + else + { + bufp->arg = Qnil; } + + bufp->kind = FOCUS_IN_EVENT; + XSETFRAME (bufp->frame_or_window, frame); } frame->output_data.x->focus_state |= state; @@ -2913,7 +2927,10 @@ x_focus_changed (int type, int state, struct w32_display_info *dpyinfo, { dpyinfo->w32_focus_event_frame = 0; x_new_focus_frame (dpyinfo, 0); - } + + bufp->kind = FOCUS_OUT_EVENT; + XSETFRAME (bufp->frame_or_window, frame); + } /* TODO: IME focus? */ } @@ -3165,7 +3182,7 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f) HDROP hdrop; POINT p; WORD num_files; - char *name; + guichar_t *name; int i, len; result->kind = DRAG_N_DROP_EVENT; @@ -3190,12 +3207,17 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f) for (i = 0; i < num_files; i++) { - len = DragQueryFile (hdrop, i, NULL, 0); + len = GUI_FN (DragQueryFile) (hdrop, i, NULL, 0); if (len <= 0) continue; - name = alloca (len + 1); - DragQueryFile (hdrop, i, name, len + 1); + + name = alloca ((len + 1) * sizeof (*name)); + GUI_FN (DragQueryFile) (hdrop, i, name, len + 1); +#ifdef NTGUI_UNICODE + files = Fcons (from_unicode_buffer (name), files); +#else files = Fcons (DECODE_FILE (build_string (name)), files); +#endif /* NTGUI_UNICODE */ } DragFinish (hdrop); @@ -3207,6 +3229,8 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f) } +#if HAVE_W32NOTIFY + /* File event notifications (see w32notify.c). */ Lisp_Object @@ -3322,7 +3346,8 @@ queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f, /* We've stuffed all the events ourselves, so w32_read_socket shouldn't. */ event->kind = NO_EVENT; } -#endif +#endif /* WINDOWSNT */ +#endif /* HAVE_W32NOTIFY */ /* Function to report a mouse movement to the mainstream Emacs code. @@ -3337,7 +3362,7 @@ static MSG last_mouse_motion_event; static Lisp_Object last_mouse_motion_frame; static int -note_mouse_movement (FRAME_PTR frame, MSG *msg) +note_mouse_movement (struct frame *frame, MSG *msg) { int mouse_x = LOWORD (msg->lParam); int mouse_y = HIWORD (msg->lParam); @@ -3386,7 +3411,7 @@ note_mouse_movement (FRAME_PTR frame, MSG *msg) ************************************************************************/ static struct scroll_bar *x_window_to_scroll_bar (Window); -static void x_scroll_bar_report_motion (FRAME_PTR *, Lisp_Object *, +static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, enum scroll_bar_part *, Lisp_Object *, Lisp_Object *, unsigned long *); @@ -3428,11 +3453,11 @@ w32_define_cursor (Window window, Cursor cursor) movement. */ static void -w32_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window, +w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, unsigned long *time) { - FRAME_PTR f1; + struct frame *f1; block_input (); @@ -3663,7 +3688,7 @@ my_create_scrollbar (struct frame * f, struct scroll_bar * bar) /*#define ATTACH_THREADS*/ static BOOL -my_show_window (FRAME_PTR f, HWND hwnd, int how) +my_show_window (struct frame *f, HWND hwnd, int how) { #ifndef ATTACH_THREADS return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW, @@ -3732,7 +3757,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) HWND hwnd; SCROLLINFO si; struct scroll_bar *bar - = XSCROLL_BAR (Fmake_vector (make_number (VECSIZE (struct scroll_bar)), Qnil)); + = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, fringe_extended_p, PVEC_OTHER); Lisp_Object barobj; block_input (); @@ -3745,7 +3770,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) XSETINT (bar->start, 0); XSETINT (bar->end, 0); bar->dragging = Qnil; - bar->fringe_extended_p = Qnil; + bar->fringe_extended_p = 0; /* Requires geometry to be set before call to create the real window */ @@ -3783,7 +3808,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) static void x_scroll_bar_remove (struct scroll_bar *bar) { - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); block_input (); @@ -3809,7 +3834,7 @@ w32_set_vertical_scroll_bar (struct window *w, struct scroll_bar *bar; int top, height, left, sb_left, width, sb_width; int window_y, window_height; - int fringe_extended_p; + bool fringe_extended_p; /* Get window dimensions. */ window_box (w, -1, 0, &window_y, 0, &window_height); @@ -3833,16 +3858,7 @@ w32_set_vertical_scroll_bar (struct window *w, else sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width); - if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) - fringe_extended_p = (WINDOW_LEFTMOST_P (w) - && WINDOW_LEFT_FRINGE_WIDTH (w) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - || WINDOW_LEFT_MARGIN_COLS (w) == 0)); - else - fringe_extended_p = (WINDOW_RIGHTMOST_P (w) - && WINDOW_RIGHT_FRINGE_WIDTH (w) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - || WINDOW_RIGHT_MARGIN_COLS (w) == 0)); + fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w); /* Does the scroll bar exist yet? */ if (NILP (w->vertical_scroll_bar)) @@ -3871,11 +3887,11 @@ w32_set_vertical_scroll_bar (struct window *w, hwnd = SCROLL_BAR_W32_WINDOW (bar); /* If already correctly positioned, do nothing. */ - if ( XINT (bar->left) == sb_left - && XINT (bar->top) == top - && XINT (bar->width) == sb_width - && XINT (bar->height) == height - && !NILP (bar->fringe_extended_p) == fringe_extended_p ) + if (XINT (bar->left) == sb_left + && XINT (bar->top) == top + && XINT (bar->width) == sb_width + && XINT (bar->height) == height + && bar->fringe_extended_p == fringe_extended_p) { /* Redraw after clear_frame. */ if (!my_show_window (f, hwnd, SW_NORMAL)) @@ -3925,7 +3941,7 @@ w32_set_vertical_scroll_bar (struct window *w, unblock_input (); } } - bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil; + bar->fringe_extended_p = fringe_extended_p; w32_set_scroll_bar_thumb (bar, portion, position, whole); XSETVECTOR (barobj, bar); @@ -3946,7 +3962,7 @@ w32_set_vertical_scroll_bar (struct window *w, `*redeem_scroll_bar_hook' is applied to its window before the judgment. */ static void -w32_condemn_scroll_bars (FRAME_PTR frame) +w32_condemn_scroll_bars (struct frame *frame) { /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */ while (! NILP (FRAME_SCROLL_BARS (frame))) @@ -4014,7 +4030,7 @@ w32_redeem_scroll_bar (struct window *window) last call to `*condemn_scroll_bars_hook'. */ static void -w32_judge_scroll_bars (FRAME_PTR f) +w32_judge_scroll_bars (struct frame *f) { Lisp_Object bar, next; @@ -4152,14 +4168,14 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg, on the scroll bar. */ static void -x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window, +x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, unsigned long *time) { struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar); Window w = SCROLL_BAR_W32_WINDOW (bar); - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); int pos; int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)); SCROLLINFO si; @@ -4211,7 +4227,7 @@ x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window, redraw them. */ void -x_scroll_bar_clear (FRAME_PTR f) +x_scroll_bar_clear (struct frame *f) { Lisp_Object bar; @@ -4319,24 +4335,26 @@ w32_read_socket (struct terminal *terminal, DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f, SDATA (f->name))); } - else if (f->async_visible != 1) + else if (FRAME_VISIBLE_P (f) != 1) { + bool iconified = FRAME_ICONIFIED_P (f); + /* Definitely not obscured, so mark as visible. */ - f->async_visible = 1; - f->async_iconified = 0; + SET_FRAME_VISIBLE (f, 1); + SET_FRAME_ICONIFIED (f, 0); SET_FRAME_GARBAGED (f); - DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f, - SDATA (f->name))); + if (!f->output_data.w32->asked_for_visible) + DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f, + SDATA (f->name))); /* WM_PAINT serves as MapNotify as well, so report visibility changes properly. */ - if (f->iconified) + if (iconified) { inev.kind = DEICONIFY_EVENT; XSETFRAME (inev.frame_or_window, f); } - else if (! NILP (Vframe_list) - && ! NILP (XCDR (Vframe_list))) + else if (!NILP (Vframe_list) && !NILP (XCDR (Vframe_list))) /* Force a redisplay sooner or later to update the frame titles in case this is the second frame. */ record_asynch_buffer_change (); @@ -4379,7 +4397,7 @@ w32_read_socket (struct terminal *terminal, case WM_SYSKEYDOWN: f = x_window_to_frame (dpyinfo, msg.msg.hwnd); - if (f && !f->iconified) + if (f && !FRAME_ICONIFIED_P (f)) { if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) @@ -4404,7 +4422,7 @@ w32_read_socket (struct terminal *terminal, case WM_CHAR: f = x_window_to_frame (dpyinfo, msg.msg.hwnd); - if (f && !f->iconified) + if (f && !FRAME_ICONIFIED_P (f)) { if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) @@ -4482,7 +4500,7 @@ w32_read_socket (struct terminal *terminal, case WM_APPCOMMAND: f = x_window_to_frame (dpyinfo, msg.msg.hwnd); - if (f && !f->iconified) + if (f && !FRAME_ICONIFIED_P (f)) { if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) @@ -4594,7 +4612,7 @@ w32_read_socket (struct terminal *terminal, { /* If we decide we want to generate an event to be seen by the rest of Emacs, we put it here. */ - int tool_bar_p = 0; + bool tool_bar_p = 0; int button; int up; @@ -4702,27 +4720,30 @@ w32_read_socket (struct terminal *terminal, } case WM_WINDOWPOSCHANGED: - f = x_window_to_frame (dpyinfo, msg.msg.hwnd); - if (f) - { - if (f->want_fullscreen & FULLSCREEN_WAIT) - f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH); - } - check_visibility = 1; - break; - case WM_ACTIVATE: case WM_ACTIVATEAPP: f = x_window_to_frame (dpyinfo, msg.msg.hwnd); if (f) - x_check_fullscreen (f); + { + /* Run the full-screen hook function also when we are + being activated, to actually install the required + size in effect, if the WAIT flag is set. This is + because when the hook is run from x_set_fullscreen, + the frame might not yet be visible, if that call is a + result of make-frame, and in that case the hook just + sets the WAIT flag. */ + if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam) + && (f->want_fullscreen & FULLSCREEN_WAIT)) + w32fullscreen_hook (f); + x_check_fullscreen (f); + } check_visibility = 1; break; case WM_MOVE: f = x_window_to_frame (dpyinfo, msg.msg.hwnd); - if (f && !f->async_iconified) + if (f && !FRAME_ICONIFIED_P (f)) { int x, y; @@ -4770,8 +4791,8 @@ w32_read_socket (struct terminal *terminal, switch (msg.msg.wParam) { case SIZE_MINIMIZED: - f->async_visible = 0; - f->async_iconified = 1; + SET_FRAME_VISIBLE (f, 0); + SET_FRAME_ICONIFIED (f, 1); inev.kind = ICONIFY_EVENT; XSETFRAME (inev.frame_or_window, f); @@ -4779,40 +4800,45 @@ w32_read_socket (struct terminal *terminal, case SIZE_MAXIMIZED: case SIZE_RESTORED: - f->async_visible = 1; - f->async_iconified = 0; - - /* wait_reading_process_output will notice this and update - the frame's display structures. */ - SET_FRAME_GARBAGED (f); + { + bool iconified = FRAME_ICONIFIED_P (f); - if (f->iconified) - { - int x, y; + if (iconified) + SET_FRAME_VISIBLE (f, 1); + SET_FRAME_ICONIFIED (f, 0); - /* Reset top and left positions of the Window - here since Windows sends a WM_MOVE message - BEFORE telling us the Window is minimized - when the Window is iconified, with 3000,3000 - as the co-ords. */ - x_real_positions (f, &x, &y); - f->left_pos = x; - f->top_pos = y; + /* wait_reading_process_output will notice this + and update the frame's display structures. */ + SET_FRAME_GARBAGED (f); - inev.kind = DEICONIFY_EVENT; - XSETFRAME (inev.frame_or_window, f); - } - else if (! NILP (Vframe_list) - && ! NILP (XCDR (Vframe_list))) - /* Force a redisplay sooner or later - to update the frame titles - in case this is the second frame. */ - record_asynch_buffer_change (); + if (iconified) + { + int x, y; + + /* Reset top and left positions of the Window + here since Windows sends a WM_MOVE message + BEFORE telling us the Window is minimized + when the Window is iconified, with 3000,3000 + as the co-ords. */ + x_real_positions (f, &x, &y); + f->left_pos = x; + f->top_pos = y; + + inev.kind = DEICONIFY_EVENT; + XSETFRAME (inev.frame_or_window, f); + } + else if (! NILP (Vframe_list) + && ! NILP (XCDR (Vframe_list))) + /* Force a redisplay sooner or later + to update the frame titles + in case this is the second frame. */ + record_asynch_buffer_change (); + } break; } } - if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED) + if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED) { RECT rect; int rows; @@ -4880,16 +4906,11 @@ w32_read_socket (struct terminal *terminal, break; case WM_KILLFOCUS: + w32_detect_focus_change (dpyinfo, &msg, &inev); f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd); if (f) { - if (f == dpyinfo->w32_focus_event_frame) - dpyinfo->w32_focus_event_frame = 0; - - if (f == dpyinfo->w32_focus_frame) - x_new_focus_frame (dpyinfo, 0); - if (f == hlinfo->mouse_face_mouse_frame) { /* If we move outside the frame, then we're @@ -4936,7 +4957,7 @@ w32_read_socket (struct terminal *terminal, if (f) { extern void menubar_selection_callback - (FRAME_PTR f, void * client_data); + (struct frame *f, void * client_data); menubar_selection_callback (f, (void *)msg.msg.wParam); } @@ -4957,7 +4978,7 @@ w32_read_socket (struct terminal *terminal, check_visibility = 1; break; -#ifdef WINDOWSNT +#if HAVE_W32NOTIFY case WM_EMACS_FILENOTIFY: f = x_window_to_frame (dpyinfo, msg.msg.hwnd); if (f) @@ -5033,19 +5054,20 @@ w32_read_socket (struct terminal *terminal, FOR_EACH_FRAME (tail, frame) { - FRAME_PTR f = XFRAME (frame); + struct frame *f = XFRAME (frame); /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED below. */ if (EQ (frame, tip_frame)) continue; /* Check "visible" frames and mark each as obscured or not. - Note that async_visible is nonzero for unobscured and - obscured frames, but zero for hidden and iconified frames. */ - if (FRAME_W32_P (f) && f->async_visible) + Note that visible is nonzero for unobscured and obscured + frames, but zero for hidden and iconified frames. */ + if (FRAME_W32_P (f) && FRAME_VISIBLE_P (f)) { RECT clipbox; HDC hdc; + bool obscured; enter_crit (); /* Query clipping rectangle for the entire window area @@ -5059,31 +5081,28 @@ w32_read_socket (struct terminal *terminal, ReleaseDC (FRAME_W32_WINDOW (f), hdc); leave_crit (); - if (clipbox.right == clipbox.left - || clipbox.bottom == clipbox.top) + obscured = FRAME_OBSCURED_P (f); + + if (clipbox.right == clipbox.left || clipbox.bottom == clipbox.top) { - /* Frame has become completely obscured so mark as - such (we do this by setting async_visible to 2 so - that FRAME_VISIBLE_P is still true, but redisplay - will skip it). */ - f->async_visible = 2; + /* Frame has become completely obscured so mark as such (we + do this by setting visible to 2 so that FRAME_VISIBLE_P + is still true, but redisplay will skip it). */ + SET_FRAME_VISIBLE (f, 2); - if (!FRAME_OBSCURED_P (f)) - { - DebPrint (("frame %p (%s) obscured\n", f, - SDATA (f->name))); - } + if (!obscured) + DebPrint (("frame %p (%s) obscured\n", f, SDATA (f->name))); } else { /* Frame is not obscured, so mark it as such. */ - f->async_visible = 1; + SET_FRAME_VISIBLE (f, 1); - if (FRAME_OBSCURED_P (f)) + if (obscured) { SET_FRAME_GARBAGED (f); - DebPrint (("obscured frame %p (%s) found to be visible\n", f, - SDATA (f->name))); + DebPrint (("obscured frame %p (%s) found to be visible\n", + f, SDATA (f->name))); /* Force a redisplay sooner or later. */ record_asynch_buffer_change (); @@ -5144,7 +5163,10 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row) the current matrix is invalid or such, give up. */ cursor_glyph = get_phys_cursor_glyph (w); if (cursor_glyph == NULL) - return; + { + DeleteObject (hb); + return; + } /* Compute frame-relative coordinates for phys cursor. */ get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h); @@ -5316,6 +5338,9 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, w32_system_caret_y = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y) + glyph_row->ascent - w->phys_cursor_ascent); + w32_system_caret_window = w; + w32_system_caret_hdr_height = WINDOW_HEADER_LINE_HEIGHT (w); + w32_system_caret_mode_height = WINDOW_MODE_LINE_HEIGHT (w); PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0); @@ -5650,74 +5675,51 @@ x_check_fullscreen (struct frame *f) } static void -w32fullscreen_hook (FRAME_PTR f) +w32fullscreen_hook (struct frame *f) { - static int normal_width, normal_height, normal_top, normal_left; - - if (f->async_visible) + if (FRAME_VISIBLE_P (f)) { - int width, height, top_pos, left_pos, pixel_height, pixel_width; - int cur_w = FRAME_COLS (f), cur_h = FRAME_LINES (f); - RECT workarea_rect; + HWND hwnd = FRAME_W32_WINDOW(f); + DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE); + RECT rect; - block_input (); - if (normal_height <= 0) - normal_height = cur_h; - if (normal_width <= 0) - normal_width = cur_w; - x_real_positions (f, &f->left_pos, &f->top_pos); - x_fullscreen_adjust (f, &width, &height, &top_pos, &left_pos); + block_input(); + f->want_fullscreen &= ~FULLSCREEN_WAIT; - SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0); - pixel_height = workarea_rect.bottom - workarea_rect.top; - pixel_width = workarea_rect.right - workarea_rect.left; + if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE) + GetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f)); - switch (f->want_fullscreen) - { - /* No difference between these two when there is no WM */ - case FULLSCREEN_MAXIMIZED: - PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, 0xf030, 0); - break; - case FULLSCREEN_BOTH: - height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height) - 2; - width = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width); - left_pos = workarea_rect.left; - top_pos = workarea_rect.top; - break; - case FULLSCREEN_WIDTH: - width = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width); - if (normal_height > 0) - height = normal_height; - left_pos = workarea_rect.left; - break; - case FULLSCREEN_HEIGHT: - height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height) - 2; - if (normal_width > 0) - width = normal_width; - top_pos = workarea_rect.top; - break; - case FULLSCREEN_NONE: - if (normal_height > 0) - height = normal_height; - else - normal_height = height; - if (normal_width > 0) - width = normal_width; - else - normal_width = width; - /* FIXME: Should restore the original position of the frame. */ - top_pos = left_pos = 0; - break; - } + if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH) + { + SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW); + SetWindowPos (hwnd, NULL, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + } - if (cur_w != width || cur_h != height) - { - x_set_offset (f, left_pos, top_pos, 1); - x_set_window_size (f, 1, width, height); - do_pending_window_change (0); - } + w32_fullscreen_rect (hwnd, f->want_fullscreen, + FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); + FRAME_PREV_FSMODE (f) = f->want_fullscreen; + if (f->want_fullscreen == FULLSCREEN_MAXIMIZED) + PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, 0xf030, 0); + else if (f->want_fullscreen == FULLSCREEN_BOTH) + { + SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); + SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, + SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + } + else + { + SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, 0); + } + + f->want_fullscreen = FULLSCREEN_NONE; unblock_input (); } + else + f->want_fullscreen |= FULLSCREEN_WAIT; } /* Call this to change the size of frame F's x-window. @@ -5872,11 +5874,6 @@ x_focus_on_frame (struct frame *f) unblock_input (); } -void -x_unfocus_frame (struct frame *f) -{ -} - /* Raise frame F. */ void x_raise_frame (struct frame *f) @@ -5952,7 +5949,7 @@ x_lower_frame (struct frame *f) } static void -w32_frame_raise_lower (FRAME_PTR f, int raise_flag) +w32_frame_raise_lower (struct frame *f, int raise_flag) { if (! FRAME_W32_P (f)) return; @@ -6014,11 +6011,11 @@ x_make_frame_visible (struct frame *f) causes unexpected behavior when unminimizing frames that were previously maximized. But only SW_SHOWNORMAL works properly for frames that were truely hidden (using make-frame-invisible), so - we need it to avoid Bug#5482. It seems that async_iconified - is only set for minimized windows that are still visible, so - use that to determine the appropriate flag to pass ShowWindow. */ + we need it to avoid Bug#5482. It seems that iconified is only + set for minimized windows that are still visible, so use that to + determine the appropriate flag to pass ShowWindow. */ my_show_window (f, FRAME_W32_WINDOW (f), - f->async_iconified ? SW_RESTORE : SW_SHOWNORMAL); + FRAME_ICONIFIED_P (f) ? SW_RESTORE : SW_SHOWNORMAL); } /* Synchronize to ensure Emacs knows the frame is visible @@ -6057,7 +6054,6 @@ x_make_frame_visible (struct frame *f) poll_suppress_count = old_poll_suppress_count; } } - FRAME_SAMPLE_VISIBILITY (f); } } @@ -6081,10 +6077,8 @@ x_make_frame_invisible (struct frame *f) So we can't win using the usual strategy of letting FRAME_SAMPLE_VISIBILITY set this. So do it by hand, and synchronize with the server to make sure we agree. */ - f->visible = 0; - FRAME_ICONIFIED_P (f) = 0; - f->async_visible = 0; - f->async_iconified = 0; + SET_FRAME_VISIBLE (f, 0); + SET_FRAME_ICONIFIED (f, 0); unblock_input (); } @@ -6100,7 +6094,7 @@ x_iconify_frame (struct frame *f) if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f) FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0; - if (f->async_iconified) + if (FRAME_ICONIFIED_P (f)) return; block_input (); @@ -6112,6 +6106,9 @@ x_iconify_frame (struct frame *f) /* Simulate the user minimizing the frame. */ SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0); + SET_FRAME_VISIBLE (f, 0); + SET_FRAME_ICONIFIED (f, 1); + unblock_input (); } @@ -6208,22 +6205,6 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) leave_crit (); } -/* Window manager things */ -void -x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y) -{ -#if 0 - Window window = FRAME_W32_WINDOW (f); - - f->display.x->wm_hints.flags |= IconPositionHint; - f->display.x->wm_hints.icon_x = icon_x; - f->display.x->wm_hints.icon_y = icon_y; - - XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints); -#endif -} - - /*********************************************************************** Fonts ***********************************************************************/ @@ -6616,7 +6597,7 @@ w32_initialize (void) } #ifdef CYGWIN - if ((w32_message_fd = open ("/dev/windows", O_RDWR | O_CLOEXEC)) == -1) + if ((w32_message_fd = emacs_open ("/dev/windows", O_RDWR, 0)) == -1) fatal ("opening /dev/windows: %s", strerror (errno)); #endif /* CYGWIN */ @@ -6634,7 +6615,7 @@ w32_initialize (void) Fset_input_mode (Qnil, Qnil, make_number (2), Qnil); { - DWORD input_locale_id = (DWORD) GetKeyboardLayout (0); + DWORD input_locale_id = ((DWORD_PTR) GetKeyboardLayout (0) & 0xffffffff); w32_keyboard_codepage = codepage_for_locale ((LCID) (input_locale_id & 0xffff)); }