1 /*
2 * Copyright (c) 2000,2001 Sasha Vasko <sasha at aftercode.net>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #ifdef _WIN32
20 #include "win32/config.h"
21 #else
22 #include "config.h"
23 #endif
24
25 #undef LOCAL_DEBUG
26 #define DO_CLOCKING
27
28 #ifdef DO_CLOCKING
29 #if TIME_WITH_SYS_TIME
30 # include <sys/time.h>
31 # include <time.h>
32 #else
33 # if HAVE_SYS_TIME_H
34 # include <sys/time.h>
35 # else
36 # include <time.h>
37 # endif
38 #endif
39 #endif
40 #ifdef HAVE_STDARG_H
41 #include <stdarg.h>
42 #endif
43
44 #ifdef HAVE_GLX
45 # include <GL/gl.h>
46 # include <GL/glx.h>
47 /*# include <GL/glu.h> */
48 #endif
49
50
51 #ifdef _WIN32
52 # include "win32/afterbase.h"
53 #else
54 # include "afterbase.h"
55 #endif
56 #include "asvisual.h"
57 #include "blender.h"
58 #include "asimage.h"
59 #include "imencdec.h"
60 #include "ximage.h"
61
62
63 /* ***************************************************************************/
64 /* ASImage->XImage->pixmap->XImage->ASImage conversion */
65 /* ***************************************************************************/
66
67 ASImage *
picture_ximage2asimage(ASVisual * asv,XImage * xim,XImage * alpha_xim,unsigned int compression)68 picture_ximage2asimage (ASVisual *asv, XImage *xim, XImage *alpha_xim, unsigned int compression)
69 {
70 ASImage *im = NULL;
71 unsigned char *xim_line;
72 int i, height, width, bpl;
73 ASScanline xim_buf;
74 #ifdef LOCAL_DEBUG
75 CARD32 *tmp ;
76 #endif
77 #if 0
78 struct timeval stv;
79 gettimeofday (&stv,NULL);
80 #define PRINT_BACKGROUND_OP_TIME do{ struct timeval tv;gettimeofday (&tv,NULL); tv.tv_sec-= stv.tv_sec;\
81 fprintf (stderr,__FILE__ "%d: elapsed %ld usec\n",__LINE__,\
82 tv.tv_sec*1000000+tv.tv_usec-stv.tv_usec );}while(0)
83 #else
84 #define PRINT_BACKGROUND_OP_TIME do{}while(0)
85 #endif
86
87 if( xim && alpha_xim )
88 if( xim->width != alpha_xim->width ||
89 xim->height != alpha_xim->height )
90 return NULL ;
91 if( xim == NULL && alpha_xim == NULL )
92 return NULL ;
93
94 width = xim?xim->width:alpha_xim->width;
95 height = xim?xim->height:alpha_xim->height;
96
97 im = create_asimage( width, height, compression);
98 prepare_scanline( width, 0, &xim_buf, asv->BGR_mode );
99 #ifdef LOCAL_DEBUG
100 tmp = safemalloc( width * sizeof(CARD32));
101 #endif
102 PRINT_BACKGROUND_OP_TIME;
103 if( xim )
104 {
105 bpl = xim->bytes_per_line;
106 xim_line = (unsigned char *)xim->data;
107
108 for (i = 0; i < height; i++)
109 {
110 #if 0
111 /* unfortunately this method does not seem to yield any better results performancewise: */
112 if (asv->true_depth == 32 || asv->true_depth == 24)
113 {
114 if( asv->msb_first )
115 {
116 }else
117 asimage_add_line_bgra (im, xim_line, i);
118 }else
119 #endif
120 if( xim->depth == (int)asv->true_depth )
121 {
122 GET_SCANLINE(asv,xim,&xim_buf,i,xim_line);
123 asimage_add_line (im, IC_RED, xim_buf.red, i);
124 asimage_add_line (im, IC_GREEN, xim_buf.green, i);
125 asimage_add_line (im, IC_BLUE, xim_buf.blue, i);
126 if( xim->depth == 32 && alpha_xim == NULL )
127 asimage_add_line (im, IC_ALPHA, xim_buf.alpha, i);
128 #ifdef LOCAL_DEBUG
129 if( !asimage_compare_line( im, IC_RED, xim_buf.red, tmp, i, True ) )
130 exit(0);
131 if( !asimage_compare_line( im, IC_GREEN, xim_buf.green, tmp, i, True ) )
132 exit(0);
133 if( !asimage_compare_line( im, IC_BLUE, xim_buf.blue, tmp, i, True ) )
134 exit(0);
135 #endif
136 }else if( xim->depth == 8 )
137 {
138 register int x = width;
139 while(--x >= 0 )
140 xim_buf.blue[x] = (CARD32)(xim_line[x]);
141 asimage_add_line (im, IC_RED, xim_buf.red, i);
142 asimage_add_line (im, IC_GREEN, xim_buf.red, i);
143 asimage_add_line (im, IC_BLUE, xim_buf.red, i);
144 }else if( xim->depth == 1 )
145 {
146 register int x = width;
147 while(--x >= 0 )
148 {
149 #ifndef X_DISPLAY_MISSING
150 xim_buf.red[x] = (XGetPixel(xim, x, i) == 0)?0x00:0xFF;
151 #else
152 xim_buf.red[x] = 0xFF ;
153 #endif
154 }
155 asimage_add_line (im, IC_RED, xim_buf.red, i);
156 asimage_add_line (im, IC_GREEN, xim_buf.red, i);
157 asimage_add_line (im, IC_BLUE, xim_buf.red, i);
158 }
159
160 xim_line += bpl;
161 }
162 }
163 PRINT_BACKGROUND_OP_TIME;
164 if( alpha_xim )
165 {
166 CARD32 *dst = xim_buf.alpha ;
167 bpl = alpha_xim->bytes_per_line;
168 xim_line = (unsigned char *)alpha_xim->data;
169
170 for (i = 0; i < height; i++)
171 {
172 register int x = width;
173 if( alpha_xim->depth == 8 )
174 {
175 while(--x >= 0 ) dst[x] = (CARD32)(xim_line[x]);
176 }else
177 {
178 while(--x >= 0 )
179 #ifndef X_DISPLAY_MISSING
180 dst[x] = (XGetPixel(alpha_xim, x, i) == 0)?0x00:0xFF;
181 #else
182 dst[x] = 0xFF ;
183 #endif
184 }
185 asimage_add_line (im, IC_ALPHA, xim_buf.alpha, i);
186 #ifdef LOCAL_DEBUG
187 if( !asimage_compare_line( im, IC_ALPHA, xim_buf.alpha, tmp, i, True ) )
188 exit(0);
189 #endif
190 xim_line += bpl;
191 }
192 }
193 free_scanline(&xim_buf, True);
194 PRINT_BACKGROUND_OP_TIME;
195
196 return im;
197 }
198
199 ASImage *
ximage2asimage(ASVisual * asv,XImage * xim,unsigned int compression)200 ximage2asimage (ASVisual *asv, XImage * xim, unsigned int compression)
201 {
202 return picture_ximage2asimage (asv, xim, NULL, compression);
203 }
204
205 static inline int
xim_set_component(register CARD32 * src,register CARD32 value,int offset,int len)206 xim_set_component( register CARD32 *src, register CARD32 value, int offset, int len )
207 {
208 register int i ;
209 for( i = offset ; i < len ; ++i )
210 src[i] = value;
211 return len-offset;
212 }
213
214 Bool
subimage2ximage(ASVisual * asv,ASImage * im,int x,int y,XImage * xim)215 subimage2ximage (ASVisual *asv, ASImage *im, int x, int y, XImage* xim)
216 {
217 int i, max_i;
218 ASScanline xim_buf;
219 ASImageOutput *imout ;
220 /*#ifdef DO_CLOCKING
221 clock_t started = clock ();
222 #endif*/
223 int width, height ;
224 ASImage *scratch_im ;
225
226 if (im == NULL)
227 {
228 LOCAL_DEBUG_OUT( "Attempt to convert NULL ASImage into XImage.", "" );
229 return False;
230 }
231 if( x >= (int)im->width || y >= (int)im->height )
232 return False;
233 width = xim->width ;
234 if( width > (int)im->width - x)
235 width = (int)im->width - x;
236 width = ( x > (int)im->width - width )?im->width - width:im->width - x ;
237 height = xim->height ;
238 if( height > (int)im->height - y )
239 height = im->height - y ;
240 scratch_im = create_asimage( width, height, 0);
241 scratch_im->alt.ximage = xim ;
242 LOCAL_DEBUG_OUT( "target width = %d, height = %d", width, height );
243 if( (imout = start_image_output( asv, scratch_im, ASA_ScratchXImage, 0, ASIMAGE_QUALITY_DEFAULT )) == NULL )
244 {
245 LOCAL_DEBUG_OUT( "Failed to start ASImageOutput for ASImage %p and ASVisual %p", im, asv );
246 return False;
247 }
248
249 prepare_scanline( width, 0, &xim_buf, asv->BGR_mode );
250 /*#ifdef DO_CLOCKING
251 started = clock ();
252 #endif*/
253 set_flags( xim_buf.flags, SCL_DO_ALL );
254 max_i = y + height ;
255 for (i = y; i < max_i; i++)
256 {
257 int count ;
258 if( (count = asimage_decode_line (im, IC_RED, xim_buf.red, i, x, xim_buf.width)) < (int)xim_buf.width )
259 xim_set_component( xim_buf.red, ARGB32_RED8(im->back_color), count, xim_buf.width );
260 if( (count = asimage_decode_line (im, IC_GREEN, xim_buf.green, i, x, xim_buf.width))< (int)xim_buf.width )
261 xim_set_component( xim_buf.green, ARGB32_GREEN8(im->back_color), count, xim_buf.width );
262 if( (count = asimage_decode_line (im, IC_BLUE, xim_buf.blue, i, x, xim_buf.width)) < (int)xim_buf.width )
263 xim_set_component( xim_buf.blue, ARGB32_BLUE8(im->back_color), count, xim_buf.width );
264 if( xim->depth == 32 )
265 if( (count = asimage_decode_line (im, IC_ALPHA, xim_buf.alpha, i, x, xim_buf.width)) < (int)xim_buf.width )
266 xim_set_component( xim_buf.alpha, ARGB32_ALPHA8(im->back_color), count, xim_buf.width );
267
268 imout->output_image_scanline( imout, &xim_buf, 1 );
269 /* LOCAL_DEBUG_OUT( "line %d, count = %d", i, count ); */
270 }
271 /*#ifdef DO_CLOCKING
272 fprintf (stderr, "asimage->ximage time (clocks): %lu\n", clock () - started);
273 #endif*/
274 free_scanline(&xim_buf, True);
275 stop_image_output(&imout);
276
277 scratch_im->alt.ximage = NULL ;
278 destroy_asimage( &scratch_im );
279 return True;
280 }
281
282
283
284 static XImage*
asimage2ximage_ext(ASVisual * asv,ASImage * im,Bool scratch)285 asimage2ximage_ext (ASVisual *asv, ASImage *im, Bool scratch)
286 {
287 XImage *xim = NULL;
288 int i;
289 ASImageOutput *imout ;
290 ASImageDecoder *imdec;
291 /*#ifdef DO_CLOCKING
292 clock_t started = clock ();
293 #endif*/
294
295 if (im == NULL)
296 {
297 LOCAL_DEBUG_OUT( "Attempt to convert NULL ASImage into XImage.", "" );
298 return xim;
299 }
300 if( (imout = start_image_output( asv, im, scratch?ASA_ScratchXImage:ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT )) == NULL )
301 {
302 LOCAL_DEBUG_OUT( "Failed to start ASImageOutput for ASImage %p and ASVisual %p", im, asv );
303 return xim;
304 }
305 xim = im->alt.ximage ;
306 /* no data in ximage yet */
307 set_flags( im->flags, ASIM_XIMAGE_NOT_USEFUL);
308 /*#ifdef DO_CLOCKING
309 started = clock ();
310 #endif*/
311 #if 1
312 if ((imdec = start_image_decoding( asv, im, (xim->depth >= 24)?SCL_DO_ALL:SCL_DO_COLOR,
313 0, 0, im->width, im->height, NULL)) != NULL )
314 {
315 for (i = 0; i < (int)im->height; i++)
316 {
317 imdec->decode_image_scanline( imdec );
318 imout->output_image_scanline( imout, &(imdec->buffer), 1);
319 }
320 stop_image_decoding( &imdec );
321 }
322 #else
323 {
324 ASScanline xim_buf;
325 prepare_scanline( im->width, 0, &xim_buf, asv->BGR_mode );
326 set_flags( xim_buf.flags, SCL_DO_ALL );
327 for (i = 0; i < (int)im->height; i++)
328 {
329 int count ;
330 if( (count = asimage_decode_line (im, IC_RED, xim_buf.red, i, 0, xim_buf.width)) < (int)xim_buf.width )
331 xim_set_component( xim_buf.red, ARGB32_RED8(im->back_color), count, xim_buf.width );
332 if( (count = asimage_decode_line (im, IC_GREEN, xim_buf.green, i, 0, xim_buf.width))< (int)xim_buf.width )
333 xim_set_component( xim_buf.green, ARGB32_GREEN8(im->back_color), count, xim_buf.width );
334 if( (count = asimage_decode_line (im, IC_BLUE, xim_buf.blue, i, 0, xim_buf.width)) < (int)xim_buf.width )
335 xim_set_component( xim_buf.blue, ARGB32_BLUE8(im->back_color), count, xim_buf.width );
336 if( xim->depth == 32 )
337 if( (count = asimage_decode_line (im, IC_ALPHA, xim_buf.alpha, i, 0, xim_buf.width)) < (int)xim_buf.width )
338 xim_set_component( xim_buf.alpha, ARGB32_ALPHA8(im->back_color), count, xim_buf.width );
339 imout->output_image_scanline( imout, &xim_buf, 1 );
340 }
341 free_scanline(&xim_buf, True);
342 }
343 #endif
344
345 /*#ifdef DO_CLOCKING
346 fprintf (stderr, "asimage->ximage time (clocks): %lu\n", clock () - started);
347 #endif*/
348
349 stop_image_output(&imout);
350 clear_flags( im->flags, ASIM_XIMAGE_NOT_USEFUL);
351
352 return xim;
353 }
354
355 XImage*
asimage2ximage(ASVisual * asv,ASImage * im)356 asimage2ximage (ASVisual *asv, ASImage *im)
357 {
358 return asimage2ximage_ext (asv, im, False);
359 }
360
361 XImage*
asimage2alpha_ximage(ASVisual * asv,ASImage * im,Bool bitmap)362 asimage2alpha_ximage (ASVisual *asv, ASImage *im, Bool bitmap )
363 {
364 XImage *xim = NULL;
365 int i;
366 ASScanline xim_buf;
367 ASImageOutput *imout ;
368 ASFlagType flag = bitmap?0:ASIM_XIMAGE_8BIT_MASK;
369
370 if (im == NULL)
371 return xim;
372
373 if( im->alt.mask_ximage )
374 if( (im->flags & ASIM_XIMAGE_8BIT_MASK )^flag)
375 {
376 #ifndef X_DISPLAY_MISSING
377 XDestroyImage( im->alt.mask_ximage );
378 #endif
379 im->alt.mask_ximage = NULL ;
380 }
381 clear_flags( im->flags, ASIM_XIMAGE_8BIT_MASK );
382 set_flags( im->flags, flag );
383
384 if( (imout = start_image_output( asv, im, ASA_MaskXImage, 0, ASIMAGE_QUALITY_POOR )) == NULL )
385 return xim;
386 xim = im->alt.mask_ximage ;
387 prepare_scanline( xim->width, 0, &xim_buf, asv->BGR_mode );
388 xim_buf.flags = SCL_DO_ALPHA ;
389 for (i = 0; i < (int)im->height; i++)
390 {
391 int count = asimage_decode_line (im, IC_ALPHA, xim_buf.alpha, i, 0, xim_buf.width);
392 if( count < (int)xim_buf.width )
393 xim_set_component( xim_buf.alpha, ARGB32_ALPHA8(im->back_color), count, xim_buf.width );
394 imout->output_image_scanline( imout, &xim_buf, 1 );
395 }
396 free_scanline(&xim_buf, True);
397
398 stop_image_output(&imout);
399
400 return xim;
401 }
402
403 XImage*
asimage2mask_ximage(ASVisual * asv,ASImage * im)404 asimage2mask_ximage (ASVisual *asv, ASImage *im)
405 {
406 return asimage2alpha_ximage (asv, im, True );
407 }
408
409 ASImage *
pixmap2ximage(ASVisual * asv,Pixmap p,int x,int y,unsigned int width,unsigned int height,unsigned long plane_mask,unsigned int compression)410 pixmap2ximage(ASVisual *asv, Pixmap p, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, unsigned int compression)
411 {
412 #ifndef X_DISPLAY_MISSING
413 XImage *xim = ASGetXImage (asv, p, x, y, width, height, plane_mask);
414 ASImage *im = NULL;
415
416 if (xim)
417 {
418 im = create_asimage( xim->width, xim->height, compression);
419 im->flags = ASIM_DATA_NOT_USEFUL ;
420 im->alt.ximage = xim ;
421 }
422 return im;
423 #else
424 return NULL ;
425 #endif
426 }
427
428 ASImage *
picture2asimage(ASVisual * asv,Pixmap rgb,Pixmap a,int x,int y,unsigned int width,unsigned int height,unsigned long plane_mask,Bool keep_cache,unsigned int compression)429 picture2asimage(ASVisual *asv, Pixmap rgb, Pixmap a , int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, Bool keep_cache, unsigned int compression)
430 {
431 #ifndef X_DISPLAY_MISSING
432 XImage *xim = ASGetXImage (asv, rgb, x, y, width, height, plane_mask);
433 XImage *alpha_xim = (a==None)?NULL:ASGetXImage (asv, a, x, y, width, height, 0xFFFFFFFF);
434 ASImage *im = NULL;
435
436 if (xim)
437 {
438 im = picture_ximage2asimage (asv, xim, alpha_xim, compression);
439 if( keep_cache )
440 {
441 im->alt.ximage = xim ;
442 if( alpha_xim )
443 {
444 im->alt.mask_ximage = alpha_xim ;
445 if( alpha_xim->depth == 8 )
446 set_flags( im->flags, ASIM_XIMAGE_8BIT_MASK );
447 }
448 }else
449 {
450 XDestroyImage (xim);
451 if( alpha_xim )
452 XDestroyImage (alpha_xim);
453 }
454 }
455 return im;
456 #else
457 return NULL ;
458 #endif
459 }
460
461 ASImage *
pixmap2asimage(ASVisual * asv,Pixmap p,int x,int y,unsigned int width,unsigned int height,unsigned long plane_mask,Bool keep_cache,unsigned int compression)462 pixmap2asimage(ASVisual *asv, Pixmap p, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, Bool keep_cache, unsigned int compression)
463 {
464 return picture2asimage(asv, p, None, x, y, width, height, plane_mask, keep_cache, compression);
465 }
466
467 Bool
put_ximage(ASVisual * asv,XImage * xim,Drawable d,GC gc,int src_x,int src_y,int dest_x,int dest_y,unsigned int width,unsigned int height)468 put_ximage( ASVisual *asv, XImage *xim, Drawable d, GC gc,
469 int src_x, int src_y, int dest_x, int dest_y,
470 unsigned int width, unsigned int height )
471 {
472 #ifndef X_DISPLAY_MISSING
473 GC my_gc = gc ;
474
475 if( src_x < 0 )
476 {
477 width += src_x ;
478 src_x = 0;
479 }else if( src_x > xim->width )
480 return False;
481 if( xim->width > src_x+width )
482 width = xim->width - src_x ;
483 if( src_y < 0 )
484 {
485 height+= src_y ;
486 src_y = 0;
487 }else if( src_y > xim->height )
488 return False;
489 if( xim->height > src_y+height )
490 height = xim->height - src_y ;
491
492 if( my_gc == NULL )
493 {
494 XGCValues gcv ;
495 my_gc = XCreateGC( asv->dpy, d, 0, &gcv );
496 }
497 ASPutXImage( asv, d, my_gc, xim, src_x, src_y, dest_x, dest_y, width, height );
498 if( my_gc != gc )
499 XFreeGC( asv->dpy, my_gc );
500 return True ;
501 #else
502 return False ;
503 #endif
504 }
505
506 #define IS_POWER_OF2(i) (((((i)>>16)&1)+(((i)>>15)&1)+(((i)>>14)&1)+(((i)>>13)&1)+(((i)>>12)&1)+(((i)>>11)&1)+(((i)>>10)&1)+(((i)>>9)&1)+(((i)>>8)&1) \
507 +(((i)>>7)&1)+(((i)>>6)&1)+(((i)>>5)&1)+(((i)>>4)&1)+(((i)>>3)&1)+(((i)>>2)&1))==1)
508
509 Bool
asimage2drawable_gl(ASVisual * asv,Drawable d,ASImage * im,int src_x,int src_y,int dest_x,int dest_y,int width,int height,int d_width,int d_height,Bool force_direct)510 asimage2drawable_gl( ASVisual *asv, Drawable d, ASImage *im,
511 int src_x, int src_y, int dest_x, int dest_y,
512 int width, int height, int d_width, int d_height,
513 Bool force_direct )
514 {
515 if( im != NULL && get_flags( asv->glx_support, ASGLX_Available ) && d != None )
516 {
517 #ifdef HAVE_GLX
518 int glbuf_size = (get_flags( asv->glx_support, ASGLX_RGBA )? 4 : 3 ) * width * height;
519 CARD8 *glbuf = NULL;
520 ASImageDecoder *imdec = NULL ;
521 GLXPixmap glxp = None;
522
523 if ((imdec = start_image_decoding( asv, im,
524 get_flags( asv->glx_support, ASGLX_RGBA )?SCL_DO_ALL:SCL_DO_COLOR,
525 src_x, src_y, width, height, NULL)) != NULL )
526 {
527 int i, l = glbuf_size;
528 glbuf = safemalloc( glbuf_size );
529 for (i = 0; i < (int)height; i++)
530 {
531 int k = width;
532 imdec->decode_image_scanline( imdec );
533 if( get_flags( asv->glx_support, ASGLX_RGBA ) )
534 {
535 while( --k >= 0 )
536 {
537 glbuf[--l] = imdec->buffer.alpha[k] ;
538 glbuf[--l] = imdec->buffer.blue[k] ;
539 glbuf[--l] = imdec->buffer.green[k] ;
540 glbuf[--l] = imdec->buffer.red[k] ;
541 }
542 }else
543 {
544 while( --k >= 0 )
545 {
546 glbuf[--l] = imdec->buffer.blue[k] ;
547 glbuf[--l] = imdec->buffer.green[k] ;
548 glbuf[--l] = imdec->buffer.red[k] ;
549 }
550 }
551 }
552 stop_image_decoding( &imdec );
553 }else
554 return False;
555
556 if( !force_direct )
557 {
558 glxp = glXCreateGLXPixmap( asv->dpy, &(asv->visual_info), d);
559 /* d is either invalid drawable or is a window */
560 if( glxp == None )
561 force_direct = True ;
562 }
563 if( glxp == None )
564 {
565 if( asv->glx_scratch_gc_direct != NULL )
566 glXMakeCurrent (asv->dpy, d, asv->glx_scratch_gc_direct);
567 else
568 glXMakeCurrent (asv->dpy, d, asv->glx_scratch_gc_indirect);
569 }else
570 glXMakeCurrent (asv->dpy, glxp, asv->glx_scratch_gc_indirect);
571
572 if( glGetError() != 0 )
573 return False;
574
575 if ( get_flags( asv->glx_support, ASGLX_DoubleBuffer ) )
576 glDrawBuffer (GL_FRONT);
577
578 glDisable(GL_BLEND); /* optimize pixel transfer rates */
579 glDisable (GL_DEPTH_TEST);
580 glDisable (GL_DITHER);
581 glDisable (GL_FOG);
582 glDisable (GL_LIGHTING);
583
584 glViewport( 0, 0, d_width, d_height);
585 glMatrixMode (GL_PROJECTION);
586 glLoadIdentity ();
587 /* gluOrtho2D (0, d_width, 0, d_height); */
588 glMatrixMode (GL_MODELVIEW);
589 glLoadIdentity ();
590 glTranslatef (0.375, 0.375, 0.0);
591
592
593 #if 1
594 if( !IS_POWER_OF2(width) || !IS_POWER_OF2(height))
595 {
596 /* now put pixels on */
597 glRasterPos2i( dest_x, d_height - (dest_y+height) );
598 glDrawPixels( width, height,
599 get_flags( asv->glx_support, ASGLX_RGBA )?GL_RGBA:GL_RGB,
600 GL_UNSIGNED_BYTE, glbuf );
601 }else
602 #endif
603 { /* this stuff might be faster : */
604 GLuint texture ;
605
606 #define TARGET_TEXTURE_ID GL_TEXTURE_2D
607
608 #if TARGET_TEXTURE_ID!=GL_TEXTURE_2D
609 glEnable(GL_TEXTURE_2D);
610 #endif
611 glEnable(TARGET_TEXTURE_ID);
612 glGenTextures(1, &texture);
613
614 glBindTexture(TARGET_TEXTURE_ID, texture);
615 glTexParameteri(TARGET_TEXTURE_ID, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
616 glTexParameteri(TARGET_TEXTURE_ID, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
617 glTexImage2D(TARGET_TEXTURE_ID, 0, get_flags( asv->glx_support, ASGLX_RGBA )?GL_RGBA:GL_RGB,
618 /* width and height must be the power of 2 !!! */
619 width, height,
620 0, GL_RGBA, GL_UNSIGNED_BYTE, glbuf);
621
622 glBegin(GL_QUADS);
623 /* bottom-left */
624 glTexCoord2d(0., 0.); glVertex2i(dest_x, d_height - (dest_y+height) );
625 /* bottom-right */
626 glTexCoord2d(1.0, 0.0); glVertex2i(dest_x+width, d_height - (dest_y+height));
627 /* top-right */
628 glTexCoord2d(1.0, 1.0); glVertex2i(dest_x+width, d_height - dest_y);
629 /* top-left */
630 glTexCoord2d(0.0, 1.0); glVertex2i(dest_x, d_height - dest_y);
631 glEnd();
632
633 glBindTexture(TARGET_TEXTURE_ID, 0);
634 glFinish();
635 }
636
637 free( glbuf );
638 glXMakeCurrent (asv->dpy, None, NULL);
639 if( glxp )
640 glXDestroyGLXPixmap( asv->dpy, glxp);
641 glFinish();
642 return True;
643 #endif /* #ifdef HAVE_GLX */
644 }
645 {
646 static Bool warning_shown = False ;
647 if( !warning_shown )
648 {
649 warning_shown = True ;
650 show_warning( "Support for GLX is unavailable.");
651 }
652 }
653 return False;
654 }
655
656 Bool
asimage2drawable(ASVisual * asv,Drawable d,ASImage * im,GC gc,int src_x,int src_y,int dest_x,int dest_y,unsigned int width,unsigned int height,Bool use_cached)657 asimage2drawable( ASVisual *asv, Drawable d, ASImage *im, GC gc,
658 int src_x, int src_y, int dest_x, int dest_y,
659 unsigned int width, unsigned int height,
660 Bool use_cached)
661 {
662 #ifndef X_DISPLAY_MISSING
663 if( im )
664 {
665 Bool my_xim = False ;
666 XImage *xim ;
667 Bool res = False;
668 if ( !use_cached || im->alt.ximage == NULL )
669 {
670 if( (xim = asimage2ximage_ext( asv, im, False )) == NULL )
671 {
672 show_error("cannot export image into XImage.");
673 return None ;
674 }
675 my_xim = True ;
676 }else
677 xim = im->alt.ximage ;
678 if (xim != NULL )
679 {
680 res = put_ximage( asv, xim, d, gc, src_x, src_y, dest_x, dest_y, width, height );
681 if( my_xim && xim == im->alt.ximage )
682 im->alt.ximage = NULL ;
683 if( xim != im->alt.ximage )
684 XDestroyImage (xim);
685 }
686 return res;
687 }
688 #endif
689 return False ;
690 }
691
692 Bool
asimage2alpha_drawable(ASVisual * asv,Drawable d,ASImage * im,GC gc,int src_x,int src_y,int dest_x,int dest_y,unsigned int width,unsigned int height,Bool use_cached)693 asimage2alpha_drawable( ASVisual *asv, Drawable d, ASImage *im, GC gc,
694 int src_x, int src_y, int dest_x, int dest_y,
695 unsigned int width, unsigned int height,
696 Bool use_cached)
697 {
698 #ifndef X_DISPLAY_MISSING
699 if( im )
700 {
701 XImage *xim ;
702 unsigned int alpha_depth = 1 ;
703 int dumm; unsigned int udumm; Window root ;
704 Bool res = False ;
705
706 XGetGeometry( asv->dpy, d, &root, &dumm, &dumm, &udumm, &udumm, &udumm, &alpha_depth );
707
708 if ( !use_cached || im->alt.mask_ximage == NULL || im->alt.mask_ximage->depth != alpha_depth )
709 {
710 if( (xim = asimage2alpha_ximage (asv, im, (alpha_depth == 1) )) == NULL )
711 {
712 show_error("cannot export image into alpha XImage.");
713 return None ;
714 }
715 }else
716 xim = im->alt.mask_ximage ;
717 if (xim != NULL )
718 {
719 res = put_ximage( asv, xim, d, gc, src_x, src_y, dest_x, dest_y, width, height );
720 if( xim != im->alt.mask_ximage )
721 XDestroyImage (xim);
722 }
723 return res;
724 }
725 #endif
726 return False ;
727 }
728
729
730 Pixmap
asimage2pixmap(ASVisual * asv,Window root,ASImage * im,GC gc,Bool use_cached)731 asimage2pixmap(ASVisual *asv, Window root, ASImage *im, GC gc, Bool use_cached)
732 {
733 #ifndef X_DISPLAY_MISSING
734 if( im )
735 {
736 Pixmap p = None;
737
738 p = create_visual_pixmap( asv, root, im->width, im->height, 0 );
739
740 if( !asimage2drawable( asv, p, im, gc, 0, 0, 0, 0, im->width, im->height, use_cached) )
741 {
742 XFreePixmap( asv->dpy, p );
743 p = None ;
744 }
745 return p;
746 }
747 #endif
748 return None ;
749 }
750
751 Pixmap
asimage2alpha(ASVisual * asv,Window root,ASImage * im,GC gc,Bool use_cached,Bool bitmap)752 asimage2alpha(ASVisual *asv, Window root, ASImage *im, GC gc, Bool use_cached, Bool bitmap)
753 {
754 #ifndef X_DISPLAY_MISSING
755 XImage *xim ;
756 Pixmap mask = None;
757 GC my_gc = gc ;
758
759 int target_depth = bitmap?1:8;
760
761 if ( !use_cached || im->alt.mask_ximage == NULL ||
762 im->alt.mask_ximage->depth != target_depth )
763 {
764 if( (xim = asimage2alpha_ximage( asv, im, bitmap )) == NULL )
765 {
766 show_error("cannot export image's mask into XImage.");
767 return None ;
768 }
769 }else
770 xim = im->alt.mask_ximage ;
771 mask = create_visual_pixmap( asv, root, xim->width, xim->height, target_depth );
772 if( my_gc == NULL )
773 {
774 XGCValues gcv ;
775 my_gc = XCreateGC( asv->dpy, mask, 0, &gcv );
776 }
777 ASPutXImage( asv, mask, my_gc, xim, 0, 0, 0, 0, xim->width, xim->height );
778 if( my_gc != gc )
779 XFreeGC( asv->dpy, my_gc );
780 if( xim != im->alt.mask_ximage )
781 XDestroyImage (xim);
782 return mask;
783 #else
784 return None ;
785 #endif
786 }
787
788 Pixmap
asimage2mask(ASVisual * asv,Window root,ASImage * im,GC gc,Bool use_cached)789 asimage2mask(ASVisual *asv, Window root, ASImage *im, GC gc, Bool use_cached)
790 {
791 return asimage2alpha(asv, root, im, gc, use_cached, True);
792 }
793 /* ********************************************************************************/
794 /* The end !!!! */
795 /* ********************************************************************************/
796
797