move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / xrender_xcb / evas_engine.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3 #include "evas_engine.h"
4 #include "Evas_Engine_XRender_Xcb.h"
5
6 /* function tables - filled in later (func and parent func) */
7 static Evas_Func func, pfunc;
8
9 /* engine struct data */
10 typedef struct _Render_Engine        Render_Engine;
11 typedef struct _Render_Engine_Update Render_Engine_Update;
12
13 struct _Render_Engine_Update
14 {
15    int                 x;
16    int                 y;
17    int                 w;
18    int                 h;
19    Xcb_Render_Surface *surface;
20 };
21
22 struct _Render_Engine
23 {
24    xcb_connection_t      *conn;
25    xcb_visualid_t         vis;
26    xcb_drawable_t         win;
27    xcb_pixmap_t           mask;
28    unsigned char          destination_alpha : 1;
29
30    Xcb_Image_Info        *xcbinf;
31    Xcb_Render_Surface    *output;
32    Xcb_Render_Surface    *mask_output;
33
34    Tilebuf               *tb;
35    Tilebuf_Rect          *rects;
36    Evas_Object_List      *cur_rect;
37    int                    end : 1;
38
39    Evas_List             *updates;
40 };
41
42 /* internal engine routines */
43
44 /* engine api this module provides */
45
46 static void *
47 eng_info(Evas *e)
48 {
49    Evas_Engine_Info_XRender_Xcb *info;
50
51    info = calloc(1, sizeof(Evas_Engine_Info_XRender_Xcb));
52    if (!info) return NULL;
53    info->magic.magic = rand();
54    return info;
55    e = NULL;
56 }
57
58 static void
59 eng_info_free(Evas *e, void *info)
60 {
61    Evas_Engine_Info_XRender_Xcb *in;
62
63    in = (Evas_Engine_Info_XRender_Xcb *)info;
64    free(in);
65 }
66 static void
67 eng_setup(Evas *e, void *in)
68 {
69    Render_Engine *re;
70    Evas_Engine_Info_XRender_Xcb *info;
71    int resize = 1;
72
73    info = (Evas_Engine_Info_XRender_Xcb *)in;
74    if (!e->engine.data.output)
75      {
76         re = calloc(1, sizeof(Render_Engine));
77         evas_common_cpu_init();
78         evas_common_blend_init();
79         evas_common_image_init();
80         evas_common_convert_init();
81         evas_common_scale_init();
82         evas_common_rectangle_init();
83         evas_common_gradient_init();
84         evas_common_polygon_init();
85         evas_common_line_init();
86         evas_common_font_init();
87         evas_common_draw_init();
88         evas_common_tilebuf_init();
89         re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
90         if (re->tb)
91           evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
92         e->engine.data.output = re;
93         resize = 0;
94      }
95    re = e->engine.data.output;
96    if (!re) return;
97
98    if (!e->engine.data.context) e->engine.data.context = e->engine.func->context_new(e->engine.data.output);
99
100    re->conn = info->info.conn;
101    re->vis = info->info.visual;
102    re->win = info->info.drawable;
103    re->mask = info->info.mask;
104    re->destination_alpha = info->info.destination_alpha;
105
106    if (re->xcbinf) _xr_image_info_free(re->xcbinf);
107    re->xcbinf = _xr_image_info_get(re->conn, re->win, re->vis);
108
109    if (re->output) _xr_render_surface_free(re->output);
110    if (re->mask_output) _xr_render_surface_free(re->mask_output);
111    if (!re->mask)
112      re->output = _xr_render_surface_adopt(re->xcbinf, re->win, e->output.w, e->output.h, re->destination_alpha);
113    else
114      re->output = _xr_render_surface_adopt(re->xcbinf, re->win, e->output.w, e->output.h, 0);
115    if (re->mask) {
116      xcb_drawable_t draw;
117
118      draw = re->mask;
119      re->mask_output = _xr_render_surface_format_adopt(re->xcbinf, draw,
120                                                       e->output.w, e->output.h,
121                                                       re->xcbinf->fmt1, 1);
122    }
123    else
124      re->mask_output = NULL;
125    if (resize)
126      {
127         if (re->tb) evas_common_tilebuf_free(re->tb);
128         if ((e->output.w > 0) && (e->output.h > 0))
129           re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
130         else
131           re->tb = evas_common_tilebuf_new(1, 1);
132         if (re->tb)
133           evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
134      }
135 }
136
137 static void
138 eng_output_free(void *data)
139 {
140    Render_Engine *re;
141
142    re = (Render_Engine *)data;
143    evas_common_font_shutdown();
144    evas_common_image_shutdown();
145    while (re->updates)
146      {
147         Render_Engine_Update *reu;
148
149         reu = re->updates->data;
150         re->updates = evas_list_remove_list(re->updates, re->updates);
151         _xr_render_surface_free(reu->surface);
152         free(reu);
153      }
154    if (re->tb) evas_common_tilebuf_free(re->tb);
155    if (re->output) _xr_render_surface_free(re->output);
156    if (re->mask_output) _xr_render_surface_free(re->mask_output);
157    if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
158    if (re->xcbinf) _xr_image_info_free(re->xcbinf);
159    free(re);
160 }
161
162 static void
163 eng_output_resize(void *data, int w, int h)
164 {
165    Render_Engine *re;
166
167    re = (Render_Engine *)data;
168    if (re->output)
169      {
170         if ((re->output->w == w) && (re->output->h ==h)) return;
171         if (re->output) _xr_render_surface_free(re->output);
172      }
173    re->output = _xr_render_surface_adopt(re->xcbinf, re->win, w, h, 0);
174    if (re->mask_output)
175      {
176         xcb_drawable_t draw;
177
178         if (re->mask_output) _xr_render_surface_free(re->mask_output);
179         draw = re->mask;
180         re->mask_output = _xr_render_surface_format_adopt(re->xcbinf, draw,
181                                                           w, h,
182                                                           re->xcbinf->fmt1, 1);
183      }
184    evas_common_tilebuf_free(re->tb);
185    re->tb = evas_common_tilebuf_new(w, h);
186    if (re->tb) evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
187 }
188
189 static void
190 eng_output_tile_size_set(void *data, int w, int h)
191 {
192    Render_Engine *re;
193
194    re = (Render_Engine *)data;
195    evas_common_tilebuf_set_tile_size(re->tb, w, h);
196 }
197
198 static void
199 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
200 {
201    Render_Engine *re;
202
203    re = (Render_Engine *)data;
204    evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
205 }
206
207 static void
208 eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
209 {
210    Render_Engine *re;
211
212    re = (Render_Engine *)data;
213    evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
214 }
215
216 static void
217 eng_output_redraws_clear(void *data)
218 {
219    Render_Engine *re;
220
221    re = (Render_Engine *)data;
222    evas_common_tilebuf_clear(re->tb);
223 }
224
225 static void *
226 eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
227 {
228    Render_Engine *re;
229    Tilebuf_Rect *rect;
230    int ux, uy, uw, uh;
231
232    re = (Render_Engine *)data;
233    if (re->end)
234      {
235         re->end = 0;
236         return NULL;
237      }
238    if (!re->rects)
239      {
240         re->rects = evas_common_tilebuf_get_render_rects(re->tb);
241         re->cur_rect = (Evas_Object_List *)re->rects;
242      }
243    if (!re->cur_rect) return NULL;
244    rect = (Tilebuf_Rect *)re->cur_rect;
245    ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
246    re->cur_rect = re->cur_rect->next;
247    if (!re->cur_rect)
248      {
249         evas_common_tilebuf_free_render_rects(re->rects);
250         re->rects = NULL;
251         re->end = 1;
252      }
253
254    *x = ux; *y = uy; *w = uw; *h = uh;
255    *cx = 0; *cy = 0; *cw = uw; *ch = uh;
256    if ((re->destination_alpha) || (re->mask))
257      {
258         Xcb_Render_Surface *surface;
259
260         surface = _xr_render_surface_new(re->xcbinf, uw, uh, re->xcbinf->fmt32, 1);
261         _xr_render_surface_solid_rectangle_set(surface, 0, 0, 0, 0, 0, 0, uw, uh);
262         return surface;
263      }
264    return _xr_render_surface_new(re->xcbinf, uw, uh, re->xcbinf->fmt24, 0);
265 }
266
267 static void
268 eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
269 {
270    Render_Engine        *re;
271    Render_Engine_Update *reu;
272
273    re = (Render_Engine *)data;
274    reu = malloc(sizeof(Render_Engine_Update));
275    if (!reu) return;
276    reu->x = x;
277    reu->y = y;
278    reu->w = w;
279    reu->h = h;
280    reu->surface = (Xcb_Render_Surface *)surface;
281    re->updates = evas_list_append(re->updates, reu);
282 }
283
284 static void
285 eng_output_flush(void *data)
286 {
287    Render_Engine               *re;
288    xcb_get_input_focus_reply_t *reply;
289
290    re = (Render_Engine *)data;
291    while (re->updates)
292      {
293         Render_Engine_Update *reu;
294
295         reu = re->updates->data;
296         re->updates = evas_list_remove_list(re->updates, re->updates);
297         if (re->mask_output)
298           {
299              Xcb_Render_Surface *tsurf;
300
301              _xr_render_surface_copy(reu->surface, re->output, 0, 0,
302                                      reu->x, reu->y, reu->w, reu->h);
303              tsurf = _xr_render_surface_new(re->xcbinf, reu->w, reu->h, re->xcbinf->fmt1, 1);
304              if (tsurf)
305                {
306                   _xr_render_surface_copy(reu->surface, tsurf, 0, 0,
307                                           0, 0, reu->w, reu->h);
308                   _xr_render_surface_copy(tsurf, re->mask_output, 0, 0,
309                                           reu->x, reu->y, reu->w, reu->h);
310                   _xr_render_surface_free(tsurf);
311                }
312           }
313         else
314           {
315              _xr_render_surface_copy(reu->surface, re->output, 0, 0,
316                                      reu->x, reu->y, reu->w, reu->h);
317           }
318         _xr_render_surface_free(reu->surface);
319         free(reu);
320      }
321    /* we sync */
322    reply = xcb_get_input_focus_reply(re->conn,
323                                      xcb_get_input_focus_unchecked(re->conn),
324                                      NULL);
325    free(reply);
326    _xr_image_info_pool_flush(re->xcbinf, 0, 0);
327 }
328
329 static void
330 eng_output_idle_flush(void *data)
331 {
332    Render_Engine               *re;
333
334    re = (Render_Engine *)data;
335 }
336
337 static void
338 eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
339 {
340    _xr_render_surface_rectangle_draw((Xcb_Render_Surface *)surface,
341                                      (RGBA_Draw_Context *)context,
342                                      x, y, w, h);
343 }
344
345 static void
346 eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
347 {
348    _xr_render_surface_line_draw((Xcb_Render_Surface *)surface, (RGBA_Draw_Context *)context, x1, y1, x2, y2);
349 }
350
351 static void
352 eng_polygon_draw(void *data, void *context, void *surface, void *polygon)
353 {
354    _xre_poly_draw((Xcb_Render_Surface *)surface, (RGBA_Draw_Context *)context, (RGBA_Polygon_Point *)polygon);
355 }
356
357 static void *
358 eng_gradient_new(void *data)
359 {
360    Render_Engine *re = (Render_Engine *)data;
361
362    return _xre_gradient_new(re->xcbinf);
363 }
364
365 static void
366 eng_gradient_free(void *data, void *gradient)
367 {
368    _xre_gradient_free(gradient);
369 }
370
371 static void
372 eng_gradient_color_stop_add(void *data, void *gradient, int r, int g, int b, int a, int delta)
373 {
374    _xre_gradient_color_stop_add(gradient, r, g, b, a, delta);
375 }
376
377 static void
378 eng_gradient_alpha_stop_add(void *data, void *gradient, int a, int delta)
379 {
380    _xre_gradient_alpha_stop_add(gradient, a, delta);
381 }
382
383 static void
384 eng_gradient_color_data_set(void *data, void *gradient, void *map, int len, int has_alpha)
385 {
386    _xre_gradient_color_data_set(gradient, map, len, has_alpha);
387 }
388
389 static void
390 eng_gradient_alpha_data_set(void *data, void *gradient, void *alpha_map, int len)
391 {
392    _xre_gradient_alpha_data_set(gradient, alpha_map, len);
393 }
394
395 static void
396 eng_gradient_clear(void *data, void *gradient)
397 {
398    _xre_gradient_clear(gradient);
399 }
400
401 static void
402 eng_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h)
403 {
404    _xre_gradient_fill_set(gradient, x, y, w, h);
405 }
406
407 static void
408 eng_gradient_fill_angle_set(void *data, void *gradient, double angle)
409 {
410    _xre_gradient_fill_angle_set(gradient, angle);
411 }
412
413 static void
414 eng_gradient_fill_spread_set(void *data, void *gradient, int spread)
415 {
416    _xre_gradient_fill_spread_set(gradient, spread);
417 }
418
419 static void
420 eng_gradient_angle_set(void *data, void *gradient, double angle)
421 {
422    _xre_gradient_angle_set(gradient, angle);
423 }
424
425 static void
426 eng_gradient_offset_set(void *data, void *gradient, float offset)
427 {
428    _xre_gradient_offset_set(gradient, offset);
429 }
430
431 static void
432 eng_gradient_direction_set(void *data, void *gradient, int direction)
433 {
434    _xre_gradient_direction_set(gradient, direction);
435 }
436
437 static void
438 eng_gradient_type_set(void *data, void *gradient, char *name, char *params)
439 {
440    _xre_gradient_type_set(gradient, name, params);
441 }
442
443 static int
444 eng_gradient_is_opaque(void *data, void *context, void *gradient, int x, int y, int w, int h)
445 {
446    RGBA_Gradient     *grad;
447    RGBA_Draw_Context *dc = (RGBA_Draw_Context *)context;
448
449    if (!dc || !gradient) return 0;
450    grad = ((XR_Gradient *)gradient)->grad;
451    if(!grad || !grad->type.geometer)  return 0;
452    return !(grad->type.geometer->has_alpha(grad, dc->render_op) |
453             grad->type.geometer->has_mask(grad, dc->render_op));
454 }
455
456 static int
457 eng_gradient_is_visible(void *data, void *context, void *gradient, int x, int y, int w, int h)
458 {
459    if (!context || !gradient)  return 0;
460    return 1;
461 }
462
463 static void
464 eng_gradient_render_pre(void *data, void *context, void *gradient)
465 {
466    int             len;
467    RGBA_Gradient  *grad;
468
469    if (!context || !gradient) return;
470    grad = ((XR_Gradient *)gradient)->grad;
471    if(!grad || !grad->type.geometer)  return;
472    grad->type.geometer->geom_set(grad);
473    len = grad->type.geometer->get_map_len(grad);
474    evas_common_gradient_map(context, grad, len);
475 }
476
477 static void
478 eng_gradient_render_post(void *data, void *gradient)
479 {
480 }
481
482 static void
483 eng_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h)
484 {
485    _xre_gradient_draw(surface, context, gradient, x, y, w, h);
486 }
487
488 static void *
489 eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
490 {
491    Render_Engine *re;
492    XR_Image      *im;
493
494    re = (Render_Engine *)data;
495    *error = 0;
496    im = _xre_image_load(re->xcbinf, file, key, lo);
497    return im;
498 }
499
500 static void *
501 eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
502 {
503    Render_Engine *re;
504    XR_Image      *im;
505
506    re = (Render_Engine *)data;
507    im = _xre_image_new_from_data(re->xcbinf, w, h, image_data);
508    return im;
509 }
510
511 static void *
512 eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
513 {
514    Render_Engine *re;
515    XR_Image      *im;
516
517    re = (Render_Engine *)data;
518    im = _xre_image_new_from_copied_data(re->xcbinf, w, h, image_data);
519    return im;
520 }
521
522 static void
523 eng_image_free(void *data, void *image)
524 {
525    if (!image) return;
526    _xre_image_free((XR_Image *)image);
527 }
528
529 static void
530 eng_image_size_get(void *data, void *image, int *w, int *h)
531 {
532    if (!image) return;
533    if (w) *w = ((XR_Image *)image)->w;
534    if (h) *h = ((XR_Image *)image)->h;
535 }
536
537 static void *
538 eng_image_size_set(void *data, void *image, int w, int h)
539 {
540    if (!image) return image;
541    if ((w <= 0) || (h <= 0))
542      {
543         _xre_image_free((XR_Image *)image);
544         return NULL;
545      }
546    if (((XR_Image *)image)->references > 1)
547      {
548         XR_Image *old_image;
549
550         old_image = (XR_Image *)image;
551         image = _xre_image_copy((XR_Image *)old_image);
552         if (image)
553           {
554              ((XR_Image *)image)->alpha = old_image->alpha;
555              _xre_image_free(old_image);
556           }
557         else
558           image = old_image;
559      }
560    else
561      _xre_image_dirty((XR_Image *)image);
562    _xre_image_resize((XR_Image *)image, w, h);
563    return image;
564 }
565
566 static void *
567 eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
568 {
569    if (!image) return image;
570    _xre_image_dirty((XR_Image *)image);
571    _xre_image_region_dirty((XR_Image *)image, x, y, w, h);
572    return image;
573 }
574
575 static void *
576 eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data)
577 {
578    if (!image) return image;
579    if (to_write)
580      {
581         if (((XR_Image *)image)->references > 1)
582           {
583              XR_Image *old_image;
584
585              old_image = (XR_Image *)image;
586              image = _xre_image_copy((XR_Image *)old_image);
587              if (image)
588                {
589                   ((XR_Image *)image)->alpha = old_image->alpha;
590                   _xre_image_free(old_image);
591                }
592              else
593                image = old_image;
594           }
595         else
596           _xre_image_dirty((XR_Image *)image);
597      }
598    if (image_data) *image_data = _xre_image_data_get((XR_Image *)image);
599    return image;
600 }
601
602 static void *
603 eng_image_data_put(void *data, void *image, DATA32 *image_data)
604 {
605    if (!image) return image;
606    if (_xre_image_data_get((XR_Image *)image) != image_data)
607      {
608         XR_Image *old_image;
609
610         old_image = (XR_Image *)image;
611         image = _xre_image_data_find(image_data);
612         if (image != old_image)
613           {
614              if (!image)
615                {
616                   image = _xre_image_new_from_data(old_image->xcbinf, old_image->w, old_image->h, image_data);
617                   if (image)
618                     {
619                        ((XR_Image *)image)->alpha = old_image->alpha;
620                        _xre_image_free(old_image);
621                     }
622                   else
623                     image = old_image;
624                }
625              else
626                {
627                   _xre_image_free(old_image);
628                }
629           }
630         else
631           {
632              _xre_image_free(image);
633           }
634      }
635    return image;
636 }
637
638 static void *
639 eng_image_alpha_set(void *data, void *image, int has_alpha)
640 {
641    if (!image) return image;
642    if (((((XR_Image *)image)->alpha) && (has_alpha)) ||
643        ((!((XR_Image *)image)->alpha) && (!has_alpha)))
644      return image;
645    if (((XR_Image *)image)->references > 1)
646      {
647         XR_Image *old_image;
648
649         old_image = (XR_Image *)image;
650         image = _xre_image_copy((XR_Image *)old_image);
651         if (image)
652           {
653              ((XR_Image *)image)->alpha = old_image->alpha;
654              _xre_image_free(old_image);
655           }
656         else
657           image = old_image;
658      }
659    else
660      _xre_image_dirty((XR_Image *)image);
661    _xre_image_alpha_set((XR_Image *)image, has_alpha);
662    return image;
663 }
664
665 static int
666 eng_image_alpha_get(void *data, void *image)
667 {
668    if (!image) return 0;
669    return _xre_image_alpha_get((XR_Image *)image);
670 }
671
672 static void *
673 eng_image_border_set(void *data, void *image, int l, int r, int t, int b)
674 {
675    if (!image) return image;
676    _xre_image_border_set((XR_Image *)image, l, r, t, b);
677    return image;
678 }
679
680 static void
681 eng_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b)
682 {
683    if (!image) return;
684    _xre_image_border_get((XR_Image *)image, l, r, t, b);
685 }
686
687 static void
688 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
689 {
690    if ((!image) || (!surface)) return;
691    _xre_image_surface_gen((XR_Image *)image);
692    if (((XR_Image *)image)->surface)
693      _xr_render_surface_composite(((XR_Image *)image)->surface,
694                                   (Xcb_Render_Surface *)surface,
695                                   (RGBA_Draw_Context *)context,
696                                   src_x, src_y, src_w, src_h,
697                                   dst_x, dst_y, dst_w, dst_h,
698                                   smooth);
699 }
700
701 static const char *
702 eng_image_comment_get(void *data, void *image, char *key)
703 {
704    if (!image) return NULL;
705    return ((XR_Image *)image)->comment;
706 }
707
708 static char *
709 eng_image_format_get(void *data, void *image)
710 {
711    if (!image) return NULL;
712    return ((XR_Image *)image)->format;
713 }
714
715 static void
716 eng_image_colorspace_set(void *data, void *image, int cspace)
717 {
718 }
719
720 static int
721 eng_image_colorspace_get(void *data, void *image)
722 {
723    return EVAS_COLORSPACE_ARGB8888;
724 }
725
726 static void
727 eng_image_native_set(void *data, void *image, void *native)
728 {
729 }
730
731 static void *
732 eng_image_native_get(void *data, void *image)
733 {
734    return NULL;
735 }
736
737 static void
738 eng_image_cache_flush(void *data)
739 {
740    int tmp_size;
741
742    tmp_size = _xre_image_cache_get();
743    pfunc.image_cache_flush(data);
744    _xre_image_cache_set(0);
745    _xre_image_cache_set(tmp_size);
746 }
747
748 static void
749 eng_image_cache_set(void *data, int bytes)
750 {
751    pfunc.image_cache_set(data, bytes);
752    _xre_image_cache_set(bytes);
753 }
754
755 static int
756 eng_image_cache_get(void *data)
757 {
758    return pfunc.image_cache_get(data);
759 }
760
761 static void
762 eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text)
763 {
764    Render_Engine        *re;
765    RGBA_Image           *im;
766
767    re = (Render_Engine *)data;
768
769    im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
770                                              ((Xcb_Render_Surface *)surface)->w,
771                                              ((Xcb_Render_Surface *)surface)->h,
772                                              surface,
773                                              0, EVAS_COLORSPACE_ARGB8888);
774
775    _xr_render_surface_clips_set((Xcb_Render_Surface *)surface, (RGBA_Draw_Context *)context, x, y, w, h);
776
777    evas_common_draw_context_font_ext_set(context,
778                                          re->xcbinf,
779                                          _xre_font_surface_new,
780                                          _xre_font_surface_free,
781                                          _xre_font_surface_draw);
782    evas_common_font_draw(im, context, font, x, y, text);
783    evas_common_draw_context_font_ext_set(context,
784                                          NULL,
785                                          NULL,
786                                          NULL,
787                                          NULL);
788    evas_common_cpu_end_opt();
789 }
790
791 /* module advertising code */
792 EAPI int
793 module_open(Evas_Module *em)
794 {
795    if (!em) return 0;
796    /* get whatever engine module we inherit from */
797    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
798    /* store it for later use */
799    func = pfunc;
800    /* now to override methods */
801 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
802    ORD(info);
803    ORD(info_free);
804    ORD(setup);
805    ORD(output_free);
806    ORD(output_resize);
807    ORD(output_tile_size_set);
808    ORD(output_redraws_rect_add);
809    ORD(output_redraws_rect_del);
810    ORD(output_redraws_clear);
811    ORD(output_redraws_next_update_get);
812    ORD(output_redraws_next_update_push);
813    ORD(output_flush);
814    ORD(output_idle_flush);
815    ORD(rectangle_draw);
816    ORD(line_draw);
817    ORD(polygon_draw);
818    ORD(gradient_new);
819    ORD(gradient_free);
820    ORD(gradient_color_stop_add);
821    ORD(gradient_alpha_stop_add);
822    ORD(gradient_color_data_set);
823    ORD(gradient_alpha_data_set);
824    ORD(gradient_clear);
825    ORD(gradient_fill_set);
826    ORD(gradient_fill_angle_set);
827    ORD(gradient_fill_spread_set);
828    ORD(gradient_angle_set);
829    ORD(gradient_offset_set);
830    ORD(gradient_direction_set);
831    ORD(gradient_type_set);
832    ORD(gradient_is_opaque);
833    ORD(gradient_is_visible);
834    ORD(gradient_render_pre);
835    ORD(gradient_render_post);
836    ORD(gradient_draw);
837    ORD(image_load);
838    ORD(image_new_from_data);
839    ORD(image_new_from_copied_data);
840    ORD(image_free);
841    ORD(image_size_get);
842    ORD(image_size_set);
843    ORD(image_dirty_region);
844    ORD(image_data_get);
845    ORD(image_data_put);
846    ORD(image_alpha_set);
847    ORD(image_alpha_get);
848    ORD(image_border_set);
849    ORD(image_border_get);
850    ORD(image_draw);
851    ORD(image_comment_get);
852    ORD(image_format_get);
853    ORD(image_colorspace_set);
854    ORD(image_colorspace_get);
855    ORD(image_native_set);
856    ORD(image_native_get);
857    ORD(image_cache_flush);
858    ORD(image_cache_set);
859    ORD(image_cache_get);
860    ORD(font_draw);
861    /* now advertise out own api */
862    em->functions = (void *)(&func);
863    return 1;
864 }
865
866 EAPI void
867 module_close(void)
868 {
869 }
870
871 EAPI Evas_Module_Api evas_modapi =
872 {
873    EVAS_MODULE_API_VERSION,
874      EVAS_MODULE_TYPE_ENGINE,
875      "xrender_xcb",
876      "none"
877 };