908a84dfa16ee983571ce84304d64a1083da3053
[framework/uifw/evas.git] / src / modules / engines / software_x11 / evas_engine.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3
4 #include "Evas_Engine_Software_X11.h"
5 #include "evas_engine.h"
6
7 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
8 # include "evas_xlib_outbuf.h"
9 # include "evas_xlib_color.h"
10 #endif
11
12 #ifdef BUILD_ENGINE_SOFTWARE_XCB
13 # include "evas_xcb_outbuf.h"
14 # include "evas_xcb_color.h"
15 #endif
16
17 int _evas_engine_soft_x11_log_dom = -1;
18
19 /* function tables - filled in later (func and parent func) */
20 static Evas_Func func, pfunc;
21
22 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
23 struct xrdb_user
24 {
25    time_t last_stat;
26    time_t last_mtime;
27    XrmDatabase db;
28 };
29 static struct xrdb_user xrdb_user = {0, 0, NULL};
30
31 static Eina_Bool
32 xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
33 {
34    time_t last, now;
35
36    last = xrdb_user.last_stat;
37    now = time(NULL);
38
39    xrdb_user.last_stat = now;
40    if (last != now) /* don't stat() more than once every second */
41      {
42         struct stat st;
43         const char *home;
44         char tmp[PATH_MAX];
45
46         if (!(home = getenv("HOME"))) 
47           goto failed;
48
49         snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
50         if (stat(tmp, &st) != 0) goto failed;
51         if (xrdb_user.last_mtime != st.st_mtime)
52           {
53              if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
54              xrdb_user.db = XrmGetFileDatabase(tmp);
55              if (!xrdb_user.db) goto failed;
56              xrdb_user.last_mtime = st.st_mtime;
57           }
58      }
59
60    if (!xrdb_user.db) return EINA_FALSE;
61    return XrmGetResource(xrdb_user.db, name, cls, type, val);
62
63  failed:
64    if (xrdb_user.db)
65      {
66         XrmDestroyDatabase(xrdb_user.db);
67         xrdb_user.db = NULL;
68      }
69    xrdb_user.last_mtime = 0;
70    return EINA_FALSE;
71 }
72 #endif
73
74 /* engine struct data */
75 typedef struct _Render_Engine Render_Engine;
76
77 struct _Render_Engine
78 {
79    Tilebuf *tb;
80    Outbuf *ob;
81    Tilebuf_Rect *rects;
82    Eina_Inlist *cur_rect;
83    unsigned char end : 1;
84
85 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
86    XrmDatabase xrdb;
87 #endif
88    struct 
89      {
90         int dpi;
91      } xr;
92
93 #ifdef EVAS_FRAME_QUEUING
94    Evas_Engine_Render_Mode render_mode;
95 #endif
96
97    void (*outbuf_free)(Outbuf *ob);
98    void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
99    int (*outbuf_get_rot)(Outbuf *ob);
100    RGBA_Image *(*outbuf_new_region_for_update)(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
101    void (*outbuf_push_updated_region)(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
102    void (*outbuf_free_region_for_update)(Outbuf *ob, RGBA_Image *update);
103    void (*outbuf_flush)(Outbuf *ob);
104    void (*outbuf_idle_flush)(Outbuf *ob);
105    Eina_Bool (*outbuf_alpha_get)(Outbuf *ob);
106 #ifdef EVAS_FRAME_QUEUING
107    void (*outbuf_set_priv)(Outbuf *ob, void *cur, void *prev);
108 #endif
109 };
110
111 /* prototypes we will use here */
112 static void *_best_visual_get(int backend, void *connection, int screen);
113 static unsigned int _best_colormap_get(int backend, void *connection, int screen);
114 static int _best_depth_get(int backend, void *connection, int screen);
115
116 static void *eng_info(Evas *e);
117 static void eng_info_free(Evas *e, void *info);
118 static int eng_setup(Evas *e, void *info);
119 static void eng_output_free(void *data);
120 static void eng_output_resize(void *data, int w, int h);
121 static void eng_output_tile_size_set(void *data, int w, int h);
122 static void eng_output_redraws_rect_add(void *data, int x, int y, int w, int h);
123 static void eng_output_redraws_rect_del(void *data, int x, int y, int w, int h);
124 static void eng_output_redraws_clear(void *data);
125 static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch);
126 static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h);
127 static void eng_output_flush(void *data);
128 static void eng_output_idle_flush(void *data);
129
130 /* internal engine routines */
131
132 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
133 static void *
134 _output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw,
135                    Visual *vis, Colormap cmap, int depth, int debug,
136                    int grayscale, int max_colors, Pixmap mask,
137                    int shape_dither, int destination_alpha)
138 {
139    Render_Engine *re;
140    int status;
141    char *type = NULL;
142    XrmValue val;
143
144    if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
145
146    evas_software_xlib_x_init();
147    evas_software_xlib_x_color_init();
148    evas_software_xlib_outbuf_init();
149
150    re->xr.dpi = 75000; // dpy * 1000
151
152    status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
153    if ((!status) || (!type))
154      {
155         if (!re->xrdb) re->xrdb = XrmGetDatabase(disp);
156         if (re->xrdb)
157           status = XrmGetResource(re->xrdb,
158                                   "Xft.dpi", "Xft.Dpi", &type, &val);
159      }
160
161    if ((status) && (type))
162      {
163         if (!strcmp(type, "String"))
164           {
165              const char *str, *dp;
166                   
167              str = val.addr;
168              dp = strchr(str, '.');
169              if (!dp) dp = strchr(str, ',');
170
171              if (dp)
172                {
173                   int subdpi, len, i;
174                   char *buf;
175                        
176                   buf = alloca(dp - str + 1);
177                   strncpy(buf, str, dp - str);
178                   buf[dp - str] = 0;
179                   len = strlen(dp + 1);
180                   subdpi = atoi(dp + 1);
181
182                   if (len < 3)
183                     {
184                        for (i = len; i < 3; i++) 
185                          subdpi *= 10;
186                     }
187                   else if (len > 3)
188                     {
189                        for (i = len; i > 3; i--) 
190                          subdpi /= 10;
191                     }
192                   re->xr.dpi = atoi(buf) * 1000;
193                }
194              else
195                re->xr.dpi = atoi(str) * 1000;
196              evas_common_font_dpi_set(re->xr.dpi / 1000);
197           }
198      }
199    
200    re->ob = 
201      evas_software_xlib_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp, 
202                                        draw, vis, cmap, depth, grayscale,
203                                        max_colors, mask, shape_dither,
204                                        destination_alpha);
205    if (!re->ob)
206      {
207         free(re);
208         return NULL;
209      }
210
211    /* for updates return 1 big buffer, but only use portions of it, also cache
212     * it and keepit around until an idle_flush */
213
214    /* disable for now - i am hunting down why some expedite tests are slower,
215     * as well as shaped stuff is broken and probable non-32bpp is broken as
216     * convert funcs dont do the right thing
217     *
218     */
219 //   re->ob->onebuf = 1;
220
221    evas_software_xlib_outbuf_debug_set(re->ob, debug);
222    re->tb = evas_common_tilebuf_new(w, h);
223    if (!re->tb)
224      {
225         evas_software_xlib_outbuf_free(re->ob);
226         free(re);
227         return NULL;
228      }
229
230    /* in preliminary tests 16x16 gave highest framerates */
231    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
232    return re;
233 }
234 #endif
235
236 #ifdef BUILD_ENGINE_SOFTWARE_XCB
237 static void *
238 _output_xcb_setup(int w, int h, int rot, xcb_connection_t *conn, 
239                   xcb_screen_t *screen, xcb_drawable_t draw, 
240                   xcb_visualtype_t *vis, xcb_colormap_t cmap, int depth,
241                   int debug, int grayscale, int max_colors, xcb_drawable_t mask,
242                   int shape_dither, int destination_alpha)
243 {
244    Render_Engine *re;
245
246    if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
247
248    evas_software_xcb_init();
249    evas_software_xcb_color_init();
250    evas_software_xcb_outbuf_init();
251
252    // FIXME: re->xrdb
253    re->xr.dpi = 75000; // dpy * 1000
254    evas_common_font_dpi_set(re->xr.dpi / 1000);
255
256    re->ob = 
257      evas_software_xcb_outbuf_setup(w, h, rot, OUTBUF_DEPTH_INHERIT, conn, 
258                                     screen, draw, vis, cmap, depth,
259                                     grayscale, max_colors, mask, 
260                                     shape_dither, destination_alpha);
261    if (!re->ob)
262      {
263         free(re);
264         return NULL;
265      }
266
267    /* for updates return 1 big buffer, but only use portions of it, also cache 
268     * it and keepit around until an idle_flush */
269
270    /* disable for now - i am hunting down why some expedite tests are slower,
271     * as well as shaped stuff is broken and probable non-32bpp is broken as
272     * convert funcs dont do the right thing
273     *
274     */
275 //   re->ob->onebuf = 1;
276
277    evas_software_xcb_outbuf_debug_set(re->ob, debug);
278
279    re->tb = evas_common_tilebuf_new(w, h);
280    if (!re->tb)
281      {
282         evas_software_xcb_outbuf_free(re->ob);
283         free(re);
284         return NULL;
285      }
286
287    /* in preliminary tests 16x16 gave highest framerates */
288    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
289    return re;
290 }
291 #endif
292
293 static void *
294 _best_visual_get(int backend, void *connection, int screen)
295 {
296    if (!connection) return NULL;
297
298 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
299    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
300      return DefaultVisual((Display *)connection, screen);
301 #endif
302
303 #ifdef BUILD_ENGINE_SOFTWARE_XCB
304    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
305      {
306         xcb_screen_iterator_t iter_screen;
307         xcb_depth_iterator_t iter_depth;
308         xcb_screen_t *s = NULL;
309
310         iter_screen = 
311           xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection));
312         for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen))
313           if (screen == 0)
314             {
315                s = iter_screen.data;
316                break;
317             }
318
319         iter_depth = xcb_screen_allowed_depths_iterator(s);
320         for (; iter_depth.rem; xcb_depth_next(&iter_depth))
321           {
322              xcb_visualtype_iterator_t iter_vis;
323
324              iter_vis = xcb_depth_visuals_iterator(iter_depth.data);
325              for (; iter_vis.rem; xcb_visualtype_next(&iter_vis))
326                {
327                   if (s->root_visual == iter_vis.data->visual_id)
328                     return iter_vis.data;
329                }
330           }
331      }
332 #endif
333
334    return NULL;
335 }
336
337 static unsigned int
338 _best_colormap_get(int backend, void *connection, int screen)
339 {
340    if (!connection) return 0;
341
342 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
343    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
344      return DefaultColormap((Display *)connection, screen);
345 #endif
346
347 #ifdef BUILD_ENGINE_SOFTWARE_XCB
348    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
349      {
350         xcb_screen_iterator_t iter_screen;
351         xcb_screen_t *s = NULL;
352
353         iter_screen = 
354           xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection));
355         for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen))
356           if (screen == 0)
357             {
358                s = iter_screen.data;
359                break;
360             }
361
362         return s->default_colormap;
363      }
364 #endif
365
366    return 0;
367 }
368
369 static int
370 _best_depth_get(int backend, void *connection, int screen)
371 {
372    if (!connection) return 0;
373
374 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
375    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
376      return DefaultDepth((Display *)connection, screen);
377 #endif
378
379 #ifdef BUILD_ENGINE_SOFTWARE_XCB
380    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
381      {
382         xcb_screen_iterator_t iter_screen;
383         xcb_screen_t *s = NULL;
384
385         iter_screen = 
386           xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection));
387         for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen))
388           if (screen == 0)
389             {
390                s = iter_screen.data;
391                break;
392             }
393
394         return s->root_depth;
395      }
396 #endif
397
398    return 0;
399 }
400
401 /* engine api this module provides */
402 static void *
403 eng_info(Evas *e __UNUSED__)
404 {
405    Evas_Engine_Info_Software_X11 *info;
406
407    if (!(info = calloc(1, sizeof(Evas_Engine_Info_Software_X11))))
408      return NULL;
409
410    info->magic.magic = rand();
411    info->info.debug = 0;
412    info->info.alloc_grayscale = 0;
413    info->info.alloc_colors_max = 216;
414    info->func.best_visual_get = _best_visual_get;
415    info->func.best_colormap_get = _best_colormap_get;
416    info->func.best_depth_get = _best_depth_get;
417    info->render_mode = EVAS_RENDER_MODE_BLOCKING;
418    return info;
419 }
420
421 static void
422 eng_info_free(Evas *e __UNUSED__, void *info)
423 {
424    Evas_Engine_Info_Software_X11 *in;
425
426    in = (Evas_Engine_Info_Software_X11 *)info;
427    free(in);
428 }
429
430 static int
431 eng_setup(Evas *e, void *in)
432 {
433    Evas_Engine_Info_Software_X11 *info;
434    Render_Engine *re = NULL;
435
436    info = (Evas_Engine_Info_Software_X11 *)in;
437    if (!e->engine.data.output)
438      {
439         /* if we haven't initialized - init (automatic abort if already done) */
440         evas_common_cpu_init();
441         evas_common_blend_init();
442         evas_common_image_init();
443         evas_common_convert_init();
444         evas_common_scale_init();
445         evas_common_rectangle_init();
446         evas_common_polygon_init();
447         evas_common_line_init();
448         evas_common_font_init();
449         evas_common_draw_init();
450         evas_common_tilebuf_init();
451
452 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
453         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
454           {
455              re = _output_xlib_setup(e->output.w, e->output.h,
456                                      info->info.rotation, info->info.connection,
457                                      info->info.drawable, info->info.visual,
458                                      info->info.colormap,
459                                      info->info.depth, info->info.debug,
460                                      info->info.alloc_grayscale,
461                                      info->info.alloc_colors_max,
462                                      info->info.mask, info->info.shape_dither,
463                                      info->info.destination_alpha);
464
465              re->outbuf_free = evas_software_xlib_outbuf_free;
466              re->outbuf_reconfigure = evas_software_xlib_outbuf_reconfigure;
467              re->outbuf_get_rot = evas_software_xlib_outbuf_get_rot;
468              re->outbuf_new_region_for_update = 
469                evas_software_xlib_outbuf_new_region_for_update;
470              re->outbuf_push_updated_region = 
471                evas_software_xlib_outbuf_push_updated_region;
472              re->outbuf_free_region_for_update = 
473                evas_software_xlib_outbuf_free_region_for_update;
474              re->outbuf_flush = evas_software_xlib_outbuf_flush;
475              re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush;
476              re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get;
477 # ifdef EVAS_FRAME_QUEUING
478              re->outbuf_set_priv = evas_software_xlib_outbuf_set_priv;
479              re->render_mode = info->render_mode;
480 # endif
481           }
482 #endif
483
484 #ifdef BUILD_ENGINE_SOFTWARE_XCB
485         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
486           {
487              re = _output_xcb_setup(e->output.w, e->output.h,
488                                     info->info.rotation, info->info.connection, 
489                                     info->info.screen, info->info.drawable, 
490                                     info->info.visual, info->info.colormap, 
491                                     info->info.depth, info->info.debug, 
492                                     info->info.alloc_grayscale,
493                                     info->info.alloc_colors_max,
494                                     info->info.mask, info->info.shape_dither,
495                                     info->info.destination_alpha);
496
497              re->outbuf_free = evas_software_xcb_outbuf_free;
498              re->outbuf_reconfigure = evas_software_xcb_outbuf_reconfigure;
499              re->outbuf_get_rot = evas_software_xcb_outbuf_rotation_get;
500              re->outbuf_new_region_for_update = 
501                evas_software_xcb_outbuf_new_region_for_update;
502              re->outbuf_push_updated_region = 
503                evas_software_xcb_outbuf_push_updated_region;
504              re->outbuf_free_region_for_update = 
505                evas_software_xcb_outbuf_free_region_for_update;
506              re->outbuf_flush = evas_software_xcb_outbuf_flush;
507              re->outbuf_idle_flush = evas_software_xcb_outbuf_idle_flush;
508              re->outbuf_alpha_get = evas_software_xcb_outbuf_alpha_get;
509 # ifdef EVAS_FRAME_QUEUING
510              re->outbuf_set_priv = evas_software_xcb_outbuf_priv_set;
511              re->render_mode = info->render_mode;
512 # endif
513           }
514 #endif
515
516         e->engine.data.output = re;
517      }
518    else
519      {
520         int ponebuf = 0;
521
522 #ifdef EVAS_FRAME_QUEUING
523         evas_common_frameq_flush();
524 #endif
525         re = e->engine.data.output;
526         ponebuf = re->ob->onebuf;
527
528 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
529         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
530           {
531              evas_software_xlib_outbuf_free(re->ob);
532              re->ob = 
533                evas_software_xlib_outbuf_setup_x(e->output.w, e->output.h,
534                                                  info->info.rotation,
535                                                  OUTBUF_DEPTH_INHERIT,
536                                                  info->info.connection,
537                                                  info->info.drawable,
538                                                  info->info.visual,
539                                                  info->info.colormap,
540                                                  info->info.depth,
541                                                  info->info.alloc_grayscale,
542                                                  info->info.alloc_colors_max,
543                                                  info->info.mask,
544                                                  info->info.shape_dither,
545                                                  info->info.destination_alpha);
546
547              evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug);
548 # ifdef EVAS_FRAME_QUEUING
549              re->render_mode = info->render_mode;
550 # endif
551           }
552 #endif
553
554 #ifdef BUILD_ENGINE_SOFTWARE_XCB
555         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
556           {
557              evas_software_xcb_outbuf_free(re->ob);
558              re->ob = 
559                evas_software_xcb_outbuf_setup(e->output.w, e->output.h,
560                                               info->info.rotation,
561                                               OUTBUF_DEPTH_INHERIT,
562                                               info->info.connection,
563                                               info->info.screen,
564                                               info->info.drawable,
565                                               info->info.visual,
566                                               info->info.colormap,
567                                               info->info.depth,
568                                               info->info.alloc_grayscale,
569                                               info->info.alloc_colors_max,
570                                               info->info.mask,
571                                               info->info.shape_dither,
572                                               info->info.destination_alpha);
573
574              evas_software_xcb_outbuf_debug_set(re->ob, info->info.debug);
575 #ifdef EVAS_FRAME_QUEUING
576              re->render_mode = info->render_mode;
577 #endif
578           }
579 #endif
580         re->ob->onebuf = ponebuf;
581      }
582    if (!e->engine.data.output) return 0;
583    if (!e->engine.data.context) 
584      {
585         e->engine.data.context = 
586           e->engine.func->context_new(e->engine.data.output);
587      }
588
589    re = e->engine.data.output;
590
591    return 1;
592 }
593
594 static void
595 eng_output_free(void *data)
596 {
597    Render_Engine *re;
598
599 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
600 // NOTE: XrmGetDatabase() result is shared per connection, do not free it.
601 //   if (re->xrdb) XrmDestroyDatabase(re->xrdb);
602 #endif
603
604    if ((re = (Render_Engine *)data))
605      {
606         re->outbuf_free(re->ob);
607         evas_common_tilebuf_free(re->tb);
608         if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
609         free(re);
610      }
611
612    evas_common_font_shutdown();
613    evas_common_image_shutdown();
614 }
615
616 static void
617 eng_output_resize(void *data, int w, int h)
618 {
619    Render_Engine *re;
620
621    re = (Render_Engine *)data;
622    re->outbuf_reconfigure(re->ob, w, h, re->outbuf_get_rot(re->ob),
623                           OUTBUF_DEPTH_INHERIT);
624    evas_common_tilebuf_free(re->tb);
625    re->tb = evas_common_tilebuf_new(w, h);
626    if (re->tb)
627      evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
628 }
629
630 static void
631 eng_output_tile_size_set(void *data, int w, int h)
632 {
633    Render_Engine *re;
634
635    re = (Render_Engine *)data;
636    evas_common_tilebuf_set_tile_size(re->tb, w, h);
637 }
638
639 static void
640 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
641 {
642    Render_Engine *re;
643
644    re = (Render_Engine *)data;
645    evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
646 }
647
648 static void
649 eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
650 {
651    Render_Engine *re;
652
653    re = (Render_Engine *)data;
654    evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
655 }
656
657 static void
658 eng_output_redraws_clear(void *data)
659 {
660    Render_Engine *re;
661
662    re = (Render_Engine *)data;
663    evas_common_tilebuf_clear(re->tb);
664 }
665
666 static void *
667 eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
668 {
669    Render_Engine *re;
670    RGBA_Image *surface;
671    Tilebuf_Rect *rect;
672    int ux, uy, uw, uh;
673
674    re = (Render_Engine *)data;
675    if (re->end)
676      {
677         re->end = 0;
678         return NULL;
679      }
680    if (!re->rects)
681      {
682         re->rects = evas_common_tilebuf_get_render_rects(re->tb);
683         re->cur_rect = EINA_INLIST_GET(re->rects);
684      }
685    if (!re->cur_rect) return NULL;
686    rect = (Tilebuf_Rect *)re->cur_rect;
687    ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
688    re->cur_rect = re->cur_rect->next;
689    if (!re->cur_rect)
690      {
691         evas_common_tilebuf_free_render_rects(re->rects);
692         re->rects = NULL;
693         re->end = 1;
694      }
695
696    surface = 
697      re->outbuf_new_region_for_update(re->ob, ux, uy, uw, uh, cx, cy, cw, ch);
698
699    *x = ux; *y = uy; *w = uw; *h = uh;
700    return surface;
701 }
702
703 static void
704 eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
705 {
706    Render_Engine *re;
707 #ifdef EVAS_FRAME_QUEUING
708    Evas_Surface *e_surface;
709 #endif
710
711    re = (Render_Engine *)data;
712 #if defined(BUILD_PIPE_RENDER) && !defined(EVAS_FRAME_QUEUING)
713    evas_common_pipe_map_begin(surface);
714 #endif /* BUILD_PIPE_RENDER  && !EVAS_FRAME_QUEUING*/
715
716 #ifdef EVAS_FRAME_QUEUING
717    if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
718      {
719         /* create a new frame if this is the first surface of this frame */
720         evas_common_frameq_prepare_frame();
721         /* add surface into the frame */
722         e_surface = evas_common_frameq_new_surface(surface, x, y, w, h);
723         evas_common_frameq_add_surface(e_surface);
724         return;
725      }
726 #endif
727
728    re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
729    re->outbuf_free_region_for_update(re->ob, surface);
730    evas_common_cpu_end_opt();
731 }
732
733 #ifdef EVAS_FRAME_QUEUING
734 static void *
735 eng_image_map_surface_new(void *data , int w, int h, int alpha)
736 {
737    void *surface;
738    DATA32 *pixels;
739    Render_Engine *re;
740    Evas_Surface *e_surface;
741
742    re = (Render_Engine *)data;
743
744    surface = 
745      evas_cache_image_copied_data(evas_common_image_cache_get(), w, h, NULL, 
746                                   alpha, EVAS_COLORSPACE_ARGB8888);
747    pixels = evas_cache_image_pixels(surface);
748
749    if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
750      {
751         /* create a new frame if this is the first surface of this frame */
752         evas_common_frameq_prepare_frame();
753
754         /* add surface into the frame */
755         e_surface = evas_common_frameq_new_surface(surface, 0, 0, w, h);
756
757         /* this surface is not going to be pushed to screen */
758         e_surface->dontpush = 1;
759         evas_common_frameq_add_surface(e_surface);
760      }
761    return surface;
762 }
763
764 static void
765 eng_output_frameq_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
766 {
767    Render_Engine *re;
768
769    re = (Render_Engine *)data;
770    re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
771    re->outbuf_free_region_for_update(re->ob, surface);
772    evas_common_cpu_end_opt();
773 }
774
775 static void
776 eng_output_frameq_flush(void *data)
777 {
778    Render_Engine *re;
779
780    re = (Render_Engine *)data;
781    re->outbuf_flush(re->ob);
782 }
783
784 static void
785 eng_output_frameq_set_priv(void *data, void *cur, void *prev)
786 {
787    Render_Engine *re;
788
789    re = (Render_Engine *)data;
790    re->outbuf_set_priv(re->ob, cur, prev);
791 }
792 #endif
793
794 static void
795 eng_output_flush(void *data)
796 {
797    Render_Engine *re;
798
799    re = (Render_Engine *)data;
800 #ifdef EVAS_FRAME_QUEUING
801    if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
802      {
803         evas_common_frameq_set_frame_data(data,
804                                           eng_output_frameq_redraws_next_update_push,
805                                           eng_output_frameq_flush,
806                                           eng_output_frameq_set_priv);
807         evas_common_frameq_ready_frame();
808         evas_common_frameq_begin();
809      } 
810    else
811 #endif
812      re->outbuf_flush(re->ob);
813 }
814
815 static void
816 eng_output_idle_flush(void *data)
817 {
818    Render_Engine *re;
819
820    re = (Render_Engine *)data;
821    re->outbuf_idle_flush(re->ob);
822 }
823
824 static Eina_Bool
825 eng_canvas_alpha_get(void *data, void *context __UNUSED__)
826 {
827    Render_Engine *re;
828
829    re = (Render_Engine *)data;
830    return (re->ob->priv.destination_alpha) || (re->outbuf_alpha_get(re->ob));
831 }
832
833
834 /* module advertising code */
835 static int
836 module_open(Evas_Module *em)
837 {
838 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
839    static Eina_Bool xrm_inited = EINA_FALSE;
840
841    if (!xrm_inited)
842      {
843         xrm_inited = EINA_TRUE;
844         XrmInitialize();
845      }
846 #endif
847
848    if (!em) return 0;
849
850    /* get whatever engine module we inherit from */
851    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
852
853    _evas_engine_soft_x11_log_dom = 
854      eina_log_domain_register("evas-software_x11", EVAS_DEFAULT_LOG_COLOR);
855
856    if (_evas_engine_soft_x11_log_dom < 0)
857      {
858         EINA_LOG_ERR("Can not create a module log domain.");
859         return 0;
860      }
861
862    /* store it for later use */
863    func = pfunc;
864
865    /* now to override methods */
866 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
867    ORD(info);
868    ORD(info_free);
869    ORD(setup);
870    ORD(canvas_alpha_get);
871    ORD(output_free);
872    ORD(output_resize);
873    ORD(output_tile_size_set);
874    ORD(output_redraws_rect_add);
875    ORD(output_redraws_rect_del);
876    ORD(output_redraws_clear);
877    ORD(output_redraws_next_update_get);
878    ORD(output_redraws_next_update_push);
879    ORD(output_flush);
880    ORD(output_idle_flush);
881 #ifdef EVAS_FRAME_QUEUING
882    ORD(image_map_surface_new);
883 #endif
884
885    /* now advertise out own api */
886    em->functions = (void *)(&func);
887    return 1;
888 }
889
890 static void
891 module_close(Evas_Module *em __UNUSED__)
892 {
893   eina_log_domain_unregister(_evas_engine_soft_x11_log_dom);
894 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
895   if (xrdb_user.db)
896     {
897        XrmDestroyDatabase(xrdb_user.db);
898        xrdb_user.last_stat = 0;
899        xrdb_user.last_mtime = 0;
900        xrdb_user.db = NULL;
901     }
902 #endif
903 }
904
905 static Evas_Module_Api evas_modapi =
906 {
907    EVAS_MODULE_API_VERSION, "software_x11", "none",
908    {
909      module_open,
910      module_close
911    }
912 };
913
914 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_x11);
915
916 #ifndef EVAS_STATIC_BUILD_SOFTWARE_X11
917 EVAS_EINA_MODULE_DEFINE(engine, software_x11);
918 #endif