swat 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ Copyright (c) 2007 Hemant Kumar ( mail [at] gnufied [dot] org )
2
+
3
+ The Library is dual licensed under terms of Ruby License or MIT License.
data/README ADDED
@@ -0,0 +1,18 @@
1
+ Swat is a todo list manager for Gnome & Emacs.
2
+
3
+ Heck : Emacs?
4
+
5
+ Features:
6
+ - Manage your todos, add them according to priority and category.
7
+ - Move your todos to wish list, when not feeling like working on them.
8
+ - libtomboy bindings for global shortcut(Alt-F11).
9
+ - Nice stats for your number of tasks finished and added.
10
+ - All your todos are in a .org file and hence can be managed from
11
+ Emacs as well.
12
+
13
+ KeyBindings:
14
+ - Alt-F11 : from anywhere, brings the todo window to front.
15
+ - Esc : do dismiss todo window.
16
+ - Control-N : to add a todo.
17
+
18
+
data/TODO ADDED
File without changes
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require 'libglade2'
5
+ require "erb"
6
+ require "yaml"
7
+ require "ostruct"
8
+ require "enumerator"
9
+ SWAT_APP = File.expand_path(File.dirname(__FILE__)+"/..")
10
+ ["lib","ext"].each { |x| $LOAD_PATH.unshift("#{SWAT_APP}/#{x}"); }
11
+
12
+ require "list_helper"
13
+ require "stat_box"
14
+ require "swat_meta_data"
15
+ require "todo_context_menu"
16
+ require "todo_window"
17
+ require "keybinder"
18
+ require "todo_data"
19
+ require "add_todo_dialog"
20
+ require "wish_list"
21
+ require "swat"
22
+
23
+ Swat::SwatMain.new
24
+ Gtk.main
@@ -0,0 +1,149 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ #### Start of system configuration section. ####
5
+
6
+ srcdir = .
7
+ topdir = /usr/local/lib/ruby/1.8/i686-linux
8
+ hdrdir = $(topdir)
9
+ VPATH = $(srcdir):$(topdir):$(hdrdir)
10
+ prefix = $(DESTDIR)/usr/local
11
+ exec_prefix = $(prefix)
12
+ sitedir = $(prefix)/lib/ruby/site_ruby
13
+ rubylibdir = $(libdir)/ruby/$(ruby_version)
14
+ docdir = $(datarootdir)/doc/$(PACKAGE)
15
+ dvidir = $(docdir)
16
+ datarootdir = $(prefix)/share
17
+ archdir = $(rubylibdir)/$(arch)
18
+ sbindir = $(exec_prefix)/sbin
19
+ psdir = $(docdir)
20
+ localedir = $(datarootdir)/locale
21
+ htmldir = $(docdir)
22
+ datadir = $(datarootdir)
23
+ includedir = $(prefix)/include
24
+ infodir = $(datarootdir)/info
25
+ sysconfdir = $(prefix)/etc
26
+ mandir = $(datarootdir)/man
27
+ libdir = $(exec_prefix)/lib
28
+ sharedstatedir = $(prefix)/com
29
+ oldincludedir = $(DESTDIR)/usr/include
30
+ pdfdir = $(docdir)
31
+ sitearchdir = $(sitelibdir)/$(sitearch)
32
+ bindir = $(exec_prefix)/bin
33
+ localstatedir = $(prefix)/var
34
+ sitelibdir = $(sitedir)/$(ruby_version)
35
+ libexecdir = $(exec_prefix)/libexec
36
+
37
+ CC = gcc
38
+ LIBRUBY = $(LIBRUBY_A)
39
+ LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
40
+ LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir)
41
+ LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
42
+
43
+ RUBY_EXTCONF_H =
44
+ CFLAGS = -fPIC -g -O2 -Wall -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gtk-unix-print-2.0 -I/usr/include/gtk-2.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/lib/gtk-2.0/include -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/cairo -I/usr/include/freetype2 -I/usr/include/libpng12
45
+ INCFLAGS = -I. -I. -I/usr/local/lib/ruby/1.8/i686-linux -I.
46
+ CPPFLAGS = -DHAVE_RB_DEFINE_ALLOC_FUNC -DHAVE_RB_BLOCK_PROC -DHAVE_OBJECT_ALLOCATE -DHAVE_NODE_ATTRASGN -DRUBY_GTK2_TARGET=\"x11\" -DHAVE_GTK_PLUG_GET_TYPE -DHAVE_GTK_SOCKET_GET_TYPE -DHAVE_PANGO_RENDER_PART_GET_TYPE -DHAVE_XREADBITMAPFILEDATA -DHAVE_X11_XLIB_H -DHAVE_XGETERRORTEXT -DHAVE_GTK_PRINT_UNIX_DIALOG_GET_TYPE -DHAVE_GTK_PRINT_JOB_GET_TYPE -DHAVE_GTK_PRINTER_GET_TYPE -I/usr/local/lib/ruby/site_ruby/1.8/i686-linux
47
+ CXXFLAGS = $(CFLAGS)
48
+ DLDFLAGS = -L. -rdynamic -Wl,-export-dynamic -pthread
49
+ LDSHARED = $(CC) -shared
50
+ AR = ar
51
+ EXEEXT =
52
+
53
+ RUBY_INSTALL_NAME = ruby
54
+ RUBY_SO_NAME = ruby
55
+ arch = i686-linux
56
+ sitearch = i686-linux
57
+ ruby_version = 1.8
58
+ ruby = /usr/local/bin/ruby
59
+ RUBY = $(ruby)
60
+ RM = rm -f
61
+ MAKEDIRS = mkdir -p
62
+ INSTALL = /usr/bin/install -c
63
+ INSTALL_PROG = $(INSTALL) -m 0755
64
+ INSTALL_DATA = $(INSTALL) -m 644
65
+ COPY = cp
66
+
67
+ #### End of system configuration section. ####
68
+
69
+ preload =
70
+
71
+ libpath = . $(libdir)
72
+ LIBPATH = -L'.' -L'$(libdir)' -Wl,-R'$(libdir)'
73
+ DEFFILE =
74
+
75
+ CLEANFILES = mkmf.log
76
+ DISTCLEANFILES = rbgdkkeysyms.h rbgtkinits.c
77
+
78
+ extout =
79
+ extout_prefix =
80
+ target_prefix =
81
+ LOCAL_LIBS =
82
+ LIBS = -lgthread-2.0 -lrt -lglib-2.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXcomposite -lXdamage -lpango-1.0 -lcairo -lX11 -lXfixes -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXcomposite -lXdamage -lpango-1.0 -lcairo -lX11 -lXfixes -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -lcairo -ldl -lcrypt -lm -lc
83
+ SRCS = keybinder.c tomboykeybinder.c eggaccelerators.c
84
+ OBJS = keybinder.o tomboykeybinder.o eggaccelerators.o
85
+ TARGET = keybinder
86
+ DLLIB = $(TARGET).so
87
+ EXTSTATIC =
88
+ STATIC_LIB =
89
+
90
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
91
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
92
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
93
+
94
+ TARGET_SO = $(DLLIB)
95
+ CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
96
+ CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
97
+
98
+ all: $(DLLIB)
99
+ static: $(STATIC_LIB)
100
+
101
+ clean:
102
+ @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
103
+
104
+ distclean: clean
105
+ @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
106
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
107
+
108
+ realclean: distclean
109
+ install: install-so install-rb
110
+
111
+ install-so: $(RUBYARCHDIR)
112
+ install-so: $(RUBYARCHDIR)/$(DLLIB)
113
+ $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
114
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
115
+ install-rb: pre-install-rb install-rb-default
116
+ install-rb-default: pre-install-rb-default
117
+ pre-install-rb: Makefile
118
+ pre-install-rb-default: Makefile
119
+ $(RUBYARCHDIR):
120
+ $(MAKEDIRS) $@
121
+
122
+ site-install: site-install-so site-install-rb
123
+ site-install-so: install-so
124
+ site-install-rb: install-rb
125
+
126
+ .SUFFIXES: .c .m .cc .cxx .cpp .C .o
127
+
128
+ .cc.o:
129
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
130
+
131
+ .cxx.o:
132
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
133
+
134
+ .cpp.o:
135
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
136
+
137
+ .C.o:
138
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
139
+
140
+ .c.o:
141
+ $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
142
+
143
+ $(DLLIB): $(OBJS)
144
+ @-$(RM) $@
145
+ $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
146
+
147
+
148
+
149
+ $(OBJS): ruby.h defines.h
@@ -0,0 +1,657 @@
1
+ /* eggaccelerators.c
2
+ * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3
+ * Developed by Havoc Pennington, Tim Janik
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Library General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Library General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Library General Public
16
+ * License along with this library; if not, write to the
17
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
+ * Boston, MA 02111-1307, USA.
19
+ */
20
+
21
+ #include "eggaccelerators.h"
22
+
23
+ #include <string.h>
24
+ #include <gdk/gdkx.h>
25
+ #include <gdk/gdkkeysyms.h>
26
+
27
+ enum
28
+ {
29
+ EGG_MODMAP_ENTRY_SHIFT = 0,
30
+ EGG_MODMAP_ENTRY_LOCK = 1,
31
+ EGG_MODMAP_ENTRY_CONTROL = 2,
32
+ EGG_MODMAP_ENTRY_MOD1 = 3,
33
+ EGG_MODMAP_ENTRY_MOD2 = 4,
34
+ EGG_MODMAP_ENTRY_MOD3 = 5,
35
+ EGG_MODMAP_ENTRY_MOD4 = 6,
36
+ EGG_MODMAP_ENTRY_MOD5 = 7,
37
+ EGG_MODMAP_ENTRY_LAST = 8
38
+ };
39
+
40
+ #define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
41
+
42
+ typedef struct
43
+ {
44
+ EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
+
46
+ } EggModmap;
47
+
48
+ const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
+
50
+ static inline gboolean
51
+ is_alt (const gchar *string)
52
+ {
53
+ return ((string[0] == '<') &&
54
+ (string[1] == 'a' || string[1] == 'A') &&
55
+ (string[2] == 'l' || string[2] == 'L') &&
56
+ (string[3] == 't' || string[3] == 'T') &&
57
+ (string[4] == '>'));
58
+ }
59
+
60
+ static inline gboolean
61
+ is_ctl (const gchar *string)
62
+ {
63
+ return ((string[0] == '<') &&
64
+ (string[1] == 'c' || string[1] == 'C') &&
65
+ (string[2] == 't' || string[2] == 'T') &&
66
+ (string[3] == 'l' || string[3] == 'L') &&
67
+ (string[4] == '>'));
68
+ }
69
+
70
+ static inline gboolean
71
+ is_modx (const gchar *string)
72
+ {
73
+ return ((string[0] == '<') &&
74
+ (string[1] == 'm' || string[1] == 'M') &&
75
+ (string[2] == 'o' || string[2] == 'O') &&
76
+ (string[3] == 'd' || string[3] == 'D') &&
77
+ (string[4] >= '1' && string[4] <= '5') &&
78
+ (string[5] == '>'));
79
+ }
80
+
81
+ static inline gboolean
82
+ is_ctrl (const gchar *string)
83
+ {
84
+ return ((string[0] == '<') &&
85
+ (string[1] == 'c' || string[1] == 'C') &&
86
+ (string[2] == 't' || string[2] == 'T') &&
87
+ (string[3] == 'r' || string[3] == 'R') &&
88
+ (string[4] == 'l' || string[4] == 'L') &&
89
+ (string[5] == '>'));
90
+ }
91
+
92
+ static inline gboolean
93
+ is_shft (const gchar *string)
94
+ {
95
+ return ((string[0] == '<') &&
96
+ (string[1] == 's' || string[1] == 'S') &&
97
+ (string[2] == 'h' || string[2] == 'H') &&
98
+ (string[3] == 'f' || string[3] == 'F') &&
99
+ (string[4] == 't' || string[4] == 'T') &&
100
+ (string[5] == '>'));
101
+ }
102
+
103
+ static inline gboolean
104
+ is_shift (const gchar *string)
105
+ {
106
+ return ((string[0] == '<') &&
107
+ (string[1] == 's' || string[1] == 'S') &&
108
+ (string[2] == 'h' || string[2] == 'H') &&
109
+ (string[3] == 'i' || string[3] == 'I') &&
110
+ (string[4] == 'f' || string[4] == 'F') &&
111
+ (string[5] == 't' || string[5] == 'T') &&
112
+ (string[6] == '>'));
113
+ }
114
+
115
+ static inline gboolean
116
+ is_control (const gchar *string)
117
+ {
118
+ return ((string[0] == '<') &&
119
+ (string[1] == 'c' || string[1] == 'C') &&
120
+ (string[2] == 'o' || string[2] == 'O') &&
121
+ (string[3] == 'n' || string[3] == 'N') &&
122
+ (string[4] == 't' || string[4] == 'T') &&
123
+ (string[5] == 'r' || string[5] == 'R') &&
124
+ (string[6] == 'o' || string[6] == 'O') &&
125
+ (string[7] == 'l' || string[7] == 'L') &&
126
+ (string[8] == '>'));
127
+ }
128
+
129
+ static inline gboolean
130
+ is_release (const gchar *string)
131
+ {
132
+ return ((string[0] == '<') &&
133
+ (string[1] == 'r' || string[1] == 'R') &&
134
+ (string[2] == 'e' || string[2] == 'E') &&
135
+ (string[3] == 'l' || string[3] == 'L') &&
136
+ (string[4] == 'e' || string[4] == 'E') &&
137
+ (string[5] == 'a' || string[5] == 'A') &&
138
+ (string[6] == 's' || string[6] == 'S') &&
139
+ (string[7] == 'e' || string[7] == 'E') &&
140
+ (string[8] == '>'));
141
+ }
142
+
143
+ static inline gboolean
144
+ is_meta (const gchar *string)
145
+ {
146
+ return ((string[0] == '<') &&
147
+ (string[1] == 'm' || string[1] == 'M') &&
148
+ (string[2] == 'e' || string[2] == 'E') &&
149
+ (string[3] == 't' || string[3] == 'T') &&
150
+ (string[4] == 'a' || string[4] == 'A') &&
151
+ (string[5] == '>'));
152
+ }
153
+
154
+ static inline gboolean
155
+ is_super (const gchar *string)
156
+ {
157
+ return ((string[0] == '<') &&
158
+ (string[1] == 's' || string[1] == 'S') &&
159
+ (string[2] == 'u' || string[2] == 'U') &&
160
+ (string[3] == 'p' || string[3] == 'P') &&
161
+ (string[4] == 'e' || string[4] == 'E') &&
162
+ (string[5] == 'r' || string[5] == 'R') &&
163
+ (string[6] == '>'));
164
+ }
165
+
166
+ static inline gboolean
167
+ is_hyper (const gchar *string)
168
+ {
169
+ return ((string[0] == '<') &&
170
+ (string[1] == 'h' || string[1] == 'H') &&
171
+ (string[2] == 'y' || string[2] == 'Y') &&
172
+ (string[3] == 'p' || string[3] == 'P') &&
173
+ (string[4] == 'e' || string[4] == 'E') &&
174
+ (string[5] == 'r' || string[5] == 'R') &&
175
+ (string[6] == '>'));
176
+ }
177
+
178
+ /**
179
+ * egg_accelerator_parse_virtual:
180
+ * @accelerator: string representing an accelerator
181
+ * @accelerator_key: return location for accelerator keyval
182
+ * @accelerator_mods: return location for accelerator modifier mask
183
+ *
184
+ * Parses a string representing a virtual accelerator. The format
185
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186
+ * "&lt;Release&gt;z" (the last one is for key release). The parser
187
+ * is fairly liberal and allows lower or upper case, and also
188
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189
+ *
190
+ * If the parse fails, @accelerator_key and @accelerator_mods will
191
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
192
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193
+ * returned.
194
+ *
195
+ * The virtual vs. concrete accelerator distinction is a relic of
196
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
197
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
198
+ * the virtual modifier represents the keyboard key, the concrete
199
+ * modifier the actual Mod2-Mod5 bits in the key press event.
200
+ *
201
+ * Returns: %TRUE on success.
202
+ */
203
+ gboolean
204
+ egg_accelerator_parse_virtual (const gchar *accelerator,
205
+ guint *accelerator_key,
206
+ EggVirtualModifierType *accelerator_mods)
207
+ {
208
+ guint keyval;
209
+ GdkModifierType mods;
210
+ gint len;
211
+ gboolean bad_keyval;
212
+
213
+ if (accelerator_key)
214
+ *accelerator_key = 0;
215
+ if (accelerator_mods)
216
+ *accelerator_mods = 0;
217
+
218
+ g_return_val_if_fail (accelerator != NULL, FALSE);
219
+
220
+ bad_keyval = FALSE;
221
+
222
+ keyval = 0;
223
+ mods = 0;
224
+ len = strlen (accelerator);
225
+ while (len)
226
+ {
227
+ if (*accelerator == '<')
228
+ {
229
+ if (len >= 9 && is_release (accelerator))
230
+ {
231
+ accelerator += 9;
232
+ len -= 9;
233
+ mods |= EGG_VIRTUAL_RELEASE_MASK;
234
+ }
235
+ else if (len >= 9 && is_control (accelerator))
236
+ {
237
+ accelerator += 9;
238
+ len -= 9;
239
+ mods |= EGG_VIRTUAL_CONTROL_MASK;
240
+ }
241
+ else if (len >= 7 && is_shift (accelerator))
242
+ {
243
+ accelerator += 7;
244
+ len -= 7;
245
+ mods |= EGG_VIRTUAL_SHIFT_MASK;
246
+ }
247
+ else if (len >= 6 && is_shft (accelerator))
248
+ {
249
+ accelerator += 6;
250
+ len -= 6;
251
+ mods |= EGG_VIRTUAL_SHIFT_MASK;
252
+ }
253
+ else if (len >= 6 && is_ctrl (accelerator))
254
+ {
255
+ accelerator += 6;
256
+ len -= 6;
257
+ mods |= EGG_VIRTUAL_CONTROL_MASK;
258
+ }
259
+ else if (len >= 6 && is_modx (accelerator))
260
+ {
261
+ static const guint mod_vals[] = {
262
+ EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263
+ EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264
+ };
265
+
266
+ len -= 6;
267
+ accelerator += 4;
268
+ mods |= mod_vals[*accelerator - '1'];
269
+ accelerator += 2;
270
+ }
271
+ else if (len >= 5 && is_ctl (accelerator))
272
+ {
273
+ accelerator += 5;
274
+ len -= 5;
275
+ mods |= EGG_VIRTUAL_CONTROL_MASK;
276
+ }
277
+ else if (len >= 5 && is_alt (accelerator))
278
+ {
279
+ accelerator += 5;
280
+ len -= 5;
281
+ mods |= EGG_VIRTUAL_ALT_MASK;
282
+ }
283
+ else if (len >= 6 && is_meta (accelerator))
284
+ {
285
+ accelerator += 6;
286
+ len -= 6;
287
+ mods |= EGG_VIRTUAL_META_MASK;
288
+ }
289
+ else if (len >= 7 && is_hyper (accelerator))
290
+ {
291
+ accelerator += 7;
292
+ len -= 7;
293
+ mods |= EGG_VIRTUAL_HYPER_MASK;
294
+ }
295
+ else if (len >= 7 && is_super (accelerator))
296
+ {
297
+ accelerator += 7;
298
+ len -= 7;
299
+ mods |= EGG_VIRTUAL_SUPER_MASK;
300
+ }
301
+ else
302
+ {
303
+ gchar last_ch;
304
+
305
+ last_ch = *accelerator;
306
+ while (last_ch && last_ch != '>')
307
+ {
308
+ last_ch = *accelerator;
309
+ accelerator += 1;
310
+ len -= 1;
311
+ }
312
+ }
313
+ }
314
+ else
315
+ {
316
+ keyval = gdk_keyval_from_name (accelerator);
317
+
318
+ if (keyval == 0)
319
+ bad_keyval = TRUE;
320
+
321
+ accelerator += len;
322
+ len -= len;
323
+ }
324
+ }
325
+
326
+ if (accelerator_key)
327
+ *accelerator_key = gdk_keyval_to_lower (keyval);
328
+ if (accelerator_mods)
329
+ *accelerator_mods = mods;
330
+
331
+ return !bad_keyval;
332
+ }
333
+
334
+
335
+ /**
336
+ * egg_virtual_accelerator_name:
337
+ * @accelerator_key: accelerator keyval
338
+ * @accelerator_mods: accelerator modifier mask
339
+ * @returns: a newly-allocated accelerator name
340
+ *
341
+ * Converts an accelerator keyval and modifier mask
342
+ * into a string parseable by egg_accelerator_parse_virtual().
343
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344
+ * this function returns "&lt;Control&gt;q".
345
+ *
346
+ * The caller of this function must free the returned string.
347
+ */
348
+ gchar*
349
+ egg_virtual_accelerator_name (guint accelerator_key,
350
+ EggVirtualModifierType accelerator_mods)
351
+ {
352
+ static const gchar text_release[] = "<Release>";
353
+ static const gchar text_shift[] = "<Shift>";
354
+ static const gchar text_control[] = "<Control>";
355
+ static const gchar text_mod1[] = "<Alt>";
356
+ static const gchar text_mod2[] = "<Mod2>";
357
+ static const gchar text_mod3[] = "<Mod3>";
358
+ static const gchar text_mod4[] = "<Mod4>";
359
+ static const gchar text_mod5[] = "<Mod5>";
360
+ static const gchar text_meta[] = "<Meta>";
361
+ static const gchar text_super[] = "<Super>";
362
+ static const gchar text_hyper[] = "<Hyper>";
363
+ guint l;
364
+ gchar *keyval_name;
365
+ gchar *accelerator;
366
+
367
+ accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
+
369
+ keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370
+ if (!keyval_name)
371
+ keyval_name = "";
372
+
373
+ l = 0;
374
+ if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375
+ l += sizeof (text_release) - 1;
376
+ if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377
+ l += sizeof (text_shift) - 1;
378
+ if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379
+ l += sizeof (text_control) - 1;
380
+ if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381
+ l += sizeof (text_mod1) - 1;
382
+ if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383
+ l += sizeof (text_mod2) - 1;
384
+ if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385
+ l += sizeof (text_mod3) - 1;
386
+ if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387
+ l += sizeof (text_mod4) - 1;
388
+ if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389
+ l += sizeof (text_mod5) - 1;
390
+ if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391
+ l += sizeof (text_meta) - 1;
392
+ if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393
+ l += sizeof (text_hyper) - 1;
394
+ if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395
+ l += sizeof (text_super) - 1;
396
+ l += strlen (keyval_name);
397
+
398
+ accelerator = g_new (gchar, l + 1);
399
+
400
+ l = 0;
401
+ accelerator[l] = 0;
402
+ if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403
+ {
404
+ strcpy (accelerator + l, text_release);
405
+ l += sizeof (text_release) - 1;
406
+ }
407
+ if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408
+ {
409
+ strcpy (accelerator + l, text_shift);
410
+ l += sizeof (text_shift) - 1;
411
+ }
412
+ if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413
+ {
414
+ strcpy (accelerator + l, text_control);
415
+ l += sizeof (text_control) - 1;
416
+ }
417
+ if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418
+ {
419
+ strcpy (accelerator + l, text_mod1);
420
+ l += sizeof (text_mod1) - 1;
421
+ }
422
+ if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423
+ {
424
+ strcpy (accelerator + l, text_mod2);
425
+ l += sizeof (text_mod2) - 1;
426
+ }
427
+ if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428
+ {
429
+ strcpy (accelerator + l, text_mod3);
430
+ l += sizeof (text_mod3) - 1;
431
+ }
432
+ if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433
+ {
434
+ strcpy (accelerator + l, text_mod4);
435
+ l += sizeof (text_mod4) - 1;
436
+ }
437
+ if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438
+ {
439
+ strcpy (accelerator + l, text_mod5);
440
+ l += sizeof (text_mod5) - 1;
441
+ }
442
+ if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443
+ {
444
+ strcpy (accelerator + l, text_meta);
445
+ l += sizeof (text_meta) - 1;
446
+ }
447
+ if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448
+ {
449
+ strcpy (accelerator + l, text_hyper);
450
+ l += sizeof (text_hyper) - 1;
451
+ }
452
+ if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453
+ {
454
+ strcpy (accelerator + l, text_super);
455
+ l += sizeof (text_super) - 1;
456
+ }
457
+
458
+ strcpy (accelerator + l, keyval_name);
459
+
460
+ return accelerator;
461
+ }
462
+
463
+ void
464
+ egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465
+ EggVirtualModifierType virtual_mods,
466
+ GdkModifierType *concrete_mods)
467
+ {
468
+ GdkModifierType concrete;
469
+ int i;
470
+ const EggModmap *modmap;
471
+
472
+ g_return_if_fail (GDK_IS_KEYMAP (keymap));
473
+ g_return_if_fail (concrete_mods != NULL);
474
+
475
+ modmap = egg_keymap_get_modmap (keymap);
476
+
477
+ /* Not so sure about this algorithm. */
478
+
479
+ concrete = 0;
480
+ i = 0;
481
+ while (i < EGG_MODMAP_ENTRY_LAST)
482
+ {
483
+ if (modmap->mapping[i] & virtual_mods)
484
+ concrete |= (1 << i);
485
+
486
+ ++i;
487
+ }
488
+
489
+ *concrete_mods = concrete;
490
+ }
491
+
492
+ void
493
+ egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494
+ GdkModifierType concrete_mods,
495
+ EggVirtualModifierType *virtual_mods)
496
+ {
497
+ GdkModifierType virtual;
498
+ int i;
499
+ const EggModmap *modmap;
500
+
501
+ g_return_if_fail (GDK_IS_KEYMAP (keymap));
502
+ g_return_if_fail (virtual_mods != NULL);
503
+
504
+ modmap = egg_keymap_get_modmap (keymap);
505
+
506
+ /* Not so sure about this algorithm. */
507
+
508
+ virtual = 0;
509
+ i = 0;
510
+ while (i < EGG_MODMAP_ENTRY_LAST)
511
+ {
512
+ if ((1 << i) & concrete_mods)
513
+ {
514
+ EggVirtualModifierType cleaned;
515
+
516
+ cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517
+ EGG_VIRTUAL_MOD3_MASK |
518
+ EGG_VIRTUAL_MOD4_MASK |
519
+ EGG_VIRTUAL_MOD5_MASK);
520
+
521
+ if (cleaned != 0)
522
+ {
523
+ virtual |= cleaned;
524
+ }
525
+ else
526
+ {
527
+ /* Rather than dropping mod2->mod5 if not bound,
528
+ * go ahead and use the concrete names
529
+ */
530
+ virtual |= modmap->mapping[i];
531
+ }
532
+ }
533
+
534
+ ++i;
535
+ }
536
+
537
+ *virtual_mods = virtual;
538
+ }
539
+
540
+ static void
541
+ reload_modmap (GdkKeymap *keymap,
542
+ EggModmap *modmap)
543
+ {
544
+ XModifierKeymap *xmodmap;
545
+ int map_size;
546
+ int i;
547
+
548
+ /* FIXME multihead */
549
+ xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
+
551
+ memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
+
553
+ /* there are 8 modifiers, and the first 3 are shift, shift lock,
554
+ * and control
555
+ */
556
+ map_size = 8 * xmodmap->max_keypermod;
557
+ i = 3 * xmodmap->max_keypermod;
558
+ while (i < map_size)
559
+ {
560
+ /* get the key code at this point in the map,
561
+ * see if its keysym is one we're interested in
562
+ */
563
+ int keycode = xmodmap->modifiermap[i];
564
+ GdkKeymapKey *keys;
565
+ guint *keyvals;
566
+ int n_entries;
567
+ int j;
568
+ EggVirtualModifierType mask;
569
+
570
+ keys = NULL;
571
+ keyvals = NULL;
572
+ n_entries = 0;
573
+
574
+ gdk_keymap_get_entries_for_keycode (keymap,
575
+ keycode,
576
+ &keys, &keyvals, &n_entries);
577
+
578
+ mask = 0;
579
+ j = 0;
580
+ while (j < n_entries)
581
+ {
582
+ if (keyvals[j] == GDK_Num_Lock)
583
+ mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584
+ else if (keyvals[j] == GDK_Scroll_Lock)
585
+ mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586
+ else if (keyvals[j] == GDK_Meta_L ||
587
+ keyvals[j] == GDK_Meta_R)
588
+ mask |= EGG_VIRTUAL_META_MASK;
589
+ else if (keyvals[j] == GDK_Hyper_L ||
590
+ keyvals[j] == GDK_Hyper_R)
591
+ mask |= EGG_VIRTUAL_HYPER_MASK;
592
+ else if (keyvals[j] == GDK_Super_L ||
593
+ keyvals[j] == GDK_Super_R)
594
+ mask |= EGG_VIRTUAL_SUPER_MASK;
595
+ else if (keyvals[j] == GDK_Mode_switch)
596
+ mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
+
598
+ ++j;
599
+ }
600
+
601
+ /* Mod1Mask is 1 << 3 for example, i.e. the
602
+ * fourth modifier, i / keyspermod is the modifier
603
+ * index
604
+ */
605
+ modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
+
607
+ g_free (keyvals);
608
+ g_free (keys);
609
+
610
+ ++i;
611
+ }
612
+
613
+ /* Add in the not-really-virtual fixed entries */
614
+ modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615
+ modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616
+ modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
+
623
+ XFreeModifiermap (xmodmap);
624
+ }
625
+
626
+ const EggModmap*
627
+ egg_keymap_get_modmap (GdkKeymap *keymap)
628
+ {
629
+ EggModmap *modmap;
630
+
631
+ /* This is all a hack, much simpler when we can just
632
+ * modify GDK directly.
633
+ */
634
+
635
+ modmap = g_object_get_data (G_OBJECT (keymap),
636
+ "egg-modmap");
637
+
638
+ if (modmap == NULL)
639
+ {
640
+ modmap = g_new0 (EggModmap, 1);
641
+
642
+ /* FIXME modify keymap change events with an event filter
643
+ * and force a reload if we get one
644
+ */
645
+
646
+ reload_modmap (keymap, modmap);
647
+
648
+ g_object_set_data_full (G_OBJECT (keymap),
649
+ "egg-modmap",
650
+ modmap,
651
+ g_free);
652
+ }
653
+
654
+ g_assert (modmap != NULL);
655
+
656
+ return modmap;
657
+ }