2011-11-24 15:34:52 +00:00
/*
* Copyright © 2011 Red Hat , Inc .
*
* 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 2 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
2014-01-23 12:57:27 +01:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2011-11-24 15:34:52 +00:00
*
* Authors : Peter Hutterer < peter . hutterer @ redhat . com >
* Bastien Nocera < hadess @ hadess . net >
*
*/
# include <config.h>
2013-04-04 12:05:24 +02:00
# ifdef FAKE_AREA
# include <gdk/gdk.h>
# endif /* FAKE_AREA */
2012-02-14 19:19:16 +00:00
# include <glib/gi18n-lib.h>
# include <gtk/gtk.h>
2016-06-06 14:49:13 +02:00
# include <gdesktop-enums.h>
2017-06-16 18:15:23 +02:00
# ifdef GDK_WINDOWING_X11
# include <gdk/gdkx.h>
# endif
# ifdef GDK_WINDOWING_WAYLAND
# include <gdk/gdkwayland.h>
# endif
2012-02-14 19:19:16 +00:00
2016-06-06 14:49:13 +02:00
# include "cc-wacom-device.h"
2013-07-23 12:45:20 +02:00
# include "cc-wacom-button-row.h"
2011-11-24 15:34:52 +00:00
# include "cc-wacom-page.h"
2011-11-28 18:23:28 +00:00
# include "cc-wacom-nav-button.h"
2012-02-16 17:24:55 +01:00
# include "cc-wacom-mapping-panel.h"
2012-01-16 17:18:32 +00:00
# include "cc-wacom-stylus-page.h"
2012-02-14 19:19:16 +00:00
# include "gsd-enums.h"
2013-04-08 18:44:12 +02:00
# include "calibrator-gui.h"
2017-06-16 18:15:23 +02:00
# include "gsd-input-helper.h"
2011-11-24 15:34:52 +00:00
# include <string.h>
# define WID(x) (GtkWidget *) gtk_builder_get_object (priv->builder, x)
2012-01-30 16:50:03 +00:00
# define CWID(x) (GtkContainer *) gtk_builder_get_object (priv->builder, x)
2012-02-14 19:19:16 +00:00
# define MWID(x) (GtkWidget *) gtk_builder_get_object (priv->mapping_builder, x)
2011-11-24 15:34:52 +00:00
G_DEFINE_TYPE ( CcWacomPage , cc_wacom_page , GTK_TYPE_BOX )
# define WACOM_PAGE_PRIVATE(o) \
( G_TYPE_INSTANCE_GET_PRIVATE ( ( o ) , CC_TYPE_WACOM_PAGE , CcWacomPagePrivate ) )
2012-01-13 11:51:27 +00:00
# define THRESHOLD_MISCLICK 15
# define THRESHOLD_DOUBLECLICK 7
2012-02-14 19:19:16 +00:00
enum {
MAPPING_DESCRIPTION_COLUMN ,
2012-06-26 11:06:07 +02:00
MAPPING_TYPE_COLUMN ,
2012-02-14 19:19:16 +00:00
MAPPING_BUTTON_COLUMN ,
2012-02-28 10:43:33 +00:00
MAPPING_BUTTON_DIRECTION ,
2012-02-14 19:19:16 +00:00
MAPPING_N_COLUMNS
} ;
2011-11-24 15:34:52 +00:00
struct _CcWacomPagePrivate
{
2012-01-26 17:49:56 +00:00
CcWacomPanel * panel ;
2016-06-06 14:49:13 +02:00
CcWacomDevice * stylus ;
CcWacomDevice * pad ;
2011-11-24 18:58:29 +00:00
GtkBuilder * builder ;
2011-11-28 18:23:28 +00:00
GtkWidget * nav ;
2012-01-16 17:18:32 +00:00
GtkWidget * notebook ;
2012-01-12 18:57:55 +00:00
CalibArea * area ;
2011-11-24 18:58:29 +00:00
GSettings * wacom_settings ;
2012-02-16 17:24:55 +01:00
2016-06-06 14:49:13 +02:00
GtkSizeGroup * header_group ;
2012-02-16 17:24:55 +01:00
/* Button mapping */
2012-02-14 19:19:16 +00:00
GtkBuilder * mapping_builder ;
2012-05-25 11:19:37 +01:00
GtkWidget * button_map ;
2012-06-26 11:06:07 +02:00
GtkListStore * action_store ;
2012-02-16 17:24:55 +01:00
/* Display mapping */
GtkWidget * mapping ;
GtkWidget * dialog ;
2013-07-26 17:29:20 +02:00
GCancellable * cancellable ;
2011-11-24 15:34:52 +00:00
} ;
/* Button combo box storage columns */
enum {
BUTTONNUMBER_COLUMN ,
BUTTONNAME_COLUMN ,
N_BUTTONCOLUMNS
} ;
/* Tablet mode combo box storage columns */
enum {
MODENUMBER_COLUMN ,
MODELABEL_COLUMN ,
N_MODECOLUMNS
} ;
/* Tablet mode options - keep in sync with .ui */
enum {
MODE_ABSOLUTE , /* stylus + eraser absolute */
MODE_RELATIVE , /* stylus + eraser relative */
} ;
2012-04-12 15:29:36 +02:00
/* Different types of layout for the tablet config */
enum {
LAYOUT_NORMAL , /* tracking mode, button mapping */
LAYOUT_REVERSIBLE , /* tracking mode, button mapping, left-hand orientation */
LAYOUT_SCREEN /* button mapping, calibration, display resolution */
} ;
static void
update_tablet_ui ( CcWacomPage * page ,
int layout ) ;
static int
2016-06-06 14:49:13 +02:00
get_layout_type ( CcWacomDevice * device )
2012-04-12 15:29:36 +02:00
{
int layout ;
2016-06-06 14:49:13 +02:00
if ( cc_wacom_device_get_integration_flags ( device ) &
( WACOM_DEVICE_INTEGRATED_DISPLAY | WACOM_DEVICE_INTEGRATED_SYSTEM ) )
2012-04-12 15:29:36 +02:00
layout = LAYOUT_SCREEN ;
2016-06-06 14:49:13 +02:00
else if ( cc_wacom_device_is_reversible ( device ) )
2012-04-12 15:29:36 +02:00
layout = LAYOUT_REVERSIBLE ;
else
layout = LAYOUT_NORMAL ;
return layout ;
}
2012-01-09 16:01:14 -08:00
static void
2016-06-24 17:38:08 +02:00
set_calibration ( CcWacomDevice * device ,
2013-04-19 16:37:59 +02:00
const gint display_width ,
const gint display_height ,
2016-06-24 17:38:08 +02:00
gdouble * cal ,
2013-04-19 16:37:59 +02:00
gsize ncal ,
GSettings * settings )
2012-01-09 16:01:14 -08:00
{
GVariant * current ; /* current calibration */
GVariant * array ; /* new calibration */
GVariant * * tmp ;
gsize nvalues ;
2013-04-19 16:37:59 +02:00
gint i ;
2012-01-09 16:01:14 -08:00
current = g_settings_get_value ( settings , " area " ) ;
2016-06-24 17:38:08 +02:00
g_variant_get_fixed_array ( current , & nvalues , sizeof ( gdouble ) ) ;
2012-01-12 18:57:55 +00:00
if ( ( ncal ! = 4 ) | | ( nvalues ! = 4 ) ) {
2012-01-10 19:45:02 +00:00
g_warning ( " Unable set set device calibration property. Got % " G_GSIZE_FORMAT " items to put in % " G_GSIZE_FORMAT " slots; expected %d items. \n " , ncal , nvalues , 4 ) ;
2012-01-09 16:01:14 -08:00
return ;
}
tmp = g_malloc ( nvalues * sizeof ( GVariant * ) ) ;
for ( i = 0 ; i < ncal ; i + + )
2016-06-24 17:38:08 +02:00
tmp [ i ] = g_variant_new_double ( cal [ i ] ) ;
2012-01-09 16:01:14 -08:00
2016-06-24 17:38:08 +02:00
array = g_variant_new_array ( G_VARIANT_TYPE_DOUBLE , tmp , nvalues ) ;
2012-01-09 16:01:14 -08:00
g_settings_set_value ( settings , " area " , array ) ;
g_free ( tmp ) ;
2013-04-19 16:37:59 +02:00
2017-06-20 15:55:26 -07:00
g_debug ( " Setting area to %f, %f, %f, %f (left/right/top/bottom) (last used resolution: %d x %d) " ,
2013-10-04 10:57:43 +02:00
cal [ 0 ] , cal [ 1 ] , cal [ 2 ] , cal [ 3 ] ,
display_width , display_height ) ;
2012-01-09 16:01:14 -08:00
}
2012-01-12 18:57:55 +00:00
static void
finish_calibration ( CalibArea * area ,
gpointer user_data )
2012-01-09 16:01:14 -08:00
{
2012-01-12 18:57:55 +00:00
CcWacomPage * page = ( CcWacomPage * ) user_data ;
CcWacomPagePrivate * priv = page - > priv ;
2012-01-10 19:19:24 +00:00
XYinfo axis ;
2016-06-24 17:38:08 +02:00
gdouble cal [ 4 ] ;
gint display_width , display_height ;
2012-01-09 16:01:14 -08:00
2017-06-20 12:09:39 -07:00
if ( calib_area_finish ( area ) ) {
calib_area_get_padding ( area , & axis ) ;
2012-01-10 19:19:24 +00:00
cal [ 0 ] = axis . x_min ;
2017-06-20 15:55:26 -07:00
cal [ 1 ] = axis . x_max ;
cal [ 2 ] = axis . y_min ;
2012-01-10 19:19:24 +00:00
cal [ 3 ] = axis . y_max ;
2012-01-12 18:57:55 +00:00
2013-04-19 16:37:59 +02:00
calib_area_get_display_size ( area , & display_width , & display_height ) ;
set_calibration ( page - > priv - > stylus ,
display_width ,
display_height ,
cal , 4 , priv - > wacom_settings ) ;
2013-10-08 08:46:41 +02:00
} else {
/* Reset the old values */
GVariant * old_calibration ;
old_calibration = g_object_get_data ( G_OBJECT ( page ) , " old-calibration " ) ;
g_settings_set_value ( page - > priv - > wacom_settings , " area " , old_calibration ) ;
g_object_set_data ( G_OBJECT ( page ) , " old-calibration " , NULL ) ;
2012-01-09 16:01:14 -08:00
}
2012-01-12 18:57:55 +00:00
calib_area_free ( area ) ;
2012-12-05 10:21:26 +01:00
priv - > area = NULL ;
2012-01-12 18:57:55 +00:00
gtk_widget_set_sensitive ( WID ( " button-calibrate " ) , TRUE ) ;
}
2017-06-16 18:15:23 +02:00
static GdkDevice *
cc_wacom_page_get_gdk_device ( CcWacomPage * page )
{
GsdDevice * gsd_device ;
GdkDevice * gdk_device = NULL ;
GdkDisplay * display ;
2018-05-26 10:02:34 +02:00
GdkSeat * seat ;
2017-06-16 18:15:23 +02:00
GList * slaves , * l ;
gsd_device = cc_wacom_device_get_device ( page - > priv - > stylus ) ;
g_return_val_if_fail ( GSD_IS_DEVICE ( gsd_device ) , NULL ) ;
display = gtk_widget_get_display ( GTK_WIDGET ( page ) ) ;
2018-05-26 10:02:34 +02:00
seat = gdk_display_get_default_seat ( display ) ;
slaves = gdk_seat_get_slaves ( seat , GDK_SEAT_CAPABILITY_TABLET_STYLUS ) ;
2017-06-16 18:15:23 +02:00
for ( l = slaves ; l & & ! gdk_device ; l = l - > next ) {
gchar * device_node = NULL ;
if ( gdk_device_get_source ( l - > data ) ! = GDK_SOURCE_PEN )
continue ;
# ifdef GDK_WINDOWING_X11
if ( GDK_IS_X11_DISPLAY ( display ) )
device_node = xdevice_get_device_node ( gdk_x11_device_get_id ( l - > data ) ) ;
# endif
# ifdef GDK_WINDOWING_WAYLAND
if ( GDK_IS_WAYLAND_DISPLAY ( display ) )
device_node = g_strdup ( gdk_wayland_device_get_node_path ( l - > data ) ) ;
# endif
if ( g_strcmp0 ( device_node , gsd_device_get_device_file ( gsd_device ) ) = = 0 )
gdk_device = l - > data ;
g_free ( device_node ) ;
}
g_list_free ( slaves ) ;
return gdk_device ;
}
2012-01-12 18:57:55 +00:00
static gboolean
run_calibration ( CcWacomPage * page ,
2013-10-08 08:46:41 +02:00
GVariant * old_calibration ,
2016-06-24 17:38:08 +02:00
gdouble * cal ,
2012-01-13 13:30:03 -08:00
gint monitor )
2012-01-12 18:57:55 +00:00
{
2012-07-18 14:23:29 +02:00
CcWacomPagePrivate * priv ;
2012-01-12 18:57:55 +00:00
g_assert ( page - > priv - > area = = NULL ) ;
2012-07-18 14:23:29 +02:00
priv = page - > priv ;
2012-12-05 10:21:26 +01:00
priv - > area = calib_area_new ( NULL ,
monitor ,
2017-06-16 18:15:23 +02:00
cc_wacom_page_get_gdk_device ( page ) ,
2012-12-05 10:21:26 +01:00
finish_calibration ,
page ,
THRESHOLD_MISCLICK ,
THRESHOLD_DOUBLECLICK ) ;
2012-01-12 18:57:55 +00:00
2013-10-08 08:46:41 +02:00
g_object_set_data_full ( G_OBJECT ( page ) ,
" old-calibration " ,
old_calibration ,
( GDestroyNotify ) g_variant_unref ) ;
2012-01-10 20:16:33 +00:00
return FALSE ;
2012-01-09 16:01:14 -08:00
}
static void
2013-06-03 19:21:35 +02:00
calibrate ( CcWacomPage * page )
2012-01-09 16:01:14 -08:00
{
2013-06-03 19:21:35 +02:00
CcWacomPagePrivate * priv ;
2016-06-24 17:38:08 +02:00
int i ;
2013-10-08 08:46:41 +02:00
GVariant * old_calibration , * * tmp , * array ;
2016-06-24 17:38:08 +02:00
gdouble * calibration ;
2012-01-12 15:26:16 +00:00
gsize ncal ;
2012-01-12 13:02:22 -08:00
gint monitor ;
2013-10-08 08:46:41 +02:00
GdkScreen * screen ;
2016-06-24 17:38:08 +02:00
GnomeRRScreen * rr_screen ;
GnomeRROutput * output ;
GError * error = NULL ;
gint x , y ;
2012-01-12 13:02:22 -08:00
2013-06-03 19:21:35 +02:00
priv = page - > priv ;
2016-06-24 17:38:08 +02:00
screen = gdk_screen_get_default ( ) ;
rr_screen = gnome_rr_screen_new ( screen , & error ) ;
if ( error ) {
g_warning ( " Could not connect to display manager: %s " , error - > message ) ;
g_error_free ( error ) ;
return ;
}
output = cc_wacom_device_get_output ( page - > priv - > stylus , rr_screen ) ;
gnome_rr_output_get_position ( output , & x , & y ) ;
monitor = gdk_screen_get_monitor_at_point ( screen , x , y ) ;
2012-01-12 13:02:22 -08:00
if ( monitor < 0 ) {
/* The display the tablet should be mapped to could not be located.
* This shouldn ' t happen if the EDID data is good . . .
*/
g_critical ( " Output associated with the tablet is not connected. Unable to calibrate. " ) ;
return ;
}
2012-01-12 15:26:16 +00:00
2013-10-08 08:46:41 +02:00
old_calibration = g_settings_get_value ( page - > priv - > wacom_settings , " area " ) ;
2016-06-24 17:38:08 +02:00
g_variant_get_fixed_array ( old_calibration , & ncal , sizeof ( gdouble ) ) ;
2012-01-12 15:23:53 +00:00
2012-01-12 15:26:16 +00:00
if ( ncal ! = 4 ) {
g_warning ( " Device calibration property has wrong length. Got % " G_GSIZE_FORMAT " items; expected %d. \n " , ncal , 4 ) ;
2012-01-12 15:23:53 +00:00
return ;
}
2012-01-09 16:01:14 -08:00
2016-06-24 17:38:08 +02:00
calibration = g_new0 ( gdouble , ncal ) ;
2013-04-04 12:05:24 +02:00
2013-10-08 08:46:41 +02:00
/* Reset the current values, to avoid old calibrations
* from interfering with the calibration */
tmp = g_malloc ( ncal * sizeof ( GVariant * ) ) ;
2016-06-24 17:38:08 +02:00
for ( i = 0 ; i < ncal ; i + + ) {
calibration [ i ] = 0.0 ;
tmp [ i ] = g_variant_new_double ( calibration [ i ] ) ;
}
2013-10-08 08:46:41 +02:00
2016-06-24 17:38:08 +02:00
array = g_variant_new_array ( G_VARIANT_TYPE_DOUBLE , tmp , ncal ) ;
2013-10-08 08:46:41 +02:00
g_settings_set_value ( page - > priv - > wacom_settings , " area " , array ) ;
g_free ( tmp ) ;
2012-01-12 15:23:53 +00:00
2013-10-08 08:46:41 +02:00
run_calibration ( page , old_calibration , calibration , monitor ) ;
2013-10-08 18:59:22 +02:00
g_free ( calibration ) ;
2013-06-03 19:21:35 +02:00
gtk_widget_set_sensitive ( WID ( " button-calibrate " ) , FALSE ) ;
2016-06-24 17:38:08 +02:00
g_object_unref ( rr_screen ) ;
}
2016-06-06 14:49:13 +02:00
2013-06-03 19:21:35 +02:00
static void
calibrate_button_clicked_cb ( GtkButton * button ,
CcWacomPage * page )
{
calibrate ( page ) ;
2012-01-12 15:23:53 +00:00
}
2012-01-09 16:01:14 -08:00
2012-12-20 12:07:00 +01:00
/* This avoids us crashing when a newer version of
* gnome - control - center has been used , and we load up an
* old one , as the action type if unknown to the old g - c - c */
static gboolean
2016-06-23 16:52:35 +02:00
action_type_is_valid ( GDesktopPadButtonAction action )
2012-12-20 12:07:00 +01:00
{
2016-06-23 16:52:35 +02:00
if ( action > = G_N_ELEMENTS ( action_table ) )
2012-12-20 12:07:00 +01:00
return FALSE ;
return TRUE ;
}
2012-02-14 19:19:16 +00:00
static void
2016-06-23 16:52:35 +02:00
create_row_from_button ( GtkWidget * list_box ,
guint button ,
GSettings * settings )
2012-02-14 19:19:16 +00:00
{
2013-07-23 12:45:20 +02:00
GtkWidget * row ;
2012-02-14 19:19:16 +00:00
2016-06-23 16:52:35 +02:00
row = cc_wacom_button_row_new ( button , settings ) ;
2013-07-23 12:45:20 +02:00
gtk_container_add ( GTK_CONTAINER ( list_box ) , row ) ;
gtk_widget_show ( row ) ;
2012-02-28 10:43:33 +00:00
}
static void
2013-07-23 12:45:20 +02:00
setup_button_mapping ( CcWacomPage * page )
2012-02-14 19:19:16 +00:00
{
2016-06-23 16:52:35 +02:00
CcWacomPagePrivate * priv = page - > priv ;
GDesktopPadButtonAction action ;
GtkWidget * list_box ;
guint i , n_buttons ;
GSettings * settings ;
2012-02-14 19:19:16 +00:00
2013-07-23 12:45:20 +02:00
list_box = MWID ( " shortcuts_list " ) ;
2016-06-23 16:52:35 +02:00
n_buttons = cc_wacom_device_get_num_buttons ( priv - > pad ) ;
2013-07-23 12:45:20 +02:00
2016-06-23 16:52:35 +02:00
for ( i = 0 ; i < n_buttons ; i + + ) {
settings = cc_wacom_device_get_button_settings ( priv - > pad , i ) ;
if ( ! settings )
2013-07-23 12:45:20 +02:00
continue ;
2012-06-26 11:06:07 +02:00
2016-06-23 16:52:35 +02:00
action = g_settings_get_enum ( settings , " action " ) ;
if ( ! action_type_is_valid ( action ) )
2013-07-23 12:45:20 +02:00
continue ;
2012-02-14 19:21:59 +00:00
2016-06-23 16:52:35 +02:00
create_row_from_button ( list_box , i , settings ) ;
2012-02-14 19:19:16 +00:00
}
}
2012-02-14 19:37:28 +00:00
static void
button_mapping_dialog_closed ( GtkDialog * dialog ,
int response_id ,
CcWacomPage * page )
{
CcWacomPagePrivate * priv ;
priv = page - > priv ;
gtk_widget_destroy ( MWID ( " button-mapping-dialog " ) ) ;
2012-12-05 10:21:26 +01:00
g_object_unref ( priv - > mapping_builder ) ;
priv - > mapping_builder = NULL ;
2012-02-14 19:37:28 +00:00
}
2012-02-14 15:51:54 +00:00
static void
2013-07-26 17:29:20 +02:00
show_button_mapping_dialog ( CcWacomPage * page )
2012-02-14 15:51:54 +00:00
{
2013-07-26 17:29:20 +02:00
GtkWidget * toplevel ;
GError * error = NULL ;
GtkWidget * dialog ;
2012-02-14 19:19:16 +00:00
CcWacomPagePrivate * priv ;
priv = page - > priv ;
2012-02-14 15:51:54 +00:00
2012-02-19 16:05:27 +01:00
g_assert ( priv - > mapping_builder = = NULL ) ;
priv - > mapping_builder = gtk_builder_new ( ) ;
2013-01-04 16:36:56 +01:00
gtk_builder_add_from_resource ( priv - > mapping_builder ,
" /org/gnome/control-center/wacom/button-mapping.ui " ,
& error ) ;
2012-02-14 15:51:54 +00:00
if ( error ! = NULL ) {
g_warning ( " Error loading UI file: %s " , error - > message ) ;
2012-02-19 16:05:27 +01:00
g_object_unref ( priv - > mapping_builder ) ;
priv - > mapping_builder = NULL ;
2012-02-14 15:51:54 +00:00
g_error_free ( error ) ;
return ;
}
2013-07-23 12:45:20 +02:00
setup_button_mapping ( page ) ;
2012-02-14 19:19:16 +00:00
2012-02-14 15:51:54 +00:00
dialog = MWID ( " button-mapping-dialog " ) ;
2012-02-19 16:05:27 +01:00
toplevel = gtk_widget_get_toplevel ( GTK_WIDGET ( page ) ) ;
gtk_window_set_transient_for ( GTK_WINDOW ( dialog ) , GTK_WINDOW ( toplevel ) ) ;
2012-02-14 15:51:54 +00:00
gtk_window_set_modal ( GTK_WINDOW ( dialog ) , TRUE ) ;
2012-02-14 19:37:28 +00:00
g_signal_connect ( G_OBJECT ( dialog ) , " response " ,
G_CALLBACK ( button_mapping_dialog_closed ) , page ) ;
2012-02-14 15:51:54 +00:00
gtk_widget_show ( dialog ) ;
2012-05-25 11:19:37 +01:00
priv - > button_map = dialog ;
g_object_add_weak_pointer ( G_OBJECT ( dialog ) , ( gpointer * ) & priv - > button_map ) ;
2012-02-14 15:51:54 +00:00
}
2013-07-26 17:29:20 +02:00
static void
set_osd_visibility_cb ( GObject * source_object ,
GAsyncResult * res ,
gpointer data )
{
GError * error = NULL ;
GVariant * result ;
CcWacomPage * page ;
page = CC_WACOM_PAGE ( data ) ;
result = g_dbus_proxy_call_finish ( G_DBUS_PROXY ( source_object ) , res , & error ) ;
if ( result = = NULL ) {
if ( ! g_error_matches ( error , G_IO_ERROR , G_IO_ERROR_CANCELLED ) ) {
g_printerr ( " Error setting OSD's visibility: %s \n " , error - > message ) ;
g_error_free ( error ) ;
show_button_mapping_dialog ( page ) ;
} else {
g_error_free ( error ) ;
return ;
}
}
}
static void
2016-06-06 14:49:13 +02:00
set_osd_visibility ( CcWacomPage * page )
2013-07-26 17:29:20 +02:00
{
CcWacomPagePrivate * priv ;
GDBusProxy * proxy ;
2016-06-06 14:49:13 +02:00
GsdDevice * gsd_device ;
const gchar * device_path ;
2013-07-26 17:29:20 +02:00
priv = page - > priv ;
proxy = cc_wacom_panel_get_gsd_wacom_bus_proxy ( priv - > panel ) ;
2016-06-06 14:49:13 +02:00
gsd_device = cc_wacom_device_get_device ( priv - > pad ) ;
device_path = gsd_device_get_device_file ( gsd_device ) ;
2013-07-26 17:29:20 +02:00
if ( proxy = = NULL ) {
show_button_mapping_dialog ( page ) ;
return ;
}
g_dbus_proxy_call ( proxy ,
2016-06-23 16:55:29 +02:00
" Show " ,
g_variant_new ( " (ob) " , device_path , TRUE ) ,
2013-07-26 17:29:20 +02:00
G_DBUS_CALL_FLAGS_NONE ,
- 1 ,
priv - > cancellable ,
set_osd_visibility_cb ,
page ) ;
}
static void
map_buttons_button_clicked_cb ( GtkButton * button ,
CcWacomPage * page )
{
2016-06-06 14:49:13 +02:00
set_osd_visibility ( page ) ;
2013-07-26 17:29:20 +02:00
}
2012-02-16 17:24:55 +01:00
static void
display_mapping_dialog_closed ( GtkDialog * dialog ,
int response_id ,
CcWacomPage * page )
{
CcWacomPagePrivate * priv ;
2012-04-12 15:29:36 +02:00
int layout ;
2012-02-16 17:24:55 +01:00
priv = page - > priv ;
gtk_widget_destroy ( priv - > dialog ) ;
priv - > dialog = NULL ;
priv - > mapping = NULL ;
2012-04-12 15:29:36 +02:00
layout = get_layout_type ( priv - > stylus ) ;
update_tablet_ui ( page , layout ) ;
2012-02-16 17:24:55 +01:00
}
static void
display_mapping_button_clicked_cb ( GtkButton * button ,
CcWacomPage * page )
{
CcWacomPagePrivate * priv ;
priv = page - > priv ;
g_assert ( priv - > mapping = = NULL ) ;
priv - > dialog = gtk_dialog_new_with_buttons ( _ ( " Display Mapping " ) ,
GTK_WINDOW ( gtk_widget_get_toplevel ( GTK_WIDGET ( page ) ) ) ,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
2013-07-19 15:59:26 +03:00
_ ( " _Close " ) ,
2012-02-16 17:24:55 +01:00
GTK_RESPONSE_ACCEPT ,
NULL ) ;
priv - > mapping = cc_wacom_mapping_panel_new ( ) ;
cc_wacom_mapping_panel_set_device ( CC_WACOM_MAPPING_PANEL ( priv - > mapping ) ,
priv - > stylus ) ;
gtk_container_add ( GTK_CONTAINER ( gtk_dialog_get_content_area ( GTK_DIALOG ( priv - > dialog ) ) ) ,
priv - > mapping ) ;
g_signal_connect ( G_OBJECT ( priv - > dialog ) , " response " ,
G_CALLBACK ( display_mapping_dialog_closed ) , page ) ;
gtk_widget_show_all ( priv - > dialog ) ;
2012-07-03 13:59:08 +02:00
g_object_add_weak_pointer ( G_OBJECT ( priv - > mapping ) , ( gpointer * ) & priv - > dialog ) ;
2012-02-16 17:24:55 +01:00
}
2011-11-24 15:34:52 +00:00
static void
tabletmode_changed_cb ( GtkComboBox * combo , gpointer user_data )
{
2016-06-06 14:49:13 +02:00
CcWacomPagePrivate * priv = CC_WACOM_PAGE ( user_data ) - > priv ;
GtkListStore * liststore ;
GtkTreeIter iter ;
gint mode ;
2011-11-24 15:34:52 +00:00
if ( ! gtk_combo_box_get_active_iter ( combo , & iter ) )
return ;
liststore = GTK_LIST_STORE ( WID ( " liststore-tabletmode " ) ) ;
gtk_tree_model_get ( GTK_TREE_MODEL ( liststore ) , & iter ,
MODENUMBER_COLUMN , & mode ,
- 1 ) ;
2016-06-06 14:49:13 +02:00
g_settings_set_enum ( priv - > wacom_settings , " mapping " , mode ) ;
2012-05-16 16:56:28 +02:00
}
2011-11-24 15:34:52 +00:00
static void
left_handed_toggled_cb ( GtkSwitch * sw , GParamSpec * pspec , gpointer * user_data )
{
2016-06-06 14:49:13 +02:00
CcWacomPagePrivate * priv = CC_WACOM_PAGE ( user_data ) - > priv ;
gboolean left_handed ;
2011-11-24 15:34:52 +00:00
2016-06-06 14:49:13 +02:00
left_handed = gtk_switch_get_active ( sw ) ;
g_settings_set_boolean ( priv - > wacom_settings , " left-handed " , left_handed ) ;
2011-11-24 15:34:52 +00:00
}
static void
set_left_handed_from_gsettings ( CcWacomPage * page )
{
2016-06-06 14:49:13 +02:00
CcWacomPagePrivate * priv = CC_WACOM_PAGE ( page ) - > priv ;
gboolean left_handed ;
left_handed = g_settings_get_boolean ( priv - > wacom_settings , " left-handed " ) ;
gtk_switch_set_active ( GTK_SWITCH ( WID ( " switch-left-handed " ) ) , left_handed ) ;
2011-11-24 15:34:52 +00:00
}
static void
2016-06-06 14:49:13 +02:00
set_mode_from_gsettings ( GtkComboBox * combo ,
CcWacomPage * page )
2011-11-24 15:34:52 +00:00
{
2016-06-06 14:49:13 +02:00
CcWacomPagePrivate * priv = page - > priv ;
GDesktopTabletMapping mapping ;
2011-11-24 15:34:52 +00:00
2016-06-06 14:49:13 +02:00
mapping = g_settings_get_enum ( priv - > wacom_settings , " mapping " ) ;
2011-11-24 15:34:52 +00:00
/* this must be kept in sync with the .ui file */
2016-06-06 14:49:13 +02:00
gtk_combo_box_set_active ( combo , mapping ) ;
2011-11-24 15:34:52 +00:00
}
static void
combobox_text_cellrenderer ( GtkComboBox * combo , int name_column )
{
GtkCellRenderer * renderer ;
renderer = gtk_cell_renderer_text_new ( ) ;
gtk_cell_layout_pack_start ( GTK_CELL_LAYOUT ( combo ) , renderer , TRUE ) ;
gtk_cell_layout_set_attributes ( GTK_CELL_LAYOUT ( combo ) , renderer ,
" text " , BUTTONNAME_COLUMN , NULL ) ;
}
2012-01-26 17:49:56 +00:00
static gboolean
display_clicked_cb ( GtkButton * button ,
CcWacomPage * page )
{
cc_wacom_panel_switch_to_panel ( page - > priv - > panel , " display " ) ;
return TRUE ;
}
2013-04-04 14:01:08 +02:00
static gboolean
mouse_clicked_cb ( GtkButton * button ,
CcWacomPage * page )
{
cc_wacom_panel_switch_to_panel ( page - > priv - > panel , " mouse " ) ;
return TRUE ;
}
2011-11-24 15:34:52 +00:00
/* Boilerplate code goes below */
static void
cc_wacom_page_get_property ( GObject * object ,
guint property_id ,
GValue * value ,
GParamSpec * pspec )
{
switch ( property_id )
{
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID ( object , property_id , pspec ) ;
}
}
static void
cc_wacom_page_set_property ( GObject * object ,
guint property_id ,
const GValue * value ,
GParamSpec * pspec )
{
switch ( property_id )
{
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID ( object , property_id , pspec ) ;
}
}
static void
cc_wacom_page_dispose ( GObject * object )
{
CcWacomPagePrivate * priv = CC_WACOM_PAGE ( object ) - > priv ;
2013-07-26 17:29:20 +02:00
if ( priv - > cancellable ) {
g_cancellable_cancel ( priv - > cancellable ) ;
g_clear_object ( & priv - > cancellable ) ;
}
2012-01-12 18:57:55 +00:00
if ( priv - > area ) {
calib_area_free ( priv - > area ) ;
priv - > area = NULL ;
}
2012-05-25 11:19:37 +01:00
if ( priv - > button_map ) {
gtk_widget_destroy ( priv - > button_map ) ;
priv - > button_map = NULL ;
}
2012-07-03 13:59:08 +02:00
if ( priv - > dialog ) {
gtk_widget_destroy ( priv - > dialog ) ;
priv - > dialog = NULL ;
}
2012-01-12 18:57:55 +00:00
if ( priv - > builder ) {
2011-11-24 15:34:52 +00:00
g_object_unref ( priv - > builder ) ;
priv - > builder = NULL ;
}
2016-06-06 14:49:13 +02:00
if ( priv - > header_group ) {
g_object_unref ( priv - > header_group ) ;
priv - > header_group = NULL ;
}
2012-05-25 12:14:27 +01:00
priv - > panel = NULL ;
2012-01-12 18:57:55 +00:00
2011-11-24 15:34:52 +00:00
G_OBJECT_CLASS ( cc_wacom_page_parent_class ) - > dispose ( object ) ;
}
static void
cc_wacom_page_class_init ( CcWacomPageClass * klass )
{
GObjectClass * object_class = G_OBJECT_CLASS ( klass ) ;
g_type_class_add_private ( klass , sizeof ( CcWacomPagePrivate ) ) ;
object_class - > get_property = cc_wacom_page_get_property ;
object_class - > set_property = cc_wacom_page_set_property ;
object_class - > dispose = cc_wacom_page_dispose ;
}
static void
cc_wacom_page_init ( CcWacomPage * self )
{
CcWacomPagePrivate * priv ;
GError * error = NULL ;
GtkComboBox * combo ;
GtkWidget * box ;
GtkSwitch * sw ;
char * objects [ ] = {
" main-grid " ,
" liststore-tabletmode " ,
" liststore-buttons " ,
" adjustment-tip-feel " ,
" adjustment-eraser-feel " ,
NULL
} ;
priv = self - > priv = WACOM_PAGE_PRIVATE ( self ) ;
priv - > builder = gtk_builder_new ( ) ;
2013-01-04 16:36:56 +01:00
gtk_builder_add_objects_from_resource ( priv - > builder ,
" /org/gnome/control-center/wacom/gnome-wacom-properties.ui " ,
objects ,
& error ) ;
2011-11-24 15:34:52 +00:00
if ( error ! = NULL ) {
g_warning ( " Error loading UI file: %s " , error - > message ) ;
g_object_unref ( priv - > builder ) ;
g_error_free ( error ) ;
return ;
}
box = WID ( " main-grid " ) ;
gtk_container_add ( GTK_CONTAINER ( self ) , box ) ;
gtk_widget_set_vexpand ( GTK_WIDGET ( box ) , TRUE ) ;
2012-01-09 16:01:14 -08:00
g_signal_connect ( WID ( " button-calibrate " ) , " clicked " ,
G_CALLBACK ( calibrate_button_clicked_cb ) , self ) ;
2012-02-14 15:51:54 +00:00
g_signal_connect ( WID ( " map-buttons-button " ) , " clicked " ,
G_CALLBACK ( map_buttons_button_clicked_cb ) , self ) ;
2012-01-09 16:01:14 -08:00
2011-11-24 15:34:52 +00:00
combo = GTK_COMBO_BOX ( WID ( " combo-tabletmode " ) ) ;
combobox_text_cellrenderer ( combo , MODELABEL_COLUMN ) ;
g_signal_connect ( G_OBJECT ( combo ) , " changed " ,
G_CALLBACK ( tabletmode_changed_cb ) , self ) ;
sw = GTK_SWITCH ( WID ( " switch-left-handed " ) ) ;
g_signal_connect ( G_OBJECT ( sw ) , " notify::active " ,
G_CALLBACK ( left_handed_toggled_cb ) , self ) ;
2012-01-26 17:49:56 +00:00
g_signal_connect ( G_OBJECT ( WID ( " display-link " ) ) , " activate-link " ,
G_CALLBACK ( display_clicked_cb ) , self ) ;
2013-04-04 14:01:08 +02:00
g_signal_connect ( G_OBJECT ( WID ( " mouse-link " ) ) , " activate-link " ,
G_CALLBACK ( mouse_clicked_cb ) , self ) ;
2012-02-16 17:24:55 +01:00
g_signal_connect ( G_OBJECT ( WID ( " display-mapping-button " ) ) , " clicked " ,
G_CALLBACK ( display_mapping_button_clicked_cb ) , self ) ;
2011-11-28 18:23:28 +00:00
priv - > nav = cc_wacom_nav_button_new ( ) ;
2012-02-16 08:46:20 +01:00
gtk_widget_set_halign ( priv - > nav , GTK_ALIGN_END ) ;
2013-11-19 22:34:39 +02:00
gtk_widget_set_margin_start ( priv - > nav , 10 ) ;
2016-06-24 19:21:37 +02:00
gtk_widget_show ( priv - > nav ) ;
gtk_container_add ( CWID ( " navigation-placeholder " ) , priv - > nav ) ;
2013-07-26 17:29:20 +02:00
priv - > cancellable = g_cancellable_new ( ) ;
2011-11-24 15:34:52 +00:00
}
2011-11-25 15:05:34 +00:00
static void
set_icon_name ( CcWacomPage * page ,
const char * widget_name ,
const char * icon_name )
{
CcWacomPagePrivate * priv ;
2013-01-04 16:36:56 +01:00
char * resource ;
2011-11-25 15:05:34 +00:00
priv = page - > priv ;
2013-01-04 16:36:56 +01:00
resource = g_strdup_printf ( " /org/gnome/control-center/wacom/%s.svg " , icon_name ) ;
gtk_image_set_from_resource ( GTK_IMAGE ( WID ( widget_name ) ) , resource ) ;
g_free ( resource ) ;
2011-11-25 15:05:34 +00:00
}
2012-01-30 16:50:03 +00:00
static void
remove_left_handed ( CcWacomPagePrivate * priv )
{
gtk_widget_destroy ( WID ( " label-left-handed " ) ) ;
gtk_widget_destroy ( WID ( " switch-left-handed " ) ) ;
}
static void
remove_display_link ( CcWacomPagePrivate * priv )
{
gtk_widget_destroy ( WID ( " display-link " ) ) ;
2012-02-16 00:36:17 -05:00
gtk_container_child_set ( CWID ( " main-grid " ) ,
2012-02-23 12:41:23 +01:00
WID ( " tablet-buttons-box " ) ,
2012-02-16 00:36:17 -05:00
" top_attach " , 2 , NULL ) ;
2012-01-30 16:50:03 +00:00
}
2013-04-04 14:01:08 +02:00
static void
remove_mouse_link ( CcWacomPagePrivate * priv )
{
gtk_widget_destroy ( WID ( " mouse-link " ) ) ;
gtk_container_child_set ( CWID ( " main-grid " ) ,
WID ( " tablet-buttons-box " ) ,
" top_attach " , 2 , NULL ) ;
}
2013-06-03 19:21:35 +02:00
static gboolean
has_monitor ( CcWacomPage * page )
{
2016-06-06 14:49:13 +02:00
WacomIntegrationFlags integration_flags ;
CcWacomPagePrivate * priv ;
priv = page - > priv ;
integration_flags = cc_wacom_device_get_integration_flags ( priv - > stylus ) ;
return ( ( integration_flags &
( WACOM_DEVICE_INTEGRATED_DISPLAY | WACOM_DEVICE_INTEGRATED_SYSTEM ) ) ! = 0 ) ;
2013-06-03 19:21:35 +02:00
}
2012-01-30 16:50:03 +00:00
static void
update_tablet_ui ( CcWacomPage * page ,
int layout )
{
2016-06-06 14:49:13 +02:00
WacomIntegrationFlags integration_flags ;
2012-01-30 16:50:03 +00:00
CcWacomPagePrivate * priv ;
priv = page - > priv ;
2016-06-06 14:49:13 +02:00
integration_flags = cc_wacom_device_get_integration_flags ( priv - > stylus ) ;
if ( ( integration_flags &
( WACOM_DEVICE_INTEGRATED_DISPLAY | WACOM_DEVICE_INTEGRATED_SYSTEM ) ) ! = 0 ) {
/* FIXME: Check we've got a puck, or a corresponding touchpad device */
2013-04-04 14:01:08 +02:00
remove_mouse_link ( priv ) ;
2016-06-06 14:49:13 +02:00
}
2012-01-30 16:50:03 +00:00
2012-04-12 15:29:36 +02:00
/* Hide the pad buttons if no pad is present */
gtk_widget_set_visible ( WID ( " map-buttons-button " ) , priv - > pad ! = NULL ) ;
2012-02-14 18:30:34 +00:00
2012-01-30 16:50:03 +00:00
switch ( layout ) {
case LAYOUT_NORMAL :
2012-12-05 10:21:26 +01:00
remove_left_handed ( priv ) ;
remove_display_link ( priv ) ;
2012-01-30 16:50:03 +00:00
break ;
case LAYOUT_REVERSIBLE :
2012-12-05 10:21:26 +01:00
remove_display_link ( priv ) ;
2012-01-30 16:50:03 +00:00
break ;
case LAYOUT_SCREEN :
2012-12-05 10:21:26 +01:00
remove_left_handed ( priv ) ;
2012-01-30 16:50:03 +00:00
gtk_widget_destroy ( WID ( " combo-tabletmode " ) ) ;
gtk_widget_destroy ( WID ( " label-trackingmode " ) ) ;
2012-02-16 16:38:21 +01:00
gtk_widget_destroy ( WID ( " display-mapping-button " ) ) ;
2012-01-30 16:50:03 +00:00
gtk_widget_show ( WID ( " button-calibrate " ) ) ;
2013-06-03 19:21:35 +02:00
gtk_widget_set_sensitive ( WID ( " button-calibrate " ) ,
2013-06-06 15:32:41 +02:00
has_monitor ( page ) ) ;
2012-01-30 16:50:03 +00:00
gtk_container_child_set ( CWID ( " main-grid " ) ,
WID ( " tablet-buttons-box " ) ,
" top_attach " , 1 , NULL ) ;
gtk_container_child_set ( CWID ( " main-grid " ) ,
WID ( " display-link " ) ,
" top_attach " , 2 , NULL ) ;
break ;
default :
g_assert_not_reached ( ) ;
}
}
2012-04-12 15:29:36 +02:00
gboolean
2016-06-06 14:49:13 +02:00
cc_wacom_page_update_tools ( CcWacomPage * page ,
CcWacomDevice * stylus ,
CcWacomDevice * pad )
2012-04-12 15:29:36 +02:00
{
CcWacomPagePrivate * priv ;
int layout ;
gboolean changed ;
/* Type of layout */
layout = get_layout_type ( stylus ) ;
priv = page - > priv ;
2015-03-13 13:11:10 -04:00
changed = ( priv - > stylus ! = stylus | | priv - > pad ! = pad ) ;
2012-04-12 15:29:36 +02:00
if ( ! changed )
return FALSE ;
priv - > stylus = stylus ;
priv - > pad = pad ;
update_tablet_ui ( CC_WACOM_PAGE ( page ) , layout ) ;
return TRUE ;
}
2011-11-24 15:34:52 +00:00
GtkWidget *
2016-06-06 14:49:13 +02:00
cc_wacom_page_new ( CcWacomPanel * panel ,
CcWacomDevice * stylus ,
CcWacomDevice * pad )
2011-11-24 15:34:52 +00:00
{
CcWacomPage * page ;
CcWacomPagePrivate * priv ;
2016-06-06 14:49:13 +02:00
g_return_val_if_fail ( CC_IS_WACOM_DEVICE ( stylus ) , NULL ) ;
g_return_val_if_fail ( ! pad | | CC_IS_WACOM_DEVICE ( pad ) , NULL ) ;
2012-02-14 18:30:34 +00:00
2011-11-24 15:34:52 +00:00
page = g_object_new ( CC_TYPE_WACOM_PAGE , NULL ) ;
priv = page - > priv ;
2012-05-25 12:14:27 +01:00
priv - > panel = panel ;
2012-04-12 15:29:36 +02:00
2015-03-13 13:11:10 -04:00
cc_wacom_page_update_tools ( page , stylus , pad ) ;
2011-11-24 15:34:52 +00:00
/* FIXME move this to construct */
2016-06-06 14:49:13 +02:00
priv - > wacom_settings = cc_wacom_device_get_settings ( stylus ) ;
2011-11-24 15:34:52 +00:00
set_mode_from_gsettings ( GTK_COMBO_BOX ( WID ( " combo-tabletmode " ) ) , page ) ;
2011-11-24 19:12:14 +00:00
2011-11-25 15:05:34 +00:00
/* Tablet name */
2016-06-06 14:49:13 +02:00
gtk_label_set_text ( GTK_LABEL ( WID ( " label-tabletmodel " ) ) , cc_wacom_device_get_name ( stylus ) ) ;
2011-11-25 15:05:34 +00:00
/* Left-handedness */
2016-06-06 14:49:13 +02:00
if ( cc_wacom_device_is_reversible ( stylus ) )
2011-11-24 19:12:14 +00:00
set_left_handed_from_gsettings ( page ) ;
2011-12-08 13:25:32 -08:00
2011-11-25 15:05:34 +00:00
/* Tablet icon */
2016-06-06 14:49:13 +02:00
set_icon_name ( page , " image-tablet " , cc_wacom_device_get_icon_name ( stylus ) ) ;
2012-02-20 16:50:44 +01:00
2011-11-24 15:34:52 +00:00
return GTK_WIDGET ( page ) ;
}
2011-11-28 18:23:28 +00:00
void
cc_wacom_page_set_navigation ( CcWacomPage * page ,
GtkNotebook * notebook ,
gboolean ignore_first_page )
{
CcWacomPagePrivate * priv ;
g_return_if_fail ( CC_IS_WACOM_PAGE ( page ) ) ;
priv = page - > priv ;
g_object_set ( G_OBJECT ( priv - > nav ) ,
" notebook " , notebook ,
" ignore-first " , ignore_first_page ,
NULL ) ;
}
2013-06-03 19:21:35 +02:00
void
cc_wacom_page_calibrate ( CcWacomPage * page )
{
g_return_if_fail ( CC_IS_WACOM_PAGE ( page ) ) ;
calibrate ( page ) ;
}
gboolean
cc_wacom_page_can_calibrate ( CcWacomPage * page )
{
g_return_val_if_fail ( CC_IS_WACOM_PAGE ( page ) ,
FALSE ) ;
return has_monitor ( page ) ;
}