73fcd563d0ab05ae45970482c51046f40b7881c3
[framework/uifw/ecore.git] / src / lib / ecore_wince / ecore_wince_event.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include <stdlib.h>
6 #include <stdio.h>   /* for printf */
7
8 #define WIN32_LEAN_AND_MEAN
9 #include <windows.h>
10 #undef WIN32_LEAN_AND_MEAN
11
12 #include "Ecore.h"
13 #include "Ecore_WinCE.h"
14 #include "ecore_wince_private.h"
15
16
17 /***** Private declarations *****/
18
19 static Ecore_WinCE_Window *_ecore_wince_mouse_down_last_window = NULL;
20 static Ecore_WinCE_Window *_ecore_wince_mouse_down_last_last_window = NULL;
21 static double              _ecore_wince_mouse_down_last_time = 0;
22 static double              _ecore_wince_mouse_down_last_last_time = 0;
23 static int                 _ecore_wince_mouse_down_did_triple = 0;
24 static int                 _ecore_wince_mouse_up_count = 0;
25
26
27 static void _ecore_wince_event_free_key_down(void *data,
28                                              void *ev);
29
30 static void _ecore_wince_event_free_key_up(void *data,
31                                            void *ev);
32
33 static int  _ecore_wince_event_keystroke_get(int    key,
34                                              char **keyname,
35                                              char **keysymbol,
36                                              char **keycompose);
37
38 static int  _ecore_wince_event_char_get(int    key,
39                                         char **keyname,
40                                         char **keysymbol,
41                                         char **keycompose);
42
43
44 /***** Global functions *****/
45
46 void
47 _ecore_wince_event_handle_key_press(Ecore_WinCE_Callback_Data *msg)
48 {
49    Ecore_WinCE_Event_Key_Down *e;
50
51    e = (Ecore_WinCE_Event_Key_Down *)malloc(sizeof(Ecore_WinCE_Event_Key_Down));
52    if (!e) return;
53
54    if (!_ecore_wince_event_keystroke_get(LOWORD(msg->window_param),
55                                          &e->keyname,
56                                          &e->keysymbol,
57                                          &e->keycompose))
58      {
59         free(e);
60         return;
61      }
62
63    e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
64    if (!e->window)
65      {
66         free(e);
67         return;
68      }
69    e->time = (double)msg->time / 1000.0;
70
71    _ecore_wince_event_last_time = e->time;
72
73    ecore_event_add(ECORE_WINCE_EVENT_KEY_DOWN, e, _ecore_wince_event_free_key_down, NULL);
74 }
75
76 void
77 _ecore_wince_event_handle_key_release(Ecore_WinCE_Callback_Data *msg)
78 {
79    Ecore_WinCE_Event_Key_Up *e;
80
81    e = (Ecore_WinCE_Event_Key_Up *)calloc(1, sizeof(Ecore_WinCE_Event_Key_Up));
82    if (!e) return;
83
84    if (!_ecore_wince_event_keystroke_get(LOWORD(msg->window_param),
85                                          &e->keyname,
86                                          &e->keysymbol,
87                                          &e->keycompose))
88      {
89         free(e);
90         return;
91      }
92
93    e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
94    if (!e->window)
95      {
96         free(e);
97         return;
98      }
99    e->time = (double)msg->time / 1000.0;
100
101    _ecore_wince_event_last_time = e->time;
102
103    ecore_event_add(ECORE_WINCE_EVENT_KEY_UP, e, _ecore_wince_event_free_key_up, NULL);
104 }
105
106 void
107 _ecore_wince_event_handle_button_press(Ecore_WinCE_Callback_Data *msg,
108                                        int                        button)
109 {
110    Ecore_WinCE_Window *window;
111
112    window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
113
114    {
115       Ecore_WinCE_Event_Mouse_Move *e;
116
117       e = (Ecore_WinCE_Event_Mouse_Move *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_Move));
118       if (!e) return;
119
120       e->window = window;
121       e->x = LOWORD(msg->data_param);
122       e->y = HIWORD(msg->data_param);
123       e->time = (double)msg->time / 1000.0;
124
125       _ecore_wince_event_last_time = e->time;
126       _ecore_wince_event_last_window = e->window;
127
128       ecore_event_add(ECORE_WINCE_EVENT_MOUSE_MOVE, e, NULL, NULL);
129    }
130
131    {
132       Ecore_WinCE_Event_Mouse_Button_Down *e;
133
134       if (_ecore_wince_mouse_down_did_triple)
135         {
136            _ecore_wince_mouse_down_last_window = NULL;
137            _ecore_wince_mouse_down_last_last_window = NULL;
138            _ecore_wince_mouse_down_last_time = 0.0;
139            _ecore_wince_mouse_down_last_last_time = 0.0;
140         }
141
142       e = (Ecore_WinCE_Event_Mouse_Button_Down *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_Button_Down));
143       if (!e) return;
144
145       e->window = window;
146       e->button = button;
147       e->x = LOWORD(msg->data_param);
148       e->y = HIWORD(msg->data_param);
149       e->time = (double)msg->time / 1000.0;
150
151       if (((e->time - _ecore_wince_mouse_down_last_time) <= _ecore_wince_double_click_time) &&
152           (e->window == _ecore_wince_mouse_down_last_window))
153         e->double_click = 1;
154
155       if (((e->time - _ecore_wince_mouse_down_last_last_time) <= (2.0 * _ecore_wince_double_click_time)) &&
156           (e->window == _ecore_wince_mouse_down_last_window) &&
157           (e->window == _ecore_wince_mouse_down_last_last_window))
158         {
159            e->triple_click = 1;
160            _ecore_wince_mouse_down_did_triple = 1;
161         }
162       else
163         _ecore_wince_mouse_down_did_triple = 0;
164
165       if (!e->double_click && !e->triple_click)
166         _ecore_wince_mouse_up_count = 0;
167
168       _ecore_wince_event_last_time = e->time;
169       _ecore_wince_event_last_window = e->window;
170
171       if (!_ecore_wince_mouse_down_did_triple)
172         {
173            _ecore_wince_mouse_down_last_last_window = _ecore_wince_mouse_down_last_window;
174            _ecore_wince_mouse_down_last_window = e->window;
175            _ecore_wince_mouse_down_last_last_time = _ecore_wince_mouse_down_last_time;
176            _ecore_wince_mouse_down_last_time = e->time;
177         }
178
179       ecore_event_add(ECORE_WINCE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
180    }
181    printf (" * ecore event button press\n");
182 }
183
184 void
185 _ecore_wince_event_handle_button_release(Ecore_WinCE_Callback_Data *msg,
186                                          int                          button)
187 {
188    Ecore_WinCE_Window *window;
189
190    window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
191
192    {
193       Ecore_WinCE_Event_Mouse_Move *e;
194
195       e = (Ecore_WinCE_Event_Mouse_Move *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_Move));
196       if (!e) return;
197
198       e->window = window;
199       e->x = LOWORD(msg->data_param);
200       e->y = HIWORD(msg->data_param);
201       e->time = (double)msg->time / 1000.0;
202
203       _ecore_wince_event_last_time = e->time;
204       _ecore_wince_event_last_window = e->window;
205
206       ecore_event_add(ECORE_WINCE_EVENT_MOUSE_MOVE, e, NULL, NULL);
207    }
208
209    {
210       Ecore_WinCE_Event_Mouse_Button_Up *e;
211
212       e = (Ecore_WinCE_Event_Mouse_Button_Up *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_Button_Up));
213       if (!e) return;
214
215       e->window = window;
216       e->button = button;
217       e->x = LOWORD(msg->data_param);
218       e->y = HIWORD(msg->data_param);
219       e->time = (double)msg->time / 1000.0;
220
221       _ecore_wince_mouse_up_count++;
222
223       if ((_ecore_wince_mouse_up_count >= 2) &&
224           ((e->time - _ecore_wince_mouse_down_last_time) <= _ecore_wince_double_click_time) &&
225           (e->window == _ecore_wince_mouse_down_last_window))
226         e->double_click = 1;
227
228       if ((_ecore_wince_mouse_up_count >= 3) &&
229           ((e->time - _ecore_wince_mouse_down_last_last_time) <= (2.0 * _ecore_wince_double_click_time)) &&
230           (e->window == _ecore_wince_mouse_down_last_window) &&
231           (e->window == _ecore_wince_mouse_down_last_last_window))
232         e->triple_click = 1;
233
234       _ecore_wince_event_last_time = e->time;
235       _ecore_wince_event_last_window = e->window;
236
237       ecore_event_add(ECORE_WINCE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
238    }
239
240    printf (" * ecore event button release\n");
241 }
242
243 void
244 _ecore_wince_event_handle_motion_notify(Ecore_WinCE_Callback_Data *msg)
245 {
246    Ecore_WinCE_Event_Mouse_Move *e;
247
248    e = (Ecore_WinCE_Event_Mouse_Move *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_Move));
249    if (!e) return;
250
251    e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
252    e->x = LOWORD(msg->data_param);
253    e->y = HIWORD(msg->data_param);
254    e->time = (double)msg->time / 1000.0;
255
256    ecore_event_add(ECORE_WINCE_EVENT_MOUSE_MOVE, e, NULL, NULL);
257    printf (" * ecore event motion notify\n");
258 }
259
260 void
261 _ecore_wince_event_handle_enter_notify(Ecore_WinCE_Callback_Data *msg)
262 {
263    Ecore_WinCE_Window *window;
264
265    window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
266    printf (" * ecore event enter notify 0\n");
267
268    {
269       Ecore_WinCE_Event_Mouse_Move *e;
270
271       e = (Ecore_WinCE_Event_Mouse_Move *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_Move));
272       if (!e) return;
273
274       e->window = window;
275       e->x = msg->x;
276       e->y = msg->y;
277       e->time = (double)msg->time / 1000.0;
278
279       _ecore_wince_event_last_time = e->time;
280       _ecore_wince_event_last_window = e->window;
281
282       ecore_event_add(ECORE_WINCE_EVENT_MOUSE_MOVE, e, NULL, NULL);
283    }
284
285    {
286       Ecore_WinCE_Event_Mouse_In *e;
287
288       e = (Ecore_WinCE_Event_Mouse_In *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_In));
289       if (!e) return;
290
291       e->window = window;
292       e->x = msg->x;
293       e->y = msg->y;
294       e->time = (double)msg->time / 1000.0;
295
296       _ecore_wince_event_last_time = e->time;
297
298       ecore_event_add(ECORE_WINCE_EVENT_MOUSE_IN, e, NULL, NULL);
299    }
300    printf (" * ecore event enter notify 1\n");
301 }
302
303 void
304 _ecore_wince_event_handle_leave_notify(Ecore_WinCE_Callback_Data *msg)
305 {
306    Ecore_WinCE_Window *window;
307
308    window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
309
310    {
311       Ecore_WinCE_Event_Mouse_Move *e;
312
313       e = (Ecore_WinCE_Event_Mouse_Move *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_Move));
314       if (!e) return;
315
316       e->window = window;
317       e->x = msg->x;
318       e->y = msg->y;
319       e->time = (double)msg->time / 1000.0;
320
321       _ecore_wince_event_last_time = e->time;
322       _ecore_wince_event_last_window = e->window;
323
324       ecore_event_add(ECORE_WINCE_EVENT_MOUSE_MOVE, e, NULL, NULL);
325    }
326
327    {
328       Ecore_WinCE_Event_Mouse_Out *e;
329
330       e = (Ecore_WinCE_Event_Mouse_Out *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_Out));
331       if (!e) return;
332
333       e->window = window;
334       e->x = msg->x;
335       e->y = msg->y;
336       e->time = (double)msg->time / 1000.0;
337
338       _ecore_wince_event_last_time = e->time;
339
340       ecore_event_add(ECORE_WINCE_EVENT_MOUSE_OUT, e, NULL, NULL);
341    }
342    printf (" * ecore event leave notify\n");
343 }
344
345 void
346 _ecore_wince_event_handle_focus_in(Ecore_WinCE_Callback_Data *msg)
347 {
348    Ecore_WinCE_Event_Window_Focus_In *e;
349    struct _Ecore_WinCE_Window        *window;
350
351    e = (Ecore_WinCE_Event_Window_Focus_In *)calloc(1, sizeof(Ecore_WinCE_Event_Window_Focus_In));
352    if (!e) return;
353
354    window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
355    if (!e->window)
356      {
357         free(e);
358         return;
359      }
360
361    if (window->resume)
362      window->resume(window->backend);
363
364    e->window = window;
365
366    e->time = _ecore_wince_event_last_time;
367    _ecore_wince_event_last_time = e->time;
368
369    ecore_event_add(ECORE_WINCE_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
370 }
371
372 void
373 _ecore_wince_event_handle_focus_out(Ecore_WinCE_Callback_Data *msg)
374 {
375    Ecore_WinCE_Event_Window_Focus_Out *e;
376    struct _Ecore_WinCE_Window         *window;
377
378    e = (Ecore_WinCE_Event_Window_Focus_Out *)calloc(1, sizeof(Ecore_WinCE_Event_Window_Focus_Out));
379    if (!e) return;
380
381    window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
382    if (!e->window)
383      {
384         free(e);
385         return;
386      }
387    if (window->suspend)
388      window->suspend(window->backend);
389
390    e->window = window;
391
392    e->time = _ecore_wince_event_last_time;
393    _ecore_wince_event_last_time = e->time;
394
395    ecore_event_add(ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
396 }
397
398 void
399 _ecore_wince_event_handle_expose(Ecore_WinCE_Callback_Data *msg)
400 {
401    Ecore_WinCE_Event_Window_Damage *e;
402
403    e = (Ecore_WinCE_Event_Window_Damage *)calloc(1, sizeof(Ecore_WinCE_Event_Window_Damage));
404    if (!e) return;
405
406    e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
407    if (!e->window)
408      {
409         free(e);
410         return;
411      }
412
413    e->x = msg->update.left;
414    e->y = msg->update.top;
415    e->width = msg->update.right - msg->update.left;
416    e->height = msg->update.bottom - msg->update.top;
417    printf (" * ecore : event expose %d %d\n", e->width, e->height);
418
419    e->time = _ecore_wince_event_last_time;
420
421    ecore_event_add(ECORE_WINCE_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
422 }
423
424 void
425 _ecore_wince_event_handle_create_notify(Ecore_WinCE_Callback_Data *msg)
426 {
427    Ecore_WinCE_Event_Window_Create *e;
428
429    e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Create));
430    if (!e) return;
431
432    e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
433    if (!e->window)
434      {
435         free(e);
436         return;
437      }
438
439    e->time = _ecore_wince_event_last_time;
440
441    ecore_event_add(ECORE_WINCE_EVENT_WINDOW_CREATE, e, NULL, NULL);
442 }
443
444 void
445 _ecore_wince_event_handle_destroy_notify(Ecore_WinCE_Callback_Data *msg)
446 {
447    Ecore_WinCE_Event_Window_Destroy *e;
448
449    e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Destroy));
450    if (!e) return;
451
452    e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
453    if (!e->window)
454      {
455         free(e);
456         return;
457      }
458
459    e->time = _ecore_wince_event_last_time;
460 /*    if (e->window == _ecore_wince_event_last_window) _ecore_wince_event_last_window = NULL; */
461
462    ecore_event_add(ECORE_WINCE_EVENT_WINDOW_DESTROY, e, NULL, NULL);
463 }
464
465 void
466 _ecore_wince_event_handle_map_notify(Ecore_WinCE_Callback_Data *msg)
467 {
468    Ecore_WinCE_Event_Window_Show *e;
469
470    e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Show));
471    if (!e) return;
472
473    e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
474    if (!e->window)
475      {
476         free(e);
477         return;
478      }
479
480    e->time = _ecore_wince_event_last_time;
481
482    ecore_event_add(ECORE_WINCE_EVENT_WINDOW_SHOW, e, NULL, NULL);
483 }
484
485 void
486 _ecore_wince_event_handle_unmap_notify(Ecore_WinCE_Callback_Data *msg)
487 {
488    Ecore_WinCE_Event_Window_Hide *e;
489
490    e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Hide));
491    if (!e) return;
492
493    e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
494    if (!e->window)
495      {
496         free(e);
497         return;
498      }
499
500    e->time = _ecore_wince_event_last_time;
501
502    ecore_event_add(ECORE_WINCE_EVENT_WINDOW_HIDE, e, NULL, NULL);
503 }
504
505 void
506 _ecore_wince_event_handle_delete_request(Ecore_WinCE_Callback_Data *msg)
507 {
508    Ecore_WinCE_Event_Window_Delete_Request *e;
509
510    e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Delete_Request));
511    if (!e) return;
512
513    e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
514    if (!e->window)
515      {
516         free(e);
517         return;
518      }
519
520    e->time = _ecore_wince_event_last_time;
521
522    ecore_event_add(ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
523 }
524
525
526 /***** Private functions definitions *****/
527
528 static void
529 _ecore_wince_event_free_key_down(void *data,
530                                  void *ev)
531 {
532    Ecore_WinCE_Event_Key_Down *e;
533
534    e = ev;
535    if (e->keyname) free(e->keyname);
536    if (e->keysymbol) free(e->keysymbol);
537    if (e->keycompose) free(e->keycompose);
538    free(e);
539 }
540
541 static void
542 _ecore_wince_event_free_key_up(void *data,
543                                void *ev)
544 {
545    Ecore_WinCE_Event_Key_Up *e;
546
547    e = ev;
548    if (e->keyname) free(e->keyname);
549    if (e->keysymbol) free(e->keysymbol);
550    if (e->keycompose) free(e->keycompose);
551    free(e);
552 }
553
554 static int
555 _ecore_wince_event_keystroke_get(int    key,
556                                  char **keyname,
557                                  char **keysymbol,
558                                  char **keycompose)
559 {
560   char *kn;
561   char *ks;
562   char *kc;
563
564   *keyname = NULL;
565   *keysymbol = NULL;
566   *keycompose = NULL;
567
568    switch (key)
569      {
570        /* Keystroke */
571      case VK_PRIOR:
572        kn = "KP_Prior";
573        ks = "KP_Prior";
574        kc = "";
575        break;
576      case VK_NEXT:
577        kn = "KP_Next";
578        ks = "KP_Next";
579        kc = "";
580        break;
581      case VK_END:
582        kn = "KP_End";
583        ks = "KP_End";
584        kc = "";
585        break;
586      case VK_HOME:
587        kn = "KP_Home";
588        ks = "KP_Home";
589        kc = "";
590        break;
591      case VK_LEFT:
592        kn = "KP_Left";
593        ks = "KP_Left";
594        kc = "";
595        break;
596      case VK_UP:
597        kn = "KP_Up";
598        ks = "KP_Up";
599        kc = "";
600        break;
601      case VK_RIGHT:
602        kn = "KP_Right";
603        ks = "KP_Right";
604        kc = "";
605        break;
606      case VK_DOWN:
607        kn = "KP_Down";
608        ks = "KP_Down";
609        kc = "";
610        break;
611      case VK_INSERT:
612        kn = "KP_Insert";
613        ks = "KP_Insert";
614        kc = "";
615        break;
616      case VK_DELETE:
617        kn = "KP_Delete";
618        ks = "KP_Delete";
619        kc = "";
620        break;
621      case VK_F1:
622        kn = "F1";
623        ks = "F1";
624        kc = "";
625        break;
626      case VK_F2:
627        kn = "F2";
628        ks = "F2";
629        kc = "";
630        break;
631      case VK_F3:
632        kn = "F3";
633        ks = "F3";
634        kc = "";
635        break;
636      case VK_F4:
637        kn = "F4";
638        ks = "F4";
639        kc = "";
640        break;
641      case VK_F5:
642        kn = "F5";
643        ks = "F5";
644        kc = "";
645        break;
646      case VK_F6:
647        kn = "F6";
648        ks = "F6";
649        kc = "";
650        break;
651      case VK_F7:
652        kn = "F7";
653        ks = "F7";
654        kc = "";
655        break;
656      case VK_F8:
657        kn = "F8";
658        ks = "F8";
659        kc = "";
660        break;
661      case VK_F9:
662        kn = "F9";
663        ks = "F9";
664        kc = "";
665        break;
666      case VK_F10:
667        kn = "F10";
668        ks = "F10";
669        kc = "";
670        break;
671      case VK_F11:
672        kn = "F11";
673        ks = "F11";
674        kc = "";
675        break;
676      case VK_F12:
677        kn = "F12";
678        ks = "F12";
679        kc = "";
680        break;
681      case VK_F13:
682        kn = "F13";
683        ks = "F13";
684        kc = "";
685        break;
686      case VK_F14:
687        kn = "F14";
688        ks = "F14";
689        kc = "";
690        break;
691      case VK_F15:
692        kn = "F15";
693        ks = "F15";
694        kc = "";
695        break;
696      case VK_F16:
697        kn = "F16";
698        ks = "F16";
699        kc = "";
700        break;
701      case VK_F17:
702        kn = "F17";
703        ks = "F17";
704        kc = "";
705        break;
706      case VK_F18:
707        kn = "F18";
708        ks = "F18";
709        kc = "";
710        break;
711      case VK_F19:
712        kn = "F19";
713        ks = "F19";
714        kc = "";
715        break;
716      case VK_F20:
717        kn = "F20";
718        ks = "F20";
719        kc = "";
720        break;
721      case VK_F21:
722        kn = "F21";
723        ks = "F21";
724        kc = "";
725        break;
726      case VK_F22:
727        kn = "F22";
728        ks = "F22";
729        kc = "";
730        break;
731      case VK_F23:
732        kn = "F23";
733        ks = "F23";
734        kc = "";
735        break;
736      case VK_F24:
737        kn = "F24";
738        ks = "F24";
739        kc = "";
740        break;
741      default:
742        /* other non keystroke characters */
743        return 0;
744      }
745    *keyname = strdup(kn);
746    if (!*keyname) return 0;
747    *keysymbol = strdup(ks);
748    if (!*keysymbol)
749      {
750         free(*keyname);
751         *keyname = NULL;
752         return 0;
753      }
754    *keycompose = strdup(kc);
755    if (!*keycompose)
756      {
757         free(*keyname);
758         free(*keysymbol);
759         *keyname = NULL;
760         *keysymbol = NULL;
761         return 0;
762      }
763
764    return 1;
765 }
766
767 static int
768 _ecore_wince_event_char_get(int    key,
769                             char **keyname,
770                             char **keysymbol,
771                             char **keycompose)
772 {
773   char kn[32];
774   char ks[32];
775   char *kc;
776
777   *keyname = NULL;
778   *keysymbol = NULL;
779   *keycompose = NULL;
780
781    switch (key)
782      {
783      case VK_APP3:
784      case VK_BACK:
785        strncpy(kn, "Backspace", 32);
786        strncpy(ks, "Backspace", 32);
787        kc = "";
788        break;
789      case VK_APP4:
790      case VK_TAB:
791        strncpy(kn, "Tab", 32);
792        strncpy(ks, "Tab", 32);
793        kc = "";
794        break;
795      case VK_APP5:
796      case 0x0a:
797        /* Line feed (Shift + Enter) */
798        strncpy(kn, "LineFeed", 32);
799        strncpy(ks, "LineFeed", 32);
800        kc = "";
801        break;
802      case VK_APP2:
803      case VK_RETURN:
804        strncpy(kn, "Return", 32);
805        strncpy(ks, "Return", 32);
806        kc = "";
807        break;
808      case VK_APP1:
809      case VK_ESCAPE:
810        strncpy(kn, "Escape", 32);
811        strncpy(ks, "Escape", 32);
812        kc = "";
813        break;
814      default:
815        /* displayable characters */
816        printf (" * key : %d\n", key);
817        kn[0] = (TCHAR)key;
818        kn[1] = '\0';
819        ks[0] = (TCHAR)key;
820        ks[1] = '\0';
821        kc = "";
822        break;
823      }
824    *keyname = strdup(kn);
825    if (!*keyname) return 0;
826    *keysymbol = strdup(ks);
827    if (!*keysymbol)
828      {
829         free(*keyname);
830         *keyname = NULL;
831         return 0;
832      }
833    *keycompose = strdup(kc);
834    if (!*keycompose)
835      {
836         free(*keyname);
837         free(*keysymbol);
838         *keyname = NULL;
839         *keysymbol = NULL;
840         return 0;
841      }
842
843    return 1;
844 }