Add wm_rotation infrastructure support
[platform/upstream/ecore.git] / src / lib / ecore_evas / ecore_evas_buffer.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 // NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar!
6 #include <stdlib.h>
7
8 #include <Ecore.h>
9 #include "ecore_private.h"
10 #include <Ecore_Input.h>
11
12 #include "ecore_evas_private.h"
13 #include "Ecore_Evas.h"
14
15 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
16 static int _ecore_evas_init_count = 0;
17
18 static int
19 _ecore_evas_buffer_init(void)
20 {
21    _ecore_evas_init_count++;
22    return _ecore_evas_init_count;
23 }
24
25 static void
26 _ecore_evas_buffer_free(Ecore_Evas *ee)
27 {
28    if (ee->engine.buffer.image)
29      {
30         Ecore_Evas *ee2;
31
32         ee2 = evas_object_data_get(ee->engine.buffer.image, "Ecore_Evas_Parent");
33         evas_object_del(ee->engine.buffer.image);
34         ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee);
35      }
36    else
37      {
38         ee->engine.buffer.free_func(ee->engine.buffer.data,
39                                     ee->engine.buffer.pixels);
40      }
41    _ecore_evas_buffer_shutdown();
42 }
43
44 static void
45 _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
46 {
47    Evas_Engine_Info_Buffer *einfo;
48    int stride = 0;
49
50    if (w < 1) w = 1;
51    if (h < 1) h = 1;
52    ee->req.w = w;
53    ee->req.h = h;
54    if ((w == ee->w) && (h == ee->h)) return;
55    ee->w = w;
56    ee->h = h;
57    evas_output_size_set(ee->evas, ee->w, ee->h);
58    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
59    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
60
61    if (ee->engine.buffer.image)
62      {
63         ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1);
64         stride = evas_object_image_stride_get(ee->engine.buffer.image);
65      }
66    else
67      {
68         if (ee->engine.buffer.pixels)
69           ee->engine.buffer.free_func(ee->engine.buffer.data,
70                                       ee->engine.buffer.pixels);
71         ee->engine.buffer.pixels =
72           ee->engine.buffer.alloc_func(ee->engine.buffer.data,
73                                        ee->w * ee->h * sizeof(int));
74         stride = ee->w * sizeof(int);
75      }
76
77    einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
78    if (einfo)
79      {
80         if (ee->alpha)
81           einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
82         else
83           einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
84         einfo->info.dest_buffer = ee->engine.buffer.pixels;
85         einfo->info.dest_buffer_row_bytes = stride;
86         einfo->info.use_color_key = 0;
87         einfo->info.alpha_threshold = 0;
88         einfo->info.func.new_update_region = NULL;
89         einfo->info.func.free_update_region = NULL;
90         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
91           {
92              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
93           }
94      }
95    if (ee->engine.buffer.image)
96       evas_object_image_data_set(ee->engine.buffer.image, ee->engine.buffer.pixels);
97    if (ee->func.fn_resize) ee->func.fn_resize(ee);
98 }
99
100 static void
101 _ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
102 {
103    _ecore_evas_resize(ee, w, h);
104 }
105
106 int
107 _ecore_evas_buffer_shutdown(void)
108 {
109    _ecore_evas_init_count--;
110    if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
111    return _ecore_evas_init_count;
112 }
113
114 static void
115 _ecore_evas_show(Ecore_Evas *ee)
116 {
117    if (ee->engine.buffer.image) return;
118    if (ee->prop.focused) return;
119    ee->prop.focused = 1;
120    evas_focus_in(ee->evas);
121    if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
122 }
123
124 int
125 _ecore_evas_buffer_render(Ecore_Evas *ee)
126 {
127    Eina_List *updates = NULL, *l, *ll;
128    Ecore_Evas *ee2;
129    int rend = 0;
130
131    EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
132      {
133         if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
134         if (ee2->engine.func->fn_render)
135            rend |= ee2->engine.func->fn_render(ee2);
136         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
137      }
138    if (ee->engine.buffer.image)
139      {
140         int w, h;
141
142         evas_object_image_size_get(ee->engine.buffer.image, &w, &h);
143         if ((w != ee->w) || (h != ee->h))
144            _ecore_evas_resize(ee, w, h);
145         ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1);
146      }
147    if (ee->engine.buffer.pixels)
148      {
149         updates = evas_render_updates(ee->evas);
150      }
151    if (ee->engine.buffer.image)
152      {
153         Eina_Rectangle *r;
154
155         evas_object_image_data_set(ee->engine.buffer.image, ee->engine.buffer.pixels);
156         EINA_LIST_FOREACH(updates, l, r)
157            evas_object_image_data_update_add(ee->engine.buffer.image,
158                                              r->x, r->y, r->w, r->h);
159      }
160    if (updates)
161      {
162         evas_render_updates_free(updates);
163         _ecore_evas_idle_timeout_update(ee);
164      }
165
166    return updates ? 1 : rend;
167 }
168
169 // NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar!
170 static void
171 _ecore_evas_buffer_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
172 {
173    Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh;
174
175    evas_object_geometry_get(ee->engine.buffer.image, &xx, &yy, &ww, &hh);
176    evas_object_image_fill_get(ee->engine.buffer.image, &fx, &fy, &fw, &fh);
177
178    if (fw < 1) fw = 1;
179    if (fh < 1) fh = 1;
180
181    if (evas_object_map_get(ee->engine.buffer.image) &&
182        evas_object_map_enable_get(ee->engine.buffer.image))
183      {
184         fx = 0; fy = 0;
185         fw = ee->w; fh = ee->h;
186         ww = ee->w; hh = ee->h;
187      }
188    
189    if ((fx == 0) && (fy == 0) && (fw == ww) && (fh == hh))
190      {
191         *x = (ee->w * (*x - xx)) / fw;
192         *y = (ee->h * (*y - yy)) / fh;
193      }
194    else
195      {
196         xx = (*x - xx) - fx;
197         while (xx < 0) xx += fw;
198         while (xx > fw) xx -= fw;
199         *x = (ee->w * xx) / fw;
200
201         yy = (*y - yy) - fy;
202         while (yy < 0) yy += fh;
203         while (yy > fh) yy -= fh;
204         *y = (ee->h * yy) / fh;
205      }
206 }
207
208 static void
209 _ecore_evas_buffer_transfer_modifiers_locks(Evas *e, Evas *e2)
210 {
211    const char *mods[] = 
212      { "Shift", "Control", "Alt", "Meta", "Hyper", "Super", NULL };
213    const char *locks[] = 
214      { "Scroll_Lock", "Num_Lock", "Caps_Lock", NULL };
215    int i;
216    
217    for (i = 0; mods[i]; i++)
218      {
219         if (evas_key_modifier_is_set(evas_key_modifier_get(e), mods[i]))
220           evas_key_modifier_on(e2, mods[i]);
221         else
222           evas_key_modifier_off(e2, mods[i]);
223      }
224    for (i = 0; locks[i]; i++)
225      {
226         if (evas_key_lock_is_set(evas_key_lock_get(e), locks[i]))
227           evas_key_lock_on(e2, locks[i]);
228         else
229           evas_key_lock_off(e2, locks[i]);
230      }
231 }
232
233 static void
234 _ecore_evas_buffer_cb_mouse_in(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
235 {
236    Ecore_Evas *ee;
237    Evas_Event_Mouse_In *ev;
238
239    ee = data;
240    ev = event_info;
241    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
242    evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL);
243 }
244
245 static void
246 _ecore_evas_buffer_cb_mouse_out(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
247 {
248    Ecore_Evas *ee;
249    Evas_Event_Mouse_Out *ev;
250
251    ee = data;
252    ev = event_info;
253    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
254    evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL);
255 }
256
257 static void
258 _ecore_evas_buffer_cb_mouse_down(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
259 {
260    Ecore_Evas *ee;
261    Evas_Event_Mouse_Down *ev;
262
263    ee = data;
264    ev = event_info;
265    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
266    evas_event_feed_mouse_down(ee->evas, ev->button, ev->flags, ev->timestamp, NULL);
267 }
268
269 static void
270 _ecore_evas_buffer_cb_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
271 {
272    Ecore_Evas *ee;
273    Evas_Event_Mouse_Up *ev;
274
275    ee = data;
276    ev = event_info;
277    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
278    evas_event_feed_mouse_up(ee->evas, ev->button, ev->flags, ev->timestamp, NULL);
279 }
280
281 static void
282 _ecore_evas_buffer_cb_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
283 {
284    Ecore_Evas *ee;
285    Evas_Event_Mouse_Move *ev;
286    Evas_Coord x, y;
287
288    ee = data;
289    ev = event_info;
290    x = ev->cur.canvas.x;
291    y = ev->cur.canvas.y;
292    _ecore_evas_buffer_coord_translate(ee, &x, &y);
293    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
294    _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp);
295 }
296
297 static void
298 _ecore_evas_buffer_cb_mouse_wheel(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
299 {
300    Ecore_Evas *ee;
301    Evas_Event_Mouse_Wheel *ev;
302
303    ee = data;
304    ev = event_info;
305    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
306    evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z, ev->timestamp, NULL);
307 }
308
309 static void
310 _ecore_evas_buffer_cb_multi_down(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
311 {
312    Ecore_Evas *ee;
313    Evas_Event_Multi_Down *ev;
314    Evas_Coord x, y, xx, yy;
315    double xf, yf;
316
317    ee = data;
318    ev = event_info;
319    x = ev->canvas.x;
320    y = ev->canvas.y;
321    xx = x;
322    yy = y;
323    _ecore_evas_buffer_coord_translate(ee, &x, &y);
324    xf = (ev->canvas.xsub - (double)xx) + (double)x;
325    yf = (ev->canvas.ysub - (double)yy) + (double)y;
326    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
327    evas_event_feed_multi_down(ee->evas, ev->device, x, y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, xf, yf, ev->flags, ev->timestamp, NULL);
328 }
329
330 static void
331 _ecore_evas_buffer_cb_multi_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
332 {
333    Ecore_Evas *ee;
334    Evas_Event_Multi_Up *ev;
335    Evas_Coord x, y, xx, yy;
336    double xf, yf;
337
338    ee = data;
339    ev = event_info;
340    x = ev->canvas.x;
341    y = ev->canvas.y;
342    xx = x;
343    yy = y;
344    _ecore_evas_buffer_coord_translate(ee, &x, &y);
345    xf = (ev->canvas.xsub - (double)xx) + (double)x;
346    yf = (ev->canvas.ysub - (double)yy) + (double)y;
347    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
348    evas_event_feed_multi_up(ee->evas, ev->device, x, y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, xf, yf, ev->flags, ev->timestamp, NULL);
349 }
350
351 static void
352 _ecore_evas_buffer_cb_multi_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
353 {
354    Ecore_Evas *ee;
355    Evas_Event_Multi_Move *ev;
356    Evas_Coord x, y, xx, yy;
357    double xf, yf;
358
359    ee = data;
360    ev = event_info;
361    x = ev->cur.canvas.x;
362    y = ev->cur.canvas.y;
363    xx = x;
364    yy = y;
365    _ecore_evas_buffer_coord_translate(ee, &x, &y);
366    xf = (ev->cur.canvas.xsub - (double)xx) + (double)x;
367    yf = (ev->cur.canvas.ysub - (double)yy) + (double)y;
368    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
369    evas_event_feed_multi_move(ee->evas, ev->device, x, y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, xf, yf, ev->timestamp, NULL);
370 }
371
372 static void
373 _ecore_evas_buffer_cb_free(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
374 {
375    Ecore_Evas *ee;
376
377    ee = data;
378    if (ee->driver) _ecore_evas_free(ee);
379 }
380
381 static void
382 _ecore_evas_buffer_cb_key_down(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
383 {
384    Ecore_Evas *ee;
385    Evas_Event_Key_Down *ev;
386
387    ee = data;
388    ev = event_info;
389    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
390    evas_event_feed_key_down(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL);
391 }
392
393 static void
394 _ecore_evas_buffer_cb_key_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
395 {
396    Ecore_Evas *ee;
397    Evas_Event_Key_Up *ev;
398
399    ee = data;
400    ev = event_info;
401    _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas);
402    evas_event_feed_key_up(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL);
403 }
404
405 static void
406 _ecore_evas_buffer_cb_focus_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
407 {
408    Ecore_Evas *ee;
409
410    ee = data;
411    ee->prop.focused = 1;
412    evas_focus_in(ee->evas);
413    if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
414 }
415
416 static void
417 _ecore_evas_buffer_cb_focus_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
418 {
419    Ecore_Evas *ee;
420
421    ee = data;
422    ee->prop.focused = 0;
423    evas_focus_out(ee->evas);
424    if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
425 }
426
427 static void
428 _ecore_evas_buffer_cb_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
429 {
430    Ecore_Evas *ee;
431
432    ee = data;
433    ee->visible = 1;
434    if (ee->func.fn_show) ee->func.fn_show(ee);
435 }
436
437 static void
438 _ecore_evas_buffer_cb_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
439 {
440    Ecore_Evas *ee;
441
442    ee = data;
443    ee->visible = 0;
444    if (ee->func.fn_hide) ee->func.fn_hide(ee);
445 }
446
447 static void
448 _ecore_evas_buffer_alpha_set(Ecore_Evas *ee, int alpha)
449 {
450    if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha))) return;
451    ee->alpha = alpha;
452    if (ee->engine.buffer.image)
453       evas_object_image_alpha_set(ee->engine.buffer.image, ee->alpha);
454    else
455      {
456         Evas_Engine_Info_Buffer *einfo;
457         
458         einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
459         if (einfo)
460           {
461              if (ee->alpha)
462                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
463              else
464                einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
465              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
466           }
467      }
468 }
469
470 static Ecore_Evas_Engine_Func _ecore_buffer_engine_func =
471 {
472    _ecore_evas_buffer_free,
473      NULL,
474      NULL,
475      NULL,
476      NULL,
477      NULL,
478      NULL,
479      NULL,
480      NULL,
481      NULL,
482      NULL,
483      NULL,
484      NULL,
485      NULL,
486      NULL,
487      NULL,
488      NULL,
489      _ecore_evas_resize,
490      _ecore_evas_move_resize,
491      NULL,
492      NULL,
493      _ecore_evas_show,
494      NULL,
495      NULL,
496      NULL,
497      NULL,
498      NULL,
499      NULL,
500      NULL,
501      NULL,
502      NULL,
503      NULL,
504      NULL,
505      NULL,
506      NULL,
507      NULL,
508      NULL,
509      NULL,
510      NULL,
511      NULL,
512      NULL,
513      NULL,
514      NULL,
515      NULL,
516      _ecore_evas_buffer_alpha_set,
517      NULL, //transparent
518      NULL, // profiles_set
519
520      NULL,
521      NULL,
522      NULL,
523      NULL,
524      NULL,
525      NULL,
526
527      _ecore_evas_buffer_render,
528      NULL, // screen_geometry_get
529      NULL,  // screen_dpi_get
530
531      NULL, // wm_rot_preferred_rotation_set
532      NULL  // wm_rot_available_rotations_set
533
534 };
535 #endif
536
537 static void *
538 _ecore_evas_buffer_pix_alloc(void *data __UNUSED__, int size)
539 {
540    return malloc(size);
541 }
542
543 static void
544 _ecore_evas_buffer_pix_free(void *data __UNUSED__, void *pix)
545 {
546    free(pix);
547 }
548
549 EAPI Ecore_Evas *
550 ecore_evas_buffer_new(int w, int h)
551 {
552     return ecore_evas_buffer_allocfunc_new
553      (w, h, _ecore_evas_buffer_pix_alloc, _ecore_evas_buffer_pix_free, NULL);
554 }
555
556 EAPI Ecore_Evas *
557 ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, int size), void (*free_func) (void *data, void *pix), const void *data)
558 {
559 // NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar!
560 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
561    Evas_Engine_Info_Buffer *einfo;
562    Ecore_Evas *ee;
563    int rmethod;
564
565    if ((!alloc_func) || (!free_func)) return NULL;
566    rmethod = evas_render_method_lookup("buffer");
567    if (!rmethod) return NULL;
568    ee = calloc(1, sizeof(Ecore_Evas));
569    if (!ee) return NULL;
570
571    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
572
573    _ecore_evas_buffer_init();
574
575    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_buffer_engine_func;
576    ee->engine.buffer.alloc_func = alloc_func;
577    ee->engine.buffer.free_func = free_func;
578    ee->engine.buffer.data = (void *)data;
579
580    ee->driver = "buffer";
581
582    if (w < 1) w = 1;
583    if (h < 1) h = 1;
584    ee->rotation = 0;
585    ee->visible = 1;
586    ee->w = w;
587    ee->h = h;
588    ee->req.w = ee->w;
589    ee->req.h = ee->h;
590
591    ee->prop.max.w = 0;
592    ee->prop.max.h = 0;
593    ee->prop.layer = 0;
594    ee->prop.focused = 1;
595    ee->prop.borderless = 1;
596    ee->prop.override = 1;
597    ee->prop.maximized = 1;
598    ee->prop.fullscreen = 0;
599    ee->prop.withdrawn = 0;
600    ee->prop.sticky = 0;
601
602    /* init evas here */
603    ee->evas = evas_new();
604    evas_data_attach_set(ee->evas, ee);
605    evas_output_method_set(ee->evas, rmethod);
606    evas_output_size_set(ee->evas, w, h);
607    evas_output_viewport_set(ee->evas, 0, 0, w, h);
608
609    ee->engine.buffer.pixels =
610      ee->engine.buffer.alloc_func
611      (ee->engine.buffer.data, w * h * sizeof(int));
612
613    einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
614    if (einfo)
615      {
616         einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
617         einfo->info.dest_buffer = ee->engine.buffer.pixels;
618         einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int);
619         einfo->info.use_color_key = 0;
620         einfo->info.alpha_threshold = 0;
621         einfo->info.func.new_update_region = NULL;
622         einfo->info.func.free_update_region = NULL;
623         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
624           {
625              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
626              ecore_evas_free(ee);
627              return NULL;
628           }
629      }
630    else
631      {
632         ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
633         ecore_evas_free(ee);
634         return NULL;
635      }
636    evas_key_modifier_add(ee->evas, "Shift");
637    evas_key_modifier_add(ee->evas, "Control");
638    evas_key_modifier_add(ee->evas, "Alt");
639    evas_key_modifier_add(ee->evas, "Meta");
640    evas_key_modifier_add(ee->evas, "Hyper");
641    evas_key_modifier_add(ee->evas, "Super");
642    evas_key_lock_add(ee->evas, "Caps_Lock");
643    evas_key_lock_add(ee->evas, "Num_Lock");
644    evas_key_lock_add(ee->evas, "Scroll_Lock");
645
646    evas_event_feed_mouse_in(ee->evas, 0, NULL);
647
648    _ecore_evas_register(ee);
649
650    evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
651    
652    return ee;
653 #else
654    return NULL;
655 #endif
656 }
657
658 EAPI const void *
659 ecore_evas_buffer_pixels_get(Ecore_Evas *ee)
660 {
661 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
662    _ecore_evas_buffer_render(ee);
663    return ee->engine.buffer.pixels;
664 #else
665    return NULL;
666 #endif
667 }
668
669 EAPI Evas *
670 ecore_evas_object_evas_get(Evas_Object *obj)
671 {
672    Ecore_Evas *ee;
673
674    ee = evas_object_data_get(obj, "Ecore_Evas");
675    if (!ee) return NULL;
676
677    return ecore_evas_get(ee);
678 }
679
680 EAPI Ecore_Evas *
681 ecore_evas_object_ecore_evas_get(Evas_Object *obj)
682 {
683    return evas_object_data_get(obj, "Ecore_Evas");
684 }
685
686 EAPI Evas_Object *
687 ecore_evas_object_image_new(Ecore_Evas *ee_target)
688 {
689 // NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar!
690 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
691    Evas_Object *o;
692    Evas_Engine_Info_Buffer *einfo;
693    Ecore_Evas *ee;
694    int rmethod;
695    int w = 1, h = 1;
696
697    rmethod = evas_render_method_lookup("buffer");
698    if (!rmethod) return NULL;
699    ee = calloc(1, sizeof(Ecore_Evas));
700    if (!ee) return NULL;
701
702    o = evas_object_image_add(ee_target->evas);
703    evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
704    evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
705    evas_object_image_alpha_set(o, 0);
706    evas_object_image_size_set(o, w, h);
707
708    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
709
710    _ecore_evas_buffer_init();
711
712    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_buffer_engine_func;
713
714    ee->driver = "buffer";
715
716    ee->rotation = 0;
717    ee->visible = 0;
718    ee->w = w;
719    ee->h = h;
720    ee->req.w = ee->w;
721    ee->req.h = ee->h;
722
723    ee->prop.max.w = 0;
724    ee->prop.max.h = 0;
725    ee->prop.layer = 0;
726    ee->prop.focused = 0;
727    ee->prop.borderless = 1;
728    ee->prop.override = 1;
729    ee->prop.maximized = 0;
730    ee->prop.fullscreen = 0;
731    ee->prop.withdrawn = 0;
732    ee->prop.sticky = 0;
733
734    /* init evas here */
735    ee->evas = evas_new();
736    evas_data_attach_set(ee->evas, ee);
737    evas_output_method_set(ee->evas, rmethod);
738    evas_output_size_set(ee->evas, w, h);
739    evas_output_viewport_set(ee->evas, 0, 0, w, h);
740
741    ee->engine.buffer.image = o;
742    evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas", ee);
743    evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas_Parent", ee_target);
744    evas_object_event_callback_add(ee->engine.buffer.image,
745                                   EVAS_CALLBACK_MOUSE_IN,
746                                   _ecore_evas_buffer_cb_mouse_in, ee);
747    evas_object_event_callback_add(ee->engine.buffer.image,
748                                   EVAS_CALLBACK_MOUSE_OUT,
749                                   _ecore_evas_buffer_cb_mouse_out, ee);
750    evas_object_event_callback_add(ee->engine.buffer.image,
751                                   EVAS_CALLBACK_MOUSE_DOWN,
752                                   _ecore_evas_buffer_cb_mouse_down, ee);
753    evas_object_event_callback_add(ee->engine.buffer.image,
754                                   EVAS_CALLBACK_MOUSE_UP,
755                                   _ecore_evas_buffer_cb_mouse_up, ee);
756    evas_object_event_callback_add(ee->engine.buffer.image,
757                                   EVAS_CALLBACK_MOUSE_MOVE,
758                                   _ecore_evas_buffer_cb_mouse_move, ee);
759    evas_object_event_callback_add(ee->engine.buffer.image,
760                                   EVAS_CALLBACK_MOUSE_WHEEL,
761                                   _ecore_evas_buffer_cb_mouse_wheel, ee);
762    evas_object_event_callback_add(ee->engine.buffer.image,
763                                   EVAS_CALLBACK_MULTI_DOWN,
764                                   _ecore_evas_buffer_cb_multi_down, ee);
765    evas_object_event_callback_add(ee->engine.buffer.image,
766                                   EVAS_CALLBACK_MULTI_UP,
767                                   _ecore_evas_buffer_cb_multi_up, ee);
768    evas_object_event_callback_add(ee->engine.buffer.image,
769                                   EVAS_CALLBACK_MULTI_MOVE,
770                                   _ecore_evas_buffer_cb_multi_move, ee);
771    evas_object_event_callback_add(ee->engine.buffer.image,
772                                   EVAS_CALLBACK_FREE,
773                                   _ecore_evas_buffer_cb_free, ee);
774    evas_object_event_callback_add(ee->engine.buffer.image,
775                                   EVAS_CALLBACK_KEY_DOWN,
776                                   _ecore_evas_buffer_cb_key_down, ee);
777    evas_object_event_callback_add(ee->engine.buffer.image,
778                                   EVAS_CALLBACK_KEY_UP,
779                                   _ecore_evas_buffer_cb_key_up, ee);
780    evas_object_event_callback_add(ee->engine.buffer.image,
781                                   EVAS_CALLBACK_FOCUS_IN,
782                                   _ecore_evas_buffer_cb_focus_in, ee);
783    evas_object_event_callback_add(ee->engine.buffer.image,
784                                   EVAS_CALLBACK_FOCUS_OUT,
785                                   _ecore_evas_buffer_cb_focus_out, ee);
786    evas_object_event_callback_add(ee->engine.buffer.image,
787                                   EVAS_CALLBACK_SHOW,
788                                   _ecore_evas_buffer_cb_show, ee);
789    evas_object_event_callback_add(ee->engine.buffer.image,
790                                   EVAS_CALLBACK_HIDE,
791                                   _ecore_evas_buffer_cb_hide, ee);
792    einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
793    if (einfo)
794      {
795         ee->engine.buffer.pixels = evas_object_image_data_get(o, 1);
796         einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
797         einfo->info.dest_buffer = ee->engine.buffer.pixels;
798         einfo->info.dest_buffer_row_bytes = evas_object_image_stride_get(o);
799         einfo->info.use_color_key = 0;
800         einfo->info.alpha_threshold = 0;
801         einfo->info.func.new_update_region = NULL;
802         einfo->info.func.free_update_region = NULL;
803         evas_object_image_data_set(o, ee->engine.buffer.pixels);
804         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
805           {
806              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
807              ecore_evas_free(ee);
808              return NULL;
809           }
810      }
811    else
812      {
813         ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
814         ecore_evas_free(ee);
815         return NULL;
816      }
817    evas_key_modifier_add(ee->evas, "Shift");
818    evas_key_modifier_add(ee->evas, "Control");
819    evas_key_modifier_add(ee->evas, "Alt");
820    evas_key_modifier_add(ee->evas, "Meta");
821    evas_key_modifier_add(ee->evas, "Hyper");
822    evas_key_modifier_add(ee->evas, "Super");
823    evas_key_lock_add(ee->evas, "Caps_Lock");
824    evas_key_lock_add(ee->evas, "Num_Lock");
825    evas_key_lock_add(ee->evas, "Scroll_Lock");
826
827    ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas, ee);
828
829    return o;
830 #else
831    return NULL;
832 #endif
833 }