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