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