display: Add new monitor apis

This follows our general direction of moving functionality
from GdkScreen to GdkDisplay.
This commit is contained in:
Matthias Clasen 2016-03-31 23:10:37 -04:00
parent 837244809e
commit 9d719b9989
3 changed files with 259 additions and 0 deletions

View File

@ -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);
}

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__ */

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