diff options
| author | Jason Rumney | 2008-03-14 15:53:46 +0000 |
|---|---|---|
| committer | Jason Rumney | 2008-03-14 15:53:46 +0000 |
| commit | 64f0809df49fe27e4c9372859e5ceb1e4e643582 (patch) | |
| tree | aa18f42d3012964bacf2acb1c855859ee66cc6f0 /src | |
| parent | 31fe2b00d9ea2e8f96b009e0e34619bf07d2280e (diff) | |
| download | emacs-64f0809df49fe27e4c9372859e5ceb1e4e643582.tar.gz emacs-64f0809df49fe27e4c9372859e5ceb1e4e643582.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/w32fns.c | 86 |
2 files changed, 84 insertions, 10 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index df5adc233e2..9d496f46c32 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2008-03-14 Jason Rumney <jasonr@gnu.org> | ||
| 2 | |||
| 3 | * w32fns.c (MONITOR_DEFAULT_TO_NEAREST, struct MONITOR_INFO) | ||
| 4 | (MonitorFromPoint_Proc, GetMonitorInfo_Proc): New definitions. | ||
| 5 | (monitor_from_point_fn, get_monitor_info_fn): New globals. | ||
| 6 | (globals_of_w32fns): Initialize them. | ||
| 7 | (compute_tip_xy): Use them to position tooltips. | ||
| 8 | |||
| 1 | 2008-03-14 Glenn Morris <rgm@gnu.org> | 9 | 2008-03-14 Glenn Morris <rgm@gnu.org> |
| 2 | 10 | ||
| 3 | * emacs.c (main): Revert previous change. | 11 | * emacs.c (main): Revert previous change. |
diff --git a/src/w32fns.c b/src/w32fns.c index ffa5c8be6d8..348cda7a24e 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -261,16 +261,36 @@ static unsigned mouse_move_timer = 0; | |||
| 261 | /* Window that is tracking the mouse. */ | 261 | /* Window that is tracking the mouse. */ |
| 262 | static HWND track_mouse_window; | 262 | static HWND track_mouse_window; |
| 263 | 263 | ||
| 264 | /* Multi-monitor API definitions that are not pulled from the headers | ||
| 265 | since we are compiling for NT 4. */ | ||
| 266 | #ifndef MONITOR_DEFAULT_TO_NEAREST | ||
| 267 | #define MONITOR_DEFAULT_TO_NEAREST 2 | ||
| 268 | #endif | ||
| 269 | /* MinGW headers define MONITORINFO unconditionally, but MSVC ones don't. | ||
| 270 | To avoid a compile error on one or the other, redefine with a new name. */ | ||
| 271 | struct MONITOR_INFO | ||
| 272 | { | ||
| 273 | DWORD cbSize; | ||
| 274 | RECT rcMonitor; | ||
| 275 | RECT rcWork; | ||
| 276 | DWORD dwFlags; | ||
| 277 | }; | ||
| 278 | |||
| 264 | typedef BOOL (WINAPI * TrackMouseEvent_Proc) | 279 | typedef BOOL (WINAPI * TrackMouseEvent_Proc) |
| 265 | (IN OUT LPTRACKMOUSEEVENT lpEventTrack); | 280 | (IN OUT LPTRACKMOUSEEVENT lpEventTrack); |
| 266 | typedef LONG (WINAPI * ImmGetCompositionString_Proc) | 281 | typedef LONG (WINAPI * ImmGetCompositionString_Proc) |
| 267 | (IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen); | 282 | (IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen); |
| 268 | typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window); | 283 | typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window); |
| 284 | typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); | ||
| 285 | typedef BOOL (WINAPI * GetMonitorInfo_Proc) | ||
| 286 | (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); | ||
| 269 | 287 | ||
| 270 | TrackMouseEvent_Proc track_mouse_event_fn = NULL; | 288 | TrackMouseEvent_Proc track_mouse_event_fn = NULL; |
| 271 | ClipboardSequence_Proc clipboard_sequence_fn = NULL; | 289 | ClipboardSequence_Proc clipboard_sequence_fn = NULL; |
| 272 | ImmGetCompositionString_Proc get_composition_string_fn = NULL; | 290 | ImmGetCompositionString_Proc get_composition_string_fn = NULL; |
| 273 | ImmGetContext_Proc get_ime_context_fn = NULL; | 291 | ImmGetContext_Proc get_ime_context_fn = NULL; |
| 292 | MonitorFromPoint_Proc monitor_from_point_fn = NULL; | ||
| 293 | GetMonitorInfo_Proc get_monitor_info_fn = NULL; | ||
| 274 | 294 | ||
| 275 | extern AppendMenuW_Proc unicode_append_menu; | 295 | extern AppendMenuW_Proc unicode_append_menu; |
| 276 | 296 | ||
| @@ -315,6 +335,12 @@ static HWND w32_visible_system_caret_hwnd; | |||
| 315 | extern HMENU current_popup_menu; | 335 | extern HMENU current_popup_menu; |
| 316 | static int menubar_in_use = 0; | 336 | static int menubar_in_use = 0; |
| 317 | 337 | ||
| 338 | /* From w32uniscribe.h */ | ||
| 339 | #ifdef USE_FONT_BACKEND | ||
| 340 | extern void syms_of_w32uniscribe (); | ||
| 341 | extern int uniscribe_available; | ||
| 342 | #endif | ||
| 343 | |||
| 318 | 344 | ||
| 319 | /* Error if we are not connected to MS-Windows. */ | 345 | /* Error if we are not connected to MS-Windows. */ |
| 320 | void | 346 | void |
| @@ -4391,6 +4417,8 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 4391 | { | 4417 | { |
| 4392 | /* Perhaps, we must allow frame parameter, say `font-backend', | 4418 | /* Perhaps, we must allow frame parameter, say `font-backend', |
| 4393 | to specify which font backends to use. */ | 4419 | to specify which font backends to use. */ |
| 4420 | if (uniscribe_available) | ||
| 4421 | register_font_driver (&uniscribe_font_driver, f); | ||
| 4394 | register_font_driver (&w32font_driver, f); | 4422 | register_font_driver (&w32font_driver, f); |
| 4395 | 4423 | ||
| 4396 | x_default_parameter (f, parameters, Qfont_backend, Qnil, | 4424 | x_default_parameter (f, parameters, Qfont_backend, Qnil, |
| @@ -4910,7 +4938,7 @@ w32_load_font (f, fontname, size) | |||
| 4910 | bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist); | 4938 | bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist); |
| 4911 | bdf_file = SDATA (XCDR (bdf_pair)); | 4939 | bdf_file = SDATA (XCDR (bdf_pair)); |
| 4912 | 4940 | ||
| 4913 | // If the font is already loaded, do not load it again. | 4941 | /* If the font is already loaded, do not load it again. */ |
| 4914 | for (i = 0; i < dpyinfo->n_fonts; i++) | 4942 | for (i = 0; i < dpyinfo->n_fonts; i++) |
| 4915 | { | 4943 | { |
| 4916 | if ((dpyinfo->font_table[i].name | 4944 | if ((dpyinfo->font_table[i].name |
| @@ -7705,6 +7733,7 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y) | |||
| 7705 | int *root_x, *root_y; | 7733 | int *root_x, *root_y; |
| 7706 | { | 7734 | { |
| 7707 | Lisp_Object left, top; | 7735 | Lisp_Object left, top; |
| 7736 | int min_x, min_y, max_x, max_y; | ||
| 7708 | 7737 | ||
| 7709 | /* User-specified position? */ | 7738 | /* User-specified position? */ |
| 7710 | left = Fcdr (Fassq (Qleft, parms)); | 7739 | left = Fcdr (Fassq (Qleft, parms)); |
| @@ -7716,40 +7745,68 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y) | |||
| 7716 | { | 7745 | { |
| 7717 | POINT pt; | 7746 | POINT pt; |
| 7718 | 7747 | ||
| 7748 | /* Default min and max values. */ | ||
| 7749 | min_x = 0; | ||
| 7750 | min_y = 0; | ||
| 7751 | max_x = FRAME_W32_DISPLAY_INFO (f)->width; | ||
| 7752 | max_y = FRAME_W32_DISPLAY_INFO (f)->height; | ||
| 7753 | |||
| 7719 | BLOCK_INPUT; | 7754 | BLOCK_INPUT; |
| 7720 | GetCursorPos (&pt); | 7755 | GetCursorPos (&pt); |
| 7721 | *root_x = pt.x; | 7756 | *root_x = pt.x; |
| 7722 | *root_y = pt.y; | 7757 | *root_y = pt.y; |
| 7723 | UNBLOCK_INPUT; | 7758 | UNBLOCK_INPUT; |
| 7759 | |||
| 7760 | /* If multiple monitor support is available, constrain the tip onto | ||
| 7761 | the current monitor. This improves the above by allowing negative | ||
| 7762 | co-ordinates if monitor positions are such that they are valid, and | ||
| 7763 | snaps a tooltip onto a single monitor if we are close to the edge | ||
| 7764 | where it would otherwise flow onto the other monitor (or into | ||
| 7765 | nothingness if there is a gap in the overlap). */ | ||
| 7766 | if (monitor_from_point_fn && get_monitor_info_fn) | ||
| 7767 | { | ||
| 7768 | struct MONITOR_INFO info; | ||
| 7769 | HMONITOR monitor | ||
| 7770 | = monitor_from_point_fn (pt, MONITOR_DEFAULT_TO_NEAREST); | ||
| 7771 | info.cbSize = sizeof (info); | ||
| 7772 | |||
| 7773 | if (get_monitor_info_fn (monitor, &info)) | ||
| 7774 | { | ||
| 7775 | min_x = info.rcWork.left; | ||
| 7776 | min_y = info.rcWork.top; | ||
| 7777 | max_x = info.rcWork.right; | ||
| 7778 | max_y = info.rcWork.bottom; | ||
| 7779 | } | ||
| 7780 | } | ||
| 7724 | } | 7781 | } |
| 7725 | 7782 | ||
| 7726 | if (INTEGERP (top)) | 7783 | if (INTEGERP (top)) |
| 7727 | *root_y = XINT (top); | 7784 | *root_y = XINT (top); |
| 7728 | else if (*root_y + XINT (dy) <= 0) | 7785 | else if (*root_y + XINT (dy) <= min_y) |
| 7729 | *root_y = 0; /* Can happen for negative dy */ | 7786 | *root_y = min_y; /* Can happen for negative dy */ |
| 7730 | else if (*root_y + XINT (dy) + height <= FRAME_W32_DISPLAY_INFO (f)->height) | 7787 | else if (*root_y + XINT (dy) + height <= max_y) |
| 7731 | /* It fits below the pointer */ | 7788 | /* It fits below the pointer */ |
| 7732 | *root_y += XINT (dy); | 7789 | *root_y += XINT (dy); |
| 7733 | else if (height + XINT (dy) <= *root_y) | 7790 | else if (height + XINT (dy) + min_y <= *root_y) |
| 7734 | /* It fits above the pointer. */ | 7791 | /* It fits above the pointer. */ |
| 7735 | *root_y -= height + XINT (dy); | 7792 | *root_y -= height + XINT (dy); |
| 7736 | else | 7793 | else |
| 7737 | /* Put it on the top. */ | 7794 | /* Put it on the top. */ |
| 7738 | *root_y = 0; | 7795 | *root_y = min_y; |
| 7739 | 7796 | ||
| 7740 | if (INTEGERP (left)) | 7797 | if (INTEGERP (left)) |
| 7741 | *root_x = XINT (left); | 7798 | *root_x = XINT (left); |
| 7742 | else if (*root_x + XINT (dx) <= 0) | 7799 | else if (*root_x + XINT (dx) <= min_x) |
| 7743 | *root_x = 0; /* Can happen for negative dx */ | 7800 | *root_x = 0; /* Can happen for negative dx */ |
| 7744 | else if (*root_x + XINT (dx) + width <= FRAME_W32_DISPLAY_INFO (f)->width) | 7801 | else if (*root_x + XINT (dx) + width <= max_x) |
| 7745 | /* It fits to the right of the pointer. */ | 7802 | /* It fits to the right of the pointer. */ |
| 7746 | *root_x += XINT (dx); | 7803 | *root_x += XINT (dx); |
| 7747 | else if (width + XINT (dx) <= *root_x) | 7804 | else if (width + XINT (dx) + min_x <= *root_x) |
| 7748 | /* It fits to the left of the pointer. */ | 7805 | /* It fits to the left of the pointer. */ |
| 7749 | *root_x -= width + XINT (dx); | 7806 | *root_x -= width + XINT (dx); |
| 7750 | else | 7807 | else |
| 7751 | /* Put it left justified on the screen -- it ought to fit that way. */ | 7808 | /* Put it left justified on the screen -- it ought to fit that way. */ |
| 7752 | *root_x = 0; | 7809 | *root_x = min_x; |
| 7753 | } | 7810 | } |
| 7754 | 7811 | ||
| 7755 | 7812 | ||
| @@ -9311,6 +9368,12 @@ globals_of_w32fns () | |||
| 9311 | /* ditto for GetClipboardSequenceNumber. */ | 9368 | /* ditto for GetClipboardSequenceNumber. */ |
| 9312 | clipboard_sequence_fn = (ClipboardSequence_Proc) | 9369 | clipboard_sequence_fn = (ClipboardSequence_Proc) |
| 9313 | GetProcAddress (user32_lib, "GetClipboardSequenceNumber"); | 9370 | GetProcAddress (user32_lib, "GetClipboardSequenceNumber"); |
| 9371 | |||
| 9372 | monitor_from_point_fn = (MonitorFromPoint_Proc) | ||
| 9373 | GetProcAddress (user32_lib, "MonitorFromPoint"); | ||
| 9374 | get_monitor_info_fn = (GetMonitorInfo_Proc) | ||
| 9375 | GetProcAddress (user32_lib, "GetMonitorInfoA"); | ||
| 9376 | |||
| 9314 | { | 9377 | { |
| 9315 | HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); | 9378 | HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); |
| 9316 | get_composition_string_fn = (ImmGetCompositionString_Proc) | 9379 | get_composition_string_fn = (ImmGetCompositionString_Proc) |
| @@ -9325,6 +9388,9 @@ globals_of_w32fns () | |||
| 9325 | 9388 | ||
| 9326 | /* MessageBox does not work without this when linked to comctl32.dll 6.0. */ | 9389 | /* MessageBox does not work without this when linked to comctl32.dll 6.0. */ |
| 9327 | InitCommonControls (); | 9390 | InitCommonControls (); |
| 9391 | #ifdef USE_FONT_BACKEND | ||
| 9392 | syms_of_w32uniscribe (); | ||
| 9393 | #endif | ||
| 9328 | } | 9394 | } |
| 9329 | 9395 | ||
| 9330 | #undef abort | 9396 | #undef abort |