[gtk+] display: Add new monitor apis



commit 9d719b99893297bdd1675217ba9a7c8575cc0d80
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Mar 31 23:10:37 2016 -0400

    display: Add new monitor apis
    
    This follows our general direction of moving functionality
    from GdkScreen to GdkDisplay.

 gdk/gdkdisplay.c        |  232 +++++++++++++++++++++++++++++++++++++++++++++++
 gdk/gdkdisplay.h        |   17 ++++
 gdk/gdkdisplayprivate.h |   10 ++
 3 files changed, 259 insertions(+), 0 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 6150ef7..d932b50 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -71,6 +71,8 @@ enum {
   CLOSED,
   SEAT_ADDED,
   SEAT_REMOVED,
+  MONITOR_ADDED,
+  MONITOR_REMOVED,
   LAST_SIGNAL
 };
 
@@ -227,6 +229,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 +2502,197 @@ 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);
+
+  return GDK_DISPLAY_GET_CLASS (display)->get_n_monitors (display);
+}
+
+/**
+ * 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);
+
+  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);
+}
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index 6e06cc8..197b95f 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -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__ */
diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h
index 1b174d5..c8bc712 100644
--- a/gdk/gdkdisplayprivate.h
+++ b/gdk/gdkdisplayprivate.h
@@ -21,6 +21,7 @@
 #include "gdkdisplay.h"
 #include "gdkwindow.h"
 #include "gdkcursor.h"
+#include "gdkmonitor.h"
 #include "gdkinternals.h"
 
 G_BEGIN_DECLS
@@ -241,6 +242,11 @@ struct _GdkDisplayClass
 
   GdkSeat *              (*get_default_seat)           (GdkDisplay     *display);
 
+  int                    (*get_n_monitors)             (GdkDisplay     *display);
+  GdkMonitor *           (*get_monitor)                (GdkDisplay     *display,
+                                                        int             index);
+  GdkMonitor *           (*get_primary_monitor)        (GdkDisplay     *display);
+
   /* Signals */
   void                   (*opened)                     (GdkDisplay     *display);
   void (*closed) (GdkDisplay *display,
@@ -328,6 +334,10 @@ void                gdk_display_add_seat              (GdkDisplay       *display
                                                        GdkSeat          *seat);
 void                gdk_display_remove_seat           (GdkDisplay       *display,
                                                        GdkSeat          *seat);
+void                gdk_display_monitor_added         (GdkDisplay       *display,
+                                                       GdkMonitor       *monitor);
+void                gdk_display_monitor_removed       (GdkDisplay       *display,
+                                                       GdkMonitor       *monitor);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]