1 #include "evas_common_private.h"
2 #include "evas_private.h"
3 
4 /* private calls */
5 
6 static int
evas_key_modifier_number(const Evas_Modifier * m,const char * keyname)7 evas_key_modifier_number(const Evas_Modifier *m, const char *keyname)
8 {
9    int i;
10 
11    for (i = 0; i < m->mod.count; i++)
12      {
13 	if (!strcmp(m->mod.list[i], keyname)) return i;
14      }
15    return -1;
16 }
17 
18 static int
evas_key_lock_number(const Evas_Lock * l,const char * keyname)19 evas_key_lock_number(const Evas_Lock *l, const char *keyname)
20 {
21    int i;
22 
23    for (i = 0; i < l->lock.count; i++)
24      {
25 	if (!strcmp(l->lock.list[i], keyname)) return i;
26      }
27    return -1;
28 }
29 
30 /* local calls */
31 
32 /* public calls */
33 
34 EAPI const Evas_Modifier*
evas_key_modifier_get(const Evas * eo_e)35 evas_key_modifier_get(const Evas *eo_e)
36 {
37    EVAS_LEGACY_API(eo_e, e, NULL);
38    return &(e->modifiers);
39 }
40 
41 EAPI const Evas_Lock*
evas_key_lock_get(const Evas * eo_e)42 evas_key_lock_get(const Evas *eo_e)
43 {
44    EVAS_LEGACY_API(eo_e, e, NULL);
45    return &(e->locks);
46 }
47 
48 static Eina_Bool
_key_is_set(int n,Eina_Hash * masks,const Evas_Device * seat)49 _key_is_set(int n, Eina_Hash *masks, const Evas_Device *seat)
50 {
51    Evas_Modifier_Mask num, *seat_mask;
52 
53    if (n < 0) return 0;
54    else if (n >= 64) return 0;
55    num = (Evas_Modifier_Mask)n;
56    num = 1ULL << num;
57    seat_mask = eina_hash_find(masks, &seat);
58    if (!seat_mask) return 0;
59    if (*seat_mask & num) return 1;
60    return 0;
61 }
62 
63 EAPI Eina_Bool
evas_seat_key_modifier_is_set(const Evas_Modifier * m,const char * keyname,const Evas_Device * seat)64 evas_seat_key_modifier_is_set(const Evas_Modifier *m, const char *keyname,
65                               const Evas_Device *seat)
66 {
67    EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE);
68    if (!seat)
69      seat = m->e->default_seat;
70    EINA_SAFETY_ON_NULL_RETURN_VAL(seat, 0);
71    if (!keyname) return 0;
72    return _key_is_set(evas_key_modifier_number(m, keyname), m->masks, seat);
73 }
74 
75 EAPI Eina_Bool
evas_key_modifier_is_set(const Evas_Modifier * m,const char * keyname)76 evas_key_modifier_is_set(const Evas_Modifier *m, const char *keyname)
77 {
78    EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE);
79    return evas_seat_key_modifier_is_set(m, keyname, NULL);
80 }
81 
82 EAPI Eina_Bool
evas_key_lock_is_set(const Evas_Lock * l,const char * keyname)83 evas_key_lock_is_set(const Evas_Lock *l, const char *keyname)
84 {
85    EINA_SAFETY_ON_NULL_RETURN_VAL(l, EINA_FALSE);
86    return evas_seat_key_lock_is_set(l, keyname, NULL);
87 }
88 
89 EAPI Eina_Bool
evas_seat_key_lock_is_set(const Evas_Lock * l,const char * keyname,const Evas_Device * seat)90 evas_seat_key_lock_is_set(const Evas_Lock *l, const char *keyname,
91                           const Evas_Device *seat)
92 {
93    EINA_SAFETY_ON_NULL_RETURN_VAL(l, EINA_FALSE);
94    if (!seat)
95      seat = l->e->default_seat;
96    EINA_SAFETY_ON_NULL_RETURN_VAL(seat, 0);
97    if (!keyname) return 0;
98    return _key_is_set(evas_key_lock_number(l, keyname), l->masks, seat);
99 }
100 
101 EOLIAN void
_evas_canvas_key_modifier_add(Eo * eo_e,Evas_Public_Data * e,const char * keyname)102 _evas_canvas_key_modifier_add(Eo *eo_e, Evas_Public_Data *e, const char *keyname)
103 {
104    if (!keyname) return;
105    if (e->modifiers.mod.count >= 64) return;
106    evas_key_modifier_del(eo_e, keyname);
107    e->modifiers.mod.count++;
108    e->modifiers.mod.list = realloc(e->modifiers.mod.list, e->modifiers.mod.count * sizeof(char *));
109    e->modifiers.mod.list[e->modifiers.mod.count - 1] = strdup(keyname);
110    eina_hash_free_buckets(e->modifiers.masks);
111 }
112 
113 EOLIAN void
_evas_canvas_key_modifier_del(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,const char * keyname)114 _evas_canvas_key_modifier_del(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, const char *keyname)
115 {
116    int i;
117 
118    if (!keyname) return;
119    for (i = 0; i < e->modifiers.mod.count; i++)
120      {
121 	if (!strcmp(e->modifiers.mod.list[i], keyname))
122 	  {
123 	     int j;
124 
125 	     free(e->modifiers.mod.list[i]);
126 	     e->modifiers.mod.count--;
127 	     for (j = i; j < e->modifiers.mod.count; j++)
128 	       e->modifiers.mod.list[j] = e->modifiers.mod.list[j + 1];
129              eina_hash_free_buckets(e->modifiers.masks);
130 	     return;
131 	  }
132      }
133 }
134 
135 EOLIAN void
_evas_canvas_key_lock_add(Eo * eo_e,Evas_Public_Data * e,const char * keyname)136 _evas_canvas_key_lock_add(Eo *eo_e, Evas_Public_Data *e, const char *keyname)
137 {
138    if (!keyname) return;
139    if (e->locks.lock.count >= 64) return;
140    evas_key_lock_del(eo_e, keyname);
141    e->locks.lock.count++;
142    e->locks.lock.list = realloc(e->locks.lock.list, e->locks.lock.count * sizeof(char *));
143    e->locks.lock.list[e->locks.lock.count - 1] = strdup(keyname);
144    eina_hash_free_buckets(e->locks.masks);
145 }
146 
147 EOLIAN void
_evas_canvas_key_lock_del(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,const char * keyname)148 _evas_canvas_key_lock_del(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, const char *keyname)
149 {
150    int i;
151    if (!keyname) return;
152    for (i = 0; i < e->locks.lock.count; i++)
153      {
154 	if (!strcmp(e->locks.lock.list[i], keyname))
155 	  {
156 	     int j;
157 
158 	     free(e->locks.lock.list[i]);
159 	     e->locks.lock.count--;
160 	     for (j = i; j < e->locks.lock.count; j++)
161 	       e->locks.lock.list[j] = e->locks.lock.list[j + 1];
162              eina_hash_free_buckets(e->locks.masks);
163 	     return;
164 	  }
165      }
166 }
167 
168 static void
_mask_set(int n,Eina_Hash * masks,Efl_Input_Device * seat,Eina_Bool add)169 _mask_set(int n, Eina_Hash *masks, Efl_Input_Device *seat, Eina_Bool add)
170 {
171    Evas_Modifier_Mask *current_mask;
172    Evas_Modifier_Mask num;
173 
174    if (n < 0 || n > 63) return;
175    num = 1ULL << n;
176 
177    current_mask = eina_hash_find(masks, &seat);
178    if (add)
179      {
180         if (!current_mask)
181           {
182              current_mask = calloc(1, sizeof(Evas_Modifier_Mask));
183              EINA_SAFETY_ON_NULL_RETURN(current_mask);
184              eina_hash_add(masks, &seat, current_mask);
185           }
186         *current_mask |= num;
187      }
188    else
189      {
190         if (!current_mask) return;
191         *current_mask &= ~num;
192         if (!(*current_mask))
193           eina_hash_del_by_key(masks, &seat);
194      }
195 }
196 
197 EOLIAN void
_evas_canvas_seat_key_modifier_on(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,const char * keyname,Efl_Input_Device * seat)198 _evas_canvas_seat_key_modifier_on(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e,
199                                   const char *keyname, Efl_Input_Device *seat)
200 {
201    if (!seat)
202      seat = e->default_seat;
203    EINA_SAFETY_ON_NULL_RETURN(seat);
204    if (efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_TYPE_SEAT) return;
205    _mask_set(evas_key_modifier_number(&(e->modifiers), keyname),
206              e->modifiers.masks, seat, EINA_TRUE);
207 }
208 
209 EOLIAN void
_evas_canvas_seat_key_modifier_off(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,const char * keyname,Efl_Input_Device * seat)210 _evas_canvas_seat_key_modifier_off(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e,
211                                    const char *keyname, Efl_Input_Device *seat)
212 {
213    if (!seat)
214      seat = e->default_seat;
215    EINA_SAFETY_ON_NULL_RETURN(seat);
216    _mask_set(evas_key_modifier_number(&(e->modifiers), keyname),
217              e->modifiers.masks, seat, EINA_FALSE);
218 }
219 
220 EOLIAN void
_evas_canvas_key_modifier_on(Eo * eo_e,Evas_Public_Data * e,const char * keyname)221 _evas_canvas_key_modifier_on(Eo *eo_e, Evas_Public_Data *e, const char *keyname)
222 {
223    _evas_canvas_seat_key_modifier_on(eo_e, e, keyname, NULL);
224 }
225 
226 EOLIAN void
_evas_canvas_key_modifier_off(Eo * eo_e,Evas_Public_Data * e,const char * keyname)227 _evas_canvas_key_modifier_off(Eo *eo_e, Evas_Public_Data *e,
228                               const char *keyname)
229 {
230    _evas_canvas_seat_key_modifier_off(eo_e, e, keyname, NULL);
231 }
232 
233 EOLIAN void
_evas_canvas_seat_key_lock_on(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,const char * keyname,Efl_Input_Device * seat)234 _evas_canvas_seat_key_lock_on(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e,
235                               const char *keyname, Efl_Input_Device *seat)
236 {
237    if (!seat)
238      seat = e->default_seat;
239    EINA_SAFETY_ON_NULL_RETURN(seat);
240    if (efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_TYPE_SEAT) return;
241    _mask_set(evas_key_lock_number(&(e->locks), keyname), e->locks.masks,
242              seat, EINA_TRUE);
243 }
244 
245 EOLIAN void
_evas_canvas_seat_key_lock_off(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,const char * keyname,Efl_Input_Device * seat)246 _evas_canvas_seat_key_lock_off(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e,
247                                const char *keyname, Efl_Input_Device *seat)
248 {
249    if (!seat)
250      seat = e->default_seat;
251    EINA_SAFETY_ON_NULL_RETURN(seat);
252    _mask_set(evas_key_lock_number(&(e->locks), keyname), e->locks.masks,
253              seat, EINA_FALSE);
254 }
255 
256 EOLIAN void
_evas_canvas_key_lock_on(Eo * eo_e,Evas_Public_Data * e,const char * keyname)257 _evas_canvas_key_lock_on(Eo *eo_e, Evas_Public_Data *e, const char *keyname)
258 {
259    _evas_canvas_seat_key_lock_on(eo_e, e, keyname, NULL);
260 }
261 
262 EOLIAN void
_evas_canvas_key_lock_off(Eo * eo_e,Evas_Public_Data * e,const char * keyname)263 _evas_canvas_key_lock_off(Eo *eo_e, Evas_Public_Data *e, const char *keyname)
264 {
265    _evas_canvas_seat_key_lock_off(eo_e, e, keyname, NULL);
266 }
267 
268 /* errr need to add key grabbing/ungrabbing calls - missing modifier stuff. */
269 
270 EAPI Evas_Modifier_Mask
evas_key_modifier_mask_get(const Evas * eo_e,const char * keyname)271 evas_key_modifier_mask_get(const Evas *eo_e, const char *keyname)
272 {
273    int n;
274 
275    if (!keyname) return 0;
276    EVAS_LEGACY_API(eo_e, e, 0);
277    n = evas_key_modifier_number(&(e->modifiers), keyname);
278    if (n < 0 || n > 63) return 0;
279    return 1ULL << n;
280 }
281 
282