summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2016-04-24 20:08:38 (GMT)
committerfvogel <fvogelnew1@free.fr>2016-04-24 20:08:38 (GMT)
commit6250eb699b51c0410198ede173942cb77c262bc9 (patch)
treef530019d9ef5100793e1aa4d283666ceaa796e13 /win
parentfa289415c7aaacc173ab97665af201a54eae611a (diff)
downloadtk-6250eb699b51c0410198ede173942cb77c262bc9.zip
tk-6250eb699b51c0410198ede173942cb77c262bc9.tar.gz
tk-6250eb699b51c0410198ede173942cb77c262bc9.tar.bz2
Bug [c95d4691ff] - Made Tk, on Win, aware of secondary monitors
Diffstat (limited to 'win')
-rw-r--r--win/tkWinInt.h1
-rw-r--r--win/tkWinWm.c54
-rw-r--r--win/tkWinX.c214
3 files changed, 197 insertions, 72 deletions
diff --git a/win/tkWinInt.h b/win/tkWinInt.h
index 0e2c844..f6f22fb 100644
--- a/win/tkWinInt.h
+++ b/win/tkWinInt.h
@@ -161,6 +161,7 @@ MODULE_SCOPE HICON TkWinGetIcon(Tk_Window tkw, DWORD iconsize);
*/
MODULE_SCOPE void TkWinDisplayChanged(Display *display);
+MODULE_SCOPE void TkWinGetAllMonitorsSize(Display *display);
MODULE_SCOPE void TkWinCleanupContainerList(void);
/*
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 4e7618d..fd5639c 100644
--- a/win/tkWinWm.c
+++ b/win/tkWinWm.c
@@ -546,6 +546,12 @@ static int WmWithdrawCmd(Tk_Window tkwin,
static void WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);
/*
+ * Declarations of static variables used in this file.
+ */
+
+static int screenId = -1; /* Used to enumerate monitors */
+
+/*
* Used in BytesPerLine
*/
@@ -7830,6 +7836,44 @@ TopLevelProc(
/*
*----------------------------------------------------------------------
*
+ * MonitorEnumProcScreenChanged
+ *
+ * Monitors enumeration callback. This updates the screen number for
+ * the given window. This callback is called once for each monitor.
+ *
+ * Results:
+ * Screen number of the given window is updated.
+ *
+ * Side effects:
+ * The window becomes "linked" to the new screen.
+ * All [winfo screenxxx ...] will return information based on the new
+ * screen.
+ *
+ *----------------------------------------------------------------------
+ */
+
+BOOL CALLBACK
+MonitorEnumProcScreenChanged(
+ HMONITOR hMonitor,
+ HDC hdcMonitor,
+ LPRECT lprcMonitor,
+ LPARAM dwData)
+{
+ HMONITOR hMonitorWin;
+
+ screenId++;
+ hMonitorWin = MonitorFromWindow(Tk_GetHWND(((TkWindow *) dwData)->window),
+ MONITOR_DEFAULTTOPRIMARY);
+ if (hMonitor == hMonitorWin) {
+ ((TkWindow *) dwData)->screenNum = screenId;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* WmProc --
*
* Callback from Windows whenever an event occurs on the decorative
@@ -7928,8 +7972,14 @@ WmProc(
} else {
HDC dc = GetDC(NULL);
- screen->width = LOWORD(lParam); /* horizontal res */
- screen->height = HIWORD(lParam); /* vertical res */
+ /*
+ * Get new width and height of all monitors. This call will
+ * fill in all display->screens[...].width and
+ * display->screens[...].height
+ */
+
+ TkWinGetAllMonitorsSize(Tk_Display(winPtr));
+
screen->mwidth = MulDiv(screen->width, 254,
GetDeviceCaps(dc, LOGPIXELSX) * 10);
screen->mheight = MulDiv(screen->height, 254,
diff --git a/win/tkWinX.c b/win/tkWinX.c
index 6c44059..4a07810 100644
--- a/win/tkWinX.c
+++ b/win/tkWinX.c
@@ -70,6 +70,7 @@ static int keyInputCharset = -1; /* The Win32 CHARSET for the keyboard
* encoding */
static Tcl_Encoding unicodeEncoding = NULL;
/* The UNICODE encoding */
+static int screenId = -1; /* Used to enumerate monitors */
/*
* Thread local storage. Notice that now each thread must have its own
@@ -437,6 +438,64 @@ TkGetDefaultScreenName(
/*
*----------------------------------------------------------------------
*
+ * MonitorEnumProcWidthHeight
+ *
+ * Monitors enumeration callback. This fills in the size (width and
+ * height in pixels) of all monitors. This callback is called once
+ * for each monitor.
+ *
+ * Results:
+ * Number of pixels in horizontal and vertical directions is updated
+ * for each monitor.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+BOOL CALLBACK
+MonitorEnumProcWidthHeight(
+ HMONITOR hMonitor,
+ HDC hdcMonitor,
+ LPRECT lprcMonitor,
+ LPARAM dwData)
+{
+ screenId++;
+ ((Display *) dwData)->screens[screenId].width = lprcMonitor->right
+ - lprcMonitor->left;
+ ((Display *) dwData)->screens[screenId].height = lprcMonitor->bottom
+ - lprcMonitor->top;
+ return TRUE;
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkGetAllMonitorsSize
+ *
+ * Updates the Tk record of the resolution of each monitor.
+ *
+ * Results:
+ * Number of pixels in horizontal and vertical directions for each monitor
+ * is filled in the appropriate place in the display structure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkWinGetAllMonitorsSize(
+ Display *display)
+{
+ screenId = -1;
+ EnumDisplayMonitors(NULL, NULL, MonitorEnumProcWidthHeight, (LPARAM) display);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkWinDisplayChanged --
*
* Called to set up initial screen info or when an event indicated
@@ -457,76 +516,85 @@ TkWinDisplayChanged(
{
HDC dc;
Screen *screen;
+ int screenId;
if (display == NULL || display->screens == NULL) {
return;
}
- screen = display->screens;
-
- dc = GetDC(NULL);
- screen->width = GetDeviceCaps(dc, HORZRES);
- screen->height = GetDeviceCaps(dc, VERTRES);
- screen->mwidth = MulDiv(screen->width, 254,
- GetDeviceCaps(dc, LOGPIXELSX) * 10);
- screen->mheight = MulDiv(screen->height, 254,
- GetDeviceCaps(dc, LOGPIXELSY) * 10);
/*
- * On windows, when creating a color bitmap, need two pieces of
- * information: the number of color planes and the number of pixels per
- * plane. Need to remember both quantities so that when constructing an
- * HBITMAP for offscreen rendering, we can specify the correct value for
- * the number of planes. Otherwise the HBITMAP won't be compatible with
- * the HWND and we'll just get blank spots copied onto the screen.
+ * Get width and height of all monitors. This call will fill in all
+ * display->screens[...].width and display->screens[...].height
*/
- screen->ext_data = INT2PTR(GetDeviceCaps(dc, PLANES));
- screen->root_depth = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data);
-
- if (screen->root_visual != NULL) {
- ckfree(screen->root_visual);
- }
- screen->root_visual = ckalloc(sizeof(Visual));
- screen->root_visual->visualid = 0;
- if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
- screen->root_visual->map_entries = GetDeviceCaps(dc, SIZEPALETTE);
- screen->root_visual->class = PseudoColor;
- screen->root_visual->red_mask = 0x0;
- screen->root_visual->green_mask = 0x0;
- screen->root_visual->blue_mask = 0x0;
- } else if (screen->root_depth == 4) {
- screen->root_visual->class = StaticColor;
- screen->root_visual->map_entries = 16;
- } else if (screen->root_depth == 8) {
- screen->root_visual->class = StaticColor;
- screen->root_visual->map_entries = 256;
- } else if (screen->root_depth == 12) {
- screen->root_visual->class = TrueColor;
- screen->root_visual->map_entries = 32;
- screen->root_visual->red_mask = 0xf0;
- screen->root_visual->green_mask = 0xf000;
- screen->root_visual->blue_mask = 0xf00000;
- } else if (screen->root_depth == 16) {
- screen->root_visual->class = TrueColor;
- screen->root_visual->map_entries = 64;
- screen->root_visual->red_mask = 0xf8;
- screen->root_visual->green_mask = 0xfc00;
- screen->root_visual->blue_mask = 0xf80000;
- } else if (screen->root_depth >= 24) {
- screen->root_visual->class = TrueColor;
- screen->root_visual->map_entries = 256;
- screen->root_visual->red_mask = 0xff;
- screen->root_visual->green_mask = 0xff00;
- screen->root_visual->blue_mask = 0xff0000;
- }
- screen->root_visual->bits_per_rgb = screen->root_depth;
- ReleaseDC(NULL, dc);
-
- if (screen->cmap != None) {
- XFreeColormap(display, screen->cmap);
+ TkWinGetAllMonitorsSize(display);
+
+ for (screenId = 0; screenId < display->nscreens; screenId++) {
+ screen = &display->screens[screenId];
+
+ dc = GetDC(NULL);
+ screen->mwidth = MulDiv(screen->width, 254,
+ GetDeviceCaps(dc, LOGPIXELSX) * 10);
+ screen->mheight = MulDiv(screen->height, 254,
+ GetDeviceCaps(dc, LOGPIXELSY) * 10);
+
+ /*
+ * On windows, when creating a color bitmap, need two pieces of
+ * information: the number of color planes and the number of pixels per
+ * plane. Need to remember both quantities so that when constructing an
+ * HBITMAP for offscreen rendering, we can specify the correct value for
+ * the number of planes. Otherwise the HBITMAP won't be compatible with
+ * the HWND and we'll just get blank spots copied onto the screen.
+ */
+
+ screen->ext_data = INT2PTR(GetDeviceCaps(dc, PLANES));
+ screen->root_depth = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data);
+
+ if (screen->root_visual != NULL) {
+ ckfree(screen->root_visual);
+ }
+ screen->root_visual = ckalloc(sizeof(Visual));
+ screen->root_visual->visualid = 0;
+ if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
+ screen->root_visual->map_entries = GetDeviceCaps(dc, SIZEPALETTE);
+ screen->root_visual->class = PseudoColor;
+ screen->root_visual->red_mask = 0x0;
+ screen->root_visual->green_mask = 0x0;
+ screen->root_visual->blue_mask = 0x0;
+ } else if (screen->root_depth == 4) {
+ screen->root_visual->class = StaticColor;
+ screen->root_visual->map_entries = 16;
+ } else if (screen->root_depth == 8) {
+ screen->root_visual->class = StaticColor;
+ screen->root_visual->map_entries = 256;
+ } else if (screen->root_depth == 12) {
+ screen->root_visual->class = TrueColor;
+ screen->root_visual->map_entries = 32;
+ screen->root_visual->red_mask = 0xf0;
+ screen->root_visual->green_mask = 0xf000;
+ screen->root_visual->blue_mask = 0xf00000;
+ } else if (screen->root_depth == 16) {
+ screen->root_visual->class = TrueColor;
+ screen->root_visual->map_entries = 64;
+ screen->root_visual->red_mask = 0xf8;
+ screen->root_visual->green_mask = 0xfc00;
+ screen->root_visual->blue_mask = 0xf80000;
+ } else if (screen->root_depth >= 24) {
+ screen->root_visual->class = TrueColor;
+ screen->root_visual->map_entries = 256;
+ screen->root_visual->red_mask = 0xff;
+ screen->root_visual->green_mask = 0xff00;
+ screen->root_visual->blue_mask = 0xff0000;
+ }
+ screen->root_visual->bits_per_rgb = screen->root_depth;
+ ReleaseDC(NULL, dc);
+
+ if (screen->cmap != None) {
+ XFreeColormap(display, screen->cmap);
+ }
+ screen->cmap = XCreateColormap(display, None, screen->root_visual,
+ AllocNone);
}
- screen->cmap = XCreateColormap(display, None, screen->root_visual,
- AllocNone);
}
/*
@@ -551,6 +619,7 @@ TkpOpenDisplay(
const char *display_name)
{
Screen *screen;
+ int screenId;
TkWinDrawable *twdPtr;
Display *display;
ThreadSpecificData *tsdPtr =
@@ -571,13 +640,15 @@ TkpOpenDisplay(
strcpy(display->display_name, display_name);
display->cursor_font = 1;
- display->nscreens = 1;
+ display->nscreens = GetSystemMetrics(SM_CMONITORS);
display->request = 1;
display->qlen = 0;
- screen = ckalloc(sizeof(Screen));
- ZeroMemory(screen, sizeof(Screen));
- screen->display = display;
+ screen = ckalloc(sizeof(Screen) * display->nscreens);
+ ZeroMemory(screen, sizeof(Screen) * display->nscreens);
+ for (screenId = 0; screenId < display->nscreens; screenId++) {
+ screen[screenId].display = display;
+ }
/*
* Set up the root window.
@@ -590,18 +661,21 @@ TkpOpenDisplay(
twdPtr->type = TWD_WINDOW;
twdPtr->window.winPtr = NULL;
twdPtr->window.handle = NULL;
- screen->root = (Window)twdPtr;
+ for (screenId = 0; screenId < display->nscreens; screenId++) {
+ screen[screenId].root = (Window)twdPtr;
+ }
/*
* Note that these pixel values are not palette relative.
*/
- screen->white_pixel = RGB(255, 255, 255);
- screen->black_pixel = RGB(0, 0, 0);
- screen->cmap = None;
+ for (screenId = 0; screenId < display->nscreens; screenId++) {
+ screen[screenId].white_pixel = RGB(255, 255, 255);
+ screen[screenId].black_pixel = RGB(0, 0, 0);
+ screen[screenId].cmap = None;
+ }
display->screens = screen;
- display->nscreens = 1;
display->default_screen = 0;
TkWinDisplayChanged(display);