Index: src/w32fns.c =================================================================== RCS file: /sources/emacs/emacs/src/w32fns.c,v retrieving revision 1.290 diff -c -r1.290 w32fns.c *** src/w32fns.c 15 Jul 2007 01:50:54 -0000 1.290 --- src/w32fns.c 21 Jul 2007 10:02:15 -0000 *************** *** 7458,7463 **** --- 7458,7464 ---- int *root_x, *root_y; { Lisp_Object left, top; + RECT monitor_rect; /* User-specified position? */ left = Fcdr (Fassq (Qleft, parms)); *************** *** 7468,7508 **** if (!INTEGERP (left) || !INTEGERP (top)) { POINT pt; BLOCK_INPUT; GetCursorPos (&pt); *root_x = pt.x; *root_y = pt.y; UNBLOCK_INPUT; } 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) /* It fits below the pointer */ ! *root_y += XINT (dy); ! else if (height + XINT (dy) <= *root_y) /* It fits above the pointer. */ *root_y -= height + XINT (dy); else /* Put it on the top. */ ! *root_y = 0; if (INTEGERP (left)) *root_x = XINT (left); ! else if (*root_x + XINT (dx) <= 0) ! *root_x = 0; /* Can happen for negative dx */ ! else if (*root_x + XINT (dx) + width <= FRAME_W32_DISPLAY_INFO (f)->width) /* It fits to the right of the pointer. */ *root_x += XINT (dx); ! else if (width + XINT (dx) <= *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; } --- 7469,7538 ---- if (!INTEGERP (left) || !INTEGERP (top)) { POINT pt; + HMODULE user32; + void *(WINAPI * monitor_from_point) (POINT, DWORD); + BOOL (WINAPI * get_monitor_info) (void *, void *); BLOCK_INPUT; GetCursorPos (&pt); *root_x = pt.x; *root_y = pt.y; + + /* Try to get the rectangle for the monitor around the point. If + the monitor API is not available (eg, on Windows 95) then + just assume there is only one monitor */ + monitor_rect.left = 0; + monitor_rect.right = FRAME_W32_DISPLAY_INFO (f)->width; + monitor_rect.top = 0; + monitor_rect.bottom = FRAME_W32_DISPLAY_INFO (f)->height; + if ((user32 = LoadLibrary ("user32"))) + { + if ((monitor_from_point = (void *(WINAPI *) (POINT, DWORD)) + GetProcAddress (user32, "MonitorFromPoint")) + && (get_monitor_info = (BOOL (WINAPI *) (void *, void*)) + GetProcAddress (user32, "GetMonitorInfoA"))) + { + void *monitor; + char buf[40 /* sizeof (MONITORINFO) */]; + *(DWORD *) buf = 40; /* set cbSize */ + monitor = (* monitor_from_point) (pt, 2 /* MONITOR_DEFAULTTONEAREST */); + if ((* get_monitor_info) (monitor, buf)) + monitor_rect = *(RECT *) (buf + sizeof (DWORD)); + } + + FreeLibrary (user32); + } + UNBLOCK_INPUT; } if (INTEGERP (top)) *root_y = XINT (top); ! else if (*root_y + XINT (dy) <= monitor_rect.top) ! *root_y = monitor_rect.top; /* Can happen for negative dy */ ! else if (*root_y + XINT (dy) + height <= monitor_rect.bottom) /* It fits below the pointer */ ! *root_y += XINT (dy); ! else if (*root_y - XINT (dy) - height >= monitor_rect.top) /* It fits above the pointer. */ *root_y -= height + XINT (dy); else /* Put it on the top. */ ! *root_y = monitor_rect.top; if (INTEGERP (left)) *root_x = XINT (left); ! else if (*root_x + XINT (dx) <= monitor_rect.left) ! *root_x = monitor_rect.left; /* Can happen for negative dx */ ! else if (*root_x + XINT (dx) + width <= monitor_rect.right) /* It fits to the right of the pointer. */ *root_x += XINT (dx); ! else if (*root_x - width - XINT (dx) >= monitor_rect.left) /* 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 = monitor_rect.left; }