X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/cfc09582247ffef6a46b6249e2fba9136a62d21e..3438fe218c77633ee2c5f106e3a335f906347247:/src/w32fns.c diff --git a/src/w32fns.c b/src/w32fns.c index 5c135b2e46..1b1c500134 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1,6 +1,6 @@ /* Graphical user interface functions for the Microsoft W32 API. -Copyright (C) 1989, 1992-2011 Free Software Foundation, Inc. +Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -32,13 +32,13 @@ along with GNU Emacs. If not, see . */ #include "w32term.h" #include "frame.h" #include "window.h" +#include "character.h" #include "buffer.h" #include "intervals.h" #include "dispextern.h" #include "keyboard.h" #include "blockinput.h" #include "epaths.h" -#include "character.h" #include "charset.h" #include "coding.h" #include "ccl.h" @@ -140,8 +140,8 @@ struct MONITOR_INFO DWORD dwFlags; }; -/* Reportedly, VS 6 does not have this in its headers. */ -#if defined (_MSC_VER) && _MSC_VER < 1300 +/* Reportedly, MSVC does not have this in its headers. */ +#ifdef _MSC_VER DECLARE_HANDLE(HMONITOR); #endif @@ -183,7 +183,7 @@ unsigned int msh_mousewheel = 0; #define MENU_FREE_DELAY 1000 static unsigned menu_free_timer = 0; -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG static int image_cache_refcount, dpyinfo_refcount; #endif @@ -635,9 +635,8 @@ colormap_t w32_color_map[] = {"LightGreen" , PALETTERGB (144,238,144)}, }; -DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map, - 0, 0, 0, doc: /* Return the default color map. */) - (void) +static Lisp_Object +w32_default_color_map (void) { int i; colormap_t *pc = w32_color_map; @@ -658,6 +657,13 @@ DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map, return (cmap); } +DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map, + 0, 0, 0, doc: /* Return the default color map. */) + (void) +{ + return w32_default_color_map (); +} + static Lisp_Object w32_color_map_lookup (char *colorname) { @@ -672,7 +678,7 @@ w32_color_map_lookup (char *colorname) elt = XCAR (tail); if (!CONSP (elt)) continue; - tem = Fcar (elt); + tem = XCAR (elt); if (lstrcmpi (SDATA (tem), colorname) == 0) { @@ -683,7 +689,6 @@ w32_color_map_lookup (char *colorname) QUIT; } - UNBLOCK_INPUT; return ret; @@ -1001,8 +1006,7 @@ w32_map_color (FRAME_PTR f, COLORREF color) } /* not already mapped, so add to list and recreate Windows palette */ - list = (struct w32_palette_entry *) - xmalloc (sizeof (struct w32_palette_entry)); + 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; @@ -1104,8 +1108,7 @@ w32_defined_color (FRAME_PTR f, char *color, XColor *color_def, int alloc) if (entry == NULL && alloc) { /* not already mapped, so add to list */ - entry = (struct w32_palette_entry *) - xmalloc (sizeof (struct w32_palette_entry)); + entry = xmalloc (sizeof (struct w32_palette_entry)); SET_W32_COLOR (entry->entry, XUINT (tem)); entry->next = NULL; *prev = entry; @@ -2083,7 +2086,7 @@ w32_key_to_modifier (int key) key_mapping = Qnil; } - /* NB. This code runs in the input thread, asychronously to the lisp + /* NB. This code runs in the input thread, asynchronously to the lisp thread, so we must be careful to ensure access to lisp data is thread-safe. The following code is safe because the modifier variable values are updated atomically from lisp and symbols are @@ -2257,7 +2260,7 @@ w32_msg_pump (deferred_msg * msg_buf) some third party shell extensions can cause it to be used in system dialogs, which causes a crash if it is not initialized. This is a known bug in Windows, which was fixed long ago, but - the patch for XP is not publically available until XP SP3, + the patch for XP is not publicly available until XP SP3, and older versions will never be patched. */ CoInitialize (NULL); w32_createwindow ((struct frame *) msg.wParam); @@ -2412,7 +2415,7 @@ complete_deferred_msg (HWND hwnd, UINT msg, LRESULT result) deferred_msg * msg_buf = find_deferred_msg (hwnd, msg); if (msg_buf == NULL) - /* Message may have been cancelled, so don't abort. */ + /* Message may have been canceled, so don't abort. */ return; msg_buf->result = result; @@ -2474,6 +2477,10 @@ signal_user_input (void) if (!NILP (Vthrow_on_input)) { Vquit_flag = Vthrow_on_input; + /* Doing a QUIT from this thread is a bad idea, since this + unwinds the stack of the Lisp thread, and the Windows runtime + rightfully barfs. Disabled. */ +#if 0 /* If we're inside a function that wants immediate quits, do it now. */ if (immediate_quit && NILP (Vinhibit_quit)) @@ -2481,6 +2488,7 @@ signal_user_input (void) immediate_quit = 0; QUIT; } +#endif } } @@ -2499,19 +2507,19 @@ post_character_message (HWND hwnd, UINT msg, woken up if blocked in sys_select, but we do NOT want to post the quit_char message itself (because it will usually be as if the user had typed quit_char twice). Instead, we post a dummy - message that has no particular effect. */ + message that has no particular effect. */ { int c = wParam; if (isalpha (c) && wmsg.dwModifiers == ctrl_modifier) c = make_ctrl_char (c) & 0377; if (c == quit_char - || (wmsg.dwModifiers == 0 && - w32_quit_key && wParam == w32_quit_key)) + || (wmsg.dwModifiers == 0 + && w32_quit_key && wParam == w32_quit_key)) { Vquit_flag = Qt; /* The choice of message is somewhat arbitrary, as long as - the main thread handler just ignores it. */ + the main thread handler just ignores it. */ msg = WM_NULL; /* Interrupt any blocking system calls. */ @@ -2533,7 +2541,7 @@ post_character_message (HWND hwnd, UINT msg, the lisp thread to respond. Note that we don't want to block the input thread waiting for - a reponse from the lisp thread (although that would at least + a response from the lisp thread (although that would at least solve the deadlock problem above), because we want to be able to receive C-g to interrupt the lisp thread. */ cancel_all_deferred_msgs (); @@ -2875,7 +2883,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) key.dwControlKeyState = modifiers; add = w32_kbd_patch_key (&key); - /* 0 means an unrecognised keycode, negative means + /* 0 means an unrecognized keycode, negative means dead key. Ignore both. */ while (--add >= 0) { @@ -2938,7 +2946,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) break; case WM_IME_CHAR: - /* If we can't get the IME result as unicode, use default processing, + /* If we can't get the IME result as Unicode, use default processing, which will at least allow characters decodable in the system locale get through. */ if (!get_composition_string_fn) @@ -3653,6 +3661,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_EMACS_SHOWWINDOW: return ShowWindow ((HWND) wParam, (WPARAM) lParam); + case WM_EMACS_BRINGTOTOP: case WM_EMACS_SETFOREGROUND: { HWND foreground_window; @@ -3670,6 +3679,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) foreground_thread = 0; retval = SetForegroundWindow ((HWND) wParam); + if (msg == WM_EMACS_BRINGTOTOP) + retval = BringWindowToTop ((HWND) wParam); /* Detach from the previous foreground thread. */ if (foreground_thread) @@ -3706,7 +3717,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (w32_system_caret_hwnd == NULL) { /* Use the default caret width, and avoid changing it - unneccesarily, as it confuses screen reader software. */ + unnecessarily, as it confuses screen reader software. */ w32_system_caret_hwnd = hwnd; CreateCaret (hwnd, NULL, 0, w32_system_caret_height); @@ -3744,7 +3755,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) flags |= TPM_RIGHTBUTTON; /* Remember we did a SetCapture on the initial mouse down event, - so for safety, we make sure the capture is cancelled now. */ + so for safety, we make sure the capture is canceled now. */ ReleaseCapture (); button_state = 0; @@ -3868,7 +3879,7 @@ w32_window (struct frame *f, long window_prompting, int minibuffer_only) { char *str = SSDATA (Vx_resource_name); - f->namebuf = (char *) xmalloc (strlen (str) + 1); + f->namebuf = xmalloc (strlen (str) + 1); strcpy (f->namebuf, str); } @@ -3972,7 +3983,7 @@ x_make_gc (struct frame *f) /* Handler for signals raised during x_create_frame and - x_create_top_frame. FRAME is the frame which is partially + x_create_tip_frame. FRAME is the frame which is partially constructed. */ static Lisp_Object @@ -3981,18 +3992,19 @@ unwind_create_frame (Lisp_Object frame) struct frame *f = XFRAME (frame); /* If frame is ``official'', nothing to do. */ - if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame)) + if (NILP (Fmemq (frame, Vframe_list))) { -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); #endif x_free_frame_resources (f); + free_glyphs (f); -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG /* Check that reference counts are indeed correct. */ - xassert (dpyinfo->reference_count == dpyinfo_refcount); - xassert (dpyinfo->image_cache->refcount == image_cache_refcount); + eassert (dpyinfo->reference_count == dpyinfo_refcount); + eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); #endif return Qt; } @@ -4024,7 +4036,7 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms) for (i = 0; names[i]; i++) { - font = font_open_by_name (f, names[i]); + font = font_open_by_name (f, build_unibyte_string (names[i])); if (! NILP (font)) break; } @@ -4129,12 +4141,9 @@ This function is an internal primitive--use `make-frame' instead. */) FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL); f->terminal = dpyinfo->terminal; - f->terminal->reference_count++; f->output_method = output_w32; - f->output_data.w32 = - (struct w32_output *) xmalloc (sizeof (struct w32_output)); - memset (f->output_data.w32, 0, sizeof (struct w32_output)); + f->output_data.w32 = xzalloc (sizeof (struct w32_output)); FRAME_FONTSET (f) = -1; f->icon_name @@ -4147,8 +4156,9 @@ This function is an internal primitive--use `make-frame' instead. */) /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */ record_unwind_protect (unwind_create_frame, frame); -#if GLYPH_DEBUG - image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount; +#ifdef GLYPH_DEBUG + image_cache_refcount = + FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ @@ -4281,6 +4291,7 @@ This function is an internal primitive--use `make-frame' instead. */) x_make_gc (f); /* Now consider the frame official. */ + f->terminal->reference_count++; FRAME_W32_DISPLAY_INFO (f)->reference_count++; Vframe_list = Fcons (frame, Vframe_list); @@ -4768,7 +4779,7 @@ terminate Emacs if we can't open the connection. UNGCPRO; } if (NILP (Vw32_color_map)) - Vw32_color_map = Fw32_default_color_map (); + Vw32_color_map = w32_default_color_map (); /* Merge in system logical colors. */ add_system_logical_colors_to_map (&Vw32_color_map); @@ -4886,9 +4897,10 @@ If TYPE is not given or nil, the type is STRING. FORMAT gives the size in bits of each element if VALUE is a list. It must be one of 8, 16 or 32. If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8. -If OUTER_P is non-nil, the property is changed for the outer X window of +If OUTER-P is non-nil, the property is changed for the outer X window of 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) + (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); Atom prop_atom; @@ -4933,23 +4945,24 @@ FRAME nil or omitted means use the selected frame. Value is PROP. */) DEFUN ("x-window-property", Fx_window_property, Sx_window_property, - 1, 2, 0, + 1, 6, 0, doc: /* Value is the value of window property PROP on FRAME. If FRAME is nil or omitted, use the selected frame. -On MS Windows, this function only accepts the PROP and FRAME arguments. - On X Windows, the following optional arguments are also accepted: If TYPE is nil or omitted, get the property as a string. Otherwise TYPE is the name of the atom that denotes the type expected. If SOURCE is non-nil, get the property on that window instead of from FRAME. The number 0 denotes the root window. -If DELETE_P is non-nil, delete the property after retreiving it. -If VECTOR_RET_P is non-nil, don't return a string but a vector of values. +If DELETE-P is non-nil, delete the property after retrieving it. +If VECTOR-RET-P is non-nil, don't return a string but a vector of values. + +On MS Windows, this function accepts but ignores those optional arguments. Value is nil if FRAME hasn't a property with name PROP or if PROP has no value of TYPE (always string in the MS Windows case). */) - (Lisp_Object prop, Lisp_Object frame) + (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); Atom prop_atom; @@ -5004,15 +5017,6 @@ no value of TYPE (always string in the MS Windows case). */) cursor. Duplicated from xdisp.c, but cannot use the version there due to lack of atimers on w32. */ #define DEFAULT_HOURGLASS_DELAY 1 -/* Return non-zero if houglass timer has been started or hourglass is shown. */ -/* PENDING: if W32 can use atimers (atimer.[hc]) then the common impl in - xdisp.c could be used. */ - -int -hourglass_started (void) -{ - return hourglass_shown_p || hourglass_timer; -} /* Cancel a currently active hourglass timer, and start a new one. */ @@ -5223,17 +5227,15 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, from this point on, x_destroy_window might screw up reference counts etc. */ f->terminal = dpyinfo->terminal; - f->terminal->reference_count++; f->output_method = output_w32; - f->output_data.w32 = - (struct w32_output *) xmalloc (sizeof (struct w32_output)); - memset (f->output_data.w32, 0, sizeof (struct w32_output)); + f->output_data.w32 = xzalloc (sizeof (struct w32_output)); FRAME_FONTSET (f) = -1; f->icon_name = Qnil; -#if GLYPH_DEBUG - image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount; +#ifdef GLYPH_DEBUG + image_cache_refcount = + FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ FRAME_KBOARD (f) = kb; @@ -5374,15 +5376,16 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, UNGCPRO; + /* Now that the frame is official, it counts as a reference to + its display. */ + FRAME_W32_DISPLAY_INFO (f)->reference_count++; + f->terminal->reference_count++; + /* It is now ok to make the frame official even if we get an error below. And the frame needs to be on Vframe_list or making it visible won't work. */ Vframe_list = Fcons (frame, Vframe_list); - /* Now that the frame is official, it counts as a reference to - its display. */ - FRAME_W32_DISPLAY_INFO (f)->reference_count++; - /* Setting attributes of faces of the tooltip frame from resources and similar will increment face_change_count, which leads to the clearing of all current matrices. Since this isn't necessary @@ -6023,7 +6026,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) file = DECODE_FILE (build_string (filename)); } - /* User cancelled the dialog without making a selection. */ + /* User canceled the dialog without making a selection. */ else if (!CommDlgExtendedError ()) file = Qnil; /* An error occurred, fallback on reading from the mini-buffer. */ @@ -6194,8 +6197,7 @@ an integer representing a ShowWindow flag: if (!NILP (Vlocale_coding_system)) { Lisp_Object decoded = - code_convert_string_norecord (make_unibyte_string (errstr, - strlen (errstr)), + code_convert_string_norecord (build_unibyte_string (errstr), Vlocale_coding_system, 0); errstr = SSDATA (decoded); } @@ -6319,13 +6321,8 @@ The return value is the hotkey-id if registered, otherwise nil. */) /* Notify input thread about new hot-key definition, so that it takes effect without needing to switch focus. */ -#ifdef USE_LISP_UNION_TYPE PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY, - (WPARAM) key.i, 0); -#else - PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY, - (WPARAM) key, 0); -#endif + (WPARAM) XLI (key), 0); } return key; @@ -6347,13 +6344,8 @@ DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key, { /* Notify input thread about hot-key definition being removed, so that it takes effect without needing focus switch. */ -#ifdef USE_LISP_UNION_TYPE if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY, - (WPARAM) XINT (XCAR (item)), (LPARAM) item.i)) -#else - if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY, - (WPARAM) XINT (XCAR (item)), (LPARAM) item)) -#endif + (WPARAM) XINT (XCAR (item)), (LPARAM) XLI (item))) { MSG msg; GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); @@ -6425,13 +6417,8 @@ is set to off if the low bit of NEW-STATE is zero, otherwise on. */) if (!dwWindowsThreadId) return make_number (w32_console_toggle_lock_key (vk_code, new_state)); -#ifdef USE_LISP_UNION_TYPE - if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY, - (WPARAM) vk_code, (LPARAM) new_state.i)) -#else if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY, - (WPARAM) vk_code, (LPARAM) new_state)) -#endif + (WPARAM) vk_code, (LPARAM) XLI (new_state))) { MSG msg; GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); @@ -6483,7 +6470,6 @@ The following %-sequences are provided: { Lisp_Object line_status, battery_status, battery_status_symbol; Lisp_Object load_percentage, seconds, minutes, hours, remain; - Lisp_Object sequences[8]; long seconds_left = (long) system_status.BatteryLifeTime; @@ -6557,16 +6543,16 @@ The following %-sequences are provided: _snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60); remain = build_string (buffer); } - sequences[0] = Fcons (make_number ('L'), line_status); - sequences[1] = Fcons (make_number ('B'), battery_status); - sequences[2] = Fcons (make_number ('b'), battery_status_symbol); - sequences[3] = Fcons (make_number ('p'), load_percentage); - sequences[4] = Fcons (make_number ('s'), seconds); - sequences[5] = Fcons (make_number ('m'), minutes); - sequences[6] = Fcons (make_number ('h'), hours); - sequences[7] = Fcons (make_number ('t'), remain); - - status = Flist (8, sequences); + + status = listn (CONSTYPE_HEAP, 8, + Fcons (make_number ('L'), line_status), + Fcons (make_number ('B'), battery_status), + Fcons (make_number ('b'), battery_status_symbol), + Fcons (make_number ('p'), load_percentage), + Fcons (make_number ('s'), seconds), + Fcons (make_number ('m'), minutes), + Fcons (make_number ('h'), hours), + Fcons (make_number ('t'), remain)); } return status; } @@ -6695,13 +6681,13 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name, return Qnil; } /* Allocate memory for the PRINTER_INFO_2 struct */ - ppi2 = (PRINTER_INFO_2 *) xmalloc (dwNeeded); + ppi2 = xmalloc (dwNeeded); if (!ppi2) { ClosePrinter (hPrn); return Qnil; } - /* Call GetPrinter again with big enouth memory block */ + /* Call GetPrinter again with big enough memory block. */ err = GetPrinter (hPrn, 2, (LPBYTE)ppi2, dwNeeded, &dwReturned); ClosePrinter (hPrn); if (!err) @@ -6808,9 +6794,9 @@ syms_of_w32fns (void) Fput (Qundefined_color, Qerror_conditions, - pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); + listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror)); Fput (Qundefined_color, Qerror_message, - make_pure_c_string ("Undefined color")); + build_pure_c_string ("Undefined color")); staticpro (&w32_grabbed_keys); w32_grabbed_keys = Qnil;