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