Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f672a788f9 | |||
| a4a5a4807f | |||
| d2d09fe40d | |||
| 4aed4cf40a | |||
| 194d73f432 | |||
| 6aa3d4cb37 | |||
| b10ac55551 | |||
| d4c187ffc7 | |||
| 70cbbb148f | |||
| 7c1e9588b3 | |||
| a1f86d0878 | |||
| df19d99ebd | |||
| 1b86a7647b | |||
| df589e3cf6 | |||
| 31bf2677ba | |||
| fd586f7ade | |||
| ec0b81e1eb | |||
| e4e3d5c389 | |||
| f18e5d1ccb | |||
| 05b023980a | |||
| b348de178e | |||
| acb0f796a0 | |||
| 7201a76a62 | |||
| 62a1c0a8b4 | |||
| bbe69dbd4b | |||
| 589c7dd779 | |||
| a4929f0d28 | |||
| 4775aa24c7 | |||
| e1a2f9bde7 | |||
| ef0ae6464f | |||
| b7f3da23d1 | |||
| 7901fbfcf5 | |||
| 73735acb29 | |||
| ab76987099 | |||
| de2837056a | |||
| 0f37375c45 | |||
| d3b2830a95 | |||
| bdb891c015 | |||
| 8ecf370601 | |||
| 7a00f361f3 | |||
| 146fdaf2b8 | |||
| f0c8a78c67 | |||
| b91c27c6f1 | |||
| 7aabbd39d9 | |||
| 12337c9751 | |||
| a267c20531 | |||
| 08fef8929e | |||
| ab4c086baf | |||
| d04d12e0b5 | |||
| b224d1df61 | |||
| ad8483caad | |||
| 7c81188f65 | |||
| 26fa5b6906 | |||
| 2196be62e3 | |||
| cd2553c5c3 | |||
| 544d706e9e | |||
| d021874ea3 | |||
| 80811e74f7 | |||
| 1c0a93b3f8 | |||
| c0228940bd | |||
| 10606363fd | |||
| 71b4a82f0d |
+49
-1
@@ -385,7 +385,7 @@ if test "$enable_win32_backend" = "yes"; then
|
||||
backend_immodules="$backend_immodules,ime"
|
||||
GDK_WINDOWING="$GDK_WINDOWING
|
||||
#define GDK_WINDOWING_WIN32"
|
||||
GDK_EXTRA_LIBS="$GDK_EXTRA_LIBS -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid -lwinmm -ldwmapi"
|
||||
GDK_EXTRA_LIBS="$GDK_EXTRA_LIBS -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid -lwinmm -ldwmapi -lsetupapi -lcfgmgr32"
|
||||
AM_CONDITIONAL(USE_WIN32, true)
|
||||
PANGO_PACKAGES="pangowin32 pangocairo"
|
||||
else
|
||||
@@ -756,6 +756,54 @@ case $host in
|
||||
;;
|
||||
esac
|
||||
|
||||
AS_CASE([$host_os],
|
||||
[mingw*],
|
||||
[
|
||||
AC_CHECK_SIZEOF(
|
||||
[DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY],
|
||||
[],
|
||||
[
|
||||
#define _WIN32_WINNT 0x601
|
||||
#include <windows.h>
|
||||
]
|
||||
)
|
||||
AS_IF(
|
||||
[test x$ac_cv_sizeof_DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY = x4],
|
||||
[AC_MSG_RESULT([DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY is OK])],
|
||||
[test x$ac_cv_sizeof_DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY = x0],
|
||||
[AC_MSG_ERROR([DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY is unavailable])],
|
||||
[AC_MSG_RESULT([DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY is not OK])]
|
||||
)
|
||||
AC_MSG_CHECKING([for SetupDiGetDevicePropertyW])
|
||||
gtk_save_LIBS="$LIBS"
|
||||
LIBS="-lsetupapi $LIBS"
|
||||
AC_TRY_LINK(
|
||||
[
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#include <windows.h>
|
||||
#include <devpropdef.h>
|
||||
#include <setupapi.h>
|
||||
],
|
||||
[return SetupDiGetDevicePropertyW(NULL, NULL, NULL, NULL, NULL, 0, NULL, 0);],
|
||||
[have_SetupDiGetDevicePropertyW=yes],
|
||||
[have_SetupDiGetDevicePropertyW=no]
|
||||
)
|
||||
AS_IF(
|
||||
[test x$have_SetupDiGetDevicePropertyW = xyes],
|
||||
[
|
||||
AC_DEFINE(
|
||||
[HAVE_SETUP_DI_GET_DEVICE_PROPERTY_W],
|
||||
[1],
|
||||
[Define to 1 if SetupDiGetDevicePropertyW() is available]
|
||||
)
|
||||
]
|
||||
)
|
||||
AC_MSG_RESULT([$have_SetupDiGetDevicePropertyW])
|
||||
LIBS="$gtk_save_LIBS"
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
AC_SUBST(MATH_LIB)
|
||||
#
|
||||
# see bug 162979
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<xi:include href="xml/gdkdisplay.xml" />
|
||||
<xi:include href="xml/gdkscreen.xml" />
|
||||
<xi:include href="xml/gdkseat.xml" />
|
||||
<xi:include href="xml/gdkmonitor.xml" />
|
||||
<xi:include href="xml/gdkdevicemanager.xml" />
|
||||
<xi:include href="xml/gdkdevice.xml" />
|
||||
<xi:include href="xml/regions.xml" />
|
||||
|
||||
@@ -158,6 +158,11 @@ gdk_display_get_app_launch_context
|
||||
gdk_display_notify_startup_complete
|
||||
gdk_display_get_default_seat
|
||||
gdk_display_list_seats
|
||||
gdk_display_get_n_monitors
|
||||
gdk_display_get_monitor
|
||||
gdk_display_get_primary_monitor
|
||||
gdk_display_get_monitor_at_point
|
||||
gdk_display_get_monitor_at_window
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_DISPLAY
|
||||
@@ -1366,3 +1371,27 @@ GDK_GL_ERROR
|
||||
GDK_TYPE_GL_ERROR
|
||||
GDK_TYPE_GL_PROFILE
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gdkmonitor</FILE>
|
||||
GdkMonitor
|
||||
gdk_monitor_get_display
|
||||
gdk_monitor_get_geometry
|
||||
gdk_monitor_get_workarea
|
||||
gdk_monitor_get_width_mm
|
||||
gdk_monitor_get_height_mm
|
||||
gdk_monitor_get_manufacturer
|
||||
gdk_monitor_get_model
|
||||
gdk_monitor_get_scale_factor
|
||||
gdk_monitor_get_refresh_rate
|
||||
GdkSubpixelLayout
|
||||
gdk_monitor_get_subpixel_layout
|
||||
gdk_monitor_is_primary
|
||||
|
||||
<SUBSECTION Standard>
|
||||
gdk_monitor_get_type
|
||||
GdkMonitorClass
|
||||
GDK_TYPE_MONITOR
|
||||
GDK_MONITOR
|
||||
GDK_IS_MONITOR
|
||||
</SECTION>
|
||||
|
||||
@@ -10,6 +10,7 @@ gdk_drag_context_get_type
|
||||
gdk_frame_clock_get_type
|
||||
gdk_gl_context_get_type
|
||||
gdk_keymap_get_type
|
||||
gdk_monitor_get_type
|
||||
gdk_screen_get_type
|
||||
gdk_seat_get_type
|
||||
gdk_visual_get_type
|
||||
|
||||
@@ -77,6 +77,7 @@ gdk_public_h_sources = \
|
||||
gdkkeysyms.h \
|
||||
gdkkeysyms-compat.h \
|
||||
gdkmain.h \
|
||||
gdkmonitor.h \
|
||||
gdkpango.h \
|
||||
gdkframeclock.h \
|
||||
gdkpixbuf.h \
|
||||
@@ -144,6 +145,7 @@ gdk_c_sources = \
|
||||
gdkglobals.c \
|
||||
gdkkeys.c \
|
||||
gdkkeyuni.c \
|
||||
gdkmonitor.c \
|
||||
gdkoffscreenwindow.c \
|
||||
gdkframeclock.c \
|
||||
gdkframeclockidle.c \
|
||||
|
||||
@@ -28,6 +28,7 @@ libgdkbroadwayinclude_HEADERS = \
|
||||
gdkbroadwaydisplay.h \
|
||||
gdkbroadwaywindow.h \
|
||||
gdkbroadwaycursor.h \
|
||||
gdkbroadwaymonitor.h \
|
||||
gdkbroadwayvisual.h
|
||||
|
||||
EXTRA_DIST += toarray.pl
|
||||
@@ -64,6 +65,8 @@ libgdk_broadway_la_SOURCES = \
|
||||
gdkeventsource.h \
|
||||
gdkglobals-broadway.c \
|
||||
gdkkeys-broadway.c \
|
||||
gdkmonitor-broadway.c \
|
||||
gdkmonitor-broadway.h \
|
||||
gdkproperty-broadway.c \
|
||||
gdkscreen-broadway.c \
|
||||
gdkscreen-broadway.h \
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <gdk/broadway/gdkbroadwaydisplay.h>
|
||||
#include <gdk/broadway/gdkbroadwaywindow.h>
|
||||
#include <gdk/broadway/gdkbroadwaycursor.h>
|
||||
#include <gdk/broadway/gdkbroadwaymonitor.h>
|
||||
#include <gdk/broadway/gdkbroadwayvisual.h>
|
||||
|
||||
#undef __GDKBROADWAY_H_INSIDE__
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* gdkbroadwaymonitor.h
|
||||
*
|
||||
* Copyright 2016 Red Hat, Inc.
|
||||
*
|
||||
* Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_BROADWAY_MONITOR_H__
|
||||
#define __GDK_BROADWAY_MONITOR_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkmonitor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_BROADWAY_MONITOR (gdk_broadway_monitor_get_type ())
|
||||
#define GDK_BROADWAY_MONITOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_MONITOR, GdkBroadwayMonitor))
|
||||
#define GDK_IS_BROADWAY_MONITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_MONITOR))
|
||||
|
||||
typedef struct _GdkBroadwayMonitor GdkBroadwayMonitor;
|
||||
typedef struct _GdkBroadwayMonitorClass GdkBroadwayMonitorClass;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gdk_broadway_monitor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_BROADWAY_MONITOR_H__ */
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "gdkeventsource.h"
|
||||
#include "gdkscreen.h"
|
||||
#include "gdkscreen-broadway.h"
|
||||
#include "gdkmonitor-broadway.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevicemanager-broadway.h"
|
||||
@@ -55,6 +56,12 @@ static void
|
||||
gdk_broadway_display_init (GdkBroadwayDisplay *display)
|
||||
{
|
||||
display->id_ht = g_hash_table_new (NULL, NULL);
|
||||
|
||||
display->monitor = g_object_new (GDK_TYPE_BROADWAY_MONITOR,
|
||||
"display", display,
|
||||
NULL);
|
||||
gdk_monitor_set_manufacturer (display->monitor, "browser");
|
||||
gdk_monitor_set_model (display->monitor, "0");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -200,6 +207,8 @@ gdk_broadway_display_finalize (GObject *object)
|
||||
g_object_unref (broadway_display->screens[0]);
|
||||
g_free (broadway_display->screens);
|
||||
|
||||
g_object_unref (broadway_display->monitor);
|
||||
|
||||
G_OBJECT_CLASS (gdk_broadway_display_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -281,6 +290,32 @@ gdk_broadway_display_hide_keyboard (GdkBroadwayDisplay *display)
|
||||
_gdk_broadway_server_set_show_keyboard (display->server, FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_broadway_display_get_n_monitors (GdkDisplay *display)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static GdkMonitor *
|
||||
gdk_broadway_display_get_monitor (GdkDisplay *display,
|
||||
int monitor_num)
|
||||
{
|
||||
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (display);
|
||||
|
||||
if (monitor_num == 0)
|
||||
return broadway_display->monitor;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkMonitor *
|
||||
gdk_broadway_display_get_primary_monitor (GdkDisplay *display)
|
||||
{
|
||||
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (display);
|
||||
|
||||
return broadway_display->monitor;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
|
||||
{
|
||||
@@ -328,5 +363,9 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
|
||||
display_class->convert_selection = _gdk_broadway_display_convert_selection;
|
||||
display_class->text_property_to_utf8_list = _gdk_broadway_display_text_property_to_utf8_list;
|
||||
display_class->utf8_to_string_target = _gdk_broadway_display_utf8_to_string_target;
|
||||
|
||||
display_class->get_n_monitors = gdk_broadway_display_get_n_monitors;
|
||||
display_class->get_monitor = gdk_broadway_display_get_monitor;
|
||||
display_class->get_primary_monitor = gdk_broadway_display_get_primary_monitor;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkmain.h"
|
||||
#include "gdkbroadway-server.h"
|
||||
#include "gdkmonitorprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -56,6 +57,8 @@ struct _GdkBroadwayDisplay
|
||||
GdkBroadwayServer *server;
|
||||
|
||||
gpointer move_resize_data;
|
||||
|
||||
GdkMonitor *monitor;
|
||||
};
|
||||
|
||||
struct _GdkBroadwayDisplayClass
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gdkmonitor-broadway.h"
|
||||
#include "gdkscreen-broadway.h"
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkBroadwayMonitor, gdk_broadway_monitor, GDK_TYPE_MONITOR)
|
||||
|
||||
static void
|
||||
gdk_broadway_monitor_init (GdkBroadwayMonitor *monitor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_monitor_class_init (GdkBroadwayMonitorClass *class)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_BROADWAY_MONITOR_PRIVATE_H__
|
||||
#define __GDK_BROADWAY_MONITOR_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
|
||||
#include "gdkbroadwaymonitor.h"
|
||||
|
||||
|
||||
struct _GdkBroadwayMonitor
|
||||
{
|
||||
GdkMonitor parent;
|
||||
};
|
||||
|
||||
struct _GdkBroadwayMonitorClass {
|
||||
GdkMonitorClass parent_class;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -91,6 +91,7 @@ _gdk_broadway_screen_size_changed (GdkScreen *screen,
|
||||
BroadwayInputScreenResizeNotify *msg)
|
||||
{
|
||||
GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (screen);
|
||||
GdkMonitor *monitor;
|
||||
gint width, height;
|
||||
GList *toplevels, *l;
|
||||
|
||||
@@ -104,6 +105,11 @@ _gdk_broadway_screen_size_changed (GdkScreen *screen,
|
||||
height == gdk_screen_get_height (screen))
|
||||
return;
|
||||
|
||||
monitor = GDK_BROADWAY_DISPLAY (broadway_screen->display)->monitor;
|
||||
|
||||
gdk_monitor_set_size (monitor, msg->width, msg->height);
|
||||
gdk_monitor_set_physical_size (monitor, msg->width * 25.4 / 96, msg->height * 25.4 / 96);
|
||||
|
||||
g_signal_emit_by_name (screen, "size-changed");
|
||||
toplevels = gdk_screen_get_toplevel_windows (screen);
|
||||
for (l = toplevels; l != NULL; l = l->next)
|
||||
@@ -146,55 +152,6 @@ gdk_broadway_screen_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (gdk_broadway_screen_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_broadway_screen_get_n_monitors (GdkScreen *screen)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_broadway_screen_get_primary_monitor (GdkScreen *screen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_broadway_screen_get_monitor_width_mm (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
return gdk_screen_get_width_mm (screen);
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_broadway_screen_get_monitor_height_mm (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
return gdk_screen_get_height_mm (screen);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gdk_broadway_screen_get_monitor_plug_name (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
return g_strdup ("browser");
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_screen_get_monitor_geometry (GdkScreen *screen,
|
||||
gint monitor_num,
|
||||
GdkRectangle *dest)
|
||||
{
|
||||
GdkBroadwayScreen *broadway_screen = GDK_BROADWAY_SCREEN (screen);
|
||||
|
||||
if (dest)
|
||||
{
|
||||
dest->x = 0;
|
||||
dest->y = 0;
|
||||
dest->width = broadway_screen->width;
|
||||
dest->height = broadway_screen->height;
|
||||
}
|
||||
}
|
||||
|
||||
static GdkVisual *
|
||||
gdk_broadway_screen_get_rgba_visual (GdkScreen *screen)
|
||||
{
|
||||
@@ -290,13 +247,6 @@ gdk_broadway_screen_class_init (GdkBroadwayScreenClass *klass)
|
||||
screen_class->get_height_mm = gdk_broadway_screen_get_height_mm;
|
||||
screen_class->get_number = gdk_broadway_screen_get_number;
|
||||
screen_class->get_root_window = gdk_broadway_screen_get_root_window;
|
||||
screen_class->get_n_monitors = gdk_broadway_screen_get_n_monitors;
|
||||
screen_class->get_primary_monitor = gdk_broadway_screen_get_primary_monitor;
|
||||
screen_class->get_monitor_width_mm = gdk_broadway_screen_get_monitor_width_mm;
|
||||
screen_class->get_monitor_height_mm = gdk_broadway_screen_get_monitor_height_mm;
|
||||
screen_class->get_monitor_plug_name = gdk_broadway_screen_get_monitor_plug_name;
|
||||
screen_class->get_monitor_geometry = gdk_broadway_screen_get_monitor_geometry;
|
||||
screen_class->get_monitor_workarea = gdk_broadway_screen_get_monitor_geometry;
|
||||
screen_class->is_composited = gdk_broadway_screen_is_composited;
|
||||
screen_class->make_display_name = gdk_broadway_screen_make_display_name;
|
||||
screen_class->get_active_window = gdk_broadway_screen_get_active_window;
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <gdk/gdkkeys.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gdk/gdkmain.h>
|
||||
#include <gdk/gdkmonitor.h>
|
||||
#include <gdk/gdkpango.h>
|
||||
#include <gdk/gdkpixbuf.h>
|
||||
#include <gdk/gdkproperty.h>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkmarshalers.h"
|
||||
#include "gdkscreen.h"
|
||||
#include "gdkmonitorprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <glib.h>
|
||||
@@ -71,6 +72,8 @@ enum {
|
||||
CLOSED,
|
||||
SEAT_ADDED,
|
||||
SEAT_REMOVED,
|
||||
MONITOR_ADDED,
|
||||
MONITOR_REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -227,6 +230,42 @@ gdk_display_class_init (GdkDisplayClass *class)
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_SEAT);
|
||||
|
||||
/**
|
||||
* GdkDisplay::monitor-added:
|
||||
* @display: the objedct on which the signal is emitted
|
||||
* @monitor: the monitor that was just added
|
||||
*
|
||||
* The ::monitor-added signal is emitted whenever a monitor is
|
||||
* added.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
signals[MONITOR_ADDED] =
|
||||
g_signal_new (g_intern_static_string ("monitor-added"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_MONITOR);
|
||||
|
||||
/**
|
||||
* GdkDisplay::monitor-removed:
|
||||
* @display: the object on which the signal is emitted
|
||||
* @monitor: the monitor that was just removed
|
||||
*
|
||||
* The ::monitor-removed signal is emitted whenever a monitor is
|
||||
* removed.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
signals[MONITOR_REMOVED] =
|
||||
g_signal_new (g_intern_static_string ("monitor-removed"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_MONITOR);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2464,3 +2503,229 @@ gdk_display_list_seats (GdkDisplay *display)
|
||||
|
||||
return g_list_copy (display->seats);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_n_monitors:
|
||||
* @display: a #GdkDisplay
|
||||
*
|
||||
* Gets the number of monitors that belong to @display.
|
||||
*
|
||||
* The returned number is valid until the next emission of the
|
||||
* #GdkDisplay::monitor-added or #GdkDisplay::monitor-removed signal.
|
||||
*
|
||||
* Returns: the number of monitors
|
||||
* Since: 3.22
|
||||
*/
|
||||
int
|
||||
gdk_display_get_n_monitors (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
|
||||
|
||||
if (GDK_DISPLAY_GET_CLASS (display)->get_n_monitors == NULL)
|
||||
return 1;
|
||||
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_n_monitors (display);
|
||||
}
|
||||
|
||||
static GdkMonitor *
|
||||
get_fallback_monitor (GdkDisplay *display)
|
||||
{
|
||||
static GdkMonitor *monitor = NULL;
|
||||
GdkScreen *screen;
|
||||
|
||||
if (monitor == NULL)
|
||||
{
|
||||
g_warning ("%s does not implement the monitor vfuncs", G_OBJECT_TYPE_NAME (display));
|
||||
monitor = gdk_monitor_new (display);
|
||||
gdk_monitor_set_manufacturer (monitor, "fallback");
|
||||
gdk_monitor_set_position (monitor, 0, 0);
|
||||
gdk_monitor_set_scale_factor (monitor, 1);
|
||||
}
|
||||
|
||||
screen = gdk_display_get_default_screen (display);
|
||||
gdk_monitor_set_size (monitor,
|
||||
gdk_screen_get_width (screen),
|
||||
gdk_screen_get_height (screen));
|
||||
gdk_monitor_set_physical_size (monitor,
|
||||
gdk_screen_get_width_mm (screen),
|
||||
gdk_screen_get_height_mm (screen));
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_monitor:
|
||||
* @display: a #GdkDisplay
|
||||
* @monitor_num: number of the monitor
|
||||
*
|
||||
* Gets a monitor associated with this display.
|
||||
*
|
||||
* Returns: (transfer none): the #GdkMonitor, or %NULL if
|
||||
* @monitor_num is not a valid monitor number
|
||||
* Since: 3.22
|
||||
*/
|
||||
GdkMonitor *
|
||||
gdk_display_get_monitor (GdkDisplay *display,
|
||||
gint monitor_num)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
if (GDK_DISPLAY_GET_CLASS (display)->get_monitor == NULL)
|
||||
return get_fallback_monitor (display);
|
||||
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_monitor (display, monitor_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_primary_monitor:
|
||||
* @display: a #GdkDisplay
|
||||
*
|
||||
* Gets the primary monitor for the display.
|
||||
*
|
||||
* The primary monitor is considered the monitor where the “main desktop”
|
||||
* lives. While normal application windows typically allow the window
|
||||
* manager to place the windows, specialized desktop applications
|
||||
* such as panels should place themselves on the primary monitor.
|
||||
*
|
||||
* Returns: (transfer none): the primary monitor, or %NULL if no primary
|
||||
* monitor is configured by the user
|
||||
* Since: 3.22
|
||||
*/
|
||||
GdkMonitor *
|
||||
gdk_display_get_primary_monitor (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
if (GDK_DISPLAY_GET_CLASS (display)->get_primary_monitor)
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_primary_monitor (display);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_monitor_at_point:
|
||||
* @display: a #GdkDisplay
|
||||
* @x: the x coordinate of the point
|
||||
* @y: the y coordinate of the point
|
||||
*
|
||||
* Gets the monitor in which the point (@x, @y) is located,
|
||||
* or a nearby monitor if the point is not in any monitor.
|
||||
*
|
||||
* Returns: (transfer none): the monitor containing the point
|
||||
* Since: 3.22
|
||||
*/
|
||||
GdkMonitor *
|
||||
gdk_display_get_monitor_at_point (GdkDisplay *display,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GdkMonitor *nearest;
|
||||
int nearest_dist = G_MAXINT;
|
||||
int n_monitors, i;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
n_monitors = gdk_display_get_n_monitors (display);
|
||||
for (i = 0; i < n_monitors; i++)
|
||||
{
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle geometry;
|
||||
int dist_x, dist_y, dist;
|
||||
|
||||
monitor = gdk_display_get_monitor (display, i);
|
||||
gdk_monitor_get_geometry (monitor, &geometry);
|
||||
|
||||
if (x < geometry.x)
|
||||
dist_x = geometry.x - x;
|
||||
else if (geometry.x + geometry.width <= x)
|
||||
dist_x = x - (geometry.x + geometry.width) + 1;
|
||||
else
|
||||
dist_x = 0;
|
||||
|
||||
if (y < geometry.y)
|
||||
dist_y = geometry.y - y;
|
||||
else if (geometry.y + geometry.height <= y)
|
||||
dist_y = y - (geometry.y + geometry.height) + 1;
|
||||
else
|
||||
dist_y = 0;
|
||||
|
||||
dist = dist_x + dist_y;
|
||||
if (dist < nearest_dist)
|
||||
{
|
||||
nearest_dist = dist;
|
||||
nearest = monitor;
|
||||
}
|
||||
|
||||
if (nearest_dist == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return nearest;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_monitor_at_window:
|
||||
* @display: a #GdkDisplay
|
||||
* @window: a #GdkWindow
|
||||
*
|
||||
* Gets the monitor in which the largest area of @window
|
||||
* resides, or a monitor close to @window if it is outside
|
||||
* of all monitors.
|
||||
*
|
||||
* Returns: (transfer none): the monitor with the largest overlap with @window
|
||||
* Since: 3.22
|
||||
*/
|
||||
GdkMonitor *
|
||||
gdk_display_get_monitor_at_window (GdkDisplay *display,
|
||||
GdkWindow *window)
|
||||
{
|
||||
GdkRectangle win;
|
||||
int n_monitors, i;
|
||||
int area = 0;
|
||||
GdkMonitor *best = NULL;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
gdk_window_get_geometry (window, &win.x, &win.y, &win.width, &win.height);
|
||||
gdk_window_get_origin (window, &win.x, &win.y);
|
||||
|
||||
n_monitors = gdk_display_get_n_monitors (display);
|
||||
for (i = 0; i < n_monitors; i++)
|
||||
{
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle mon, intersect;
|
||||
int overlap;
|
||||
|
||||
monitor = gdk_display_get_monitor (display, i);
|
||||
gdk_monitor_get_geometry (monitor, &mon);
|
||||
gdk_rectangle_intersect (&win, &mon, &intersect);
|
||||
overlap = intersect.width *intersect.height;
|
||||
if (overlap > area)
|
||||
{
|
||||
area = overlap;
|
||||
best = monitor;
|
||||
}
|
||||
}
|
||||
|
||||
if (best)
|
||||
return best;
|
||||
|
||||
return gdk_display_get_monitor_at_point (display,
|
||||
win.x + win.width / 2,
|
||||
win.y + win.height / 2);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_monitor_added (GdkDisplay *display,
|
||||
GdkMonitor *monitor)
|
||||
{
|
||||
g_signal_emit (display, signals[MONITOR_ADDED], 0, monitor);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_monitor_removed (GdkDisplay *display,
|
||||
GdkMonitor *monitor)
|
||||
{
|
||||
g_signal_emit (display, signals[MONITOR_REMOVED], 0, monitor);
|
||||
gdk_monitor_invalidate (monitor);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <gdk/gdkevents.h>
|
||||
#include <gdk/gdkdevicemanager.h>
|
||||
#include <gdk/gdkseat.h>
|
||||
#include <gdk/gdkmonitor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -178,6 +179,22 @@ GdkSeat * gdk_display_get_default_seat (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_3_20
|
||||
GList * gdk_display_list_seats (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
int gdk_display_get_n_monitors (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkMonitor * gdk_display_get_monitor (GdkDisplay *display,
|
||||
int monitor_num);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkMonitor * gdk_display_get_primary_monitor (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkMonitor * gdk_display_get_monitor_at_point (GdkDisplay *display,
|
||||
int x,
|
||||
int y);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkMonitor * gdk_display_get_monitor_at_window (GdkDisplay *dsplay,
|
||||
GdkWindow *window);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DISPLAY_H__ */
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkwindow.h"
|
||||
#include "gdkcursor.h"
|
||||
#include "gdkmonitor.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -241,6 +242,11 @@ struct _GdkDisplayClass
|
||||
|
||||
GdkSeat * (*get_default_seat) (GdkDisplay *display);
|
||||
|
||||
int (*get_n_monitors) (GdkDisplay *display);
|
||||
GdkMonitor * (*get_monitor) (GdkDisplay *display,
|
||||
int index);
|
||||
GdkMonitor * (*get_primary_monitor) (GdkDisplay *display);
|
||||
|
||||
/* Signals */
|
||||
void (*opened) (GdkDisplay *display);
|
||||
void (*closed) (GdkDisplay *display,
|
||||
@@ -328,6 +334,10 @@ void gdk_display_add_seat (GdkDisplay *display
|
||||
GdkSeat *seat);
|
||||
void gdk_display_remove_seat (GdkDisplay *display,
|
||||
GdkSeat *seat);
|
||||
void gdk_display_monitor_added (GdkDisplay *display,
|
||||
GdkMonitor *monitor);
|
||||
void gdk_display_monitor_removed (GdkDisplay *display,
|
||||
GdkMonitor *monitor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -0,0 +1,611 @@
|
||||
/*
|
||||
* gdkmonitor.c
|
||||
*
|
||||
* Copyright 2016 Red Hat, Inc.
|
||||
*
|
||||
* Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkenumtypes.h"
|
||||
|
||||
/**
|
||||
* SECTION:gdkmonitor
|
||||
* @Title: GdkMonitor
|
||||
* @Short_description: Object representing an output
|
||||
*
|
||||
* GdkMonitor objects represent the individual outputs that are
|
||||
* associated with a #GdkDisplay. GdkDisplay has APIs to enumerate
|
||||
* monitors with gdk_display_get_monitors() and to find particular
|
||||
* monitors with gdk_display_get_primary_monitor() or
|
||||
* gdk_display_get_monitor_at_window().
|
||||
*
|
||||
* GdkMonitor was introduced in GTK+ 3.22 and supersedes earlier
|
||||
* APIs in GdkScreen to obtain monitor-related information.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* - monitor type (laptop, projector, ...)
|
||||
* - consider vfuncs instead of baseclass storage
|
||||
* - provide a persistent id (if the backend allows)
|
||||
* - convert win32
|
||||
* - convert quartz
|
||||
* - convert mir
|
||||
*/
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DISPLAY,
|
||||
PROP_MANUFACTURER,
|
||||
PROP_MODEL,
|
||||
PROP_SCALE_FACTOR,
|
||||
PROP_GEOMETRY,
|
||||
PROP_WORKAREA,
|
||||
PROP_WIDTH_MM,
|
||||
PROP_HEIGHT_MM,
|
||||
PROP_REFRESH_RATE,
|
||||
PROP_SUBPIXEL_LAYOUT,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *props[LAST_PROP] = { NULL, };
|
||||
|
||||
enum {
|
||||
INVALIDATE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (GdkMonitor, gdk_monitor, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_monitor_init (GdkMonitor *monitor)
|
||||
{
|
||||
monitor->scale_factor = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_monitor_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkMonitor *monitor = GDK_MONITOR (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, monitor->display);
|
||||
break;
|
||||
|
||||
case PROP_MANUFACTURER:
|
||||
g_value_set_string (value, monitor->manufacturer);
|
||||
break;
|
||||
|
||||
case PROP_MODEL:
|
||||
g_value_set_string (value, monitor->model);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
g_value_set_int (value, monitor->scale_factor);
|
||||
break;
|
||||
|
||||
case PROP_GEOMETRY:
|
||||
g_value_set_boxed (value, &monitor->geometry);
|
||||
break;
|
||||
|
||||
case PROP_WORKAREA:
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
g_value_set_boxed (value, &workarea);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_WIDTH_MM:
|
||||
g_value_set_int (value, monitor->width_mm);
|
||||
break;
|
||||
|
||||
case PROP_HEIGHT_MM:
|
||||
g_value_set_int (value, monitor->height_mm);
|
||||
break;
|
||||
|
||||
case PROP_REFRESH_RATE:
|
||||
g_value_set_boolean (value, monitor->refresh_rate);
|
||||
break;
|
||||
|
||||
case PROP_SUBPIXEL_LAYOUT:
|
||||
g_value_set_enum (value, monitor->subpixel_layout);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_monitor_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkMonitor *monitor = GDK_MONITOR (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
monitor->display = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_monitor_finalize (GObject *object)
|
||||
{
|
||||
GdkMonitor *monitor = GDK_MONITOR (object);
|
||||
|
||||
g_free (monitor->manufacturer);
|
||||
g_free (monitor->model);
|
||||
|
||||
G_OBJECT_CLASS (gdk_monitor_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_monitor_class_init (GdkMonitorClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = gdk_monitor_finalize;
|
||||
object_class->get_property = gdk_monitor_get_property;
|
||||
object_class->set_property = gdk_monitor_set_property;
|
||||
|
||||
props[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display",
|
||||
"Display",
|
||||
"The display of the monitor",
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
props[PROP_MANUFACTURER] =
|
||||
g_param_spec_string ("manufacturer",
|
||||
"Manufacturer",
|
||||
"The manufacturer name",
|
||||
NULL,
|
||||
G_PARAM_READABLE);
|
||||
props[PROP_MODEL] =
|
||||
g_param_spec_string ("model",
|
||||
"Model",
|
||||
"The model name",
|
||||
NULL,
|
||||
G_PARAM_READABLE);
|
||||
props[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor",
|
||||
"Scale factor",
|
||||
"The scale factor",
|
||||
0, G_MAXINT,
|
||||
1,
|
||||
G_PARAM_READABLE);
|
||||
props[PROP_GEOMETRY] =
|
||||
g_param_spec_boxed ("geometry",
|
||||
"Geometry",
|
||||
"The geometry of the monitor",
|
||||
GDK_TYPE_RECTANGLE,
|
||||
G_PARAM_READABLE);
|
||||
props[PROP_WORKAREA] =
|
||||
g_param_spec_boxed ("workarea",
|
||||
"Workarea",
|
||||
"The workarea of the monitor",
|
||||
GDK_TYPE_RECTANGLE,
|
||||
G_PARAM_READABLE);
|
||||
props[PROP_WIDTH_MM] =
|
||||
g_param_spec_int ("width-mm",
|
||||
"Physical width",
|
||||
"The width of the monitor, in millimeters",
|
||||
0, G_MAXINT,
|
||||
0,
|
||||
G_PARAM_READABLE);
|
||||
props[PROP_HEIGHT_MM] =
|
||||
g_param_spec_int ("height-mm",
|
||||
"Physical height",
|
||||
"The height of the monitor, in millimeters",
|
||||
0, G_MAXINT,
|
||||
0,
|
||||
G_PARAM_READABLE);
|
||||
props[PROP_REFRESH_RATE] =
|
||||
g_param_spec_int ("refresh-rate",
|
||||
"Refresh rate",
|
||||
"The refresh rate, in millihertz",
|
||||
0, G_MAXINT,
|
||||
0,
|
||||
G_PARAM_READABLE);
|
||||
props[PROP_SUBPIXEL_LAYOUT] =
|
||||
g_param_spec_enum ("subpixel-layout",
|
||||
"Subpixel layout",
|
||||
"The subpixel layout",
|
||||
GDK_TYPE_SUBPIXEL_LAYOUT,
|
||||
GDK_SUBPIXEL_LAYOUT_UNKNOWN,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, props);
|
||||
|
||||
signals[INVALIDATE] = g_signal_new ("invalidate",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_display:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets the display that this monitor belongs to.
|
||||
*
|
||||
* Returns: (transfer none): the display
|
||||
* Since: 3.22
|
||||
*/
|
||||
GdkDisplay *
|
||||
gdk_monitor_get_display (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), NULL);
|
||||
|
||||
return monitor->display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_geometry:
|
||||
* @monitor: a #GdkMonitor
|
||||
* @geometry: (out): a #GdkRectangle to be filled wiht the monitor geometry
|
||||
*
|
||||
* Retrieves the size and position of an individual monitor within the
|
||||
* display coordinate space. The returned geometry is in ”application pixels”,
|
||||
* not in ”device pixels” (see gdk_monitor_get_scale_factor()).
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
void
|
||||
gdk_monitor_get_geometry (GdkMonitor *monitor,
|
||||
GdkRectangle *geometry)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MONITOR (monitor));
|
||||
g_return_if_fail (geometry != NULL);
|
||||
|
||||
*geometry = monitor->geometry;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_workarea:
|
||||
* @monitor: a #GdkMonitor
|
||||
* @workarea: (out): a #GdkRectangle to be filled with
|
||||
* the monitor workarea
|
||||
*
|
||||
* Retrieves the size and position of the “work area” on a monitor
|
||||
* within the display coordinate space. The returned geometry is in
|
||||
* ”application pixels”, not in ”device pixels” (see
|
||||
* gdk_monitor_get_scale_factor()).
|
||||
*
|
||||
* The work area should be considered when positioning menus and
|
||||
* similar popups, to avoid placing them below panels, docks or other
|
||||
* desktop components.
|
||||
*
|
||||
* Note that not all backends may have a concept of workarea. This
|
||||
* function will return the monitor geometry if a workarea is not
|
||||
* available, or does not apply.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
void
|
||||
gdk_monitor_get_workarea (GdkMonitor *monitor,
|
||||
GdkRectangle *workarea)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MONITOR (monitor));
|
||||
g_return_if_fail (workarea != NULL);
|
||||
|
||||
if (GDK_MONITOR_GET_CLASS (monitor)->get_workarea)
|
||||
GDK_MONITOR_GET_CLASS (monitor)->get_workarea (monitor, workarea);
|
||||
else
|
||||
*workarea = monitor->geometry;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_width_mm:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets the width in millimeters of the monitor.
|
||||
*
|
||||
* Returns: the physical width of the monitor
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
int
|
||||
gdk_monitor_get_width_mm (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), 0);
|
||||
|
||||
return monitor->width_mm;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_height_mm:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets the height in millimeters of the monitor.
|
||||
*
|
||||
* Returns: the physical height of the monitor
|
||||
* Since: 3.22
|
||||
*/
|
||||
int
|
||||
gdk_monitor_get_height_mm (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), 0);
|
||||
|
||||
return monitor->height_mm;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_manufacturer:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets the name of the monitor's manufacturer, if available.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the name of the manufacturer, or %NULL
|
||||
*/
|
||||
const char *
|
||||
gdk_monitor_get_manufacturer (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), NULL);
|
||||
|
||||
return monitor->manufacturer;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_model:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets the a string identifying the monitor model, if available.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the monitor model, or %NULL
|
||||
*/
|
||||
const char *
|
||||
gdk_monitor_get_model (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), NULL);
|
||||
|
||||
return monitor->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_scale_factor:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets the internal scale factor that maps from monitor coordinates
|
||||
* to the actual device pixels. On traditional systems this is 1, but
|
||||
* on very high density outputs this can be a higher value (often 2).
|
||||
*
|
||||
* This can be used if you want to create pixel based data for a
|
||||
* particular monitor, but most of the time you’re drawing to a window
|
||||
* where it is better to use gdk_window_get_scale_factor() instead.
|
||||
*
|
||||
* Returns: the scale factor
|
||||
* Since: 3.22
|
||||
*/
|
||||
int
|
||||
gdk_monitor_get_scale_factor (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), 0);
|
||||
|
||||
return monitor->scale_factor;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_refresh_rate:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets the refresh rate of the monitor, if available.
|
||||
*
|
||||
* The value is in milli-Hertz, so a refresh rate of 60Hz
|
||||
* is returned as 60000.
|
||||
*
|
||||
* Returns: the refresh rate in milli-Hertz, or 0
|
||||
* Since: 3.22
|
||||
*/
|
||||
int
|
||||
gdk_monitor_get_refresh_rate (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), 0);
|
||||
|
||||
return monitor->refresh_rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_subpixel_layout:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets information about the layout of red, green and blue
|
||||
* primaries for each pixel in this monitor, if available.
|
||||
*
|
||||
* Returns: the subpixel layout
|
||||
* Since: 3.22
|
||||
*/
|
||||
GdkSubpixelLayout
|
||||
gdk_monitor_get_subpixel_layout (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), GDK_SUBPIXEL_LAYOUT_UNKNOWN);
|
||||
|
||||
return monitor->subpixel_layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_is_primary:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets whether this monitor should be considered primary
|
||||
* (see gdk_display_get_primary_monitor()).
|
||||
*
|
||||
* Returns: %TRUE if @monitor is primary
|
||||
* Since: 3.22
|
||||
*/
|
||||
gboolean
|
||||
gdk_monitor_is_primary (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), FALSE);
|
||||
|
||||
return monitor == gdk_display_get_primary_monitor (monitor->display);
|
||||
}
|
||||
|
||||
GdkMonitor *
|
||||
gdk_monitor_new (GdkDisplay *display)
|
||||
{
|
||||
return GDK_MONITOR (g_object_new (GDK_TYPE_MONITOR,
|
||||
"display", display,
|
||||
NULL));
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_manufacturer (GdkMonitor *monitor,
|
||||
const char *manufacturer)
|
||||
{
|
||||
g_free (monitor->manufacturer);
|
||||
monitor->manufacturer = g_strdup (manufacturer);
|
||||
|
||||
g_object_notify (G_OBJECT (monitor), "manufacturer");
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_model (GdkMonitor *monitor,
|
||||
const char *model)
|
||||
{
|
||||
g_free (monitor->model);
|
||||
monitor->model = g_strdup (model);
|
||||
|
||||
g_object_notify (G_OBJECT (monitor), "model");
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_position (GdkMonitor *monitor,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
g_object_freeze_notify (G_OBJECT (monitor));
|
||||
|
||||
if (monitor->geometry.x != x)
|
||||
{
|
||||
monitor->geometry.x = x;
|
||||
g_object_notify (G_OBJECT (monitor), "geometry");
|
||||
}
|
||||
|
||||
if (monitor->geometry.y != y)
|
||||
{
|
||||
monitor->geometry.y = y;
|
||||
g_object_notify (G_OBJECT (monitor), "geometry");
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (monitor));
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_size (GdkMonitor *monitor,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_object_freeze_notify (G_OBJECT (monitor));
|
||||
|
||||
if (monitor->geometry.width != width)
|
||||
{
|
||||
monitor->geometry.width = width;
|
||||
g_object_notify (G_OBJECT (monitor), "geometry");
|
||||
}
|
||||
|
||||
if (monitor->geometry.height != height)
|
||||
{
|
||||
monitor->geometry.height = height;
|
||||
g_object_notify (G_OBJECT (monitor), "geometry");
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (monitor));
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_physical_size (GdkMonitor *monitor,
|
||||
int width_mm,
|
||||
int height_mm)
|
||||
{
|
||||
g_object_freeze_notify (G_OBJECT (monitor));
|
||||
|
||||
if (monitor->width_mm != width_mm)
|
||||
{
|
||||
monitor->width_mm = width_mm;
|
||||
g_object_notify (G_OBJECT (monitor), "width-mm");
|
||||
}
|
||||
|
||||
if (monitor->height_mm != height_mm)
|
||||
{
|
||||
monitor->height_mm = height_mm;
|
||||
g_object_notify (G_OBJECT (monitor), "height-mm");
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (monitor));
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_scale_factor (GdkMonitor *monitor,
|
||||
int scale_factor)
|
||||
{
|
||||
if (monitor->scale_factor == scale_factor)
|
||||
return;
|
||||
|
||||
monitor->scale_factor = scale_factor;
|
||||
|
||||
g_object_notify (G_OBJECT (monitor), "scale-factor");
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_refresh_rate (GdkMonitor *monitor,
|
||||
int refresh_rate)
|
||||
{
|
||||
if (monitor->refresh_rate == refresh_rate)
|
||||
return;
|
||||
|
||||
monitor->refresh_rate = refresh_rate;
|
||||
|
||||
g_object_notify (G_OBJECT (monitor), "refresh-rate");
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_subpixel_layout (GdkMonitor *monitor,
|
||||
GdkSubpixelLayout subpixel_layout)
|
||||
{
|
||||
if (monitor->subpixel_layout == subpixel_layout)
|
||||
return;
|
||||
|
||||
monitor->subpixel_layout = subpixel_layout;
|
||||
|
||||
g_object_notify (G_OBJECT (monitor), "subpixel-layout");
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_invalidate (GdkMonitor *monitor)
|
||||
{
|
||||
g_signal_emit (monitor, signals[INVALIDATE], 0);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* gdkmonitor.h
|
||||
*
|
||||
* Copyright 2016 Red Hat, Inc.
|
||||
*
|
||||
* Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MONITOR_H__
|
||||
#define __GDK_MONITOR_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdkrectangle.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MONITOR (gdk_monitor_get_type ())
|
||||
#define GDK_MONITOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MONITOR, GdkMonitor))
|
||||
#define GDK_IS_MONITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MONITOR))
|
||||
|
||||
typedef struct _GdkMonitor GdkMonitor;
|
||||
typedef struct _GdkMonitorClass GdkMonitorClass;
|
||||
|
||||
/**
|
||||
* GdkSubpixelLayout:
|
||||
* @GDK_SUBPIXEL_LAYOUT_UNKNOWN: The layout is not known
|
||||
* @GDK_SUBPIXEL_LAYOUT_NONE: Not organized in this way
|
||||
* @GDK_SUBPIXEL_LAYOUT_HORIZONTAL_RGB: The layout is horizontal, the order is RGB
|
||||
* @GDK_SUBPIXEL_LAYOUT_HORIZONTAL_BGR: The layout is horizontal, the order is BGR
|
||||
* @GDK_SUBPIXEL_LAYOUT_VERTICAL_RGB: The layout is vertical, the order is RGB
|
||||
* @GDK_SUBPIXEL_LAYOUT_VERTICAL_BGR: The layout is vertical, the order is BGR
|
||||
*
|
||||
* This enumeration describes how the red, green and blue components
|
||||
* of physical pixels on an output device are laid out.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_SUBPIXEL_LAYOUT_UNKNOWN,
|
||||
GDK_SUBPIXEL_LAYOUT_NONE,
|
||||
GDK_SUBPIXEL_LAYOUT_HORIZONTAL_RGB,
|
||||
GDK_SUBPIXEL_LAYOUT_HORIZONTAL_BGR,
|
||||
GDK_SUBPIXEL_LAYOUT_VERTICAL_RGB,
|
||||
GDK_SUBPIXEL_LAYOUT_VERTICAL_BGR
|
||||
} GdkSubpixelLayout;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gdk_monitor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkDisplay * gdk_monitor_get_display (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gdk_monitor_get_geometry (GdkMonitor *monitor,
|
||||
GdkRectangle *geometry);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gdk_monitor_get_workarea (GdkMonitor *monitor,
|
||||
GdkRectangle *geometry);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
int gdk_monitor_get_width_mm (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
int gdk_monitor_get_height_mm (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
const char * gdk_monitor_get_manufacturer (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
const char * gdk_monitor_get_model (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
int gdk_monitor_get_scale_factor (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
int gdk_monitor_get_refresh_rate (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkSubpixelLayout gdk_monitor_get_subpixel_layout (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gdk_monitor_is_primary (GdkMonitor *monitor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MONITOR_H__ */
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* gdkmonitorprivate.h
|
||||
*
|
||||
* Copyright 2016 Red Hat, Inc.
|
||||
*
|
||||
* Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MONITOR_PRIVATE_H__
|
||||
#define __GDK_MONITOR_PRIVATE_H__
|
||||
|
||||
#include "gdkmonitor.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_MONITOR, GdkMonitorClass))
|
||||
#define GDK_IS_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_MONITOR))
|
||||
#define GDK_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_MONITOR, GdkMonitorClass))
|
||||
|
||||
struct _GdkMonitor {
|
||||
GObject parent;
|
||||
|
||||
GdkDisplay *display;
|
||||
char *manufacturer;
|
||||
char *model;
|
||||
GdkRectangle geometry;
|
||||
int width_mm;
|
||||
int height_mm;
|
||||
int scale_factor;
|
||||
int refresh_rate;
|
||||
GdkSubpixelLayout subpixel_layout;
|
||||
};
|
||||
|
||||
struct _GdkMonitorClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* get_workarea) (GdkMonitor *monitor,
|
||||
GdkRectangle *geometry);
|
||||
};
|
||||
|
||||
GdkMonitor * gdk_monitor_new (GdkDisplay *display);
|
||||
|
||||
void gdk_monitor_set_manufacturer (GdkMonitor *monitor,
|
||||
const char *manufacturer);
|
||||
void gdk_monitor_set_model (GdkMonitor *monitor,
|
||||
const char *model);
|
||||
void gdk_monitor_set_position (GdkMonitor *monitor,
|
||||
int x,
|
||||
int y);
|
||||
void gdk_monitor_set_size (GdkMonitor *monitor,
|
||||
int width,
|
||||
int height);
|
||||
void gdk_monitor_set_physical_size (GdkMonitor *monitor,
|
||||
int width_mm,
|
||||
int height_mm);
|
||||
void gdk_monitor_set_scale_factor (GdkMonitor *monitor,
|
||||
int scale);
|
||||
void gdk_monitor_set_refresh_rate (GdkMonitor *monitor,
|
||||
int refresh_rate);
|
||||
void gdk_monitor_set_subpixel_layout (GdkMonitor *monitor,
|
||||
GdkSubpixelLayout subpixel);
|
||||
void gdk_monitor_invalidate (GdkMonitor *monitor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MONITOR_PRIVATE_H__ */
|
||||
+91
-113
@@ -84,7 +84,7 @@ gdk_screen_class_init (GdkScreenClass *klass)
|
||||
object_class->finalize = gdk_screen_finalize;
|
||||
object_class->set_property = gdk_screen_set_property;
|
||||
object_class->get_property = gdk_screen_get_property;
|
||||
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_FONT_OPTIONS,
|
||||
g_param_spec_pointer ("font-options",
|
||||
@@ -194,52 +194,20 @@ _gdk_screen_close (GdkScreen *screen)
|
||||
}
|
||||
}
|
||||
|
||||
/* Fallback used when the monitor "at" a point or window
|
||||
* doesn’t exist.
|
||||
*/
|
||||
static gint
|
||||
get_nearest_monitor (GdkScreen *screen,
|
||||
gint x,
|
||||
gint y)
|
||||
static int
|
||||
get_monitor_num (GdkMonitor *monitor)
|
||||
{
|
||||
gint num_monitors, i;
|
||||
gint nearest_dist = G_MAXINT;
|
||||
gint nearest_monitor = 0;
|
||||
GdkDisplay *display;
|
||||
int n_monitors, i;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
|
||||
|
||||
num_monitors = gdk_screen_get_n_monitors (screen);
|
||||
|
||||
for (i = 0; i < num_monitors; i++)
|
||||
display = gdk_monitor_get_display (monitor);
|
||||
n_monitors = gdk_display_get_n_monitors (display);
|
||||
for (i = 0; i < n_monitors; i++)
|
||||
{
|
||||
GdkRectangle monitor;
|
||||
gint dist_x, dist_y, dist;
|
||||
|
||||
gdk_screen_get_monitor_geometry (screen, i, &monitor);
|
||||
|
||||
if (x < monitor.x)
|
||||
dist_x = monitor.x - x;
|
||||
else if (x >= monitor.x + monitor.width)
|
||||
dist_x = x - (monitor.x + monitor.width) + 1;
|
||||
else
|
||||
dist_x = 0;
|
||||
|
||||
if (y < monitor.y)
|
||||
dist_y = monitor.y - y;
|
||||
else if (y >= monitor.y + monitor.height)
|
||||
dist_y = y - (monitor.y + monitor.height) + 1;
|
||||
else
|
||||
dist_y = 0;
|
||||
|
||||
dist = dist_x + dist_y;
|
||||
if (dist < nearest_dist)
|
||||
{
|
||||
nearest_dist = dist;
|
||||
nearest_monitor = i;
|
||||
}
|
||||
if (gdk_display_get_monitor (display, i) == monitor)
|
||||
return i;
|
||||
}
|
||||
|
||||
return nearest_monitor;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,31 +223,19 @@ get_nearest_monitor (GdkScreen *screen,
|
||||
*
|
||||
* Since: 2.2
|
||||
**/
|
||||
gint
|
||||
gint
|
||||
gdk_screen_get_monitor_at_point (GdkScreen *screen,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
gint num_monitors, i;
|
||||
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
|
||||
|
||||
num_monitors = gdk_screen_get_n_monitors (screen);
|
||||
|
||||
for (i=0;i<num_monitors;i++)
|
||||
{
|
||||
GdkRectangle monitor;
|
||||
|
||||
gdk_screen_get_monitor_geometry (screen, i, &monitor);
|
||||
|
||||
if (x >= monitor.x &&
|
||||
x < monitor.x + monitor.width &&
|
||||
y >= monitor.y &&
|
||||
y < (monitor.y + monitor.height))
|
||||
return i;
|
||||
}
|
||||
|
||||
return get_nearest_monitor (screen, x, y);
|
||||
display = gdk_screen_get_display (screen);
|
||||
monitor = gdk_display_get_monitor_at_point (display, x, y);
|
||||
return get_monitor_num (monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,39 +252,19 @@ gdk_screen_get_monitor_at_point (GdkScreen *screen,
|
||||
*
|
||||
* Since: 2.2
|
||||
**/
|
||||
gint
|
||||
gdk_screen_get_monitor_at_window (GdkScreen *screen,
|
||||
GdkWindow *window)
|
||||
gint
|
||||
gdk_screen_get_monitor_at_window (GdkScreen *screen,
|
||||
GdkWindow *window)
|
||||
{
|
||||
gint num_monitors, i, area = 0, screen_num = -1;
|
||||
GdkRectangle win_rect;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), -1);
|
||||
|
||||
gdk_window_get_geometry (window, &win_rect.x, &win_rect.y, &win_rect.width,
|
||||
&win_rect.height);
|
||||
gdk_window_get_origin (window, &win_rect.x, &win_rect.y);
|
||||
num_monitors = gdk_screen_get_n_monitors (screen);
|
||||
|
||||
for (i=0;i<num_monitors;i++)
|
||||
{
|
||||
GdkRectangle tmp_monitor, intersect;
|
||||
|
||||
gdk_screen_get_monitor_geometry (screen, i, &tmp_monitor);
|
||||
gdk_rectangle_intersect (&win_rect, &tmp_monitor, &intersect);
|
||||
|
||||
if (intersect.width * intersect.height > area)
|
||||
{
|
||||
area = intersect.width * intersect.height;
|
||||
screen_num = i;
|
||||
}
|
||||
}
|
||||
if (screen_num >= 0)
|
||||
return screen_num;
|
||||
else
|
||||
return get_nearest_monitor (screen,
|
||||
win_rect.x + win_rect.width / 2,
|
||||
win_rect.y + win_rect.height / 2);
|
||||
display = gdk_screen_get_display (screen);
|
||||
monitor = gdk_display_get_monitor_at_window (display, window);
|
||||
return get_monitor_num (monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -703,6 +639,16 @@ gdk_screen_get_root_window (GdkScreen *screen)
|
||||
return GDK_SCREEN_GET_CLASS (screen)->get_root_window (screen);
|
||||
}
|
||||
|
||||
static GdkMonitor *
|
||||
get_monitor (GdkScreen *screen,
|
||||
gint n)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
display = gdk_screen_get_display (screen);
|
||||
return gdk_display_get_monitor (display, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_screen_get_n_monitors:
|
||||
* @screen: a #GdkScreen
|
||||
@@ -716,9 +662,12 @@ gdk_screen_get_root_window (GdkScreen *screen)
|
||||
gint
|
||||
gdk_screen_get_n_monitors (GdkScreen *screen)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
|
||||
|
||||
return GDK_SCREEN_GET_CLASS (screen)->get_n_monitors (screen);
|
||||
display = gdk_screen_get_display (screen);
|
||||
return gdk_display_get_n_monitors (display);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -741,9 +690,17 @@ gdk_screen_get_n_monitors (GdkScreen *screen)
|
||||
gint
|
||||
gdk_screen_get_primary_monitor (GdkScreen *screen)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *primary;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
|
||||
|
||||
return GDK_SCREEN_GET_CLASS (screen)->get_primary_monitor (screen);
|
||||
display = gdk_screen_get_display (screen);
|
||||
primary = gdk_display_get_primary_monitor (display);
|
||||
if (primary)
|
||||
return get_monitor_num (primary);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -761,11 +718,15 @@ gint
|
||||
gdk_screen_get_monitor_width_mm (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
|
||||
g_return_val_if_fail (monitor_num >= 0, -1);
|
||||
g_return_val_if_fail (monitor_num < gdk_screen_get_n_monitors (screen), -1);
|
||||
GdkMonitor *monitor;
|
||||
|
||||
return GDK_SCREEN_GET_CLASS (screen)->get_monitor_width_mm (screen, monitor_num);
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
|
||||
|
||||
monitor = get_monitor (screen, monitor_num);
|
||||
|
||||
g_return_val_if_fail (monitor != NULL, -1);
|
||||
|
||||
return gdk_monitor_get_width_mm (monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -783,11 +744,15 @@ gint
|
||||
gdk_screen_get_monitor_height_mm (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
|
||||
g_return_val_if_fail (monitor_num >= 0, -1);
|
||||
g_return_val_if_fail (monitor_num < gdk_screen_get_n_monitors (screen), -1);
|
||||
GdkMonitor *monitor;
|
||||
|
||||
return GDK_SCREEN_GET_CLASS (screen)->get_monitor_height_mm (screen, monitor_num);
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
|
||||
|
||||
monitor = get_monitor (screen, monitor_num);
|
||||
|
||||
g_return_val_if_fail (monitor != NULL, -1);
|
||||
|
||||
return gdk_monitor_get_height_mm (monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -808,11 +773,15 @@ gchar *
|
||||
gdk_screen_get_monitor_plug_name (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
|
||||
g_return_val_if_fail (monitor_num >= 0, NULL);
|
||||
g_return_val_if_fail (monitor_num < gdk_screen_get_n_monitors (screen), NULL);
|
||||
GdkMonitor *monitor;
|
||||
|
||||
return GDK_SCREEN_GET_CLASS (screen)->get_monitor_plug_name (screen, monitor_num);
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
|
||||
|
||||
monitor = get_monitor (screen, monitor_num);
|
||||
|
||||
g_return_val_if_fail (monitor != NULL, NULL);
|
||||
|
||||
return g_strdup (gdk_monitor_get_model (monitor));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -840,11 +809,15 @@ gdk_screen_get_monitor_geometry (GdkScreen *screen,
|
||||
gint monitor_num,
|
||||
GdkRectangle *dest)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SCREEN (screen));
|
||||
g_return_if_fail (monitor_num >= 0);
|
||||
g_return_if_fail (monitor_num < gdk_screen_get_n_monitors (screen));
|
||||
GdkMonitor *monitor;
|
||||
|
||||
GDK_SCREEN_GET_CLASS(screen)->get_monitor_geometry (screen, monitor_num, dest);
|
||||
g_return_if_fail (GDK_IS_SCREEN (screen));
|
||||
|
||||
monitor = get_monitor (screen, monitor_num);
|
||||
|
||||
g_return_if_fail (monitor != NULL);
|
||||
|
||||
gdk_monitor_get_geometry (monitor, dest);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -877,11 +850,16 @@ gdk_screen_get_monitor_workarea (GdkScreen *screen,
|
||||
gint monitor_num,
|
||||
GdkRectangle *dest)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SCREEN (screen));
|
||||
g_return_if_fail (monitor_num >= 0);
|
||||
g_return_if_fail (monitor_num < gdk_screen_get_n_monitors (screen));
|
||||
GdkMonitor *monitor;
|
||||
|
||||
GDK_SCREEN_GET_CLASS (screen)->get_monitor_workarea (screen, monitor_num, dest);
|
||||
g_return_if_fail (GDK_IS_SCREEN (screen));
|
||||
|
||||
monitor = get_monitor (screen, monitor_num);
|
||||
|
||||
g_return_if_fail (monitor != NULL);
|
||||
|
||||
/* FIXME */
|
||||
gdk_monitor_get_geometry (monitor, dest);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,6 +46,8 @@ libgdk_wayland_la_SOURCES = \
|
||||
gdkkeys-wayland.c \
|
||||
gdkglcontext-wayland.c \
|
||||
gdkglcontext-wayland.h \
|
||||
gdkmonitor-wayland.c \
|
||||
gdkmonitor-wayland.h \
|
||||
gdkscreen-wayland.c \
|
||||
gdkseat-wayland.h \
|
||||
gdkselection-wayland.c \
|
||||
@@ -62,6 +64,7 @@ libgdkwaylandinclude_HEADERS = \
|
||||
gdkwaylanddevice.h \
|
||||
gdkwaylanddisplay.h \
|
||||
gdkwaylandglcontext.h \
|
||||
gdkwaylandmonitor.h \
|
||||
gdkwaylandselection.h \
|
||||
gdkwaylandwindow.h
|
||||
|
||||
|
||||
@@ -591,6 +591,8 @@ gdk_wayland_display_finalize (GObject *object)
|
||||
|
||||
g_free (display_wayland->startup_notification_id);
|
||||
|
||||
g_ptr_array_free (display_wayland->monitors, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_display_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -805,6 +807,26 @@ gdk_wayland_display_pop_error_trap (GdkDisplay *display,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_wayland_display_get_n_monitors (GdkDisplay *display)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
return display_wayland->monitors->len;
|
||||
}
|
||||
|
||||
static GdkMonitor *
|
||||
gdk_wayland_display_get_monitor (GdkDisplay *display,
|
||||
int monitor_num)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
if (monitor_num < 0 || monitor_num >= display_wayland->monitors->len)
|
||||
return NULL;
|
||||
|
||||
return (GdkMonitor *)display_wayland->monitors->pdata[monitor_num];
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
||||
{
|
||||
@@ -856,12 +878,17 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
||||
display_class->utf8_to_string_target = _gdk_wayland_display_utf8_to_string_target;
|
||||
|
||||
display_class->make_gl_context_current = gdk_wayland_display_make_gl_context_current;
|
||||
|
||||
display_class->get_n_monitors = gdk_wayland_display_get_n_monitors;
|
||||
display_class->get_monitor = gdk_wayland_display_get_monitor;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_display_init (GdkWaylandDisplay *display)
|
||||
{
|
||||
display->xkb_context = xkb_context_new (0);
|
||||
|
||||
display->monitors = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -98,6 +98,8 @@ struct _GdkWaylandDisplay
|
||||
|
||||
GdkWaylandSelection *selection;
|
||||
|
||||
GPtrArray *monitors;
|
||||
|
||||
/* egl info */
|
||||
EGLDisplay egl_display;
|
||||
int egl_major_version;
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include "gdkprivate-wayland.h"
|
||||
|
||||
#include "gdkmonitor-wayland.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandMonitor, gdk_wayland_monitor, GDK_TYPE_MONITOR)
|
||||
|
||||
static void
|
||||
gdk_wayland_monitor_init (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_monitor_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)object;
|
||||
|
||||
wl_output_destroy (monitor->output);
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_monitor_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_monitor_class_init (GdkWaylandMonitorClass *class)
|
||||
{
|
||||
G_OBJECT_CLASS (class)->finalize = gdk_wayland_monitor_finalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_wayland_monitor_get_wl_output:
|
||||
* @monitor: (type GdkWaylandMonitor): a #GdkMonitor
|
||||
*
|
||||
* Returns the Wayland wl_output of a #GdkMonitor.
|
||||
*
|
||||
* Returns: (transfer none): a Wayland wl_output
|
||||
* Since: 3.22
|
||||
*/
|
||||
struct wl_output *
|
||||
gdk_wayland_monitor_get_wl_output (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_WAYLAND_MONITOR (monitor), NULL);
|
||||
|
||||
return GDK_WAYLAND_MONITOR (monitor)->output;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_WAYLAND_MONITOR_PRIVATE_H__
|
||||
#define __GDK_WAYLAND_MONITOR_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include "gdkwaylandmonitor.h"
|
||||
#include "gdkmonitorprivate.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
|
||||
struct _GdkWaylandMonitor {
|
||||
GdkMonitor parent;
|
||||
|
||||
guint32 id;
|
||||
guint32 version;
|
||||
struct wl_output *output;
|
||||
gboolean added;
|
||||
};
|
||||
|
||||
struct _GdkWaylandMonitorClass {
|
||||
GdkMonitorClass parent_class;
|
||||
};
|
||||
|
||||
#endif
|
||||
+106
-199
@@ -26,6 +26,7 @@
|
||||
#include "gdkvisualprivate.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkmonitor-wayland.h"
|
||||
#include "gdkwayland.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
|
||||
@@ -49,7 +50,6 @@ typedef struct {
|
||||
const gchar *hintstyle;
|
||||
} GsdXftSettings;
|
||||
|
||||
typedef struct _GdkWaylandMonitor GdkWaylandMonitor;
|
||||
|
||||
struct _GdkWaylandScreen
|
||||
{
|
||||
@@ -64,10 +64,6 @@ struct _GdkWaylandScreen
|
||||
/* Visual Part */
|
||||
GdkVisual *visual;
|
||||
|
||||
/* Xinerama/RandR 1.2 */
|
||||
GPtrArray *monitors;
|
||||
gint primary_monitor;
|
||||
|
||||
GHashTable *settings;
|
||||
GsdXftSettings xft_settings;
|
||||
|
||||
@@ -83,59 +79,11 @@ struct _GdkWaylandScreenClass
|
||||
|
||||
#define OUTPUT_VERSION_WITH_DONE 2
|
||||
|
||||
struct _GdkWaylandMonitor
|
||||
{
|
||||
GdkWaylandScreen *screen;
|
||||
guint32 id;
|
||||
guint32 version;
|
||||
struct wl_output *output;
|
||||
GdkRectangle geometry;
|
||||
int width_mm;
|
||||
int height_mm;
|
||||
char * output_name;
|
||||
char * manufacturer;
|
||||
int refresh_rate;
|
||||
gint scale;
|
||||
};
|
||||
|
||||
GType _gdk_wayland_screen_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
|
||||
|
||||
static void
|
||||
free_monitor (gpointer data)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = data;
|
||||
|
||||
if (monitor == NULL)
|
||||
return;
|
||||
|
||||
wl_output_destroy (monitor->output);
|
||||
g_free (monitor->output_name);
|
||||
g_free (monitor->manufacturer);
|
||||
|
||||
g_free (monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
deinit_multihead (GdkScreen *screen)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
|
||||
g_ptr_array_free (screen_wayland->monitors, TRUE);
|
||||
|
||||
screen_wayland->monitors = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
init_multihead (GdkScreen *screen)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
|
||||
screen_wayland->monitors = g_ptr_array_new_with_free_func (free_monitor);
|
||||
screen_wayland->primary_monitor = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_screen_dispose (GObject *object)
|
||||
{
|
||||
@@ -157,8 +105,6 @@ gdk_wayland_screen_finalize (GObject *object)
|
||||
|
||||
g_object_unref (screen_wayland->visual);
|
||||
|
||||
deinit_multihead (GDK_SCREEN (object));
|
||||
|
||||
g_hash_table_destroy (screen_wayland->settings);
|
||||
|
||||
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->finalize (object);
|
||||
@@ -206,80 +152,6 @@ gdk_wayland_screen_get_root_window (GdkScreen *screen)
|
||||
return GDK_WAYLAND_SCREEN (screen)->root_window;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_wayland_screen_get_n_monitors (GdkScreen *screen)
|
||||
{
|
||||
return GDK_WAYLAND_SCREEN (screen)->monitors->len;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_wayland_screen_get_primary_monitor (GdkScreen *screen)
|
||||
{
|
||||
return GDK_WAYLAND_SCREEN (screen)->primary_monitor;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_wayland_screen_get_monitor_width_mm (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
|
||||
|
||||
return monitor->width_mm;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_wayland_screen_get_monitor_height_mm (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
|
||||
|
||||
return monitor->height_mm;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gdk_wayland_screen_get_monitor_plug_name (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
|
||||
|
||||
return g_strdup (monitor->output_name);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_screen_get_monitor_geometry (GdkScreen *screen,
|
||||
gint monitor_num,
|
||||
GdkRectangle *dest)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
|
||||
|
||||
if (dest)
|
||||
*dest = monitor->geometry;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_wayland_screen_get_monitor_scale_factor (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
|
||||
|
||||
return monitor->scale;
|
||||
}
|
||||
|
||||
static GdkVisual *
|
||||
gdk_wayland_screen_get_system_visual (GdkScreen * screen)
|
||||
{
|
||||
@@ -964,8 +836,6 @@ _gdk_wayland_screen_new (GdkDisplay *display)
|
||||
|
||||
screen_wayland->visual = gdk_wayland_visual_new (screen);
|
||||
|
||||
init_multihead (screen);
|
||||
|
||||
screen_wayland->root_window =
|
||||
_gdk_wayland_screen_create_root_window (screen,
|
||||
screen_wayland->width,
|
||||
@@ -992,14 +862,6 @@ _gdk_wayland_screen_class_init (GdkWaylandScreenClass *klass)
|
||||
screen_class->get_height_mm = gdk_wayland_screen_get_height_mm;
|
||||
screen_class->get_number = gdk_wayland_screen_get_number;
|
||||
screen_class->get_root_window = gdk_wayland_screen_get_root_window;
|
||||
screen_class->get_n_monitors = gdk_wayland_screen_get_n_monitors;
|
||||
screen_class->get_primary_monitor = gdk_wayland_screen_get_primary_monitor;
|
||||
screen_class->get_monitor_width_mm = gdk_wayland_screen_get_monitor_width_mm;
|
||||
screen_class->get_monitor_height_mm = gdk_wayland_screen_get_monitor_height_mm;
|
||||
screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name;
|
||||
screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
|
||||
screen_class->get_monitor_workarea = gdk_wayland_screen_get_monitor_geometry;
|
||||
screen_class->get_monitor_scale_factor = gdk_wayland_screen_get_monitor_scale_factor;
|
||||
screen_class->get_system_visual = gdk_wayland_screen_get_system_visual;
|
||||
screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
|
||||
screen_class->is_composited = gdk_wayland_screen_is_composited;
|
||||
@@ -1027,16 +889,17 @@ _gdk_wayland_screen_init (GdkWaylandScreen *screen_wayland)
|
||||
static void
|
||||
update_screen_size (GdkWaylandScreen *screen_wayland)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
|
||||
gboolean emit_changed = FALSE;
|
||||
gint width, height;
|
||||
gint width_mm, height_mm;
|
||||
gint i;
|
||||
int i;
|
||||
|
||||
width = height = 0;
|
||||
width_mm = height_mm = 0;
|
||||
for (i = 0; i < screen_wayland->monitors->len; i++)
|
||||
for (i = 0; i < display_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
|
||||
GdkMonitor *monitor = display_wayland->monitors->pdata[i];
|
||||
|
||||
/* XXX: Largely assuming here that monitor areas
|
||||
* are contiguous and never overlap.
|
||||
@@ -1143,19 +1006,18 @@ output_handle_geometry (void *data,
|
||||
g_message ("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s",
|
||||
monitor->id, x, y, physical_width, physical_height, subpixel_to_string (subpixel), make, model, transform_to_string (transform)));
|
||||
|
||||
monitor->geometry.x = x;
|
||||
monitor->geometry.y = y;
|
||||
gdk_monitor_set_position (GDK_MONITOR (monitor), x, y);
|
||||
gdk_monitor_set_physical_size (GDK_MONITOR (monitor), physical_width, physical_height);
|
||||
gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor), subpixel);
|
||||
gdk_monitor_set_manufacturer (GDK_MONITOR (monitor), make);
|
||||
gdk_monitor_set_model (GDK_MONITOR (monitor), model);
|
||||
|
||||
monitor->width_mm = physical_width;
|
||||
monitor->height_mm = physical_height;
|
||||
|
||||
monitor->manufacturer = g_strdup (make);
|
||||
monitor->output_name = g_strdup (model);
|
||||
|
||||
if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
update_screen_size (monitor->screen);
|
||||
GdkDisplay *display = GDK_MONITOR (monitor)->display;
|
||||
GdkWaylandScreen *screen = GDK_WAYLAND_SCREEN (gdk_display_get_default_screen (display));
|
||||
g_signal_emit_by_name (screen, "monitors-changed");
|
||||
update_screen_size (screen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1164,12 +1026,21 @@ output_handle_done (void *data,
|
||||
struct wl_output *wl_output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
GdkDisplay *display = gdk_monitor_get_display (GDK_MONITOR (monitor));
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (gdk_display_get_default_screen (display));
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle done output %d", monitor->id));
|
||||
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
update_screen_size (monitor->screen);
|
||||
if (!monitor->added)
|
||||
{
|
||||
monitor->added = TRUE;
|
||||
g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
|
||||
gdk_display_monitor_added (display, GDK_MONITOR (monitor));
|
||||
}
|
||||
|
||||
g_signal_emit_by_name (screen_wayland, "monitors-changed");
|
||||
update_screen_size (screen_wayland);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1182,10 +1053,13 @@ output_handle_scale (void *data,
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle scale output %d, scale %d", monitor->id, scale));
|
||||
|
||||
monitor->scale = scale;
|
||||
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
|
||||
|
||||
if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
GdkScreen *screen = gdk_display_get_default_screen (GDK_MONITOR (monitor)->display);
|
||||
g_signal_emit_by_name (screen, "monitors-changed");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1205,14 +1079,14 @@ output_handle_mode (void *data,
|
||||
if ((flags & WL_OUTPUT_MODE_CURRENT) == 0)
|
||||
return;
|
||||
|
||||
monitor->geometry.width = width;
|
||||
monitor->geometry.height = height;
|
||||
monitor->refresh_rate = refresh;
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), width, height);
|
||||
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
|
||||
|
||||
if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
if (width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
update_screen_size (monitor->screen);
|
||||
GdkScreen *screen = gdk_display_get_default_screen (GDK_MONITOR (monitor)->display);
|
||||
g_signal_emit_by_name (screen, "monitors-changed");
|
||||
update_screen_size (GDK_WAYLAND_SCREEN (screen));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1230,18 +1104,22 @@ _gdk_wayland_screen_add_output (GdkScreen *screen,
|
||||
struct wl_output *output,
|
||||
guint32 version)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkDisplay *display = gdk_screen_get_display (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = g_new0 (GdkWaylandMonitor, 1);
|
||||
monitor = g_object_new (GDK_TYPE_WAYLAND_MONITOR,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
monitor->id = id;
|
||||
monitor->output = output;
|
||||
monitor->version = version;
|
||||
monitor->screen = screen_wayland;
|
||||
monitor->scale = 1;
|
||||
|
||||
g_ptr_array_add (screen_wayland->monitors, monitor);
|
||||
if (monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
|
||||
gdk_display_monitor_added (display, GDK_MONITOR (monitor));
|
||||
}
|
||||
|
||||
wl_output_add_listener (output, &output_listener, monitor);
|
||||
}
|
||||
@@ -1250,30 +1128,67 @@ struct wl_output *
|
||||
_gdk_wayland_screen_get_wl_output (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (GDK_WAYLAND_SCREEN (screen)->display);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = display_wayland->monitors->pdata[monitor_num];
|
||||
|
||||
return monitor->output;
|
||||
}
|
||||
|
||||
static GdkWaylandMonitor *
|
||||
get_monitor_for_id (GdkWaylandScreen *screen_wayland,
|
||||
guint32 id)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < display_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->id == id)
|
||||
return monitor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkWaylandMonitor *
|
||||
get_monitor_for_output (GdkWaylandScreen *screen_wayland,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < display_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->output == output)
|
||||
return monitor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_screen_remove_output (GdkScreen *screen,
|
||||
guint32 id)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
int i;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
for (i = 0; i < screen_wayland->monitors->len; i++)
|
||||
monitor = get_monitor_for_id (screen_wayland, id);
|
||||
if (monitor != NULL)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->id == id)
|
||||
{
|
||||
g_ptr_array_remove (screen_wayland->monitors, monitor);
|
||||
|
||||
g_signal_emit_by_name (screen_wayland, "monitors-changed");
|
||||
update_screen_size (screen_wayland);
|
||||
break;
|
||||
}
|
||||
g_object_ref (monitor);
|
||||
g_ptr_array_remove (display_wayland->monitors, monitor);
|
||||
gdk_display_monitor_removed (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
|
||||
g_object_unref (monitor);
|
||||
g_signal_emit_by_name (screen_wayland, "monitors-changed");
|
||||
update_screen_size (screen_wayland);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1282,15 +1197,11 @@ _gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
int i;
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
for (i = 0; i < screen_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->output == output)
|
||||
return monitor->refresh_rate;
|
||||
}
|
||||
monitor = get_monitor_for_output (screen_wayland, output);
|
||||
if (monitor != NULL)
|
||||
return gdk_monitor_get_refresh_rate (GDK_MONITOR (monitor));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1300,15 +1211,11 @@ _gdk_wayland_screen_get_output_scale (GdkScreen *screen,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
int i;
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
for (i = 0; i < screen_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->output == output)
|
||||
return monitor->scale;
|
||||
}
|
||||
monitor = get_monitor_for_output (screen_wayland, output);
|
||||
if (monitor != NULL)
|
||||
return gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <gdk/wayland/gdkwaylanddevice.h>
|
||||
#include <gdk/wayland/gdkwaylanddisplay.h>
|
||||
#include <gdk/wayland/gdkwaylandmonitor.h>
|
||||
#include <gdk/wayland/gdkwaylandselection.h>
|
||||
#include <gdk/wayland/gdkwaylandwindow.h>
|
||||
#include <gdk/wayland/gdkwaylandglcontext.h>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* gdkwaylandmonitor.h
|
||||
*
|
||||
* Copyright 2016 Red Hat, Inc.
|
||||
*
|
||||
* Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_WAYLAND_MONITOR_H__
|
||||
#define __GDK_WAYLAND_MONITOR_H__
|
||||
|
||||
#if !defined (__GDKWAYLAND_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdkwayland.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkmonitor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_WAYLAND_MONITOR (gdk_wayland_monitor_get_type ())
|
||||
#define GDK_WAYLAND_MONITOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_MONITOR, GdkWaylandMonitor))
|
||||
#define GDK_IS_WAYLAND_MONITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_MONITOR))
|
||||
|
||||
typedef struct _GdkWaylandMonitor GdkWaylandMonitor;
|
||||
typedef struct _GdkWaylandMonitorClass GdkWaylandMonitorClass;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gdk_wayland_monitor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
struct wl_output *gdk_wayland_monitor_get_wl_output (GdkMonitor *monitor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_WAYLAND_MONITOR_H__ */
|
||||
@@ -47,6 +47,8 @@ libgdk_win32_la_SOURCES = \
|
||||
gdkglobals-win32.c \
|
||||
gdkkeys-win32.c \
|
||||
gdkmain-win32.c \
|
||||
gdkmonitor-win32.c \
|
||||
gdkmonitor-win32.h \
|
||||
gdkprivate-win32.h \
|
||||
gdkproperty-win32.c \
|
||||
gdkscreen-win32.c \
|
||||
@@ -56,10 +58,11 @@ libgdk_win32_la_SOURCES = \
|
||||
gdkwin32display.h \
|
||||
gdkwin32displaymanager.h \
|
||||
gdkwin32dnd.h \
|
||||
gdkwin32glcontext.h \
|
||||
gdkwin32glcontext.h \
|
||||
gdkwin32.h \
|
||||
gdkwin32id.c \
|
||||
gdkwin32keys.h \
|
||||
gdkwin32monitor.h \
|
||||
gdkwin32screen.h \
|
||||
gdkwin32window.h \
|
||||
gdkwindow-win32.c \
|
||||
@@ -76,9 +79,10 @@ libgdkwin32include_HEADERS = \
|
||||
gdkwin32display.h \
|
||||
gdkwin32displaymanager.h\
|
||||
gdkwin32dnd.h \
|
||||
gdkwin32glcontext.h \
|
||||
gdkwin32glcontext.h \
|
||||
gdkwin32keys.h \
|
||||
gdkwin32misc.h \
|
||||
gdkwin32monitor.h \
|
||||
gdkwin32screen.h \
|
||||
gdkwin32window.h
|
||||
|
||||
|
||||
@@ -25,10 +25,178 @@
|
||||
#include "gdkwin32display.h"
|
||||
#include "gdkwin32screen.h"
|
||||
#include "gdkwin32window.h"
|
||||
#include "gdkmonitor-win32.h"
|
||||
#include "gdkwin32.h"
|
||||
|
||||
static int debug_indent = 0;
|
||||
|
||||
static GdkMonitor *
|
||||
_gdk_win32_display_find_matching_monitor (GdkWin32Display *win32_display,
|
||||
GdkMonitor *needle)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < win32_display->monitors->len; i++)
|
||||
{
|
||||
GdkWin32Monitor *m;
|
||||
|
||||
m = GDK_WIN32_MONITOR (g_ptr_array_index (win32_display->monitors, i));
|
||||
|
||||
if (_gdk_win32_monitor_compare (m, GDK_WIN32_MONITOR (needle)) == 0)
|
||||
return GDK_MONITOR (m);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_win32_display_init_monitors (GdkWin32Display *win32_display)
|
||||
{
|
||||
GdkDisplay *display = GDK_DISPLAY (win32_display);
|
||||
GPtrArray *new_monitors;
|
||||
gint i;
|
||||
gboolean changed = FALSE;
|
||||
GdkWin32Monitor *primary_to_move = NULL;
|
||||
|
||||
for (i = 0; i < win32_display->monitors->len; i++)
|
||||
GDK_WIN32_MONITOR (g_ptr_array_index (win32_display->monitors, i))->remove = TRUE;
|
||||
|
||||
new_monitors = _gdk_win32_display_get_monitor_list (win32_display);
|
||||
|
||||
for (i = 0; i < new_monitors->len; i++)
|
||||
{
|
||||
GdkWin32Monitor *w32_m;
|
||||
GdkMonitor *m;
|
||||
GdkWin32Monitor *w32_ex_monitor;
|
||||
GdkMonitor *ex_monitor;
|
||||
GdkRectangle geometry, ex_geometry;
|
||||
GdkRectangle workarea, ex_workarea;
|
||||
|
||||
w32_m = GDK_WIN32_MONITOR (g_ptr_array_index (new_monitors, i));
|
||||
m = GDK_MONITOR (w32_m);
|
||||
ex_monitor = _gdk_win32_display_find_matching_monitor (win32_display, m);
|
||||
w32_ex_monitor = GDK_WIN32_MONITOR (ex_monitor);
|
||||
|
||||
if (ex_monitor == NULL)
|
||||
{
|
||||
w32_m->add = TRUE;
|
||||
changed = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
w32_ex_monitor->remove = FALSE;
|
||||
|
||||
if (i == 0)
|
||||
primary_to_move = w32_ex_monitor;
|
||||
|
||||
gdk_monitor_get_geometry (m, &geometry);
|
||||
gdk_monitor_get_geometry (ex_monitor, &ex_geometry);
|
||||
gdk_monitor_get_workarea (m, &workarea);
|
||||
gdk_monitor_get_workarea (ex_monitor, &ex_workarea);
|
||||
|
||||
if (memcmp (&workarea, &ex_workarea, sizeof (GdkRectangle)) != 0)
|
||||
{
|
||||
w32_ex_monitor->work_rect = workarea;
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (memcmp (&geometry, &ex_geometry, sizeof (GdkRectangle)) != 0)
|
||||
{
|
||||
gdk_monitor_set_size (ex_monitor, geometry.width, geometry.height);
|
||||
gdk_monitor_set_position (ex_monitor, geometry.x, geometry.y);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (gdk_monitor_get_width_mm (m) != gdk_monitor_get_width_mm (ex_monitor) ||
|
||||
gdk_monitor_get_height_mm (m) != gdk_monitor_get_height_mm (ex_monitor))
|
||||
{
|
||||
gdk_monitor_set_physical_size (ex_monitor,
|
||||
gdk_monitor_get_width_mm (m),
|
||||
gdk_monitor_get_height_mm (m));
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (gdk_monitor_get_model (m), gdk_monitor_get_model (ex_monitor)) != 0)
|
||||
{
|
||||
gdk_monitor_set_model (ex_monitor,
|
||||
gdk_monitor_get_model (m));
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (gdk_monitor_get_manufacturer (m), gdk_monitor_get_manufacturer (ex_monitor)) != 0)
|
||||
{
|
||||
gdk_monitor_set_manufacturer (ex_monitor,
|
||||
gdk_monitor_get_manufacturer (m));
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (gdk_monitor_get_refresh_rate (m) != gdk_monitor_get_refresh_rate (ex_monitor))
|
||||
{
|
||||
gdk_monitor_set_refresh_rate (ex_monitor, gdk_monitor_get_refresh_rate (m));
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (gdk_monitor_get_scale_factor (m) != gdk_monitor_get_scale_factor (ex_monitor))
|
||||
{
|
||||
gdk_monitor_set_scale_factor (ex_monitor, gdk_monitor_get_scale_factor (m));
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (gdk_monitor_get_subpixel_layout (m) != gdk_monitor_get_subpixel_layout (ex_monitor))
|
||||
{
|
||||
gdk_monitor_set_subpixel_layout (ex_monitor, gdk_monitor_get_subpixel_layout (m));
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = win32_display->monitors->len - 1; i >= 0; i--)
|
||||
{
|
||||
GdkWin32Monitor *w32_ex_monitor;
|
||||
GdkMonitor *ex_monitor;
|
||||
|
||||
w32_ex_monitor = GDK_WIN32_MONITOR (g_ptr_array_index (win32_display->monitors, i));
|
||||
ex_monitor = GDK_MONITOR (w32_ex_monitor);
|
||||
|
||||
if (!w32_ex_monitor->remove)
|
||||
continue;
|
||||
|
||||
changed = TRUE;
|
||||
gdk_display_monitor_removed (display, ex_monitor);
|
||||
g_ptr_array_remove_index (win32_display->monitors, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < new_monitors->len; i++)
|
||||
{
|
||||
GdkWin32Monitor *w32_m;
|
||||
GdkMonitor *m;
|
||||
|
||||
w32_m = GDK_WIN32_MONITOR (g_ptr_array_index (new_monitors, i));
|
||||
m = GDK_MONITOR (w32_m);
|
||||
|
||||
if (!w32_m->add)
|
||||
continue;
|
||||
|
||||
gdk_display_monitor_added (display, m);
|
||||
|
||||
if (i == 0)
|
||||
g_ptr_array_insert (win32_display->monitors, 0, g_object_ref (w32_m));
|
||||
else
|
||||
g_ptr_array_add (win32_display->monitors, g_object_ref (w32_m));
|
||||
}
|
||||
|
||||
g_ptr_array_free (new_monitors, TRUE);
|
||||
|
||||
if (primary_to_move)
|
||||
{
|
||||
g_ptr_array_remove (win32_display->monitors, g_object_ref (primary_to_move));
|
||||
g_ptr_array_insert (win32_display->monitors, 0, primary_to_move);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_win32_display_set_cursor_theme:
|
||||
* @display: (type GdkWin32Display): a #GdkDisplay
|
||||
@@ -636,12 +804,15 @@ gdk_win32_display_finalize (GObject *object)
|
||||
_gdk_win32_display_finalize_cursors (display_win32);
|
||||
_gdk_win32_dnd_exit ();
|
||||
|
||||
g_ptr_array_free (display_win32->monitors, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (gdk_win32_display_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_display_init (GdkWin32Display *display)
|
||||
{
|
||||
display->monitors = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
_gdk_win32_display_init_cursors (display);
|
||||
}
|
||||
|
||||
@@ -672,6 +843,40 @@ gdk_win32_display_pop_error_trap (GdkDisplay *display,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_win32_display_get_n_monitors (GdkDisplay *display)
|
||||
{
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
return win32_display->monitors->len;
|
||||
}
|
||||
|
||||
|
||||
static GdkMonitor *
|
||||
gdk_win32_display_get_monitor (GdkDisplay *display,
|
||||
int monitor_num)
|
||||
{
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
if (0 <= monitor_num || monitor_num < win32_display->monitors->len)
|
||||
return (GdkMonitor *) g_ptr_array_index (win32_display->monitors, monitor_num);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkMonitor *
|
||||
gdk_win32_display_get_primary_monitor (GdkDisplay *display)
|
||||
{
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
/* We arrange for the first monitor in the array to also be the primiary monitor */
|
||||
if (win32_display->monitors->len > 0)
|
||||
return (GdkMonitor *) g_ptr_array_index (win32_display->monitors, 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||
{
|
||||
@@ -727,5 +932,9 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||
display_class->utf8_to_string_target = _gdk_win32_display_utf8_to_string_target;
|
||||
display_class->make_gl_context_current = _gdk_win32_display_make_gl_context_current;
|
||||
|
||||
display_class->get_n_monitors = gdk_win32_display_get_n_monitors;
|
||||
display_class->get_monitor = gdk_win32_display_get_monitor;
|
||||
display_class->get_primary_monitor = gdk_win32_display_get_primary_monitor;
|
||||
|
||||
_gdk_win32_windowing_init ();
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ struct _GdkWin32Display
|
||||
HDC gl_hdc;
|
||||
HWND gl_hwnd;
|
||||
|
||||
GPtrArray *monitors;
|
||||
|
||||
guint hasWglARBCreateContext : 1;
|
||||
guint hasWglEXTSwapControl : 1;
|
||||
guint hasWglOMLSyncControl : 1;
|
||||
@@ -52,4 +54,8 @@ struct _GdkWin32DisplayClass
|
||||
GdkDisplayClass display_class;
|
||||
};
|
||||
|
||||
gboolean _gdk_win32_display_init_monitors (GdkWin32Display *display);
|
||||
|
||||
GPtrArray *_gdk_win32_display_get_monitor_list (GdkWin32Display *display);
|
||||
|
||||
#endif /* __GDK_DISPLAY__WIN32_H__ */
|
||||
|
||||
@@ -0,0 +1,833 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined (_WIN32_WINNT) && WIN32_WINNT < 0x0601
|
||||
# undef _WIN32_WINNT
|
||||
|
||||
# define _WIN32_WINNT 0x0601
|
||||
# ifdef WINVER
|
||||
# undef WINVER
|
||||
# endif
|
||||
# define WINVER _WIN32_WINNT
|
||||
#elif !defined (_WIN32_WINNT)
|
||||
# define _WIN32_WINNT 0x0601
|
||||
# ifdef WINVER
|
||||
# undef WINVER
|
||||
# endif
|
||||
# define WINVER _WIN32_WINNT
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkmonitor-win32.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include <cfgmgr32.h>
|
||||
#include <devpropdef.h>
|
||||
#include <setupapi.h>
|
||||
|
||||
#include "gdkprivate-win32.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32Monitor, gdk_win32_monitor, GDK_TYPE_MONITOR)
|
||||
|
||||
/* MinGW-w64 carelessly put DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = -1 into this
|
||||
* enum, as documented by MSDN. However, with
|
||||
* DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = 0x80000000 and
|
||||
* DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = 0xFFFFFFFF
|
||||
* this had the effect of increasing enum size from 4 to 8 bytes,
|
||||
* when compiled by GCC (MSVC doesn't have this problem), breaking ABI.
|
||||
* At the moment of writing MinGW-w64 headers are still broken.
|
||||
* When they are fixed, replace 9999 with actual version numbers.
|
||||
* The fix below is not necessarily correct, but it works.
|
||||
*/
|
||||
#if SIZEOF_DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY == 4
|
||||
# define fixedDISPLAYCONFIG_PATH_INFO DISPLAYCONFIG_PATH_INFO
|
||||
# define fixedDISPLAYCONFIG_TARGET_DEVICE_NAME DISPLAYCONFIG_TARGET_DEVICE_NAME
|
||||
#else
|
||||
typedef enum {
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = (int) -1,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = (int) 0,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = (int) 1,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = (int) 2,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO = (int) 3,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI = (int) 4,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI = (int) 5,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS = (int) 6,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN = (int) 8,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI = (int) 9,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL = (int) 10,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED = (int) 11,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL = (int) 12,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED = (int) 13,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE = (int) 14,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = (int) 0x80000000,
|
||||
fixedDISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = (int) 0xFFFFFFFF
|
||||
} fixedDISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY;
|
||||
|
||||
typedef struct fixedDISPLAYCONFIG_PATH_TARGET_INFO {
|
||||
LUID adapterId;
|
||||
UINT32 id;
|
||||
UINT32 modeInfoIdx;
|
||||
fixedDISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
|
||||
DISPLAYCONFIG_ROTATION rotation;
|
||||
DISPLAYCONFIG_SCALING scaling;
|
||||
DISPLAYCONFIG_RATIONAL refreshRate;
|
||||
DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
|
||||
WINBOOL targetAvailable;
|
||||
UINT32 statusFlags;
|
||||
} fixedDISPLAYCONFIG_PATH_TARGET_INFO;
|
||||
|
||||
typedef struct fixedDISPLAYCONFIG_PATH_INFO
|
||||
{
|
||||
DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo;
|
||||
fixedDISPLAYCONFIG_PATH_TARGET_INFO targetInfo;
|
||||
UINT32 flags;
|
||||
} fixedDISPLAYCONFIG_PATH_INFO;
|
||||
|
||||
typedef struct fixedDISPLAYCONFIG_TARGET_DEVICE_NAME
|
||||
{
|
||||
DISPLAYCONFIG_DEVICE_INFO_HEADER header;
|
||||
DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS flags;
|
||||
fixedDISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
|
||||
UINT16 edidManufactureId;
|
||||
UINT16 edidProductCodeId;
|
||||
UINT32 connectorInstance;
|
||||
WCHAR monitorFriendlyDeviceName[64];
|
||||
WCHAR monitorDevicePath[128];
|
||||
} fixedDISPLAYCONFIG_TARGET_DEVICE_NAME;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* MinGW-w64 does not have these functions in its import libraries
|
||||
* at the moment of writing.
|
||||
* Also, Windows Vista doesn't have these functions at all
|
||||
* (according to MSDN it does, but that is a lie), so we'd have
|
||||
* to load them manually anyway (otherwise GTK apps won't even start
|
||||
* on Vista).
|
||||
*/
|
||||
typedef LONG WINAPI
|
||||
(* funcGetDisplayConfigBufferSizes) (UINT32 flags,
|
||||
UINT32* numPathArrayElements,
|
||||
UINT32* numModeInfoArrayElements);
|
||||
|
||||
typedef LONG WINAPI
|
||||
(* funcQueryDisplayConfig) (UINT32 flags,
|
||||
UINT32* numPathArrayElements,
|
||||
fixedDISPLAYCONFIG_PATH_INFO* pathArray,
|
||||
UINT32* numModeInfoArrayElements,
|
||||
DISPLAYCONFIG_MODE_INFO* modeInfoArray,
|
||||
DISPLAYCONFIG_TOPOLOGY_ID* currentTopologyId);
|
||||
|
||||
typedef LONG WINAPI
|
||||
(* funcDisplayConfigGetDeviceInfo) (DISPLAYCONFIG_DEVICE_INFO_HEADER* requestPacket);
|
||||
|
||||
#ifndef MONITORINFOF_PRIMARY
|
||||
#define MONITORINFOF_PRIMARY 1
|
||||
#endif
|
||||
|
||||
/* MinGW-w64 does not have a prototype for function in its headers
|
||||
* at the moment of writing.
|
||||
*/
|
||||
#if !defined (HAVE_SETUP_DI_GET_DEVICE_PROPERTY_W)
|
||||
BOOL WINAPI SetupDiGetDevicePropertyW (HDEVINFO DeviceInfoSet,
|
||||
PSP_DEVINFO_DATA DeviceInfoData,
|
||||
const DEVPROPKEY *PropertyKey,
|
||||
DEVPROPTYPE *PropertyType,
|
||||
PBYTE PropertyBuffer,
|
||||
DWORD PropertyBufferSize,
|
||||
PDWORD RequiredSize,
|
||||
DWORD Flags);
|
||||
#endif
|
||||
|
||||
#define G_GUID_FORMAT "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
|
||||
#define g_format_guid(guid) (guid)->Data1, \
|
||||
(guid)->Data2, \
|
||||
(guid)->Data3, \
|
||||
(guid)->Data4[0], \
|
||||
(guid)->Data4[1], \
|
||||
(guid)->Data4[2], \
|
||||
(guid)->Data4[3], \
|
||||
(guid)->Data4[4], \
|
||||
(guid)->Data4[5], \
|
||||
(guid)->Data4[6], \
|
||||
(guid)->Data4[7]
|
||||
|
||||
static gboolean
|
||||
get_device_property (HDEVINFO device_infoset,
|
||||
SP_DEVINFO_DATA *device_info_data,
|
||||
DEVPROPKEY *property_key,
|
||||
gpointer *r_buffer,
|
||||
gsize *r_buffer_size,
|
||||
DEVPROPTYPE *r_property_type,
|
||||
GError **error)
|
||||
{
|
||||
DEVPROPTYPE property_type;
|
||||
gpointer property;
|
||||
DWORD property_size;
|
||||
|
||||
property = NULL;
|
||||
property_size = 0;
|
||||
|
||||
if (!SetupDiGetDevicePropertyW (device_infoset,
|
||||
device_info_data,
|
||||
property_key,
|
||||
&property_type,
|
||||
property,
|
||||
property_size,
|
||||
&property_size,
|
||||
0))
|
||||
{
|
||||
DWORD error_code = GetLastError ();
|
||||
|
||||
if (error_code != ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
gchar *emsg = g_win32_error_message (error_code);
|
||||
g_warning ("Failed to get device node property {" G_GUID_FORMAT "},%lu size: %s",
|
||||
g_format_guid (&property_key->fmtid),
|
||||
property_key->pid,
|
||||
emsg);
|
||||
g_free (emsg);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (r_buffer)
|
||||
{
|
||||
property = g_malloc (property_size);
|
||||
|
||||
if (!SetupDiGetDevicePropertyW (device_infoset,
|
||||
device_info_data,
|
||||
property_key,
|
||||
&property_type,
|
||||
property,
|
||||
property_size,
|
||||
&property_size,
|
||||
0))
|
||||
{
|
||||
DWORD error_code = GetLastError ();
|
||||
|
||||
gchar *emsg = g_win32_error_message (error_code);
|
||||
g_warning ("Failed to get device node property {" G_GUID_FORMAT "},%lu: %s",
|
||||
g_format_guid (&property_key->fmtid),
|
||||
property_key->pid,
|
||||
emsg);
|
||||
g_free (emsg);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*r_buffer = property;
|
||||
}
|
||||
|
||||
if (r_buffer_size)
|
||||
*r_buffer_size = property_size;
|
||||
|
||||
if (r_property_type)
|
||||
*r_property_type = property_type;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
get_monitor_devices (GdkWin32Display *win32_display)
|
||||
{
|
||||
GPtrArray *monitor_array;
|
||||
HDEVINFO device_infoset;
|
||||
SP_DEVINFO_DATA device_info_data;
|
||||
DWORD device_index;
|
||||
GUID device_interface_monitor = {0xe6f07b5f, 0xee97, 0x4a90, {0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7}};
|
||||
DEVPROPKEY pkey_device_instance_id = {{0x78C34FC8, 0x104A, 0x4ACA, {0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57}}, 256};
|
||||
DEVPROPKEY pkey_manufacturer = {{0xA45C254E, 0xDF1C, 0x4EFD, {0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0}}, 13};
|
||||
DEVPROPKEY pkey_display_name = {{0xB725F130, 0x47EF, 0x101A, {0xA5, 0xF1, 0x02, 0x60, 0x8C, 0x9E, 0xEB, 0xAC}}, 10};
|
||||
|
||||
monitor_array = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
device_infoset = SetupDiGetClassDevs (&device_interface_monitor, 0, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
|
||||
|
||||
if (device_infoset == INVALID_HANDLE_VALUE)
|
||||
return monitor_array;
|
||||
|
||||
for (device_index = 0; TRUE; device_index++)
|
||||
{
|
||||
gunichar2 *p;
|
||||
gchar *instance_path;
|
||||
gunichar2 *prop;
|
||||
DWORD proptype;
|
||||
HKEY device_registry_key;
|
||||
GdkWin32Monitor *w32mon;
|
||||
GdkMonitor *mon;
|
||||
unsigned char *edid;
|
||||
DWORD edid_size;
|
||||
DWORD edid_type;
|
||||
|
||||
memset (&device_info_data, 0, sizeof (device_info_data));
|
||||
device_info_data.cbSize = sizeof (device_info_data);
|
||||
|
||||
if (!SetupDiEnumDeviceInfo (device_infoset, device_index, &device_info_data))
|
||||
{
|
||||
DWORD error_code = GetLastError ();
|
||||
|
||||
if (error_code == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
|
||||
g_warning ("SetupDiEnumDeviceInfo() failed: %lu\n", error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!get_device_property (device_infoset,
|
||||
&device_info_data,
|
||||
&pkey_device_instance_id,
|
||||
(gpointer *) &prop,
|
||||
NULL,
|
||||
&proptype,
|
||||
NULL))
|
||||
continue;
|
||||
|
||||
if (proptype != DEVPROP_TYPE_STRING)
|
||||
{
|
||||
g_free (prop);
|
||||
continue;
|
||||
}
|
||||
|
||||
w32mon = g_object_new (GDK_TYPE_WIN32_MONITOR, "display", win32_display, NULL);
|
||||
mon = GDK_MONITOR (w32mon);
|
||||
|
||||
g_ptr_array_add (monitor_array, w32mon);
|
||||
|
||||
/* Half-initialized monitors are candidates for removal */
|
||||
w32mon->remove = TRUE;
|
||||
|
||||
/* device instance ID looks like: DISPLAY\FOO\X&XXXXXXX&X&UIDXXX */
|
||||
for (p = prop; p[0]; p++)
|
||||
if (p[0] == L'\\')
|
||||
p[0] = L'#';
|
||||
/* now device instance ID looks like: DISPLAY#FOO#X&XXXXXXX&X&UIDXXX */
|
||||
|
||||
/* instance path looks like: \\?\DISPLAY#FOO#X&XXXXXXX&X&UIDXXX#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7} */
|
||||
instance_path = g_strdup_printf ("\\\\?\\%ls#{" G_GUID_FORMAT "}",
|
||||
prop,
|
||||
g_format_guid (&device_interface_monitor));
|
||||
w32mon->instance_path = g_utf8_strdown (instance_path, -1);
|
||||
g_free (instance_path);
|
||||
g_free (prop);
|
||||
|
||||
if (get_device_property (device_infoset,
|
||||
&device_info_data,
|
||||
&pkey_manufacturer,
|
||||
(gpointer *) &prop,
|
||||
NULL, &proptype, NULL))
|
||||
{
|
||||
if (proptype == DEVPROP_TYPE_STRING)
|
||||
{
|
||||
gchar *manufacturer = g_utf16_to_utf8 (prop, -1, NULL, NULL, NULL);
|
||||
gdk_monitor_set_manufacturer (mon, manufacturer);
|
||||
g_free (manufacturer);
|
||||
}
|
||||
|
||||
g_free (prop);
|
||||
}
|
||||
|
||||
if (get_device_property (device_infoset,
|
||||
&device_info_data,
|
||||
&pkey_display_name,
|
||||
(gpointer *) &prop,
|
||||
NULL, &proptype, NULL))
|
||||
{
|
||||
if (proptype == DEVPROP_TYPE_STRING)
|
||||
{
|
||||
gchar *name = g_utf16_to_utf8 (prop, -1, NULL, NULL, NULL);
|
||||
gdk_monitor_set_model (mon, name);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
g_free (prop);
|
||||
}
|
||||
|
||||
device_registry_key = SetupDiOpenDevRegKey (device_infoset, &device_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
|
||||
|
||||
if (device_registry_key == NULL || device_registry_key == INVALID_HANDLE_VALUE)
|
||||
continue;
|
||||
|
||||
edid = NULL;
|
||||
edid_size = 0;
|
||||
|
||||
|
||||
if (RegQueryValueExW (device_registry_key, L"EDID",
|
||||
NULL, &edid_type,
|
||||
edid, &edid_size) == ERROR_SUCCESS)
|
||||
{
|
||||
edid = g_malloc (edid_size);
|
||||
|
||||
if (RegQueryValueExW (device_registry_key, L"EDID",
|
||||
NULL, &edid_type,
|
||||
edid, &edid_size) == ERROR_SUCCESS)
|
||||
{
|
||||
gdk_monitor_set_physical_size (mon,
|
||||
((edid[68] & 0x00F0) << 4) + edid[66],
|
||||
((edid[68] & 0x000F) << 8) + edid[67]);
|
||||
}
|
||||
|
||||
g_free (edid);
|
||||
}
|
||||
|
||||
RegCloseKey (device_registry_key);
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList (device_infoset);
|
||||
|
||||
return monitor_array;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_monitor_devices_from_display_config (GPtrArray *monitors)
|
||||
{
|
||||
HMODULE user32;
|
||||
LONG return_code;
|
||||
funcGetDisplayConfigBufferSizes getDisplayConfigBufferSizes;
|
||||
funcQueryDisplayConfig queryDisplayConfig;
|
||||
funcDisplayConfigGetDeviceInfo displayConfigGetDeviceInfo;
|
||||
UINT32 dispconf_mode_count;
|
||||
UINT32 dispconf_path_count;
|
||||
fixedDISPLAYCONFIG_PATH_INFO *dispconf_paths;
|
||||
DISPLAYCONFIG_MODE_INFO *dispconf_modes;
|
||||
gint path_index;
|
||||
|
||||
user32 = LoadLibraryA ("user32.dll");
|
||||
|
||||
if (user32 == NULL)
|
||||
return;
|
||||
|
||||
getDisplayConfigBufferSizes = (funcGetDisplayConfigBufferSizes) GetProcAddress (user32,
|
||||
"GetDisplayConfigBufferSizes");
|
||||
queryDisplayConfig = (funcQueryDisplayConfig) GetProcAddress (user32,
|
||||
"QueryDisplayConfig");
|
||||
displayConfigGetDeviceInfo = (funcDisplayConfigGetDeviceInfo) GetProcAddress (user32,
|
||||
"DisplayConfigGetDeviceInfo");
|
||||
if (getDisplayConfigBufferSizes == NULL ||
|
||||
queryDisplayConfig == NULL ||
|
||||
displayConfigGetDeviceInfo == NULL)
|
||||
{
|
||||
/* This does happen on Windows Vista, so don't warn about this */
|
||||
FreeLibrary (user32);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return_code = getDisplayConfigBufferSizes (QDC_ONLY_ACTIVE_PATHS,
|
||||
&dispconf_path_count,
|
||||
&dispconf_mode_count);
|
||||
|
||||
if (return_code != ERROR_SUCCESS)
|
||||
{
|
||||
g_warning ("Can't get displayconfig buffer size: 0x%lx\n", return_code);
|
||||
FreeLibrary (user32);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dispconf_paths = g_new (fixedDISPLAYCONFIG_PATH_INFO, dispconf_path_count);
|
||||
dispconf_modes = g_new (DISPLAYCONFIG_MODE_INFO, dispconf_mode_count);
|
||||
|
||||
return_code = queryDisplayConfig (QDC_ONLY_ACTIVE_PATHS,
|
||||
&dispconf_path_count,
|
||||
dispconf_paths,
|
||||
&dispconf_mode_count,
|
||||
dispconf_modes,
|
||||
NULL);
|
||||
|
||||
if (return_code != ERROR_SUCCESS)
|
||||
{
|
||||
g_free (dispconf_paths);
|
||||
g_free (dispconf_modes);
|
||||
FreeLibrary (user32);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (path_index = 0; path_index < dispconf_path_count; path_index++)
|
||||
{
|
||||
fixedDISPLAYCONFIG_TARGET_DEVICE_NAME tdn;
|
||||
gint i;
|
||||
GdkWin32Monitor *w32mon;
|
||||
GdkMonitor *mon;
|
||||
gchar *path, *path_lower;
|
||||
DISPLAYCONFIG_RATIONAL *refresh;
|
||||
|
||||
if ((dispconf_paths[path_index].flags & DISPLAYCONFIG_PATH_ACTIVE) == 0)
|
||||
continue;
|
||||
|
||||
tdn.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
|
||||
tdn.header.size = sizeof (tdn);
|
||||
tdn.header.adapterId = dispconf_paths[path_index].targetInfo.adapterId;
|
||||
tdn.header.id = dispconf_paths[path_index].targetInfo.id;
|
||||
|
||||
return_code = displayConfigGetDeviceInfo (&tdn.header);
|
||||
|
||||
if (return_code != ERROR_SUCCESS)
|
||||
continue;
|
||||
|
||||
path = g_utf16_to_utf8 (tdn.monitorDevicePath, -1, NULL, NULL, NULL);
|
||||
|
||||
if (path == NULL)
|
||||
continue;
|
||||
|
||||
path_lower = g_utf8_strdown (path, -1);
|
||||
|
||||
g_free (path);
|
||||
|
||||
for (i = 0, w32mon = NULL; i < monitors->len; i++)
|
||||
{
|
||||
GdkWin32Monitor *m = g_ptr_array_index (monitors, i);
|
||||
|
||||
if (g_strcmp0 (m->instance_path, path_lower) != 0)
|
||||
continue;
|
||||
|
||||
w32mon = m;
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (path_lower);
|
||||
|
||||
if (w32mon == NULL)
|
||||
continue;
|
||||
|
||||
mon = GDK_MONITOR (w32mon);
|
||||
|
||||
if (!tdn.flags.friendlyNameForced)
|
||||
{
|
||||
/* monitorFriendlyDeviceName is usually nicer */
|
||||
gchar *name = g_utf16_to_utf8 (tdn.monitorFriendlyDeviceName, -1, NULL, NULL, NULL);
|
||||
gdk_monitor_set_model (mon, name);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
refresh = &dispconf_paths[path_index].targetInfo.refreshRate;
|
||||
gdk_monitor_set_refresh_rate (mon,
|
||||
refresh->Numerator * 1000 / refresh->Denominator);
|
||||
}
|
||||
|
||||
g_free (dispconf_paths);
|
||||
g_free (dispconf_modes);
|
||||
|
||||
FreeLibrary (user32);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GPtrArray *monitors;
|
||||
gboolean have_monitor_devices;
|
||||
GdkWin32Display *display;
|
||||
} EnumMonitorData;
|
||||
|
||||
static BOOL CALLBACK
|
||||
enum_monitor (HMONITOR hmonitor,
|
||||
HDC hdc,
|
||||
LPRECT rect,
|
||||
LPARAM param)
|
||||
{
|
||||
EnumMonitorData *data = (EnumMonitorData *) param;
|
||||
MONITORINFOEXW monitor_info;
|
||||
DWORD i_adapter;
|
||||
|
||||
/* Grab monitor_info for this logical monitor */
|
||||
monitor_info.cbSize = sizeof (MONITORINFOEXW);
|
||||
GetMonitorInfoW (hmonitor, (MONITORINFO *) &monitor_info);
|
||||
|
||||
/* Sidestep to enumerate display adapters */
|
||||
for (i_adapter = 0; TRUE; i_adapter++)
|
||||
{
|
||||
DISPLAY_DEVICEW dd;
|
||||
DEVMODEW dm;
|
||||
DWORD i_monitor;
|
||||
DWORD frequency;
|
||||
|
||||
memset (&dd, 0, sizeof (dd));
|
||||
dd.cb = sizeof (dd);
|
||||
|
||||
/* 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
|
||||
* (logical monitor == 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;
|
||||
gchar *device_id_lower, *tmp;
|
||||
DWORD i;
|
||||
GdkWin32Monitor *w32mon;
|
||||
GdkMonitor *mon;
|
||||
GdkRectangle rect;
|
||||
|
||||
memset (&dd_monitor, 0, sizeof (dd_monitor));
|
||||
dd_monitor.cb = sizeof (dd_monitor);
|
||||
|
||||
if (data->have_monitor_devices)
|
||||
{
|
||||
/* Get i_monitor'th monitor */
|
||||
if (!EnumDisplayDevicesW (dd.DeviceName, i_monitor, &dd_monitor, EDD_GET_DEVICE_INTERFACE_NAME))
|
||||
break;
|
||||
|
||||
tmp = g_utf16_to_utf8 (dd_monitor.DeviceID, -1, NULL, NULL, NULL);
|
||||
|
||||
if (tmp == NULL)
|
||||
continue;
|
||||
|
||||
device_id_lower = g_utf8_strdown (tmp, -1);
|
||||
g_free (tmp);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Headless PC or a virtual machine, it has no monitor devices.
|
||||
* Make one up.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
|
||||
gchar *name = NULL;
|
||||
|
||||
/* Only use dd.DeviceName as a last resort, as it is just
|
||||
* \\.\DISPLAYX\MonitorY (for some values of X and Y).
|
||||
*/
|
||||
if (dd_monitor.DeviceName[0] != L'\0')
|
||||
name = g_utf16_to_utf8 (dd_monitor.DeviceName, -1, NULL, NULL, NULL);
|
||||
else if (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);
|
||||
|
||||
gdk_monitor_set_physical_size (mon,
|
||||
GetDeviceCaps (hDC, HORZSIZE),
|
||||
GetDeviceCaps (hDC, VERTSIZE));
|
||||
DeleteDC (hDC);
|
||||
}
|
||||
|
||||
/* frequency is in Hz and is unsigned long,
|
||||
* prefer more precise refresh_rate found earlier,
|
||||
* which comes as a Numerator & Denominator pair and is more precise.
|
||||
*/
|
||||
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
|
||||
* via other functions.
|
||||
*/
|
||||
rect.x = monitor_info.rcMonitor.left;
|
||||
rect.y = monitor_info.rcMonitor.top;
|
||||
rect.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
|
||||
rect.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
|
||||
gdk_monitor_set_position (mon, rect.x, rect.y);
|
||||
gdk_monitor_set_size (mon, rect.width, rect.height);
|
||||
|
||||
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;
|
||||
w32mon->work_rect = rect;
|
||||
|
||||
if (monitor_info.dwFlags & MONITORINFOF_PRIMARY && i != 0)
|
||||
{
|
||||
/* Put primary monitor at index 0, just in case somebody needs
|
||||
* to know which one is the primary.
|
||||
*/
|
||||
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,
|
||||
* but our initial list of monitor devices did not have it.
|
||||
* Any monitor devices not matched in this functions will have
|
||||
* 0-filled work area and will therefore be useless, so let them
|
||||
* keep remove == TRUE and be removed further up the stack.
|
||||
*/
|
||||
w32mon->remove = FALSE;
|
||||
|
||||
/* One virtual monitor per display adapter */
|
||||
if (w32mon->madeup)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GPtrArray *
|
||||
_gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
|
||||
{
|
||||
EnumMonitorData data;
|
||||
gint i;
|
||||
|
||||
data.display = win32_display;
|
||||
data.monitors = get_monitor_devices (win32_display);
|
||||
|
||||
if (data.monitors->len != 0)
|
||||
{
|
||||
populate_monitor_devices_from_display_config (data.monitors);
|
||||
data.have_monitor_devices = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.have_monitor_devices = FALSE;
|
||||
}
|
||||
|
||||
EnumDisplayMonitors (NULL, NULL, enum_monitor, (LPARAM) &data);
|
||||
|
||||
_gdk_offset_x = G_MININT;
|
||||
_gdk_offset_y = G_MININT;
|
||||
|
||||
for (i = 0; i < data.monitors->len; i++)
|
||||
{
|
||||
GdkWin32Monitor *m;
|
||||
GdkRectangle rect;
|
||||
|
||||
m = g_ptr_array_index (data.monitors, i);
|
||||
|
||||
if (m->remove)
|
||||
{
|
||||
g_ptr_array_remove_index (data.monitors, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Calculate offset */
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (m), &rect);
|
||||
_gdk_offset_x = MAX (_gdk_offset_x, -rect.x);
|
||||
_gdk_offset_y = MAX (_gdk_offset_y, -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 < data.monitors->len; i++)
|
||||
{
|
||||
GdkWin32Monitor *m;
|
||||
GdkRectangle rect;
|
||||
|
||||
m = g_ptr_array_index (data.monitors, i);
|
||||
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (m), &rect);
|
||||
rect.x += _gdk_offset_x;
|
||||
rect.y += _gdk_offset_y;
|
||||
gdk_monitor_set_position (GDK_MONITOR (m), rect.x, rect.y);
|
||||
|
||||
m->work_rect.x += _gdk_offset_x;
|
||||
m->work_rect.y += _gdk_offset_y;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@%+d%+d\n", i,
|
||||
rect.width, rect.height, rect.x, rect.y));
|
||||
}
|
||||
|
||||
return data.monitors;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_monitor_finalize (GObject *object)
|
||||
{
|
||||
GdkWin32Monitor *win32_monitor = GDK_WIN32_MONITOR (object);
|
||||
|
||||
g_free (win32_monitor->instance_path);
|
||||
|
||||
G_OBJECT_CLASS (gdk_win32_monitor_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
int
|
||||
_gdk_win32_monitor_compare (GdkWin32Monitor *a,
|
||||
GdkWin32Monitor *b)
|
||||
{
|
||||
if (a->instance_path != NULL &&
|
||||
b->instance_path != NULL)
|
||||
return g_strcmp0 (a->instance_path, b->instance_path);
|
||||
|
||||
return a == b ? 0 : a < b ? -1 : 1;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_monitor_get_workarea (GdkMonitor *monitor,
|
||||
GdkRectangle *dest)
|
||||
{
|
||||
GdkWin32Monitor *win32_monitor = GDK_WIN32_MONITOR (monitor);
|
||||
|
||||
*dest = win32_monitor->work_rect;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_monitor_init (GdkWin32Monitor *monitor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_monitor_class_init (GdkWin32MonitorClass *class)
|
||||
{
|
||||
G_OBJECT_CLASS (class)->finalize = gdk_win32_monitor_finalize;
|
||||
|
||||
GDK_MONITOR_CLASS (class)->get_workarea = gdk_win32_monitor_get_workarea;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_WIN32_MONITOR_PRIVATE_H__
|
||||
#define __GDK_WIN32_MONITOR_PRIVATE_H__
|
||||
|
||||
#include <windows.h>
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
|
||||
#include "gdkwin32monitor.h"
|
||||
|
||||
struct _GdkWin32Monitor
|
||||
{
|
||||
GdkMonitor parent;
|
||||
|
||||
/* work area */
|
||||
GdkRectangle work_rect;
|
||||
|
||||
/* Device instance path (used to match GdkWin32Monitor to monitor device) */
|
||||
gchar *instance_path;
|
||||
|
||||
/* TRUE if monitor is made up by us
|
||||
* (this happens when system has logical monitors, but no physical ones).
|
||||
*/
|
||||
guint madeup : 1;
|
||||
|
||||
/* TRUE if we should notify GDK about this monitor being added */
|
||||
guint add : 1;
|
||||
|
||||
/* TRUE if we should notify GDK about this monitor being removed */
|
||||
guint remove : 1;
|
||||
};
|
||||
|
||||
struct _GdkWin32MonitorClass {
|
||||
GdkMonitorClass parent_class;
|
||||
};
|
||||
|
||||
int _gdk_win32_monitor_compare (GdkWin32Monitor *a, GdkWin32Monitor *b);
|
||||
|
||||
#endif
|
||||
+40
-243
@@ -22,24 +22,15 @@
|
||||
#include "gdkwin32screen.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkvisualprivate.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkmonitor-win32.h"
|
||||
|
||||
#include <dwmapi.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *name;
|
||||
gint width_mm, height_mm;
|
||||
GdkRectangle rect;
|
||||
GdkRectangle work_rect;
|
||||
} GdkWin32Monitor;
|
||||
|
||||
struct _GdkWin32Screen
|
||||
{
|
||||
GdkScreen parent_instance;
|
||||
|
||||
gint num_monitors;
|
||||
GdkWin32Monitor *monitors;
|
||||
|
||||
GdkVisual *system_visual;
|
||||
GdkVisual *rgba_visual;
|
||||
gint available_visual_depths[1];
|
||||
@@ -257,26 +248,44 @@ init_visual (GdkScreen *screen,
|
||||
return visual;
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
init_root_window_size (GdkWin32Screen *screen)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
GdkRectangle result;
|
||||
int i;
|
||||
GdkDisplay *display = _gdk_display;
|
||||
int monitor_count;
|
||||
GdkMonitor *monitor;
|
||||
gboolean changed;
|
||||
|
||||
rect = screen->monitors[0].rect;
|
||||
for (i = 1; i < screen->num_monitors; i++)
|
||||
gdk_rectangle_union (&rect, &screen->monitors[i].rect, &rect);
|
||||
monitor_count = gdk_display_get_n_monitors (display);
|
||||
monitor = gdk_display_get_monitor (display, 0);
|
||||
gdk_monitor_get_geometry (monitor, &result);
|
||||
|
||||
screen->root_window->width = rect.width;
|
||||
screen->root_window->height = rect.height;
|
||||
for (i = 1; i < monitor_count; i++)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
|
||||
monitor = gdk_display_get_monitor (display, i);
|
||||
gdk_monitor_get_geometry (monitor, &rect);
|
||||
gdk_rectangle_union (&result, &rect, &result);
|
||||
}
|
||||
|
||||
changed = screen->root_window->width != result.width ||
|
||||
screen->root_window->height != result.height;
|
||||
screen->root_window->width = result.width;
|
||||
screen->root_window->height = result.height;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
init_root_window (GdkWin32Screen *screen_win32)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GdkWindow *window;
|
||||
GdkWindowImplWin32 *impl_win32;
|
||||
gboolean changed;
|
||||
|
||||
screen = GDK_SCREEN (screen_win32);
|
||||
|
||||
@@ -295,7 +304,7 @@ init_root_window (GdkWin32Screen *screen_win32)
|
||||
|
||||
screen_win32->root_window = window;
|
||||
|
||||
init_root_window_size (screen_win32);
|
||||
changed = init_root_window_size (screen_win32);
|
||||
|
||||
window->x = 0;
|
||||
window->y = 0;
|
||||
@@ -307,134 +316,8 @@ init_root_window (GdkWin32Screen *screen_win32)
|
||||
gdk_win32_handle_table_insert ((HANDLE *) &impl_win32->handle, window);
|
||||
|
||||
GDK_NOTE (MISC, g_print ("screen->root_window=%p\n", window));
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
count_monitor (HMONITOR hmonitor,
|
||||
HDC hdc,
|
||||
LPRECT rect,
|
||||
LPARAM data)
|
||||
{
|
||||
gint *n = (gint *) data;
|
||||
|
||||
(*n)++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GdkWin32Screen *screen;
|
||||
gint index;
|
||||
} EnumMonitorData;
|
||||
|
||||
static BOOL CALLBACK
|
||||
enum_monitor (HMONITOR hmonitor,
|
||||
HDC hdc,
|
||||
LPRECT rect,
|
||||
LPARAM param)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
EnumMonitorData *data = (EnumMonitorData *) param;
|
||||
GdkWin32Monitor *monitor;
|
||||
MONITORINFOEXA2 monitor_info;
|
||||
HDC hDC;
|
||||
|
||||
g_assert (data->index < data->screen->num_monitors);
|
||||
|
||||
monitor = data->screen->monitors + data->index;
|
||||
|
||||
monitor_info.cbSize = sizeof (MONITORINFOEXA2);
|
||||
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;
|
||||
monitor->work_rect.x = monitor_info.rcWork.left;
|
||||
monitor->work_rect.y = monitor_info.rcWork.top;
|
||||
monitor->work_rect.width = monitor_info.rcWork.right - monitor_info.rcWork.left;
|
||||
monitor->work_rect.height = monitor_info.rcWork.bottom - monitor_info.rcWork.top;
|
||||
|
||||
if (monitor_info.dwFlags & MONITORINFOF_PRIMARY && data->index != 0)
|
||||
{
|
||||
/* Put primary monitor at index 0, just in case somebody needs
|
||||
* to know which one is the primary.
|
||||
*/
|
||||
GdkWin32Monitor temp = *monitor;
|
||||
*monitor = data->screen->monitors[0];
|
||||
data->screen->monitors[0] = temp;
|
||||
}
|
||||
|
||||
data->index++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_monitors (GdkWin32Screen *screen)
|
||||
{
|
||||
gint count;
|
||||
EnumMonitorData data;
|
||||
gint i;
|
||||
|
||||
count = 0;
|
||||
EnumDisplayMonitors (NULL, NULL, count_monitor, (LPARAM) &count);
|
||||
screen->num_monitors = count;
|
||||
|
||||
screen->monitors = g_renew (GdkWin32Monitor, screen->monitors, screen->num_monitors);
|
||||
|
||||
data.screen = screen;
|
||||
data.index = 0;
|
||||
EnumDisplayMonitors (NULL, NULL, enum_monitor, (LPARAM) &data);
|
||||
|
||||
_gdk_offset_x = G_MININT;
|
||||
_gdk_offset_y = G_MININT;
|
||||
|
||||
/* Calculate offset */
|
||||
for (i = 0; i < screen->num_monitors; i++)
|
||||
{
|
||||
GdkRectangle *rect = &screen->monitors[i].rect;
|
||||
_gdk_offset_x = MAX (_gdk_offset_x, -rect->x);
|
||||
_gdk_offset_y = MAX (_gdk_offset_y, -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 < screen->num_monitors; i++)
|
||||
{
|
||||
GdkRectangle *rect;
|
||||
rect = &screen->monitors[i].rect;
|
||||
rect->x += _gdk_offset_x;
|
||||
rect->y += _gdk_offset_y;
|
||||
rect = &screen->monitors[i].work_rect;
|
||||
rect->x += _gdk_offset_x;
|
||||
rect->y += _gdk_offset_y;
|
||||
GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@%+d%+d\n", i,
|
||||
rect->width, rect->height, rect->x, rect->y));
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -470,7 +353,7 @@ gdk_win32_screen_init (GdkWin32Screen *win32_screen)
|
||||
win32_screen->available_visual_depths[0] = win32_screen->rgba_visual->depth;
|
||||
win32_screen->available_visual_types[0] = win32_screen->rgba_visual->type;
|
||||
|
||||
init_monitors (win32_screen);
|
||||
_gdk_win32_display_init_monitors (GDK_WIN32_DISPLAY (_gdk_display));
|
||||
init_root_window (win32_screen);
|
||||
|
||||
/* On Windows 8 and later, DWM (composition) is always enabled */
|
||||
@@ -480,9 +363,15 @@ gdk_win32_screen_init (GdkWin32Screen *win32_screen)
|
||||
void
|
||||
_gdk_win32_screen_on_displaychange_event (GdkWin32Screen *screen)
|
||||
{
|
||||
init_monitors (screen);
|
||||
init_root_window_size (screen);
|
||||
g_signal_emit_by_name (screen, "size-changed");
|
||||
gboolean monitors_changed;
|
||||
|
||||
monitors_changed = _gdk_win32_display_init_monitors (GDK_WIN32_DISPLAY (_gdk_display));
|
||||
|
||||
if (init_root_window_size (screen))
|
||||
g_signal_emit_by_name (screen, "size-changed");
|
||||
|
||||
if (monitors_changed)
|
||||
g_signal_emit_by_name (screen, "monitors-changed");
|
||||
}
|
||||
|
||||
static GdkDisplay *
|
||||
@@ -521,84 +410,6 @@ gdk_win32_screen_get_root_window (GdkScreen *screen)
|
||||
return GDK_WIN32_SCREEN (screen)->root_window;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_win32_screen_get_n_monitors (GdkScreen *screen)
|
||||
{
|
||||
g_return_val_if_fail (screen == gdk_display_get_default_screen (gdk_display_get_default ()), 0);
|
||||
|
||||
return GDK_WIN32_SCREEN (screen)->num_monitors;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_win32_screen_get_primary_monitor (GdkScreen *screen)
|
||||
{
|
||||
g_return_val_if_fail (screen == gdk_display_get_default_screen (gdk_display_get_default ()), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_win32_screen_get_monitor_width_mm (GdkScreen *screen,
|
||||
gint num_monitor)
|
||||
{
|
||||
GdkWin32Screen *win32_screen = GDK_WIN32_SCREEN (screen);
|
||||
|
||||
g_return_val_if_fail (screen == gdk_display_get_default_screen (gdk_display_get_default ()), 0);
|
||||
g_return_val_if_fail (num_monitor < win32_screen->num_monitors, 0);
|
||||
|
||||
return win32_screen->monitors[num_monitor].width_mm;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_win32_screen_get_monitor_height_mm (GdkScreen *screen,
|
||||
gint num_monitor)
|
||||
{
|
||||
GdkWin32Screen *win32_screen = GDK_WIN32_SCREEN (screen);
|
||||
|
||||
g_return_val_if_fail (screen == gdk_display_get_default_screen (gdk_display_get_default ()), 0);
|
||||
g_return_val_if_fail (num_monitor < win32_screen->num_monitors, 0);
|
||||
|
||||
return win32_screen->monitors[num_monitor].height_mm;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gdk_win32_screen_get_monitor_plug_name (GdkScreen *screen,
|
||||
gint num_monitor)
|
||||
{
|
||||
GdkWin32Screen *win32_screen = GDK_WIN32_SCREEN (screen);
|
||||
|
||||
g_return_val_if_fail (screen == gdk_display_get_default_screen (gdk_display_get_default ()), NULL);
|
||||
g_return_val_if_fail (num_monitor < win32_screen->num_monitors, NULL);
|
||||
|
||||
return g_strdup (win32_screen->monitors[num_monitor].name);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_screen_get_monitor_geometry (GdkScreen *screen,
|
||||
gint num_monitor,
|
||||
GdkRectangle *dest)
|
||||
{
|
||||
GdkWin32Screen *win32_screen = GDK_WIN32_SCREEN (screen);
|
||||
|
||||
g_return_if_fail (screen == gdk_display_get_default_screen (gdk_display_get_default ()));
|
||||
g_return_if_fail (num_monitor < win32_screen->num_monitors);
|
||||
|
||||
*dest = win32_screen->monitors[num_monitor].rect;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_screen_get_monitor_workarea (GdkScreen *screen,
|
||||
gint num_monitor,
|
||||
GdkRectangle *dest)
|
||||
{
|
||||
GdkWin32Screen *win32_screen = GDK_WIN32_SCREEN (screen);
|
||||
|
||||
g_return_if_fail (screen == gdk_display_get_default_screen (gdk_display_get_default ()));
|
||||
g_return_if_fail (num_monitor < win32_screen->num_monitors);
|
||||
|
||||
*dest = win32_screen->monitors[num_monitor].work_rect;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_win32_screen_get_number (GdkScreen *screen)
|
||||
{
|
||||
@@ -750,13 +561,6 @@ gdk_win32_screen_list_visuals (GdkScreen *screen)
|
||||
static void
|
||||
gdk_win32_screen_finalize (GObject *object)
|
||||
{
|
||||
GdkWin32Screen *screen = GDK_WIN32_SCREEN (object);
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < screen->num_monitors; i++)
|
||||
g_free (screen->monitors[i].name);
|
||||
g_free (screen->monitors);
|
||||
|
||||
G_OBJECT_CLASS (gdk_win32_screen_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -775,13 +579,6 @@ gdk_win32_screen_class_init (GdkWin32ScreenClass *klass)
|
||||
screen_class->get_height_mm = gdk_win32_screen_get_height_mm;
|
||||
screen_class->get_number = gdk_win32_screen_get_number;
|
||||
screen_class->get_root_window = gdk_win32_screen_get_root_window;
|
||||
screen_class->get_n_monitors = gdk_win32_screen_get_n_monitors;
|
||||
screen_class->get_primary_monitor = gdk_win32_screen_get_primary_monitor;
|
||||
screen_class->get_monitor_width_mm = gdk_win32_screen_get_monitor_width_mm;
|
||||
screen_class->get_monitor_height_mm = gdk_win32_screen_get_monitor_height_mm;
|
||||
screen_class->get_monitor_plug_name = gdk_win32_screen_get_monitor_plug_name;
|
||||
screen_class->get_monitor_geometry = gdk_win32_screen_get_monitor_geometry;
|
||||
screen_class->get_monitor_workarea = gdk_win32_screen_get_monitor_workarea;
|
||||
screen_class->is_composited = gdk_win32_screen_is_composited;
|
||||
screen_class->make_display_name = gdk_win32_screen_make_display_name;
|
||||
screen_class->get_active_window = gdk_win32_screen_get_active_window;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <gdk/win32/gdkwin32screen.h>
|
||||
#include <gdk/win32/gdkwin32window.h>
|
||||
#include <gdk/win32/gdkwin32misc.h>
|
||||
#include <gdk/win32/gdkwin32monitor.h>
|
||||
#include <gdk/win32/gdkwin32glcontext.h>
|
||||
|
||||
#undef __GDKWIN32_H_INSIDE__
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* gdkwin32monitor.h
|
||||
*
|
||||
* Copyright 2016 Red Hat, Inc.
|
||||
*
|
||||
* Matthias Clasen <mclasen@redhat.com>
|
||||
* Руслан Ижбулатов <lrn1986@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_WIN32_MONITOR_H__
|
||||
#define __GDK_WIN32_MONITOR_H__
|
||||
|
||||
#if !defined (__GDKWIN32_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdkwin32.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkmonitor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_WIN32_MONITOR (gdk_win32_monitor_get_type ())
|
||||
#define GDK_WIN32_MONITOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WIN32_MONITOR, GdkWin32Monitor))
|
||||
#define GDK_IS_WIN32_MONITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WIN32_MONITOR))
|
||||
|
||||
#ifdef GDK_COMPILATION
|
||||
typedef struct _GdkWin32Monitor GdkWin32Monitor;
|
||||
#else
|
||||
typedef GdkMonitor GdkWin32Monitor;
|
||||
#endif
|
||||
typedef struct _GdkWin32MonitorClass GdkWin32MonitorClass;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gdk_win32_monitor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_WIN32_MONITOR_H__ */
|
||||
@@ -43,6 +43,8 @@ libgdk_x11_la_SOURCES = \
|
||||
gdkglcontext-x11.h \
|
||||
gdkkeys-x11.c \
|
||||
gdkmain-x11.c \
|
||||
gdkmonitor-x11.c \
|
||||
gdkmonitor-x11.h \
|
||||
gdkproperty-x11.c \
|
||||
gdkscreen-x11.c \
|
||||
gdkscreen-x11.h \
|
||||
@@ -76,6 +78,7 @@ libgdkx11include_HEADERS = \
|
||||
gdkx11dnd.h \
|
||||
gdkx11glcontext.h \
|
||||
gdkx11keys.h \
|
||||
gdkx11monitor.h \
|
||||
gdkx11property.h \
|
||||
gdkx11screen.h \
|
||||
gdkx11selection.h \
|
||||
|
||||
@@ -180,6 +180,7 @@ G_DEFINE_TYPE_WITH_CODE (GdkX11Display, gdk_x11_display, GDK_TYPE_DISPLAY,
|
||||
static void
|
||||
gdk_x11_display_init (GdkX11Display *display)
|
||||
{
|
||||
display->monitors = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1903,6 +1904,8 @@ gdk_x11_display_finalize (GObject *object)
|
||||
g_object_unref (display_x11->screen);
|
||||
g_list_free_full (display_x11->screens, g_object_unref);
|
||||
|
||||
g_ptr_array_free (display_x11->monitors, TRUE);
|
||||
|
||||
g_free (display_x11->startup_notification_id);
|
||||
|
||||
/* X ID hashtable */
|
||||
@@ -2903,6 +2906,38 @@ gdk_x11_display_get_default_seat (GdkDisplay *display)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_x11_display_get_n_monitors (GdkDisplay *display)
|
||||
{
|
||||
GdkX11Display *x11_display = GDK_X11_DISPLAY (display);
|
||||
|
||||
return x11_display->monitors->len;
|
||||
}
|
||||
|
||||
|
||||
static GdkMonitor *
|
||||
gdk_x11_display_get_monitor (GdkDisplay *display,
|
||||
int monitor_num)
|
||||
{
|
||||
GdkX11Display *x11_display = GDK_X11_DISPLAY (display);
|
||||
|
||||
if (0 <= monitor_num || monitor_num < x11_display->monitors->len)
|
||||
return (GdkMonitor *)x11_display->monitors->pdata[monitor_num];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkMonitor *
|
||||
gdk_x11_display_get_primary_monitor (GdkDisplay *display)
|
||||
{
|
||||
GdkX11Display *x11_display = GDK_X11_DISPLAY (display);
|
||||
|
||||
if (0 <= x11_display->primary_monitor && x11_display->primary_monitor < x11_display->monitors->len)
|
||||
return x11_display->monitors->pdata[x11_display->primary_monitor];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
{
|
||||
@@ -2959,5 +2994,9 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
|
||||
display_class->get_default_seat = gdk_x11_display_get_default_seat;
|
||||
|
||||
display_class->get_n_monitors = gdk_x11_display_get_n_monitors;
|
||||
display_class->get_monitor = gdk_x11_display_get_monitor;
|
||||
display_class->get_primary_monitor = gdk_x11_display_get_primary_monitor;
|
||||
|
||||
_gdk_x11_windowing_init ();
|
||||
}
|
||||
|
||||
@@ -100,6 +100,9 @@ struct _GdkX11Display
|
||||
/* input GdkWindow list */
|
||||
GList *input_windows;
|
||||
|
||||
GPtrArray *monitors;
|
||||
int primary_monitor;
|
||||
|
||||
/* Startup notification */
|
||||
gchar *startup_notification_id;
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gdkmonitor-x11.h"
|
||||
#include "gdkscreen-x11.h"
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkX11Monitor, gdk_x11_monitor, GDK_TYPE_MONITOR)
|
||||
|
||||
static gboolean
|
||||
gdk_monitor_has_fullscreen_window (GdkMonitor *monitor)
|
||||
{
|
||||
GdkScreen *screen = gdk_display_get_default_screen (monitor->display);
|
||||
GList *toplevels, *l;
|
||||
GdkWindow *window;
|
||||
gboolean has_fullscreen;
|
||||
|
||||
toplevels = gdk_screen_get_toplevel_windows (screen);
|
||||
|
||||
has_fullscreen = FALSE;
|
||||
for (l = toplevels; l; l = l->next)
|
||||
{
|
||||
window = l->data;
|
||||
|
||||
if ((gdk_window_get_state (window) & GDK_WINDOW_STATE_FULLSCREEN) == 0)
|
||||
continue;
|
||||
|
||||
if (gdk_window_get_fullscreen_mode (window) == GDK_FULLSCREEN_ON_ALL_MONITORS ||
|
||||
gdk_display_get_monitor_at_window (monitor->display, window) == monitor)
|
||||
{
|
||||
has_fullscreen = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (toplevels);
|
||||
|
||||
return has_fullscreen;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_monitor_get_workarea (GdkMonitor *monitor,
|
||||
GdkRectangle *dest)
|
||||
{
|
||||
GdkScreen *screen = gdk_display_get_default_screen (monitor->display);
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_monitor_get_geometry (monitor, dest);
|
||||
|
||||
/* The EWMH constrains workarea to be a rectangle, so it
|
||||
* can't adequately deal with L-shaped monitor arrangements.
|
||||
* As a workaround, we ignore the workarea for anything
|
||||
* but the primary monitor. Since that is where the 'desktop
|
||||
* chrome' usually lives, this works ok in practice.
|
||||
*/
|
||||
if (gdk_monitor_is_primary (monitor) &&
|
||||
!gdk_monitor_has_fullscreen_window (monitor))
|
||||
{
|
||||
gdk_x11_screen_get_work_area (screen, &workarea);
|
||||
if (gdk_rectangle_intersect (dest, &workarea, &workarea))
|
||||
*dest = workarea;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_monitor_init (GdkX11Monitor *monitor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_monitor_class_init (GdkX11MonitorClass *class)
|
||||
{
|
||||
GDK_MONITOR_CLASS (class)->get_workarea = gdk_x11_monitor_get_workarea;
|
||||
}
|
||||
|
||||
XID
|
||||
gdk_x11_monitor_get_output (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_X11_MONITOR (monitor), 0);
|
||||
|
||||
return GDK_X11_MONITOR (monitor)->output;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_X11_MONITOR_PRIVATE_H__
|
||||
#define __GDK_X11_MONITOR_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
|
||||
#include "gdkx11monitor.h"
|
||||
|
||||
|
||||
struct _GdkX11Monitor
|
||||
{
|
||||
GdkMonitor parent;
|
||||
|
||||
XID output;
|
||||
guint add : 1;
|
||||
guint remove : 1;
|
||||
};
|
||||
|
||||
struct _GdkX11MonitorClass {
|
||||
GdkMonitorClass parent_class;
|
||||
};
|
||||
|
||||
#endif
|
||||
+384
-680
File diff suppressed because it is too large
Load Diff
@@ -42,10 +42,6 @@ struct _GdkX11Screen
|
||||
Window xroot_window;
|
||||
GdkWindow *root_window;
|
||||
gint screen_num;
|
||||
/* Xinerama/RandR 1.2 */
|
||||
gint n_monitors;
|
||||
GdkX11Monitor *monitors;
|
||||
gint primary_monitor;
|
||||
|
||||
gint width;
|
||||
gint height;
|
||||
@@ -96,9 +92,6 @@ struct _GdkX11Screen
|
||||
|
||||
/* cache for window->translate vfunc */
|
||||
GC subwindow_gcs[32];
|
||||
|
||||
/* cache for Xinerama monitor indices */
|
||||
GHashTable *xinerama_matches;
|
||||
};
|
||||
|
||||
struct _GdkX11ScreenClass
|
||||
@@ -119,8 +112,6 @@ void _gdk_x11_screen_size_changed (GdkScreen *screen,
|
||||
XEvent *event);
|
||||
void _gdk_x11_screen_process_owner_change (GdkScreen *screen,
|
||||
XEvent *event);
|
||||
gint _gdk_x11_screen_get_xinerama_index (GdkScreen *screen,
|
||||
gint monitor_num);
|
||||
void _gdk_x11_screen_get_edge_monitors (GdkScreen *screen,
|
||||
gint *top,
|
||||
gint *bottom,
|
||||
@@ -128,6 +119,8 @@ void _gdk_x11_screen_get_edge_monitors (GdkScreen *screen,
|
||||
gint *right);
|
||||
void _gdk_x11_screen_set_window_scale (GdkX11Screen *x11_screen,
|
||||
int scale);
|
||||
void gdk_x11_screen_get_work_area (GdkScreen *screen,
|
||||
GdkRectangle *area);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -4167,7 +4167,7 @@ gdk_x11_window_apply_fullscreen_mode (GdkWindow *window)
|
||||
if (GDK_WINDOW_IS_MAPPED (window))
|
||||
{
|
||||
XClientMessageEvent xclient;
|
||||
gint gdk_monitors[4];
|
||||
gint monitors[4];
|
||||
gint i;
|
||||
|
||||
memset (&xclient, 0, sizeof (xclient));
|
||||
@@ -4208,15 +4208,14 @@ gdk_x11_window_apply_fullscreen_mode (GdkWindow *window)
|
||||
case GDK_FULLSCREEN_ON_ALL_MONITORS:
|
||||
|
||||
_gdk_x11_screen_get_edge_monitors (GDK_WINDOW_SCREEN (window),
|
||||
&gdk_monitors[0],
|
||||
&gdk_monitors[1],
|
||||
&gdk_monitors[2],
|
||||
&gdk_monitors[3]);
|
||||
&monitors[0],
|
||||
&monitors[1],
|
||||
&monitors[2],
|
||||
&monitors[3]);
|
||||
/* Translate all 4 monitors from the GDK set into XINERAMA indices */
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
xclient.data.l[i] = _gdk_x11_screen_get_xinerama_index (GDK_WINDOW_SCREEN (window),
|
||||
gdk_monitors[i]);
|
||||
xclient.data.l[i] = monitors[i];
|
||||
/* Sanity check, if XINERAMA is not available, we could have invalid
|
||||
* negative values for the XINERAMA indices.
|
||||
*/
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <gdk/x11/gdkx11dnd.h>
|
||||
#include <gdk/x11/gdkx11glcontext.h>
|
||||
#include <gdk/x11/gdkx11keys.h>
|
||||
#include <gdk/x11/gdkx11monitor.h>
|
||||
#include <gdk/x11/gdkx11property.h>
|
||||
#include <gdk/x11/gdkx11screen.h>
|
||||
#include <gdk/x11/gdkx11selection.h>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* gdkx11monitor.h
|
||||
*
|
||||
* Copyright 2016 Red Hat, Inc.
|
||||
*
|
||||
* Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_X11_MONITOR_H__
|
||||
#define __GDK_X11_MONITOR_H__
|
||||
|
||||
#if !defined (__GDKX_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdkx.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkmonitor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_X11_MONITOR (gdk_x11_monitor_get_type ())
|
||||
#define GDK_X11_MONITOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_X11_MONITOR, GdkX11Monitor))
|
||||
#define GDK_IS_X11_MONITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_X11_MONITOR))
|
||||
|
||||
typedef struct _GdkX11Monitor GdkX11Monitor;
|
||||
typedef struct _GdkX11MonitorClass GdkX11MonitorClass;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gdk_x11_monitor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
XID gdk_x11_monitor_get_output (GdkMonitor *monitor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_X11_MONITOR_H__ */
|
||||
+41
-39
@@ -1934,9 +1934,9 @@ gtk_combo_box_menu_position_below (GtkMenu *menu,
|
||||
gint sx, sy;
|
||||
GtkWidget *child;
|
||||
GtkRequisition req;
|
||||
GdkScreen *screen;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle area;
|
||||
|
||||
/* FIXME: is using the size request here broken? */
|
||||
child = gtk_bin_get_child (GTK_BIN (combo_box));
|
||||
@@ -1953,8 +1953,7 @@ gtk_combo_box_menu_position_below (GtkMenu *menu,
|
||||
sy += child_allocation.y;
|
||||
}
|
||||
|
||||
gdk_window_get_root_coords (gtk_widget_get_window (child),
|
||||
sx, sy, &sx, &sy);
|
||||
gdk_window_get_root_coords (gtk_widget_get_window (child), sx, sy, &sx, &sy);
|
||||
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (combo_box)) == GTK_TEXT_DIR_RTL)
|
||||
sx += (content_allocation.x - border_allocation.x);
|
||||
@@ -1972,21 +1971,20 @@ gtk_combo_box_menu_position_below (GtkMenu *menu,
|
||||
*x = sx + child_allocation.width - req.width;
|
||||
*y = sy;
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (combo_box));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
||||
gtk_widget_get_window (GTK_WIDGET (combo_box)));
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (GTK_WIDGET (combo_box));
|
||||
monitor = gdk_display_get_monitor_at_window (display, gtk_widget_get_window (GTK_WIDGET (combo_box)));
|
||||
gdk_monitor_get_workarea (monitor, &area);
|
||||
|
||||
if (*x < monitor.x)
|
||||
*x = monitor.x;
|
||||
else if (*x + req.width > monitor.x + monitor.width)
|
||||
*x = monitor.x + monitor.width - req.width;
|
||||
if (*x < area.x)
|
||||
*x = area.x;
|
||||
else if (*x + req.width > area.x + area.width)
|
||||
*x = area.x + area.width - req.width;
|
||||
|
||||
if (monitor.y + monitor.height - *y - child_allocation.height >= req.height)
|
||||
if (area.y + area.height - *y - child_allocation.height >= req.height)
|
||||
*y += child_allocation.height;
|
||||
else if (*y - monitor.y >= req.height)
|
||||
else if (*y - area.y >= req.height)
|
||||
*y -= req.height;
|
||||
else if (monitor.y + monitor.height - *y - child_allocation.height > *y - monitor.y)
|
||||
else if (area.y + area.height - *y - child_allocation.height > *y - area.y)
|
||||
*y += child_allocation.height;
|
||||
else
|
||||
*y -= req.height;
|
||||
@@ -2009,10 +2007,12 @@ gtk_combo_box_menu_position_over (GtkMenu *menu,
|
||||
GtkAllocation content_allocation;
|
||||
GtkAllocation child_allocation;
|
||||
GList *children;
|
||||
gint screen_width;
|
||||
gint menu_xpos;
|
||||
gint menu_ypos;
|
||||
gint menu_width;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
|
||||
active = gtk_menu_get_active (GTK_MENU (priv->popup_widget));
|
||||
|
||||
@@ -2058,12 +2058,14 @@ gtk_combo_box_menu_position_over (GtkMenu *menu,
|
||||
&menu_xpos, &menu_ypos);
|
||||
|
||||
/* Clamp the position on screen */
|
||||
screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget));
|
||||
|
||||
if (menu_xpos < 0)
|
||||
menu_xpos = 0;
|
||||
else if ((menu_xpos + menu_width) > screen_width)
|
||||
menu_xpos -= ((menu_xpos + menu_width) - screen_width);
|
||||
display = gtk_widget_get_display (widget);
|
||||
monitor = gdk_display_get_monitor_at_window (display, gtk_widget_get_window (widget));
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
if (menu_xpos < workarea.x)
|
||||
menu_xpos = workarea.x;
|
||||
else if ((menu_xpos + menu_width) > workarea.x + workarea.width)
|
||||
menu_xpos -= (menu_xpos + menu_width) - (workarea.x + workarea.width);
|
||||
|
||||
*x = menu_xpos;
|
||||
*y = menu_ypos;
|
||||
@@ -2109,9 +2111,9 @@ gtk_combo_box_list_position (GtkComboBox *combo_box,
|
||||
{
|
||||
GtkComboBoxPrivate *priv = combo_box->priv;
|
||||
GtkAllocation content_allocation;
|
||||
GdkScreen *screen;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle area;
|
||||
GtkRequisition popup_req;
|
||||
GtkPolicyType hpolicy, vpolicy;
|
||||
GdkWindow *window;
|
||||
@@ -2162,31 +2164,31 @@ gtk_combo_box_list_position (GtkComboBox *combo_box,
|
||||
|
||||
*height = popup_req.height;
|
||||
|
||||
screen = gtk_widget_get_screen (widget);
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (widget);
|
||||
monitor = gdk_display_get_monitor_at_window (display, window);
|
||||
gdk_monitor_get_workarea (monitor, &area);
|
||||
|
||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
|
||||
*x = *x + content_allocation.width - *width;
|
||||
|
||||
if (*x < monitor.x)
|
||||
*x = monitor.x;
|
||||
else if (*x + *width > monitor.x + monitor.width)
|
||||
*x = monitor.x + monitor.width - *width;
|
||||
if (*x < area.x)
|
||||
*x = area.x;
|
||||
else if (*x + *width > area.x + area.width)
|
||||
*x = area.x + area.width - *width;
|
||||
|
||||
if (*y + content_allocation.height + *height <= monitor.y + monitor.height)
|
||||
if (*y + content_allocation.height + *height <= area.y + area.height)
|
||||
*y += content_allocation.height;
|
||||
else if (*y - *height >= monitor.y)
|
||||
else if (*y - *height >= area.y)
|
||||
*y -= *height;
|
||||
else if (monitor.y + monitor.height - (*y + content_allocation.height) > *y - monitor.y)
|
||||
else if (area.y + area.height - (*y + content_allocation.height) > *y - area.y)
|
||||
{
|
||||
*y += content_allocation.height;
|
||||
*height = monitor.y + monitor.height - *y;
|
||||
*height = area.y + area.height - *y;
|
||||
}
|
||||
else
|
||||
{
|
||||
*height = *y - monitor.y;
|
||||
*y = monitor.y;
|
||||
*height = *y - area.y;
|
||||
*y = area.y;
|
||||
}
|
||||
|
||||
if (popup_req.height > *height)
|
||||
|
||||
+13
-16
@@ -9415,24 +9415,21 @@ popup_position_func (GtkMenu *menu,
|
||||
GtkEntry *entry = GTK_ENTRY (user_data);
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
GdkScreen *screen;
|
||||
GdkDisplay *display;
|
||||
GtkRequisition menu_req;
|
||||
GdkRectangle monitor;
|
||||
gint monitor_num, strong_x, height;
|
||||
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle area;
|
||||
gint strong_x, height;
|
||||
|
||||
g_return_if_fail (gtk_widget_get_realized (widget));
|
||||
|
||||
gdk_window_get_origin (priv->text_area, x, y);
|
||||
|
||||
screen = gtk_widget_get_screen (widget);
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen, priv->text_area);
|
||||
if (monitor_num < 0)
|
||||
monitor_num = 0;
|
||||
gtk_menu_set_monitor (menu, monitor_num);
|
||||
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
gtk_widget_get_preferred_size (priv->popup_menu,
|
||||
&menu_req, NULL);
|
||||
display = gtk_widget_get_display (widget);
|
||||
monitor = gdk_display_get_monitor_at_window (display, priv->text_area);
|
||||
gtk_menu_place_on_monitor (menu, monitor);
|
||||
gdk_monitor_get_workarea (monitor, &area);
|
||||
gtk_widget_get_preferred_size (priv->popup_menu, &menu_req, NULL);
|
||||
height = gdk_window_get_height (priv->text_area);
|
||||
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL);
|
||||
|
||||
@@ -9440,11 +9437,11 @@ popup_position_func (GtkMenu *menu,
|
||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
|
||||
*x -= menu_req.width;
|
||||
|
||||
if ((*y + height + menu_req.height) <= monitor.y + monitor.height)
|
||||
if ((*y + height + menu_req.height) <= area.y + area.height)
|
||||
*y += height;
|
||||
else if ((*y - menu_req.height) >= monitor.y)
|
||||
else if ((*y - menu_req.height) >= area.y)
|
||||
*y -= menu_req.height;
|
||||
else if (monitor.y + monitor.height - (*y + height) > *y)
|
||||
else if (area.y + area.height - (*y + height) > *y)
|
||||
*y += height;
|
||||
else
|
||||
*y -= menu_req.height;
|
||||
|
||||
+16
-16
@@ -1494,10 +1494,10 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
|
||||
GtkAllocation allocation;
|
||||
gint x, y;
|
||||
gint matches, actions, items, height;
|
||||
GdkScreen *screen;
|
||||
gint monitor_num;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
gint vertical_separator;
|
||||
GdkRectangle monitor;
|
||||
GdkRectangle area;
|
||||
GdkWindow *window;
|
||||
GtkRequisition popup_req;
|
||||
GtkRequisition entry_req;
|
||||
@@ -1546,16 +1546,16 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
|
||||
|
||||
gtk_widget_realize (completion->priv->tree_view);
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (completion->priv->entry));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (GTK_WIDGET (completion->priv->entry));
|
||||
monitor = gdk_display_get_monitor_at_window (display, window);
|
||||
gdk_monitor_get_workarea (monitor, &area);
|
||||
|
||||
if (height == 0)
|
||||
items = 0;
|
||||
else if (y > monitor.height / 2)
|
||||
items = MIN (matches, (((monitor.y + y) - (actions * action_height)) / height) - 1);
|
||||
else if (y > area.height / 2)
|
||||
items = MIN (matches, (((area.y + y) - (actions * action_height)) / height) - 1);
|
||||
else
|
||||
items = MIN (matches, (((monitor.height - y) - (actions * action_height)) / height) - 1);
|
||||
items = MIN (matches, (((area.height - y) - (actions * action_height)) / height) - 1);
|
||||
|
||||
if (items <= 0)
|
||||
gtk_widget_hide (completion->priv->scrolled_window);
|
||||
@@ -1563,7 +1563,7 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
|
||||
gtk_widget_show (completion->priv->scrolled_window);
|
||||
|
||||
if (completion->priv->popup_set_width)
|
||||
width = MIN (allocation.width, monitor.width);
|
||||
width = MIN (allocation.width, area.width);
|
||||
else
|
||||
width = -1;
|
||||
|
||||
@@ -1580,13 +1580,13 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
|
||||
gtk_widget_get_preferred_size (completion->priv->popup_window,
|
||||
&popup_req, NULL);
|
||||
|
||||
if (x < monitor.x)
|
||||
x = monitor.x;
|
||||
else if (x + popup_req.width > monitor.x + monitor.width)
|
||||
x = monitor.x + monitor.width - popup_req.width;
|
||||
if (x < area.x)
|
||||
x = area.x;
|
||||
else if (x + popup_req.width > area.x + area.width)
|
||||
x = area.x + area.width - popup_req.width;
|
||||
|
||||
if (y + entry_req.height + popup_req.height <= monitor.y + monitor.height ||
|
||||
y - monitor.y < (monitor.y + monitor.height) - (y + entry_req.height))
|
||||
if (y + entry_req.height + popup_req.height <= area.y + area.height ||
|
||||
y - area.y < (area.y + area.height) - (y + entry_req.height))
|
||||
{
|
||||
y += entry_req.height;
|
||||
above = FALSE;
|
||||
|
||||
+11
-7
@@ -6571,31 +6571,35 @@ popup_position_func (GtkMenu *menu,
|
||||
GtkWidget *widget;
|
||||
GtkAllocation allocation;
|
||||
GtkRequisition req;
|
||||
GdkScreen *screen;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
|
||||
label = GTK_LABEL (user_data);
|
||||
widget = GTK_WIDGET (label);
|
||||
|
||||
g_return_if_fail (gtk_widget_get_realized (widget));
|
||||
|
||||
screen = gtk_widget_get_screen (widget);
|
||||
gdk_window_get_origin (gtk_widget_get_window (widget), x, y);
|
||||
display = gtk_widget_get_display (widget);
|
||||
monitor = gdk_display_get_monitor_at_window (display,
|
||||
gtk_widget_get_window (widget));
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
gdk_window_get_origin (gtk_widget_get_window (widget), x, y);
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
*x += allocation.x;
|
||||
*y += allocation.y;
|
||||
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (menu),
|
||||
&req, NULL);
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
*x += allocation.width / 2;
|
||||
*y += allocation.height;
|
||||
|
||||
*x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width));
|
||||
*y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height));
|
||||
*x = CLAMP (*x, 0, MAX (0, workarea.width - req.width));
|
||||
*y = CLAMP (*y, 0, MAX (0, workarea.height - req.height));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+10
-9
@@ -346,11 +346,11 @@ popup_position_func (GtkMenu *menu,
|
||||
GtkLinkButtonPrivate *priv = link_button->priv;
|
||||
GtkAllocation allocation;
|
||||
GtkWidget *widget = GTK_WIDGET (link_button);
|
||||
GdkScreen *screen = gtk_widget_get_screen (widget);
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GtkRequisition req;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
|
||||
GdkRectangle area;
|
||||
|
||||
g_return_if_fail (gtk_widget_get_realized (widget));
|
||||
|
||||
gdk_window_get_origin (gtk_widget_get_window (widget), x, y);
|
||||
@@ -361,12 +361,13 @@ popup_position_func (GtkMenu *menu,
|
||||
*x += allocation.width / 2;
|
||||
*y += allocation.height;
|
||||
|
||||
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
|
||||
gtk_menu_set_monitor (menu, monitor_num);
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (widget);
|
||||
monitor = gdk_display_get_monitor_at_point (display, *x, *y);
|
||||
gtk_menu_place_on_monitor (menu, monitor);
|
||||
gdk_monitor_get_workarea (monitor, &area);
|
||||
|
||||
*x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
|
||||
*y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
|
||||
*x = CLAMP (*x, area.x, area.x + MAX (0, area.width - req.width));
|
||||
*y = CLAMP (*y, area.y, area.y + MAX (0, area.height - req.height));
|
||||
|
||||
*push_in = FALSE;
|
||||
}
|
||||
|
||||
+86
-49
@@ -3203,24 +3203,27 @@ gtk_menu_get_preferred_height_for_width (GtkWidget *widget,
|
||||
|
||||
if (priv->have_position)
|
||||
{
|
||||
GdkScreen *screen = gtk_widget_get_screen (priv->toplevel);
|
||||
GdkRectangle monitor;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
GtkBorder border;
|
||||
|
||||
gdk_screen_get_monitor_workarea (screen, priv->monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (priv->toplevel);
|
||||
monitor = gdk_display_get_monitor (display, priv->monitor_num);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
if (priv->position_y + min_height > monitor.y + monitor.height)
|
||||
min_height = monitor.y + monitor.height - priv->position_y;
|
||||
if (priv->position_y + min_height > workarea.y + workarea.height)
|
||||
min_height = workarea.y + workarea.height - priv->position_y;
|
||||
|
||||
if (priv->position_y + nat_height > monitor.y + monitor.height)
|
||||
nat_height = monitor.y + monitor.height - priv->position_y;
|
||||
if (priv->position_y + nat_height > workarea.y + workarea.height)
|
||||
nat_height = workarea.y + workarea.height - priv->position_y;
|
||||
|
||||
_gtk_window_get_shadow_width (GTK_WINDOW (priv->toplevel), &border);
|
||||
|
||||
if (priv->position_y + border.top < monitor.y)
|
||||
if (priv->position_y + border.top < workarea.y)
|
||||
{
|
||||
min_height -= monitor.y - (priv->position_y + border.top);
|
||||
nat_height -= monitor.y - (priv->position_y + border.top);
|
||||
min_height -= workarea.y - (priv->position_y + border.top);
|
||||
nat_height -= workarea.y - (priv->position_y + border.top);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4270,17 +4273,19 @@ gtk_menu_position (GtkMenu *menu,
|
||||
GtkRequisition requisition;
|
||||
gint x, y;
|
||||
gint scroll_offset;
|
||||
GdkScreen *screen;
|
||||
GdkScreen *pointer_screen;
|
||||
GdkRectangle monitor;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
gint monitor_num;
|
||||
GdkDevice *pointer;
|
||||
GtkBorder border;
|
||||
gint i;
|
||||
|
||||
widget = GTK_WIDGET (menu);
|
||||
|
||||
screen = gtk_widget_get_screen (widget);
|
||||
display = gtk_widget_get_display (widget);
|
||||
pointer = _gtk_menu_shell_get_grab_device (GTK_MENU_SHELL (menu));
|
||||
gdk_device_get_position (pointer, &pointer_screen, &x, &y);
|
||||
gdk_device_get_position (pointer, NULL, &x, &y);
|
||||
|
||||
/* Realize so we have the proper width and height to figure out
|
||||
* the right place to popup the menu.
|
||||
@@ -4292,18 +4297,22 @@ gtk_menu_position (GtkMenu *menu,
|
||||
requisition.width = gtk_widget_get_allocated_width (widget);
|
||||
requisition.height = gtk_widget_get_allocated_height (widget);
|
||||
|
||||
if (pointer_screen != screen)
|
||||
monitor = gdk_display_get_monitor_at_point (display, x, y);
|
||||
monitor_num = 0;
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
/* Pointer is on a different screen; roughly center the
|
||||
* menu on the screen. If someone was using multiscreen
|
||||
* + Xinerama together they'd probably want something
|
||||
* fancier; but that is likely to be vanishingly rare.
|
||||
*/
|
||||
x = MAX (0, (gdk_screen_get_width (screen) - requisition.width) / 2);
|
||||
y = MAX (0, (gdk_screen_get_height (screen) - requisition.height) / 2);
|
||||
GdkMonitor *m = gdk_display_get_monitor (display, i);
|
||||
|
||||
if (m == monitor)
|
||||
{
|
||||
monitor_num = i;
|
||||
break;
|
||||
}
|
||||
if (m == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
priv->monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
|
||||
priv->monitor_num = monitor_num;
|
||||
priv->initially_pushed_in = FALSE;
|
||||
|
||||
/* Set the type hint here to allow custom position functions
|
||||
@@ -4318,9 +4327,10 @@ gtk_menu_position (GtkMenu *menu,
|
||||
priv->position_func_data);
|
||||
|
||||
if (priv->monitor_num < 0)
|
||||
priv->monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
|
||||
priv->monitor_num = monitor_num;
|
||||
|
||||
gdk_screen_get_monitor_workarea (screen, priv->monitor_num, &monitor);
|
||||
monitor = gdk_display_get_monitor (display, priv->monitor_num);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4352,12 +4362,13 @@ gtk_menu_position (GtkMenu *menu,
|
||||
* Positioning in the vertical direction is similar: first try below
|
||||
* mouse cursor, then above.
|
||||
*/
|
||||
gdk_screen_get_monitor_workarea (screen, priv->monitor_num, &monitor);
|
||||
monitor = gdk_display_get_monitor (display, priv->monitor_num);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
space_left = x - monitor.x;
|
||||
space_right = monitor.x + monitor.width - x - 1;
|
||||
space_above = y - monitor.y;
|
||||
space_below = monitor.y + monitor.height - y - 1;
|
||||
space_left = x - workarea.x;
|
||||
space_right = workarea.x + workarea.width - x - 1;
|
||||
space_above = y - workarea.y;
|
||||
space_below = workarea.y + workarea.height - y - 1;
|
||||
|
||||
/* Position horizontally. */
|
||||
|
||||
@@ -4383,7 +4394,7 @@ gtk_menu_position (GtkMenu *menu,
|
||||
|
||||
/* x is clamped on-screen further down */
|
||||
}
|
||||
else if (requisition.width <= monitor.width)
|
||||
else if (requisition.width <= workarea.width)
|
||||
{
|
||||
/* the menu is too big to fit on either side of the mouse
|
||||
* cursor, but smaller than the monitor. Position it on
|
||||
@@ -4392,12 +4403,12 @@ gtk_menu_position (GtkMenu *menu,
|
||||
if (space_left > space_right)
|
||||
{
|
||||
/* left justify */
|
||||
x = monitor.x;
|
||||
x = workarea.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* right justify */
|
||||
x = monitor.x + monitor.width - requisition.width;
|
||||
x = workarea.x + workarea.width - requisition.width;
|
||||
}
|
||||
}
|
||||
else /* menu is simply too big for the monitor */
|
||||
@@ -4405,12 +4416,12 @@ gtk_menu_position (GtkMenu *menu,
|
||||
if (rtl)
|
||||
{
|
||||
/* right justify */
|
||||
x = monitor.x + monitor.width - requisition.width;
|
||||
x = workarea.x + workarea.width - requisition.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* left justify */
|
||||
x = monitor.x;
|
||||
x = workarea.x;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4428,39 +4439,39 @@ gtk_menu_position (GtkMenu *menu,
|
||||
else
|
||||
y = y - margin.bottom + padding.bottom - requisition.height + 1;
|
||||
|
||||
y = CLAMP (y, monitor.y,
|
||||
monitor.y + monitor.height - requisition.height);
|
||||
y = CLAMP (y, workarea.y,
|
||||
workarea.y + workarea.height - requisition.height);
|
||||
}
|
||||
else if (needed_height > space_below && needed_height > space_above)
|
||||
{
|
||||
if (space_below >= space_above)
|
||||
y = monitor.y + monitor.height - requisition.height;
|
||||
y = workarea.y + workarea.height - requisition.height;
|
||||
else
|
||||
y = monitor.y;
|
||||
y = workarea.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = monitor.y;
|
||||
y = workarea.y;
|
||||
}
|
||||
}
|
||||
|
||||
scroll_offset = 0;
|
||||
|
||||
if (y + requisition.height > monitor.y + monitor.height)
|
||||
if (y + requisition.height > workarea.y + workarea.height)
|
||||
{
|
||||
if (priv->initially_pushed_in)
|
||||
scroll_offset += (monitor.y + monitor.height) - requisition.height - y;
|
||||
y = (monitor.y + monitor.height) - requisition.height;
|
||||
scroll_offset += (workarea.y + workarea.height) - requisition.height - y;
|
||||
y = (workarea.y + workarea.height) - requisition.height;
|
||||
}
|
||||
|
||||
if (y < monitor.y)
|
||||
if (y < workarea.y)
|
||||
{
|
||||
if (priv->initially_pushed_in)
|
||||
scroll_offset += monitor.y - y;
|
||||
y = monitor.y;
|
||||
scroll_offset += workarea.y - y;
|
||||
y = workarea.y;
|
||||
}
|
||||
|
||||
x = CLAMP (x, monitor.x, MAX (monitor.x, monitor.x + monitor.width - requisition.width));
|
||||
x = CLAMP (x, workarea.x, MAX (workarea.x, workarea.x + workarea.width - requisition.width));
|
||||
|
||||
x -= border.left;
|
||||
y -= border.top;
|
||||
@@ -5279,7 +5290,7 @@ gtk_menu_real_move_scroll (GtkMenu *menu,
|
||||
* be popped up
|
||||
*
|
||||
* Informs GTK+ on which monitor a menu should be popped up.
|
||||
* See gdk_screen_get_monitor_geometry().
|
||||
* See gdk_monitor_get_geometry().
|
||||
*
|
||||
* This function should be called from a #GtkMenuPositionFunc
|
||||
* if the menu should not appear on the same monitor as the pointer.
|
||||
@@ -5324,6 +5335,32 @@ gtk_menu_get_monitor (GtkMenu *menu)
|
||||
return menu->priv->monitor_num;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_menu_place_on_monitor (GtkMenu *menu,
|
||||
GdkMonitor *monitor)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
gint i, monitor_num;
|
||||
|
||||
g_return_if_fail (GTK_IS_MENU (menu));
|
||||
|
||||
display = gtk_widget_get_display (GTK_WIDGET (menu));
|
||||
monitor_num = 0;
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
GdkMonitor *m = gdk_display_get_monitor (display, i);
|
||||
if (m == monitor)
|
||||
{
|
||||
monitor_num = i;
|
||||
break;
|
||||
}
|
||||
if (m == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_menu_set_monitor (menu, monitor_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_menu_get_for_attach_widget:
|
||||
* @widget: a #GtkWidget
|
||||
|
||||
@@ -240,6 +240,11 @@ void gtk_menu_set_monitor (GtkMenu *menu,
|
||||
gint monitor_num);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gint gtk_menu_get_monitor (GtkMenu *menu);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gtk_menu_place_on_monitor (GtkMenu *menu,
|
||||
GdkMonitor *monitor);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GList* gtk_menu_get_for_attach_widget (GtkWidget *widget);
|
||||
|
||||
|
||||
+18
-22
@@ -251,9 +251,9 @@ menu_position_up_down_func (GtkMenu *menu,
|
||||
GtkWidget *widget = GTK_WIDGET (menu_button);
|
||||
GtkWidget *toplevel;
|
||||
GtkTextDirection direction;
|
||||
GdkRectangle monitor;
|
||||
gint monitor_num;
|
||||
GdkScreen *screen;
|
||||
GdkRectangle workarea;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkWindow *window;
|
||||
GtkAllocation menu_allocation, allocation, arrow_allocation;
|
||||
GtkAlign align;
|
||||
@@ -272,11 +272,9 @@ menu_position_up_down_func (GtkMenu *menu,
|
||||
direction = gtk_widget_get_direction (widget);
|
||||
window = gtk_widget_get_window (priv->align_widget ? priv->align_widget : widget);
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
|
||||
if (monitor_num < 0)
|
||||
monitor_num = 0;
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (GTK_WIDGET (menu));
|
||||
monitor = gdk_display_get_monitor_at_window (display, window);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
gtk_widget_get_allocation (priv->align_widget ? priv->align_widget : widget, &allocation);
|
||||
gtk_widget_get_allocation (widget, &arrow_allocation);
|
||||
@@ -298,17 +296,17 @@ menu_position_up_down_func (GtkMenu *menu,
|
||||
else if (menu_allocation.width > allocation.width)
|
||||
*x -= menu_allocation.width - allocation.width;
|
||||
|
||||
if (priv->arrow_type == GTK_ARROW_UP && *y - menu_allocation.height >= monitor.y)
|
||||
if (priv->arrow_type == GTK_ARROW_UP && *y - menu_allocation.height >= workarea.y)
|
||||
{
|
||||
*y -= menu_allocation.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*y + arrow_allocation.height + menu_allocation.height) <= monitor.y + monitor.height)
|
||||
if ((*y + arrow_allocation.height + menu_allocation.height) <= workarea.y + workarea.height)
|
||||
*y += arrow_allocation.height;
|
||||
else if ((*y - menu_allocation.height) >= monitor.y)
|
||||
else if ((*y - menu_allocation.height) >= workarea.y)
|
||||
*y -= menu_allocation.height;
|
||||
else if (monitor.y + monitor.height - (*y + arrow_allocation.height) > *y)
|
||||
else if (workarea.y + workarea.height - (*y + arrow_allocation.height) > *y)
|
||||
*y += arrow_allocation.height;
|
||||
else
|
||||
*y -= menu_allocation.height;
|
||||
@@ -328,9 +326,9 @@ menu_position_side_func (GtkMenu *menu,
|
||||
GtkAllocation allocation;
|
||||
GtkAllocation menu_allocation;
|
||||
GtkWidget *widget = GTK_WIDGET (menu_button);
|
||||
GdkRectangle monitor;
|
||||
gint monitor_num;
|
||||
GdkScreen *screen;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
GdkWindow *window;
|
||||
GtkAlign align;
|
||||
GtkTextDirection direction;
|
||||
@@ -339,11 +337,9 @@ menu_position_side_func (GtkMenu *menu,
|
||||
|
||||
direction = gtk_widget_get_direction (widget);
|
||||
align = gtk_widget_get_valign (GTK_WIDGET (menu));
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
|
||||
if (monitor_num < 0)
|
||||
monitor_num = 0;
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (GTK_WIDGET (menu));
|
||||
monitor = gdk_display_get_monitor_at_window (display, window);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
gdk_window_get_origin (gtk_button_get_event_window (GTK_BUTTON (menu_button)), x, y);
|
||||
|
||||
@@ -354,14 +350,14 @@ menu_position_side_func (GtkMenu *menu,
|
||||
(priv->arrow_type == GTK_ARROW_LEFT && direction == GTK_TEXT_DIR_RTL))
|
||||
|
||||
{
|
||||
if (*x + allocation.width + menu_allocation.width <= monitor.x + monitor.width)
|
||||
if (*x + allocation.width + menu_allocation.width <= workarea.x + workarea.width)
|
||||
*x += allocation.width;
|
||||
else
|
||||
*x -= menu_allocation.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*x - menu_allocation.width >= monitor.x)
|
||||
if (*x - menu_allocation.width >= workarea.x)
|
||||
*x -= menu_allocation.width;
|
||||
else
|
||||
*x += allocation.width;
|
||||
|
||||
+16
-18
@@ -2099,12 +2099,12 @@ gtk_menu_item_position_menu (GtkMenu *menu,
|
||||
GtkWidget *widget;
|
||||
GtkMenuItem *parent_menu_item;
|
||||
GtkWidget *parent;
|
||||
GdkScreen *screen;
|
||||
GdkDisplay *display;
|
||||
gint twidth, theight;
|
||||
gint tx, ty;
|
||||
GtkTextDirection direction;
|
||||
GdkRectangle monitor;
|
||||
gint monitor_num;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
gint horizontal_offset;
|
||||
gint vertical_offset;
|
||||
gint available_left, available_right;
|
||||
@@ -2125,11 +2125,9 @@ gtk_menu_item_position_menu (GtkMenu *menu,
|
||||
twidth = gtk_widget_get_allocated_width (GTK_WIDGET (menu));
|
||||
theight = gtk_widget_get_allocated_height (GTK_WIDGET (menu));
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen, priv->event_window);
|
||||
if (monitor_num < 0)
|
||||
monitor_num = 0;
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (GTK_WIDGET (menu));
|
||||
monitor = gdk_display_get_monitor_at_window (display, priv->event_window);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
if (!gdk_window_get_origin (gtk_widget_get_window (widget), &tx, &ty))
|
||||
{
|
||||
@@ -2144,8 +2142,8 @@ gtk_menu_item_position_menu (GtkMenu *menu,
|
||||
|
||||
get_offsets (menu, &horizontal_offset, &vertical_offset);
|
||||
|
||||
available_left = tx - monitor.x;
|
||||
available_right = monitor.x + monitor.width - (tx + allocation.width);
|
||||
available_left = tx - workarea.x;
|
||||
available_right = workarea.x + workarea.width - (tx + allocation.width);
|
||||
|
||||
parent = gtk_widget_get_parent (widget);
|
||||
priv->from_menubar = GTK_IS_MENU_BAR (parent);
|
||||
@@ -2160,11 +2158,11 @@ gtk_menu_item_position_menu (GtkMenu *menu,
|
||||
priv->submenu_direction = GTK_DIRECTION_LEFT;
|
||||
tx += allocation.width - twidth;
|
||||
}
|
||||
if ((ty + allocation.height + theight) <= monitor.y + monitor.height)
|
||||
if ((ty + allocation.height + theight) <= workarea.y + workarea.height)
|
||||
ty += allocation.height;
|
||||
else if ((ty - theight) >= monitor.y)
|
||||
else if ((ty - theight) >= workarea.y)
|
||||
ty -= theight;
|
||||
else if (monitor.y + monitor.height - (ty + allocation.height) > ty)
|
||||
else if (workarea.y + workarea.height - (ty + allocation.height) > ty)
|
||||
ty += allocation.height;
|
||||
else
|
||||
ty -= theight;
|
||||
@@ -2194,7 +2192,7 @@ gtk_menu_item_position_menu (GtkMenu *menu,
|
||||
switch (priv->submenu_direction)
|
||||
{
|
||||
case GTK_DIRECTION_LEFT:
|
||||
if (tx - twidth - parent_padding.left - horizontal_offset >= monitor.x ||
|
||||
if (tx - twidth - parent_padding.left - horizontal_offset >= workarea.x ||
|
||||
available_left >= available_right)
|
||||
tx -= twidth + parent_padding.left + horizontal_offset;
|
||||
else
|
||||
@@ -2205,7 +2203,7 @@ gtk_menu_item_position_menu (GtkMenu *menu,
|
||||
break;
|
||||
|
||||
case GTK_DIRECTION_RIGHT:
|
||||
if (tx + allocation.width + parent_padding.right + horizontal_offset + twidth <= monitor.x + monitor.width ||
|
||||
if (tx + allocation.width + parent_padding.right + horizontal_offset + twidth <= workarea.x + workarea.width ||
|
||||
available_right >= available_left)
|
||||
tx += allocation.width + parent_padding.right + horizontal_offset;
|
||||
else
|
||||
@@ -2219,17 +2217,17 @@ gtk_menu_item_position_menu (GtkMenu *menu,
|
||||
ty += vertical_offset;
|
||||
|
||||
/* If the height of the menu doesn't fit we move it upward. */
|
||||
ty = CLAMP (ty, monitor.y, MAX (monitor.y, monitor.y + monitor.height - theight));
|
||||
ty = CLAMP (ty, workarea.y, MAX (workarea.y, workarea.y + workarea.height - theight));
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we have negative, tx, here it is because we can't get
|
||||
* the menu all the way on screen. Favor the left portion.
|
||||
*/
|
||||
*x = CLAMP (tx, monitor.x, MAX (monitor.x, monitor.x + monitor.width - twidth));
|
||||
*x = CLAMP (tx, workarea.x, MAX (workarea.x, workarea.x + workarea.width - twidth));
|
||||
*y = ty;
|
||||
|
||||
gtk_menu_set_monitor (menu, monitor_num);
|
||||
gtk_menu_place_on_monitor (menu, monitor);
|
||||
|
||||
if (!gtk_widget_get_visible (menu->priv->toplevel))
|
||||
{
|
||||
|
||||
@@ -873,10 +873,10 @@ set_default_size (GtkRecentChooserDefault *impl)
|
||||
GtkWidget *widget;
|
||||
gint width, height;
|
||||
double font_size;
|
||||
GdkScreen *screen;
|
||||
gint monitor_num;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GtkRequisition req;
|
||||
GdkRectangle monitor;
|
||||
GdkRectangle workarea;
|
||||
GtkStyleContext *context;
|
||||
|
||||
widget = GTK_WIDGET (impl);
|
||||
@@ -894,14 +894,12 @@ set_default_size (GtkRecentChooserDefault *impl)
|
||||
height = MAX (height, req.height);
|
||||
|
||||
/* ... but no larger than the monitor */
|
||||
screen = gtk_widget_get_screen (widget);
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
||||
gtk_widget_get_window (widget));
|
||||
display = gtk_widget_get_display (widget);
|
||||
monitor = gdk_display_get_monitor_at_window (display, gtk_widget_get_window (widget));
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
|
||||
width = MIN (width, monitor.width * 3 / 4);
|
||||
height = MIN (height, monitor.height * 3 / 4);
|
||||
width = MIN (width, workarea.width * 3 / 4);
|
||||
height = MIN (height, workarea.height * 3 / 4);
|
||||
|
||||
/* Set size */
|
||||
scrollw = GTK_SCROLLED_WINDOW (gtk_widget_get_parent (impl->priv->recent_view));
|
||||
@@ -1739,30 +1737,29 @@ popup_position_func (GtkMenu *menu,
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
GtkWidget *widget = GTK_WIDGET (user_data);
|
||||
GdkScreen *screen = gtk_widget_get_screen (widget);
|
||||
GtkRequisition req;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
|
||||
if (G_UNLIKELY (!gtk_widget_get_realized (widget)))
|
||||
return;
|
||||
|
||||
gdk_window_get_origin (gtk_widget_get_window (widget),
|
||||
x, y);
|
||||
gdk_window_get_origin (gtk_widget_get_window (widget), x, y);
|
||||
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (menu),
|
||||
&req, NULL);
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
*x += (allocation.width - req.width) / 2;
|
||||
*y += (allocation.height - req.height) / 2;
|
||||
|
||||
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
|
||||
gtk_menu_set_monitor (menu, monitor_num);
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (widget);
|
||||
monitor = gdk_display_get_monitor_at_point (display, *x, *y);
|
||||
gtk_menu_place_on_monitor (menu, monitor);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
*x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
|
||||
*y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
|
||||
*x = CLAMP (*x, workarea.x, workarea.x + MAX (0, workarea.width - req.width));
|
||||
*y = CLAMP (*y, workarea.y, workarea.y + MAX (0, workarea.height - req.height));
|
||||
|
||||
*push_in = FALSE;
|
||||
}
|
||||
|
||||
+9
-13
@@ -2919,21 +2919,17 @@ static void
|
||||
settings_update_double_click (GtkSettings *settings)
|
||||
{
|
||||
GtkSettingsPrivate *priv = settings->priv;
|
||||
GdkDisplay *display = gdk_screen_get_display (priv->screen);
|
||||
gint double_click_time;
|
||||
gint double_click_distance;
|
||||
|
||||
if (gdk_screen_get_number (priv->screen) == 0)
|
||||
{
|
||||
GdkDisplay *display = gdk_screen_get_display (priv->screen);
|
||||
gint double_click_time;
|
||||
gint double_click_distance;
|
||||
g_object_get (settings,
|
||||
"gtk-double-click-time", &double_click_time,
|
||||
"gtk-double-click-distance", &double_click_distance,
|
||||
NULL);
|
||||
|
||||
g_object_get (settings,
|
||||
"gtk-double-click-time", &double_click_time,
|
||||
"gtk-double-click-distance", &double_click_distance,
|
||||
NULL);
|
||||
|
||||
gdk_display_set_double_click_time (display, double_click_time);
|
||||
gdk_display_set_double_click_distance (display, double_click_distance);
|
||||
}
|
||||
gdk_display_set_double_click_time (display, double_click_time);
|
||||
gdk_display_set_double_click_distance (display, double_click_distance);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+14
-14
@@ -9356,17 +9356,17 @@ popup_position_func (GtkMenu *menu,
|
||||
GdkRectangle onscreen_rect;
|
||||
gint root_x, root_y;
|
||||
GtkTextIter iter;
|
||||
GtkRequisition req;
|
||||
GdkScreen *screen;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
|
||||
GtkRequisition req;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
|
||||
text_view = GTK_TEXT_VIEW (user_data);
|
||||
widget = GTK_WIDGET (text_view);
|
||||
|
||||
|
||||
g_return_if_fail (gtk_widget_get_realized (widget));
|
||||
|
||||
screen = gtk_widget_get_screen (widget);
|
||||
|
||||
display = gtk_widget_get_display (widget);
|
||||
|
||||
gdk_window_get_origin (gtk_widget_get_window (widget),
|
||||
&root_x, &root_y);
|
||||
@@ -9391,7 +9391,7 @@ popup_position_func (GtkMenu *menu,
|
||||
cursor_rect.x < onscreen_rect.x + onscreen_rect.width &&
|
||||
cursor_rect.y >= onscreen_rect.y &&
|
||||
cursor_rect.y < onscreen_rect.y + onscreen_rect.height)
|
||||
{
|
||||
{
|
||||
gtk_text_view_buffer_to_window_coords (text_view,
|
||||
GTK_TEXT_WINDOW_WIDGET,
|
||||
cursor_rect.x, cursor_rect.y,
|
||||
@@ -9411,12 +9411,12 @@ popup_position_func (GtkMenu *menu,
|
||||
*x = CLAMP (*x, root_x, (root_x + allocation.width));
|
||||
*y = CLAMP (*y, root_y, (root_y + allocation.height));
|
||||
|
||||
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
|
||||
gtk_menu_set_monitor (menu, monitor_num);
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
monitor = gdk_display_get_monitor_at_point (display, *x, *y);
|
||||
gtk_menu_place_on_monitor (menu, monitor);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
*x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
|
||||
*y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
|
||||
*x = CLAMP (*x, workarea.x, workarea.x + MAX (0, workarea.width - req.width));
|
||||
*y = CLAMP (*y, workarea.y, workarea.y + MAX (0, workarea.height - req.height));
|
||||
|
||||
*push_in = FALSE;
|
||||
}
|
||||
|
||||
+17
-19
@@ -2629,50 +2629,48 @@ menu_position_func (GtkMenu *menu,
|
||||
GtkToolbarPrivate *priv = toolbar->priv;
|
||||
GtkRequisition req;
|
||||
GtkRequisition menu_req;
|
||||
GdkRectangle monitor;
|
||||
gint monitor_num;
|
||||
GdkScreen *screen;
|
||||
GdkRectangle workarea;
|
||||
GdkMonitor *monitor;
|
||||
GdkDisplay *display;
|
||||
|
||||
gtk_widget_get_preferred_size (priv->arrow_button,
|
||||
&req, NULL);
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (menu),
|
||||
&menu_req, NULL);
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
||||
gtk_widget_get_window (priv->arrow_button));
|
||||
if (monitor_num < 0)
|
||||
monitor_num = 0;
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
display = gtk_widget_get_display (GTK_WIDGET (menu));
|
||||
monitor = gdk_display_get_monitor_at_window (display,
|
||||
gtk_widget_get_window (priv->arrow_button));
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
gtk_widget_get_allocation (priv->arrow_button, &allocation);
|
||||
|
||||
gdk_window_get_origin (gtk_button_get_event_window (GTK_BUTTON (priv->arrow_button)), x, y);
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
|
||||
*x += allocation.width - req.width;
|
||||
else
|
||||
else
|
||||
*x += req.width - menu_req.width;
|
||||
|
||||
if ((*y + allocation.height + menu_req.height) <= monitor.y + monitor.height)
|
||||
if ((*y + allocation.height + menu_req.height) <= workarea.y + workarea.height)
|
||||
*y += allocation.height;
|
||||
else if ((*y - menu_req.height) >= monitor.y)
|
||||
else if ((*y - menu_req.height) >= workarea.y)
|
||||
*y -= menu_req.height;
|
||||
else if (monitor.y + monitor.height - (*y + allocation.height) > *y)
|
||||
else if (workarea.y + workarea.height - (*y + allocation.height) > *y)
|
||||
*y += allocation.height;
|
||||
else
|
||||
*y -= menu_req.height;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
|
||||
*x += allocation.width;
|
||||
else
|
||||
else
|
||||
*x -= menu_req.width;
|
||||
|
||||
if (*y + menu_req.height > monitor.y + monitor.height &&
|
||||
*y + allocation.height - monitor.y > monitor.y + monitor.height - *y)
|
||||
if (*y + menu_req.height > workarea.y + workarea.height &&
|
||||
*y + allocation.height - workarea.y > workarea.y + workarea.height - *y)
|
||||
*y += allocation.height - menu_req.height;
|
||||
}
|
||||
|
||||
|
||||
+16
-21
@@ -895,9 +895,8 @@ gtk_tooltip_position (GtkTooltip *tooltip,
|
||||
GtkWidget *new_tooltip_widget)
|
||||
{
|
||||
gint x, y, width, height;
|
||||
GdkScreen *screen;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
guint cursor_size;
|
||||
GdkRectangle bounds;
|
||||
GtkBorder border;
|
||||
@@ -909,17 +908,13 @@ gtk_tooltip_position (GtkTooltip *tooltip,
|
||||
|
||||
tooltip->tooltip_widget = new_tooltip_widget;
|
||||
|
||||
screen = gtk_widget_get_screen (new_tooltip_widget);
|
||||
|
||||
_gtk_window_get_shadow_width (GTK_WINDOW (tooltip->current_window), &border);
|
||||
|
||||
width = gtk_widget_get_allocated_width (GTK_WIDGET (tooltip->current_window)) - border.left - border.right;
|
||||
height = gtk_widget_get_allocated_height (GTK_WIDGET (tooltip->current_window)) - border.top - border.bottom;
|
||||
|
||||
monitor_num = gdk_screen_get_monitor_at_point (screen,
|
||||
tooltip->last_x,
|
||||
tooltip->last_y);
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
monitor = gdk_display_get_monitor_at_point (display, tooltip->last_x, tooltip->last_y);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
get_bounding_box (new_tooltip_widget, &bounds);
|
||||
|
||||
@@ -931,7 +926,7 @@ gtk_tooltip_position (GtkTooltip *tooltip,
|
||||
x = bounds.x + bounds.width / 2 - width / 2;
|
||||
y = bounds.y + bounds.height + 4;
|
||||
|
||||
if (y + height <= monitor.y + monitor.height)
|
||||
if (y + height <= workarea.y + workarea.height)
|
||||
{
|
||||
if (tooltip->keyboard_mode_enabled)
|
||||
goto found;
|
||||
@@ -951,7 +946,7 @@ gtk_tooltip_position (GtkTooltip *tooltip,
|
||||
x = bounds.x + bounds.width / 2 - width / 2;
|
||||
y = bounds.y - height - 4;
|
||||
|
||||
if (y >= monitor.y)
|
||||
if (y >= workarea.y)
|
||||
{
|
||||
if (tooltip->keyboard_mode_enabled)
|
||||
goto found;
|
||||
@@ -971,7 +966,7 @@ gtk_tooltip_position (GtkTooltip *tooltip,
|
||||
x = bounds.x + bounds.width + 4;
|
||||
y = bounds.y + bounds.height / 2 - height / 2;
|
||||
|
||||
if (x + width <= monitor.x + monitor.width)
|
||||
if (x + width <= workarea.x + workarea.width)
|
||||
{
|
||||
if (tooltip->keyboard_mode_enabled)
|
||||
goto found;
|
||||
@@ -991,7 +986,7 @@ gtk_tooltip_position (GtkTooltip *tooltip,
|
||||
x = bounds.x - width - 4;
|
||||
y = bounds.y + bounds.height / 2 - height / 2;
|
||||
|
||||
if (x >= monitor.x)
|
||||
if (x >= workarea.x)
|
||||
{
|
||||
if (tooltip->keyboard_mode_enabled)
|
||||
goto found;
|
||||
@@ -1022,15 +1017,15 @@ gtk_tooltip_position (GtkTooltip *tooltip,
|
||||
|
||||
found:
|
||||
/* Show it */
|
||||
if (x + width > monitor.x + monitor.width)
|
||||
x -= x - (monitor.x + monitor.width) + width;
|
||||
else if (x < monitor.x)
|
||||
x = monitor.x;
|
||||
if (x + width > workarea.x + workarea.width)
|
||||
x -= x - (workarea.x + workarea.width) + width;
|
||||
else if (x < workarea.x)
|
||||
x = workarea.x;
|
||||
|
||||
if (y + height > monitor.y + monitor.height)
|
||||
y -= y - (monitor.y + monitor.height) + height;
|
||||
else if (y < monitor.y)
|
||||
y = monitor.y;
|
||||
if (y + height > workarea.y + workarea.height)
|
||||
y -= y - (workarea.y + workarea.height) + height;
|
||||
else if (y < workarea.y)
|
||||
y = workarea.y;
|
||||
|
||||
if (!tooltip->keyboard_mode_enabled)
|
||||
{
|
||||
|
||||
+15
-14
@@ -15038,33 +15038,34 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view,
|
||||
gint x, y;
|
||||
gint tree_x, tree_y;
|
||||
gint tree_width, tree_height;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
GdkWindow *tree_window = gtk_widget_get_window (GTK_WIDGET (tree_view));
|
||||
GdkScreen *screen = gdk_window_get_screen (tree_window);
|
||||
GtkRequisition requisition;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen, tree_window);
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
|
||||
gtk_widget_realize (search_window);
|
||||
|
||||
display = gtk_widget_get_display (GTK_WIDGET (tree_view));
|
||||
monitor = gdk_display_get_monitor_at_window (display, tree_window);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
gdk_window_get_origin (tree_window, &tree_x, &tree_y);
|
||||
tree_width = gdk_window_get_width (tree_window);
|
||||
tree_height = gdk_window_get_height (tree_window);
|
||||
gtk_widget_get_preferred_size (search_window, &requisition, NULL);
|
||||
|
||||
if (tree_x + tree_width > gdk_screen_get_width (screen))
|
||||
x = gdk_screen_get_width (screen) - requisition.width;
|
||||
else if (tree_x + tree_width - requisition.width < 0)
|
||||
x = 0;
|
||||
if (tree_x + tree_width > workarea.x + workarea.width)
|
||||
x = workarea.x + workarea.width - requisition.width;
|
||||
else if (tree_x + tree_width - requisition.width < workarea.x)
|
||||
x = workarea.x;
|
||||
else
|
||||
x = tree_x + tree_width - requisition.width;
|
||||
|
||||
if (tree_y + tree_height + requisition.height > gdk_screen_get_height (screen))
|
||||
y = gdk_screen_get_height (screen) - requisition.height;
|
||||
else if (tree_y + tree_height < 0) /* isn't really possible ... */
|
||||
y = 0;
|
||||
if (tree_y + tree_height + requisition.height > workarea.y + workarea.height)
|
||||
y = workarea.y + workarea.height - requisition.height;
|
||||
else if (tree_y + tree_height < workarea.y) /* isn't really possible ... */
|
||||
y = workarea.y;
|
||||
else
|
||||
y = tree_y + tree_height;
|
||||
|
||||
|
||||
+5
-5
@@ -10838,7 +10838,8 @@ gint
|
||||
gtk_widget_get_scale_factor (GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GdkScreen *screen;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), 1);
|
||||
|
||||
@@ -10852,11 +10853,10 @@ gtk_widget_get_scale_factor (GtkWidget *widget)
|
||||
/* else fall back to something that is more likely to be right than
|
||||
* just returning 1:
|
||||
*/
|
||||
screen = gtk_widget_get_screen (widget);
|
||||
if (screen)
|
||||
return gdk_screen_get_monitor_scale_factor (screen, 0);
|
||||
display = gtk_widget_get_display (widget);
|
||||
monitor = gdk_display_get_monitor (display, 0);
|
||||
|
||||
return 1;
|
||||
return gdk_monitor_get_scale_factor (monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+52
-87
@@ -183,6 +183,7 @@ struct _GtkWindowPrivate
|
||||
GtkWindowGeometryInfo *geometry_info;
|
||||
GtkWindowGroup *group;
|
||||
GdkScreen *screen;
|
||||
GdkDisplay *display;
|
||||
GtkApplication *application;
|
||||
|
||||
GList *popovers;
|
||||
@@ -6187,7 +6188,7 @@ gtk_window_map (GtkWidget *widget)
|
||||
GtkWindowPrivate *priv = window->priv;
|
||||
GdkWindow *gdk_window;
|
||||
GList *link;
|
||||
GdkScreen *screen;
|
||||
GdkDisplay *display;
|
||||
|
||||
if (!_gtk_widget_is_toplevel (widget))
|
||||
{
|
||||
@@ -6195,10 +6196,10 @@ gtk_window_map (GtkWidget *widget)
|
||||
return;
|
||||
}
|
||||
|
||||
screen = _gtk_window_get_screen (window);
|
||||
if (priv->initial_fullscreen_monitor > gdk_screen_get_n_monitors (screen))
|
||||
display = gtk_widget_get_display (widget);
|
||||
if (priv->initial_fullscreen_monitor > gdk_display_get_n_monitors (display))
|
||||
priv->initial_fullscreen_monitor = -1;
|
||||
|
||||
|
||||
gtk_widget_set_mapped (widget, TRUE);
|
||||
|
||||
child = gtk_bin_get_child (&(window->bin));
|
||||
@@ -6402,28 +6403,22 @@ gtk_window_guess_default_size (GtkWindow *window,
|
||||
gint *height)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GdkScreen *screen;
|
||||
GdkDisplay *display;
|
||||
GdkWindow *gdkwindow;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
int minimum, natural;
|
||||
|
||||
widget = GTK_WIDGET (window);
|
||||
screen = _gtk_window_get_screen (window);
|
||||
display = gtk_widget_get_display (widget);
|
||||
gdkwindow = _gtk_widget_get_window (widget);
|
||||
|
||||
if (gdkwindow)
|
||||
{
|
||||
gdk_screen_get_monitor_workarea (screen,
|
||||
gdk_screen_get_monitor_at_window (screen, gdkwindow),
|
||||
&workarea);
|
||||
}
|
||||
monitor = gdk_display_get_monitor_at_window (display, gdkwindow);
|
||||
else
|
||||
{
|
||||
/* XXX: Figure out what screen we appear on */
|
||||
gdk_screen_get_monitor_workarea (screen,
|
||||
0,
|
||||
&workarea);
|
||||
}
|
||||
monitor = gdk_display_get_monitor (display, 0);
|
||||
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
*width = workarea.width;
|
||||
*height = workarea.height;
|
||||
@@ -9198,40 +9193,31 @@ get_effective_position (GtkWindow *window)
|
||||
return pos;
|
||||
}
|
||||
|
||||
static int
|
||||
static GdkMonitor *
|
||||
get_center_monitor_of_window (GtkWindow *window)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
/* We could try to sort out the relative positions of the monitors and
|
||||
* stuff, or we could just be losers and assume you have a row
|
||||
* or column of monitors.
|
||||
*/
|
||||
return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
|
||||
display = gdk_screen_get_display (gtk_window_check_screen (window));
|
||||
return gdk_display_get_monitor (display, gdk_display_get_n_monitors (display) / 2);
|
||||
}
|
||||
|
||||
static int
|
||||
static GdkMonitor *
|
||||
get_monitor_containing_pointer (GtkWindow *window)
|
||||
{
|
||||
gint px, py;
|
||||
gint monitor_num;
|
||||
GdkScreen *window_screen;
|
||||
GdkScreen *pointer_screen;
|
||||
GdkDisplay *display;
|
||||
GdkDevice *pointer;
|
||||
|
||||
window_screen = gtk_window_check_screen (window);
|
||||
display = gdk_screen_get_display (window_screen);
|
||||
display = gdk_screen_get_display (gtk_window_check_screen (window));
|
||||
pointer = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
|
||||
gdk_device_get_position (pointer, NULL, &px, &py);
|
||||
|
||||
gdk_device_get_position (pointer,
|
||||
&pointer_screen,
|
||||
&px, &py);
|
||||
|
||||
if (pointer_screen == window_screen)
|
||||
monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
|
||||
else
|
||||
monitor_num = -1;
|
||||
|
||||
return monitor_num;
|
||||
return gdk_display_get_monitor_at_point (display, px, py);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -9241,27 +9227,26 @@ center_window_on_monitor (GtkWindow *window,
|
||||
gint *x,
|
||||
gint *y)
|
||||
{
|
||||
GdkRectangle monitor;
|
||||
int monitor_num;
|
||||
GdkRectangle area;
|
||||
GdkMonitor *monitor;
|
||||
|
||||
monitor_num = get_monitor_containing_pointer (window);
|
||||
monitor = get_monitor_containing_pointer (window);
|
||||
|
||||
if (monitor_num == -1)
|
||||
monitor_num = get_center_monitor_of_window (window);
|
||||
if (monitor == NULL)
|
||||
monitor = get_center_monitor_of_window (window);
|
||||
|
||||
gdk_screen_get_monitor_workarea (gtk_window_check_screen (window),
|
||||
monitor_num, &monitor);
|
||||
gdk_monitor_get_workarea (monitor, &area);
|
||||
|
||||
*x = (monitor.width - w) / 2 + monitor.x;
|
||||
*y = (monitor.height - h) / 2 + monitor.y;
|
||||
*x = (area.width - w) / 2 + area.x;
|
||||
*y = (area.height - h) / 2 + area.y;
|
||||
|
||||
/* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
|
||||
* and WM decorations.
|
||||
*/
|
||||
if (*x < monitor.x)
|
||||
*x = monitor.x;
|
||||
if (*y < monitor.y)
|
||||
*y = monitor.y;
|
||||
if (*x < area.x)
|
||||
*x = area.x;
|
||||
if (*y < area.y)
|
||||
*y = area.y;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -9362,24 +9347,20 @@ gtk_window_compute_configure_request (GtkWindow *window,
|
||||
|
||||
case GTK_WIN_POS_CENTER_ON_PARENT:
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GtkAllocation allocation;
|
||||
GdkWindow *gdk_window;
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle area;
|
||||
gint ox, oy;
|
||||
|
||||
g_assert (_gtk_widget_get_mapped (parent_widget)); /* established earlier */
|
||||
|
||||
display = gdk_screen_get_display (screen);
|
||||
gdk_window = _gtk_widget_get_window (parent_widget);
|
||||
monitor = gdk_display_get_monitor_at_window (display, gdk_window);
|
||||
|
||||
if (gdk_window != NULL)
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
||||
gdk_window);
|
||||
else
|
||||
monitor_num = -1;
|
||||
|
||||
gdk_window_get_origin (gdk_window,
|
||||
&ox, &oy);
|
||||
gdk_window_get_origin (gdk_window, &ox, &oy);
|
||||
|
||||
_gtk_widget_get_allocation (parent_widget, &allocation);
|
||||
x = ox + (allocation.width - w) / 2;
|
||||
@@ -9389,51 +9370,36 @@ gtk_window_compute_configure_request (GtkWindow *window,
|
||||
* WM decorations. If parent wasn't on a monitor, just
|
||||
* give up.
|
||||
*/
|
||||
if (monitor_num >= 0)
|
||||
if (monitor != NULL)
|
||||
{
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
clamp_window_to_rectangle (&x, &y, w, h, &monitor);
|
||||
gdk_monitor_get_geometry (monitor, &area);
|
||||
clamp_window_to_rectangle (&x, &y, w, h, &area);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GTK_WIN_POS_MOUSE:
|
||||
{
|
||||
gint screen_width = gdk_screen_get_width (screen);
|
||||
gint screen_height = gdk_screen_get_height (screen);
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GdkRectangle area;
|
||||
GdkDisplay *display;
|
||||
GdkDevice *pointer;
|
||||
GdkScreen *pointer_screen;
|
||||
GdkMonitor *monitor;
|
||||
gint px, py;
|
||||
|
||||
display = gdk_screen_get_display (screen);
|
||||
pointer = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
|
||||
|
||||
gdk_device_get_position (pointer,
|
||||
&pointer_screen,
|
||||
&px, &py);
|
||||
|
||||
if (pointer_screen == screen)
|
||||
monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
|
||||
else
|
||||
monitor_num = -1;
|
||||
gdk_device_get_position (pointer, NULL, &px, &py);
|
||||
monitor = gdk_display_get_monitor_at_point (display, px, py);
|
||||
|
||||
x = px - w / 2;
|
||||
y = py - h / 2;
|
||||
x = CLAMP (x, 0, screen_width - w);
|
||||
y = CLAMP (y, 0, screen_height - h);
|
||||
|
||||
/* Clamp onto current monitor, ignoring _NET_WM_STRUT and
|
||||
* WM decorations. Don't try to figure out what's going
|
||||
* on if the mouse wasn't inside a monitor.
|
||||
* WM decorations.
|
||||
*/
|
||||
if (monitor_num >= 0)
|
||||
{
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
clamp_window_to_rectangle (&x, &y, w, h, &monitor);
|
||||
}
|
||||
gdk_monitor_get_geometry (monitor, &area);
|
||||
clamp_window_to_rectangle (&x, &y, w, h, &area);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -10534,12 +10500,11 @@ gtk_window_fullscreen_on_monitor (GtkWindow *window,
|
||||
GtkWindowPrivate *priv;
|
||||
GtkWidget *widget;
|
||||
GdkWindow *toplevel;
|
||||
|
||||
|
||||
g_return_if_fail (GTK_IS_WINDOW (window));
|
||||
g_return_if_fail (GDK_IS_SCREEN (screen));
|
||||
g_return_if_fail (monitor >= 0);
|
||||
g_return_if_fail (monitor < gdk_screen_get_n_monitors (screen));
|
||||
|
||||
g_return_if_fail (gdk_display_get_monitor (gdk_screen_get_display (screen), monitor) != NULL);
|
||||
|
||||
priv = window->priv;
|
||||
widget = GTK_WIDGET (window);
|
||||
|
||||
|
||||
+147
-91
@@ -57,7 +57,7 @@ struct _GtkInspectorGeneralPrivate
|
||||
{
|
||||
GtkWidget *version_box;
|
||||
GtkWidget *env_box;
|
||||
GtkWidget *x_box;
|
||||
GtkWidget *display_box;
|
||||
GtkWidget *gl_box;
|
||||
GtkWidget *device_box;
|
||||
GtkWidget *gtk_version;
|
||||
@@ -71,9 +71,9 @@ struct _GtkInspectorGeneralPrivate
|
||||
GtkWidget *gtk_exe_prefix;
|
||||
GtkWidget *gtk_data_prefix;
|
||||
GtkWidget *gsettings_schema_dir;
|
||||
GtkWidget *x_display;
|
||||
GtkWidget *x_rgba;
|
||||
GtkWidget *x_composited;
|
||||
GtkWidget *display_name;
|
||||
GtkWidget *display_rgba;
|
||||
GtkWidget *display_composited;
|
||||
GtkSizeGroup *labels;
|
||||
GtkAdjustment *focus_adjustment;
|
||||
};
|
||||
@@ -120,29 +120,78 @@ init_version (GtkInspectorGeneral *gen)
|
||||
}
|
||||
|
||||
static G_GNUC_UNUSED void
|
||||
append_extension_row (GtkInspectorGeneral *gen,
|
||||
const gchar *ext,
|
||||
gboolean have_ext)
|
||||
add_check_row (GtkInspectorGeneral *gen,
|
||||
GtkListBox *list,
|
||||
const gchar *name,
|
||||
gboolean value,
|
||||
gint indent)
|
||||
{
|
||||
GtkWidget *row, *box, *label, *check;
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 40);
|
||||
g_object_set (box, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
label = gtk_label_new (ext);
|
||||
g_object_set (box,
|
||||
"margin", 10,
|
||||
"margin-start", 10 + indent,
|
||||
NULL);
|
||||
|
||||
label = gtk_label_new (name);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
||||
|
||||
check = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU);
|
||||
gtk_widget_set_halign (check, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (check, GTK_ALIGN_BASELINE);
|
||||
gtk_widget_set_opacity (check, have_ext ? 1.0 : 0.0);
|
||||
gtk_widget_set_opacity (check, value ? 1.0 : 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (box), check, TRUE, TRUE, 0);
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
|
||||
gtk_widget_show_all (row);
|
||||
gtk_list_box_insert (GTK_LIST_BOX (gen->priv->gl_box), row, -1);
|
||||
|
||||
gtk_list_box_insert (list, row, -1);
|
||||
|
||||
gtk_size_group_add_widget (GTK_SIZE_GROUP (gen->priv->labels), label);
|
||||
}
|
||||
|
||||
static void
|
||||
add_label_row (GtkInspectorGeneral *gen,
|
||||
GtkListBox *list,
|
||||
const char *name,
|
||||
const char *value,
|
||||
gint indent)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
GtkWidget *row;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 40);
|
||||
g_object_set (box,
|
||||
"margin", 10,
|
||||
"margin-start", 10 + indent,
|
||||
NULL);
|
||||
|
||||
label = gtk_label_new (name);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new (value);
|
||||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||||
gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
|
||||
gtk_widget_show_all (row);
|
||||
|
||||
gtk_list_box_insert (GTK_LIST_BOX (list), row, -1);
|
||||
|
||||
gtk_size_group_add_widget (GTK_SIZE_GROUP (gen->priv->labels), label);
|
||||
}
|
||||
@@ -153,7 +202,7 @@ append_glx_extension_row (GtkInspectorGeneral *gen,
|
||||
Display *dpy,
|
||||
const gchar *ext)
|
||||
{
|
||||
append_extension_row (gen, ext, epoxy_has_glx_extension (dpy, 0, ext));
|
||||
add_check_row (gen, GTK_LIST_BOX (gen->priv->gl_box), ext, epoxy_has_glx_extension (dpy, 0, ext), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -163,7 +212,7 @@ append_egl_extension_row (GtkInspectorGeneral *gen,
|
||||
EGLDisplay *dpy,
|
||||
const gchar *ext)
|
||||
{
|
||||
append_extension_row (gen, ext, epoxy_has_egl_extension (dpy, ext));
|
||||
add_check_row (gen, GTK_LIST_BOX (gen->priv->gl_box), ext, epoxy_has_egl_extension (dpy, ext), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -273,41 +322,19 @@ init_env (GtkInspectorGeneral *gen)
|
||||
set_path_label (gen->priv->gsettings_schema_dir, "GSETTINGS_SCHEMA_DIR");
|
||||
}
|
||||
|
||||
static void
|
||||
add_label_row (GtkListBox *list,
|
||||
const char *name,
|
||||
const char *value,
|
||||
gint indent)
|
||||
static const char *
|
||||
translate_subpixel_layout (GdkSubpixelLayout subpixel)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
GtkWidget *row;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 40);
|
||||
g_object_set (box,
|
||||
"margin", 10,
|
||||
"margin-start", 10 + indent,
|
||||
NULL);
|
||||
|
||||
label = gtk_label_new (name);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new (value);
|
||||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||||
gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
|
||||
gtk_widget_show_all (row);
|
||||
|
||||
gtk_list_box_insert (GTK_LIST_BOX (list), row, -1);
|
||||
switch (subpixel)
|
||||
{
|
||||
case GDK_SUBPIXEL_LAYOUT_NONE: return "none";
|
||||
case GDK_SUBPIXEL_LAYOUT_UNKNOWN: return "unknown";
|
||||
case GDK_SUBPIXEL_LAYOUT_HORIZONTAL_RGB: return "horizontal rgb";
|
||||
case GDK_SUBPIXEL_LAYOUT_HORIZONTAL_BGR: return "horizontal bgr";
|
||||
case GDK_SUBPIXEL_LAYOUT_VERTICAL_RGB: return "vertical rgb";
|
||||
case GDK_SUBPIXEL_LAYOUT_VERTICAL_BGR: return "vertical bgr";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -317,14 +344,18 @@ populate_display (GdkScreen *screen, GtkInspectorGeneral *gen)
|
||||
gint i;
|
||||
GList *children, *l;
|
||||
GtkWidget *child;
|
||||
GdkDisplay *display;
|
||||
int n_monitors;
|
||||
GtkListBox *list;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (gen->priv->x_box));
|
||||
list = GTK_LIST_BOX (gen->priv->display_box);
|
||||
children = gtk_container_get_children (GTK_CONTAINER (list));
|
||||
for (l = children; l; l = l->next)
|
||||
{
|
||||
child = l->data;
|
||||
if (gtk_widget_is_ancestor (gen->priv->x_display, child) ||
|
||||
gtk_widget_is_ancestor (gen->priv->x_rgba, child) ||
|
||||
gtk_widget_is_ancestor (gen->priv->x_composited, child))
|
||||
if (gtk_widget_is_ancestor (gen->priv->display_name, child) ||
|
||||
gtk_widget_is_ancestor (gen->priv->display_rgba, child) ||
|
||||
gtk_widget_is_ancestor (gen->priv->display_composited, child))
|
||||
continue;
|
||||
|
||||
gtk_widget_destroy (child);
|
||||
@@ -332,44 +363,69 @@ populate_display (GdkScreen *screen, GtkInspectorGeneral *gen)
|
||||
g_list_free (children);
|
||||
|
||||
name = gdk_screen_make_display_name (screen);
|
||||
gtk_label_set_label (GTK_LABEL (gen->priv->x_display), name);
|
||||
gtk_label_set_label (GTK_LABEL (gen->priv->display_name), name);
|
||||
g_free (name);
|
||||
|
||||
if (gdk_screen_get_rgba_visual (screen) != NULL)
|
||||
gtk_widget_show (gen->priv->x_rgba);
|
||||
gtk_widget_show (gen->priv->display_rgba);
|
||||
|
||||
if (gdk_screen_is_composited (screen))
|
||||
gtk_widget_show (gen->priv->x_composited);
|
||||
gtk_widget_show (gen->priv->display_composited);
|
||||
|
||||
for (i = 0; i < gdk_screen_get_n_monitors (screen); i++)
|
||||
display = gdk_screen_get_display (screen);
|
||||
n_monitors = gdk_display_get_n_monitors (display);
|
||||
for (i = 0; i < n_monitors; i++)
|
||||
{
|
||||
GdkMonitor *monitor;
|
||||
gchar *name;
|
||||
gchar *value;
|
||||
gchar *plug_name;
|
||||
GdkRectangle rect;
|
||||
gint w, h, wmm, hmm, scale;
|
||||
gint scale;
|
||||
const char *manufacturer;
|
||||
const char *model;
|
||||
|
||||
plug_name = gdk_screen_get_monitor_plug_name (screen, i);
|
||||
if (plug_name)
|
||||
name = g_strdup_printf ("Monitor %s", plug_name);
|
||||
else
|
||||
name = g_strdup_printf ("Monitor %d", i);
|
||||
g_free (plug_name);
|
||||
|
||||
gdk_screen_get_monitor_geometry (screen, i, &rect);
|
||||
w = rect.width;
|
||||
h = rect.height;
|
||||
wmm = gdk_screen_get_monitor_width_mm (screen, i);
|
||||
hmm = gdk_screen_get_monitor_height_mm (screen, i);
|
||||
scale = gdk_screen_get_monitor_scale_factor (screen, i);
|
||||
value = g_strdup_printf ("%d × %d%s, %d × %d mm²",
|
||||
w, h, scale == 2 ? " @ 2" : "",
|
||||
wmm, hmm);
|
||||
|
||||
add_label_row (GTK_LIST_BOX (gen->priv->x_box), name, value, 0);
|
||||
monitor = gdk_display_get_monitor (display, i);
|
||||
|
||||
name = g_strdup_printf ("Monitor %d", i);
|
||||
manufacturer = gdk_monitor_get_manufacturer (monitor);
|
||||
model = gdk_monitor_get_model (monitor);
|
||||
value = g_strdup_printf ("%s%s%s",
|
||||
manufacturer ? manufacturer : "",
|
||||
manufacturer || model ? " " : "",
|
||||
model ? model : "");
|
||||
add_label_row (gen, list, name, value, 0);
|
||||
g_free (name);
|
||||
g_free (value);
|
||||
|
||||
gdk_monitor_get_geometry (monitor, &rect);
|
||||
scale = gdk_monitor_get_scale_factor (monitor);
|
||||
|
||||
value = g_strdup_printf ("%d × %d%s at %d, %d",
|
||||
rect.width, rect.height,
|
||||
scale == 2 ? " @ 2" : "",
|
||||
rect.x, rect.y);
|
||||
add_label_row (gen, list, "Geometry", value, 10);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%d × %d mm²",
|
||||
gdk_monitor_get_width_mm (monitor),
|
||||
gdk_monitor_get_height_mm (monitor));
|
||||
add_label_row (gen, list, "Size", value, 10);
|
||||
g_free (value);
|
||||
|
||||
add_check_row (gen, list, "Primary", gdk_monitor_is_primary (monitor), 10);
|
||||
|
||||
if (gdk_monitor_get_refresh_rate (monitor) != 0)
|
||||
value = g_strdup_printf ("%.2f Hz",
|
||||
0.001 * gdk_monitor_get_refresh_rate (monitor));
|
||||
else
|
||||
value = g_strdup ("unknown");
|
||||
add_label_row (gen, list, "Refresh rate", value, 10);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup (translate_subpixel_layout (gdk_monitor_get_subpixel_layout (monitor)));
|
||||
add_label_row (gen, list, "Subpixel layout", value, 10);
|
||||
g_free (value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,7 +485,7 @@ add_device (GtkInspectorGeneral *gen,
|
||||
break;
|
||||
}
|
||||
|
||||
add_label_row (GTK_LIST_BOX (gen->priv->device_box), name, value, 10);
|
||||
add_label_row (gen, GTK_LIST_BOX (gen->priv->device_box), name, value, 10);
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
@@ -477,7 +533,7 @@ add_device (GtkInspectorGeneral *gen,
|
||||
}
|
||||
|
||||
if (str->len > 0)
|
||||
add_label_row (GTK_LIST_BOX (gen->priv->device_box), "Axes", str->str, 20);
|
||||
add_label_row (gen, GTK_LIST_BOX (gen->priv->device_box), "Axes", str->str, 20);
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
|
||||
@@ -485,7 +541,7 @@ add_device (GtkInspectorGeneral *gen,
|
||||
if (n_touches > 0)
|
||||
{
|
||||
text = g_strdup_printf ("%d", n_touches);
|
||||
add_label_row (GTK_LIST_BOX (gen->priv->device_box), "Touches", text, 20);
|
||||
add_label_row (gen, GTK_LIST_BOX (gen->priv->device_box), "Touches", text, 20);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
@@ -532,7 +588,7 @@ add_seat (GtkInspectorGeneral *gen,
|
||||
}
|
||||
}
|
||||
|
||||
add_label_row (GTK_LIST_BOX (gen->priv->device_box), text, str->str, 0);
|
||||
add_label_row (gen, GTK_LIST_BOX (gen->priv->device_box), text, str->str, 0);
|
||||
g_free (text);
|
||||
g_string_free (str, FALSE);
|
||||
|
||||
@@ -596,16 +652,16 @@ keynav_failed (GtkWidget *widget, GtkDirectionType direction, GtkInspectorGenera
|
||||
if (direction == GTK_DIR_DOWN && widget == gen->priv->version_box)
|
||||
next = gen->priv->env_box;
|
||||
else if (direction == GTK_DIR_DOWN && widget == gen->priv->env_box)
|
||||
next = gen->priv->x_box;
|
||||
else if (direction == GTK_DIR_DOWN && widget == gen->priv->x_box)
|
||||
next = gen->priv->display_box;
|
||||
else if (direction == GTK_DIR_DOWN && widget == gen->priv->display_box)
|
||||
next = gen->priv->gl_box;
|
||||
else if (direction == GTK_DIR_DOWN && widget == gen->priv->gl_box)
|
||||
next = gen->priv->device_box;
|
||||
else if (direction == GTK_DIR_UP && widget == gen->priv->device_box)
|
||||
next = gen->priv->gl_box;
|
||||
else if (direction == GTK_DIR_UP && widget == gen->priv->gl_box)
|
||||
next = gen->priv->x_box;
|
||||
else if (direction == GTK_DIR_UP && widget == gen->priv->x_box)
|
||||
next = gen->priv->display_box;
|
||||
else if (direction == GTK_DIR_UP && widget == gen->priv->display_box)
|
||||
next = gen->priv->env_box;
|
||||
else if (direction == GTK_DIR_UP && widget == gen->priv->env_box)
|
||||
next = gen->priv->version_box;
|
||||
@@ -650,7 +706,7 @@ gtk_inspector_general_constructed (GObject *object)
|
||||
|
||||
g_signal_connect (gen->priv->version_box, "keynav-failed", G_CALLBACK (keynav_failed), gen);
|
||||
g_signal_connect (gen->priv->env_box, "keynav-failed", G_CALLBACK (keynav_failed), gen);
|
||||
g_signal_connect (gen->priv->x_box, "keynav-failed", G_CALLBACK (keynav_failed), gen);
|
||||
g_signal_connect (gen->priv->display_box, "keynav-failed", G_CALLBACK (keynav_failed), gen);
|
||||
g_signal_connect (gen->priv->gl_box, "keynav-failed", G_CALLBACK (keynav_failed), gen);
|
||||
g_signal_connect (gen->priv->device_box, "keynav-failed", G_CALLBACK (keynav_failed), gen);
|
||||
}
|
||||
@@ -666,7 +722,7 @@ gtk_inspector_general_class_init (GtkInspectorGeneralClass *klass)
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/general.ui");
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, version_box);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, env_box);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, x_box);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, display_box);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gl_box);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gtk_version);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gdk_backend);
|
||||
@@ -680,9 +736,9 @@ gtk_inspector_general_class_init (GtkInspectorGeneralClass *klass)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gtk_data_prefix);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gsettings_schema_dir);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, labels);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, x_display);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, x_composited);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, x_rgba);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, display_name);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, display_composited);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, display_rgba);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, device_box);
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -350,11 +350,11 @@
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkFrame" id="x_frame">
|
||||
<object class="GtkFrame" id="display_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">center</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="x_box">
|
||||
<object class="GtkListBox" id="display_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
@@ -368,7 +368,7 @@
|
||||
<property name="margin">10</property>
|
||||
<property name="spacing">40</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="x_display_label">
|
||||
<object class="GtkLabel" id="display_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Display</property>
|
||||
<property name="halign">start</property>
|
||||
@@ -377,7 +377,7 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="x_display">
|
||||
<object class="GtkLabel" id="display_name">
|
||||
<property name="visible">True</property>
|
||||
<property name="selectable">True</property>
|
||||
<property name="halign">end</property>
|
||||
@@ -403,7 +403,7 @@
|
||||
<property name="margin">10</property>
|
||||
<property name="spacing">40</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="x_rgba_label">
|
||||
<object class="GtkLabel" id="display_rgba_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">RGBA visual</property>
|
||||
<property name="halign">start</property>
|
||||
@@ -412,7 +412,7 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="x_rgba">
|
||||
<object class="GtkImage" id="display_rgba">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
@@ -437,7 +437,7 @@
|
||||
<property name="margin">10</property>
|
||||
<property name="spacing">40</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="x_composited_label">
|
||||
<object class="GtkLabel" id="display_composited_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Composited</property>
|
||||
<property name="halign">start</property>
|
||||
@@ -446,7 +446,7 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="x_composited">
|
||||
<object class="GtkImage" id="display_composited">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
@@ -578,9 +578,9 @@
|
||||
<widget name="gtk_exe_prefix_label"/>
|
||||
<widget name="gtk_data_prefix_label"/>
|
||||
<widget name="gsettings_schema_dir_label"/>
|
||||
<widget name="x_display_label"/>
|
||||
<widget name="x_rgba_label"/>
|
||||
<widget name="x_composited_label"/>
|
||||
<widget name="display_label"/>
|
||||
<widget name="display_rgba_label"/>
|
||||
<widget name="display_composited_label"/>
|
||||
</widgets>
|
||||
</object>
|
||||
<object class="GtkSizeGroup">
|
||||
@@ -589,7 +589,7 @@
|
||||
<widget name="version_frame"/>
|
||||
<widget name="gl_frame"/>
|
||||
<widget name="env_frame"/>
|
||||
<widget name="x_frame"/>
|
||||
<widget name="display_frame"/>
|
||||
<widget name="device_frame"/>
|
||||
</widgets>
|
||||
</object>
|
||||
|
||||
Reference in New Issue
Block a user