Skip to content
Snippets Groups Projects
Commit 0a8c306b authored by Guido Gunther's avatar Guido Gunther :zzz:
Browse files

Merge branch 'gamma' into 'master'

Support org.gnome.Mutter.DisplayConfig.{Set,Get}CrtcGamma

Closes #13

See merge request Librem5/phosh!58
parents 273b7632 420334dc
No related branches found
No related tags found
No related merge requests found
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="gamma_control">
<copyright>
Copyright © 2015 Giulio camuffo
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
the copyright holders not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
</copyright>
<interface name="gamma_control_manager" version="1">
<request name="destroy" type="destructor"/>
<request name="get_gamma_control">
<arg name="id" type="new_id" interface="gamma_control"/>
<arg name="output" type="object" interface="wl_output"/>
</request>
</interface>
<interface name="gamma_control" version="1">
<enum name="error">
<entry name="invalid_gamma" value="0"/>
</enum>
<request name="destroy" type="destructor"/>
<request name="set_gamma">
<arg name="red" type="array"/>
<arg name="green" type="array"/>
<arg name="blue" type="array"/>
</request>
<request name="reset_gamma"/>
<event name="gamma_size">
<arg name="size" type="uint"/>
</event>
</interface>
</protocol>
......@@ -22,6 +22,7 @@ phosh_resources = gnome.compile_resources(
wl_protos = [
'/'.join([wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml']),
'../protocol/gamma-control.xml',
'../protocol/idle.xml',
'../protocol/phosh-private.xml',
'../protocol/wlr-input-inhibitor-unstable-v1.xml',
......
......@@ -10,8 +10,13 @@
#include "monitor-manager.h"
#include "monitor/monitor.h"
#include "gamma-control-client-protocol.h"
#include "phosh.h"
#include <gdk/gdkwayland.h>
static void phosh_monitor_manager_display_config_init (
PhoshDisplayDbusOrgGnomeMutterDisplayConfigIface *iface);
......@@ -52,6 +57,9 @@ phosh_monitor_manager_handle_get_resources (
PhoshMonitor *monitor = g_ptr_array_index (self->monitors, i);
GVariantBuilder transforms;
if (!monitor->done)
continue;
/* TODO: add transforms */
g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
g_variant_builder_add (&transforms, "u", 0);
......@@ -75,6 +83,9 @@ phosh_monitor_manager_handle_get_resources (
GVariantBuilder crtcs, modes, clones, properties;
g_autofree gchar *output_name = NULL;
if (!monitor->done)
continue;
g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
g_variant_builder_add (&crtcs, "u", i /* possible_crtc_index */);
g_variant_builder_init (&modes, G_VARIANT_TYPE ("au"));
......@@ -108,6 +119,9 @@ phosh_monitor_manager_handle_get_resources (
PhoshMonitor *monitor = g_ptr_array_index (self->monitors, i);
GArray *modes = monitor->modes;
if (!monitor->done)
continue;
for (int k = 0; k < modes->len; k++) {
PhoshMonitorMode *mode = &g_array_index (modes, PhoshMonitorMode, k);
g_variant_builder_add (&mode_builder, "(uxuudu)",
......@@ -135,6 +149,7 @@ phosh_monitor_manager_handle_get_resources (
return TRUE;
}
static gboolean
phosh_monitor_manager_handle_change_backlight (
PhoshDisplayDbusOrgGnomeMutterDisplayConfig *skeleton,
......@@ -143,11 +158,57 @@ phosh_monitor_manager_handle_change_backlight (
guint output_index,
gint value)
{
g_debug ("Unimplemented DBus call %s\n", __func__);
g_debug ("Unimplemented DBus call %s", __func__);
return FALSE;
}
struct get_wl_gamma_callback_data {
PhoshDisplayDbusOrgGnomeMutterDisplayConfig *skeleton;
GDBusMethodInvocation *invocation;
};
static void handle_wl_gamma_size(void *data, struct gamma_control *gamma_control,
uint32_t size) {
struct get_wl_gamma_callback_data *gamma_callback_data = data;
GBytes *red_bytes, *green_bytes, *blue_bytes;
GVariant *red_v, *green_v, *blue_v;
/* All known clients using libgnome-desktop's
gnome_rr_crtc_get_gamma only do so to get the size of the gamma
table. So don't bother getting the real table since this is not
supported by wlroots: https://github.com/swaywm/wlroots/pull/1059.
Return an empty table instead.
*/
size *= sizeof(unsigned short);
red_bytes = g_bytes_new_take (g_malloc0 (size), size);
green_bytes = g_bytes_new_take (g_malloc0 (size), size);
blue_bytes = g_bytes_new_take (g_malloc0 (size), size);
red_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), red_bytes, TRUE);
green_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), green_bytes, TRUE);
blue_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), blue_bytes, TRUE);
phosh_display_dbus_org_gnome_mutter_display_config_complete_get_crtc_gamma (
gamma_callback_data->skeleton,
gamma_callback_data->invocation,
red_v, green_v, blue_v);
g_bytes_unref (red_bytes);
g_bytes_unref (green_bytes);
g_bytes_unref (blue_bytes);
g_free (gamma_callback_data);
gamma_control_destroy (gamma_control);
}
static const struct
gamma_control_listener gamma_control_listener = {
.gamma_size = handle_wl_gamma_size,
};
static gboolean
phosh_monitor_manager_handle_get_crtc_gamma (
PhoshDisplayDbusOrgGnomeMutterDisplayConfig *skeleton,
......@@ -155,8 +216,47 @@ phosh_monitor_manager_handle_get_crtc_gamma (
guint serial,
guint crtc_id)
{
g_debug ("Unimplemented DBus call %s\n", __func__);
return FALSE;
PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (skeleton);
PhoshMonitor *monitor;
struct gamma_control *gamma_control;
struct gamma_control_manager *gamma_control_manager;
struct get_wl_gamma_callback_data *data;;
g_debug ("DBus call %s for crtc %d, serial %d", __func__, crtc_id, serial);
if (serial != self->serial) {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"The requested configuration is based on stale information");
return TRUE;
}
if (crtc_id >= self->monitors->len) {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Invalid crtc id %d", crtc_id);
return TRUE;
}
gamma_control_manager = phosh_shell_get_wl_gamma_control_manager ();
if (gamma_control_manager == NULL) {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_NOT_SUPPORTED,
"gamma control not supported");
return TRUE;
}
data = g_new0 (struct get_wl_gamma_callback_data, 1);
data->skeleton = skeleton;
data->invocation = invocation;
monitor = g_ptr_array_index (self->monitors, crtc_id);
gamma_control = gamma_control_manager_get_gamma_control (
gamma_control_manager,
monitor->wl_output);
gamma_control_add_listener (gamma_control, &gamma_control_listener, data);
return TRUE;
}
......@@ -170,8 +270,87 @@ phosh_monitor_manager_handle_set_crtc_gamma (
GVariant *green_v,
GVariant *blue_v)
{
g_debug ("Unimplemented DBus call %s\n", __func__);
return FALSE;
PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (skeleton);
PhoshMonitor *monitor;
unsigned short *red, *green, *blue;
GBytes *red_bytes, *green_bytes, *blue_bytes;
gsize size, dummy;
struct gamma_control_manager *gamma_control_manager;
struct gamma_control *gamma_control;
struct wl_array wl_red, wl_green, wl_blue;
g_debug ("DBus call %s for crtc %d, serial %d\n", __func__, crtc_id, serial);
if (serial != self->serial) {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"The requested configuration is based on stale information");
return TRUE;
}
if (crtc_id >= self->monitors->len) {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Invalid crtc id");
return TRUE;
}
gamma_control_manager = phosh_shell_get_wl_gamma_control_manager ();
if (!gamma_control_manager) {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_NOT_SUPPORTED,
"gamma control not supported");
return TRUE;
}
monitor = g_ptr_array_index (self->monitors, crtc_id);
red_bytes = g_variant_get_data_as_bytes (red_v);
green_bytes = g_variant_get_data_as_bytes (green_v);
blue_bytes = g_variant_get_data_as_bytes (blue_v);
size = g_bytes_get_size (red_bytes);
if (size != g_bytes_get_size (blue_bytes) || size != g_bytes_get_size (green_bytes)) {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_NOT_SUPPORTED,
"gamma for each color must have same size");
goto err;
}
red = (unsigned short*) g_bytes_get_data (red_bytes, &dummy);
green = (unsigned short*) g_bytes_get_data (green_bytes, &dummy);
blue = (unsigned short*) g_bytes_get_data (blue_bytes, &dummy);
wl_array_init (&wl_red);
wl_array_init (&wl_green);
wl_array_init (&wl_blue);
wl_array_add (&wl_red, size);
wl_array_add (&wl_green, size);
wl_array_add (&wl_blue, size);
memcpy(wl_red.data, red, size);
memcpy(wl_green.data, green, size);
memcpy(wl_blue.data, blue, size);
gamma_control = gamma_control_manager_get_gamma_control (
gamma_control_manager,
monitor->wl_output);
gamma_control_set_gamma(gamma_control, &wl_red, &wl_green, &wl_blue);
gamma_control_destroy (gamma_control);
phosh_display_dbus_org_gnome_mutter_display_config_complete_set_crtc_gamma (
skeleton,
invocation);
wl_array_release (&wl_red);
wl_array_release (&wl_green);
wl_array_release (&wl_blue);
err:
g_bytes_unref (red_bytes);
g_bytes_unref (green_bytes);
g_bytes_unref (blue_bytes);
return TRUE;
}
#define MODE_FORMAT "(siiddada{sv})"
......@@ -206,6 +385,9 @@ phosh_monitor_manager_handle_get_current_state (
g_autofree gchar *serial = NULL;
g_autofree gchar *connector = NULL;
if (!monitor->done)
continue;
g_variant_builder_init (&modes_builder, G_VARIANT_TYPE (MODES_FORMAT));
for (int k = 0; k < monitor->modes->len; k++) {
......@@ -264,6 +446,9 @@ phosh_monitor_manager_handle_get_current_state (
g_autofree gchar *serial = NULL;
g_autofree gchar *connector = NULL;
if (!monitor->done)
continue;
connector = g_strdup_printf ("DP%d", i);
serial = g_strdup_printf ("00%d", i);
g_variant_builder_init (&logical_monitor_monitors_builder,
......@@ -318,7 +503,7 @@ phosh_monitor_manager_handle_apply_monitors_config (
GVariant *logical_monitor_configs_variant,
GVariant *properties_variant)
{
g_debug ("Stubbed DBus call %s\n", __func__);
g_debug ("Stubbed DBus call %s", __func__);
/* Just do nothing for the moment */
phosh_display_dbus_org_gnome_mutter_display_config_complete_apply_monitors_config (
......@@ -346,7 +531,7 @@ on_name_acquired (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
g_debug ("Acquired name %s\n", name);
g_debug ("Acquired name %s", name);
}
......@@ -355,7 +540,7 @@ on_name_lost (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
g_debug ("Lost or failed to acquire name %s\n", name);
g_debug ("Lost or failed to acquire name %s", name);
}
......
......@@ -13,9 +13,11 @@
G_DECLARE_FINAL_TYPE (PhoshMonitorManager, phosh_monitor_manager, PHOSH, MONITOR_MANAGER,
PhoshDisplayDbusOrgGnomeMutterDisplayConfigSkeleton)
PhoshMonitorManager * phosh_monitor_manager_new (void);
void phosh_monitor_manager_add_monitor (PhoshMonitorManager *self,
PhoshMonitor *monitor);
PhoshMonitor * phosh_monitor_manager_get_monitor (PhoshMonitorManager *self,
guint monitor);
guint phosh_monitor_manager_get_num_monitors (PhoshMonitorManager *self);
PhoshMonitorManager * phosh_monitor_manager_new (void);
void phosh_monitor_manager_add_monitor (PhoshMonitorManager *self,
PhoshMonitor *monitor);
PhoshMonitor * phosh_monitor_manager_get_monitor (PhoshMonitorManager *self,
guint monitor);
guint phosh_monitor_manager_get_num_monitors (PhoshMonitorManager *self);
void phosh_monitor_manager_set_gamma_control_manager (PhoshMonitorManager *self,
gpointer *gamma);
......@@ -26,7 +26,7 @@
#include "wlr-input-inhibitor-unstable-v1-client-protocol.h"
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
#include "xdg-shell-client-protocol.h"
#include "gamma-control-client-protocol.h"
#include "phosh.h"
#include "monitor/monitor.h" /* FIXME: move upwards? */
......@@ -70,6 +70,7 @@ typedef struct
struct org_kde_kwin_idle *idle_manager;
struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager;
struct zwlr_input_inhibitor_v1 *input_inhibitor;
struct gamma_control_manager *gamma_control_manager;
struct wl_seat *wl_seat;
struct xdg_wm_base *xdg_wm_base;
......@@ -653,24 +654,36 @@ registry_handle_global (void *data,
PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
struct wl_output *output;
if (!strcmp (interface, "phosh_private")) {
priv->mshell = wl_registry_bind (registry, name,
&phosh_private_interface, 1);
priv->mshell = wl_registry_bind (
registry,
name,
&phosh_private_interface,
1);
} else if (!strcmp (interface, zwlr_layer_shell_v1_interface.name)) {
priv->layer_shell = wl_registry_bind (registry, name,
&zwlr_layer_shell_v1_interface, 1);
priv->layer_shell = wl_registry_bind (
registry,
name,
&zwlr_layer_shell_v1_interface,
1);
} else if (!strcmp (interface, "wl_output")) {
output = wl_registry_bind (registry, name,
&wl_output_interface, 1);
phosh_monitor_manager_add_monitor (priv->monitor_manager,
phosh_monitor_new_from_wl_output(output));
output = wl_registry_bind (
registry,
name,
&wl_output_interface, 2);
phosh_monitor_manager_add_monitor (
priv->monitor_manager,
phosh_monitor_new_from_wl_output(output));
} else if (!strcmp (interface, "org_kde_kwin_idle")) {
priv->idle_manager = wl_registry_bind (registry,
name,
&org_kde_kwin_idle_interface, 1);
priv->idle_manager = wl_registry_bind (
registry,
name,
&org_kde_kwin_idle_interface,
1);
} else if (!strcmp(interface, "wl_seat")) {
priv->wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 1);
priv->wl_seat = wl_registry_bind(
registry, name, &wl_seat_interface,
1);
} else if (!strcmp(interface, zwlr_input_inhibit_manager_v1_interface.name)) {
priv->input_inhibit_manager = wl_registry_bind(
registry,
......@@ -678,7 +691,17 @@ registry_handle_global (void *data,
&zwlr_input_inhibit_manager_v1_interface,
1);
} else if (!strcmp(interface, xdg_wm_base_interface.name)) {
priv->xdg_wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
priv->xdg_wm_base = wl_registry_bind(
registry,
name,
&xdg_wm_base_interface,
1);
} else if (!strcmp(interface, gamma_control_manager_interface.name)) {
priv->gamma_control_manager = wl_registry_bind(
registry,
name,
&gamma_control_manager_interface,
1);
}
}
......@@ -768,7 +791,7 @@ phosh_shell_constructed (GObject *object)
{
PhoshShell *self = PHOSH_SHELL (object);
PhoshShellPrivate *priv = phosh_shell_get_instance_private (self);
guint num_mon;;
guint num_mon;
G_OBJECT_CLASS (phosh_shell_parent_class)->constructed (object);
......@@ -788,26 +811,34 @@ phosh_shell_constructed (GObject *object)
/* Wait until we have been notified about the compositor,
* shell, and shell helper objects */
num_mon = phosh_monitor_manager_get_num_monitors (priv->monitor_manager);
if (!num_mon || !priv->layer_shell || !priv->idle_manager ||
!priv->input_inhibit_manager || !priv->mshell || !priv->xdg_wm_base)
if (!num_mon ||
!priv->layer_shell ||
!priv->idle_manager ||
!priv->input_inhibit_manager ||
!priv->mshell ||
!priv->xdg_wm_base ||
!priv->gamma_control_manager)
wl_display_roundtrip (priv->display);
num_mon = phosh_monitor_manager_get_num_monitors (priv->monitor_manager);
if (!num_mon || !priv->layer_shell || !priv->idle_manager ||
!priv->input_inhibit_manager || !priv->xdg_wm_base) {
if (!num_mon ||
!priv->layer_shell ||
!priv->idle_manager ||
!priv->input_inhibit_manager ||
!priv->xdg_wm_base ||
!priv->gamma_control_manager) {
g_error ("Could not find needed globals\n"
"outputs: %d, layer_shell: %p, seat: %p, "
"inhibit: %p, xdg_wm: %p\n",
"inhibit: %p, xdg_wm: %p, gamma %p\n",
num_mon, priv->layer_shell, priv->idle_manager,
priv->input_inhibit_manager, priv->xdg_wm_base);
priv->input_inhibit_manager, priv->xdg_wm_base,
priv->gamma_control_manager);
}
if (!priv->mshell) {
g_info ("Could not find phosh global, disabling some features\n");
}
gtk_icon_theme_add_resource_path (gtk_icon_theme_get_default (),
"/sm/puri/phosh/icons");
env_setup ();
css_setup (self);
panel_create (self);
......@@ -884,6 +915,14 @@ phosh_shell_get_wl_layer_shell ()
}
gpointer
phosh_shell_get_wl_gamma_control_manager ()
{
PhoshShellPrivate *priv = phosh_shell_get_instance_private (_phosh);
return priv->gamma_control_manager;
}
PhoshMonitor *
phosh_shell_get_primary_monitor ()
{
......
......@@ -31,4 +31,5 @@ PhoshMonitor *phosh_shell_get_primary_monitor ();
/* Phosh keeps track of the wayland globals */
gpointer phosh_shell_get_wl_layer_shell ();
gpointer phosh_shell_get_wl_gamma_control_manager ();
#endif /* PHOSH_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment