bec246b5607f232d64cd753b55e0303199a5ef47
[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
1195 static Eina_Bool
1196 _ipc_server_add(void *data, int type __UNUSED__, void *event)
1197 {
1198    Ecore_Ipc_Event_Server_Add *e = event;
1199    Ecore_Evas *ee = data;
1200    Extn *extn;
1201
1202    if (ee != ecore_ipc_server_data_get(e->server))
1203      return ECORE_CALLBACK_PASS_ON;
1204    if (!eina_list_data_find(extn_ee_list, ee))
1205      return ECORE_CALLBACK_PASS_ON;
1206    extn = ee->engine.buffer.data;
1207    if (!extn) return ECORE_CALLBACK_PASS_ON;
1208    //FIXME: find a way to let app know server there
1209    return ECORE_CALLBACK_PASS_ON;
1210 }
1211
1212 static Eina_Bool
1213 _ipc_server_del(void *data, int type __UNUSED__, void *event)
1214 {
1215    Ecore_Ipc_Event_Server_Del *e = event;
1216    Ecore_Evas *ee = data;
1217    Extn *extn;
1218
1219    extn = ee->engine.buffer.data;
1220    if (!extn) return ECORE_CALLBACK_PASS_ON;
1221    if (extn->ipc.server != e->server) return ECORE_CALLBACK_PASS_ON;
1222    evas_object_image_data_set(ee->engine.buffer.image, NULL);
1223    ee->engine.buffer.pixels = NULL;
1224    if (extn->file.shmfile)
1225      {
1226         shmfile_close(extn->file.shmfile);
1227         extn->file.shmfile = NULL;
1228      }
1229    if (extn->file.shm)
1230      {
1231         eina_stringshare_del(extn->file.shm);
1232         extn->file.shm = NULL;
1233      }
1234    extn->ipc.server = NULL;
1235    if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
1236    return ECORE_CALLBACK_PASS_ON;
1237 }
1238
1239 static Eina_Bool
1240 _ipc_server_data(void *data, int type __UNUSED__, void *event)
1241 {
1242    Ecore_Ipc_Event_Server_Data *e = event;
1243    Ecore_Evas *ee = data;
1244    Extn *extn;
1245
1246    if (ee != ecore_ipc_server_data_get(e->server))
1247      return ECORE_CALLBACK_PASS_ON;
1248    if (!eina_list_data_find(extn_ee_list, ee))
1249      return ECORE_CALLBACK_PASS_ON;
1250    extn = ee->engine.buffer.data;
1251    if (!extn) return ECORE_CALLBACK_PASS_ON;
1252    if (e->major != MAJOR)
1253      return ECORE_CALLBACK_PASS_ON;
1254    switch (e->minor)
1255      {
1256       case OP_UPDATE:
1257          // add rect to update list
1258          if (e->size >= (int)sizeof(Ipc_Data_Update))
1259            {
1260               Ipc_Data_Update *ipc = malloc(sizeof(Ipc_Data_Update));
1261               if (ipc)
1262                 {
1263                    memcpy(ipc, e->data, sizeof(Ipc_Data_Update));
1264                    extn->file.updates = eina_list_append(extn->file.updates, ipc);
1265                 }
1266            }
1267          break;
1268       case OP_UPDATE_DONE:
1269          // updates finished being sent - done now. frame ready
1270            {
1271               Ipc_Data_Update *ipc;
1272
1273               EINA_LIST_FREE(extn->file.updates, ipc)
1274                 {
1275                    if (ee->engine.buffer.image)
1276                      evas_object_image_data_update_add(ee->engine.buffer.image,
1277                                                        ipc->x, ipc->y,
1278                                                        ipc->w, ipc->h);
1279                    free(ipc);
1280                 }
1281            }
1282          break;
1283       case OP_LOCK_FILE:
1284          if ((e->data) && (e->size > 0) &&
1285              (((unsigned char *)e->data)[e->size - 1] == 0))
1286            {
1287               if (extn->file.have_lock) _ecore_evas_socket_unlock(ee);
1288               if (extn->file.lockfd) close(extn->file.lockfd);
1289               if (extn->file.lock) eina_stringshare_del(extn->file.lock);
1290               extn->file.lock = eina_stringshare_add(e->data);
1291               extn->file.lockfd = open(extn->file.lock, O_RDONLY);
1292            }
1293          break;
1294       case OP_SHM_REF:
1295          // e->ref == w
1296          // e->ref_to == h
1297          // e->response == alpha
1298          // e->data = shm ref string + nul byte
1299          if ((e->data) && ((unsigned char *)e->data)[e->size - 1] == 0)
1300            {
1301               ee->engine.buffer.pixels = NULL;
1302               if (extn->file.shmfile)
1303                 {
1304                    shmfile_close(extn->file.shmfile);
1305                    extn->file.shmfile = NULL;
1306                 }
1307               if (extn->file.shm)
1308                 {
1309                    eina_stringshare_del(extn->file.shm);
1310                    extn->file.shm = NULL;
1311                 }
1312               if ((e->ref > 0) && (e->ref_to > 0))
1313                 {
1314                    extn->file.w = e->ref;
1315                    extn->file.h = e->ref_to;
1316                    extn->file.shm = eina_stringshare_add(e->data);
1317                    extn->file.shmfile = shmfile_open(extn->file.shm,
1318                                                      extn->file.w *
1319                                                      extn->file.h * 4,
1320                                                      EINA_TRUE);
1321                    if (extn->file.shmfile)
1322                      {
1323                         ee->engine.buffer.pixels = extn->file.shmfile->addr;
1324                         if (ee->engine.buffer.image)
1325                           {
1326                              if (e->response)
1327                                evas_object_image_alpha_set(ee->engine.buffer.image,
1328                                                            EINA_TRUE);
1329                              else
1330                                evas_object_image_alpha_set(ee->engine.buffer.image,
1331                                                            EINA_FALSE);
1332                              evas_object_image_size_set(ee->engine.buffer.image,
1333                                                         extn->file.w,
1334                                                         extn->file.h);
1335                              evas_object_image_data_set(ee->engine.buffer.image,
1336                                                         ee->engine.buffer.pixels);
1337                              evas_object_image_data_update_add(ee->engine.buffer.image,
1338                                                                0, 0,
1339                                                                extn->file.w,
1340                                                                extn->file.h);
1341                              _ecore_evas_resize(ee,
1342                                                 extn->file.w,
1343                                                 extn->file.h);
1344                           }
1345                         else
1346                           evas_object_image_data_set(ee->engine.buffer.image, NULL);
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          break;
1355       case OP_RESIZE:
1356          if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize)))
1357            {
1358               Ipc_Data_Resize *ipc = e->data;
1359               _ecore_evas_resize(ee, ipc->w, ipc->h);
1360            }
1361          break;
1362       default:
1363          break;
1364      }
1365    return ECORE_CALLBACK_PASS_ON;
1366 }
1367 #else
1368 void
1369 _ecore_evas_extn_init(void)
1370 {
1371 }
1372
1373 void
1374 _ecore_evas_extn_shutdown(void)
1375 {
1376 }
1377
1378 #endif /* BUILD_ECORE_EVAS_EXTN */
1379
1380 EAPI Evas_Object *
1381 ecore_evas_extn_plug_new(Ecore_Evas *ee_target)
1382 {
1383 #ifdef BUILD_ECORE_EVAS_EXTN
1384    Evas_Object *o;
1385    Ecore_Evas *ee;
1386    int w = 1, h = 1;
1387
1388    if (!ee_target) return NULL;
1389
1390    ee = calloc(1, sizeof(Ecore_Evas));
1391    if (!ee) return NULL;
1392
1393    o = evas_object_image_filled_add(ee_target->evas);
1394    /* this make problem in gl engine, so I'll block this until solve problem 
1395    evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);*/
1396    evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
1397    evas_object_image_alpha_set(o, 1);
1398    evas_object_image_size_set(o, 1, 1);
1399    evas_object_image_data_set(o, &blank);
1400
1401    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
1402
1403    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_plug_engine_func;
1404
1405    ee->driver = "extn_plug";
1406
1407    ee->rotation = 0;
1408    ee->visible = 0;
1409    ee->w = w;
1410    ee->h = h;
1411    ee->req.w = ee->w;
1412    ee->req.h = ee->h;
1413
1414    ee->prop.max.w = 0;
1415    ee->prop.max.h = 0;
1416    ee->prop.layer = 0;
1417    ee->prop.focused = 0;
1418    ee->prop.borderless = 1;
1419    ee->prop.override = 1;
1420    ee->prop.maximized = 0;
1421    ee->prop.fullscreen = 0;
1422    ee->prop.withdrawn = 0;
1423    ee->prop.sticky = 0;
1424
1425    ee->engine.buffer.image = o;
1426    evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas", ee);
1427    evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas_Parent", ee_target);
1428    evas_object_event_callback_add(ee->engine.buffer.image,
1429                                   EVAS_CALLBACK_MOUSE_IN,
1430                                   _ecore_evas_extn_cb_mouse_in, ee);
1431    evas_object_event_callback_add(ee->engine.buffer.image,
1432                                   EVAS_CALLBACK_MOUSE_OUT,
1433                                   _ecore_evas_extn_cb_mouse_out, ee);
1434    evas_object_event_callback_add(ee->engine.buffer.image,
1435                                   EVAS_CALLBACK_MOUSE_DOWN,
1436                                   _ecore_evas_extn_cb_mouse_down, ee);
1437    evas_object_event_callback_add(ee->engine.buffer.image,
1438                                   EVAS_CALLBACK_MOUSE_UP,
1439                                   _ecore_evas_extn_cb_mouse_up, ee);
1440    evas_object_event_callback_add(ee->engine.buffer.image,
1441                                   EVAS_CALLBACK_MOUSE_MOVE,
1442                                   _ecore_evas_extn_cb_mouse_move, ee);
1443    evas_object_event_callback_add(ee->engine.buffer.image,
1444                                   EVAS_CALLBACK_MOUSE_WHEEL,
1445                                   _ecore_evas_extn_cb_mouse_wheel, ee);
1446    evas_object_event_callback_add(ee->engine.buffer.image,
1447                                   EVAS_CALLBACK_MULTI_DOWN,
1448                                   _ecore_evas_extn_cb_multi_down, ee);
1449    evas_object_event_callback_add(ee->engine.buffer.image,
1450                                   EVAS_CALLBACK_MULTI_UP,
1451                                   _ecore_evas_extn_cb_multi_up, ee);
1452    evas_object_event_callback_add(ee->engine.buffer.image,
1453                                   EVAS_CALLBACK_MULTI_MOVE,
1454                                   _ecore_evas_extn_cb_multi_move, ee);
1455    evas_object_event_callback_add(ee->engine.buffer.image,
1456                                   EVAS_CALLBACK_KEY_DOWN,
1457                                   _ecore_evas_extn_cb_key_down, ee);
1458    evas_object_event_callback_add(ee->engine.buffer.image,
1459                                   EVAS_CALLBACK_KEY_UP,
1460                                   _ecore_evas_extn_cb_key_up, ee);
1461    evas_object_event_callback_add(ee->engine.buffer.image,
1462                                   EVAS_CALLBACK_HOLD,
1463                                   _ecore_evas_extn_cb_hold, ee);
1464    evas_object_event_callback_add(ee->engine.buffer.image,
1465                                   EVAS_CALLBACK_FOCUS_IN,
1466                                   _ecore_evas_extn_cb_focus_in, ee);
1467    evas_object_event_callback_add(ee->engine.buffer.image,
1468                                   EVAS_CALLBACK_FOCUS_OUT,
1469                                   _ecore_evas_extn_cb_focus_out, ee);
1470    evas_object_event_callback_add(ee->engine.buffer.image,
1471                                   EVAS_CALLBACK_SHOW,
1472                                   _ecore_evas_extn_cb_show, ee);
1473    evas_object_event_callback_add(ee->engine.buffer.image,
1474                                   EVAS_CALLBACK_HIDE,
1475                                   _ecore_evas_extn_cb_hide, ee);
1476
1477    evas_object_event_callback_add(ee->engine.buffer.image,
1478                                   EVAS_CALLBACK_DEL,
1479                                   _ecore_evas_extn_plug_image_obj_del, ee);
1480
1481
1482    extn_ee_list = eina_list_append(extn_ee_list, ee);
1483    ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas, ee);
1484
1485    evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_PRE,
1486                            _ecore_evas_extn_plug_targer_render_pre, ee);
1487    evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_POST,
1488                            _ecore_evas_extn_plug_targer_render_post, ee);
1489    return o;
1490 #else
1491    return NULL;
1492 #endif
1493 }
1494
1495 EAPI Eina_Bool
1496 ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys)
1497 {
1498 #ifdef BUILD_ECORE_EVAS_EXTN
1499    Extn *extn;
1500    Ecore_Evas *ee = NULL;
1501
1502    if (!obj) return EINA_FALSE;
1503
1504    ee = evas_object_data_get(obj, "Ecore_Evas");
1505    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) return EINA_FALSE;
1506
1507    extn = calloc(1, sizeof(Extn));
1508    if (!extn) return EINA_FALSE;
1509
1510    Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER;
1511
1512    ecore_ipc_init();
1513    extn->svc.name = eina_stringshare_add(svcname);
1514    extn->svc.num = svcnum;
1515    extn->svc.sys = svcsys;
1516
1517    if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM;
1518    extn->ipc.server = ecore_ipc_server_connect(ipctype, (char *)extn->svc.name,
1519                                                extn->svc.num, ee);
1520    if (!extn->ipc.server)
1521      {
1522         eina_stringshare_del(extn->svc.name);
1523         free(extn);
1524         ecore_ipc_shutdown();
1525         return EINA_FALSE;
1526      }
1527    ee->engine.buffer.data = extn;
1528    extn->ipc.handlers = eina_list_append
1529       (extn->ipc.handlers,
1530        ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD,
1531                                _ipc_server_add, ee));
1532    extn->ipc.handlers = eina_list_append
1533       (extn->ipc.handlers,
1534        ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL,
1535                                _ipc_server_del, ee));
1536    extn->ipc.handlers = eina_list_append
1537       (extn->ipc.handlers,
1538        ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA,
1539                                _ipc_server_data, ee));
1540    return EINA_TRUE;
1541 #else
1542    return EINA_FALSE;
1543 #endif
1544 }
1545
1546 EAPI void
1547 ecore_evas_extn_plug_object_data_lock(Evas_Object *obj)
1548 {
1549 #ifdef BUILD_ECORE_EVAS_EXTN
1550    Ecore_Evas *ee;
1551
1552    ee = ecore_evas_object_ecore_evas_get(obj);
1553    if (!ee) return;
1554    _ecore_evas_socket_lock(ee);
1555 #endif
1556 }
1557
1558 EAPI void
1559 ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj)
1560 {
1561 #ifdef BUILD_ECORE_EVAS_EXTN
1562    Ecore_Evas *ee;
1563
1564    ee = ecore_evas_object_ecore_evas_get(obj);
1565    if (!ee) return;
1566    _ecore_evas_socket_unlock(ee);
1567 #endif
1568 }
1569
1570 #ifdef BUILD_ECORE_EVAS_EXTN
1571 static void
1572 _ecore_evas_socket_resize(Ecore_Evas *ee, int w, int h)
1573 {
1574    Extn *extn;
1575    Evas_Engine_Info_Buffer *einfo;
1576    int stride = 0;
1577
1578    if (w < 1) w = 1;
1579    if (h < 1) h = 1;
1580    ee->req.w = w;
1581    ee->req.h = h;
1582    if ((w == ee->w) && (h == ee->h)) return;
1583    ee->w = w;
1584    ee->h = h;
1585    evas_output_size_set(ee->evas, ee->w, ee->h);
1586    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1587    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1588    extn = ee->engine.buffer.data;
1589    if (extn)
1590      {
1591         if (extn->file.shmfile)
1592           shmfile_free(extn->file.shmfile);
1593         ee->engine.buffer.pixels = NULL;
1594         extn->file.shmfile = shmfile_new(extn->svc.name, extn->svc.num,
1595                                          ee->w * ee->h * 4, extn->svc.sys);
1596         if (extn->file.shmfile)
1597           ee->engine.buffer.pixels = extn->file.shmfile->addr;
1598
1599         stride = ee->w * 4;
1600         einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
1601         if (einfo)
1602           {
1603              if (ee->alpha)
1604                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
1605              else
1606                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
1607              einfo->info.dest_buffer = ee->engine.buffer.pixels;
1608              einfo->info.dest_buffer_row_bytes = stride;
1609              einfo->info.use_color_key = 0;
1610              einfo->info.alpha_threshold = 0;
1611              einfo->info.func.new_update_region = NULL;
1612              einfo->info.func.free_update_region = NULL;
1613              if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1614                {
1615                   ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1616                }
1617           }
1618
1619         if (extn->ipc.clients && extn->file.shmfile)
1620           {
1621              Ipc_Data_Resize ipc;
1622              Eina_List *l;
1623              Ecore_Ipc_Client *client;
1624
1625              EINA_LIST_FOREACH(extn->ipc.clients, l, client)
1626                 ecore_ipc_client_send(client, MAJOR, OP_SHM_REF,
1627                                       ee->w, ee->h, ee->alpha,
1628                                       extn->file.shmfile->file,
1629                                       strlen(extn->file.shmfile->file) + 1);
1630              ipc.w = ee->w;
1631              ipc.h = ee->h;
1632              EINA_LIST_FOREACH(extn->ipc.clients, l, client)
1633                 ecore_ipc_client_send(client, MAJOR, OP_RESIZE,
1634                                       0, 0, 0, &ipc, sizeof(ipc));
1635           }
1636      }
1637    if (ee->func.fn_resize) ee->func.fn_resize(ee);
1638 }
1639
1640 static void
1641 _ecore_evas_socket_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
1642 {
1643    _ecore_evas_socket_resize(ee, w, h);
1644 }
1645
1646 int
1647 _ecore_evas_extn_socket_render(Ecore_Evas *ee)
1648 {
1649    Eina_List *updates = NULL, *l, *ll;
1650    Ecore_Evas *ee2;
1651    int rend = 0;
1652    Eina_Rectangle *r;
1653    Extn *extn;
1654    Ecore_Ipc_Client *client;
1655
1656    extn = ee->engine.buffer.data;
1657    EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
1658      {
1659         if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
1660         if (ee2->engine.func->fn_render)
1661           rend |= ee2->engine.func->fn_render(ee2);
1662         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
1663      }
1664    if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
1665
1666    if (ee->engine.buffer.pixels)
1667      {
1668         _ecore_evas_socket_lock(ee);
1669         updates = evas_render_updates(ee->evas);
1670         _ecore_evas_socket_unlock(ee);
1671      }
1672    EINA_LIST_FOREACH(updates, l, r)
1673      {
1674         Ipc_Data_Update ipc;
1675
1676
1677         ipc.x = r->x;
1678         ipc.y = r->y;
1679         ipc.w = r->w;
1680         ipc.h = r->h;
1681         EINA_LIST_FOREACH(extn->ipc.clients, ll, client)
1682            ecore_ipc_client_send(client, MAJOR, OP_UPDATE, 0, 0, 0, &ipc, sizeof(ipc));
1683      }
1684    if (updates)
1685      {
1686         evas_render_updates_free(updates);
1687         _ecore_evas_idle_timeout_update(ee);
1688         EINA_LIST_FOREACH(extn->ipc.clients, ll, client)
1689            ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, 0, NULL, 0);
1690      }
1691
1692    if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
1693    return updates ? 1 : rend;
1694 }
1695
1696 static Eina_Bool
1697 _ipc_client_add(void *data, int type __UNUSED__, void *event)
1698 {
1699    Ecore_Ipc_Event_Client_Add *e = event;
1700    Ecore_Evas *ee = data;
1701    Extn *extn;
1702
1703    if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client)))
1704      return ECORE_CALLBACK_PASS_ON;
1705    if (!eina_list_data_find(extn_ee_list, ee))
1706      return ECORE_CALLBACK_PASS_ON;
1707    extn = ee->engine.buffer.data;
1708    if (!extn) return ECORE_CALLBACK_PASS_ON;
1709
1710    extn->ipc.clients = eina_list_append(extn->ipc.clients, e->client);
1711    ecore_ipc_client_send(e->client, MAJOR, OP_LOCK_FILE, 0, 0, 0, extn->file.lock, strlen(extn->file.lock) + 1);
1712
1713    if (extn->file.shmfile)
1714      {
1715         Ipc_Data_Resize ipc;
1716
1717         ecore_ipc_client_send(e->client, MAJOR, OP_SHM_REF,
1718                               ee->w, ee->h, ee->alpha,
1719                               extn->file.shmfile->file,
1720                               strlen(extn->file.shmfile->file) + 1);
1721         ipc.w = ee->w;
1722         ipc.h = ee->h;
1723
1724         ecore_ipc_client_send(e->client, MAJOR, OP_RESIZE,
1725                               0, 0, 0, &ipc, sizeof(ipc));
1726      }
1727    _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_ADD);
1728    return ECORE_CALLBACK_PASS_ON;
1729 }
1730
1731 static Eina_Bool
1732 _ipc_client_del(void *data, int type __UNUSED__, void *event)
1733 {
1734    Ecore_Ipc_Event_Client_Del *e = event;
1735    Ecore_Evas *ee = data;
1736    Extn *extn;
1737    extn = ee->engine.buffer.data;
1738    if (!extn) return ECORE_CALLBACK_PASS_ON;
1739    if (!eina_list_data_find(extn->ipc.clients, e->client)) return ECORE_CALLBACK_PASS_ON;
1740
1741    extn->ipc.clients = eina_list_remove(extn->ipc.clients, e->client);
1742
1743    _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_DEL);
1744    return ECORE_CALLBACK_PASS_ON;
1745 }
1746
1747 static Eina_Bool
1748 _ipc_client_data(void *data, int type __UNUSED__, void *event)
1749 {
1750    Ecore_Ipc_Event_Client_Data *e = event;
1751    Ecore_Evas *ee = data;
1752    Extn *extn;
1753
1754    if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client)))
1755      return ECORE_CALLBACK_PASS_ON;
1756    if (!eina_list_data_find(extn_ee_list, ee))
1757      return ECORE_CALLBACK_PASS_ON;
1758    extn = ee->engine.buffer.data;
1759    if (!extn) return ECORE_CALLBACK_PASS_ON;
1760    if (e->major != MAJOR)
1761      return ECORE_CALLBACK_PASS_ON;
1762    switch (e->minor)
1763      {
1764       case OP_RESIZE:
1765          if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize)))
1766            {
1767
1768               Ipc_Data_Resize *ipc = e->data;
1769               /* create callbacke data size changed */
1770               _ecore_evas_socket_resize(ee, ipc->w, ipc->h);
1771            }
1772          break;
1773       case OP_SHOW:
1774          if (!ee->visible)
1775            {
1776               ee->visible = 1;
1777               if (ee->func.fn_show) ee->func.fn_show(ee);
1778            }
1779          break;
1780       case OP_HIDE:
1781          if (ee->visible)
1782            {
1783               ee->visible = 0;
1784               if (ee->func.fn_hide) ee->func.fn_hide(ee);
1785            }
1786          break;
1787       case OP_FOCUS:
1788          if (!ee->prop.focused)
1789            {
1790               ee->prop.focused = 1;
1791               evas_focus_in(ee->evas);
1792               if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
1793            }
1794          break;
1795       case OP_UNFOCUS:
1796          if (ee->prop.focused)
1797            {
1798               ee->prop.focused = 0;
1799               evas_focus_out(ee->evas);
1800               if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
1801            }
1802          break;
1803       case OP_EV_MOUSE_IN:
1804          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_In))
1805            {
1806               Ipc_Data_Ev_Mouse_In *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_mouse_in(ee->evas, ipc->timestamp, NULL);
1813               evas_event_default_flags_set(ee->evas, flags);
1814            }
1815          break;
1816       case OP_EV_MOUSE_OUT:
1817          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Out))
1818            {
1819               Ipc_Data_Ev_Mouse_Out *ipc = e->data;
1820               Evas_Event_Flags flags;
1821
1822               flags = evas_event_default_flags_get(ee->evas);
1823               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1824               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1825               evas_event_feed_mouse_out(ee->evas, ipc->timestamp, NULL);
1826               evas_event_default_flags_set(ee->evas, flags);
1827            }
1828          break;
1829       case OP_EV_MOUSE_UP:
1830          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Up))
1831            {
1832               Ipc_Data_Ev_Mouse_Up *ipc = e->data;
1833               Evas_Event_Flags flags;
1834
1835               flags = evas_event_default_flags_get(ee->evas);
1836               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1837               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1838               evas_event_feed_mouse_up(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL);
1839               evas_event_default_flags_set(ee->evas, flags);
1840            }
1841          break;
1842       case OP_EV_MOUSE_DOWN:
1843          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Down))
1844            {
1845               Ipc_Data_Ev_Mouse_Up *ipc = e->data;
1846               Evas_Event_Flags flags;
1847
1848               flags = evas_event_default_flags_get(ee->evas);
1849               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1850               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1851               evas_event_feed_mouse_down(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL);
1852               evas_event_default_flags_set(ee->evas, flags);
1853            }
1854          break;
1855       case OP_EV_MOUSE_MOVE:
1856          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Move))
1857            {
1858               Ipc_Data_Ev_Mouse_Move *ipc = e->data;
1859               Evas_Event_Flags flags;
1860
1861               flags = evas_event_default_flags_get(ee->evas);
1862               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1863               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1864               evas_event_feed_mouse_move(ee->evas, ipc->x, ipc->y, ipc->timestamp, NULL);
1865               evas_event_default_flags_set(ee->evas, flags);
1866            }
1867          break;
1868       case OP_EV_MOUSE_WHEEL:
1869          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Wheel))
1870            {
1871               Ipc_Data_Ev_Mouse_Wheel *ipc = e->data;
1872               Evas_Event_Flags flags;
1873
1874               flags = evas_event_default_flags_get(ee->evas);
1875               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1876               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1877               evas_event_feed_mouse_wheel(ee->evas, ipc->direction, ipc->z, ipc->timestamp, NULL);
1878               evas_event_default_flags_set(ee->evas, flags);
1879            }
1880          break;
1881       case OP_EV_MULTI_UP:
1882          if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Up))
1883            {
1884               Ipc_Data_Ev_Multi_Up *ipc = e->data;
1885               Evas_Event_Flags flags;
1886
1887               flags = evas_event_default_flags_get(ee->evas);
1888               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1889               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1890               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);
1891               evas_event_default_flags_set(ee->evas, flags);
1892            }
1893          break;
1894       case OP_EV_MULTI_DOWN:
1895          if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Down))
1896            {
1897               Ipc_Data_Ev_Multi_Down *ipc = e->data;
1898               Evas_Event_Flags flags;
1899
1900               flags = evas_event_default_flags_get(ee->evas);
1901               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1902               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1903               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);
1904               evas_event_default_flags_set(ee->evas, flags);
1905            }
1906          break;
1907       case OP_EV_MULTI_MOVE:
1908          if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Move))
1909            {
1910               Ipc_Data_Ev_Multi_Move *ipc = e->data;
1911               Evas_Event_Flags flags;
1912
1913               flags = evas_event_default_flags_get(ee->evas);
1914               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1915               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1916               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);
1917               evas_event_default_flags_set(ee->evas, flags);
1918            }
1919          break;
1920
1921 #define STRGET(val) \
1922          do { \
1923               if ((ipc->val) && (ipc->val < (char *)(long)(e->size - 1))) \
1924               ipc->val = ((char *)ipc) + (long)ipc->val; \
1925               else \
1926               ipc->val = NULL; \
1927          } while (0)
1928
1929       case OP_EV_KEY_UP:
1930          if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Up))
1931            {
1932               if ((e->data) && (e->size > 0) &&
1933                   (((unsigned char *)e->data)[e->size - 1] == 0))
1934                 {
1935                    Ipc_Data_Ev_Key_Up *ipc = e->data;
1936                    Evas_Event_Flags flags;
1937
1938                    STRGET(keyname);
1939                    STRGET(key);
1940                    STRGET(string);
1941                    STRGET(compose);
1942                    flags = evas_event_default_flags_get(ee->evas);
1943                    evas_event_default_flags_set(ee->evas, ipc->event_flags);
1944                    _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1945                    evas_event_feed_key_up(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL);
1946                    evas_event_default_flags_set(ee->evas, flags);
1947                 }
1948            }
1949          break;
1950       case OP_EV_KEY_DOWN:
1951          if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Down))
1952            {
1953               if ((e->data) && (e->size > 0) &&
1954                   (((unsigned char *)e->data)[e->size - 1] == 0))
1955                 {
1956                    Ipc_Data_Ev_Key_Down *ipc = e->data;
1957                    Evas_Event_Flags flags;
1958
1959                    STRGET(keyname);
1960                    STRGET(key);
1961                    STRGET(string);
1962                    STRGET(compose);
1963                    flags = evas_event_default_flags_get(ee->evas);
1964                    evas_event_default_flags_set(ee->evas, ipc->event_flags);
1965                    _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1966                    evas_event_feed_key_down(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL);
1967                    evas_event_default_flags_set(ee->evas, flags);
1968                 }
1969            }
1970          break;
1971       case OP_EV_HOLD:
1972          if (e->size >= (int)sizeof(Ipc_Data_Ev_Hold))
1973            {
1974               Ipc_Data_Ev_Hold *ipc = e->data;
1975               Evas_Event_Flags flags;
1976
1977               flags = evas_event_default_flags_get(ee->evas);
1978               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1979               evas_event_feed_hold(ee->evas, ipc->hold, ipc->timestamp, NULL);
1980               evas_event_default_flags_set(ee->evas, flags);
1981            }
1982          break;
1983       default:
1984          break;
1985      }
1986    return ECORE_CALLBACK_PASS_ON;
1987 }
1988
1989 static void
1990 _ecore_evas_extn_socket_alpha_set(Ecore_Evas *ee, int alpha)
1991 {
1992    Extn *extn;
1993    Eina_List *l;
1994    Ecore_Ipc_Client *client;
1995
1996    if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha))) return;
1997    ee->alpha = alpha;
1998
1999    extn = ee->engine.buffer.data;
2000    if (extn)
2001      {
2002         Evas_Engine_Info_Buffer *einfo;
2003
2004         einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
2005         if (einfo)
2006           {
2007              if (ee->alpha)
2008                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
2009              else
2010                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
2011              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2012              evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2013           }
2014         EINA_LIST_FOREACH(extn->ipc.clients, l, client)
2015            ecore_ipc_client_send(client, MAJOR, OP_SHM_REF,
2016                                  ee->w, ee->h, ee->alpha,
2017                                  extn->file.shmfile->file,
2018                                  strlen(extn->file.shmfile->file) + 1);
2019      }
2020 }
2021
2022 static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func =
2023 {
2024    _ecore_evas_extn_free,
2025    NULL,
2026    NULL,
2027    NULL,
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    _ecore_evas_socket_resize,
2042    _ecore_evas_socket_move_resize,
2043    NULL,
2044    NULL,
2045    NULL,
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    _ecore_evas_extn_socket_alpha_set,
2069    NULL, //transparent
2070    NULL, // profiles_set
2071
2072    NULL,
2073    NULL,
2074    NULL,
2075    NULL,
2076    NULL,
2077    NULL,
2078    
2079    _ecore_evas_extn_socket_render, // render
2080    NULL,  // screen_geometry_get
2081    NULL,  // screen_dpi_get
2082 };
2083
2084 #endif
2085
2086 EAPI Ecore_Evas *
2087 ecore_evas_extn_socket_new(int w, int h)
2088 {
2089 #ifdef BUILD_ECORE_EVAS_EXTN
2090    Evas_Engine_Info_Buffer *einfo;
2091    Ecore_Evas *ee;
2092    int rmethod;
2093
2094    rmethod = evas_render_method_lookup("buffer");
2095    if (!rmethod) return NULL;
2096    ee = calloc(1, sizeof(Ecore_Evas));
2097    if (!ee) return NULL;
2098
2099    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
2100
2101    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_socket_engine_func;
2102
2103    ee->driver = "extn_socket";
2104
2105    ee->rotation = 0;
2106    ee->visible = 0;
2107    ee->w = w;
2108    ee->h = h;
2109    ee->req.w = ee->w;
2110    ee->req.h = ee->h;
2111
2112    ee->prop.max.w = 0;
2113    ee->prop.max.h = 0;
2114    ee->prop.layer = 0;
2115    ee->prop.focused = 0;
2116    ee->prop.borderless = 1;
2117    ee->prop.override = 1;
2118    ee->prop.maximized = 0;
2119    ee->prop.fullscreen = 0;
2120    ee->prop.withdrawn = 0;
2121    ee->prop.sticky = 0;
2122
2123    /* init evas here */
2124    ee->evas = evas_new();
2125    evas_data_attach_set(ee->evas, ee);
2126    evas_output_method_set(ee->evas, rmethod);
2127    evas_output_size_set(ee->evas, w, h);
2128    evas_output_viewport_set(ee->evas, 0, 0, w, h);
2129
2130    einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
2131    if (einfo)
2132      {
2133         if (ee->alpha)
2134           einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
2135         else
2136           einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
2137         einfo->info.dest_buffer = NULL;
2138         einfo->info.dest_buffer_row_bytes = 0;
2139         einfo->info.use_color_key = 0;
2140         einfo->info.alpha_threshold = 0;
2141         einfo->info.func.new_update_region = NULL;
2142         einfo->info.func.free_update_region = NULL;
2143         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2144           {
2145              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2146              ecore_evas_free(ee);
2147              return NULL;
2148           }
2149      }
2150    else
2151      {
2152         ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
2153         ecore_evas_free(ee);
2154         return NULL;
2155      }
2156    evas_key_modifier_add(ee->evas, "Shift");
2157    evas_key_modifier_add(ee->evas, "Control");
2158    evas_key_modifier_add(ee->evas, "Alt");
2159    evas_key_modifier_add(ee->evas, "Meta");
2160    evas_key_modifier_add(ee->evas, "Hyper");
2161    evas_key_modifier_add(ee->evas, "Super");
2162    evas_key_lock_add(ee->evas, "Caps_Lock");
2163    evas_key_lock_add(ee->evas, "Num_Lock");
2164    evas_key_lock_add(ee->evas, "Scroll_Lock");
2165
2166    extn_ee_list = eina_list_append(extn_ee_list, ee);
2167
2168    _ecore_evas_register(ee);
2169
2170    return ee;
2171 #else
2172    return NULL;
2173 #endif
2174 }
2175
2176 EAPI Eina_Bool
2177 ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys)
2178 {
2179 #ifdef BUILD_ECORE_EVAS_EXTN
2180    Extn *extn;
2181
2182    extn = calloc(1, sizeof(Extn));
2183    if (!extn)
2184      {
2185         return EINA_FALSE;
2186      }
2187    else
2188      {
2189         Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER;
2190         char buf[PATH_MAX];
2191
2192         ecore_ipc_init();
2193         extn->svc.name = eina_stringshare_add(svcname);
2194         extn->svc.num = svcnum;
2195         extn->svc.sys = svcsys;
2196
2197         snprintf(buf, sizeof(buf), "/tmp/ee-lock-XXXXXX");
2198         extn->file.lockfd = mkstemp(buf);
2199         if (extn->file.lockfd >= 0)
2200           extn->file.lock = eina_stringshare_add(buf);
2201         if ((extn->file.lockfd < 0) || (!extn->file.lock))
2202           {
2203              if (extn->file.lockfd)
2204                {
2205                   close(extn->file.lockfd);
2206                   unlink(buf);
2207                }
2208              eina_stringshare_del(extn->svc.name);
2209              if (extn->file.lock) eina_stringshare_del(extn->file.lock);
2210              free(extn);
2211              ecore_ipc_shutdown();
2212              return EINA_FALSE;
2213           }
2214
2215         if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM;
2216         extn->ipc.am_server = EINA_TRUE;
2217         extn->ipc.server = ecore_ipc_server_add(ipctype,
2218                                                 (char *)extn->svc.name,
2219                                                 extn->svc.num, ee);
2220         if (!extn->ipc.server)
2221           {
2222              if (extn->file.lockfd)
2223                {
2224                   close(extn->file.lockfd);
2225                   if (extn->file.lock) unlink(extn->file.lock);
2226                }
2227              eina_stringshare_del(extn->svc.name);
2228              eina_stringshare_del(extn->file.lock);
2229              free(extn);
2230              ecore_ipc_shutdown();
2231              return EINA_FALSE;
2232           }
2233         ee->engine.buffer.data = extn;
2234         extn->ipc.handlers = eina_list_append
2235            (extn->ipc.handlers,
2236             ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
2237                                     _ipc_client_add, ee));
2238         extn->ipc.handlers = eina_list_append
2239            (extn->ipc.handlers,
2240             ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
2241                                     _ipc_client_del, ee));
2242         extn->ipc.handlers = eina_list_append
2243            (extn->ipc.handlers,
2244             ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
2245                                     _ipc_client_data, ee));
2246      }
2247    return EINA_TRUE;
2248 #else
2249    return EINA_FALSE;
2250 #endif
2251 }