mirror of https://github.com/GNOME/gimp.git
added #define GIMP_CONTROLLER_PARAM_SERIALIZE. Made all properties
2004-06-16 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpcontroller.[ch]: added #define GIMP_CONTROLLER_PARAM_SERIALIZE. Made all properties serializable. * modules/controller_linux_input.c: made "device-name" serializable. * app/config/gimpconfig-params.h: added macro GIMP_CONFIG_INSTALL_PROP_POINTER() which needs to be handled by custom (de)serialize_property() implementations. * app/config/gimpconfig-deserialize.c * app/config/gimpconfig-serialize.c: made object (de)serialization work for object properties which are *not* GIMP_PARAM_AGGREGATE. Write/parse the exact type of the object to create to enable this. * app/core/gimpmarshal.list: new marshaller for GimpControllerInfo. * app/widgets/gimpcontrollerinfo.[ch]: implement GimpConfigInterface and add "controller" and "mapping" properties. Add "event-mapped" signal which carries the action_name. * app/widgets/gimpcontrollers.c: removed all deserialization code and simply (de)serialize the controller container. Install a container handler for "event-mapped" and do the action_name -> action mapping in the callback. * etc/controllerrc: regenerated with new syntax. Delete your old one!
This commit is contained in:
parent
429b090fd4
commit
3a7f7d54e7
30
ChangeLog
30
ChangeLog
|
@ -1,3 +1,33 @@
|
|||
2004-06-16 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* libgimpwidgets/gimpcontroller.[ch]: added #define
|
||||
GIMP_CONTROLLER_PARAM_SERIALIZE. Made all properties serializable.
|
||||
|
||||
* modules/controller_linux_input.c: made "device-name"
|
||||
serializable.
|
||||
|
||||
* app/config/gimpconfig-params.h: added macro
|
||||
GIMP_CONFIG_INSTALL_PROP_POINTER() which needs to be handled
|
||||
by custom (de)serialize_property() implementations.
|
||||
|
||||
* app/config/gimpconfig-deserialize.c
|
||||
* app/config/gimpconfig-serialize.c: made object (de)serialization
|
||||
work for object properties which are *not* GIMP_PARAM_AGGREGATE.
|
||||
Write/parse the exact type of the object to create to enable this.
|
||||
|
||||
* app/core/gimpmarshal.list: new marshaller for GimpControllerInfo.
|
||||
|
||||
* app/widgets/gimpcontrollerinfo.[ch]: implement GimpConfigInterface
|
||||
and add "controller" and "mapping" properties. Add "event-mapped"
|
||||
signal which carries the action_name.
|
||||
|
||||
* app/widgets/gimpcontrollers.c: removed all deserialization code
|
||||
and simply (de)serialize the controller container. Install a
|
||||
container handler for "event-mapped" and do the action_name ->
|
||||
action mapping in the callback.
|
||||
|
||||
* etc/controllerrc: regenerated with new syntax. Delete your old one!
|
||||
|
||||
2004-06-16 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/widgets/gimpcontrollerwheel.c
|
||||
|
|
|
@ -666,7 +666,33 @@ gimp_config_deserialize_object (GValue *value,
|
|||
prop_object = g_value_get_object (value);
|
||||
|
||||
if (! prop_object)
|
||||
{
|
||||
/* if the object property is not GIMP_PARAM_AGGREGATE, read
|
||||
* the type of the object and create it
|
||||
*/
|
||||
if (! (prop_spec->flags & GIMP_PARAM_AGGREGATE))
|
||||
{
|
||||
gchar *type_name;
|
||||
GType type;
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, &type_name))
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
type = g_type_from_name (type_name);
|
||||
g_free (type_name);
|
||||
|
||||
if (! g_type_is_a (type, prop_spec->value_type))
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
prop_object = g_object_new (type, NULL);
|
||||
|
||||
g_value_take_object (value, prop_object);
|
||||
}
|
||||
else
|
||||
{
|
||||
return G_TOKEN_RIGHT_PAREN;
|
||||
}
|
||||
}
|
||||
|
||||
config_iface = GIMP_CONFIG_GET_INTERFACE (prop_object);
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
|
|||
flags | GIMP_CONFIG_PARAM_FLAGS))
|
||||
|
||||
|
||||
/* object properties are _not_ G_PARAM_CONSTRUCT */
|
||||
/* object and pointer properties are _not_ G_PARAM_CONSTRUCT */
|
||||
|
||||
#define GIMP_CONFIG_INSTALL_PROP_OBJECT(class, id,\
|
||||
name, blurb, object_type, flags)\
|
||||
|
@ -233,5 +233,12 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
|
|||
flags |\
|
||||
G_PARAM_READWRITE | GIMP_PARAM_SERIALIZE))
|
||||
|
||||
#define GIMP_CONFIG_INSTALL_PROP_POINTER(class, id,\
|
||||
name, blurb, flags)\
|
||||
g_object_class_install_property (class, id,\
|
||||
g_param_spec_pointer (name, NULL, blurb,\
|
||||
flags |\
|
||||
G_PARAM_READWRITE | GIMP_PARAM_SERIALIZE))
|
||||
|
||||
|
||||
#endif /* __GIMP_CONFIG_PARAMS_H__ */
|
||||
|
|
|
@ -257,8 +257,7 @@ gimp_config_serialize_property (GimpConfig *config,
|
|||
|
||||
if (! success)
|
||||
{
|
||||
if (G_VALUE_HOLDS_OBJECT (&value) &&
|
||||
(param_spec->flags & GIMP_PARAM_AGGREGATE))
|
||||
if (G_VALUE_HOLDS_OBJECT (&value))
|
||||
{
|
||||
GimpConfigInterface *config_iface = NULL;
|
||||
GimpConfig *prop_object;
|
||||
|
@ -274,6 +273,17 @@ gimp_config_serialize_property (GimpConfig *config,
|
|||
{
|
||||
gimp_config_writer_open (writer, param_spec->name);
|
||||
|
||||
/* if the object property is not GIMP_PARAM_AGGREGATE,
|
||||
* deserializing will need to know the exact type
|
||||
* in order to create the object
|
||||
*/
|
||||
if (! (param_spec->flags & GIMP_PARAM_AGGREGATE))
|
||||
{
|
||||
GType object_type = G_TYPE_FROM_INSTANCE (prop_object);
|
||||
|
||||
gimp_config_writer_string (writer, g_type_name (object_type));
|
||||
}
|
||||
|
||||
success = config_iface->serialize (prop_object, writer, NULL);
|
||||
|
||||
if (success)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
BOOLEAN: BOOLEAN
|
||||
BOOLEAN: ENUM, INT
|
||||
BOOLEAN: OBJECT, POINTER
|
||||
BOOLEAN: OBJECT, POINTER, STRING
|
||||
|
||||
VOID: BOXED
|
||||
VOID: DOUBLE
|
||||
|
|
|
@ -22,20 +22,46 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
#include "libgimpwidgets/gimpcontroller.h"
|
||||
|
||||
#include "widgets-types.h"
|
||||
|
||||
#include "config/gimpconfig.h"
|
||||
#include "config/gimpconfig-params.h"
|
||||
#include "config/gimpconfigwriter.h"
|
||||
#include "config/gimpscanner.h"
|
||||
|
||||
#include "core/gimpmarshal.h"
|
||||
|
||||
#include "gimpcontrollerinfo.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CONTROLLER,
|
||||
PROP_MAPPING
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EVENT_MAPPED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
||||
static void gimp_controller_info_class_init (GimpControllerInfoClass *klass);
|
||||
static void gimp_controller_info_init (GimpControllerInfo *info);
|
||||
|
||||
static void gimp_controller_info_config_iface_init (GimpConfigInterface *config_iface);
|
||||
|
||||
static void gimp_controller_info_finalize (GObject *object);
|
||||
static void gimp_controller_info_set_property (GObject *object,
|
||||
guint property_id,
|
||||
|
@ -46,9 +72,27 @@ static void gimp_controller_info_get_property (GObject *object,
|
|||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static gboolean gimp_controller_info_serialize_property (GimpConfig *config,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec,
|
||||
GimpConfigWriter *writer);
|
||||
static gboolean gimp_controller_info_deserialize_property (GimpConfig *config,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
GScanner *scanner,
|
||||
GTokenType *expected);
|
||||
|
||||
static gboolean gimp_controller_info_event (GimpController *controller,
|
||||
const GimpControllerEvent *event,
|
||||
GimpControllerInfo *info);
|
||||
|
||||
|
||||
static GimpObjectClass *parent_class = NULL;
|
||||
|
||||
static guint info_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
||||
GType
|
||||
gimp_controller_info_get_type (void)
|
||||
|
@ -69,15 +113,40 @@ gimp_controller_info_get_type (void)
|
|||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) gimp_controller_info_init,
|
||||
};
|
||||
static const GInterfaceInfo config_iface_info =
|
||||
{
|
||||
(GInterfaceInitFunc) gimp_controller_info_config_iface_init,
|
||||
NULL, /* iface_finalize */
|
||||
NULL /* iface_data */
|
||||
};
|
||||
|
||||
controller_type = g_type_register_static (GIMP_TYPE_OBJECT,
|
||||
"GimpControllerInfo",
|
||||
&controller_info, 0);
|
||||
|
||||
g_type_add_interface_static (controller_type, GIMP_TYPE_CONFIG,
|
||||
&config_iface_info);
|
||||
}
|
||||
|
||||
return controller_type;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_controller_info_boolean_handled_accumulator (GSignalInvocationHint *ihint,
|
||||
GValue *return_accu,
|
||||
const GValue *handler_return,
|
||||
gpointer dummy)
|
||||
{
|
||||
gboolean continue_emission;
|
||||
gboolean signal_handled;
|
||||
|
||||
signal_handled = g_value_get_boolean (handler_return);
|
||||
g_value_set_boolean (return_accu, signal_handled);
|
||||
continue_emission = ! signal_handled;
|
||||
|
||||
return continue_emission;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_controller_info_class_init (GimpControllerInfoClass *klass)
|
||||
{
|
||||
|
@ -88,16 +157,40 @@ gimp_controller_info_class_init (GimpControllerInfoClass *klass)
|
|||
object_class->finalize = gimp_controller_info_finalize;
|
||||
object_class->set_property = gimp_controller_info_set_property;
|
||||
object_class->get_property = gimp_controller_info_get_property;
|
||||
|
||||
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, PROP_CONTROLLER,
|
||||
"controller", NULL,
|
||||
GIMP_TYPE_CONTROLLER,
|
||||
0);
|
||||
GIMP_CONFIG_INSTALL_PROP_POINTER (object_class, PROP_MAPPING,
|
||||
"mapping", NULL,
|
||||
0);
|
||||
|
||||
info_signals[EVENT_MAPPED] =
|
||||
g_signal_new ("event-mapped",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GimpControllerInfoClass, event_mapped),
|
||||
gimp_controller_info_boolean_handled_accumulator, NULL,
|
||||
gimp_marshal_BOOLEAN__OBJECT_POINTER_STRING,
|
||||
G_TYPE_BOOLEAN, 3,
|
||||
G_TYPE_OBJECT,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_STRING);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_controller_info_init (GimpControllerInfo *info)
|
||||
{
|
||||
info->controller = NULL;
|
||||
info->mapping = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
info->mapping = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_controller_info_config_iface_init (GimpConfigInterface *config_iface)
|
||||
{
|
||||
config_iface->serialize_property = gimp_controller_info_serialize_property;
|
||||
config_iface->deserialize_property = gimp_controller_info_deserialize_property;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -124,6 +217,31 @@ gimp_controller_info_set_property (GObject *object,
|
|||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CONTROLLER:
|
||||
if (info->controller)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (info->controller,
|
||||
gimp_controller_info_event,
|
||||
info);
|
||||
g_object_unref (info->controller);
|
||||
}
|
||||
|
||||
info->controller = (GimpController *) g_value_dup_object (value);
|
||||
|
||||
if (info->controller)
|
||||
{
|
||||
g_signal_connect_object (info->controller, "event",
|
||||
G_CALLBACK (gimp_controller_info_event),
|
||||
G_OBJECT (info),
|
||||
0);
|
||||
}
|
||||
break;
|
||||
case PROP_MAPPING:
|
||||
if (info->mapping)
|
||||
g_hash_table_destroy (info->mapping);
|
||||
info->mapping = g_value_get_pointer (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
|
@ -140,8 +258,185 @@ gimp_controller_info_get_property (GObject *object,
|
|||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CONTROLLER:
|
||||
g_value_set_object (value, info->controller);
|
||||
break;
|
||||
case PROP_MAPPING:
|
||||
g_value_set_pointer (value, info->mapping);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_controller_info_serialize_mapping (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
const gchar *event_name = key;
|
||||
const gchar *action_name = value;
|
||||
GimpConfigWriter *writer = data;
|
||||
|
||||
gimp_config_writer_open (writer, "map");
|
||||
gimp_config_writer_string (writer, event_name);
|
||||
gimp_config_writer_string (writer, action_name);
|
||||
gimp_config_writer_close (writer);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_controller_info_serialize_property (GimpConfig *config,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec,
|
||||
GimpConfigWriter *writer)
|
||||
{
|
||||
GHashTable *mapping;
|
||||
|
||||
if (property_id != PROP_MAPPING)
|
||||
return FALSE;
|
||||
|
||||
mapping = g_value_get_pointer (value);
|
||||
|
||||
gimp_config_writer_open (writer, pspec->name);
|
||||
|
||||
g_hash_table_foreach (mapping,
|
||||
(GHFunc) gimp_controller_info_serialize_mapping,
|
||||
writer);
|
||||
|
||||
gimp_config_writer_close (writer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_controller_info_deserialize_property (GimpConfig *config,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
GScanner *scanner,
|
||||
GTokenType *expected)
|
||||
{
|
||||
GHashTable *mapping = NULL;
|
||||
GTokenType token;
|
||||
|
||||
if (property_id != PROP_MAPPING)
|
||||
return FALSE;
|
||||
|
||||
mapping = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case G_TOKEN_LEFT_PAREN:
|
||||
token = G_TOKEN_IDENTIFIER;
|
||||
break;
|
||||
|
||||
case G_TOKEN_IDENTIFIER:
|
||||
if (! strcmp (scanner->value.v_identifier, "map"))
|
||||
{
|
||||
gchar *event_name;
|
||||
gchar *action_name;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &event_name))
|
||||
goto error;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &action_name))
|
||||
goto error;
|
||||
|
||||
g_hash_table_insert (mapping, event_name, action_name);
|
||||
}
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
break;
|
||||
|
||||
case G_TOKEN_RIGHT_PAREN:
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (token == G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
g_value_set_pointer (value, mapping);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error:
|
||||
if (mapping)
|
||||
g_hash_table_destroy (mapping);
|
||||
|
||||
*expected = token;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_controller_info_event (GimpController *controller,
|
||||
const GimpControllerEvent *event,
|
||||
GimpControllerInfo *info)
|
||||
{
|
||||
const gchar *class_name;
|
||||
const gchar *event_name;
|
||||
const gchar *event_blurb;
|
||||
const gchar *action_name;
|
||||
|
||||
class_name = GIMP_CONTROLLER_GET_CLASS (controller)->name;
|
||||
|
||||
event_name = gimp_controller_get_event_name (controller, event->any.event_id);
|
||||
event_blurb = gimp_controller_get_event_blurb (controller, event->any.event_id);
|
||||
|
||||
g_print ("Received '%s' (class '%s')\n"
|
||||
" controller event '%s (%s)'\n",
|
||||
controller->name, class_name,
|
||||
event_name, event_blurb);
|
||||
|
||||
action_name = g_hash_table_lookup (info->mapping, event_name);
|
||||
|
||||
if (action_name)
|
||||
{
|
||||
gboolean retval = FALSE;
|
||||
|
||||
g_print (" maps to action '%s'\n", action_name);
|
||||
|
||||
g_signal_emit (info, info_signals[EVENT_MAPPED], 0,
|
||||
controller, event, action_name, &retval);
|
||||
|
||||
if (retval)
|
||||
g_print (" action was found\n\n");
|
||||
else
|
||||
g_print (" action NOT found\n\n");
|
||||
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print (" doesn't map to action\n\n");
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,11 @@ struct _GimpControllerInfo
|
|||
struct _GimpControllerInfoClass
|
||||
{
|
||||
GimpObjectClass parent_class;
|
||||
|
||||
gboolean (* event_mapped) (GimpControllerInfo *info,
|
||||
GimpController *controller,
|
||||
const GimpControllerEvent *event,
|
||||
const gchar *action_name);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -22,16 +22,19 @@
|
|||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
#include "libgimpwidgets/gimpcontroller.h"
|
||||
|
||||
#include "widgets-types.h"
|
||||
|
||||
#include "config/gimpconfig.h"
|
||||
#include "config/gimpconfig-error.h"
|
||||
#include "config/gimpconfig-params.h"
|
||||
#include "config/gimpconfig-utils.h"
|
||||
#include "config/gimpconfigwriter.h"
|
||||
#include "config/gimpscanner.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimplist.h"
|
||||
|
||||
#include "gimpcontrollerinfo.h"
|
||||
#include "gimpcontrollers.h"
|
||||
|
@ -48,7 +51,8 @@ typedef struct _GimpControllerManager GimpControllerManager;
|
|||
|
||||
struct _GimpControllerManager
|
||||
{
|
||||
GList *controllers;
|
||||
GimpContainer *controllers;
|
||||
GQuark event_mapped_id;
|
||||
GimpController *wheel;
|
||||
GimpUIManager *ui_manager;
|
||||
};
|
||||
|
@ -59,12 +63,11 @@ struct _GimpControllerManager
|
|||
static GimpControllerManager * gimp_controller_manager_get (Gimp *gimp);
|
||||
static void gimp_controller_manager_free (GimpControllerManager *manager);
|
||||
|
||||
static gboolean gimp_controller_info_event (GimpController *controller,
|
||||
static gboolean gimp_controllers_event_mapped (GimpControllerInfo *info,
|
||||
GimpController *controller,
|
||||
const GimpControllerEvent *event,
|
||||
GimpControllerInfo *info);
|
||||
|
||||
static GTokenType gimp_controller_deserialize (GimpControllerManager *manager,
|
||||
GScanner *scanner);
|
||||
const gchar *action_name,
|
||||
GimpControllerManager *manager);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
@ -83,6 +86,13 @@ gimp_controllers_init (Gimp *gimp)
|
|||
GIMP_CONTROLLER_MANAGER_DATA_KEY, manager,
|
||||
(GDestroyNotify) gimp_controller_manager_free);
|
||||
|
||||
manager->controllers = gimp_list_new (GIMP_TYPE_CONTROLLER_INFO, TRUE);
|
||||
|
||||
manager->event_mapped_id =
|
||||
gimp_container_add_handler (manager->controllers, "event-mapped",
|
||||
G_CALLBACK (gimp_controllers_event_mapped),
|
||||
manager);
|
||||
|
||||
/* EEEEEEK */
|
||||
{
|
||||
static const GInterfaceInfo config_iface_info =
|
||||
|
@ -110,21 +120,12 @@ gimp_controllers_exit (Gimp *gimp)
|
|||
g_type_class_unref (g_type_class_peek (GIMP_TYPE_CONTROLLER_WHEEL));
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
CONTROLLER,
|
||||
CONTROLLER_OPTIONS,
|
||||
CONTROLLER_MAPPING
|
||||
};
|
||||
|
||||
void
|
||||
gimp_controllers_restore (Gimp *gimp,
|
||||
GimpUIManager *ui_manager)
|
||||
{
|
||||
GimpControllerManager *manager;
|
||||
gchar *filename;
|
||||
GScanner *scanner;
|
||||
GTokenType token;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
||||
|
@ -139,81 +140,46 @@ gimp_controllers_restore (Gimp *gimp,
|
|||
|
||||
filename = gimp_personal_rc_file ("controllerrc");
|
||||
|
||||
scanner = gimp_scanner_new_file (filename, &error);
|
||||
|
||||
if (! scanner)
|
||||
if (! gimp_config_deserialize_file (GIMP_CONFIG (manager->controllers),
|
||||
filename, NULL, &error))
|
||||
{
|
||||
if (error->code == GIMP_CONFIG_ERROR_OPEN_ENOENT)
|
||||
{
|
||||
g_clear_error (&error);
|
||||
g_free (filename);
|
||||
return;
|
||||
}
|
||||
|
||||
g_scanner_scope_add_symbol (scanner, 0, "controller",
|
||||
GINT_TO_POINTER (CONTROLLER));
|
||||
g_scanner_scope_add_symbol (scanner, CONTROLLER, "options",
|
||||
GINT_TO_POINTER (CONTROLLER_OPTIONS));
|
||||
g_scanner_scope_add_symbol (scanner, CONTROLLER, "mapping",
|
||||
GINT_TO_POINTER (CONTROLLER_MAPPING));
|
||||
filename = g_build_filename (gimp_sysconf_directory (),
|
||||
"controllerrc", NULL);
|
||||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case G_TOKEN_LEFT_PAREN:
|
||||
token = G_TOKEN_SYMBOL;
|
||||
break;
|
||||
|
||||
case G_TOKEN_SYMBOL:
|
||||
if (scanner->value.v_symbol == GINT_TO_POINTER (CONTROLLER))
|
||||
{
|
||||
g_scanner_set_scope (scanner, CONTROLLER);
|
||||
token = gimp_controller_deserialize (manager, scanner);
|
||||
|
||||
if (token == G_TOKEN_RIGHT_PAREN)
|
||||
g_scanner_set_scope (scanner, 0);
|
||||
else
|
||||
break;
|
||||
}
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
break;
|
||||
|
||||
case G_TOKEN_RIGHT_PAREN:
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
break;
|
||||
|
||||
default: /* do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (token != G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
g_scanner_get_next_token (scanner);
|
||||
g_scanner_unexp_token (scanner, token, NULL, NULL, NULL,
|
||||
_("fatal parse error"), TRUE);
|
||||
}
|
||||
|
||||
if (error)
|
||||
if (! gimp_config_deserialize_file (GIMP_CONFIG (manager->controllers),
|
||||
filename, NULL, &error))
|
||||
{
|
||||
g_message (error->message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message (error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
gimp_config_file_backup_on_error (filename, "controllerrc", NULL);
|
||||
}
|
||||
|
||||
gimp_scanner_destroy (scanner);
|
||||
g_free (filename);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
manager->controllers = g_list_reverse (manager->controllers);
|
||||
gimp_list_reverse (GIMP_LIST (manager->controllers));
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_controllers_save (Gimp *gimp)
|
||||
{
|
||||
const gchar *header =
|
||||
"GIMP controllerrc\n"
|
||||
"\n"
|
||||
"This file will be entirely rewritten every time you quit the gimp.";
|
||||
const gchar *footer =
|
||||
"end of controllerrc";
|
||||
|
||||
GimpControllerManager *manager;
|
||||
gchar *filename;
|
||||
GError *error = NULL;
|
||||
|
@ -225,6 +191,16 @@ gimp_controllers_save (Gimp *gimp)
|
|||
g_return_if_fail (manager != NULL);
|
||||
|
||||
filename = gimp_personal_rc_file ("controllerrc");
|
||||
|
||||
if (! gimp_config_serialize_to_file (GIMP_CONFIG (manager->controllers),
|
||||
filename,
|
||||
header, footer, NULL,
|
||||
&error))
|
||||
{
|
||||
g_message (error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
|
@ -253,203 +229,38 @@ gimp_controller_manager_get (Gimp *gimp)
|
|||
static void
|
||||
gimp_controller_manager_free (GimpControllerManager *manager)
|
||||
{
|
||||
g_list_foreach (manager->controllers, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (manager->controllers);
|
||||
gimp_container_remove_handler (manager->controllers,
|
||||
manager->event_mapped_id);
|
||||
|
||||
g_object_unref (manager->controllers);
|
||||
g_object_unref (manager->ui_manager);
|
||||
|
||||
g_free (manager);
|
||||
}
|
||||
|
||||
static GTokenType
|
||||
gimp_controller_deserialize (GimpControllerManager *manager,
|
||||
GScanner *scanner)
|
||||
static gboolean
|
||||
gimp_controllers_event_mapped (GimpControllerInfo *info,
|
||||
GimpController *controller,
|
||||
const GimpControllerEvent *event,
|
||||
const gchar *action_name,
|
||||
GimpControllerManager *manager)
|
||||
{
|
||||
GimpControllerInfo *info = NULL;
|
||||
GTokenType token;
|
||||
gchar *controller_name;
|
||||
GType controller_type;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, &controller_name))
|
||||
goto error;
|
||||
|
||||
controller_type = g_type_from_name (controller_name);
|
||||
g_free (controller_name);
|
||||
|
||||
if (! g_type_is_a (controller_type, GIMP_TYPE_CONTROLLER))
|
||||
goto error;
|
||||
|
||||
info = g_object_new (GIMP_TYPE_CONTROLLER_INFO, NULL);
|
||||
|
||||
info->controller = gimp_controller_new (controller_type);
|
||||
|
||||
/* EEEEEK */
|
||||
{
|
||||
GParamSpec **props;
|
||||
gint n_props;
|
||||
gint i;
|
||||
|
||||
props = g_object_class_list_properties (g_type_class_peek (controller_type),
|
||||
&n_props);
|
||||
|
||||
for (i = 0; i < n_props; i++)
|
||||
props[i]->flags |= GIMP_PARAM_SERIALIZE;
|
||||
|
||||
g_free (props);
|
||||
}
|
||||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case G_TOKEN_LEFT_PAREN:
|
||||
token = G_TOKEN_SYMBOL;
|
||||
break;
|
||||
|
||||
case G_TOKEN_SYMBOL:
|
||||
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
|
||||
{
|
||||
case CONTROLLER_OPTIONS:
|
||||
{
|
||||
GimpConfigInterface *config_iface;
|
||||
|
||||
config_iface = GIMP_CONFIG_GET_INTERFACE (info->controller);
|
||||
|
||||
if (! config_iface->deserialize (GIMP_CONFIG (info->controller),
|
||||
scanner,
|
||||
1,
|
||||
FALSE))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTROLLER_MAPPING:
|
||||
{
|
||||
GtkAction *action = NULL;
|
||||
GList *list;
|
||||
gchar *event_name;
|
||||
gchar *action_name;
|
||||
|
||||
token = G_TOKEN_INT;
|
||||
if (! gimp_scanner_parse_string (scanner, &event_name))
|
||||
goto error;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &action_name))
|
||||
goto error;
|
||||
|
||||
for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager->ui_manager));
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
GtkActionGroup *group = list->data;
|
||||
GtkAction *action;
|
||||
|
||||
action = gtk_action_group_get_action (group, action_name);
|
||||
|
||||
if (action)
|
||||
break;
|
||||
}
|
||||
|
||||
if (action)
|
||||
{
|
||||
g_hash_table_insert (info->mapping, event_name,
|
||||
g_object_ref (action));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (event_name);
|
||||
g_printerr ("%s: action '%s' not found\n",
|
||||
G_STRFUNC, action_name);
|
||||
}
|
||||
|
||||
g_free (action_name);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
break;
|
||||
|
||||
case G_TOKEN_RIGHT_PAREN:
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (token == G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
g_signal_connect (info->controller, "event",
|
||||
G_CALLBACK (gimp_controller_info_event),
|
||||
info);
|
||||
|
||||
if (GIMP_IS_CONTROLLER_WHEEL (info->controller))
|
||||
manager->wheel = info->controller;
|
||||
|
||||
manager->controllers = g_list_prepend (manager->controllers, info);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error:
|
||||
if (info)
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_controller_info_event (GimpController *controller,
|
||||
const GimpControllerEvent *event,
|
||||
GimpControllerInfo *info)
|
||||
{
|
||||
GtkAction *action;
|
||||
const gchar *class_name;
|
||||
const gchar *event_name;
|
||||
const gchar *event_blurb;
|
||||
|
||||
class_name = GIMP_CONTROLLER_GET_CLASS (controller)->name;
|
||||
|
||||
event_name = gimp_controller_get_event_name (controller, event->any.event_id);
|
||||
event_blurb = gimp_controller_get_event_blurb (controller, event->any.event_id);
|
||||
|
||||
g_print ("Received '%s' (class '%s')\n"
|
||||
" controller event '%s (%s)'\n",
|
||||
controller->name, class_name,
|
||||
event_name, event_blurb);
|
||||
|
||||
action = g_hash_table_lookup (info->mapping, event_name);
|
||||
|
||||
if (action)
|
||||
{
|
||||
g_print (" handled by action '%s'\n\n", gtk_action_get_name (action));
|
||||
gtk_action_activate (action);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print (" not handled\n\n");
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
|
@ -1,30 +1,37 @@
|
|||
# GIMP controllerrc
|
||||
#
|
||||
# This file will be entirely rewritten every time you quit the gimp.
|
||||
|
||||
(GimpControllerInfo "Main Mouse Wheel"
|
||||
(controller "GimpControllerWheel"
|
||||
(options
|
||||
(name "Main Mouse Wheel"))
|
||||
(mapping "scroll-up-shift-control-alt" "context-font-next")
|
||||
(mapping "scroll-up-control-alt" "context-gradient-next")
|
||||
(mapping "scroll-up-shift-alt" "context-pattern-next")
|
||||
(mapping "scroll-up-shift-control" "context-brush-next")
|
||||
(mapping "scroll-up-alt" "context-opacity-increase-skip")
|
||||
(mapping "scroll-down-shift-control-alt" "context-font-previous")
|
||||
(mapping "scroll-down-control-alt" "context-gradient-previous")
|
||||
(mapping "scroll-down-shift-alt" "context-pattern-previous")
|
||||
(mapping "scroll-down-shift-control" "context-brush-previous")
|
||||
(mapping "scroll-down-alt" "context-opacity-decrease-skip"))
|
||||
|
||||
(name "Main Mouse Wheel")
|
||||
(enabled yes))
|
||||
(mapping
|
||||
(map "scroll-down-alt" "context-opacity-decrease-skip")
|
||||
(map "scroll-down-control-alt" "context-gradient-previous")
|
||||
(map "scroll-down-shift-alt" "context-pattern-previous")
|
||||
(map "scroll-down-shift-control" "context-brush-previous")
|
||||
(map "scroll-down-shift-control-alt" "context-font-previous")
|
||||
(map "scroll-up-alt" "context-opacity-increase-skip")
|
||||
(map "scroll-up-control-alt" "context-gradient-next")
|
||||
(map "scroll-up-shift-alt" "context-pattern-next")
|
||||
(map "scroll-up-shift-control" "context-brush-next")
|
||||
(map "scroll-up-shift-control-alt" "context-font-next")))
|
||||
(GimpControllerInfo "ShuttlePRO"
|
||||
(controller "ControllerLinuxInput"
|
||||
(options
|
||||
(name "ShuttlePRO")
|
||||
(enabled yes)
|
||||
(device "/dev/input/event2"))
|
||||
(mapping "button-0" "tools-rect-select")
|
||||
(mapping "button-1" "tools-ellipse-select")
|
||||
(mapping "button-2" "tools-bucket-fill")
|
||||
(mapping "button-3" "tools-blend")
|
||||
(mapping "button-4" "tools-pencil")
|
||||
(mapping "button-5" "tools-paintbrush")
|
||||
(mapping "button-6" "tools-eraser")
|
||||
(mapping "button-7" "tools-airbrush")
|
||||
(mapping "wheel-turn-left" "context-brush-radius-decrease")
|
||||
(mapping "wheel-turn-right" "context-brush-radius-increase"))
|
||||
(mapping
|
||||
(map "button-0" "tools-rect-select")
|
||||
(map "button-1" "tools-ellipse-select")
|
||||
(map "button-2" "tools-bucket-fill")
|
||||
(map "button-3" "tools-blend")
|
||||
(map "button-4" "tools-pencil")
|
||||
(map "button-5" "tools-paintbrush")
|
||||
(map "button-6" "tools-eraser")
|
||||
(map "button-7" "tools-airbrush")
|
||||
(map "wheel-turn-left" "context-brush-radius-decrease")
|
||||
(map "wheel-turn-right" "context-brush-radius-increase")))
|
||||
|
||||
# end of controllerrc
|
||||
|
|
|
@ -666,7 +666,33 @@ gimp_config_deserialize_object (GValue *value,
|
|||
prop_object = g_value_get_object (value);
|
||||
|
||||
if (! prop_object)
|
||||
{
|
||||
/* if the object property is not GIMP_PARAM_AGGREGATE, read
|
||||
* the type of the object and create it
|
||||
*/
|
||||
if (! (prop_spec->flags & GIMP_PARAM_AGGREGATE))
|
||||
{
|
||||
gchar *type_name;
|
||||
GType type;
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, &type_name))
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
type = g_type_from_name (type_name);
|
||||
g_free (type_name);
|
||||
|
||||
if (! g_type_is_a (type, prop_spec->value_type))
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
prop_object = g_object_new (type, NULL);
|
||||
|
||||
g_value_take_object (value, prop_object);
|
||||
}
|
||||
else
|
||||
{
|
||||
return G_TOKEN_RIGHT_PAREN;
|
||||
}
|
||||
}
|
||||
|
||||
config_iface = GIMP_CONFIG_GET_INTERFACE (prop_object);
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
|
|||
flags | GIMP_CONFIG_PARAM_FLAGS))
|
||||
|
||||
|
||||
/* object properties are _not_ G_PARAM_CONSTRUCT */
|
||||
/* object and pointer properties are _not_ G_PARAM_CONSTRUCT */
|
||||
|
||||
#define GIMP_CONFIG_INSTALL_PROP_OBJECT(class, id,\
|
||||
name, blurb, object_type, flags)\
|
||||
|
@ -233,5 +233,12 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
|
|||
flags |\
|
||||
G_PARAM_READWRITE | GIMP_PARAM_SERIALIZE))
|
||||
|
||||
#define GIMP_CONFIG_INSTALL_PROP_POINTER(class, id,\
|
||||
name, blurb, flags)\
|
||||
g_object_class_install_property (class, id,\
|
||||
g_param_spec_pointer (name, NULL, blurb,\
|
||||
flags |\
|
||||
G_PARAM_READWRITE | GIMP_PARAM_SERIALIZE))
|
||||
|
||||
|
||||
#endif /* __GIMP_CONFIG_PARAMS_H__ */
|
||||
|
|
|
@ -257,8 +257,7 @@ gimp_config_serialize_property (GimpConfig *config,
|
|||
|
||||
if (! success)
|
||||
{
|
||||
if (G_VALUE_HOLDS_OBJECT (&value) &&
|
||||
(param_spec->flags & GIMP_PARAM_AGGREGATE))
|
||||
if (G_VALUE_HOLDS_OBJECT (&value))
|
||||
{
|
||||
GimpConfigInterface *config_iface = NULL;
|
||||
GimpConfig *prop_object;
|
||||
|
@ -274,6 +273,17 @@ gimp_config_serialize_property (GimpConfig *config,
|
|||
{
|
||||
gimp_config_writer_open (writer, param_spec->name);
|
||||
|
||||
/* if the object property is not GIMP_PARAM_AGGREGATE,
|
||||
* deserializing will need to know the exact type
|
||||
* in order to create the object
|
||||
*/
|
||||
if (! (param_spec->flags & GIMP_PARAM_AGGREGATE))
|
||||
{
|
||||
GType object_type = G_TYPE_FROM_INSTANCE (prop_object);
|
||||
|
||||
gimp_config_writer_string (writer, g_type_name (object_type));
|
||||
}
|
||||
|
||||
success = config_iface->serialize (prop_object, writer, NULL);
|
||||
|
||||
if (success)
|
||||
|
|
|
@ -120,12 +120,14 @@ gimp_controller_class_init (GimpControllerClass *klass)
|
|||
g_param_spec_string ("name", NULL, NULL,
|
||||
"Unnamed Controller",
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
G_PARAM_CONSTRUCT |
|
||||
GIMP_CONTROLLER_PARAM_SERIALIZE));
|
||||
g_object_class_install_property (object_class, PROP_ENABLED,
|
||||
g_param_spec_boolean ("enabled", NULL, NULL,
|
||||
TRUE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
G_PARAM_CONSTRUCT |
|
||||
GIMP_CONTROLLER_PARAM_SERIALIZE));
|
||||
|
||||
controller_signals[EVENT] =
|
||||
g_signal_new ("event",
|
||||
|
|
|
@ -27,6 +27,10 @@ G_BEGIN_DECLS
|
|||
|
||||
/* For information look at the html documentation */
|
||||
|
||||
|
||||
#define GIMP_CONTROLLER_PARAM_SERIALIZE (1 << (0 + G_PARAM_USER_SHIFT))
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GIMP_CONTROLLER_EVENT_TRIGGER,
|
||||
|
|
|
@ -211,7 +211,8 @@ linux_input_class_init (ControllerLinuxInputClass *klass)
|
|||
g_param_spec_string ("device", NULL, NULL,
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
G_PARAM_CONSTRUCT |
|
||||
GIMP_CONTROLLER_PARAM_SERIALIZE));
|
||||
|
||||
controller_class->name = _("Linux Input Events");
|
||||
|
||||
|
|
Loading…
Reference in New Issue