1 /*
2 * (C)opyright 2007-2009 Robert Manea <rob dot manea at gmail dot com>
3 * See LICENSE file for license details.
4 *
5 */
6
7 #include "dzen.h"
8 #include "action.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13
14 struct event_lookup ev_lookup_table[] = {
15 { "onstart", onstart},
16 { "onexit", onexit},
17 { "onnewinput", onnewinput},
18 { "button1", button1},
19 { "button2", button2},
20 { "button3", button3},
21 { "button4", button4},
22 { "button5", button5},
23 { "button6", button6},
24 { "button7", button7},
25 { "entertitle", entertitle},
26 { "leavetitle", leavetitle},
27 { "enterslave", enterslave},
28 { "leaveslave", leaveslave},
29 { "sigusr1", sigusr1},
30 { "sigusr2", sigusr2},
31 { "keymarker", keymarker},
32 { 0, 0 }
33 };
34
35 struct action_lookup ac_lookup_table[] = {
36 { "print", a_print },
37 { "exec", a_exec},
38 { "exit", a_exit},
39 { "collapse", a_collapse},
40 { "uncollapse", a_uncollapse},
41 { "togglecollapse", a_togglecollapse},
42 { "stick", a_stick},
43 { "unstick", a_unstick},
44 { "togglestick", a_togglestick},
45 { "hide", a_hide},
46 { "unhide", a_unhide},
47 { "togglehide", a_togglehide},
48 { "scrollup", a_scrollup},
49 { "scrolldown", a_scrolldown},
50 { "menuprint", a_menuprint},
51 { "menuprint_noparse", a_menuprint_noparse},
52 { "menuexec", a_menuexec},
53 { "raise", a_raise},
54 { "lower", a_lower},
55 { "scrollhome", a_scrollhome},
56 { "scrollend", a_scrollend},
57 { "grabkeys", a_grabkeys},
58 { "ungrabkeys", a_ungrabkeys},
59 { "grabmouse", a_grabmouse},
60 { "ungrabmouse", a_ungrabmouse},
61 { 0, 0 }
62 };
63
64 ev_list *head = NULL;
65
66 static int
new_event(long evid)67 new_event(long evid) {
68 ev_list *item, *newitem;
69
70 if(!head) {
71 head = emalloc(sizeof (ev_list));
72 head->id = evid;
73 head->next = NULL;
74 }
75 else {
76 item = head;
77 /* check if we already handle this event */
78 while(item) {
79 if(item->id == evid)
80 return 0;
81 item = item->next;
82 }
83 item = head;
84 while(item->next)
85 item = item->next;
86
87 newitem = emalloc(sizeof (ev_list));
88 newitem->id = evid;
89 item->next = newitem;
90 newitem->next = NULL;
91 }
92 return 0;
93 }
94
95 static void
add_handler(long evid,int hpos,handlerf * hcb)96 add_handler(long evid, int hpos, handlerf* hcb) {
97 ev_list *item;
98
99 item = head;
100 while(item) {
101 if(item->id == evid) {
102 if(hpos < MAXACTIONS) {
103 item->action[hpos] = emalloc(sizeof(As));
104 item->action[hpos]->handler = hcb;
105 }
106 break;
107 }
108 item = item->next;
109 }
110 }
111
112 static void
add_option(long evid,int hpos,int opos,char * opt)113 add_option(long evid, int hpos, int opos, char* opt) {
114 ev_list *item;
115
116 item = head;
117 while(item) {
118 if(item->id == evid) {
119 if(opos < MAXOPTIONS) {
120 item->action[hpos]->options[opos] = estrdup(opt);
121 item->action[hpos]->options[opos+1] = NULL;
122 }
123 break;
124 }
125 item = item->next;
126 }
127 }
128
129 int
find_event(long evid)130 find_event(long evid) {
131 ev_list *item;
132
133 item = head;
134 while(item) {
135 if(item->id == evid)
136 return item->id;
137 item = item->next;
138 }
139
140 return -1;
141 }
142
143 void
do_action(long evid)144 do_action(long evid) {
145 int i;
146 ev_list *item;
147
148 item = head;
149 while(item) {
150 if(item->id == evid)
151 break;
152 item = item->next;
153 }
154
155 if(item) {
156 for(i=0; item->action[i]->handler; i++) {
157 item->action[i]->handler(item->action[i]->options);
158 }
159 }
160 }
161
162 int
get_ev_id(const char * evname)163 get_ev_id(const char *evname) {
164 int i;
165 KeySym ks;
166
167 /* check for keyboard event */
168 if((!strncmp(evname, "key_", 4))
169 && ((ks = XStringToKeysym(evname+4)) != NoSymbol)) {
170 return ks+keymarker;
171 }
172
173 /* own events */
174 for(i=0; ev_lookup_table[i].name; i++) {
175 if(strncmp(ev_lookup_table[i].name, evname, strlen(ev_lookup_table[i].name)) == 0)
176 return ev_lookup_table[i].id;
177 }
178 return -1;
179 }
180
181 handlerf *
get_action_handler(const char * acname)182 get_action_handler(const char *acname) {
183 int i;
184
185 for(i=0; ac_lookup_table[i].name; i++) {
186 if(strcmp(ac_lookup_table[i].name, acname) == 0)
187 return ac_lookup_table[i].handler;
188 }
189 return NULL;
190 }
191
192
193 void
free_event_list(void)194 free_event_list(void) {
195 int i;
196 ev_list *item;
197
198 item = head;
199 while(item) {
200 for(i=0; item->action[i]->handler; i++)
201 free(item->action[i]);
202 item = item->next;
203 }
204 }
205
206 void
fill_ev_table(char * input)207 fill_ev_table(char *input) {
208 char *str1, *str2, *str3, *str4,
209 *token, *subtoken, *kommatoken, *dptoken;
210 char *saveptr1=NULL,
211 *saveptr2=NULL,
212 *saveptr3=NULL,
213 *saveptr4=NULL;
214 int j, i=0, k=0;
215 long eid=0;
216 handlerf *ah=0;
217
218 for (j = 1, str1 = input; ; j++, str1 = NULL) {
219 token = strtok_r(str1, ";", &saveptr1);
220 if (token == NULL)
221 break;
222
223 for (str2 = token; ; str2 = NULL) {
224 subtoken = strtok_r(str2, "=", &saveptr2);
225 if (subtoken == NULL)
226 break;
227 if( (str2 == token) && ((eid = get_ev_id(subtoken)) != -1))
228 ;
229 else if(eid == -1)
230 break;
231
232 for (str3 = subtoken; ; str3 = NULL) {
233 kommatoken = strtok_r(str3, ",", &saveptr3);
234 if (kommatoken == NULL)
235 break;
236
237 for (str4 = kommatoken; ; str4 = NULL) {
238 dptoken = strtok_r(str4, ":", &saveptr4);
239 if (dptoken == NULL) {
240 break;
241 }
242 if(str4 == kommatoken && str4 != token && eid != -1) {
243 if((ah = get_action_handler(dptoken)) != NULL) {
244 new_event(eid);
245 add_handler(eid, i, ah);
246 i++;
247 }
248 }
249 else if(str4 != token && eid != -1 && ah) {
250 add_option(eid, i-1, k, dptoken);
251 k++;
252 }
253 else if(!ah)
254 break;
255 }
256 k=0;
257 }
258 new_event(eid);
259 add_handler(eid, i, NULL);
260 i=0;
261 }
262 }
263 }
264
265
266 /* actions */
267 int
a_exit(char * opt[])268 a_exit(char * opt[]) {
269 if(opt[0])
270 dzen.ret_val = atoi(opt[0]);
271 dzen.running = False;
272 return 0;
273 }
274
275 int
a_collapse(char * opt[])276 a_collapse(char * opt[]){
277 (void)opt;
278 if(!dzen.slave_win.ishmenu
279 && dzen.slave_win.max_lines
280 && !dzen.slave_win.issticky) {
281 XUnmapWindow(dzen.dpy, dzen.slave_win.win);
282 }
283 return 0;
284 }
285
286 int
a_uncollapse(char * opt[])287 a_uncollapse(char * opt[]){
288 int i;
289 (void)opt;
290 if(!dzen.slave_win.ishmenu
291 && dzen.slave_win.max_lines
292 && !dzen.slave_win.issticky) {
293 XMapRaised(dzen.dpy, dzen.slave_win.win);
294 for(i=0; i < dzen.slave_win.max_lines; i++)
295 XMapWindow(dzen.dpy, dzen.slave_win.line[i]);
296 }
297 return 0;
298 }
299
300 int
a_togglecollapse(char * opt[])301 a_togglecollapse(char * opt[]){
302 XWindowAttributes wa;
303 (void)opt;
304
305 if(dzen.slave_win.max_lines &&
306 (XGetWindowAttributes(dzen.dpy, dzen.slave_win.win, &wa), wa.map_state == IsUnmapped))
307 a_uncollapse(NULL);
308 else
309 a_collapse(NULL);
310
311 return 0;
312 }
313
314 int
a_stick(char * opt[])315 a_stick(char * opt[]) {
316 (void)opt;
317 if(!dzen.slave_win.ishmenu
318 && dzen.slave_win.max_lines)
319 dzen.slave_win.issticky = True;
320 return 0;
321 }
322
323 int
a_unstick(char * opt[])324 a_unstick(char * opt[]) {
325 (void)opt;
326 if(!dzen.slave_win.ishmenu
327 && dzen.slave_win.max_lines)
328 dzen.slave_win.issticky = False;
329 return 0;
330 }
331
332 int
a_togglestick(char * opt[])333 a_togglestick(char * opt[]) {
334 (void)opt;
335 if(!dzen.slave_win.ishmenu
336 && dzen.slave_win.max_lines)
337 dzen.slave_win.issticky = dzen.slave_win.issticky ? False : True;
338 return 0;
339 }
340
341 static void
scroll(int n)342 scroll(int n) {
343 if(dzen.slave_win.tcnt <= dzen.slave_win.max_lines)
344 return;
345 if(dzen.slave_win.first_line_vis + n < 0) {
346 dzen.slave_win.first_line_vis = 0;
347 dzen.slave_win.last_line_vis = dzen.slave_win.max_lines;
348 }
349 else if(dzen.slave_win.last_line_vis + n > dzen.slave_win.tcnt) {
350 dzen.slave_win.first_line_vis = dzen.slave_win.tcnt - dzen.slave_win.max_lines;
351 dzen.slave_win.last_line_vis = dzen.slave_win.tcnt;
352 }
353 else {
354 dzen.slave_win.first_line_vis += n;
355 dzen.slave_win.last_line_vis += n;
356 }
357
358 x_draw_body();
359 }
360
361 int
a_scrollup(char * opt[])362 a_scrollup(char * opt[]) {
363 int n=1;
364
365 if(opt[0])
366 n = atoi(opt[0]);
367 if(dzen.slave_win.max_lines)
368 scroll(-1*n);
369
370 return 0;
371 }
372
373 int
a_scrolldown(char * opt[])374 a_scrolldown(char * opt[]) {
375 int n=1;
376
377 if(opt[0])
378 n = atoi(opt[0]);
379 if(dzen.slave_win.max_lines)
380 scroll(n);
381
382 return 0;
383 }
384
385 int
a_hide(char * opt[])386 a_hide(char * opt[]) {
387 int n=1;
388
389
390 printf("n:%d\n", n);
391 if(!dzen.title_win.ishidden) {
392 if(!dzen.slave_win.ishmenu)
393 XResizeWindow(dzen.dpy, dzen.title_win.win, dzen.title_win.width, 1);
394 else
395 XResizeWindow(dzen.dpy, dzen.slave_win.win, dzen.title_win.width, 1);
396
397 dzen.title_win.ishidden = True;
398 }
399 return 0;
400 }
401
402 int
a_unhide(char * opt[])403 a_unhide(char * opt[]) {
404 (void)opt;
405 if(dzen.title_win.ishidden) {
406 if(!dzen.slave_win.ishmenu)
407 XResizeWindow(dzen.dpy, dzen.title_win.win, dzen.title_win.width, dzen.line_height);
408 else
409 XResizeWindow(dzen.dpy, dzen.slave_win.win, dzen.title_win.width, dzen.line_height);
410
411 dzen.title_win.ishidden = False;
412 }
413 return 0;
414 }
415
416 int
a_togglehide(char * opt[])417 a_togglehide(char * opt[]) {
418
419 dzen.title_win.ishidden ?
420 a_unhide(NULL) :
421 a_hide(opt);
422
423 return 0;
424 }
425
426 int
a_exec(char * opt[])427 a_exec(char * opt[]) {
428 int i;
429
430 if(opt)
431 for(i=0; opt[i]; i++)
432 if(opt[i]) spawn(opt[i]);
433 return 0;
434 }
435
436 int
a_print(char * opt[])437 a_print(char * opt[]) {
438 int i;
439
440 if(opt)
441 for(i=0; opt[i]; i++)
442 puts(opt[i]);
443 fflush(stdout);
444 return 0;
445 }
446
447 int
a_menuprint(char * opt[])448 a_menuprint(char * opt[]) {
449 char *text;
450 int i;
451
452 if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1
453 && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) {
454 text = parse_line(NULL, dzen.slave_win.sel_line, 0, 0, 1);
455 printf("%s", text);
456 if(opt)
457 for(i=0; opt[i]; ++i)
458 printf("%s", opt[i]);
459 puts("");
460 fflush(stdout);
461 dzen.slave_win.sel_line = -1;
462 free(text);
463 }
464 return 0;
465 }
466
467 int
a_menuprint_noparse(char * opt[])468 a_menuprint_noparse(char * opt[]) {
469 int i;
470
471 if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1
472 && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) {
473 printf("%s", dzen.slave_win.tbuf[dzen.slave_win.sel_line]);
474 if(opt)
475 for(i=0; opt[i]; ++i)
476 printf("%s", opt[i]);
477 puts("");
478 fflush(stdout);
479 dzen.slave_win.sel_line = -1;
480 }
481 return 0;
482 }
483
484 int
a_menuexec(char * opt[])485 a_menuexec(char * opt[]) {
486 char *text;
487 (void)opt;
488
489 if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1
490 && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) {
491 text = parse_line(NULL, dzen.slave_win.sel_line, 0, 0, 1);
492 spawn(text);
493 dzen.slave_win.sel_line = -1;
494 free(text);
495 }
496 return 0;
497 }
498
499 int
a_raise(char * opt[])500 a_raise(char * opt[]) {
501 (void)opt;
502 XRaiseWindow(dzen.dpy, dzen.title_win.win);
503
504 if(dzen.slave_win.max_lines)
505 XRaiseWindow(dzen.dpy, dzen.slave_win.win);
506 return 0;
507 }
508
509 int
a_lower(char * opt[])510 a_lower(char * opt[]) {
511 (void)opt;
512 XLowerWindow(dzen.dpy, dzen.title_win.win);
513
514 if(dzen.slave_win.max_lines)
515 XLowerWindow(dzen.dpy, dzen.slave_win.win);
516 return 0;
517 }
518
519 int
a_scrollhome(char * opt[])520 a_scrollhome(char * opt[]) {
521 (void)opt;
522 if(dzen.slave_win.max_lines) {
523 dzen.slave_win.first_line_vis = 0;
524 dzen.slave_win.last_line_vis = dzen.slave_win.max_lines;
525
526 x_draw_body();
527 }
528 return 0;
529 }
530
531 int
a_scrollend(char * opt[])532 a_scrollend(char * opt[]) {
533 (void)opt;
534 if(dzen.slave_win.max_lines) {
535 dzen.slave_win.first_line_vis = dzen.slave_win.tcnt - dzen.slave_win.max_lines ;
536 dzen.slave_win.last_line_vis = dzen.slave_win.tcnt;
537
538 x_draw_body();
539 }
540 return 0;
541 }
542
543 int
a_grabkeys(char * opt[])544 a_grabkeys(char * opt[]) {
545 (void)opt;
546 XGrabKeyboard(dzen.dpy, RootWindow(dzen.dpy, dzen.screen),
547 True, GrabModeAsync, GrabModeAsync, CurrentTime);
548 return 0;
549 }
550
551 int
a_ungrabkeys(char * opt[])552 a_ungrabkeys(char * opt[]) {
553 (void)opt;
554 XUngrabKeyboard(dzen.dpy, CurrentTime);
555 return 0;
556 }
557
558 int
a_grabmouse(char * opt[])559 a_grabmouse(char * opt[]) {
560 (void)opt;
561 XGrabPointer(dzen.dpy, RootWindow(dzen.dpy, dzen.screen),
562 True, ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
563 return 0;
564 }
565
566 int
a_ungrabmouse(char * opt[])567 a_ungrabmouse(char * opt[]) {
568 (void)opt;
569 XUngrabPointer(dzen.dpy, CurrentTime);
570 return 0;
571 }
572
573