Send mouse move event before mouse down event in ecore_extn.
[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        /* We have send mouse move event before mouse down event */
676        {
677           Ipc_Data_Ev_Mouse_Move ipc_move;
678           Evas_Coord x, y;
679
680           x = ev->canvas.x;
681           y = ev->canvas.y;
682           _ecore_evas_extn_coord_translate(ee, &x, &y);
683           ipc_move.x = x;
684           ipc_move.y = y;
685           ipc_move.timestamp = ev->timestamp;
686           ipc_move.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
687           ipc_move.event_flags = ev->event_flags;
688           ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_MOVE, 0, 0, 0, &ipc_move, sizeof(ipc_move));
689        }
690        {
691           Ipc_Data_Ev_Mouse_Down ipc;
692           ipc.b = ev->button;
693           ipc.flags = ev->flags;
694           ipc.timestamp = ev->timestamp;
695           ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
696           ipc.event_flags = ev->event_flags;
697           ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_DOWN, 0, 0, 0, &ipc, sizeof(ipc));
698        }
699      }
700 }
701
702 static void
703 _ecore_evas_extn_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
704 {
705    Ecore_Evas *ee = data;
706    Evas_Event_Mouse_Up *ev = event_info;
707    Extn *extn;
708
709    extn = ee->engine.buffer.data;
710    if (!extn) return;
711    if (extn->ipc.server)
712      {
713         Ipc_Data_Ev_Mouse_Up ipc;
714
715         ipc.b = ev->button;
716         ipc.flags = ev->flags;
717         ipc.timestamp = ev->timestamp;
718         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
719         ipc.event_flags = ev->event_flags;
720         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_UP, 0, 0, 0, &ipc, sizeof(ipc));
721      }
722 }
723
724 static void
725 _ecore_evas_extn_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
726 {
727    Ecore_Evas *ee = data;
728    Evas_Event_Mouse_Move *ev = event_info;
729    Extn *extn;
730
731    extn = ee->engine.buffer.data;
732    if (!extn) return;
733    if (extn->ipc.server)
734      {
735         Ipc_Data_Ev_Mouse_Move ipc;
736         Evas_Coord x, y;
737
738         x = ev->cur.canvas.x;
739         y = ev->cur.canvas.y;
740         _ecore_evas_extn_coord_translate(ee, &x, &y);
741         ipc.x = x;
742         ipc.y = y;
743         ipc.timestamp = ev->timestamp;
744         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
745         ipc.event_flags = ev->event_flags;
746         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_MOVE, 0, 0, 0, &ipc, sizeof(ipc));
747      }
748 }
749
750 static void
751 _ecore_evas_extn_cb_mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
752 {
753    Ecore_Evas *ee = data;
754    Evas_Event_Mouse_Wheel *ev = event_info;
755    Extn *extn;
756
757    extn = ee->engine.buffer.data;
758    if (!extn) return;
759    if (extn->ipc.server)
760      {
761         Ipc_Data_Ev_Mouse_Wheel ipc;
762
763         ipc.direction = ev->direction;
764         ipc.z = ev->z;
765         ipc.timestamp = ev->timestamp;
766         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
767         ipc.event_flags = ev->event_flags;
768         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_WHEEL, 0, 0, 0, &ipc, sizeof(ipc));
769      }
770 }
771
772 static void
773 _ecore_evas_extn_cb_multi_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
774 {
775    Ecore_Evas *ee = data;
776    Evas_Event_Multi_Down *ev = event_info;
777    Extn *extn;
778
779    extn = ee->engine.buffer.data;
780    if (!extn) return;
781    if (extn->ipc.server)
782      {
783         Ipc_Data_Ev_Multi_Down ipc;
784         Evas_Coord x, y;
785
786         ipc.d = ev->device;
787         x = ev->canvas.x;
788         y = ev->canvas.y;
789         _ecore_evas_extn_coord_translate(ee, &x, &y);
790         ipc.x = x;
791         ipc.y = y;
792         ipc.rad = ev->radius;
793         ipc.radx = ev->radius_x;
794         ipc.rady = ev->radius_y;
795         ipc.pres = ev->pressure;
796         ipc.ang = ev->angle;
797         ipc.fx = ev->canvas.xsub;
798         ipc.fy = ev->canvas.ysub;
799         ipc.flags = ev->flags;
800         ipc.timestamp = ev->timestamp;
801         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
802         ipc.event_flags = ev->event_flags;
803         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_DOWN, 0, 0, 0, &ipc, sizeof(ipc));
804      }
805 }
806
807
808 static void
809 _ecore_evas_extn_cb_multi_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
810 {
811    Ecore_Evas *ee = data;
812    Evas_Event_Multi_Up *ev = event_info;
813    Extn *extn;
814
815    extn = ee->engine.buffer.data;
816    if (!extn) return;
817    if (extn->ipc.server)
818      {
819         Ipc_Data_Ev_Multi_Up ipc;
820         Evas_Coord x, y;
821
822         ipc.d = ev->device;
823         x = ev->canvas.x;
824         y = ev->canvas.y;
825         _ecore_evas_extn_coord_translate(ee, &x, &y);
826         ipc.x = x;
827         ipc.y = y;
828         ipc.rad = ev->radius;
829         ipc.radx = ev->radius_x;
830         ipc.rady = ev->radius_y;
831         ipc.pres = ev->pressure;
832         ipc.ang = ev->angle;
833         ipc.fx = ev->canvas.xsub;
834         ipc.fy = ev->canvas.ysub;
835         ipc.flags = ev->flags;
836         ipc.timestamp = ev->timestamp;
837         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
838         ipc.event_flags = ev->event_flags;
839         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_UP, 0, 0, 0, &ipc, sizeof(ipc));
840      }
841 }
842
843 static void
844 _ecore_evas_extn_cb_multi_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
845 {
846    Ecore_Evas *ee = data;
847    Evas_Event_Multi_Move *ev = event_info;
848    Extn *extn;
849
850    extn = ee->engine.buffer.data;
851    if (!extn) return;
852    if (extn->ipc.server)
853      {
854         Ipc_Data_Ev_Multi_Move ipc;
855         Evas_Coord x, y;
856
857         ipc.d = ev->device;
858         x = ev->cur.canvas.x;
859         y = ev->cur.canvas.y;
860         _ecore_evas_extn_coord_translate(ee, &x, &y);
861         ipc.x = x;
862         ipc.y = y;
863         ipc.rad = ev->radius;
864         ipc.radx = ev->radius_x;
865         ipc.rady = ev->radius_y;
866         ipc.pres = ev->pressure;
867         ipc.ang = ev->angle;
868         ipc.fx = ev->cur.canvas.xsub;
869         ipc.fy = ev->cur.canvas.ysub;
870         ipc.timestamp = ev->timestamp;
871         ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
872         ipc.event_flags = ev->event_flags;
873         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_MOVE, 0, 0, 0, &ipc, sizeof(ipc));
874      }
875 }
876
877 static void
878 _ecore_evas_extn_cb_free(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
879 {
880    Ecore_Evas *ee;
881
882    ee = data;
883    if (ee->driver) _ecore_evas_free(ee);
884 }
885
886 static void
887 _ecore_evas_extn_cb_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
888 {
889    Ecore_Evas *ee = data;
890    Evas_Event_Key_Down *ev = event_info;
891    Extn *extn;
892
893    extn = ee->engine.buffer.data;
894    if (!extn) return;
895    if (extn->ipc.server)
896      {
897         Ipc_Data_Ev_Key_Down *ipc;
898         char *st, *p;
899         int len = 0;
900
901         len = sizeof(Ipc_Data_Ev_Key_Down);
902         if (ev->key) len += strlen(ev->key) + 1;
903         if (ev->keyname) len += strlen(ev->keyname) + 1;
904         if (ev->string) len += strlen(ev->string) + 1;
905         if (ev->compose) len += strlen(ev->compose) + 1;
906         len += 1;
907         st = alloca(len);
908         ipc = (Ipc_Data_Ev_Key_Down *)st;
909         memset(st, 0, len);
910         p = st + sizeof(Ipc_Data_Ev_Key_Down);
911         if (ev->key)
912           {
913              strcpy(p, ev->key);
914              ipc->key = p - (long)st;
915              p += strlen(p) + 1;
916           }
917         if (ev->keyname)
918           {
919              strcpy(p, ev->keyname);
920              ipc->keyname = p - (long)st;
921              p += strlen(p) + 1;
922           }
923         if (ev->string)
924           {
925              strcpy(p, ev->string);
926              ipc->string = p - (long)st;
927              p += strlen(p) + 1;
928           }
929         if (ev->compose)
930           {
931              strcpy(p, ev->compose);
932              ipc->compose = p - (long)st;
933              p += strlen(p) + 1;
934           }
935         ipc->timestamp = ev->timestamp;
936         ipc->mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
937         ipc->event_flags = ev->event_flags;
938         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_KEY_DOWN, 0, 0, 0, ipc, len);
939      }
940 }
941
942 static void
943 _ecore_evas_extn_cb_key_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
944 {
945    Ecore_Evas *ee = data;
946    Evas_Event_Key_Up *ev = event_info;
947    Extn *extn;
948
949    extn = ee->engine.buffer.data;
950    if (!extn) return;
951    if (extn->ipc.server)
952      {
953         Ipc_Data_Ev_Key_Up *ipc;
954         char *st, *p;
955         int len = 0;
956
957         len = sizeof(Ipc_Data_Ev_Key_Up);
958         if (ev->key) len += strlen(ev->key) + 1;
959         if (ev->keyname) len += strlen(ev->keyname) + 1;
960         if (ev->string) len += strlen(ev->string) + 1;
961         if (ev->compose) len += strlen(ev->compose) + 1;
962         len += 1;
963         st = alloca(len);
964         ipc = (Ipc_Data_Ev_Key_Up *)st;
965         memset(st, 0, len);
966         p = st + sizeof(Ipc_Data_Ev_Key_Down);
967         if (ev->key)
968           {
969              strcpy(p, ev->key);
970              ipc->key = p - (long)st;
971              p += strlen(p) + 1;
972           }
973         if (ev->keyname)
974           {
975              strcpy(p, ev->keyname);
976              ipc->keyname = p - (long)st;
977              p += strlen(p) + 1;
978           }
979         if (ev->string)
980           {
981              strcpy(p, ev->string);
982              ipc->string = p - (long)st;
983              p += strlen(p) + 1;
984           }
985         if (ev->compose)
986           {
987              strcpy(p, ev->compose);
988              ipc->compose = p - (long)st;
989              p += strlen(p) + 1;
990           }
991         ipc->timestamp = ev->timestamp;
992         ipc->mask = _ecore_evas_modifiers_locks_mask_get(ee->evas);
993         ipc->event_flags = ev->event_flags;
994         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_KEY_UP, 0, 0, 0, ipc, len);
995      }
996 }
997
998 static void
999 _ecore_evas_extn_cb_hold(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1000 {
1001    Ecore_Evas *ee = data;
1002    Evas_Event_Hold *ev = event_info;
1003    Extn *extn;
1004
1005    extn = ee->engine.buffer.data;
1006    if (!extn) return;
1007    if (extn->ipc.server)
1008      {
1009         Ipc_Data_Ev_Hold ipc;
1010
1011         ipc.hold = ev->hold;
1012         ipc.timestamp = ev->timestamp;
1013         ipc.event_flags = ev->event_flags;
1014         ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_HOLD, 0, 0, 0, &ipc, sizeof(ipc));
1015      }
1016 }
1017
1018 static void
1019 _ecore_evas_extn_cb_focus_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1020 {
1021    Ecore_Evas *ee;
1022    Extn *extn;
1023
1024    ee = data;
1025    ee->prop.focused = 1;
1026    extn = ee->engine.buffer.data;
1027    if (!extn) return;
1028    if (!extn->ipc.server) return;
1029    ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_FOCUS, 0, 0, 0, NULL, 0);
1030 }
1031
1032 static void
1033 _ecore_evas_extn_cb_focus_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1034 {
1035    Ecore_Evas *ee;
1036    Extn *extn;
1037
1038    ee = data;
1039    ee->prop.focused = 0;
1040    extn = ee->engine.buffer.data;
1041    if (!extn) return;
1042    if (!extn->ipc.server) return;
1043    ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_UNFOCUS, 0, 0, 0, NULL, 0);
1044 }
1045
1046 static void
1047 _ecore_evas_extn_cb_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1048 {
1049    Ecore_Evas *ee;
1050    Extn *extn;
1051
1052    ee = data;
1053    ee->visible = 1;
1054    extn = ee->engine.buffer.data;
1055    if (!extn) return;
1056    if (!extn->ipc.server) return;
1057    ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_SHOW, 0, 0, 0, NULL, 0);
1058 }
1059
1060 static void
1061 _ecore_evas_extn_cb_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1062 {
1063    Ecore_Evas *ee;
1064    Extn *extn;
1065
1066    ee = data;
1067    ee->visible = 0;
1068    extn = ee->engine.buffer.data;
1069    if (!extn) return;
1070    if (!extn->ipc.server) return;
1071    ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_HIDE, 0, 0, 0, NULL, 0);
1072 }
1073
1074 static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func =
1075 {
1076    _ecore_evas_extn_free,
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    _ecore_evas_resize,
1094    _ecore_evas_move_resize,
1095    NULL,
1096    NULL,
1097    NULL,
1098    NULL,
1099    NULL,
1100    NULL,
1101    NULL,
1102    NULL,
1103    NULL,
1104    NULL,
1105    NULL,
1106    NULL,
1107    NULL,
1108    NULL,
1109    NULL,
1110    NULL,
1111    NULL,
1112    NULL,
1113    NULL,
1114    NULL,
1115    NULL,
1116    NULL,
1117    NULL,
1118    NULL,
1119    NULL,
1120    NULL,
1121    NULL, //transparent
1122
1123    NULL,
1124    NULL,
1125    NULL,
1126    NULL,
1127    NULL,
1128    NULL,
1129
1130    NULL, // render
1131    NULL  // screen_geometry_get
1132 };
1133
1134 static Eina_Bool
1135 _ipc_server_add(void *data, int type __UNUSED__, void *event)
1136 {
1137    Ecore_Ipc_Event_Server_Add *e = event;
1138    Ecore_Evas *ee = data;
1139    Extn *extn;
1140
1141    if (ee != ecore_ipc_server_data_get(e->server))
1142      return ECORE_CALLBACK_PASS_ON;
1143    if (!eina_list_data_find(extn_ee_list, ee))
1144      return ECORE_CALLBACK_PASS_ON;
1145    extn = ee->engine.buffer.data;
1146    if (!extn) return ECORE_CALLBACK_PASS_ON;
1147    //FIXME: find a way to let app know server there
1148    return ECORE_CALLBACK_PASS_ON;
1149 }
1150
1151 static Eina_Bool
1152 _ipc_server_del(void *data, int type __UNUSED__, void *event)
1153 {
1154    Ecore_Ipc_Event_Server_Del *e = event;
1155    Ecore_Evas *ee = data;
1156    Extn *extn;
1157
1158    extn = ee->engine.buffer.data;
1159    if (!extn) return ECORE_CALLBACK_PASS_ON;
1160    if (extn->ipc.server != e->server) return ECORE_CALLBACK_PASS_ON;
1161    evas_object_image_data_set(ee->engine.buffer.image, NULL);
1162    ee->engine.buffer.pixels = NULL;
1163    if (extn->file.shmfile)
1164      {
1165         shmfile_close(extn->file.shmfile);
1166         extn->file.shmfile = NULL;
1167      }
1168    if (extn->file.shm)
1169      {
1170         eina_stringshare_del(extn->file.shm);
1171         extn->file.shm = NULL;
1172      }
1173    extn->ipc.server = NULL;
1174    if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
1175    return ECORE_CALLBACK_PASS_ON;
1176 }
1177
1178 static Eina_Bool
1179 _ipc_server_data(void *data, int type __UNUSED__, void *event)
1180 {
1181    Ecore_Ipc_Event_Server_Data *e = event;
1182    Ecore_Evas *ee = data;
1183    Extn *extn;
1184
1185    if (ee != ecore_ipc_server_data_get(e->server))
1186      return ECORE_CALLBACK_PASS_ON;
1187    if (!eina_list_data_find(extn_ee_list, ee))
1188      return ECORE_CALLBACK_PASS_ON;
1189    extn = ee->engine.buffer.data;
1190    if (!extn) return ECORE_CALLBACK_PASS_ON;
1191    if (e->major != MAJOR)
1192      return ECORE_CALLBACK_PASS_ON;
1193    switch (e->minor)
1194      {
1195       case OP_UPDATE:
1196          // add rect to update list
1197          if (e->size >= (int)sizeof(Ipc_Data_Update))
1198            {
1199               Ipc_Data_Update *ipc = malloc(sizeof(Ipc_Data_Update));
1200               if (ipc)
1201                 {
1202                    memcpy(ipc, e->data, sizeof(Ipc_Data_Update));
1203                    extn->file.updates = eina_list_append(extn->file.updates, ipc);
1204                 }
1205            }
1206          break;
1207       case OP_UPDATE_DONE:
1208          // updates finished being sent - done now. frame ready
1209            {
1210               Ipc_Data_Update *ipc;
1211
1212               EINA_LIST_FREE(extn->file.updates, ipc)
1213                 {
1214                    if (ee->engine.buffer.image)
1215                      evas_object_image_data_update_add(ee->engine.buffer.image,
1216                                                        ipc->x, ipc->y,
1217                                                        ipc->w, ipc->h);
1218                 }
1219            }
1220          break;
1221       case OP_LOCK_FILE:
1222          if ((e->data) && (e->size > 0) &&
1223              (((unsigned char *)e->data)[e->size - 1] == 0))
1224            {
1225               if (extn->file.lockfd) close(extn->file.lockfd);
1226               if (extn->file.lock) eina_stringshare_del(extn->file.lock);
1227               extn->file.lock = eina_stringshare_add(e->data);
1228               extn->file.lockfd = open(extn->file.lock, O_RDONLY);
1229            }
1230          break;
1231       case OP_SHM_REF:
1232          // e->ref == w
1233          // e->ref_to == h
1234          // e->response == alpha
1235          // e->data = shm ref string + nul byte
1236          if ((e->data) && ((unsigned char *)e->data)[e->size - 1] == 0)
1237            {
1238               ee->engine.buffer.pixels = NULL;
1239               if (extn->file.shmfile)
1240                 {
1241                    shmfile_close(extn->file.shmfile);
1242                    extn->file.shmfile = NULL;
1243                 }
1244               if (extn->file.shm)
1245                 {
1246                    eina_stringshare_del(extn->file.shm);
1247                    extn->file.shm = NULL;
1248                 }
1249               if ((e->ref > 0) && (e->ref_to > 0))
1250                 {
1251                    extn->file.w = e->ref;
1252                    extn->file.h = e->ref_to;
1253                    extn->file.shm = eina_stringshare_add(e->data);
1254                    extn->file.shmfile = shmfile_open(extn->file.shm,
1255                                                      extn->file.w *
1256                                                      extn->file.h * 4,
1257                                                      EINA_TRUE);
1258                    if (extn->file.shmfile)
1259                      {
1260                         ee->engine.buffer.pixels = extn->file.shmfile->addr;
1261                         if (ee->engine.buffer.image)
1262                           {
1263                              if (e->response)
1264                                evas_object_image_alpha_set(ee->engine.buffer.image,
1265                                                            EINA_TRUE);
1266                              else
1267                                evas_object_image_alpha_set(ee->engine.buffer.image,
1268                                                            EINA_FALSE);
1269                              evas_object_image_size_set(ee->engine.buffer.image,
1270                                                         extn->file.w,
1271                                                         extn->file.h);
1272                              evas_object_image_data_set(ee->engine.buffer.image,
1273                                                         ee->engine.buffer.pixels);
1274                              evas_object_image_data_update_add(ee->engine.buffer.image,
1275                                                                0, 0,
1276                                                                extn->file.w,
1277                                                                extn->file.h);
1278                              _ecore_evas_resize(ee,
1279                                                 extn->file.w,
1280                                                 extn->file.h);
1281                           }
1282                         else
1283                           evas_object_image_data_set(ee->engine.buffer.image, NULL);
1284                      }
1285                    else
1286                      evas_object_image_data_set(ee->engine.buffer.image, NULL);
1287                 }
1288               else
1289                 evas_object_image_data_set(ee->engine.buffer.image, NULL);
1290            }
1291          break;
1292       case OP_RESIZE:
1293          if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize)))
1294            {
1295               Ipc_Data_Resize *ipc = e->data;
1296               _ecore_evas_resize(ee, ipc->w, ipc->h);
1297            }
1298          break;
1299       default:
1300          break;
1301      }
1302    return ECORE_CALLBACK_PASS_ON;
1303 }
1304 #else
1305 void
1306 _ecore_evas_extn_init(void)
1307 {
1308 }
1309
1310 void
1311 _ecore_evas_extn_shutdown(void)
1312 {
1313 }
1314
1315 #endif /* BUILD_ECORE_EVAS_EXTN */
1316
1317 EAPI Evas_Object *
1318 ecore_evas_extn_plug_new(Ecore_Evas *ee_target)
1319 {
1320 #ifdef BUILD_ECORE_EVAS_EXTN
1321    Evas_Object *o;
1322    Ecore_Evas *ee;
1323    int w = 1, h = 1;
1324
1325    if (!ee_target) return NULL;
1326
1327    ee = calloc(1, sizeof(Ecore_Evas));
1328    if (!ee) return NULL;
1329
1330    o = evas_object_image_filled_add(ee_target->evas);
1331    evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
1332    evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
1333    evas_object_image_alpha_set(o, 1);
1334    evas_object_image_size_set(o, 1, 1);
1335    evas_object_image_data_set(o, &blank);
1336
1337    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
1338
1339    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_plug_engine_func;
1340
1341    ee->driver = "extn_plug";
1342
1343    ee->rotation = 0;
1344    ee->visible = 0;
1345    ee->w = w;
1346    ee->h = h;
1347    ee->req.w = ee->w;
1348    ee->req.h = ee->h;
1349
1350    ee->prop.max.w = 0;
1351    ee->prop.max.h = 0;
1352    ee->prop.layer = 0;
1353    ee->prop.focused = 0;
1354    ee->prop.borderless = 1;
1355    ee->prop.override = 1;
1356    ee->prop.maximized = 0;
1357    ee->prop.fullscreen = 0;
1358    ee->prop.withdrawn = 0;
1359    ee->prop.sticky = 0;
1360
1361    ee->engine.buffer.image = o;
1362    evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas", ee);
1363    evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas_Parent", ee_target);
1364    evas_object_event_callback_add(ee->engine.buffer.image,
1365                                   EVAS_CALLBACK_MOUSE_IN,
1366                                   _ecore_evas_extn_cb_mouse_in, ee);
1367    evas_object_event_callback_add(ee->engine.buffer.image,
1368                                   EVAS_CALLBACK_MOUSE_OUT,
1369                                   _ecore_evas_extn_cb_mouse_out, ee);
1370    evas_object_event_callback_add(ee->engine.buffer.image,
1371                                   EVAS_CALLBACK_MOUSE_DOWN,
1372                                   _ecore_evas_extn_cb_mouse_down, ee);
1373    evas_object_event_callback_add(ee->engine.buffer.image,
1374                                   EVAS_CALLBACK_MOUSE_UP,
1375                                   _ecore_evas_extn_cb_mouse_up, ee);
1376    evas_object_event_callback_add(ee->engine.buffer.image,
1377                                   EVAS_CALLBACK_MOUSE_MOVE,
1378                                   _ecore_evas_extn_cb_mouse_move, ee);
1379    evas_object_event_callback_add(ee->engine.buffer.image,
1380                                   EVAS_CALLBACK_MOUSE_WHEEL,
1381                                   _ecore_evas_extn_cb_mouse_wheel, ee);
1382    evas_object_event_callback_add(ee->engine.buffer.image,
1383                                   EVAS_CALLBACK_MULTI_DOWN,
1384                                   _ecore_evas_extn_cb_multi_down, ee);
1385    evas_object_event_callback_add(ee->engine.buffer.image,
1386                                   EVAS_CALLBACK_MULTI_UP,
1387                                   _ecore_evas_extn_cb_multi_up, ee);
1388    evas_object_event_callback_add(ee->engine.buffer.image,
1389                                   EVAS_CALLBACK_MULTI_MOVE,
1390                                   _ecore_evas_extn_cb_multi_move, ee);
1391    evas_object_event_callback_add(ee->engine.buffer.image,
1392                                   EVAS_CALLBACK_FREE,
1393                                   _ecore_evas_extn_cb_free, ee);
1394    evas_object_event_callback_add(ee->engine.buffer.image,
1395                                   EVAS_CALLBACK_KEY_DOWN,
1396                                   _ecore_evas_extn_cb_key_down, ee);
1397    evas_object_event_callback_add(ee->engine.buffer.image,
1398                                   EVAS_CALLBACK_KEY_UP,
1399                                   _ecore_evas_extn_cb_key_up, ee);
1400    evas_object_event_callback_add(ee->engine.buffer.image,
1401                                   EVAS_CALLBACK_HOLD,
1402                                   _ecore_evas_extn_cb_hold, ee);
1403    evas_object_event_callback_add(ee->engine.buffer.image,
1404                                   EVAS_CALLBACK_FOCUS_IN,
1405                                   _ecore_evas_extn_cb_focus_in, ee);
1406    evas_object_event_callback_add(ee->engine.buffer.image,
1407                                   EVAS_CALLBACK_FOCUS_OUT,
1408                                   _ecore_evas_extn_cb_focus_out, ee);
1409    evas_object_event_callback_add(ee->engine.buffer.image,
1410                                   EVAS_CALLBACK_SHOW,
1411                                   _ecore_evas_extn_cb_show, ee);
1412    evas_object_event_callback_add(ee->engine.buffer.image,
1413                                   EVAS_CALLBACK_HIDE,
1414                                   _ecore_evas_extn_cb_hide, ee);
1415
1416    evas_object_event_callback_add(ee->engine.buffer.image,
1417                                   EVAS_CALLBACK_DEL,
1418                                   _ecore_evas_extn_plug_image_obj_del, ee);
1419
1420
1421    extn_ee_list = eina_list_append(extn_ee_list, ee);
1422    ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas, ee);
1423
1424    evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_PRE,
1425                            _ecore_evas_extn_plug_targer_render_pre, ee);
1426    evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_POST,
1427                            _ecore_evas_extn_plug_targer_render_post, ee);
1428    return o;
1429 #else
1430    return NULL;
1431 #endif
1432 }
1433
1434 EAPI Eina_Bool
1435 ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys)
1436 {
1437 #ifdef BUILD_ECORE_EVAS_EXTN
1438    Extn *extn;
1439    Ecore_Evas *ee = NULL;
1440
1441    if (!obj) return EINA_FALSE;
1442
1443    ee = evas_object_data_get(obj, "Ecore_Evas");
1444    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) return EINA_FALSE;
1445
1446    extn = calloc(1, sizeof(Extn));
1447    if (!extn) return EINA_FALSE;
1448
1449    Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER;
1450
1451    ecore_ipc_init();
1452    extn->svc.name = eina_stringshare_add(svcname);
1453    extn->svc.num = svcnum;
1454    extn->svc.sys = svcsys;
1455
1456    if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM;
1457    extn->ipc.server = ecore_ipc_server_connect(ipctype, (char *)extn->svc.name,
1458                                                extn->svc.num, ee);
1459    if (!extn->ipc.server)
1460      {
1461         eina_stringshare_del(extn->svc.name);
1462         free(extn);
1463         ecore_ipc_shutdown();
1464         return EINA_FALSE;
1465      }
1466    ee->engine.buffer.data = extn;
1467    extn->ipc.handlers = eina_list_append
1468       (extn->ipc.handlers,
1469        ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD,
1470                                _ipc_server_add, ee));
1471    extn->ipc.handlers = eina_list_append
1472       (extn->ipc.handlers,
1473        ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL,
1474                                _ipc_server_del, ee));
1475    extn->ipc.handlers = eina_list_append
1476       (extn->ipc.handlers,
1477        ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA,
1478                                _ipc_server_data, ee));
1479    return EINA_TRUE;
1480 #else
1481    return EINA_FALSE;
1482 #endif
1483 }
1484
1485 EAPI void
1486 ecore_evas_extn_plug_object_data_lock(Evas_Object *obj)
1487 {
1488 #ifdef BUILD_ECORE_EVAS_EXTN
1489    Ecore_Evas *ee;
1490
1491    ee = ecore_evas_object_ecore_evas_get(obj);
1492    if (!ee) return;
1493    _ecore_evas_socket_lock(ee);
1494 #endif
1495 }
1496
1497 EAPI void
1498 ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj)
1499 {
1500 #ifdef BUILD_ECORE_EVAS_EXTN
1501    Ecore_Evas *ee;
1502
1503    ee = ecore_evas_object_ecore_evas_get(obj);
1504    if (!ee) return;
1505    _ecore_evas_socket_unlock(ee);
1506 #endif
1507 }
1508
1509 #ifdef BUILD_ECORE_EVAS_EXTN
1510 static void
1511 _ecore_evas_socket_resize(Ecore_Evas *ee, int w, int h)
1512 {
1513    Extn *extn;
1514    Evas_Engine_Info_Buffer *einfo;
1515    int stride = 0;
1516
1517    if (w < 1) w = 1;
1518    if (h < 1) h = 1;
1519    ee->req.w = w;
1520    ee->req.h = h;
1521    if ((w == ee->w) && (h == ee->h)) return;
1522    ee->w = w;
1523    ee->h = h;
1524    evas_output_size_set(ee->evas, ee->w, ee->h);
1525    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1526    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1527    extn = ee->engine.buffer.data;
1528    if (extn)
1529      {
1530         if (extn->file.shmfile)
1531           shmfile_free(extn->file.shmfile);
1532         ee->engine.buffer.pixels = NULL;
1533         extn->file.shmfile = shmfile_new(extn->svc.name, extn->svc.num,
1534                                          ee->w * ee->h * 4, extn->svc.sys);
1535         if (extn->file.shmfile)
1536           ee->engine.buffer.pixels = extn->file.shmfile->addr;
1537
1538         stride = ee->w * 4;
1539         einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
1540         if (einfo)
1541           {
1542              if (ee->alpha)
1543                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
1544              else
1545                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
1546              einfo->info.dest_buffer = ee->engine.buffer.pixels;
1547              einfo->info.dest_buffer_row_bytes = stride;
1548              einfo->info.use_color_key = 0;
1549              einfo->info.alpha_threshold = 0;
1550              einfo->info.func.new_update_region = NULL;
1551              einfo->info.func.free_update_region = NULL;
1552              if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1553                {
1554                   ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1555                }
1556           }
1557
1558         if (extn->ipc.clients && extn->file.shmfile)
1559           {
1560              Ipc_Data_Resize ipc;
1561              Eina_List *l;
1562              Ecore_Ipc_Client *client;
1563
1564              EINA_LIST_FOREACH(extn->ipc.clients, l, client)
1565                 ecore_ipc_client_send(client, MAJOR, OP_SHM_REF,
1566                                       ee->w, ee->h, ee->alpha,
1567                                       extn->file.shmfile->file,
1568                                       strlen(extn->file.shmfile->file) + 1);
1569              ipc.w = ee->w;
1570              ipc.h = ee->h;
1571              EINA_LIST_FOREACH(extn->ipc.clients, l, client)
1572                 ecore_ipc_client_send(client, MAJOR, OP_RESIZE,
1573                                       0, 0, 0, &ipc, sizeof(ipc));
1574           }
1575      }
1576    if (ee->func.fn_resize) ee->func.fn_resize(ee);
1577 }
1578
1579 static void
1580 _ecore_evas_socket_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
1581 {
1582    _ecore_evas_socket_resize(ee, w, h);
1583 }
1584
1585 int
1586 _ecore_evas_extn_socket_render(Ecore_Evas *ee)
1587 {
1588    Eina_List *updates = NULL, *l, *ll;
1589    Ecore_Evas *ee2;
1590    int rend = 0;
1591    Eina_Rectangle *r;
1592    Extn *extn;
1593    Ecore_Ipc_Client *client;
1594
1595    extn = ee->engine.buffer.data;
1596    EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
1597      {
1598         if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
1599         if (ee2->engine.func->fn_render)
1600           rend |= ee2->engine.func->fn_render(ee2);
1601         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
1602      }
1603    if (ee->engine.buffer.pixels)
1604      {
1605         _ecore_evas_socket_lock(ee);
1606         updates = evas_render_updates(ee->evas);
1607         _ecore_evas_socket_unlock(ee);
1608      }
1609    EINA_LIST_FOREACH(updates, l, r)
1610      {
1611         Ipc_Data_Update ipc;
1612
1613
1614         ipc.x = r->x;
1615         ipc.y = r->y;
1616         ipc.w = r->w;
1617         ipc.h = r->h;
1618         EINA_LIST_FOREACH(extn->ipc.clients, ll, client)
1619            ecore_ipc_client_send(client, MAJOR, OP_UPDATE, 0, 0, 0, &ipc, sizeof(ipc));
1620      }
1621    if (updates)
1622      {
1623         evas_render_updates_free(updates);
1624         _ecore_evas_idle_timeout_update(ee);
1625         EINA_LIST_FOREACH(extn->ipc.clients, ll, client)
1626            ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, 0, NULL, 0);
1627      }
1628
1629    return updates ? 1 : rend;
1630 }
1631
1632 static Eina_Bool
1633 _ipc_client_add(void *data, int type __UNUSED__, void *event)
1634 {
1635    Ecore_Ipc_Event_Client_Add *e = event;
1636    Ecore_Evas *ee = data;
1637    Extn *extn;
1638
1639    if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client)))
1640      return ECORE_CALLBACK_PASS_ON;
1641    if (!eina_list_data_find(extn_ee_list, ee))
1642      return ECORE_CALLBACK_PASS_ON;
1643    extn = ee->engine.buffer.data;
1644    if (!extn) return ECORE_CALLBACK_PASS_ON;
1645
1646    extn->ipc.clients = eina_list_append(extn->ipc.clients, e->client);
1647    ecore_ipc_client_send(e->client, MAJOR, OP_LOCK_FILE, 0, 0, 0, extn->file.lock, strlen(extn->file.lock) + 1);
1648
1649    if (extn->file.shmfile)
1650      {
1651         Ipc_Data_Resize ipc;
1652
1653         ecore_ipc_client_send(e->client, MAJOR, OP_SHM_REF,
1654                               ee->w, ee->h, ee->alpha,
1655                               extn->file.shmfile->file,
1656                               strlen(extn->file.shmfile->file) + 1);
1657         ipc.w = ee->w;
1658         ipc.h = ee->h;
1659
1660         ecore_ipc_client_send(e->client, MAJOR, OP_RESIZE,
1661                               0, 0, 0, &ipc, sizeof(ipc));
1662      }
1663    _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_ADD);
1664    return ECORE_CALLBACK_PASS_ON;
1665 }
1666
1667 static Eina_Bool
1668 _ipc_client_del(void *data, int type __UNUSED__, void *event)
1669 {
1670    Ecore_Ipc_Event_Client_Del *e = event;
1671    Ecore_Evas *ee = data;
1672    Extn *extn;
1673    extn = ee->engine.buffer.data;
1674    if (!extn) return ECORE_CALLBACK_PASS_ON;
1675    if (!eina_list_data_find(extn->ipc.clients, e->client)) return ECORE_CALLBACK_PASS_ON;
1676
1677    extn->ipc.clients = eina_list_remove(extn->ipc.clients, e->client);
1678
1679    _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_DEL);
1680    return ECORE_CALLBACK_PASS_ON;
1681 }
1682
1683 static Eina_Bool
1684 _ipc_client_data(void *data, int type __UNUSED__, void *event)
1685 {
1686    Ecore_Ipc_Event_Client_Data *e = event;
1687    Ecore_Evas *ee = data;
1688    Extn *extn;
1689
1690    if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client)))
1691      return ECORE_CALLBACK_PASS_ON;
1692    if (!eina_list_data_find(extn_ee_list, ee))
1693      return ECORE_CALLBACK_PASS_ON;
1694    extn = ee->engine.buffer.data;
1695    if (!extn) return ECORE_CALLBACK_PASS_ON;
1696    if (e->major != MAJOR)
1697      return ECORE_CALLBACK_PASS_ON;
1698    switch (e->minor)
1699      {
1700       case OP_RESIZE:
1701          if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize)))
1702            {
1703
1704               Ipc_Data_Resize *ipc = e->data;
1705               /* create callbacke data size changed */
1706               _ecore_evas_socket_resize(ee, ipc->w, ipc->h);
1707            }
1708          break;
1709       case OP_SHOW:
1710          if (!ee->visible)
1711            {
1712               ee->visible = 1;
1713               if (ee->func.fn_show) ee->func.fn_show(ee);
1714            }
1715          break;
1716       case OP_HIDE:
1717          if (ee->visible)
1718            {
1719               ee->visible = 0;
1720               if (ee->func.fn_hide) ee->func.fn_hide(ee);
1721            }
1722          break;
1723       case OP_FOCUS:
1724          if (!ee->prop.focused)
1725            {
1726               ee->prop.focused = 1;
1727               evas_focus_in(ee->evas);
1728               if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
1729            }
1730          break;
1731       case OP_UNFOCUS:
1732          if (ee->prop.focused)
1733            {
1734               ee->prop.focused = 0;
1735               evas_focus_out(ee->evas);
1736               if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
1737            }
1738          break;
1739       case OP_EV_MOUSE_IN:
1740          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_In))
1741            {
1742               Ipc_Data_Ev_Mouse_In *ipc = e->data;
1743               Evas_Event_Flags flags;
1744
1745               flags = evas_event_default_flags_get(ee->evas);
1746               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1747               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1748               evas_event_feed_mouse_in(ee->evas, ipc->timestamp, NULL);
1749               evas_event_default_flags_set(ee->evas, flags);
1750            }
1751          break;
1752       case OP_EV_MOUSE_OUT:
1753          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Out))
1754            {
1755               Ipc_Data_Ev_Mouse_Out *ipc = e->data;
1756               Evas_Event_Flags flags;
1757
1758               flags = evas_event_default_flags_get(ee->evas);
1759               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1760               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1761               evas_event_feed_mouse_out(ee->evas, ipc->timestamp, NULL);
1762               evas_event_default_flags_set(ee->evas, flags);
1763            }
1764          break;
1765       case OP_EV_MOUSE_UP:
1766          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Up))
1767            {
1768               Ipc_Data_Ev_Mouse_Up *ipc = e->data;
1769               Evas_Event_Flags flags;
1770
1771               flags = evas_event_default_flags_get(ee->evas);
1772               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1773               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1774               evas_event_feed_mouse_up(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL);
1775               evas_event_default_flags_set(ee->evas, flags);
1776            }
1777          break;
1778       case OP_EV_MOUSE_DOWN:
1779          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Down))
1780            {
1781               Ipc_Data_Ev_Mouse_Up *ipc = e->data;
1782               Evas_Event_Flags flags;
1783
1784               flags = evas_event_default_flags_get(ee->evas);
1785               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1786               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1787               evas_event_feed_mouse_down(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL);
1788               evas_event_default_flags_set(ee->evas, flags);
1789            }
1790          break;
1791       case OP_EV_MOUSE_MOVE:
1792          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Move))
1793            {
1794               Ipc_Data_Ev_Mouse_Move *ipc = e->data;
1795               Evas_Event_Flags flags;
1796
1797               flags = evas_event_default_flags_get(ee->evas);
1798               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1799               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1800               evas_event_feed_mouse_move(ee->evas, ipc->x, ipc->y, ipc->timestamp, NULL);
1801               evas_event_default_flags_set(ee->evas, flags);
1802            }
1803          break;
1804       case OP_EV_MOUSE_WHEEL:
1805          if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Wheel))
1806            {
1807               Ipc_Data_Ev_Mouse_Wheel *ipc = e->data;
1808               Evas_Event_Flags flags;
1809
1810               flags = evas_event_default_flags_get(ee->evas);
1811               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1812               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1813               evas_event_feed_mouse_wheel(ee->evas, ipc->direction, ipc->z, ipc->timestamp, NULL);
1814               evas_event_default_flags_set(ee->evas, flags);
1815            }
1816          break;
1817       case OP_EV_MULTI_UP:
1818          if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Up))
1819            {
1820               Ipc_Data_Ev_Multi_Up *ipc = e->data;
1821               Evas_Event_Flags flags;
1822
1823               flags = evas_event_default_flags_get(ee->evas);
1824               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1825               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1826               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);
1827               evas_event_default_flags_set(ee->evas, flags);
1828            }
1829          break;
1830       case OP_EV_MULTI_DOWN:
1831          if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Down))
1832            {
1833               Ipc_Data_Ev_Multi_Down *ipc = e->data;
1834               Evas_Event_Flags flags;
1835
1836               flags = evas_event_default_flags_get(ee->evas);
1837               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1838               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1839               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);
1840               evas_event_default_flags_set(ee->evas, flags);
1841            }
1842          break;
1843       case OP_EV_MULTI_MOVE:
1844          if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Move))
1845            {
1846               Ipc_Data_Ev_Multi_Move *ipc = e->data;
1847               Evas_Event_Flags flags;
1848
1849               flags = evas_event_default_flags_get(ee->evas);
1850               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1851               _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1852               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);
1853               evas_event_default_flags_set(ee->evas, flags);
1854            }
1855          break;
1856
1857 #define STRGET(val) \
1858          do { \
1859               if ((ipc->val) && (ipc->val < (char *)(long)(e->size - 1))) \
1860               ipc->val = ((char *)ipc) + (long)ipc->val; \
1861               else \
1862               ipc->val = NULL; \
1863          } while (0)
1864
1865       case OP_EV_KEY_UP:
1866          if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Up))
1867            {
1868               if ((e->data) && (e->size > 0) &&
1869                   (((unsigned char *)e->data)[e->size - 1] == 0))
1870                 {
1871                    Ipc_Data_Ev_Key_Up *ipc = e->data;
1872                    Evas_Event_Flags flags;
1873
1874                    STRGET(keyname);
1875                    STRGET(key);
1876                    STRGET(string);
1877                    STRGET(compose);
1878                    flags = evas_event_default_flags_get(ee->evas);
1879                    evas_event_default_flags_set(ee->evas, ipc->event_flags);
1880                    _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1881                    evas_event_feed_key_up(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL);
1882                    evas_event_default_flags_set(ee->evas, flags);
1883                 }
1884            }
1885          break;
1886       case OP_EV_KEY_DOWN:
1887          if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Down))
1888            {
1889               if ((e->data) && (e->size > 0) &&
1890                   (((unsigned char *)e->data)[e->size - 1] == 0))
1891                 {
1892                    Ipc_Data_Ev_Key_Down *ipc = e->data;
1893                    Evas_Event_Flags flags;
1894
1895                    STRGET(keyname);
1896                    STRGET(key);
1897                    STRGET(string);
1898                    STRGET(compose);
1899                    flags = evas_event_default_flags_get(ee->evas);
1900                    evas_event_default_flags_set(ee->evas, ipc->event_flags);
1901                    _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask);
1902                    evas_event_feed_key_down(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL);
1903                    evas_event_default_flags_set(ee->evas, flags);
1904                 }
1905            }
1906          break;
1907       case OP_EV_HOLD:
1908          if (e->size >= (int)sizeof(Ipc_Data_Ev_Hold))
1909            {
1910               Ipc_Data_Ev_Hold *ipc = e->data;
1911               Evas_Event_Flags flags;
1912
1913               flags = evas_event_default_flags_get(ee->evas);
1914               evas_event_default_flags_set(ee->evas, ipc->event_flags);
1915               evas_event_feed_hold(ee->evas, ipc->hold, ipc->timestamp, NULL);
1916               evas_event_default_flags_set(ee->evas, flags);
1917            }
1918          break;
1919       default:
1920          break;
1921      }
1922    return ECORE_CALLBACK_PASS_ON;
1923 }
1924
1925 static void
1926 _ecore_evas_extn_socket_alpha_set(Ecore_Evas *ee, int alpha)
1927 {
1928    Extn *extn;
1929    Eina_List *l;
1930    Ecore_Ipc_Client *client;
1931
1932    if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha))) return;
1933    ee->alpha = alpha;
1934
1935    extn = ee->engine.buffer.data;
1936    if (extn)
1937      {
1938         Evas_Engine_Info_Buffer *einfo;
1939
1940         einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
1941         if (einfo)
1942           {
1943              if (ee->alpha)
1944                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
1945              else
1946                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
1947              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
1948              evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1949           }
1950         EINA_LIST_FOREACH(extn->ipc.clients, l, client)
1951            ecore_ipc_client_send(client, MAJOR, OP_SHM_REF,
1952                                  ee->w, ee->h, ee->alpha,
1953                                  extn->file.shmfile->file,
1954                                  strlen(extn->file.shmfile->file) + 1);
1955      }
1956 }
1957
1958 static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func =
1959 {
1960    _ecore_evas_extn_free,
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_socket_resize,
1978    _ecore_evas_socket_move_resize,
1979    NULL,
1980    NULL,
1981    NULL,
1982    NULL,
1983    NULL,
1984    NULL,
1985    NULL,
1986    NULL,
1987    NULL,
1988    NULL,
1989    NULL,
1990    NULL,
1991    NULL,
1992    NULL,
1993    NULL,
1994    NULL,
1995    NULL,
1996    NULL,
1997    NULL,
1998    NULL,
1999    NULL,
2000    NULL,
2001    NULL,
2002    NULL,
2003    NULL,
2004    _ecore_evas_extn_socket_alpha_set,
2005    NULL, //transparent
2006
2007    NULL,
2008    NULL,
2009    NULL,
2010    NULL,
2011    NULL,
2012    NULL,
2013    
2014    _ecore_evas_extn_socket_render, // render
2015    NULL  // screen_geometry_get
2016 };
2017
2018 #endif
2019
2020 EAPI Ecore_Evas *
2021 ecore_evas_extn_socket_new(int w, int h)
2022 {
2023 #ifdef BUILD_ECORE_EVAS_EXTN
2024    Evas_Engine_Info_Buffer *einfo;
2025    Ecore_Evas *ee;
2026    int rmethod;
2027
2028    rmethod = evas_render_method_lookup("buffer");
2029    if (!rmethod) return NULL;
2030    ee = calloc(1, sizeof(Ecore_Evas));
2031    if (!ee) return NULL;
2032
2033    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
2034
2035    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_socket_engine_func;
2036
2037    ee->driver = "extn_socket";
2038
2039    ee->rotation = 0;
2040    ee->visible = 0;
2041    ee->w = w;
2042    ee->h = h;
2043    ee->req.w = ee->w;
2044    ee->req.h = ee->h;
2045
2046    ee->prop.max.w = 0;
2047    ee->prop.max.h = 0;
2048    ee->prop.layer = 0;
2049    ee->prop.focused = 0;
2050    ee->prop.borderless = 1;
2051    ee->prop.override = 1;
2052    ee->prop.maximized = 0;
2053    ee->prop.fullscreen = 0;
2054    ee->prop.withdrawn = 0;
2055    ee->prop.sticky = 0;
2056
2057    /* init evas here */
2058    ee->evas = evas_new();
2059    evas_data_attach_set(ee->evas, ee);
2060    evas_output_method_set(ee->evas, rmethod);
2061    evas_output_size_set(ee->evas, w, h);
2062    evas_output_viewport_set(ee->evas, 0, 0, w, h);
2063
2064    einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
2065    if (einfo)
2066      {
2067         if (ee->alpha)
2068           einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
2069         else
2070           einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
2071         einfo->info.dest_buffer = NULL;
2072         einfo->info.dest_buffer_row_bytes = 0;
2073         einfo->info.use_color_key = 0;
2074         einfo->info.alpha_threshold = 0;
2075         einfo->info.func.new_update_region = NULL;
2076         einfo->info.func.free_update_region = NULL;
2077         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2078           {
2079              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2080              ecore_evas_free(ee);
2081              return NULL;
2082           }
2083      }
2084    else
2085      {
2086         ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
2087         ecore_evas_free(ee);
2088         return NULL;
2089      }
2090    evas_key_modifier_add(ee->evas, "Shift");
2091    evas_key_modifier_add(ee->evas, "Control");
2092    evas_key_modifier_add(ee->evas, "Alt");
2093    evas_key_modifier_add(ee->evas, "Meta");
2094    evas_key_modifier_add(ee->evas, "Hyper");
2095    evas_key_modifier_add(ee->evas, "Super");
2096    evas_key_lock_add(ee->evas, "Caps_Lock");
2097    evas_key_lock_add(ee->evas, "Num_Lock");
2098    evas_key_lock_add(ee->evas, "Scroll_Lock");
2099
2100    extn_ee_list = eina_list_append(extn_ee_list, ee);
2101
2102    _ecore_evas_register(ee);
2103
2104    return ee;
2105 #else
2106    return NULL;
2107 #endif
2108 }
2109
2110 EAPI Eina_Bool
2111 ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys)
2112 {
2113 #ifdef BUILD_ECORE_EVAS_EXTN
2114    Extn *extn;
2115
2116    extn = calloc(1, sizeof(Extn));
2117    if (!extn)
2118      {
2119         return EINA_FALSE;
2120      }
2121    else
2122      {
2123         Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER;
2124         char buf[PATH_MAX];
2125
2126         ecore_ipc_init();
2127         extn->svc.name = eina_stringshare_add(svcname);
2128         extn->svc.num = svcnum;
2129         extn->svc.sys = svcsys;
2130
2131         snprintf(buf, sizeof(buf), "/tmp/ee-lock-XXXXXX");
2132         extn->file.lockfd = mkstemp(buf);
2133         if (extn->file.lockfd >= 0)
2134           extn->file.lock = eina_stringshare_add(buf);
2135         if ((extn->file.lockfd < 0) || (!extn->file.lock))
2136           {
2137              if (extn->file.lockfd)
2138                {
2139                   close(extn->file.lockfd);
2140                   unlink(buf);
2141                }
2142              eina_stringshare_del(extn->svc.name);
2143              if (extn->file.lock) eina_stringshare_del(extn->file.lock);
2144              free(extn);
2145              ecore_ipc_shutdown();
2146              return EINA_FALSE;
2147           }
2148
2149         if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM;
2150         extn->ipc.am_server = EINA_TRUE;
2151         extn->ipc.server = ecore_ipc_server_add(ipctype,
2152                                                 (char *)extn->svc.name,
2153                                                 extn->svc.num, ee);
2154         if (!extn->ipc.server)
2155           {
2156              if (extn->file.lockfd)
2157                {
2158                   close(extn->file.lockfd);
2159                   if (extn->file.lock) unlink(extn->file.lock);
2160                }
2161              eina_stringshare_del(extn->svc.name);
2162              eina_stringshare_del(extn->file.lock);
2163              free(extn);
2164              ecore_ipc_shutdown();
2165              return EINA_FALSE;
2166           }
2167         ee->engine.buffer.data = extn;
2168         extn->ipc.handlers = eina_list_append
2169            (extn->ipc.handlers,
2170             ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
2171                                     _ipc_client_add, ee));
2172         extn->ipc.handlers = eina_list_append
2173            (extn->ipc.handlers,
2174             ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
2175                                     _ipc_client_del, ee));
2176         extn->ipc.handlers = eina_list_append
2177            (extn->ipc.handlers,
2178             ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
2179                                     _ipc_client_data, ee));
2180      }
2181    return EINA_TRUE;
2182 #else
2183    return EINA_FALSE;
2184 #endif
2185 }