1 #include "evas_common.h"
2 #include "evas_engine.h"
3 #include "evas_macros.h"
5 #include <sys/utsname.h>
7 static Evas_List *shmpool = NULL;
8 static int shmsize = 0;
9 static int shmmemlimit = 10 * 1024 * 1024;
10 static int shmcountlimit = 32;
11 static X_Output_Buffer *
12 _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
15 X_Output_Buffer *xob = NULL;
16 int fitness = 0x7fffffff;
19 // return evas_software_x11_x_output_buffer_new(d, v, depth, w, h, shm, data);
21 return evas_software_x11_x_output_buffer_new(d, v, depth, w, h, shm, data);
25 if (bpp == 3) bpp = 4;
26 lbytes = (((w * bpp) + 3) / 4) * 4;
29 lbytes = ((w + 31) / 32) * 4;
31 for (l = shmpool; l; l = l->next)
33 X_Output_Buffer *xob2;
37 if ((xob2->xim->depth != depth) || (xob2->visual != v) ||
40 szdif = xob2->psize - sz;
41 if (szdif < 0) continue;
55 if ((fitness > (100 * 100)) || (!xob))
56 return evas_software_x11_x_output_buffer_new(d, v, depth, w, h, shm, data);
59 shmpool = evas_list_remove_list(shmpool, xl);
63 xob->xim->width = xob->w;
64 xob->xim->height = xob->h;
65 xob->xim->bytes_per_line = xob->bpl;
66 shmsize -= xob->psize * (xob->xim->depth / 8);
71 _unfind_xob(X_Output_Buffer *xob, int sync)
73 // evas_software_x11_x_output_buffer_free(xob, sync); return;
76 shmpool = evas_list_prepend(shmpool, xob);
77 shmsize += xob->psize * xob->xim->depth / 8;
78 while ((shmsize > (shmmemlimit)) ||
79 (evas_list_count(shmpool) > shmcountlimit))
83 xl = evas_list_last(shmpool);
90 shmpool = evas_list_remove_list(shmpool, xl);
91 evas_software_x11_x_output_buffer_free(xob, sync);
95 evas_software_x11_x_output_buffer_free(xob, sync);
103 X_Output_Buffer *xob;
106 shmpool = evas_list_remove_list(shmpool, shmpool);
107 evas_software_x11_x_output_buffer_free(xob, sync);
113 evas_software_x11_outbuf_init(void)
118 evas_software_x11_outbuf_free(Outbuf *buf)
120 while (buf->priv.pending_writes)
125 im = buf->priv.pending_writes->data;
126 buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes);
127 obr = im->extended_info;
128 evas_cache_image_drop(&im->cache_entry);
129 if (obr->xob) _unfind_xob(obr->xob, 0);
130 if (obr->mxob) _unfind_xob(obr->mxob, 0);
133 evas_software_x11_outbuf_idle_flush(buf);
134 evas_software_x11_outbuf_flush(buf);
136 XFreeGC(buf->priv.x.disp, buf->priv.x.gc);
138 XFreeGC(buf->priv.x.disp, buf->priv.x.gcm);
140 evas_software_x11_x_color_deallocate(buf->priv.x.disp, buf->priv.x.cmap,
141 buf->priv.x.vis, buf->priv.pal);
147 evas_software_x11_outbuf_rotation_set(Outbuf *buf, int rot)
153 evas_software_x11_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
154 Display *disp, Drawable draw, Visual *vis,
155 Colormap cmap, int x_depth,
156 int grayscale, int max_colors, Pixmap mask,
157 int shape_dither, int destination_alpha)
161 buf = calloc(1, sizeof(Outbuf));
170 buf->priv.x.disp = disp;
171 buf->priv.x.vis = vis;
172 buf->priv.x.cmap = cmap;
173 buf->priv.x.depth = x_depth;
175 buf->priv.mask_dither = shape_dither;
176 buf->priv.destination_alpha = destination_alpha;
179 Gfx_Func_Convert conv_func;
180 X_Output_Buffer *xob;
182 buf->priv.x.shm = evas_software_x11_x_can_do_shm(buf->priv.x.disp);
183 xob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
186 1, 1, buf->priv.x.shm, NULL);
191 #ifdef WORDS_BIGENDIAN
192 if (evas_software_x11_x_output_buffer_byte_order(xob) == LSBFirst)
193 buf->priv.x.swap = 1;
194 if (evas_software_x11_x_output_buffer_bit_order(xob) == MSBFirst)
195 buf->priv.x.bit_swap = 1;
197 if (evas_software_x11_x_output_buffer_byte_order(xob) == MSBFirst)
198 buf->priv.x.swap = 1;
199 if (evas_software_x11_x_output_buffer_bit_order(xob) == MSBFirst)
200 buf->priv.x.bit_swap = 1;
202 if (((vis->class == TrueColor) || (vis->class == DirectColor)) &&
205 buf->priv.mask.r = (DATA32) vis->red_mask;
206 buf->priv.mask.g = (DATA32) vis->green_mask;
207 buf->priv.mask.b = (DATA32) vis->blue_mask;
208 if (buf->priv.x.swap)
210 SWAP32(buf->priv.mask.r);
211 SWAP32(buf->priv.mask.g);
212 SWAP32(buf->priv.mask.b);
215 else if ((vis->class == PseudoColor) ||
216 (vis->class == StaticColor) ||
217 (vis->class == GrayScale) ||
218 (vis->class == StaticGray) ||
221 Convert_Pal_Mode pm = PAL_MODE_RGB332;
223 if ((vis->class == GrayScale) || (vis->class == StaticGray))
227 if (max_colors >= 256)
228 pm = PAL_MODE_GRAY256;
229 else if (max_colors >= 64)
230 pm = PAL_MODE_GRAY64;
231 else if (max_colors >= 16)
232 pm = PAL_MODE_GRAY16;
233 else if (max_colors >= 4)
240 if (max_colors >= 256)
241 pm = PAL_MODE_RGB332;
242 else if (max_colors >= 216)
243 pm = PAL_MODE_RGB666;
244 else if (max_colors >= 128)
245 pm = PAL_MODE_RGB232;
246 else if (max_colors >= 64)
247 pm = PAL_MODE_RGB222;
248 else if (max_colors >= 32)
249 pm = PAL_MODE_RGB221;
250 else if (max_colors >= 16)
251 pm = PAL_MODE_RGB121;
252 else if (max_colors >= 8)
253 pm = PAL_MODE_RGB111;
254 else if (max_colors >= 4)
259 /* FIXME: only alloc once per display+cmap */
260 buf->priv.pal = evas_software_x11_x_color_allocate(disp, cmap, vis,
270 if (buf->rot == 0 || buf->rot == 180)
271 conv_func = evas_common_convert_func_get(0, buf->w, buf->h,
272 evas_software_x11_x_output_buffer_depth
273 (xob), buf->priv.mask.r,
276 buf->priv.pal->colors,
278 else if (buf->rot == 90 || buf->rot == 270)
279 conv_func = evas_common_convert_func_get(0, buf->h, buf->w,
280 evas_software_x11_x_output_buffer_depth
281 (xob), buf->priv.mask.r,
284 buf->priv.pal->colors,
289 if (buf->rot == 0 || buf->rot == 180)
290 conv_func = evas_common_convert_func_get(0, buf->w, buf->h,
291 evas_software_x11_x_output_buffer_depth
292 (xob), buf->priv.mask.r,
294 buf->priv.mask.b, PAL_MODE_NONE,
296 else if (buf->rot == 90 || buf->rot == 270)
297 conv_func = evas_common_convert_func_get(0, buf->h, buf->w,
298 evas_software_x11_x_output_buffer_depth
299 (xob), buf->priv.mask.r,
301 buf->priv.mask.b, PAL_MODE_NONE,
304 evas_software_x11_x_output_buffer_free(xob, 1);
307 printf(".[ Evas Error ].\n"
310 " RGB format mask: %08x, %08x, %08x\n"
311 " Palette mode: %i\n"
312 " Not supported by compiled in converters!\n"
317 buf->priv.mask.b, buf->priv.pal->colors);
320 evas_software_x11_outbuf_drawable_set(buf, draw);
321 evas_software_x11_outbuf_mask_set(buf, mask);
327 evas_software_x11_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
335 if ((buf->onebuf) && (buf->priv.x.shm))
337 Evas_Rectangle *rect;
339 rect = malloc(sizeof(Evas_Rectangle));
340 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);
345 buf->priv.onebuf_regions = evas_list_append(buf->priv.onebuf_regions, rect);
346 if (buf->priv.onebuf)
352 if (!buf->priv.synced)
354 XSync(buf->priv.x.disp, False);
355 buf->priv.synced = 1;
357 if ((buf->priv.x.mask) || (buf->priv.destination_alpha))
361 im = buf->priv.onebuf;
362 for (yy = y; yy < (y + h); yy++)
364 memset(im->image.data + (im->cache_entry.w * yy) + x,
365 0, w * sizeof(DATA32));
368 return buf->priv.onebuf;
370 obr = calloc(1, sizeof(Outbuf_Region));
380 alpha = ((buf->priv.x.mask) || (buf->priv.destination_alpha));
382 use_shm = buf->priv.x.shm;
383 if ((buf->rot == 0) &&
384 (buf->priv.mask.r == 0xff0000) &&
385 (buf->priv.mask.g == 0x00ff00) &&
386 (buf->priv.mask.b == 0x0000ff))
388 obr->xob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
394 im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
396 (DATA32 *) evas_software_x11_x_output_buffer_data(obr->xob, &bpl),
397 alpha, EVAS_COLORSPACE_ARGB8888);
398 im->extended_info = obr;
399 if (buf->priv.x.mask)
400 obr->mxob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
409 im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
410 im->cache_entry.flags.alpha |= alpha ? 1 : 0;
411 evas_cache_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
412 im->extended_info = obr;
413 if ((buf->rot == 0) || (buf->rot == 180))
414 obr->xob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
420 else if ((buf->rot == 90) || (buf->rot == 270))
421 obr->xob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
427 if (buf->priv.x.mask)
428 obr->mxob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
435 /* FIXME: faster memset! */
436 memset(im->image.data, 0, w * h * sizeof(DATA32));
438 buf->priv.onebuf = im;
442 obr = calloc(1, sizeof(Outbuf_Region));
452 use_shm = buf->priv.x.shm;
453 /* FIXME: magic - i found if shm regions are smaller than 200x200 its
454 * faster to use ximages over unix sockets - trial and error
456 // use_shm = 0; /* 630 -> 1006 fps */
457 // if ((w * h) < (200 * 200)) use_shm = 0; /* 630 -> 962 fps */
459 alpha = ((buf->priv.x.mask) || (buf->priv.destination_alpha));
461 if ((buf->rot == 0) &&
462 (buf->priv.mask.r == 0xff0000) &&
463 (buf->priv.mask.g == 0x00ff00) &&
464 (buf->priv.mask.b == 0x0000ff))
466 obr->xob = _find_xob(buf->priv.x.disp,
472 /* obr->xob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp, */
473 /* buf->priv.x.vis, */
474 /* buf->priv.x.depth, */
478 im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
480 (DATA32 *) evas_software_x11_x_output_buffer_data(obr->xob, &bpl),
481 alpha, EVAS_COLORSPACE_ARGB8888);
482 im->extended_info = obr;
483 if (buf->priv.x.mask)
484 obr->mxob = _find_xob(buf->priv.x.disp,
490 obr->mxob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
499 im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
500 im->cache_entry.flags.alpha |= alpha ? 1 : 0;
501 evas_cache_image_surface_alloc(&im->cache_entry, w, h);
502 im->extended_info = obr;
503 if ((buf->rot == 0) || (buf->rot == 180))
504 obr->xob = _find_xob(buf->priv.x.disp,
511 obr->xob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
518 else if ((buf->rot == 90) || (buf->rot == 270))
519 obr->xob = _find_xob(buf->priv.x.disp,
526 obr->xob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
533 if (buf->priv.x.mask)
534 obr->mxob = _find_xob(buf->priv.x.disp,
540 obr->mxob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp,
547 if ((buf->priv.x.mask) || (buf->priv.destination_alpha))
548 /* FIXME: faster memset! */
549 memset(im->image.data, 0, w * h * sizeof(DATA32));
551 buf->priv.pending_writes = evas_list_append(buf->priv.pending_writes, im);
556 evas_software_x11_outbuf_free_region_for_update(Outbuf *buf, RGBA_Image *update)
558 /* no need to do anything - they are cleaned up on flush */
562 evas_software_x11_outbuf_flush(Outbuf *buf)
566 if ((buf->priv.onebuf) && (buf->priv.onebuf_regions))
572 im = buf->priv.onebuf;
573 obr = im->extended_info;
574 tmpr = XCreateRegion();
575 while (buf->priv.onebuf_regions)
577 Evas_Rectangle *rect;
580 rect = buf->priv.onebuf_regions->data;
581 buf->priv.onebuf_regions = evas_list_remove_list(buf->priv.onebuf_regions, buf->priv.onebuf_regions);
586 XUnionRectWithRegion(&xr, tmpr, tmpr);
588 evas_software_x11_outbuf_debug_show(buf, buf->priv.x.win,
589 rect->x, rect->y, rect->w, rect->h);
592 XSetRegion(buf->priv.x.disp, buf->priv.x.gc, tmpr);
593 evas_software_x11_x_output_buffer_paste(obr->xob, buf->priv.x.win,
598 XSetRegion(buf->priv.x.disp, buf->priv.x.gcm, tmpr);
599 evas_software_x11_x_output_buffer_paste(obr->mxob,
604 XDestroyRegion(tmpr);
605 buf->priv.synced = 0;
610 XSync(buf->priv.x.disp, False);
611 for (l = buf->priv.pending_writes; l; l = l->next)
617 obr = im->extended_info;
619 evas_software_x11_outbuf_debug_show(buf, buf->priv.x.win,
620 obr->x, obr->y, obr->w, obr->h);
621 evas_software_x11_x_output_buffer_paste(obr->xob, buf->priv.x.win,
625 evas_software_x11_x_output_buffer_paste(obr->mxob,
630 while (buf->priv.prev_pending_writes)
635 im = buf->priv.prev_pending_writes->data;
636 buf->priv.prev_pending_writes =
637 evas_list_remove_list(buf->priv.prev_pending_writes,
638 buf->priv.prev_pending_writes);
639 obr = im->extended_info;
640 evas_cache_image_drop(&im->cache_entry);
641 if (obr->xob) _unfind_xob(obr->xob, 0);
642 if (obr->mxob) _unfind_xob(obr->mxob, 0);
644 if (obr->xob) evas_software_x11_x_output_buffer_free(obr->xob, 0);
645 if (obr->mxob) evas_software_x11_x_output_buffer_free(obr->mxob, 0);
649 buf->priv.prev_pending_writes = buf->priv.pending_writes;
650 buf->priv.pending_writes = NULL;
651 XFlush(buf->priv.x.disp);
653 /* XX async push - disable */
655 for (l = buf->priv.pending_writes; l; l = l->next)
661 obr = im->extended_info;
663 evas_software_x11_outbuf_debug_show(buf, buf->priv.x.win,
664 obr->x, obr->y, obr->w, obr->h);
665 evas_software_x11_x_output_buffer_paste(obr->xob, buf->priv.x.win,
669 evas_software_x11_x_output_buffer_paste(obr->mxob,
675 XSync(buf->priv.x.disp, False);
677 while (buf->priv.pending_writes)
682 im = evas_list_data(buf->priv.pending_writes);
683 buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes);
684 obr = im->extended_info;
685 evas_cache_image_drop(&im->cache_entry);
686 if (obr->xob) _unfind_xob(obr->xob, 0);
687 if (obr->mxob) _unfind_xob(obr->mxob, 0);
689 if (obr->xob) evas_software_x11_x_output_buffer_free(obr->xob, 0);
690 if (obr->mxob) evas_software_x11_x_output_buffer_free(obr->mxob, 0);
693 evas_cache_image_drop(&im->cache_entry);
697 evas_common_cpu_end_opt();
701 evas_software_x11_outbuf_idle_flush(Outbuf *buf)
703 if (buf->priv.onebuf)
708 im = buf->priv.onebuf;
709 buf->priv.onebuf = NULL;
710 obr = im->extended_info;
711 if (obr->xob) evas_software_x11_x_output_buffer_free(obr->xob, 0);
712 if (obr->mxob) evas_software_x11_x_output_buffer_free(obr->mxob, 0);
714 evas_cache_image_drop(&im->cache_entry);
718 if (buf->priv.prev_pending_writes) XSync(buf->priv.x.disp, False);
719 while (buf->priv.prev_pending_writes)
724 im = buf->priv.prev_pending_writes->data;
725 buf->priv.prev_pending_writes =
726 evas_list_remove_list(buf->priv.prev_pending_writes,
727 buf->priv.prev_pending_writes);
728 obr = im->extended_info;
729 evas_cache_image_drop(&im->cache_entry);
730 if (obr->xob) _unfind_xob(obr->xob, 0);
731 if (obr->mxob) _unfind_xob(obr->mxob, 0);
739 evas_software_x11_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h)
741 Gfx_Func_Convert conv_func = NULL;
747 obr = update->extended_info;
750 if ((buf->rot == 0) || (buf->rot == 180))
751 conv_func = evas_common_convert_func_get(0, w, h,
752 evas_software_x11_x_output_buffer_depth
753 (obr->xob), buf->priv.mask.r,
754 buf->priv.mask.g, buf->priv.mask.b,
755 buf->priv.pal->colors, buf->rot);
756 else if ((buf->rot == 90) || (buf->rot == 270))
757 conv_func = evas_common_convert_func_get(0, h, w,
758 evas_software_x11_x_output_buffer_depth
759 (obr->xob), buf->priv.mask.r,
760 buf->priv.mask.g, buf->priv.mask.b,
761 buf->priv.pal->colors, buf->rot);
765 if ((buf->rot == 0) || (buf->rot == 180))
766 conv_func = evas_common_convert_func_get(0, w, h,
767 evas_software_x11_x_output_buffer_depth
768 (obr->xob), buf->priv.mask.r,
769 buf->priv.mask.g, buf->priv.mask.b,
770 PAL_MODE_NONE, buf->rot);
771 else if ((buf->rot == 90) || (buf->rot == 270))
772 conv_func = evas_common_convert_func_get(0, h, w,
773 evas_software_x11_x_output_buffer_depth
774 (obr->xob), buf->priv.mask.r,
775 buf->priv.mask.g, buf->priv.mask.b,
776 PAL_MODE_NONE, buf->rot);
778 if (!conv_func) return;
780 data = evas_software_x11_x_output_buffer_data(obr->xob, &bpl);
781 src_data = update->image.data;
787 else if (buf->rot == 90)
790 obr->y = buf->w - x - w;
792 else if (buf->rot == 180)
794 obr->x = buf->w - x - w;
795 obr->y = buf->h - y - h;
797 else if (buf->rot == 270)
799 obr->x = buf->h - y - h;
802 if ((buf->rot == 0) || (buf->rot == 180))
807 else if ((buf->rot == 90) || (buf->rot == 270))
814 if (data != src_data)
815 conv_func(src_data, data,
818 ((evas_software_x11_x_output_buffer_depth(obr->xob) /
819 8)) - obr->w, obr->w, obr->h, x, y,
820 buf->priv.pal->lookup);
824 if (data != src_data)
825 conv_func(src_data, data,
828 ((evas_software_x11_x_output_buffer_depth(obr->xob) /
829 8)) - obr->w, obr->w, obr->h, x, y, NULL);
834 if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions)))
837 evas_software_x11_outbuf_debug_show(buf, buf->priv.x.win,
838 obr->x, obr->y, obr->w, obr->h);
839 evas_software_x11_x_output_buffer_paste(obr->xob, buf->priv.x.win,
846 for (yy = 0; yy < obr->h; yy++)
847 evas_software_x11_x_write_mask_line(buf, obr->mxob,
849 (yy * obr->w), obr->w, yy);
853 if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions)))
854 evas_software_x11_x_output_buffer_paste(obr->mxob,
862 XFlush(buf->priv.x.disp);
867 evas_software_x11_outbuf_reconfigure(Outbuf * buf, int w, int h, int rot,
873 (depth == buf->depth)) return;
877 evas_software_x11_outbuf_idle_flush(buf);
881 evas_software_x11_outbuf_get_width(Outbuf * buf)
887 evas_software_x11_outbuf_get_height(Outbuf * buf)
893 evas_software_x11_outbuf_get_depth(Outbuf * buf)
899 evas_software_x11_outbuf_get_rot(Outbuf * buf)
905 evas_software_x11_outbuf_drawable_set(Outbuf * buf, Drawable draw)
909 if (buf->priv.x.win == draw) return;
912 XFreeGC(buf->priv.x.disp, buf->priv.x.gc);
913 buf->priv.x.gc = NULL;
915 buf->priv.x.win = draw;
916 buf->priv.x.gc = XCreateGC(buf->priv.x.disp, buf->priv.x.win, 0, &gcv);
920 evas_software_x11_outbuf_mask_set(Outbuf * buf, Pixmap mask)
924 if (buf->priv.x.mask == mask) return;
927 XFreeGC(buf->priv.x.disp, buf->priv.x.gcm);
928 buf->priv.x.gcm = NULL;
930 buf->priv.x.mask = mask;
931 if (buf->priv.x.mask)
932 buf->priv.x.gcm = XCreateGC(buf->priv.x.disp, buf->priv.x.mask, 0, &gcv);
936 evas_software_x11_outbuf_debug_set(Outbuf * buf, int debug)
938 buf->priv.debug = debug;
942 evas_software_x11_outbuf_debug_show(Outbuf * buf, Drawable draw, int x, int y, int w,
950 unsigned int ww, wh, bd, dp;
952 XWindowAttributes wattr;
954 XGetGeometry(buf->priv.x.disp, draw, &root, &wx, &wy, &ww, &wh, &bd, &dp);
955 XGetGeometry(buf->priv.x.disp, root, &wdum, &wx, &wy, &ww, &wh, &bd, &dp);
956 XGetWindowAttributes(buf->priv.x.disp, root, &wattr);
957 screen_num = XScreenNumberOfScreen(wattr.screen);
959 for (i = 0; i < 20; i++)
963 XSetForeground(buf->priv.x.disp, buf->priv.x.gc,
964 BlackPixel(buf->priv.x.disp, screen_num));
965 XFillRectangle(buf->priv.x.disp, draw, buf->priv.x.gc, x, y, w, h);
966 XSync(buf->priv.x.disp, False);
968 // XGetImage(buf->priv.x.disp, draw, x, y, w, h, 0xffffffff, ZPixmap);
970 // XDestroyImage(xim);
971 XSync(buf->priv.x.disp, False);
972 XSetForeground(buf->priv.x.disp, buf->priv.x.gc,
973 WhitePixel(buf->priv.x.disp, screen_num));
974 XFillRectangle(buf->priv.x.disp, draw, buf->priv.x.gc, x, y, w, h);
975 XSync(buf->priv.x.disp, False);
977 // XGetImage(buf->priv.x.disp, draw, x, y, w, h, 0xffffffff, ZPixmap);
979 // XDestroyImage(xim);
980 XSync(buf->priv.x.disp, False);