/* MinGW-w64 does not have these functions in its import libraries *atthemomentofwriting. *Also,WindowsVistadoesn'thavethesefunctionsatall *(accordingtoMSDNitdoes,butthatisalie),sowe'dhave *toloadthemmanuallyanyway(otherwiseGTKappswon'tevenstart *onVista).
*/ typedefLONG
(WINAPI *funcGetDisplayConfigBufferSizes) (UINT32 flags,
UINT32* numPathArrayElements,
UINT32* numModeInfoArrayElements);
/* Get i_adapter'th adapter */ if (!EnumDisplayDevicesW (NULL, i_adapter, &dd, EDD_GET_DEVICE_INTERFACE_NAME)) break;
if ((dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == 0) continue;
/* Match this display adapter to one for which we've got monitor_info *(logicalmonitor==adapter)
*/ if (wcscmp (dd.DeviceName, monitor_info.szDevice) != 0) continue;
dm.dmSize = sizeof (dm);
/* Grab refresh rate for this adapter while we're at it */ if (EnumDisplaySettingsW (dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm))
frequency = dm.dmDisplayFrequency; else
frequency = 0;
/* Enumerate monitors connected to this display adapter */ for (i_monitor = 0; TRUE; i_monitor++)
{
DISPLAY_DEVICEW dd_monitor; char *device_id_lower, *tmp;
DWORD i;
GdkWin32Monitor *w32mon;
GdkMonitor *mon;
GdkRectangle rect;
HMONITOR scale_hmonitor;
POINT pt; int scale;
if (data->have_monitor_devices)
{ /* Get i_monitor'th monitor */ if (!EnumDisplayDevicesW (dd.DeviceName, i_monitor, &dd_monitor, EDD_GET_DEVICE_INTERFACE_NAME)) break;
/* Match this monitor to one of the monitor devices we found earlier */ for (i = 0, w32mon = NULL; i < data->monitors->len; i++)
{
GdkWin32Monitor *m = g_ptr_array_index (data->monitors, i);
if (g_strcmp0 (device_id_lower, m->instance_path) != 0) continue;
w32mon = m; break;
}
g_free (device_id_lower);
if (w32mon == NULL) continue;
w32mon->hmonitor = hmonitor;
} else
{ /* Headless PC or a virtual machine, it has no monitor devices. *Makeoneup.
*/
w32mon = g_object_new (GDK_TYPE_WIN32_MONITOR, "display", data->display, NULL);
g_ptr_array_add (data->monitors, w32mon);
i = data->monitors->len - 1;
w32mon->madeup = TRUE;
}
mon = GDK_MONITOR (w32mon);
if (gdk_monitor_get_model (mon) == NULL)
{
char *name = NULL;
/* Only use dd.DeviceName as a last resort, as it is just *\\.\DISPLAYX\MonitorY(forsomevaluesofXandY).
*/ if (dd_monitor.DeviceName[0] != L'\0')
name = g_utf16_to_utf8 (dd_monitor.DeviceName, -1, NULL, NULL, NULL); elseif (dd.DeviceName[0] != L'\0')
name = g_utf16_to_utf8 (dd.DeviceName, -1, NULL, NULL, NULL);
if (name != NULL)
gdk_monitor_set_model (mon, name);
g_free (name);
}
/* GetDeviceCaps seems to provide a wild guess, prefer more precise EDID info */ if (gdk_monitor_get_width_mm (mon) == 0 &&
gdk_monitor_get_height_mm (mon) == 0)
{
HDC hDC = CreateDCW (L"DISPLAY", monitor_info.szDevice, NULL, NULL);
/* frequency is in Hz and is unsigned long, *prefermorepreciserefresh_ratefoundearlier, *whichcomesasaNumerator&Denominatorpairandismoreprecise.
*/ if (gdk_monitor_get_refresh_rate (mon) == 0)
gdk_monitor_set_refresh_rate (mon, frequency * 1000);
/* This is the reason this function exists. This data is not available *viaotherfunctions.
*/
rect.x = monitor_info.rcWork.left;
rect.y = monitor_info.rcWork.top;
rect.width = (monitor_info.rcWork.right - monitor_info.rcWork.left);
rect.height = (monitor_info.rcWork.bottom - monitor_info.rcWork.top); /* This is temporary, scale will be applied below */
w32mon->work_rect = rect;
/* First acquire the scale using the current screen */
scale = gdk_win32_display_get_monitor_scale_factor (data->display, NULL, NULL);
/* acquire the scale using the monitor which the window is nearest */
pt.x = w32mon->work_rect.x + w32mon->work_rect.width / 2;
pt.y = w32mon->work_rect.y + w32mon->work_rect.height / 2;
scale_hmonitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
scale = gdk_win32_display_get_monitor_scale_factor (data->display, NULL, scale_hmonitor);
gdk_monitor_set_scale_factor (mon, scale); /* Now apply the scale to the work rectangle */
w32mon->work_rect.x /= scale;
w32mon->work_rect.y /= scale;
w32mon->work_rect.width /= scale;
w32mon->work_rect.height /= scale;
if (monitor_info.dwFlags & MONITORINFOF_PRIMARY && i != 0)
{ /* Put primary monitor at index 0, just in case somebody needs *toknowwhichoneistheprimary.
*/
GdkWin32Monitor *temp = g_ptr_array_index (data->monitors, 0);
g_ptr_array_index (data->monitors, 0) = w32mon;
g_ptr_array_index (data->monitors, i) = temp;
}
/* Work area is the most important component, actively used by GTK, *butourinitiallistofmonitordevicesdidnothaveit. *Anymonitordevicesnotmatchedinthisfunctionswillhave *0-filledworkareaandwillthereforebeuseless,soletthem *keepremove==TRUEandberemovedfurtherupthestack.
*/
w32mon->remove = FALSE;
/* One virtual monitor per display adapter */ if (w32mon->madeup) break;
}
}
returnTRUE;
}
staticvoid
prune_monitors (EnumMonitorData *data)
{ int i;
for (i = 0; i < data->monitors->len; i++)
{
GdkWin32Monitor *m;
m = g_ptr_array_index (data->monitors, i);
if (m->remove)
g_ptr_array_remove_index (data->monitors, i--);
}
}
if (data.monitors->len == 0 && data.have_monitor_devices)
{ /* We thought we had monitors, but enumeration eventually failed, and *wehavenone.Tryagain,thistimemakingstuffupaswego.
*/
data.have_monitor_devices = FALSE;
EnumDisplayMonitors (NULL, NULL, enum_monitor, (LPARAM) &data);
prune_monitors (&data);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.