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