Commit 7e1bae01 authored by Alberts Muktupāvels's avatar Alberts Muktupāvels

backends: move CRTC code to its own file

Based on mutter commit:
mutter@a4ba38ee
parent 0b281d62
......@@ -31,6 +31,8 @@ libbackends_la_SOURCES = \
gf-backend.h \
gf-crtc-mode.c \
gf-crtc-private.h \
gf-crtc-xrandr-private.h \
gf-crtc-xrandr.c \
gf-crtc.c \
gf-direction.h \
gf-display-config-shared.h \
......
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
* Copyright (C) 2013-2017 Red Hat Inc.
* Copyright (C) 2017-2019 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GF_CRTC_XRANDR_PRIVATE_H
#define GF_CRTC_XRANDR_PRIVATE_H
#include <X11/extensions/Xrandr.h>
#include <xcb/randr.h>
#include "gf-crtc-private.h"
#include "gf-monitor-manager-xrandr-private.h"
G_BEGIN_DECLS
GfCrtc *gf_create_xrandr_crtc (GfMonitorManager *monitor_manager,
XRRCrtcInfo *xrandr_crtc,
RRCrtc crtc_id,
XRRScreenResources *resources);
gboolean gf_crtc_xrandr_set_config (GfCrtc *crtc,
xcb_randr_crtc_t xrandr_crtc,
xcb_timestamp_t timestamp,
int x,
int y,
xcb_randr_mode_t mode,
xcb_randr_rotation_t rotation,
xcb_randr_output_t *outputs,
int n_outputs,
xcb_timestamp_t *out_timestamp);
G_END_DECLS
#endif
/*
* Copyright (C) 2001, 2002 Havoc Pennington
* Copyright (C) 2002, 2003 Red Hat Inc.
* Some ICCCM manager selection code derived from fvwm2,
* Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
* Copyright (C) 2003 Rob Adams
* Copyright (C) 2004-2006 Elijah Newren
* Copyright (C) 2013-2017 Red Hat Inc.
* Copyright (C) 2017-2019 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gf-crtc-xrandr-private.h"
#include <X11/Xlib-xcb.h>
#define ALL_ROTATIONS (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)
#define ALL_TRANSFORMS ((1 << (GF_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
static GfMonitorTransform
gf_monitor_transform_from_xrandr (Rotation rotation)
{
static const GfMonitorTransform y_reflected_map[4] = {
GF_MONITOR_TRANSFORM_FLIPPED_180,
GF_MONITOR_TRANSFORM_FLIPPED_90,
GF_MONITOR_TRANSFORM_FLIPPED,
GF_MONITOR_TRANSFORM_FLIPPED_270
};
GfMonitorTransform ret;
switch (rotation & 0x7F)
{
default:
case RR_Rotate_0:
ret = GF_MONITOR_TRANSFORM_NORMAL;
break;
case RR_Rotate_90:
ret = GF_MONITOR_TRANSFORM_90;
break;
case RR_Rotate_180:
ret = GF_MONITOR_TRANSFORM_180;
break;
case RR_Rotate_270:
ret = GF_MONITOR_TRANSFORM_270;
break;
}
if (rotation & RR_Reflect_X)
return ret + 4;
else if (rotation & RR_Reflect_Y)
return y_reflected_map[ret];
else
return ret;
}
static GfMonitorTransform
gf_monitor_transform_from_xrandr_all (Rotation rotation)
{
GfMonitorTransform ret;
/* Handle the common cases first (none or all) */
if (rotation == 0 || rotation == RR_Rotate_0)
return (1 << GF_MONITOR_TRANSFORM_NORMAL);
/* All rotations and one reflection -> all of them by composition */
if ((rotation & ALL_ROTATIONS) &&
((rotation & RR_Reflect_X) || (rotation & RR_Reflect_Y)))
return ALL_TRANSFORMS;
ret = 1 << GF_MONITOR_TRANSFORM_NORMAL;
if (rotation & RR_Rotate_90)
ret |= 1 << GF_MONITOR_TRANSFORM_90;
if (rotation & RR_Rotate_180)
ret |= 1 << GF_MONITOR_TRANSFORM_180;
if (rotation & RR_Rotate_270)
ret |= 1 << GF_MONITOR_TRANSFORM_270;
if (rotation & (RR_Rotate_0 | RR_Reflect_X))
ret |= 1 << GF_MONITOR_TRANSFORM_FLIPPED;
if (rotation & (RR_Rotate_90 | RR_Reflect_X))
ret |= 1 << GF_MONITOR_TRANSFORM_FLIPPED_90;
if (rotation & (RR_Rotate_180 | RR_Reflect_X))
ret |= 1 << GF_MONITOR_TRANSFORM_FLIPPED_180;
if (rotation & (RR_Rotate_270 | RR_Reflect_X))
ret |= 1 << GF_MONITOR_TRANSFORM_FLIPPED_270;
return ret;
}
GfCrtc *
gf_create_xrandr_crtc (GfMonitorManager *monitor_manager,
XRRCrtcInfo *xrandr_crtc,
RRCrtc crtc_id,
XRRScreenResources *resources)
{
GfCrtc *crtc;
unsigned int i;
crtc = g_object_new (GF_TYPE_CRTC, NULL);
crtc->monitor_manager = monitor_manager;
crtc->crtc_id = crtc_id;
crtc->rect.x = xrandr_crtc->x;
crtc->rect.y = xrandr_crtc->y;
crtc->rect.width = xrandr_crtc->width;
crtc->rect.height = xrandr_crtc->height;
crtc->is_dirty = FALSE;
crtc->transform = gf_monitor_transform_from_xrandr (xrandr_crtc->rotation);
crtc->all_transforms = gf_monitor_transform_from_xrandr_all (xrandr_crtc->rotations);
for (i = 0; i < (guint) resources->nmode; i++)
{
if (resources->modes[i].id == xrandr_crtc->mode)
{
crtc->current_mode = g_list_nth_data (monitor_manager->modes, i);
break;
}
}
return crtc;
}
gboolean
gf_crtc_xrandr_set_config (GfCrtc *crtc,
xcb_randr_crtc_t xrandr_crtc,
xcb_timestamp_t timestamp,
int x,
int y,
xcb_randr_mode_t mode,
xcb_randr_rotation_t rotation,
xcb_randr_output_t *outputs,
int n_outputs,
xcb_timestamp_t *out_timestamp)
{
GfMonitorManager *monitor_manager;
GfMonitorManagerXrandr *monitor_manager_xrandr;
Display *xdisplay;
XRRScreenResources *resources;
xcb_connection_t *xcb_conn;
xcb_timestamp_t config_timestamp;
xcb_randr_set_crtc_config_cookie_t cookie;
xcb_randr_set_crtc_config_reply_t *reply;
xcb_generic_error_t *xcb_error;
monitor_manager = gf_crtc_get_monitor_manager (crtc);
monitor_manager_xrandr = GF_MONITOR_MANAGER_XRANDR (monitor_manager);
xdisplay = gf_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr);
resources = gf_monitor_manager_xrandr_get_resources (monitor_manager_xrandr);
xcb_conn = XGetXCBConnection (xdisplay);
config_timestamp = resources->configTimestamp;
cookie = xcb_randr_set_crtc_config (xcb_conn, xrandr_crtc,
timestamp, config_timestamp,
x, y, mode, rotation,
n_outputs, outputs);
xcb_error = NULL;
reply = xcb_randr_set_crtc_config_reply (xcb_conn, cookie, &xcb_error);
if (xcb_error || !reply)
{
g_free (xcb_error);
g_free (reply);
return FALSE;
}
*out_timestamp = reply->timestamp;
g_free (reply);
return TRUE;
}
......@@ -26,6 +26,8 @@
#define GF_MONITOR_MANAGER_XRANDR_PRIVATE_H
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include "gf-monitor-manager-private.h"
G_BEGIN_DECLS
......@@ -34,6 +36,10 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GfMonitorManagerXrandr, gf_monitor_manager_xrandr,
GF, MONITOR_MANAGER_XRANDR, GfMonitorManager)
Display *gf_monitor_manager_xrandr_get_xdisplay (GfMonitorManagerXrandr *xrandr);
XRRScreenResources *gf_monitor_manager_xrandr_get_resources (GfMonitorManagerXrandr *xrandr);
gboolean gf_monitor_manager_xrandr_handle_xevent (GfMonitorManagerXrandr *xrandr,
XEvent *event);
......
......@@ -37,16 +37,13 @@
#include <xcb/randr.h>
#include "gf-backend-x11-private.h"
#include "gf-crtc-private.h"
#include "gf-crtc-xrandr-private.h"
#include "gf-monitor-config-manager-private.h"
#include "gf-monitor-manager-xrandr-private.h"
#include "gf-monitor-private.h"
#include "gf-monitor-tiled-private.h"
#include "gf-output-private.h"
#define ALL_ROTATIONS (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)
#define ALL_TRANSFORMS ((1 << (GF_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
/* Look for DPI_FALLBACK in:
* http://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/xsettings/gsd-xsettings-manager.c
* for the reasoning
......@@ -177,8 +174,9 @@ gf_monitor_manager_xrandr_rebuild_derived (GfMonitorManager *manager,
static gboolean
xrandr_set_crtc_config (GfMonitorManagerXrandr *xrandr,
GfCrtc *crtc,
gboolean save_timestamp,
xcb_randr_crtc_t crtc,
xcb_randr_crtc_t xrandr_crtc,
xcb_timestamp_t timestamp,
gint x,
gint y,
......@@ -187,33 +185,16 @@ xrandr_set_crtc_config (GfMonitorManagerXrandr *xrandr,
xcb_randr_output_t *outputs,
gint n_outputs)
{
xcb_connection_t *xcb_conn;
xcb_timestamp_t config_timestamp;
xcb_randr_set_crtc_config_cookie_t cookie;
xcb_randr_set_crtc_config_reply_t *reply;
xcb_generic_error_t *xcb_error;
xcb_timestamp_t new_timestamp;
xcb_conn = XGetXCBConnection (xrandr->xdisplay);
config_timestamp = xrandr->resources->configTimestamp;
cookie = xcb_randr_set_crtc_config (xcb_conn, crtc,
timestamp, config_timestamp,
if (!gf_crtc_xrandr_set_config (crtc, xrandr_crtc, timestamp,
x, y, mode, rotation,
n_outputs, outputs);
xcb_error = NULL;
reply = xcb_randr_set_crtc_config_reply (xcb_conn, cookie, &xcb_error);
if (xcb_error || !reply)
{
g_free (xcb_error);
g_free (reply);
outputs, n_outputs,
&new_timestamp))
return FALSE;
}
if (save_timestamp)
xrandr->last_xrandr_set_timestamp = reply->timestamp;
g_free (reply);
xrandr->last_xrandr_set_timestamp = new_timestamp;
return TRUE;
}
......@@ -471,45 +452,6 @@ read_output_edid (GfMonitorManagerXrandr *xrandr,
return NULL;
}
static GfMonitorTransform
gf_monitor_transform_from_xrandr (Rotation rotation)
{
static const GfMonitorTransform y_reflected_map[4] = {
GF_MONITOR_TRANSFORM_FLIPPED_180,
GF_MONITOR_TRANSFORM_FLIPPED_90,
GF_MONITOR_TRANSFORM_FLIPPED,
GF_MONITOR_TRANSFORM_FLIPPED_270
};
GfMonitorTransform ret;
switch (rotation & 0x7F)
{
default:
case RR_Rotate_0:
ret = GF_MONITOR_TRANSFORM_NORMAL;
break;
case RR_Rotate_90:
ret = GF_MONITOR_TRANSFORM_90;
break;
case RR_Rotate_180:
ret = GF_MONITOR_TRANSFORM_180;
break;
case RR_Rotate_270:
ret = GF_MONITOR_TRANSFORM_270;
break;
}
if (rotation & RR_Reflect_X)
return ret + 4;
else if (rotation & RR_Reflect_Y)
return y_reflected_map[ret];
else
return ret;
}
static xcb_randr_rotation_t
gf_monitor_transform_to_xrandr (GfMonitorTransform transform)
{
......@@ -559,39 +501,6 @@ gf_monitor_transform_to_xrandr (GfMonitorTransform transform)
return rotation;
}
static GfMonitorTransform
gf_monitor_transform_from_xrandr_all (Rotation rotation)
{
GfMonitorTransform ret;
/* Handle the common cases first (none or all) */
if (rotation == 0 || rotation == RR_Rotate_0)
return (1 << GF_MONITOR_TRANSFORM_NORMAL);
/* All rotations and one reflection -> all of them by composition */
if ((rotation & ALL_ROTATIONS) &&
((rotation & RR_Reflect_X) || (rotation & RR_Reflect_Y)))
return ALL_TRANSFORMS;
ret = 1 << GF_MONITOR_TRANSFORM_NORMAL;
if (rotation & RR_Rotate_90)
ret |= 1 << GF_MONITOR_TRANSFORM_90;
if (rotation & RR_Rotate_180)
ret |= 1 << GF_MONITOR_TRANSFORM_180;
if (rotation & RR_Rotate_270)
ret |= 1 << GF_MONITOR_TRANSFORM_270;
if (rotation & (RR_Rotate_0 | RR_Reflect_X))
ret |= 1 << GF_MONITOR_TRANSFORM_FLIPPED;
if (rotation & (RR_Rotate_90 | RR_Reflect_X))
ret |= 1 << GF_MONITOR_TRANSFORM_FLIPPED_90;
if (rotation & (RR_Rotate_180 | RR_Reflect_X))
ret |= 1 << GF_MONITOR_TRANSFORM_FLIPPED_180;
if (rotation & (RR_Rotate_270 | RR_Reflect_X))
ret |= 1 << GF_MONITOR_TRANSFORM_FLIPPED_270;
return ret;
}
static gboolean
output_get_property_exists (GfMonitorManagerXrandr *xrandr,
GfOutput *output,
......@@ -1199,6 +1108,7 @@ apply_crtc_assignments (GfMonitorManager *manager,
crtc->rect.y + crtc->rect.height > height)
{
xrandr_set_crtc_config (xrandr,
crtc,
save_timestamp,
(xcb_randr_crtc_t) crtc->crtc_id,
XCB_CURRENT_TIME,
......@@ -1229,6 +1139,7 @@ apply_crtc_assignments (GfMonitorManager *manager,
continue;
xrandr_set_crtc_config (xrandr,
crtc,
save_timestamp,
(xcb_randr_crtc_t) crtc->crtc_id,
XCB_CURRENT_TIME,
......@@ -1286,6 +1197,7 @@ apply_crtc_assignments (GfMonitorManager *manager,
rotation = gf_monitor_transform_to_xrandr (crtc_info->transform);
if (!xrandr_set_crtc_config (xrandr,
crtc,
save_timestamp,
(xcb_randr_crtc_t) crtc->crtc_id,
XCB_CURRENT_TIME,
......@@ -1620,29 +1532,12 @@ gf_monitor_manager_xrandr_read_current (GfMonitorManager *manager)
for (i = 0; i < (guint) resources->ncrtc; i++)
{
XRRCrtcInfo *xrandr_crtc;
RRCrtc crtc_id;
GfCrtc *crtc;
xrandr_crtc = XRRGetCrtcInfo (xrandr->xdisplay, resources, resources->crtcs[i]);
crtc = g_object_new (GF_TYPE_CRTC, NULL);
crtc->monitor_manager = manager;
crtc->crtc_id = resources->crtcs[i];
crtc->rect.x = xrandr_crtc->x;
crtc->rect.y = xrandr_crtc->y;
crtc->rect.width = xrandr_crtc->width;
crtc->rect.height = xrandr_crtc->height;
crtc->is_dirty = FALSE;
crtc->transform = gf_monitor_transform_from_xrandr (xrandr_crtc->rotation);
crtc->all_transforms = gf_monitor_transform_from_xrandr_all (xrandr_crtc->rotations);
for (j = 0; j < (guint) resources->nmode; j++)
{
if (resources->modes[j].id == xrandr_crtc->mode)
{
crtc->current_mode = g_list_nth_data (manager->modes, j);
break;
}
}
crtc_id = resources->crtcs[i];
xrandr_crtc = XRRGetCrtcInfo (xrandr->xdisplay, resources, crtc_id);
crtc = gf_create_xrandr_crtc (manager, xrandr_crtc, crtc_id, resources);
manager->crtcs = g_list_append (manager->crtcs, crtc);
XRRFreeCrtcInfo (xrandr_crtc);
......@@ -2122,6 +2017,18 @@ gf_monitor_manager_xrandr_init (GfMonitorManagerXrandr *xrandr)
{
}
Display *
gf_monitor_manager_xrandr_get_xdisplay (GfMonitorManagerXrandr *xrandr)
{
return xrandr->xdisplay;
}
XRRScreenResources *
gf_monitor_manager_xrandr_get_resources (GfMonitorManagerXrandr *xrandr)
{
return xrandr->resources;
}
gboolean
gf_monitor_manager_xrandr_handle_xevent (GfMonitorManagerXrandr *xrandr,
XEvent *event)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment