mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 14:10:30 +00:00
1d838f586c
There are sure regressions but basic stuff seems to be working again after all the API breakage done with comments like "Win32 and Quartz need to be ported still."
529 lines
15 KiB
C
529 lines
15 KiB
C
/* GDK - The GIMP Drawing Kit
|
|
* Copyright (C) 2002,2005 Hans Breuer
|
|
* Copyright (C) 2003 Tor Lillqvist
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "gdk.h"
|
|
#include "gdkprivate-win32.h"
|
|
#include "gdkdisplayprivate.h"
|
|
#include "gdkwin32display.h"
|
|
#include "gdkwin32screen.h"
|
|
#include "gdkwin32window.h"
|
|
|
|
#define HAVE_MONITOR_INFO
|
|
|
|
#if defined(_MSC_VER) && (WINVER < 0x500) && (WINVER > 0x0400)
|
|
#include <multimon.h>
|
|
#elif defined(_MSC_VER) && (WINVER <= 0x0400)
|
|
#undef HAVE_MONITOR_INFO
|
|
#endif
|
|
|
|
void
|
|
_gdk_windowing_set_default_display (GdkDisplay *display)
|
|
{
|
|
g_assert (display == NULL || _gdk_display == display);
|
|
}
|
|
|
|
static gulong
|
|
gdk_win32_display_get_next_serial (GdkDisplay *display)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#ifdef HAVE_MONITOR_INFO
|
|
static BOOL CALLBACK
|
|
count_monitor (HMONITOR hmonitor,
|
|
HDC hdc,
|
|
LPRECT rect,
|
|
LPARAM data)
|
|
{
|
|
gint *n = (gint *) data;
|
|
|
|
(*n)++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static BOOL CALLBACK
|
|
enum_monitor (HMONITOR hmonitor,
|
|
HDC hdc,
|
|
LPRECT rect,
|
|
LPARAM data)
|
|
{
|
|
/* The struct MONITORINFOEX definition is for some reason different
|
|
* in the winuser.h bundled with mingw64 from that in MSDN and the
|
|
* official 32-bit mingw (the MONITORINFO part is in a separate "mi"
|
|
* member). So to keep this easily compileable with either, repeat
|
|
* the MSDN definition it here.
|
|
*/
|
|
typedef struct tagMONITORINFOEXA2 {
|
|
DWORD cbSize;
|
|
RECT rcMonitor;
|
|
RECT rcWork;
|
|
DWORD dwFlags;
|
|
CHAR szDevice[CCHDEVICENAME];
|
|
} MONITORINFOEXA2;
|
|
|
|
MONITORINFOEXA2 monitor_info;
|
|
HDC hDC;
|
|
|
|
gint *index = (gint *) data;
|
|
GdkWin32Monitor *monitor;
|
|
|
|
g_assert (*index < _gdk_num_monitors);
|
|
|
|
monitor = _gdk_monitors + *index;
|
|
|
|
monitor_info.cbSize = sizeof (MONITORINFOEX);
|
|
GetMonitorInfoA (hmonitor, (MONITORINFO *) &monitor_info);
|
|
|
|
#ifndef MONITORINFOF_PRIMARY
|
|
#define MONITORINFOF_PRIMARY 1
|
|
#endif
|
|
|
|
monitor->name = g_strdup (monitor_info.szDevice);
|
|
hDC = CreateDCA ("DISPLAY", monitor_info.szDevice, NULL, NULL);
|
|
monitor->width_mm = GetDeviceCaps (hDC, HORZSIZE);
|
|
monitor->height_mm = GetDeviceCaps (hDC, VERTSIZE);
|
|
DeleteDC (hDC);
|
|
monitor->rect.x = monitor_info.rcMonitor.left;
|
|
monitor->rect.y = monitor_info.rcMonitor.top;
|
|
monitor->rect.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
|
|
monitor->rect.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
|
|
|
|
if (monitor_info.dwFlags & MONITORINFOF_PRIMARY &&
|
|
*index != 0)
|
|
{
|
|
/* Put primary monitor at index 0, just in case somebody needs
|
|
* to know which one is the primary.
|
|
*/
|
|
GdkWin32Monitor temp = *monitor;
|
|
*monitor = _gdk_monitors[0];
|
|
_gdk_monitors[0] = temp;
|
|
}
|
|
|
|
(*index)++;
|
|
|
|
return TRUE;
|
|
}
|
|
#endif /* HAVE_MONITOR_INFO */
|
|
|
|
void
|
|
_gdk_monitor_init (void)
|
|
{
|
|
#ifdef HAVE_MONITOR_INFO
|
|
gint i, index;
|
|
|
|
_gdk_num_monitors = 0;
|
|
|
|
EnumDisplayMonitors (NULL, NULL, count_monitor, (LPARAM) &_gdk_num_monitors);
|
|
|
|
_gdk_monitors = g_renew (GdkWin32Monitor, _gdk_monitors, _gdk_num_monitors);
|
|
|
|
index = 0;
|
|
EnumDisplayMonitors (NULL, NULL, enum_monitor, (LPARAM) &index);
|
|
|
|
_gdk_offset_x = G_MININT;
|
|
_gdk_offset_y = G_MININT;
|
|
|
|
/* Calculate offset */
|
|
for (i = 0; i < _gdk_num_monitors; i++)
|
|
{
|
|
_gdk_offset_x = MAX (_gdk_offset_x, -_gdk_monitors[i].rect.x);
|
|
_gdk_offset_y = MAX (_gdk_offset_y, -_gdk_monitors[i].rect.y);
|
|
}
|
|
GDK_NOTE (MISC, g_print ("Multi-monitor offset: (%d,%d)\n",
|
|
_gdk_offset_x, _gdk_offset_y));
|
|
|
|
/* Translate monitor coords into GDK coordinate space */
|
|
for (i = 0; i < _gdk_num_monitors; i++)
|
|
{
|
|
_gdk_monitors[i].rect.x += _gdk_offset_x;
|
|
_gdk_monitors[i].rect.y += _gdk_offset_y;
|
|
GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@%+d%+d\n",
|
|
i, _gdk_monitors[i].rect.width,
|
|
_gdk_monitors[i].rect.height,
|
|
_gdk_monitors[i].rect.x,
|
|
_gdk_monitors[i].rect.y));
|
|
}
|
|
#else
|
|
HDC hDC;
|
|
|
|
_gdk_num_monitors = 1;
|
|
_gdk_monitors = g_renew (GdkWin32Monitor, _gdk_monitors, 1);
|
|
|
|
_gdk_monitors[0].name = g_strdup ("DISPLAY");
|
|
hDC = GetDC (NULL);
|
|
_gdk_monitors[0].width_mm = GetDeviceCaps (hDC, HORZSIZE);
|
|
_gdk_monitors[0].height_mm = GetDeviceCaps (hDC, VERTSIZE);
|
|
ReleaseDC (NULL, hDC);
|
|
_gdk_monitors[0].rect.x = 0;
|
|
_gdk_monitors[0].rect.y = 0;
|
|
_gdk_monitors[0].rect.width = GetSystemMetrics (SM_CXSCREEN);
|
|
_gdk_monitors[0].rect.height = GetSystemMetrics (SM_CYSCREEN);
|
|
_gdk_offset_x = 0;
|
|
_gdk_offset_y = 0;
|
|
#endif
|
|
}
|
|
|
|
GdkDisplay *
|
|
_gdk_win32_display_open (const gchar *display_name)
|
|
{
|
|
GDK_NOTE (MISC, g_print ("gdk_display_open: %s\n", (display_name ? display_name : "NULL")));
|
|
|
|
if (display_name == NULL ||
|
|
g_ascii_strcasecmp (display_name,
|
|
gdk_display_get_name (_gdk_display)) == 0)
|
|
{
|
|
if (_gdk_display != NULL)
|
|
{
|
|
GDK_NOTE (MISC, g_print ("... return _gdk_display\n"));
|
|
return _gdk_display;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GDK_NOTE (MISC, g_print ("... return NULL\n"));
|
|
return NULL;
|
|
}
|
|
|
|
_gdk_display = g_object_new (GDK_TYPE_WIN32_DISPLAY, NULL);
|
|
_gdk_screen = g_object_new (GDK_TYPE_WIN32_SCREEN, NULL);
|
|
|
|
_gdk_monitor_init ();
|
|
_gdk_visual_init ();
|
|
_gdk_windowing_window_init (_gdk_screen);
|
|
_gdk_events_init ();
|
|
_gdk_input_init (_gdk_display);
|
|
_gdk_dnd_init ();
|
|
|
|
/* Precalculate display name */
|
|
(void) gdk_display_get_name (_gdk_display);
|
|
|
|
g_signal_emit_by_name (gdk_display_manager_get (),
|
|
"display_opened", _gdk_display);
|
|
|
|
GDK_NOTE (MISC, g_print ("... _gdk_display now set up\n"));
|
|
|
|
return _gdk_display;
|
|
}
|
|
|
|
struct _GdkWin32Display
|
|
{
|
|
GdkDisplay display;
|
|
};
|
|
|
|
struct _GdkWin32DisplayClass
|
|
{
|
|
GdkDisplayClass display_class;
|
|
};
|
|
|
|
G_DEFINE_TYPE (GdkWin32Display, gdk_win32_display, GDK_TYPE_DISPLAY)
|
|
|
|
static G_CONST_RETURN gchar *
|
|
gdk_win32_display_get_name (GdkDisplay *display)
|
|
{
|
|
HDESK hdesk = GetThreadDesktop (GetCurrentThreadId ());
|
|
char dummy;
|
|
char *desktop_name;
|
|
HWINSTA hwinsta = GetProcessWindowStation ();
|
|
char *window_station_name;
|
|
DWORD n;
|
|
DWORD session_id;
|
|
char *display_name;
|
|
static const char *display_name_cache = NULL;
|
|
typedef BOOL (WINAPI *PFN_ProcessIdToSessionId) (DWORD, DWORD *);
|
|
PFN_ProcessIdToSessionId processIdToSessionId;
|
|
|
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
|
|
|
if (display_name_cache != NULL)
|
|
return display_name_cache;
|
|
|
|
n = 0;
|
|
GetUserObjectInformation (hdesk, UOI_NAME, &dummy, 0, &n);
|
|
if (n == 0)
|
|
desktop_name = "Default";
|
|
else
|
|
{
|
|
n++;
|
|
desktop_name = g_alloca (n + 1);
|
|
memset (desktop_name, 0, n + 1);
|
|
|
|
if (!GetUserObjectInformation (hdesk, UOI_NAME, desktop_name, n, &n))
|
|
desktop_name = "Default";
|
|
}
|
|
|
|
n = 0;
|
|
GetUserObjectInformation (hwinsta, UOI_NAME, &dummy, 0, &n);
|
|
if (n == 0)
|
|
window_station_name = "WinSta0";
|
|
else
|
|
{
|
|
n++;
|
|
window_station_name = g_alloca (n + 1);
|
|
memset (window_station_name, 0, n + 1);
|
|
|
|
if (!GetUserObjectInformation (hwinsta, UOI_NAME, window_station_name, n, &n))
|
|
window_station_name = "WinSta0";
|
|
}
|
|
|
|
processIdToSessionId = (PFN_ProcessIdToSessionId) GetProcAddress (GetModuleHandle ("kernel32.dll"), "ProcessIdToSessionId");
|
|
if (!processIdToSessionId || !processIdToSessionId (GetCurrentProcessId (), &session_id))
|
|
session_id = 0;
|
|
|
|
display_name = g_strdup_printf ("%ld\\%s\\%s",
|
|
session_id,
|
|
window_station_name,
|
|
desktop_name);
|
|
|
|
GDK_NOTE (MISC, g_print ("gdk_win32_display_get_name: %s\n", display_name));
|
|
|
|
display_name_cache = display_name;
|
|
|
|
return display_name_cache;
|
|
}
|
|
|
|
static gint
|
|
gdk_win32_display_get_n_screens (GdkDisplay *display)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static GdkScreen *
|
|
gdk_win32_display_get_screen (GdkDisplay *display,
|
|
gint screen_num)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
|
g_return_val_if_fail (screen_num == 0, NULL);
|
|
|
|
return _gdk_screen;
|
|
}
|
|
|
|
static GdkScreen *
|
|
gdk_win32_display_get_default_screen (GdkDisplay *display)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
|
|
|
return _gdk_screen;
|
|
}
|
|
|
|
static GdkWindow *
|
|
gdk_win32_display_get_default_group (GdkDisplay *display)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
|
|
|
g_warning ("gdk_display_get_default_group not yet implemented");
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static gboolean
|
|
gdk_win32_display_supports_selection_notification (GdkDisplay *display)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
gdk_win32_display_request_selection_notification (GdkDisplay *display,
|
|
GdkAtom selection)
|
|
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
gdk_win32_display_supports_clipboard_persistence (GdkDisplay *display)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
gdk_win32_display_store_clipboard (GdkDisplay *display,
|
|
GdkWindow *clipboard_window,
|
|
guint32 time_,
|
|
const GdkAtom *targets,
|
|
gint n_targets)
|
|
{
|
|
}
|
|
|
|
static gboolean
|
|
gdk_win32_display_supports_shapes (GdkDisplay *display)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
gdk_win32_display_supports_input_shapes (GdkDisplay *display)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
|
|
|
/* Not yet implemented. See comment in
|
|
* gdk_window_input_shape_combine_mask().
|
|
*/
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
gdk_win32_display_supports_composite (GdkDisplay *display)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
gdk_win32_display_beep (GdkDisplay *display)
|
|
{
|
|
g_return_if_fail (display == gdk_display_get_default());
|
|
if (!MessageBeep (-1))
|
|
Beep(1000, 50);
|
|
}
|
|
|
|
static void
|
|
gdk_win32_display_flush (GdkDisplay * display)
|
|
{
|
|
g_return_if_fail (display == _gdk_display);
|
|
|
|
GdiFlush ();
|
|
}
|
|
|
|
static void
|
|
gdk_win32_display_dispose (GObject *object)
|
|
{
|
|
}
|
|
|
|
static void
|
|
gdk_win32_display_finalize (GObject *object)
|
|
{
|
|
}
|
|
|
|
static void
|
|
gdk_win32_display_init(GdkWin32Display *display)
|
|
{
|
|
}
|
|
|
|
static void
|
|
gdk_win32_display_before_process_all_updates (GdkDisplay *display)
|
|
{
|
|
/* nothing */
|
|
}
|
|
static void
|
|
gdk_win32_display_after_process_all_updates (GdkDisplay *display)
|
|
{
|
|
/* nothing */
|
|
}
|
|
static void
|
|
gdk_win32_display_notify_startup_complete (GdkDisplay *display,
|
|
const gchar *startup_id)
|
|
{
|
|
/* nothing */
|
|
}
|
|
static void
|
|
gdk_win32_display_event_data_copy (GdkDisplay *display,
|
|
const GdkEvent *src,
|
|
GdkEvent *dst)
|
|
{
|
|
/* nothing */
|
|
}
|
|
static void
|
|
gdk_win32_display_event_data_free (GdkDisplay *display,
|
|
GdkEvent *event)
|
|
{
|
|
/* nothing */
|
|
}
|
|
static void
|
|
gdk_win32_display_push_error_trap (GdkDisplay *display)
|
|
{
|
|
/* nothing */
|
|
}
|
|
static gint
|
|
gdk_win32_display_pop_error_trap (GdkDisplay *display,
|
|
gboolean ignored)
|
|
{
|
|
return 0;
|
|
}
|
|
static void
|
|
gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (klass);
|
|
|
|
object_class->dispose = gdk_win32_display_dispose;
|
|
object_class->finalize = gdk_win32_display_finalize;
|
|
|
|
display_class->window_type = GDK_TYPE_WIN32_WINDOW;
|
|
|
|
display_class->get_name = gdk_win32_display_get_name;
|
|
display_class->get_n_screens = gdk_win32_display_get_n_screens;
|
|
display_class->get_screen = gdk_win32_display_get_screen;
|
|
display_class->get_default_screen = gdk_win32_display_get_default_screen;
|
|
display_class->beep = gdk_win32_display_beep;
|
|
display_class->sync = _gdk_win32_display_sync;
|
|
display_class->flush = gdk_win32_display_flush;
|
|
display_class->has_pending = _gdk_win32_display_has_pending;
|
|
display_class->queue_events = _gdk_win32_display_queue_events;
|
|
display_class->get_default_group = gdk_win32_display_get_default_group;
|
|
|
|
display_class->supports_selection_notification = gdk_win32_display_supports_selection_notification;
|
|
display_class->request_selection_notification = gdk_win32_display_request_selection_notification;
|
|
display_class->supports_clipboard_persistence = gdk_win32_display_supports_clipboard_persistence;
|
|
display_class->store_clipboard = gdk_win32_display_store_clipboard;
|
|
display_class->supports_shapes = gdk_win32_display_supports_shapes;
|
|
display_class->supports_input_shapes = gdk_win32_display_supports_input_shapes;
|
|
display_class->supports_composite = gdk_win32_display_supports_composite;
|
|
|
|
display_class->list_devices = _gdk_win32_display_list_devices;
|
|
display_class->send_client_message = _gdk_win32_display_send_client_message;
|
|
display_class->add_client_message_filter = _gdk_win32_display_add_client_message_filter;
|
|
//? display_class->get_app_launch_context = _gdk_win32_display_get_app_launch_context;
|
|
display_class->get_drag_protocol = _gdk_win32_display_get_drag_protocol;
|
|
display_class->get_cursor_for_type = _gdk_win32_display_get_cursor_for_type;
|
|
display_class->get_cursor_for_name = _gdk_win32_display_get_cursor_for_name;
|
|
display_class->get_cursor_for_pixbuf = _gdk_win32_display_get_cursor_for_pixbuf;
|
|
display_class->get_default_cursor_size = _gdk_win32_display_get_default_cursor_size;
|
|
display_class->get_maximal_cursor_size = _gdk_win32_display_get_maximal_cursor_size;
|
|
display_class->supports_cursor_alpha = _gdk_win32_display_supports_cursor_alpha;
|
|
display_class->supports_cursor_color = _gdk_win32_display_supports_cursor_color;
|
|
|
|
display_class->before_process_all_updates = gdk_win32_display_before_process_all_updates;
|
|
display_class->after_process_all_updates = gdk_win32_display_after_process_all_updates;
|
|
display_class->get_next_serial = gdk_win32_display_get_next_serial;
|
|
display_class->notify_startup_complete = gdk_win32_display_notify_startup_complete;
|
|
display_class->event_data_copy = gdk_win32_display_event_data_copy;
|
|
display_class->event_data_free = gdk_win32_display_event_data_free;
|
|
display_class->create_window_impl = _gdk_win32_display_create_window_impl;
|
|
|
|
display_class->get_keymap = _gdk_win32_display_get_keymap;
|
|
display_class->push_error_trap = gdk_win32_display_push_error_trap;
|
|
display_class->pop_error_trap = gdk_win32_display_pop_error_trap;
|
|
display_class->get_selection_owner = _gdk_win32_display_get_selection_owner;
|
|
display_class->set_selection_owner = _gdk_win32_display_set_selection_owner;
|
|
display_class->send_selection_notify = _gdk_win32_display_send_selection_notify;
|
|
display_class->get_selection_property = _gdk_win32_display_get_selection_property;
|
|
display_class->convert_selection = _gdk_win32_display_convert_selection;
|
|
display_class->text_property_to_utf8_list = _gdk_win32_display_text_property_to_utf8_list;
|
|
display_class->utf8_to_string_target = _gdk_win32_display_utf8_to_string_target;
|
|
}
|