GTK+ plugin: implementation of edit window. No save available yet, just look.
[lxde/lxhotkey.git] / src / lxhotkey.h
1 /*
2 * Copyright (C) 2016 Andriy Grytsenko <andrej@rep.kiev.ua>
3 *
4 * This file is a part of LXHotkey project.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #ifndef _LXKEYS_H_
22 #define _LXKEYS_H_ 1
23
24 #include <libfm/fm.h>
25
26 G_BEGIN_DECLS
27
28 /**
29 * LXHotkeyAttr:
30 * @name: action or option name
31 * @values: (element-type char *): option value
32 * @subopts: (element-type LXHotkeyAttr): (allow-none): list of suboptions
33 * @desc: (allow-none): action or option description
34 * @has_actions: %TRUE if @subopts contains actions, %FALSE if @subopts contains options
35 * @has_value: %TRUE if option has value even if @subopts isn't %NULL
36 *
37 * Data descriptor for actions and options. Actions are ativated by keybinding.
38 * Each action may contain arbitrary number of options that alter its execution.
39 *
40 * This data is also used in a result on LXHotkeyPluginInit:get_wm_actions() or
41 * LXHotkeyPluginInit:get_app_options() call. In that case for each option the
42 * @values list should be either %NULL if option accepts any value, or list of
43 * acceptable values for the option ("#" value has a special meaning: integer
44 * value matches it, the same as "%" for percent value). For such purpose it is
45 * advisable to make @name and @values translateable constants because GUI might
46 * represent them in target locale which might be convenient for users.
47 *
48 * The @desc appears in data returned by LXHotkeyPluginInit:get_wm_actions() or
49 * LXHotkeyPluginInit:get_app_options() call, it has human-readable descriptions
50 * for option or action which can be used in GUI tooltip.
51 */
52 typedef struct {
53 gchar *name;
54 GList *values;
55 GList *subopts;
56 gchar *desc;
57 gboolean has_actions;
58 gboolean has_value;
59 } LXHotkeyAttr;
60
61 #ifdef WANT_OPTIONS_EQUAL
62 static gboolean values_equal(GList *vals1, GList *vals2)
63 {
64 while (vals1 && vals2) {
65 if (g_strcmp0(vals1->data, vals2->data) != 0)
66 return FALSE;
67 vals1 = vals1->next;
68 vals2 = vals2->next;
69 }
70 return (vals1 == NULL && vals2 == NULL);
71 }
72
73 /**
74 * options_equal
75 * @opts1: (element-type LXHotkeyAttr): list of options
76 * @opts2: (element-type LXHotkeyAttr): list of options
77 *
78 * Recursively compare two lists of options.
79 *
80 * Returns: %TRUE if two lists are equal.
81 */
82 static gboolean options_equal(GList *opts1, GList *opts2)
83 {
84 while (opts1 && opts2) {
85 LXHotkeyAttr *attr1 = opts1->data, *attr2 = opts2->data;
86
87 if (g_strcmp0(attr1->name, attr2->name) != 0)
88 return FALSE;
89 if (!values_equal(attr1->values, attr2->values))
90 return FALSE;
91 if (!options_equal(attr1->subopts, attr2->subopts))
92 return FALSE;
93 opts1 = opts1->next;
94 opts2 = opts2->next;
95 }
96 return (opts1 == NULL && opts2 == NULL);
97 }
98 #endif /* WANT_OPTIONS_EQUAL */
99
100 /**
101 * LXHotkeyGlobal:
102 * @actions: (element-type LXHotkeyAttr): list of actions
103 * @accel1: a keybinding to activate @actions, in GDK accelerator format
104 * @accel2: optional alternate keybinding to activate @actions
105 * @data1: a pointer for using by WM plugin
106 * @data2: a pointer for using by WM plugin
107 *
108 * Descriptor of a keybinding which isn't a single command line action.
109 * The keybinding string is in format that looks like "<Control>a" or
110 * "<Shift><Alt>F1" or "<Release>z" (note that not each WM supports last one
111 * variant).
112 */
113 typedef struct {
114 GList *actions;
115 gchar *accel1;
116 gchar *accel2;
117 gpointer data1;
118 gpointer data2;
119 } LXHotkeyGlobal;
120
121 /**
122 * LXHotkeyApp:
123 * @exec: a command line to execute
124 * @options: (element-type LXHotkeyAttr): (allow-none): list of options
125 * @accel1: a keybinding to activate @exec, in GDK accelerator format
126 * @accel2: optional alternate keybinding to activate @exec
127 * @data1: a pointer for using by WM plugin
128 * @data2: a pointer for using by WM plugin
129 *
130 * Descriptor of a keybinding for a single command line action. The command
131 * execution may be altered by some @options. See also #LXHotkeyGlobal.
132 */
133 typedef struct {
134 gchar *exec;
135 GList *options;
136 gchar *accel1;
137 gchar *accel2;
138 gpointer data1;
139 gpointer data2;
140 } LXHotkeyApp;
141
142
143 /* WM support plugins */
144
145 #define FM_MODULE_lxhotkey_VERSION 1 /* version of this API */
146
147 /**
148 * LXHotkeyPluginInit:
149 * @load: callback to (re)load bindings from WM configuration
150 * @save: callback to save bindings to WM configuration and apply them
151 * @free: callback to release allocated resources
152 * @get_wm_keys: (allow-none): callback to get global keys by provided mask
153 * @set_wm_key: (allow-none): callback to set a global key by provided data
154 * @get_wm_actions: (allow-none): callback to get global actions list provided by WM
155 * @get_app_keys: (allow-none): callback to get keys bound to commands
156 * @set_app_key: (allow-none): callback to set a key for a command
157 * @get_app_options: (allow-none): callback to get possible actions for commands
158 *
159 * Callbacks @get_wm_keys and @get_app_keys return list which should be freed
160 * by caller (transfer container).
161 * Callbacks @get_wm_actions and @get_app_options return list that should be
162 * not modified nor freed by caller (transfer none).
163 * Callback @get_wm_keys returns list of keybindings by @mask which is a shell
164 * style pattern for keys.
165 * Callback @set_wm_key changes a keybinding for list of actions provided. If
166 * @data::accel1 is %NULL then all keybindings for @data::actions will be
167 * cleared, otherwise keybindings will be changed accordingly.
168 */
169 typedef struct {
170 /*< public >*/
171 gpointer (*load)(gpointer config, GError **error);
172 gboolean (*save)(gpointer config, GError **error);
173 void (*free)(gpointer config);
174 GList *(*get_wm_keys)(gpointer config, const char *mask, GError **error);
175 gboolean (*set_wm_key)(gpointer config, LXHotkeyGlobal *data, GError **error);
176 GList *(*get_wm_actions)(gpointer config, GError **error);
177 GList *(*get_app_keys)(gpointer config, const char *mask, GError **error);
178 gboolean (*set_app_key)(gpointer config, LXHotkeyApp *data, GError **error);
179 GList *(*get_app_options)(gpointer config, GError **error);
180 /*< private >*/
181 gpointer _reserved1;
182 gpointer _reserved2;
183 gpointer _reserved3;
184 } LXHotkeyPluginInit;
185
186 /**
187 * This descriptor instance should be defined in each plugin code as main
188 * entry point for plugin creation. Primitive plugin example follows:
189 *
190 * #include <lxhotkey/lxhotkey.h>
191 *
192 * gpointer test_load(gpointer config, GError **error)
193 * {
194 * if (config == NULL)
195 * config = g_strdup("");
196 * return config;
197 * }
198 *
199 * gboolean test_save(gpointer config, GError **error)
200 * {
201 * return FALSE;
202 * }
203 *
204 * FM_DEFINE_MODULE(lxhotkey, NoWM)
205 *
206 * LXHotkeyPluginInit fm_module_init_lxhotkey = {
207 * .load = test_load,
208 * .save = test_save,
209 * .free = g_free
210 * }
211 */
212 extern LXHotkeyPluginInit fm_module_init_lxhotkey;
213
214
215 /* GUI plugins */
216
217 #define FM_MODULE_lxhotkey_gui_VERSION 1 /* version of this API */
218
219 /**
220 * LXHotkeyGUIPluginInit:
221 * @run: callback to run GUI
222 * @alert: callback to show an error message
223 *
224 * The @run callback receives name of WM, pointer to callbacks, and pointer to
225 * pointer to the config data which is already succesfully loaded and ready to
226 * use. Config may be reloaded by plugin if needed.
227 */
228 typedef struct {
229 /*< public >*/
230 void (*run)(const gchar *wm, const LXHotkeyPluginInit *cb, gpointer *config, GError **error);
231 void (*alert)(GError *error);
232 void (*init)(int argc, char **argv);
233 /*< private >*/
234 gpointer _reserved1;
235 gpointer _reserved2;
236 gpointer _reserved3;
237 } LXHotkeyGUIPluginInit;
238
239 /**
240 * This descriptor instance should be defined in each plugin code as main
241 * entry point for a GUI plugin creation.
242 */
243 extern LXHotkeyGUIPluginInit fm_module_init_lxhotkey_gui;
244
245 G_END_DECLS
246
247 #endif /* _LXKEYS_H_ */