Compare commits

...

62 Commits

Author SHA1 Message Date
Matthias Clasen f672a788f9 Add a fallback for unconverted backends
If the monitor vfuncs are not implemented in a display class,
fall back to providing a single monitor object representing
the entire screen. This is not meant to be 'good enough', it
is just to provide some implementation until the last backends
implement the monitor vfuncs. When that is the case, the
fallback should be removed.
2016-04-25 09:09:21 -04:00
Руслан Ижбулатов a4a5a4807f Implement GdkWin32Monitor subclass of GdkMonitor 2016-04-25 06:59:47 -04:00
Matthias Clasen d2d09fe40d inspector: Fix a unit mismatch
We are showing the refresh rate in Hertz, don't label it as mHz.
2016-04-20 13:59:28 -04:00
Matthias Clasen 4aed4cf40a Emit GdkMonitor::invalidate when a monitor is removed
We do this in the frontend, so backends don't have to do anything
special.
2016-04-11 21:06:27 -04:00
Matthias Clasen 194d73f432 Add a GdkMonitor::invalidate signal
This can be used to track when a monitor object is dropped by the
backend, without having to listen to display signals.
2016-04-11 20:57:43 -04:00
Matthias Clasen 6aa3d4cb37 window: Stop using gdk_screen_get_n_monitors 2016-04-10 23:52:00 -04:00
Matthias Clasen b10ac55551 settings: Stop comparing screen numbers
There is only one screen.
2016-04-10 23:45:36 -04:00
Matthias Clasen d4c187ffc7 window: Stop using screen width/height 2016-04-10 23:45:36 -04:00
Matthias Clasen 70cbbb148f treeview: Stop using screen width/height
Popups should always be placed relative to a monitor.
2016-04-10 23:45:36 -04:00
Matthias Clasen 7c1e9588b3 label: Stop using screen width/height
Popups should always be placed relative to a monitor.
2016-04-10 23:43:34 -04:00
Matthias Clasen a1f86d0878 combobox: Stop using screen width/height
Popups should always be placed relative to a monitor.
2016-04-10 23:42:57 -04:00
Matthias Clasen df19d99ebd gtk: Convert to new monitor api
Use the GdkDisplay monitor api instead of the GdkScreen one.
2016-04-10 23:01:10 -04:00
Matthias Clasen 1b86a7647b menu: Add new monitor api
This will work better with the new monitor api in gdk.
2016-04-10 22:59:53 -04:00
Matthias Clasen df589e3cf6 x11: Fix include guards in gdkx11monitor.h 2016-04-06 07:24:55 -04:00
Matthias Clasen 31bf2677ba wayland: Fix include guards for gdkwaylanddmonitor.h 2016-04-06 07:24:33 -04:00
Matthias Clasen fd586f7ade x11: Add gdk_x11_monitor_get_output 2016-04-05 16:53:04 -04:00
Matthias Clasen ec0b81e1eb broadway: Move monitor to its own files 2016-04-05 07:32:33 -04:00
Matthias Clasen e4e3d5c389 wayland: Minor cleanups 2016-04-05 07:17:18 -04:00
Matthias Clasen f18e5d1ccb x11: Move monitor to its own files 2016-04-05 07:16:56 -04:00
Matthias Clasen 05b023980a wayland: Add api to get wl_outputs 2016-04-04 23:23:42 -04:00
Matthias Clasen b348de178e wayland: Split off monitor into separate files 2016-04-04 23:15:42 -04:00
Matthias Clasen acb0f796a0 docs: Adapt to api change 2016-04-04 23:04:03 -04:00
Matthias Clasen 7201a76a62 inspector: Adapt to api change 2016-04-04 23:03:46 -04:00
Matthias Clasen 62a1c0a8b4 broadway: Adapt to api change 2016-04-04 23:03:30 -04:00
Matthias Clasen bbe69dbd4b x11: Adapt to api change 2016-04-04 23:03:03 -04:00
Matthias Clasen 589c7dd779 wayland: Adapt to api change 2016-04-04 23:02:41 -04:00
Matthias Clasen a4929f0d28 Redo display monitor api once more
Don't return an array.
2016-04-04 23:02:06 -04:00
Matthias Clasen 4775aa24c7 notify for ::workarea changes
The workarea generally changes whenever the geometry is modified.
2016-04-03 23:38:08 -04:00
Matthias Clasen e1a2f9bde7 More docs 2016-04-03 23:37:56 -04:00
Matthias Clasen ef0ae6464f Add docs 2016-04-03 23:28:07 -04:00
Matthias Clasen b7f3da23d1 x11: Fix hi-dpi handling 2016-04-03 22:38:29 -04:00
Matthias Clasen 7901fbfcf5 x11: fill in refresh rate 2016-04-03 20:23:17 -04:00
Matthias Clasen 73735acb29 Update todo 2016-04-03 20:03:02 -04:00
Matthias Clasen ab76987099 x11: Implement workarea vfunc 2016-04-03 20:01:58 -04:00
Matthias Clasen de2837056a Move some monitor apis to GdkDisplay 2016-04-03 20:01:20 -04:00
Matthias Clasen 0f37375c45 Implement workarea with a vfunc 2016-04-03 19:59:12 -04:00
Matthias Clasen d3b2830a95 x11: Bring back fullscreen-on-all-monitors support
It is unfortunate the EWMH requires Xinerama here - lets do this
without the caching that was previously there, I don't think it is
needed.
2016-04-03 16:53:32 -04:00
Matthias Clasen bdb891c015 inspector: Show primary too 2016-04-03 10:50:35 -04:00
Matthias Clasen 8ecf370601 inspector: Some code reorganization
Move the helper functions in the general tab around, and make them
more uniform.
2016-04-03 10:49:57 -04:00
Matthias Clasen 7a00f361f3 x11: Convert to new monitor api 2016-04-03 02:51:38 -04:00
Matthias Clasen 146fdaf2b8 x11: Drop Xinerama
It may come back after the monitor conversion.
2016-04-03 02:51:38 -04:00
Matthias Clasen f0c8a78c67 broadway: Port to new monitor api 2016-04-03 02:48:39 -04:00
Matthias Clasen b91c27c6f1 Fix up arrayification 2016-04-03 02:48:39 -04:00
Matthias Clasen 7aabbd39d9 inspector: Show more information for monitors 2016-04-03 02:48:38 -04:00
Matthias Clasen 12337c9751 inspector: Rename some variables 2016-04-02 19:48:50 -04:00
Matthias Clasen a267c20531 inspector: Show better monitor label
We can now show the manufacturer as well.
2016-04-02 19:22:36 -04:00
Matthias Clasen 08fef8929e Add primary as convenience api 2016-04-02 19:06:28 -04:00
Matthias Clasen ab4c086baf Some major reshuffling
Switch to array-based api in GdkDisplay, add monitor vfuncs in GdkDisplay,
and do away with the monitor vfuncs in GdkScreen.
2016-04-02 19:00:31 -04:00
Matthias Clasen d04d12e0b5 Some more renaming 2016-04-02 17:16:16 -04:00
Matthias Clasen b224d1df61 Add subpixel layout 2016-04-02 17:16:15 -04:00
Matthias Clasen ad8483caad Add refresh rate 2016-04-02 17:14:48 -04:00
Matthias Clasen 7c81188f65 A bunch more renaming 2016-04-02 17:13:44 -04:00
Matthias Clasen 26fa5b6906 wayland: Remove unused field 2016-04-02 17:12:59 -04:00
Matthias Clasen 2196be62e3 Fixup for properties
Construct-only properties must be writable.
2016-04-02 14:44:32 -04:00
Matthias Clasen cd2553c5c3 Rename physical size fields to _mm 2016-04-02 14:43:59 -04:00
Matthias Clasen 544d706e9e rename scale to scale_factor 2016-04-02 14:32:07 -04:00
Matthias Clasen d021874ea3 More TODO 2016-04-02 11:37:31 -04:00
Matthias Clasen 80811e74f7 Add a TODO 2016-04-02 11:31:14 -04:00
Matthias Clasen 1c0a93b3f8 screen: Implement monitor apis generically
Implement all the monitor-related GdkScreen apis based on
gdk_display_list_monitors.
2016-04-02 10:23:40 -04:00
Matthias Clasen c0228940bd wayland: Implement monitor objects 2016-04-02 10:23:31 -04:00
Matthias Clasen 10606363fd Add gdk_display_list_monitors
This follows our general direction of moving functionality
from GdkScreen to GdkDisplay.
2016-04-02 10:23:23 -04:00
Matthias Clasen 71b4a82f0d Fist cut at GdkMonitor
Add a simple object representing a monitor.
2016-04-02 10:23:13 -04:00
66 changed files with 4069 additions and 1784 deletions
+49 -1
View File
@@ -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
+1
View File
@@ -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" />
+29
View File
@@ -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>
+1
View File
@@ -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
+2
View File
@@ -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 \
+3
View File
@@ -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 \
+1
View File
@@ -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__
+46
View File
@@ -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__ */
+39
View File
@@ -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;
}
+3
View File
@@ -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
+37
View File
@@ -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)
{
}
+38
View File
@@ -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
+6 -56
View File
@@ -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;
+1
View File
@@ -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>
+265
View File
@@ -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);
}
+17
View File
@@ -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__ */
+10
View File
@@ -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
+611
View File
@@ -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 youre 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);
}
+95
View File
@@ -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__ */
+79
View File
@@ -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
View File
@@ -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
* doesnt 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);
}
/**
+3
View File
@@ -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
+27
View File
@@ -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
+2
View File
@@ -98,6 +98,8 @@ struct _GdkWaylandDisplay
GdkWaylandSelection *selection;
GPtrArray *monitors;
/* egl info */
EGLDisplay egl_display;
int egl_major_version;
+64
View File
@@ -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;
}
+39
View File
@@ -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
View File
@@ -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;
}
+1
View File
@@ -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>
+48
View File
@@ -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__ */
+6 -2
View File
@@ -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
+209
View File
@@ -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 ();
}
+6
View File
@@ -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__ */
+833
View File
@@ -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;
}
+57
View File
@@ -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
View File
@@ -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;
+1
View File
@@ -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__
+50
View File
@@ -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__ */
+3
View File
@@ -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 \
+39
View File
@@ -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 ();
}
+3
View File
@@ -100,6 +100,9 @@ struct _GdkX11Display
/* input GdkWindow list */
GList *input_windows;
GPtrArray *monitors;
int primary_monitor;
/* Startup notification */
gchar *startup_notification_id;
+102
View File
@@ -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;
}
+43
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+2 -9
View File
@@ -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
+6 -7
View File
@@ -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.
*/
+1
View File
@@ -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>
+48
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+5
View File
@@ -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
View File
@@ -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
View File
@@ -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))
{
+19 -22
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 × %dmm²",
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 ("%.2fHz",
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
View File
@@ -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>