a9945fb0631d76d221e6470036ecdde2617e0402
[framework/uifw/ecore.git] / src / lib / ecore_evas / ecore_evas_extn.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <stdlib.h>
6 #include <unistd.h>
7
8 #include <Ecore.h>
9 #include "ecore_private.h"
10 #include <Ecore_Input.h>
11
12 #ifdef BUILD_ECORE_IPC
13 # ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
14 #  define EXTN_ENABLED 1
15 # endif
16 #endif
17
18 #include "ecore_evas_private.h"
19 #include "Ecore_Evas.h"
20 #ifdef EXTN_ENABLED
21 #include "Ecore_Ipc.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <math.h>
28 #include <netinet/in.h>
29 #include <time.h>
30 #include <sys/mman.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <sys/file.h>
35
36 typedef struct _Shmfile Shmfile;
37
38 struct _Shmfile
39 {
40    int fd;
41    int size;
42    void *addr;
43    const char *file;
44 };
45
46 static int blank = 0x00000000;
47
48 static Shmfile *
49 shmfile_new(const char *base, int id, int size, Eina_Bool sys)
50 {
51    Shmfile *sf;
52    char file[PATH_MAX];
53
54    sf = calloc(1, sizeof(Shmfile));
55    do
56      {
57         mode_t mode;
58
59         snprintf(file, sizeof(file), "/%s-%i-%i.%i.%i",
60                  base, id, (int)time(NULL), (int)getpid(), (int)rand());
61         mode = S_IRUSR | S_IWUSR;
62         if (sys) mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
63         sf->fd = shm_open(file, O_RDWR | O_CREAT | O_EXCL, mode);
64      }
65    while (sf->fd < 0);
66
67    sf->file = eina_stringshare_add(file);
68    if (!sf->file)
69      {
70         close(sf->fd);
71         shm_unlink(sf->file);
72         eina_stringshare_del(sf->file);
73         free(sf);
74         return NULL;
75      }
76    sf->size = size;
77    if (ftruncate(sf->fd, size) < 0)
78      {
79         close(sf->fd);
80         shm_unlink(sf->file);
81         eina_stringshare_del(sf->file);
82         free(sf);
83         return NULL;
84      }
85    sf->addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd, 0);
86    if (sf->addr == MAP_FAILED)
87      {
88         close(sf->fd);
89         shm_unlink(sf->file);
90         eina_stringshare_del(sf->file);
91         free(sf);
92         return NULL;
93      }
94    return sf;
95 }
96
97 void
98 shmfile_free(Shmfile *sf)
99 {
100    munmap(sf->addr, sf->size);
101    close(sf->fd);
102    shm_unlink(sf->file);
103    eina_stringshare_del(sf->file);
104    free(sf);
105 }
106
107 static Shmfile *
108 shmfile_open(const char *ref, int size, Eina_Bool sys)
109 {
110    Shmfile *sf;
111    mode_t mode;
112
113    sf = calloc(1, sizeof(Shmfile));
114    mode = S_IRUSR | S_IWUSR;
115    if (sys) mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
116    sf->fd = shm_open(ref, O_RDWR, mode);
117    if (sf->fd < 0)
118      {
119         free(sf);
120         return NULL;
121      }
122    sf->file = eina_stringshare_add(ref);
123    if (!sf->file)
124      {
125         close(sf->fd);
126         eina_stringshare_del(sf->file);
127         free(sf);
128         return NULL;
129      }
130    sf->size = size;
131    sf->addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd, 0);
132    if (sf->addr == MAP_FAILED)
133      {
134         close(sf->fd);
135         eina_stringshare_del(sf->file);
136         free(sf);
137         return NULL;
138      }
139    return sf;
140 }
141
142 void
143 shmfile_close(Shmfile *sf)
144 {
145    munmap(sf->addr, sf->size);
146    close(sf->fd);
147    eina_stringshare_del(sf->file);
148    free(sf);
149 }
150
151 // procotol version - change this as needed
152 #define MAJOR 0x1011
153
154 enum // opcodes
155 {
156    OP_RESIZE,
157    OP_SHOW,
158    OP_HIDE,
159    OP_FOCUS,
160    OP_UNFOCUS,
161    OP_UPDATE,
162    OP_UPDATE_DONE,
163    OP_LOCK_FILE,
164    OP_SHM_REF,
165    OP_EV_MOUSE_IN,
166    OP_EV_MOUSE_OUT,
167    OP_EV_MOUSE_UP,
168    OP_EV_MOUSE_DOWN,
169    OP_EV_MOUSE_MOVE,
170    OP_EV_MOUSE_WHEEL,
171    OP_EV_MULTI_UP,
172    OP_EV_MULTI_DOWN,
173    OP_EV_MULTI_MOVE,
174    OP_EV_KEY_UP,
175    OP_EV_KEY_DOWN,
176    OP_EV_HOLD
177 };
178
179 enum
180 {
181    MOD_SHIFT  = (1 << 0),
182    MOD_CTRL   = (1 << 1),
183    MOD_ALT    = (1 << 2),
184    MOD_META   = (1 << 3),
185    MOD_HYPER  = (1 << 4),
186    MOD_SUPER  = (1 << 5),
187    MOD_CAPS   = (1 << 6),
188    MOD_NUM    = (1 << 7),
189    MOD_SCROLL = (1 << 8),
190 };
191
192 typedef struct _Ipc_Data_Resize Ipc_Data_Resize;
193 typedef struct _Ipc_Data_Update Ipc_Data_Update;
194 typedef struct _Ipc_Data_Ev_Mouse_In Ipc_Data_Ev_Mouse_In;
195 typedef struct _Ipc_Data_Ev_Mouse_Out Ipc_Data_Ev_Mouse_Out;
196 typedef struct _Ipc_Data_Ev_Mouse_Up Ipc_Data_Ev_Mouse_Up;
197 typedef struct _Ipc_Data_Ev_Mouse_Down Ipc_Data_Ev_Mouse_Down;
198 typedef struct _Ipc_Data_Ev_Mouse_Move Ipc_Data_Ev_Mouse_Move;
199 typedef struct _Ipc_Data_Ev_Mouse_Wheel Ipc_Data_Ev_Mouse_Wheel;
200 typedef struct _Ipc_Data_Ev_Hold Ipc_Data_Ev_Hold;
201 typedef struct _Ipc_Data_Ev_Multi_Up Ipc_Data_Ev_Multi_Up;
202 typedef struct _Ipc_Data_Ev_Multi_Down Ipc_Data_Ev_Multi_Down;
203 typedef struct _Ipc_Data_Ev_Multi_Move Ipc_Data_Ev_Multi_Move;
204 typedef struct _Ipc_Data_Ev_Key_Up Ipc_Data_Ev_Key_Up;
205 typedef struct _Ipc_Data_Ev_Key_Down Ipc_Data_Ev_Key_Down;
206
207 struct _Ipc_Data_Resize
208 {
209    int w, h;
210 };
211
212 struct _Ipc_Data_Update
213 {
214    int x, w, y, h;
215 };
216
217 struct _Ipc_Data_Ev_Mouse_In
218 {
219    unsigned int timestamp;
220    int mask;
221    Evas_Event_Flags event_flags;
222 };
223
224 struct _Ipc_Data_Ev_Mouse_Out
225 {
226    unsigned int timestamp;
227    int mask;
228    Evas_Event_Flags event_flags;
229 };
230
231 struct _Ipc_Data_Ev_Mouse_Up
232 {
233    int b;
234    Evas_Button_Flags flags;
235    int mask;
236    unsigned int timestamp;
237    Evas_Event_Flags event_flags;
238 };
239
240 struct _Ipc_Data_Ev_Mouse_Down
241 {
242    int b;
243    Evas_Button_Flags flags;
244    int mask;
245    unsigned int timestamp;
246    Evas_Event_Flags event_flags;
247 };
248
249 struct _Ipc_Data_Ev_Mouse_Move
250 {
251    int x, y;
252    Evas_Button_Flags flags;
253    int mask;
254    unsigned int timestamp;
255    Evas_Event_Flags event_flags;
256 };
257
258 struct _Ipc_Data_Ev_Mouse_Wheel
259 {
260    int direction, z;
261    Evas_Button_Flags flags;
262    int mask;
263    unsigned int timestamp;
264    Evas_Event_Flags event_flags;
265 };
266
267 struct _Ipc_Data_Ev_Hold
268 {
269    int hold;
270    unsigned int timestamp;
271    Evas_Event_Flags event_flags;
272 };
273
274 struct _Ipc_Data_Ev_Multi_Up
275 {
276    Evas_Button_Flags flags;
277    int d, x, y;
278    double rad, radx, rady, pres, ang, fx, fy;
279    int mask;
280    unsigned int timestamp;
281    Evas_Event_Flags event_flags;
282 };
283
284 struct _Ipc_Data_Ev_Multi_Down
285 {
286    Evas_Button_Flags flags;
287    int d, x, y;
288    double rad, radx, rady, pres, ang, fx, fy;
289    int mask;
290    unsigned int timestamp;
291    Evas_Event_Flags event_flags;
292 };
293
294 struct _Ipc_Data_Ev_Multi_Move
295 {
296    int d, x, y;
297    double rad, radx, rady, pres, ang, fx, fy;
298    int mask;
299    unsigned int timestamp;
300    Evas_Event_Flags event_flags;
301 };
302
303 struct _Ipc_Data_Ev_Key_Up
304 {
305    const char *keyname, *key, *string, *compose;
306    int mask;
307    unsigned int timestamp;
308    Evas_Event_Flags event_flags;
309 };
310
311 struct _Ipc_Data_Ev_Key_Down
312 {
313    const char *keyname, *key, *string, *compose;
314    int mask;
315    unsigned int timestamp;
316    Evas_Event_Flags event_flags;
317 };
318
319 typedef struct _Extn Extn;
320
321 struct _Extn
322 {
323    struct {
324         Ecore_Ipc_Server *server;
325         Eina_List *clients;
326         Eina_List *handlers;
327         Eina_Bool am_server : 1;
328    } ipc;
329    struct {
330         const char *name;
331         int         num;
332         Eina_Bool   sys : 1;
333    } svc;
334    struct {
335         const char *lock;
336         int         lockfd;
337         const char *shm;
338         int         w, h;
339         Shmfile    *shmfile;
340         Eina_List  *updates;
341         Eina_Bool   have_lock : 1;
342    } file;
343 };
344
345 static Eina_List *extn_ee_list = NULL;
346
347 EAPI int ECORE_EVAS_EXTN_CLIENT_ADD = 0;
348 EAPI int ECORE_EVAS_EXTN_CLIENT_DEL = 0;
349
350 void
351 _ecore_evas_extn_init(void)
352 {
353    if (ECORE_EVAS_EXTN_CLIENT_ADD) return;
354    ECORE_EVAS_EXTN_CLIENT_ADD = ecore_event_type_new();
355    ECORE_EVAS_EXTN_CLIENT_DEL = ecore_event_type_new();
356 }
357
358 void
359 _ecore_evas_extn_shutdown(void)
360 {
361 }
362
363 static void
364 _ecore_evas_extn_event_free(void *data, void *ev __UNUSED__)
365 {
366    Ecore_Evas *ee = data;
367    if (ee->engine.buffer.image)
368      evas_object_unref(ee->engine.buffer.image);
369    _ecore_evas_unref(ee);
370 }
371
372 static void
373 _ecore_evas_extn_event(Ecore_Evas *ee, int event)
374 {
375    _ecore_evas_ref(ee);
376    if (ee->engine.buffer.image)
377      evas_object_ref(ee->engine.buffer.image);
378    ecore_event_add(event, ee->engine.buffer.image,
379                    _ecore_evas_extn_event_free, ee);
380 }
381
382 static void
383 _ecore_evas_socket_lock(Ecore_Evas *ee)
384 {
385    Extn *extn;
386
387    extn = ee->engine.buffer.data;
388    if (!extn) return;
389    if (extn->file.lockfd < 0) return;
390    if (extn->file.have_lock) return;
391    flock(extn->file.lockfd, LOCK_EX);
392    extn->file.have_lock = EINA_TRUE;
393 }
394
395 static void
396 _ecore_evas_socket_unlock(Ecore_Evas *ee)
397 {
398    Extn *extn;
399
400    extn = ee->engine.buffer.data;
401    if (!extn) return;
402    if (extn->file.lockfd < 0) return;
403    if (!extn->file.have_lock) return;
404    flock(extn->file.lockfd, LOCK_UN);
405    extn->file.have_lock = EINA_FALSE;
406 }
407
408 static void
409 _ecore_evas_extn_plug_targer_render_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
410 {
411    Ecore_Evas *ee = data;
412    if (ee) _ecore_evas_socket_lock(ee);
413 }
414
415 static void
416 _ecore_evas_extn_plug_targer_render_post(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
417 {
418    Ecore_Evas *ee = data;
419    if (ee) _ecore_evas_socket_unlock(ee);
420 }
421
422 static void
423 _ecore_evas_extn_plug_image_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
424 {
425    Ecore_Evas *ee = data;
426    if (ee) ecore_evas_free(ee);
427 }
428
429 static void
430 _ecore_evas_extn_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
431 {
432    Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh;
433
434    evas_object_geometry_get(ee->engine.buffer.image, &xx, &yy, &ww, &hh);
435    evas_object_image_fill_get(ee->engine.buffer.image, &fx, &fy, &fw, &fh);
436
437    if (fw < 1) fw = 1;
438    if (fh < 1) fh = 1;
439
440    if (evas_object_map_get(ee->engine.buffer.image) &&
441        evas_object_map_enable_get(ee->engine.buffer.image))
442      {
443         fx = 0; fy = 0;
444         fw = ee->w; fh = ee->h;
445         ww = ee->w; hh = ee->h;
446      }
447
448    if ((fx == 0) && (fy == 0) && (fw == ww) && (fh == hh))
449      {
450         *x = (ee->w * (*x - xx)) / fw;
451         *y = (ee->h * (*y - yy)) / fh;
452      }
453    else
454      {
455         xx = (*x - xx) - fx;
456         while (xx < 0) xx += fw;
457         while (xx > fw) xx -= fw;
458         *x = (ee->w * xx) / fw;
459
460         yy = (*y - yy) - fy;
461         while (yy < 0) yy += fh;
462         while (yy > fh) yy -= fh;
463         *y = (ee->h * yy) / fh;
464      }
465 }
466
467 static void
468 _ecore_evas_extn_free(Ecore_Evas *ee)
469 {
470    Extn *extn;
471    Ecore_Ipc_Client *client;
472
473    extn = ee->engine.buffer.data;
474    if (extn)
475      {
476         Ecore_Event_Handler *hdl;
477
478         if (extn->file.have_lock)
479           _ecore_evas_socket_unlock(ee);
480         if (extn->file.lockfd)
481           {
482              close(extn->file.lockfd);
483              if (extn->ipc.am_server)
484                {
485                   if (extn->file.lock) unlink(extn->file.lock);
486                }
487           }
488         if (extn->svc.name) eina_stringshare_del(extn->svc.name);
489         if (extn->ipc.clients)
490           {
491              EINA_LIST_FREE(extn->ipc.clients, client)
492                ecore_ipc_client_del(client);
493           }
494         if (extn->ipc.server) ecore_ipc_server_del(extn->ipc.server);
495         if (extn->file.lock) eina_stringshare_del(extn->file.lock);
496         if (extn->file.shm) eina_stringshare_del(extn->file.shm);
497         if (extn->file.shmfile)
498           {
499              if (extn->ipc.am_server)
500                shmfile_free(extn->file.shmfile);
501              else
502                shmfile_close(extn->file.shmfile);
503           }
504
505         EINA_LIST_FREE(extn->ipc.handlers, hdl)
506           ecore_event_handler_del(hdl);
507         free(extn);
508         ecore_ipc_shutdown();
509         ee->engine.buffer.data = NULL;
510      }
511    if (ee->engine.buffer.image)
512      {
513         Ecore_Evas *ee2;
514
515         evas_object_event_callback_del_full(ee->engine.buffer.image,
516                                             EVAS_CALLBACK_DEL,
517                                             _ecore_evas_extn_plug_image_obj_del,
518                                             ee);
519         evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image),
520                                      EVAS_CALLBACK_RENDER_PRE,
521                                      _ecore_evas_extn_plug_targer_render_pre,
522                                      ee);
523         evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image),
524                                      EVAS_CALLBACK_RENDER_POST,
525                                      _ecore_evas_extn_plug_targer_render_post,
526                                      ee);
527         evas_object_del(ee->engine.buffer.image);
528         ee2 = evas_object_data_get(ee->engine.buffer.image, "Ecore_Evas_Parent");
529         if (ee2)
530           {
531              ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee);
532           }
533      }
534    extn_ee_list = eina_list_remove(extn_ee_list, ee);
535 }
536
537 static void
538 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
539 {
540    Extn *extn;
541
542    if (w < 1) w = 1;
543    if (h < 1) h = 1;
544    ee->req.w = w;
545    ee->req.h = h;
546    if ((w == ee->w) && (h == ee->h)) return;
547    ee->w = w;
548    ee->h = h;
549
550    extn = ee->engine.buffer.data;
551    if (ee->engine.buffer.image)
552      evas_object_image_size_set(ee->engine.buffer.image, ee->w, ee->h);
553    /* Server can have many plugs, so I block resize comand from client to server *
554       if ((extn) && (extn->ipc.server))
555       {
556       Ipc_Data_Resize ipc;
557
558       ipc.w = ee->w;
559       ipc.h = ee->h;
560       ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_RESIZE, 0, 0, 0, &ipc, sizeof(ipc));
561       }*/
562    if (ee->func.fn_resize) ee->func.fn_resize(ee);
563 }
564
565 static void
566 _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
567 {
568    _ecore_evas_resize(ee, w, h);
569 }
570
571 static int
572 _ecore_evas_modifiers_locks_mask_get(Evas *e)
573 {
574    int mask = 0;
575
576    if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift"))
577      mask |= MOD_SHIFT;
578    if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control"))
579      mask |= MOD_CTRL;
580    if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt"))
581      mask |= MOD_ALT;
582    if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta"))
583      mask |= MOD_META;
584    if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper"))
585      mask |= MOD_HYPER;
586    if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super"))
587      mask |= MOD_SUPER;
588    if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock"))
589      mask |= MOD_SCROLL;
590    if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock"))
591      mask |= MOD_NUM;
592    if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock"))
593      mask |= MOD_CAPS;
594    return mask;
595 }
596
597 static void
598 _ecore_evas_modifiers_locks_mask_set(Evas *e, int mask)
599 {
600    if (mask & MOD_SHIFT) evas_key_modifier_on (e, "Shift");
601    else                  evas_key_modifier_off(e, "Shift");
602    if (mask & MOD_CTRL)  evas_key_modifier_on (e, "Control");
603    else                  evas_key_modifier_off(e, "Control");
604    if (mask & MOD_ALT)   evas_key_modifier_on (e, "Alt");
605    else                  evas_key_modifier_off(e, "Alt");
606    if (mask & MOD_META)  evas_key_modifier_on (e, "Meta");
607    else                  evas_key_modifier_off(e, "Meta");
608    if (mask & MOD_HYPER) evas_key_modifier_on (e, "Hyper");
609    else                  evas_key_modifier_off(e, "Hyper");
610    if (mask & MOD_SUPER) evas_key_modifier_on (e, "Super");
611    else                  evas_key_modifier_off(e, "Super");
612    if (mask & MOD_SCROLL) evas_key_lock_on (e, "Scroll_Lock");
613    else                   evas_key_lock_off(e, "Scroll_Lock");
614    if (mask & MOD_NUM)    evas_key_lock_on (e, "Num_Lock");
615    else                   evas_key_lock_off(e, "Num_Lock");
616    if (mask & MOD_CAPS)   evas_key_lock_on (e, "Caps_Lock");
617    else                   evas_key_lock_off(e, "Caps_Lock");
618 }
619
620 static void
621 _ecore_evas_extn_cb_mouse_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
622 {
623    Ecore_Evas *ee = data;
624    Evas_Event_Mouse_In *ev = event_info;
625    Extn *extn;
626
627    extn = ee->engine.buffer.data;
628    if (!extn) return;
629    if (extn->ipc.server)
630      {
631         Ipc_Data_Ev_Mouse_In ipc;
632
633         ipc.timestamp = ev->timestamp;
634         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
635         ipc.event_flags = ev->event_flags;
636         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_IN, 0, 0, 0, &ipc, sizeof(ipc));
637      }
638 }
639
640 static void
641 _ecore_evas_extn_cb_mouse_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
642 {
643    Ecore_Evas *ee = data;
644    Evas_Event_Mouse_Out *ev = event_info;
645    Extn *extn;
646
647    extn = ee->engine.buffer.data;
648    if (!extn) return;
649    if (extn->ipc.server)
650      {
651         Ipc_Data_Ev_Mouse_Out ipc;
652
653         ipc.timestamp = ev->timestamp;
654         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
655         ipc.event_flags = ev->event_flags;
656         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_OUT, 0, 0, 0, &ipc, sizeof(ipc));
657      }
658 }
659
660 static void
661 _ecore_evas_extn_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
662 {
663    Ecore_Evas *ee = data;
664    Evas_Event_Mouse_Down *ev = event_info;
665    Extn *extn;
666
667    extn = ee->engine.buffer.data;
668    if (!extn) return;
669    if (extn->ipc.server)
670      {
671         Ipc_Data_Ev_Mouse_Down ipc;
672
673         ipc.b = ev->button;
674         ipc.flags = ev->flags;
675         ipc.timestamp = ev->timestamp;
676         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
677         ipc.event_flags = ev->event_flags;
678         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_DOWN, 0, 0, 0, &ipc, sizeof(ipc));
679      }
680 }
681
682 static void
683 _ecore_evas_extn_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
684 {
685    Ecore_Evas *ee = data;
686    Evas_Event_Mouse_Up *ev = event_info;
687    Extn *extn;
688
689    extn = ee->engine.buffer.data;
690    if (!extn) return;
691    if (extn->ipc.server)
692      {
693         Ipc_Data_Ev_Mouse_Up ipc;
694
695         ipc.b = ev->button;
696         ipc.flags = ev->flags;
697         ipc.timestamp = ev->timestamp;
698         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
699         ipc.event_flags = ev->event_flags;
700         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_UP, 0, 0, 0, &ipc, sizeof(ipc));
701      }
702 }
703
704 static void
705 _ecore_evas_extn_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
706 {
707    Ecore_Evas *ee = data;
708    Evas_Event_Mouse_Move *ev = event_info;
709    Extn *extn;
710
711    extn = ee->engine.buffer.data;
712    if (!extn) return;
713    if (extn->ipc.server)
714      {
715         Ipc_Data_Ev_Mouse_Move ipc;
716         Evas_Coord x, y;
717
718         x = ev->cur.canvas.x;
719         y = ev->cur.canvas.y;
720         _ecore_evas_extn_coord_translate(ee, &x, &y);
721         ipc.x = x;
722         ipc.y = y;
723         ipc.timestamp = ev->timestamp;
724         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
725         ipc.event_flags = ev->event_flags;
726         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_MOVE, 0, 0, 0, &ipc, sizeof(ipc));
727      }
728 }
729
730 static void
731 _ecore_evas_extn_cb_mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
732 {
733    Ecore_Evas *ee = data;
734    Evas_Event_Mouse_Wheel *ev = event_info;
735    Extn *extn;
736
737    extn = ee->engine.buffer.data;
738    if (!extn) return;
739    if (extn->ipc.server)
740      {
741         Ipc_Data_Ev_Mouse_Wheel ipc;
742
743         ipc.direction = ev->direction;
744         ipc.z = ev->z;
745         ipc.timestamp = ev->timestamp;
746         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
747         ipc.event_flags = ev->event_flags;
748         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_WHEEL, 0, 0, 0, &ipc, sizeof(ipc));
749      }
750 }
751
752 static void
753 _ecore_evas_extn_cb_multi_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
754 {
755    Ecore_Evas *ee = data;
756    Evas_Event_Multi_Down *ev = event_info;
757    Extn *extn;
758
759    extn = ee->engine.buffer.data;
760    if (!extn) return;
761    if (extn->ipc.server)
762      {
763         Ipc_Data_Ev_Multi_Down ipc;
764         Evas_Coord x, y;
765
766         ipc.d = ev->device;
767         x = ev->canvas.x;
768         y = ev->canvas.y;
769         _ecore_evas_extn_coord_translate(ee, &x, &y);
770         ipc.x = x;
771         ipc.y = y;
772         ipc.rad = ev->radius;
773         ipc.radx = ev->radius_x;
774         ipc.rady = ev->radius_y;
775         ipc.pres = ev->pressure;
776         ipc.ang = ev->angle;
777         ipc.fx = ev->canvas.xsub;
778         ipc.fy = ev->canvas.ysub;
779         ipc.flags = ev->flags;
780         ipc.timestamp = ev->timestamp;
781         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
782         ipc.event_flags = ev->event_flags;
783         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_DOWN, 0, 0, 0, &ipc, sizeof(ipc));
784      }
785 }
786
787
788 static void
789 _ecore_evas_extn_cb_multi_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
790 {
791    Ecore_Evas *ee = data;
792    Evas_Event_Multi_Up *ev = event_info;
793    Extn *extn;
794
795    extn = ee->engine.buffer.data;
796    if (!extn) return;
797    if (extn->ipc.server)
798      {
799         Ipc_Data_Ev_Multi_Up ipc;
800         Evas_Coord x, y;
801
802         ipc.d = ev->device;
803         x = ev->canvas.x;
804         y = ev->canvas.y;
805         _ecore_evas_extn_coord_translate(ee, &x, &y);
806         ipc.x = x;
807         ipc.y = y;
808         ipc.rad = ev->radius;
809         ipc.radx = ev->radius_x;
810         ipc.rady = ev->radius_y;
811         ipc.pres = ev->pressure;
812         ipc.ang = ev->angle;
813         ipc.fx = ev->canvas.xsub;
814         ipc.fy = ev->canvas.ysub;
815         ipc.flags = ev->flags;
816         ipc.timestamp = ev->timestamp;
817         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
818         ipc.event_flags = ev->event_flags;
819         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_UP, 0, 0, 0, &ipc, sizeof(ipc));
820      }
821 }
822
823 static void
824 _ecore_evas_extn_cb_multi_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
825 {
826    Ecore_Evas *ee = data;
827    Evas_Event_Multi_Move *ev = event_info;
828    Extn *extn;
829
830    extn = ee->engine.buffer.data;
831    if (!extn) return;
832    if (extn->ipc.server)
833      {
834         Ipc_Data_Ev_Multi_Move ipc;
835         Evas_Coord x, y;
836
837         ipc.d = ev->device;
838         x = ev->cur.canvas.x;
839         y = ev->cur.canvas.y;
840         _ecore_evas_extn_coord_translate(ee, &x, &y);
841         ipc.x = x;
842         ipc.y = y;
843         ipc.rad = ev->radius;
844         ipc.radx = ev->radius_x;
845         ipc.rady = ev->radius_y;
846         ipc.pres = ev->pressure;
847         ipc.ang = ev->angle;
848         ipc.fx = ev->cur.canvas.xsub;
849         ipc.fy = ev->cur.canvas.ysub;
850         ipc.timestamp = ev->timestamp;
851         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
852         ipc.event_flags = ev->event_flags;
853         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_MOVE, 0, 0, 0, &ipc, sizeof(ipc));
854      }
855 }
856
857 static void
858 _ecore_evas_extn_cb_free(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
859 {
860    Ecore_Evas *ee;
861
862    ee = data;
863    if (ee->driver) _ecore_evas_free(ee);
864 }
865
866 static void
867 _ecore_evas_extn_cb_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
868 {
869    Ecore_Evas *ee = data;
870    Evas_Event_Key_Down *ev = event_info;
871    Extn *extn;
872
873    extn = ee->engine.buffer.data;
874    if (!extn) return;
875    if (extn->ipc.server)
876      {
877         Ipc_Data_Ev_Key_Down *ipc;
878         char *st, *p;
879         int len = 0;
880
881         len = sizeof(Ipc_Data_Ev_Key_Down);
882         if (ev->key) len += strlen(ev->key) + 1;
883         if (ev->keyname) len += strlen(ev->keyname) + 1;
884         if (ev->string) len += strlen(ev->string) + 1;
885         if (ev->compose) len += strlen(ev->compose) + 1;
886         len += 1;
887         st = alloca(len);
888         ipc = (Ipc_Data_Ev_Key_Down *)st;
889         memset(st, 0, len);
890         p = st + sizeof(Ipc_Data_Ev_Key_Down);
891         if (ev->key)
892           {
893              strcpy(p, ev->key);
894              ipc->key = p - (long)st;
895              p += strlen(p) + 1;
896           }
897         if (ev->keyname)
898           {
899              strcpy(p, ev->keyname);
900              ipc->keyname = p - (long)st;
901              p += strlen(p) + 1;
902           }
903         if (ev->string)
904           {
905              strcpy(p, ev->string);
906              ipc->string = p - (long)st;
907              p += strlen(p) + 1;
908           }
909         if (ev->compose)
910           {
911              strcpy(p, ev->compose);
912              ipc->compose = p - (long)st;
913              p += strlen(p) + 1;
914           }
915         ipc->timestamp = ev->timestamp;
916         ipc->mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
917         ipc->event_flags = ev->event_flags;
918         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_KEY_DOWN, 0, 0, 0, ipc, len);
919      }
920 }
921
922 static void
923 _ecore_evas_extn_cb_key_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
924 {
925    Ecore_Evas *ee = data;
926    Evas_Event_Key_Up *ev = event_info;
927    Extn *extn;
928
929    extn = ee->engine.buffer.data;
930    if (!extn) return;
931    if (extn->ipc.server)
932      {
933         Ipc_Data_Ev_Key_Up *ipc;
934         char *st, *p;
935         int len = 0;
936
937         len = sizeof(Ipc_Data_Ev_Key_Up);
938         if (ev->key) len += strlen(ev->key) + 1;
939         if (ev->keyname) len += strlen(ev->keyname) + 1;
940         if (ev->string) len += strlen(ev->string) + 1;
941         if (ev->compose) len += strlen(ev->compose) + 1;
942         len += 1;
943         st = alloca(len);
944         ipc = (Ipc_Data_Ev_Key_Up *)st;
945         memset(st, 0, len);
946         p = st + sizeof(Ipc_Data_Ev_Key_Down);
947         if (ev->key)
948           {
949              strcpy(p, ev->key);
950              ipc->key = p - (long)st;
951              p += strlen(p) + 1;
952           }
953         if (ev->keyname)
954           {
955              strcpy(p, ev->keyname);
956              ipc->keyname = p - (long)st;
957              p += strlen(p) + 1;
958           }
959         if (ev->string)
960           {
961              strcpy(p, ev->string);
962              ipc->string = p - (long)st;
963              p += strlen(p) + 1;
964           }
965         if (ev->compose)
966           {
967              strcpy(p, ev->compose);
968              ipc->compose = p - (long)st;
969              p += strlen(p) + 1;
970           }
971         ipc->timestamp = ev->timestamp;
972         ipc->mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
973         ipc->event_flags = ev->event_flags;
974         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_KEY_UP, 0, 0, 0, ipc, len);
975      }
976 }
977
978 static void
979 _ecore_evas_extn_cb_hold(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
980 {
981    Ecore_Evas *ee = data;
982    Evas_Event_Hold *ev = event_info;
983    Extn *extn;
984
985    extn = ee->engine.buffer.data;
986    if (!extn) return;
987    if (extn->ipc.server)
988      {
989         Ipc_Data_Ev_Hold ipc;
990
991         ipc.hold = ev->hold;
992         ipc.timestamp = ev->timestamp;
993         ipc.event_flags = ev->event_flags;
994         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_HOLD, 0, 0, 0, &ipc, sizeof(ipc));
995      }
996 }
997
998 static void
999 _ecore_evas_extn_cb_focus_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1000 {
1001    Ecore_Evas *ee;
1002    Extn *extn;
1003
1004    ee = data;
1005    ee->prop.focused = 1;
1006    extn = ee->engine.buffer.data;
1007    if (!extn) return;
1008    if (!extn->ipc.server) return;
1009    ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_FOCUS, 0, 0, 0, NULL, 0);
1010 }
1011
1012 static void
1013 _ecore_evas_extn_cb_focus_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1014 {
1015    Ecore_Evas *ee;
1016    Extn *extn;
1017
1018    ee = data;
1019    ee->prop.focused = 0;
1020    extn = ee->engine.buffer.data;
1021    if (!extn) return;
1022    if (!extn->ipc.server) return;
1023    ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_UNFOCUS, 0, 0, 0, NULL, 0);
1024 }
1025
1026 static void
1027 _ecore_evas_extn_cb_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1028 {
1029    Ecore_Evas *ee;
1030    Extn *extn;
1031
1032    ee = data;
1033    ee->visible = 1;
1034    extn = ee->engine.buffer.data;
1035    if (!extn) return;
1036    if (!extn->ipc.server) return;
1037    ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_SHOW, 0, 0, 0, NULL, 0);
1038 }
1039
1040 static void
1041 _ecore_evas_extn_cb_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1042 {
1043    Ecore_Evas *ee;
1044    Extn *extn;
1045
1046    ee = data;
1047    ee->visible = 0;
1048    extn = ee->engine.buffer.data;
1049    if (!extn) return;
1050    if (!extn->ipc.server) return;
1051    ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_HIDE, 0, 0, 0, NULL, 0);
1052 }
1053
1054 static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func =
1055 {
1056    _ecore_evas_extn_free,
1057    NULL,
1058    NULL,
1059    NULL,
1060    NULL,
1061    NULL,
1062    NULL,
1063    NULL,
1064    NULL,
1065    NULL,
1066    NULL,
1067    NULL,
1068    NULL,
1069    NULL,
1070    NULL,
1071    NULL,
1072    NULL,
1073    _ecore_evas_resize,
1074    _ecore_evas_move_resize,
1075    NULL,
1076    NULL,
1077    NULL,
1078    NULL,
1079    NULL,
1080    NULL,
1081    NULL,
1082    NULL,
1083    NULL,
1084    NULL,
1085    NULL,
1086    NULL,
1087    NULL,
1088    NULL,
1089    NULL,
1090    NULL,
1091    NULL,
1092    NULL,
1093    NULL,
1094    NULL,
1095    NULL,
1096    NULL,
1097    NULL,
1098    NULL,
1099    NULL,
1100    NULL,
1101    NULL, //transparent
1102
1103    NULL, // render
1104    NULL  // screen_geometry_get
1105 };
1106
1107 static Eina_Bool
1108 _ipc_server_add(void *data, int type __UNUSED__, void *event)
1109 {
1110    Ecore_Ipc_Event_Server_Add *e = event;
1111    Ecore_Evas *ee = data;
1112    Extn *extn;
1113
1114    if (ee != ecore_ipc_server_data_get(e->server))
1115      return ECORE_CALLBACK_PASS_ON;
1116    if (!eina_list_data_find(extn_ee_list, ee))
1117      return ECORE_CALLBACK_PASS_ON;
1118    extn = ee->engine.buffer.data;
1119    if (!extn) return ECORE_CALLBACK_PASS_ON;
1120    //FIXME: find a way to let app know server there
1121    return ECORE_CALLBACK_PASS_ON;
1122 }
1123
1124 static Eina_Bool
1125 _ipc_server_del(void *data, int type __UNUSED__, void *event)
1126 {
1127    Ecore_Ipc_Event_Server_Del *e = event;
1128    Ecore_Evas *ee = data;
1129    Extn *extn;
1130
1131    extn = ee->engine.buffer.data;
1132    if (!extn) return ECORE_CALLBACK_PASS_ON;
1133    if (extn->ipc.server != e->server) return ECORE_CALLBACK_PASS_ON;
1134    evas_object_image_data_set(ee->engine.buffer.image, NULL);
1135    ee->engine.buffer.pixels = NULL;
1136    if (extn->file.shmfile)
1137      {
1138         shmfile_close(extn->file.shmfile);
1139         extn->file.shmfile = NULL;
1140      }
1141    if (extn->file.shm)
1142      {
1143         eina_stringshare_del(extn->file.shm);
1144         extn->file.shm = NULL;
1145      }
1146    extn->ipc.server = NULL;
1147    if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
1148    return ECORE_CALLBACK_PASS_ON;
1149 }
1150
1151 static Eina_Bool
1152 _ipc_server_data(void *data, int type __UNUSED__, void *event)
1153 {
1154    Ecore_Ipc_Event_Server_Data *e = event;
1155    Ecore_Evas *ee = data;
1156    Extn *extn;
1157
1158    if (ee != ecore_ipc_server_data_get(e->server))
1159      return ECORE_CALLBACK_PASS_ON;
1160    if (!eina_list_data_find(extn_ee_list, ee))
1161      return ECORE_CALLBACK_PASS_ON;
1162    extn = ee->engine.buffer.data;
1163    if (!extn) return ECORE_CALLBACK_PASS_ON;
1164    if (e->major != MAJOR)
1165      return ECORE_CALLBACK_PASS_ON;
1166    switch (e->minor)
1167      {
1168       case OP_UPDATE:
1169          // add rect to update list
1170          if (e->size >= (int)sizeof(Ipc_Data_Update))
1171            {
1172               Ipc_Data_Update *ipc = malloc(sizeof(Ipc_Data_Update));
1173               if (ipc)
1174                 {
1175                    memcpy(ipc, e->data, sizeof(Ipc_Data_Update));
1176                    extn->file.updates = eina_list_append(extn->file.updates, ipc);
1177                 }
1178            }
1179          break;
1180       case OP_UPDATE_DONE:
1181          // updates finished being sent - done now. frame ready
1182            {
1183               Ipc_Data_Update *ipc;
1184
1185               EINA_LIST_FREE(extn->file.updates, ipc)
1186                 {
1187                    if (ee->engine.buffer.image)
1188                      evas_object_image_data_update_add(ee->engine.buffer.image,
1189                                                        ipc->x, ipc->y,
1190                                                        ipc->w, ipc->h);
1191                 }
1192            }
1193          break;
1194       case OP_LOCK_FILE:
1195          if ((e->data) && (e->size > 0) &&
1196              (((unsigned char *)e->data)[e->size - 1] == 0))
1197            {
1198               if (extn->file.lockfd) close(extn->file.lockfd);
1199               if (extn->file.lock) eina_stringshare_del(extn->file.lock);
1200               extn->file.lock = eina_stringshare_add(e->data);
1201               extn->file.lockfd = open(extn->file.lock, O_RDONLY);
1202            }
1203          break;
1204       case OP_SHM_REF:
1205          // e->ref == w
1206          // e->ref_to == h
1207          // e->response == alpha
1208          // e->data = shm ref string + nul byte
1209          if ((e->data) && ((unsigned char *)e->data)[e->size - 1] == 0)
1210            {
1211               ee->engine.buffer.pixels = NULL;
1212               if (extn->file.shmfile)
1213                 {
1214                    shmfile_close(extn->file.shmfile);
1215                    extn->file.shmfile = NULL;
1216                 }
1217               if (extn->file.shm)
1218                 {
1219                    eina_stringshare_del(extn->file.shm);
1220                    extn->file.shm = NULL;
1221                 }
1222               if ((e->ref > 0) && (e->ref_to > 0))
1223                 {
1224                    extn->file.w = e->ref;
1225                    extn->file.h = e->ref_to;
1226                    extn->file.shm = eina_stringshare_add(e->data);
1227                    extn->file.shmfile = shmfile_open(extn->file.shm,
1228                                                      extn->file.w *
1229                                                      extn->file.h * 4,
1230                                                      EINA_TRUE);
1231                    if (extn->file.shmfile)
1232                      {
1233                         ee->engine.buffer.pixels = extn->file.shmfile->addr;
1234                         if (ee->engine.buffer.image)
1235                           {
1236                              if (e->response)
1237                                evas_object_image_alpha_set(ee->engine.buffer.image,
1238                                                            EINA_TRUE);
1239                              else
1240                                evas_object_image_alpha_set(ee->engine.buffer.image,
1241                                                            EINA_FALSE);
1242                              evas_object_image_size_set(ee->engine.buffer.image,
1243                                                         extn->file.w,
1244                                                         extn->file.h);
1245                              evas_object_image_data_set(ee->engine.buffer.image,
1246                                                         ee->engine.buffer.pixels);
1247                              evas_object_image_data_update_add(ee->engine.buffer.image,
1248                                                                0, 0,
1249                                                                extn->file.w,
1250                                                                extn->file.h);
1251                              _ecore_evas_resize(ee,
1252                                                 extn->file.w,
1253                                                 extn->file.h);
1254                           }
1255                         else
1256                           evas_object_image_data_set(ee->engine.buffer.image, NULL);
1257                      }
1258                    else
1259                      evas_object_image_data_set(ee->engine.buffer.image, NULL);
1260                 }
1261               else
1262                 evas_object_image_data_set(ee->engine.buffer.image, NULL);
1263            }
1264          break;
1265       case OP_RESIZE:
1266          if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize)))
1267            {
1268               Ipc_Data_Resize *ipc = e->data;
1269               _ecore_evas_resize(ee, ipc->w, ipc->h);
1270            }
1271          break;
1272       default:
1273          break;
1274      }
1275    return ECORE_CALLBACK_PASS_ON;
1276 }
1277 #else
1278 void
1279 _ecore_evas_extn_init(void)
1280 {
1281 }
1282
1283 void
1284 _ecore_evas_extn_shutdown(void)
1285 {
1286 }
1287 #endif
1288
1289 EAPI Evas_Object *
1290 ecore_evas_extn_plug_new(Ecore_Evas *ee_target, const char *svcname, int svcnum, Eina_Bool svcsys)
1291 {
1292 #ifdef EXTN_ENABLED
1293    Extn *extn;
1294    Evas_Object *o;
1295    Ecore_Evas *ee;
1296    int w = 1, h = 1;
1297
1298    ee = calloc(1, sizeof(Ecore_Evas));
1299    if (!ee) return NULL;
1300
1301    o = evas_object_image_filled_add(ee_target->evas);
1302    evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
1303    evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
1304    evas_object_image_alpha_set(o, 1);
1305    evas_object_image_size_set(o, 1, 1);
1306    evas_object_image_data_set(o, &blank);
1307
1308    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
1309
1310    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_plug_engine_func;
1311
1312    ee->driver = "extn_plug";
1313
1314    ee->rotation = 0;
1315    ee->visible = 0;
1316    ee->w = w;
1317    ee->h = h;
1318    ee->req.w = ee->w;
1319    ee->req.h = ee->h;
1320
1321    ee->prop.max.w = 0;
1322    ee->prop.max.h = 0;
1323    ee->prop.layer = 0;
1324    ee->prop.focused = 0;
1325    ee->prop.borderless = 1;
1326    ee->prop.override = 1;
1327    ee->prop.maximized = 0;
1328    ee->prop.fullscreen = 0;
1329    ee->prop.withdrawn = 0;
1330    ee->prop.sticky = 0;
1331
1332    ee->engine.buffer.image = o;
1333    evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas", ee);
1334    evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas_Parent", ee_target);
1335    evas_object_event_callback_add(ee->engine.buffer.image,
1336                                   EVAS_CALLBACK_MOUSE_IN,
1337                                   _ecore_evas_extn_cb_mouse_in, ee);
1338    evas_object_event_callback_add(ee->engine.buffer.image,
1339                                   EVAS_CALLBACK_MOUSE_OUT,
1340                                   _ecore_evas_extn_cb_mouse_out, ee);
1341    evas_object_event_callback_add(ee->engine.buffer.image,
1342                                   EVAS_CALLBACK_MOUSE_DOWN,
1343                                   _ecore_evas_extn_cb_mouse_down, ee);
1344    evas_object_event_callback_add(ee->engine.buffer.image,
1345                                   EVAS_CALLBACK_MOUSE_UP,
1346                                   _ecore_evas_extn_cb_mouse_up, ee);
1347    evas_object_event_callback_add(ee->engine.buffer.image,
1348                                   EVAS_CALLBACK_MOUSE_MOVE,
1349                                   _ecore_evas_extn_cb_mouse_move, ee);
1350    evas_object_event_callback_add(ee->engine.buffer.image,
1351                                   EVAS_CALLBACK_MOUSE_WHEEL,
1352                                   _ecore_evas_extn_cb_mouse_wheel, ee);
1353    evas_object_event_callback_add(ee->engine.buffer.image,
1354                                   EVAS_CALLBACK_MULTI_DOWN,
1355                                   _ecore_evas_extn_cb_multi_down, ee);
1356    evas_object_event_callback_add(ee->engine.buffer.image,
1357                                   EVAS_CALLBACK_MULTI_UP,
1358                                   _ecore_evas_extn_cb_multi_up, ee);
1359    evas_object_event_callback_add(ee->engine.buffer.image,
1360                                   EVAS_CALLBACK_MULTI_MOVE,
1361                                   _ecore_evas_extn_cb_multi_move, ee);
1362    evas_object_event_callback_add(ee->engine.buffer.image,
1363                                   EVAS_CALLBACK_FREE,
1364                                   _ecore_evas_extn_cb_free, ee);
1365    evas_object_event_callback_add(ee->engine.buffer.image,
1366                                   EVAS_CALLBACK_KEY_DOWN,
1367                                   _ecore_evas_extn_cb_key_down, ee);
1368    evas_object_event_callback_add(ee->engine.buffer.image,
1369                                   EVAS_CALLBACK_KEY_UP,
1370                                   _ecore_evas_extn_cb_key_up, ee);
1371    evas_object_event_callback_add(ee->engine.buffer.image,
1372                                   EVAS_CALLBACK_HOLD,
1373                                   _ecore_evas_extn_cb_hold, ee);
1374    evas_object_event_callback_add(ee->engine.buffer.image,
1375                                   EVAS_CALLBACK_FOCUS_IN,
1376                                   _ecore_evas_extn_cb_focus_in, ee);
1377    evas_object_event_callback_add(ee->engine.buffer.image,
1378                                   EVAS_CALLBACK_FOCUS_OUT,
1379                                   _ecore_evas_extn_cb_focus_out, ee);
1380    evas_object_event_callback_add(ee->engine.buffer.image,
1381                                   EVAS_CALLBACK_SHOW,
1382                                   _ecore_evas_extn_cb_show, ee);
1383    evas_object_event_callback_add(ee->engine.buffer.image,
1384                                   EVAS_CALLBACK_HIDE,
1385                                   _ecore_evas_extn_cb_hide, ee);
1386
1387    evas_object_event_callback_add(ee->engine.buffer.image,
1388                                   EVAS_CALLBACK_DEL,
1389                                   _ecore_evas_extn_plug_image_obj_del, ee);
1390
1391    extn = calloc(1, sizeof(Extn));
1392    if (!extn)
1393      {
1394         ecore_evas_free(ee);
1395         return NULL;
1396      }
1397    else
1398      {
1399         Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER;
1400
1401         ecore_ipc_init();
1402         extn->svc.name = eina_stringshare_add(svcname);
1403         extn->svc.num = svcnum;
1404         extn->svc.sys = svcsys;
1405
1406         if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM;
1407         extn->ipc.server = ecore_ipc_server_connect(ipctype, (char *)extn->svc.name,
1408                                                     extn->svc.num, ee);
1409         if (!extn->ipc.server)
1410           {
1411              eina_stringshare_del(extn->svc.name);
1412              free(extn);
1413              ecore_ipc_shutdown();
1414              ecore_evas_free(ee);
1415              return NULL;
1416           }
1417         ee->engine.buffer.data = extn;
1418         extn->ipc.handlers = eina_list_append
1419            (extn->ipc.handlers,
1420             ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD,
1421                                     _ipc_server_add, ee));
1422         extn->ipc.handlers = eina_list_append
1423            (extn->ipc.handlers,
1424             ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL,
1425                                     _ipc_server_del, ee));
1426         extn->ipc.handlers = eina_list_append
1427            (extn->ipc.handlers,
1428             ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA,
1429                                     _ipc_server_data, ee));
1430      }
1431
1432    extn_ee_list = eina_list_append(extn_ee_list, ee);
1433    ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas, ee);
1434
1435    evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_PRE,
1436                            _ecore_evas_extn_plug_targer_render_pre, ee);
1437    evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_POST,
1438                            _ecore_evas_extn_plug_targer_render_post, ee);
1439    return o;
1440 #else
1441    return NULL;
1442 #endif
1443 }
1444
1445 EAPI void
1446 ecore_evas_extn_plug_object_data_lock(Evas_Object *obj)
1447 {
1448 #ifdef EXTN_ENABLED
1449    Ecore_Evas *ee;
1450
1451    ee = ecore_evas_object_ecore_evas_get(obj);
1452    if (!ee) return;
1453    _ecore_evas_socket_lock(ee);
1454 #endif
1455 }
1456
1457 EAPI void
1458 ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj)
1459 {
1460 #ifdef EXTN_ENABLED
1461    Ecore_Evas *ee;
1462
1463    ee = ecore_evas_object_ecore_evas_get(obj);
1464    if (!ee) return;
1465    _ecore_evas_socket_unlock(ee);
1466 #endif
1467 }
1468
1469 #ifdef EXTN_ENABLED
1470 static void
1471 _ecore_evas_socket_resize(Ecore_Evas *ee, int w, int h)
1472 {
1473    Extn *extn;
1474    Evas_Engine_Info_Buffer *einfo;
1475    int stride = 0;
1476
1477    if (w < 1) w = 1;
1478    if (h < 1) h = 1;
1479    ee->req.w = w;
1480    ee->req.h = h;
1481    if ((w == ee->w) && (h == ee->h)) return;
1482    ee->w = w;
1483    ee->h = h;
1484    evas_output_size_set(ee->evas, ee->w, ee->h);
1485    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1486    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1487    extn = ee->engine.buffer.data;
1488    if (extn)
1489      {
1490         if (extn->file.shmfile)
1491           shmfile_free(extn->file.shmfile);
1492         ee->engine.buffer.pixels = NULL;
1493         extn->file.shmfile = shmfile_new(extn->svc.name, extn->svc.num,
1494                                          ee->w * ee->h * 4, extn->svc.sys);
1495         if (extn->file.shmfile)
1496           ee->engine.buffer.pixels = extn->file.shmfile->addr;
1497
1498         stride = ee->w * 4;
1499         einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
1500         if (einfo)
1501           {
1502              if (ee->alpha)
1503                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
1504              else
1505                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
1506              einfo->info.dest_buffer = ee->engine.buffer.pixels;
1507              einfo->info.dest_buffer_row_bytes = stride;
1508              einfo->info.use_color_key = 0;
1509              einfo->info.alpha_threshold = 0;
1510              einfo->info.func.new_update_region = NULL;
1511              einfo->info.func.free_update_region = NULL;
1512              if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1513                {
1514                   ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1515                }
1516           }
1517
1518         if (extn->ipc.clients && extn->file.shmfile)
1519           {
1520              Ipc_Data_Resize ipc;
1521              Eina_List *l;
1522              Ecore_Ipc_Client *client;
1523
1524              EINA_LIST_FOREACH(extn->ipc.clients, l, client)
1525                 ecore_ipc_client_send(client, MAJOR, OP_SHM_REF,
1526                                       ee->w, ee->h, ee->alpha,
1527                                       extn->file.shmfile->file,
1528                                       strlen(extn->file.shmfile->file) + 1);
1529              ipc.w = ee->w;
1530              ipc.h = ee->h;
1531              EINA_LIST_FOREACH(extn->ipc.clients, l, client)
1532                 ecore_ipc_client_send(client, MAJOR, OP_RESIZE,
1533                                       0, 0, 0, &ipc, sizeof(ipc));
1534           }
1535      }
1536    if (ee->func.fn_resize) ee->func.fn_resize(ee);
1537 }
1538
1539 static void
1540 _ecore_evas_socket_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
1541 {
1542    _ecore_evas_socket_resize(ee, w, h);
1543 }
1544
1545 int
1546 _ecore_evas_extn_socket_render(Ecore_Evas *ee)
1547 {
1548    Eina_List *updates = NULL, *l, *ll;
1549    Ecore_Evas *ee2;
1550    int rend = 0;
1551    Eina_Rectangle *r;
1552    Extn *extn;
1553    Ecore_Ipc_Client *client;
1554
1555    extn = ee->engine.buffer.data;
1556    EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
1557      {
1558         if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
1559         if (ee2->engine.func->fn_render)
1560           rend |= ee2->engine.func->fn_render(ee2);
1561         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
1562      }
1563    if (ee->engine.buffer.pixels)
1564      {
1565         _ecore_evas_socket_lock(ee);
1566         updates = evas_render_updates(ee->evas);
1567         _ecore_evas_socket_unlock(ee);
1568      }
1569    EINA_LIST_FOREACH(updates, l, r)
1570      {
1571         Ipc_Data_Update ipc;
1572
1573
1574         ipc.x = r->x;
1575         ipc.y = r->y;
1576         ipc.w = r->w;
1577         ipc.h = r->h;
1578         EINA_LIST_FOREACH(extn->ipc.clients, ll, client)
1579            ecore_ipc_client_send(client, MAJOR, OP_UPDATE, 0, 0, 0, &ipc, sizeof(ipc));
1580      }
1581    if (updates)
1582      {
1583         evas_render_updates_free(updates);
1584         _ecore_evas_idle_timeout_update(ee);
1585         EINA_LIST_FOREACH(extn->ipc.clients, ll, client)
1586            ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, 0, NULL, 0);
1587      }
1588
1589    return updates ? 1 : rend;
1590 }
1591
1592 static Eina_Bool
1593 _ipc_client_add(void *data, int type __UNUSED__, void *event)
1594 {
1595    Ecore_Ipc_Event_Client_Add *e = event;
1596    Ecore_Evas *ee = data;
1597    Extn *extn;
1598
1599    if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client)))
1600      return ECORE_CALLBACK_PASS_ON;
1601    if (!eina_list_data_find(extn_ee_list, ee))
1602      return ECORE_CALLBACK_PASS_ON;
1603    extn = ee->engine.buffer.data;
1604    if (!extn) return ECORE_CALLBACK_PASS_ON;
1605
1606    extn->ipc.clients = eina_list_append(extn->ipc.clients, e->client);
1607    ecore_ipc_client_send(e->client, MAJOR, OP_LOCK_FILE, 0, 0, 0, extn->file.lock, strlen(extn->file.lock) + 1);
1608
1609    if (extn->file.shmfile)
1610      {
1611         Ipc_Data_Resize ipc;
1612
1613         ecore_ipc_client_send(e->client, MAJOR, OP_SHM_REF,
1614                               ee->w, ee->h, ee->alpha,
1615                               extn->file.shmfile->file,
1616                               strlen(extn->file.shmfile->file) + 1);
1617         ipc.w = ee->w;
1618         ipc.h = ee->h;
1619
1620         ecore_ipc_client_send(e->client, MAJOR, OP_RESIZE,
1621                               0, 0, 0, &ipc, sizeof(ipc));
1622      }
1623    _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_ADD);
1624    return ECORE_CALLBACK_PASS_ON;
1625 }
1626
1627 static Eina_Bool
1628 _ipc_client_del(void *data, int type __UNUSED__, void *event)
1629 {
1630    Ecore_Ipc_Event_Client_Del *e = event;
1631    Ecore_Evas *ee = data;
1632    Extn *extn;
1633    extn = ee->engine.buffer.data;
1634    if (!extn) return ECORE_CALLBACK_PASS_ON;
1635    if (!eina_list_data_find(extn->ipc.clients, e->client)) return ECORE_CALLBACK_PASS_ON;
1636
1637    extn->ipc.clients = eina_list_remove(extn->ipc.clients, e->client);
1638
1639    _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_DEL);
1640    return ECORE_CALLBACK_PASS_ON;
1641 }
1642
1643 static Eina_Bool
1644 _ipc_client_data(void *data, int type __UNUSED__, void *event)
1645 {
1646    Ecore_Ipc_Event_Client_Data *e = event;
1647    Ecore_Evas *ee = data;
1648    Extn *extn;
1649
1650    if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client)))
1651      return ECORE_CALLBACK_PASS_ON;
1652    if (!eina_list_data_find(extn_ee_list, ee))
1653      return ECORE_CALLBACK_PASS_ON;
1654    extn = ee->engine.buffer.data;
1655    if (!extn) return ECORE_CALLBACK_PASS_ON;
1656    if (e->major != MAJOR)
1657      return ECORE_CALLBACK_PASS_ON;
1658    switch (e->minor)
1659      {
1660       case OP_RESIZE:
1661          if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize)))
1662            {
1663
1664               Ipc_Data_Resize *ipc = e->data;
1665               /* create callbacke data size changed */
1666               _ecore_evas_socket_resize(ee, ipc->w, ipc->h);
1667            }
1668          break;
1669       case OP_SHOW:
1670          if (!ee->visible)
1671            {
1672               ee->visible = 1;
1673               if (ee->func.fn_show) ee->func.fn_show(ee);
1674            }
1675          break;
1676       case OP_HIDE:
1677          if (ee->visible)
1678            {
1679               ee->visible = 0;
1680               if (ee->func.fn_hide) ee->func.fn_hide(ee);
1681            }
1682          break;
1683       case OP_FOCUS:
1684          if (!ee->prop.focused)
1685            {
1686               ee->prop.focused = 1;
1687               evas_focus_in(ee->evas);
1688               if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
1689            }
1690          break;
1691       case OP_UNFOCUS:
1692          if (ee->prop.focused)
1693            {
1694               ee->prop.focused = 0;
1695               evas_focus_out(ee->evas);
1696               if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
1697            }
1698          break;
1699       case OP_EV_MOUSE_IN:
1700          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_In))
1701            {
1702               Ipc_Data_Ev_Mouse_In *ipc = e->data;
1703               Evas_Event_Flags flags;
1704
1705               flags = evas_event_default_flags_get(ee->evas);
1706               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1707               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1708               evas_event_feed_mouse_in(ee->evas, ipc->timestamp, NULL);
1709               evas_event_default_flags_set(ee->evas, flags);
1710            }
1711          break;
1712       case OP_EV_MOUSE_OUT:
1713          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Out))
1714            {
1715               Ipc_Data_Ev_Mouse_Out *ipc = e->data;
1716               Evas_Event_Flags flags;
1717
1718               flags = evas_event_default_flags_get(ee->evas);
1719               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1720               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1721               evas_event_feed_mouse_out(ee->evas, ipc->timestamp, NULL);
1722               evas_event_default_flags_set(ee->evas, flags);
1723            }
1724          break;
1725       case OP_EV_MOUSE_UP:
1726          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Up))
1727            {
1728               Ipc_Data_Ev_Mouse_Up *ipc = e->data;
1729               Evas_Event_Flags flags;
1730
1731               flags = evas_event_default_flags_get(ee->evas);
1732               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1733               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1734               evas_event_feed_mouse_up(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL);
1735               evas_event_default_flags_set(ee->evas, flags);
1736            }
1737          break;
1738       case OP_EV_MOUSE_DOWN:
1739          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Down))
1740            {
1741               Ipc_Data_Ev_Mouse_Up *ipc = e->data;
1742               Evas_Event_Flags flags;
1743
1744               flags = evas_event_default_flags_get(ee->evas);
1745               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1746               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1747               evas_event_feed_mouse_down(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL);
1748               evas_event_default_flags_set(ee->evas, flags);
1749            }
1750          break;
1751       case OP_EV_MOUSE_MOVE:
1752          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Move))
1753            {
1754               Ipc_Data_Ev_Mouse_Move *ipc = e->data;
1755               Evas_Event_Flags flags;
1756
1757               flags = evas_event_default_flags_get(ee->evas);
1758               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1759               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1760               evas_event_feed_mouse_move(ee->evas, ipc->x, ipc->y, ipc->timestamp, NULL);
1761               evas_event_default_flags_set(ee->evas, flags);
1762            }
1763          break;
1764       case OP_EV_MOUSE_WHEEL:
1765          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Wheel))
1766            {
1767               Ipc_Data_Ev_Mouse_Wheel *ipc = e->data;
1768               Evas_Event_Flags flags;
1769
1770               flags = evas_event_default_flags_get(ee->evas);
1771               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1772               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1773               evas_event_feed_mouse_wheel(ee->evas, ipc->direction, ipc->z, ipc->timestamp, NULL);
1774               evas_event_default_flags_set(ee->evas, flags);
1775            }
1776          break;
1777       case OP_EV_MULTI_UP:
1778          if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Up))
1779            {
1780               Ipc_Data_Ev_Multi_Up *ipc = e->data;
1781               Evas_Event_Flags flags;
1782
1783               flags = evas_event_default_flags_get(ee->evas);
1784               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1785               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1786               evas_event_feed_multi_up(ee->evas, ipc->d, ipc->x, ipc->y, ipc->rad, ipc->radx, ipc->rady, ipc->pres, ipc->ang, ipc->fx, ipc->fy, ipc->flags, ipc->timestamp, NULL);
1787               evas_event_default_flags_set(ee->evas, flags);
1788            }
1789          break;
1790       case OP_EV_MULTI_DOWN:
1791          if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Down))
1792            {
1793               Ipc_Data_Ev_Multi_Down *ipc = e->data;
1794               Evas_Event_Flags flags;
1795
1796               flags = evas_event_default_flags_get(ee->evas);
1797               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1798               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1799               evas_event_feed_multi_down(ee->evas, ipc->d, ipc->x, ipc->y, ipc->rad, ipc->radx, ipc->rady, ipc->pres, ipc->ang, ipc->fx, ipc->fy, ipc->flags, ipc->timestamp, NULL);
1800               evas_event_default_flags_set(ee->evas, flags);
1801            }
1802          break;
1803       case OP_EV_MULTI_MOVE:
1804          if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Move))
1805            {
1806               Ipc_Data_Ev_Multi_Move *ipc = e->data;
1807               Evas_Event_Flags flags;
1808
1809               flags = evas_event_default_flags_get(ee->evas);
1810               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1811               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1812               evas_event_feed_multi_move(ee->evas, ipc->d, ipc->x, ipc->y, ipc->rad, ipc->radx, ipc->rady, ipc->pres, ipc->ang, ipc->fx, ipc->fy, ipc->timestamp, NULL);
1813               evas_event_default_flags_set(ee->evas, flags);
1814            }
1815          break;
1816
1817 #define STRGET(val) \
1818          do { \
1819               if ((ipc->val) && (ipc->val < (char *)(e->size - 1))) \
1820               ipc->val = ((char *)ipc) + (long)ipc->val; \
1821               else \
1822               ipc->val = NULL; \
1823          } while (0)
1824
1825       case OP_EV_KEY_UP:
1826          if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Up))
1827            {
1828               if ((e->data) && (e->size > 0) &&
1829                   (((unsigned char *)e->data)[e->size - 1] == 0))
1830                 {
1831                    Ipc_Data_Ev_Key_Up *ipc = e->data;
1832                    Evas_Event_Flags flags;
1833
1834                    STRGET(keyname);
1835                    STRGET(key);
1836                    STRGET(string);
1837                    STRGET(compose);
1838                    flags = evas_event_default_flags_get(ee->evas);
1839                    evas_event_default_flags_set(ee->evas, ipc->event_flags);
1840                    _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1841                    evas_event_feed_key_up(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL);
1842                    evas_event_default_flags_set(ee->evas, flags);
1843                 }
1844            }
1845          break;
1846       case OP_EV_KEY_DOWN:
1847          if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Down))
1848            {
1849               if ((e->data) && (e->size > 0) &&
1850                   (((unsigned char *)e->data)[e->size - 1] == 0))
1851                 {
1852                    Ipc_Data_Ev_Key_Down *ipc = e->data;
1853                    Evas_Event_Flags flags;
1854
1855                    STRGET(keyname);
1856                    STRGET(key);
1857                    STRGET(string);
1858                    STRGET(compose);
1859                    flags = evas_event_default_flags_get(ee->evas);
1860                    evas_event_default_flags_set(ee->evas, ipc->event_flags);
1861                    _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1862                    evas_event_feed_key_down(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL);
1863                    evas_event_default_flags_set(ee->evas, flags);
1864                 }
1865            }
1866          break;
1867       case OP_EV_HOLD:
1868          if (e->size >= (int)sizeof(Ipc_Data_Ev_Hold))
1869            {
1870               Ipc_Data_Ev_Hold *ipc = e->data;
1871               Evas_Event_Flags flags;
1872
1873               flags = evas_event_default_flags_get(ee->evas);
1874               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1875               evas_event_feed_hold(ee->evas, ipc->hold, ipc->timestamp, NULL);
1876               evas_event_default_flags_set(ee->evas, flags);
1877            }
1878          break;
1879       default:
1880          break;
1881      }
1882    return ECORE_CALLBACK_PASS_ON;
1883 }
1884
1885 static void
1886 _ecore_evas_extn_socket_alpha_set(Ecore_Evas *ee, int alpha)
1887 {
1888    Extn *extn;
1889    Eina_List *l;
1890    Ecore_Ipc_Client *client;
1891
1892    if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha))) return;
1893    ee->alpha = alpha;
1894
1895    extn = ee->engine.buffer.data;
1896    if (extn)
1897      {
1898         Evas_Engine_Info_Buffer *einfo;
1899
1900         einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
1901         if (einfo)
1902           {
1903              if (ee->alpha)
1904                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
1905              else
1906                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
1907              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
1908              evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1909           }
1910         EINA_LIST_FOREACH(extn->ipc.clients, l, client)
1911            ecore_ipc_client_send(client, MAJOR, OP_SHM_REF,
1912                                  ee->w, ee->h, ee->alpha,
1913                                  extn->file.shmfile->file,
1914                                  strlen(extn->file.shmfile->file) + 1);
1915      }
1916 }
1917
1918 static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func =
1919 {
1920    _ecore_evas_extn_free,
1921    NULL,
1922    NULL,
1923    NULL,
1924    NULL,
1925    NULL,
1926    NULL,
1927    NULL,
1928    NULL,
1929    NULL,
1930    NULL,
1931    NULL,
1932    NULL,
1933    NULL,
1934    NULL,
1935    NULL,
1936    NULL,
1937    _ecore_evas_socket_resize,
1938    _ecore_evas_socket_move_resize,
1939    NULL,
1940    NULL,
1941    NULL,
1942    NULL,
1943    NULL,
1944    NULL,
1945    NULL,
1946    NULL,
1947    NULL,
1948    NULL,
1949    NULL,
1950    NULL,
1951    NULL,
1952    NULL,
1953    NULL,
1954    NULL,
1955    NULL,
1956    NULL,
1957    NULL,
1958    NULL,
1959    NULL,
1960    NULL,
1961    NULL,
1962    NULL,
1963    NULL,
1964    _ecore_evas_extn_socket_alpha_set,
1965    NULL, //transparent
1966
1967    _ecore_evas_extn_socket_render, // render
1968    NULL  // screen_geometry_get
1969 };
1970
1971 #endif
1972
1973 EAPI Ecore_Evas *
1974 ecore_evas_extn_socket_new(const char *svcname, int svcnum, Eina_Bool svcsys)
1975 {
1976 #ifdef EXTN_ENABLED
1977    Extn *extn;
1978    Evas_Engine_Info_Buffer *einfo;
1979    Ecore_Evas *ee;
1980    int rmethod;
1981    int w = 1, h = 1;
1982
1983    rmethod = evas_render_method_lookup("buffer");
1984    if (!rmethod) return NULL;
1985    ee = calloc(1, sizeof(Ecore_Evas));
1986    if (!ee) return NULL;
1987
1988    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
1989
1990    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_socket_engine_func;
1991
1992    ee->driver = "extn_socket";
1993
1994    ee->rotation = 0;
1995    ee->visible = 0;
1996    ee->w = w;
1997    ee->h = h;
1998    ee->req.w = ee->w;
1999    ee->req.h = ee->h;
2000
2001    ee->prop.max.w = 0;
2002    ee->prop.max.h = 0;
2003    ee->prop.layer = 0;
2004    ee->prop.focused = 0;
2005    ee->prop.borderless = 1;
2006    ee->prop.override = 1;
2007    ee->prop.maximized = 0;
2008    ee->prop.fullscreen = 0;
2009    ee->prop.withdrawn = 0;
2010    ee->prop.sticky = 0;
2011
2012    /* init evas here */
2013    ee->evas = evas_new();
2014    evas_data_attach_set(ee->evas, ee);
2015    evas_output_method_set(ee->evas, rmethod);
2016    evas_output_size_set(ee->evas, w, h);
2017    evas_output_viewport_set(ee->evas, 0, 0, w, h);
2018
2019    einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
2020    if (einfo)
2021      {
2022         if (ee->alpha)
2023           einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
2024         else
2025           einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
2026         einfo->info.dest_buffer = NULL;
2027         einfo->info.dest_buffer_row_bytes = 0;
2028         einfo->info.use_color_key = 0;
2029         einfo->info.alpha_threshold = 0;
2030         einfo->info.func.new_update_region = NULL;
2031         einfo->info.func.free_update_region = NULL;
2032         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2033           {
2034              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2035              ecore_evas_free(ee);
2036              return NULL;
2037           }
2038      }
2039    else
2040      {
2041         ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
2042         ecore_evas_free(ee);
2043         return NULL;
2044      }
2045    evas_key_modifier_add(ee->evas, "Shift");
2046    evas_key_modifier_add(ee->evas, "Control");
2047    evas_key_modifier_add(ee->evas, "Alt");
2048    evas_key_modifier_add(ee->evas, "Meta");
2049    evas_key_modifier_add(ee->evas, "Hyper");
2050    evas_key_modifier_add(ee->evas, "Super");
2051    evas_key_lock_add(ee->evas, "Caps_Lock");
2052    evas_key_lock_add(ee->evas, "Num_Lock");
2053    evas_key_lock_add(ee->evas, "Scroll_Lock");
2054
2055    extn = calloc(1, sizeof(Extn));
2056    if (!extn)
2057      {
2058         ecore_evas_free(ee);
2059         return NULL;
2060      }
2061    else
2062      {
2063         Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER;
2064         char buf[PATH_MAX];
2065
2066         ecore_ipc_init();
2067         extn->svc.name = eina_stringshare_add(svcname);
2068         extn->svc.num = svcnum;
2069         extn->svc.sys = svcsys;
2070
2071         snprintf(buf, sizeof(buf), "/tmp/ee-lock-XXXXXX");
2072         extn->file.lockfd = mkstemp(buf);
2073         if (extn->file.lockfd >= 0)
2074           extn->file.lock = eina_stringshare_add(buf);
2075         if ((extn->file.lockfd < 0) || (!extn->file.lock))
2076           {
2077              if (extn->file.lockfd)
2078                {
2079                   close(extn->file.lockfd);
2080                   unlink(buf);
2081                }
2082              eina_stringshare_del(extn->svc.name);
2083              if (extn->file.lock) eina_stringshare_del(extn->file.lock);
2084              free(extn);
2085              ecore_ipc_shutdown();
2086              ecore_evas_free(ee);
2087              return NULL;
2088           }
2089
2090         if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM;
2091         extn->ipc.am_server = EINA_TRUE;
2092         extn->ipc.server = ecore_ipc_server_add(ipctype,
2093                                                 (char *)extn->svc.name,
2094                                                 extn->svc.num, ee);
2095         if (!extn->ipc.server)
2096           {
2097              if (extn->file.lockfd)
2098                {
2099                   close(extn->file.lockfd);
2100                   if (extn->file.lock) unlink(extn->file.lock);
2101                }
2102              eina_stringshare_del(extn->svc.name);
2103              eina_stringshare_del(extn->file.lock);
2104              free(extn);
2105              ecore_ipc_shutdown();
2106              ecore_evas_free(ee);
2107              return NULL;
2108           }
2109         ee->engine.buffer.data = extn;
2110         extn->ipc.handlers = eina_list_append
2111            (extn->ipc.handlers,
2112             ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
2113                                     _ipc_client_add, ee));
2114         extn->ipc.handlers = eina_list_append
2115            (extn->ipc.handlers,
2116             ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
2117                                     _ipc_client_del, ee));
2118         extn->ipc.handlers = eina_list_append
2119            (extn->ipc.handlers,
2120             ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
2121                                     _ipc_client_data, ee));
2122      }
2123
2124    extn_ee_list = eina_list_append(extn_ee_list, ee);
2125
2126    _ecore_evas_register(ee);
2127
2128    return ee;
2129 #else
2130    return NULL;
2131 #endif
2132 }