Mercurial > emacs
changeset 92935:c99b62a964c4
(MONITOR_DEFAULT_TO_NEAREST, struct MONITOR_INFO)
(MonitorFromPoint_Proc, GetMonitorInfo_Proc): New definitions.
(monitor_from_point_fn, get_monitor_info_fn): New globals.
(globals_of_w32fns): Initialize them.
(compute_tip_xy): Use them to position tooltips.
author | Jason Rumney <jasonr@gnu.org> |
---|---|
date | Fri, 14 Mar 2008 15:53:01 +0000 |
parents | 8c3d216d3a74 |
children | 1814780cd628 |
files | src/w32fns.c |
diffstat | 1 files changed, 76 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/w32fns.c Fri Mar 14 14:37:22 2008 +0000 +++ b/src/w32fns.c Fri Mar 14 15:53:01 2008 +0000 @@ -261,16 +261,36 @@ /* Window that is tracking the mouse. */ static HWND track_mouse_window; +/* Multi-monitor API definitions that are not pulled from the headers + since we are compiling for NT 4. */ +#ifndef MONITOR_DEFAULT_TO_NEAREST +#define MONITOR_DEFAULT_TO_NEAREST 2 +#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 +{ + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; +}; + typedef BOOL (WINAPI * TrackMouseEvent_Proc) (IN OUT LPTRACKMOUSEEVENT lpEventTrack); typedef LONG (WINAPI * ImmGetCompositionString_Proc) (IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen); typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window); +typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); +typedef BOOL (WINAPI * GetMonitorInfo_Proc) + (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); TrackMouseEvent_Proc track_mouse_event_fn = NULL; ClipboardSequence_Proc clipboard_sequence_fn = NULL; ImmGetCompositionString_Proc get_composition_string_fn = NULL; ImmGetContext_Proc get_ime_context_fn = NULL; +MonitorFromPoint_Proc monitor_from_point_fn = NULL; +GetMonitorInfo_Proc get_monitor_info_fn = NULL; extern AppendMenuW_Proc unicode_append_menu; @@ -315,6 +335,12 @@ extern HMENU current_popup_menu; static int menubar_in_use = 0; +/* From w32uniscribe.h */ +#ifdef USE_FONT_BACKEND +extern void syms_of_w32uniscribe (); +extern int uniscribe_available; +#endif + /* Error if we are not connected to MS-Windows. */ void @@ -4391,6 +4417,8 @@ { /* Perhaps, we must allow frame parameter, say `font-backend', to specify which font backends to use. */ + if (uniscribe_available) + register_font_driver (&uniscribe_font_driver, f); register_font_driver (&w32font_driver, f); x_default_parameter (f, parameters, Qfont_backend, Qnil, @@ -4910,7 +4938,7 @@ bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist); bdf_file = SDATA (XCDR (bdf_pair)); - // If the font is already loaded, do not load it again. + /* If the font is already loaded, do not load it again. */ for (i = 0; i < dpyinfo->n_fonts; i++) { if ((dpyinfo->font_table[i].name @@ -7705,6 +7733,7 @@ int *root_x, *root_y; { Lisp_Object left, top; + int min_x, min_y, max_x, max_y; /* User-specified position? */ left = Fcdr (Fassq (Qleft, parms)); @@ -7716,40 +7745,68 @@ { POINT pt; + /* Default min and max values. */ + min_x = 0; + min_y = 0; + max_x = FRAME_W32_DISPLAY_INFO (f)->width; + max_y = FRAME_W32_DISPLAY_INFO (f)->height; + BLOCK_INPUT; GetCursorPos (&pt); *root_x = pt.x; *root_y = pt.y; UNBLOCK_INPUT; + + /* If multiple monitor support is available, constrain the tip onto + the current monitor. This improves the above by allowing negative + co-ordinates if monitor positions are such that they are valid, and + snaps a tooltip onto a single monitor if we are close to the edge + where it would otherwise flow onto the other monitor (or into + nothingness if there is a gap in the overlap). */ + if (monitor_from_point_fn && get_monitor_info_fn) + { + struct MONITOR_INFO info; + HMONITOR monitor + = monitor_from_point_fn (pt, MONITOR_DEFAULT_TO_NEAREST); + info.cbSize = sizeof (info); + + if (get_monitor_info_fn (monitor, &info)) + { + min_x = info.rcWork.left; + min_y = info.rcWork.top; + max_x = info.rcWork.right; + max_y = info.rcWork.bottom; + } + } } if (INTEGERP (top)) *root_y = XINT (top); - else if (*root_y + XINT (dy) <= 0) - *root_y = 0; /* Can happen for negative dy */ - else if (*root_y + XINT (dy) + height <= FRAME_W32_DISPLAY_INFO (f)->height) + else if (*root_y + XINT (dy) <= min_y) + *root_y = min_y; /* Can happen for negative dy */ + else if (*root_y + XINT (dy) + height <= max_y) /* It fits below the pointer */ *root_y += XINT (dy); - else if (height + XINT (dy) <= *root_y) + else if (height + XINT (dy) + min_y <= *root_y) /* It fits above the pointer. */ *root_y -= height + XINT (dy); else /* Put it on the top. */ - *root_y = 0; + *root_y = min_y; if (INTEGERP (left)) *root_x = XINT (left); - else if (*root_x + XINT (dx) <= 0) + else if (*root_x + XINT (dx) <= min_x) *root_x = 0; /* Can happen for negative dx */ - else if (*root_x + XINT (dx) + width <= FRAME_W32_DISPLAY_INFO (f)->width) + else if (*root_x + XINT (dx) + width <= max_x) /* It fits to the right of the pointer. */ *root_x += XINT (dx); - else if (width + XINT (dx) <= *root_x) + else if (width + XINT (dx) + min_x <= *root_x) /* It fits to the left of the pointer. */ *root_x -= width + XINT (dx); else /* Put it left justified on the screen -- it ought to fit that way. */ - *root_x = 0; + *root_x = min_x; } @@ -9311,6 +9368,12 @@ /* ditto for GetClipboardSequenceNumber. */ clipboard_sequence_fn = (ClipboardSequence_Proc) GetProcAddress (user32_lib, "GetClipboardSequenceNumber"); + + monitor_from_point_fn = (MonitorFromPoint_Proc) + GetProcAddress (user32_lib, "MonitorFromPoint"); + get_monitor_info_fn = (GetMonitorInfo_Proc) + GetProcAddress (user32_lib, "GetMonitorInfoA"); + { HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); get_composition_string_fn = (ImmGetCompositionString_Proc) @@ -9325,6 +9388,9 @@ /* MessageBox does not work without this when linked to comctl32.dll 6.0. */ InitCommonControls (); +#ifdef USE_FONT_BACKEND + syms_of_w32uniscribe (); +#endif } #undef abort