Renamed package to ion1, and made it conflict with package 'ion'.
[ion1.git] / src / key.c
blob19e663a6f3a19c76c4f9dcee591c52d62a1f7efa
1 /*
2 * ion/key.c
4 * Copyright (c) Tuomo Valkonen 1999-2001.
5 * See the included file LICENSE for details.
6 */
8 #include <ctype.h>
10 #include "common.h"
11 #include "binding.h"
12 #include "global.h"
13 #include "key.h"
14 #include "event.h"
15 #include "cursor.h"
16 #include "client.h"
17 #include "grab.h"
19 /*{{{ prototypes */
21 static void waitrelease(WScreen *screen);
23 /*}}}*/
25 void adhoc_insstr(WEdln *wedln, XKeyEvent *ev)
27 static XComposeStatus cs={NULL, 0};
28 char buf[16]={0,};
29 Status stat;
30 int n;
31 KeySym ksym;
33 if(wedln->input.win.xic!=NULL){
34 if(XFilterEvent((XEvent*)ev, ev->window))
35 return;
36 n=XmbLookupString(wedln->input.win.xic, ev, buf, 16, &ksym, &stat);
37 }else{
38 n=XLookupString(ev, buf, 16, &ksym, &cs);
41 if(n<=0 || *(uchar*)buf<32)
42 return;
44 edln_insstr(&(wedln->edln), buf);
47 static WBinding *lookup_binding_from_event(WWindow *thing, XKeyEvent *ev)
49 WBinding *binding;
50 WBindmap **bindptr;
52 bindptr=&thing->bindmap;
53 assert(*bindptr!=NULL);
55 binding=lookup_binding(*bindptr, ACT_KEYPRESS, ev->state, ev->keycode);
56 return binding;
59 /* dispatch_binding
60 * the return values are those expected by GrabHandler's, i.e.
61 * you can just pass through the retval obtained from this function
63 static bool dispatch_binding(WThing *thing, WBinding *binding, XKeyEvent *ev)
65 WScreen *scr;
67 if(binding){
68 /* Get the screen now for waitrel grab - the thing might
69 * have been destroyed when call_binding returns.
71 scr=SCREEN_OF(thing);
72 call_binding(binding, thing);
73 if(ev->state!=0 && binding->waitrel){
74 waitrelease(scr);
75 /* return FALSE here to prevent uninstalling the waitrelease handler
76 immediately after establishing it */
77 return FALSE;
80 return TRUE;
83 static void send_key(XEvent *ev, WClientWin *cwin)
85 Window win=cwin->win;
86 ev->xkey.window=win;
87 ev->xkey.subwindow=None;
88 XSendEvent(wglobal.dpy, win, False, KeyPressMask, ev);
92 static bool quote_next_handler(WThing *thing, XEvent *xev)
94 XKeyEvent *ev=&xev->xkey;
95 if(ev->type==KeyRelease)
96 return TRUE;
97 if(ismod(ev->keycode))
98 return FALSE;
99 assert(WTHING_IS(thing, WClientWin));
100 send_key(xev, (WClientWin*)thing);
101 return TRUE; /* remove the grab */
104 void quote_next(WClient *client)
106 WClientWin *cwin=LAST_THING(client, WClientWin);
108 if(cwin==NULL)
109 return;
111 grab_establish((WThing*)cwin, quote_next_handler, FocusChangeMask);
114 static bool waitrelease_handler(WThing *thing, XEvent *ev)
116 if(!unmod(ev->xkey.state, ev->xkey.keycode))
117 return TRUE;
118 return FALSE;
121 static void waitrelease(WScreen *screen)
123 grab_establish((WThing *)screen, waitrelease_handler, FocusChangeMask);
126 static bool submapgrab_handler(WThing *thing, XEvent *ev)
128 WBinding *binding;
130 /*if(ev->type==KeyRelease)
131 return FALSE;*/
133 binding=lookup_binding_from_event((WWindow*)thing, &ev->xkey);
135 if(binding==NULL)
136 if(ismod(ev->xkey.keycode)){
137 return FALSE;
140 return dispatch_binding(thing, binding, &ev->xkey);
143 static void submapgrab(WThing *thing)
145 grab_establish(thing, submapgrab_handler, FocusChangeMask|KeyReleaseMask);
148 void handle_keypress(XKeyEvent *ev)
150 WThing *thing=NULL;
151 WScreen *scr;
152 WBinding *binding=NULL;
153 WBindmap **bindptr;
154 bool topmap=TRUE;
155 bool toplvl=FALSE;
157 /* this function gets called with grab_holder==NULL */
159 thing=FIND_WINDOW(ev->window);
160 if(thing==NULL || !WTHING_IS(thing, WWindow))
161 return;
163 toplvl=WTHING_IS(thing, WFrame);
164 bindptr=&(((WWindow*)thing)->bindmap);
166 while((*bindptr)->parent!=NULL){
167 topmap=FALSE;
168 *bindptr=(*bindptr)->parent;
171 binding=lookup_binding_from_event((WWindow*)thing, ev);
174 if(binding!=NULL && binding->submap!=NULL){
175 *bindptr=binding->submap;
176 if(toplvl){
177 submapgrab(thing);
179 return;
182 if(binding!=NULL)
183 dispatch_binding(thing, binding, ev);
184 else{
185 if(topmap && WTHING_IS(thing, WEdln))
186 adhoc_insstr((WEdln*)thing, ev);