Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / x11 / xm_span.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.3
4  *
5  * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 #include "glxheader.h"
26 #include "main/colormac.h"
27 #include "main/context.h"
28 #include "main/depth.h"
29 #include "main/drawpix.h"
30 #include "main/extensions.h"
31 #include "main/macros.h"
32 #include "main/imports.h"
33 #include "main/mtypes.h"
34 #include "main/state.h"
35 #include "xmesaP.h"
36
37 #include "swrast/swrast.h"
38
39
40 /*
41  * The following functions are used to trap XGetImage() calls which
42  * generate BadMatch errors if the drawable isn't mapped.
43  */
44
45 static int caught_xgetimage_error = 0;
46 static int (*old_xerror_handler)( XMesaDisplay *dpy, XErrorEvent *ev );
47 static unsigned long xgetimage_serial;
48
49 /*
50  * This is the error handler which will be called if XGetImage fails.
51  */
52 static int xgetimage_error_handler( XMesaDisplay *dpy, XErrorEvent *ev )
53 {
54    if (ev->serial==xgetimage_serial && ev->error_code==BadMatch) {
55       /* caught the expected error */
56       caught_xgetimage_error = 0;
57    }
58    else {
59       /* call the original X error handler, if any.  otherwise ignore */
60       if (old_xerror_handler) {
61          (*old_xerror_handler)( dpy, ev );
62       }
63    }
64    return 0;
65 }
66
67
68 /*
69  * Call this right before XGetImage to setup error trap.
70  */
71 static void catch_xgetimage_errors( XMesaDisplay *dpy )
72 {
73    xgetimage_serial = NextRequest( dpy );
74    old_xerror_handler = XSetErrorHandler( xgetimage_error_handler );
75    caught_xgetimage_error = 0;
76 }
77
78
79 /*
80  * Call this right after XGetImage to check if an error occured.
81  */
82 static int check_xgetimage_errors( void )
83 {
84    /* restore old handler */
85    (void) XSetErrorHandler( old_xerror_handler );
86    /* return 0=no error, 1=error caught */
87    return caught_xgetimage_error;
88 }
89
90
91 /*
92  * Read a pixel from an X drawable.
93  */
94 static unsigned long read_pixel( XMesaDisplay *dpy,
95                                  XMesaDrawable d, int x, int y )
96 {
97    unsigned long p;
98    XMesaImage *pixel = NULL;
99    int error;
100
101    catch_xgetimage_errors( dpy );
102    pixel = XGetImage( dpy, d, x, y, 1, 1, AllPlanes, ZPixmap );
103    error = check_xgetimage_errors();
104    if (pixel && !error) {
105       p = XMesaGetPixel( pixel, 0, 0 );
106    }
107    else {
108       p = 0;
109    }
110    if (pixel) {
111       XMesaDestroyImage( pixel );
112    }
113    return p;
114 }
115
116
117
118 /*
119  * The Mesa library needs to be able to draw pixels in a number of ways:
120  *   1. RGB vs Color Index
121  *   2. as horizontal spans (polygons, images) vs random locations (points,
122  *      lines)
123  *   3. different color per-pixel or same color for all pixels
124  *
125  * Furthermore, the X driver needs to support rendering to 3 possible
126  * "buffers", usually one, but sometimes two at a time:
127  *   1. The front buffer as an X window
128  *   2. The back buffer as a Pixmap
129  *   3. The back buffer as an XImage
130  *
131  * Finally, if the back buffer is an XImage, we can avoid using XPutPixel and
132  * optimize common cases such as 24-bit and 8-bit modes.
133  *
134  * By multiplication, there's at least 48 possible combinations of the above.
135  *
136  * Below are implementations of the most commonly used combinations.  They are
137  * accessed through function pointers which get initialized here and are used
138  * directly from the Mesa library.  The 8 function pointers directly correspond
139  * to the first 3 cases listed above.
140  *
141  *
142  * The function naming convention is:
143  *
144  *   [put|get]_[mono]_[row|values]_[format]_[pixmap|ximage]
145  *
146  * New functions optimized for specific cases can be added without too much
147  * trouble.  An example might be the 24-bit TrueColor mode 8A8R8G8B which is
148  * found on IBM RS/6000 X servers.
149  */
150
151
152
153
154 /**********************************************************************/
155 /*** Write COLOR SPAN functions                                     ***/
156 /**********************************************************************/
157
158
159 #define PUT_ROW_ARGS \
160         struct gl_context *ctx,                                 \
161         struct gl_renderbuffer *rb,                     \
162         GLuint n, GLint x, GLint y,                     \
163         const void *values, const GLubyte mask[]
164
165 #define RGB_SPAN_ARGS \
166         struct gl_context *ctx,                                 \
167         struct gl_renderbuffer *rb,                     \
168         GLuint n, GLint x, GLint y,                     \
169         const void *values, const GLubyte mask[]
170
171
172 #define GET_XRB(XRB) \
173    struct xmesa_renderbuffer *XRB = xmesa_renderbuffer(rb)
174
175
176 /*
177  * Write a span of PF_TRUECOLOR pixels to a pixmap.
178  */
179 static void put_row_TRUECOLOR_pixmap( PUT_ROW_ARGS )
180 {
181    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
182    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
183    GET_XRB(xrb);
184    XMesaDisplay *dpy = XMESA_BUFFER(ctx->DrawBuffer)->display;
185    XMesaDrawable buffer = xrb->drawable;
186    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
187    register GLuint i;
188
189    y = YFLIP(xrb, y);
190    if (mask) {
191       for (i=0;i<n;i++,x++) {
192          if (mask[i]) {
193             unsigned long p;
194             PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
195             XMesaSetForeground( dpy, gc, p );
196             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
197          }
198       }
199    }
200    else {
201       /* draw all pixels */
202       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
203       for (i=0;i<n;i++) {
204          unsigned long p;
205          PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
206          XMesaPutPixel( rowimg, i, 0, p );
207       }
208       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
209    }
210 }
211
212
213 /*
214  * Write a span of PF_TRUECOLOR pixels to a pixmap.
215  */
216 static void put_row_rgb_TRUECOLOR_pixmap( RGB_SPAN_ARGS )
217 {
218    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
219    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
220    GET_XRB(xrb);
221    XMesaDisplay *dpy = xmesa->xm_visual->display;
222    XMesaDrawable buffer = xrb->drawable;
223    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
224    register GLuint i;
225    y = YFLIP(xrb, y);
226    if (mask) {
227       for (i=0;i<n;i++,x++) {
228          if (mask[i]) {
229             unsigned long p;
230             PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
231             XMesaSetForeground( dpy, gc, p );
232             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
233          }
234       }
235    }
236    else {
237       /* draw all pixels */
238       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
239       for (i=0;i<n;i++) {
240          unsigned long p;
241          PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
242          XMesaPutPixel( rowimg, i, 0, p );
243       }
244       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
245    }
246 }
247
248 /*
249  * Write a span of PF_TRUEDITHER pixels to a pixmap.
250  */
251 static void put_row_TRUEDITHER_pixmap( PUT_ROW_ARGS )
252 {
253    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
254    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
255    GET_XRB(xrb);
256    XMesaDisplay *dpy = xmesa->xm_visual->display;
257    XMesaDrawable buffer = xrb->drawable;
258    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
259    register GLuint i;
260    y = YFLIP(xrb, y);
261    if (mask) {
262       for (i=0;i<n;i++,x++) {
263          if (mask[i]) {
264             unsigned long p;
265             PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
266             XMesaSetForeground( dpy, gc, p );
267             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
268          }
269       }
270    }
271    else {
272       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
273       for (i=0;i<n;i++) {
274          unsigned long p;
275          PACK_TRUEDITHER(p, x+i, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
276          XMesaPutPixel( rowimg, i, 0, p );
277       }
278       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
279    }
280 }
281
282
283 /*
284  * Write a span of PF_TRUEDITHER pixels to a pixmap (no alpha).
285  */
286 static void put_row_rgb_TRUEDITHER_pixmap( RGB_SPAN_ARGS )
287 {
288    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
289    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
290    GET_XRB(xrb);
291    XMesaDisplay *dpy = xmesa->xm_visual->display;
292    XMesaDrawable buffer = xrb->drawable;
293    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
294    register GLuint i;
295    y = YFLIP(xrb, y);
296    if (mask) {
297       for (i=0;i<n;i++,x++) {
298          if (mask[i]) {
299             unsigned long p;
300             PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
301             XMesaSetForeground( dpy, gc, p );
302             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
303          }
304       }
305    }
306    else {
307       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
308       for (i=0;i<n;i++) {
309          unsigned long p;
310          PACK_TRUEDITHER(p, x+i, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
311          XMesaPutPixel( rowimg, i, 0, p );
312       }
313       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
314    }
315 }
316
317
318 /*
319  * Write a span of PF_8A8B8G8R pixels to a pixmap.
320  */
321 static void put_row_8A8B8G8R_pixmap( PUT_ROW_ARGS )
322 {
323    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
324    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
325    GET_XRB(xrb);
326    XMesaDisplay *dpy = xmesa->xm_visual->display;
327    XMesaDrawable buffer = xrb->drawable;
328    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
329    register GLuint i;
330    y = YFLIP(xrb, y);
331    if (mask) {
332       for (i=0;i<n;i++,x++) {
333          if (mask[i]) {
334             XMesaSetForeground( dpy, gc,
335                          PACK_8A8B8G8R(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP]) );
336             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
337          }
338       }
339    }
340    else {
341       /* draw all pixels */
342       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
343       register GLuint *ptr4 = (GLuint *) rowimg->data;
344       for (i=0;i<n;i++) {
345          *ptr4++ = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
346       }
347       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
348    }
349 }
350
351
352 /*
353  * Write a span of PF_8A8B8G8R pixels to a pixmap (no alpha).
354  */
355 static void put_row_rgb_8A8B8G8R_pixmap( RGB_SPAN_ARGS )
356 {
357    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
358    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
359    GET_XRB(xrb);
360    XMesaDisplay *dpy = xmesa->xm_visual->display;
361    XMesaDrawable buffer = xrb->drawable;
362    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
363    register GLuint i;
364    y = YFLIP(xrb, y);
365    if (mask) {
366       for (i=0;i<n;i++,x++) {
367          if (mask[i]) {
368             XMesaSetForeground( dpy, gc,
369                    PACK_8B8G8R(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
370             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
371          }
372       }
373    }
374    else {
375       /* draw all pixels */
376       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
377       register GLuint *ptr4 = (GLuint *) rowimg->data;
378       for (i=0;i<n;i++) {
379          *ptr4++ = PACK_8B8G8R(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
380       }
381       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
382    }
383 }
384
385 /*
386  * Write a span of PF_8A8R8G8B pixels to a pixmap.
387  */
388 static void put_row_8A8R8G8B_pixmap( PUT_ROW_ARGS )
389 {
390    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
391    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
392    GET_XRB(xrb);
393    XMesaDisplay *dpy = xmesa->xm_visual->display;
394    XMesaDrawable buffer = xrb->drawable;
395    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
396    register GLuint i;
397    y = YFLIP(xrb, y);
398    if (mask) {
399       for (i=0;i<n;i++,x++) {
400          if (mask[i]) {
401             XMesaSetForeground( dpy, gc,
402                          PACK_8A8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP]) );
403             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
404          }
405       }
406    }
407    else {
408       /* draw all pixels */
409       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
410       register GLuint *ptr4 = (GLuint *) rowimg->data;
411       for (i=0;i<n;i++) {
412          *ptr4++ = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
413       }
414       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
415    }
416 }
417
418
419 /*
420  * Write a span of PF_8A8R8G8B pixels to a pixmap (no alpha).
421  */
422 static void put_row_rgb_8A8R8G8B_pixmap( RGB_SPAN_ARGS )
423 {
424    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
425    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
426    GET_XRB(xrb);
427    XMesaDisplay *dpy = xmesa->xm_visual->display;
428    XMesaDrawable buffer = xrb->drawable;
429    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
430    register GLuint i;
431    y = YFLIP(xrb, y);
432    if (mask) {
433       for (i=0;i<n;i++,x++) {
434          if (mask[i]) {
435             XMesaSetForeground( dpy, gc,
436                    PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
437             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
438          }
439       }
440    }
441    else {
442       /* draw all pixels */
443       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
444       register GLuint *ptr4 = (GLuint *) rowimg->data;
445       for (i=0;i<n;i++) {
446          *ptr4++ = PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
447       }
448       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
449    }
450 }
451
452 /*
453  * Write a span of PF_8R8G8B pixels to a pixmap.
454  */
455 static void put_row_8R8G8B_pixmap( PUT_ROW_ARGS )
456 {
457    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
458    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
459    GET_XRB(xrb);
460    XMesaDisplay *dpy = xmesa->xm_visual->display;
461    XMesaDrawable buffer = xrb->drawable;
462    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
463    register GLuint i;
464    y = YFLIP(xrb, y);
465    if (mask) {
466       for (i=0;i<n;i++,x++) {
467          if (mask[i]) {
468 #if 1
469             /*
470              * XXX Something funny is going on here.
471              * If we're drawing into a window that uses a depth 32 TrueColor
472              * visual, we see the right pixels on screen, but when we read
473              * them back with XGetImage() we get random colors.
474              * The alternative code below which uses XPutImage() instead
475              * seems to mostly fix the problem, but not always.
476              * We don't normally create windows with this visual, but glean
477              * does and we're seeing some failures there.
478              */
479             XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
480             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
481 #else
482             /* This code works more often, but not always */
483             XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
484             GLuint *ptr4 = (GLuint *) rowimg->data;
485             *ptr4 = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
486             XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, 1, 1 );
487 #endif
488          }
489       }
490    }
491    else {
492       /* draw all pixels */
493       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
494       register GLuint *ptr4 = (GLuint *) rowimg->data;
495       for (i=0;i<n;i++) {
496          *ptr4++ = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
497       }
498       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
499    }
500 }
501
502
503 /*
504  * Write a span of PF_8R8G8B24 pixels to a pixmap.
505  */
506 static void put_row_8R8G8B24_pixmap( PUT_ROW_ARGS )
507 {
508    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
509    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
510    GET_XRB(xrb);
511    XMesaDisplay *dpy = xmesa->xm_visual->display;
512    XMesaDrawable buffer = xrb->drawable;
513    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
514    y = YFLIP(xrb, y);
515    if (mask) {
516       register GLuint i;
517       for (i=0;i<n;i++,x++) {
518          if (mask[i]) {
519             XMesaSetForeground( dpy, gc,
520                PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
521             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
522          }
523       }
524    }
525    else {
526       /* draw all pixels */
527       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
528       register GLuint *ptr4 = (GLuint *) rowimg->data;
529       register GLuint pixel;
530       static const GLuint shift[4] = {0, 8, 16, 24};
531       register GLuint i = 0;
532       int w = n;
533       while (w > 3) {
534          pixel  = rgba[i][BCOMP] /* << shift[0]*/;
535          pixel |= rgba[i][GCOMP]    << shift[1];
536          pixel |= rgba[i++][RCOMP]  << shift[2];
537          pixel |= rgba[i][BCOMP]    << shift[3];
538          *ptr4++ = pixel;
539
540          pixel  = rgba[i][GCOMP] /* << shift[0]*/;
541          pixel |= rgba[i++][RCOMP]  << shift[1];
542          pixel |= rgba[i][BCOMP]    << shift[2];
543          pixel |= rgba[i][GCOMP]    << shift[3];
544          *ptr4++ = pixel;
545
546          pixel  = rgba[i++][RCOMP]/* << shift[0]*/;
547          pixel |= rgba[i][BCOMP]     << shift[1];
548          pixel |= rgba[i][GCOMP]     << shift[2];
549          pixel |= rgba[i++][RCOMP]   << shift[3];
550          *ptr4++ = pixel;
551
552          w -= 4;
553       }
554       switch (w) {
555          case 3:
556             pixel = 0;
557             pixel |= rgba[i][BCOMP] /*<< shift[0]*/;
558             pixel |= rgba[i][GCOMP]   << shift[1];
559             pixel |= rgba[i++][RCOMP] << shift[2];
560             pixel |= rgba[i][BCOMP]   << shift[3];
561             *ptr4++ = pixel;
562             pixel = 0;
563             pixel |= rgba[i][GCOMP] /*<< shift[0]*/;
564             pixel |= rgba[i++][RCOMP] << shift[1];
565             pixel |= rgba[i][BCOMP]   << shift[2];
566             pixel |= rgba[i][GCOMP]   << shift[3];
567             *ptr4++ = pixel;
568             pixel = 0xffffff00 & *ptr4;
569             pixel |= rgba[i][RCOMP] /*<< shift[0]*/;
570             *ptr4 = pixel;
571             break;
572          case 2:
573             pixel = 0;
574             pixel |= rgba[i][BCOMP] /*<< shift[0]*/;
575             pixel |= rgba[i][GCOMP]   << shift[1];
576             pixel |= rgba[i++][RCOMP] << shift[2];
577             pixel |= rgba[i][BCOMP]   << shift[3];
578             *ptr4++ = pixel;
579             pixel = 0xffff0000 & *ptr4;
580             pixel |= rgba[i][GCOMP] /*<< shift[0]*/;
581             pixel |= rgba[i][RCOMP]   << shift[1];
582             *ptr4 = pixel;
583             break;
584          case 1:
585             pixel = 0xff000000 & *ptr4;
586             pixel |= rgba[i][BCOMP] /*<< shift[0]*/;
587             pixel |= rgba[i][GCOMP] << shift[1];
588             pixel |= rgba[i][RCOMP] << shift[2];
589             *ptr4 = pixel;
590             break;
591          case 0:
592             break;
593       }
594       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
595    }
596 }
597
598
599 /*
600  * Write a span of PF_8R8G8B pixels to a pixmap (no alpha).
601  */
602 static void put_row_rgb_8R8G8B_pixmap( RGB_SPAN_ARGS )
603 {
604    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
605    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
606    GET_XRB(xrb);
607    XMesaDisplay *dpy = xmesa->xm_visual->display;
608    XMesaDrawable buffer = xrb->drawable;
609    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
610    register GLuint i;
611    y = YFLIP(xrb, y);
612    if (mask) {
613       for (i=0;i<n;i++,x++) {
614          if (mask[i]) {
615             XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ));
616             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
617          }
618       }
619    }
620    else {
621       /* draw all pixels */
622       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
623       register GLuint *ptr4 = (GLuint *) rowimg->data;
624       for (i=0;i<n;i++) {
625          *ptr4++ = PACK_8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
626       }
627       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
628    }
629 }
630
631 /*
632  * Write a span of PF_8R8G8B24 pixels to a pixmap (no alpha).
633  */
634 static void put_row_rgb_8R8G8B24_pixmap( RGB_SPAN_ARGS )
635 {
636    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
637    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
638    GET_XRB(xrb);
639    XMesaDisplay *dpy = xmesa->xm_visual->display;
640    XMesaDrawable buffer = xrb->drawable;
641    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
642    y = YFLIP(xrb, y);
643    if (mask) {
644       register GLuint i;
645       for (i=0;i<n;i++,x++) {
646          if (mask[i]) {
647             XMesaSetForeground( dpy, gc,
648                   PACK_8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ));
649             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
650          }
651       }
652    }
653    else {
654       /* draw all pixels */
655       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
656       register GLuint *ptr4 = (GLuint *) rowimg->data;
657       register GLuint pixel;
658       static const GLuint shift[4] = {0, 8, 16, 24};
659       unsigned w = n;
660       register GLuint i = 0;
661       while (w > 3) {
662          pixel = 0;
663          pixel |= rgb[i][BCOMP]/* << shift[0]*/;
664          pixel |= rgb[i][GCOMP] << shift[1];
665          pixel |= rgb[i++][RCOMP] << shift[2];
666          pixel |= rgb[i][BCOMP] <<shift[3];
667          *ptr4++ = pixel;
668
669          pixel = 0;
670          pixel |= rgb[i][GCOMP]/* << shift[0]*/;
671          pixel |= rgb[i++][RCOMP] << shift[1];
672          pixel |= rgb[i][BCOMP] << shift[2];
673          pixel |= rgb[i][GCOMP] << shift[3];
674          *ptr4++ = pixel;
675
676          pixel = 0;
677          pixel |= rgb[i++][RCOMP]/* << shift[0]*/;
678          pixel |= rgb[i][BCOMP] << shift[1];
679          pixel |= rgb[i][GCOMP] << shift[2];
680          pixel |= rgb[i++][RCOMP] << shift[3];
681          *ptr4++ = pixel;
682          w -= 4;
683       }
684       switch (w) {
685          case 3:
686             pixel = 0;
687             pixel |= rgb[i][BCOMP]/* << shift[0]*/;
688             pixel |= rgb[i][GCOMP] << shift[1];
689             pixel |= rgb[i++][RCOMP] << shift[2];
690             pixel |= rgb[i][BCOMP] << shift[3];
691             *ptr4++ = pixel;
692             pixel = 0;
693             pixel |= rgb[i][GCOMP]/* << shift[0]*/;
694             pixel |= rgb[i++][RCOMP] << shift[1];
695             pixel |= rgb[i][BCOMP] << shift[2];
696             pixel |= rgb[i][GCOMP] << shift[3];
697             *ptr4++ = pixel;
698             pixel = *ptr4;
699             pixel &= 0xffffff00;
700             pixel |= rgb[i++][RCOMP]/* << shift[0]*/;
701             *ptr4++ = pixel;
702             break;
703          case 2:
704             pixel = 0;
705             pixel |= rgb[i][BCOMP]/* << shift[0]*/;
706             pixel |= rgb[i][GCOMP] << shift[1];
707             pixel |= rgb[i++][RCOMP] << shift[2];
708             pixel |= rgb[i][BCOMP]  << shift[3];
709             *ptr4++ = pixel;
710             pixel = *ptr4;
711             pixel &= 0xffff0000;
712             pixel |= rgb[i][GCOMP]/* << shift[0]*/;
713             pixel |= rgb[i++][RCOMP] << shift[1];
714             *ptr4++ = pixel;
715             break;
716          case 1:
717             pixel = *ptr4;
718             pixel &= 0xff000000;
719             pixel |= rgb[i][BCOMP]/* << shift[0]*/;
720             pixel |= rgb[i][GCOMP] << shift[1];
721             pixel |= rgb[i++][RCOMP] << shift[2];
722             *ptr4++ = pixel;
723             break;
724          case 0:
725             break;
726       }
727       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
728    }
729 }
730
731
732 /*
733  * Write a span of PF_5R6G5B pixels to a pixmap.
734  */
735 static void put_row_5R6G5B_pixmap( PUT_ROW_ARGS )
736 {
737    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
738    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
739    GET_XRB(xrb);
740    XMesaDisplay *dpy = xmesa->xm_visual->display;
741    XMesaDrawable buffer = xrb->drawable;
742    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
743    register GLuint i;
744    y = YFLIP(xrb, y);
745    if (mask) {
746       for (i=0;i<n;i++,x++) {
747          if (mask[i]) {
748             XMesaSetForeground( dpy, gc, PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
749             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
750          }
751       }
752    }
753    else {
754       /* draw all pixels */
755       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
756       register GLushort *ptr2 = (GLushort *) rowimg->data;
757       for (i=0;i<n;i++) {
758          ptr2[i] = PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
759       }
760       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
761    }
762 }
763
764
765 /*
766  * Write a span of PF_DITHER_5R6G5B pixels to a pixmap.
767  */
768 static void put_row_DITHER_5R6G5B_pixmap( PUT_ROW_ARGS )
769 {
770    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
771    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
772    GET_XRB(xrb);
773    XMesaDisplay *dpy = xmesa->xm_visual->display;
774    XMesaDrawable buffer = xrb->drawable;
775    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
776    register GLuint i;
777    y = YFLIP(xrb, y);
778    if (mask) {
779       for (i=0;i<n;i++,x++) {
780          if (mask[i]) {
781             unsigned long p;
782             PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
783             XMesaSetForeground( dpy, gc, p );
784             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
785          }
786       }
787    }
788    else {
789       /* draw all pixels */
790       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
791       register GLushort *ptr2 = (GLushort *) rowimg->data;
792       for (i=0;i<n;i++) {
793          PACK_TRUEDITHER( ptr2[i], x+i, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
794       }
795       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
796    }
797 }
798
799
800 /*
801  * Write a span of PF_5R6G5B pixels to a pixmap (no alpha).
802  */
803 static void put_row_rgb_5R6G5B_pixmap( RGB_SPAN_ARGS )
804 {
805    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
806    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
807    GET_XRB(xrb);
808    XMesaDisplay *dpy = xmesa->xm_visual->display;
809    XMesaDrawable buffer = xrb->drawable;
810    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
811    register GLuint i;
812    y = YFLIP(xrb, y);
813    if (mask) {
814       for (i=0;i<n;i++,x++) {
815          if (mask[i]) {
816             XMesaSetForeground( dpy, gc, PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ));
817             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
818          }
819       }
820    }
821    else {
822       /* draw all pixels */
823       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
824       register GLushort *ptr2 = (GLushort *) rowimg->data;
825       for (i=0;i<n;i++) {
826          ptr2[i] = PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
827       }
828       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
829    }
830 }
831
832
833 /*
834  * Write a span of PF_DITHER_5R6G5B pixels to a pixmap (no alpha).
835  */
836 static void put_row_rgb_DITHER_5R6G5B_pixmap( RGB_SPAN_ARGS )
837 {
838    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
839    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
840    GET_XRB(xrb);
841    XMesaDisplay *dpy = xmesa->xm_visual->display;
842    XMesaDrawable buffer = xrb->drawable;
843    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
844    register GLuint i;
845    y = YFLIP(xrb, y);
846    if (mask) {
847       for (i=0;i<n;i++,x++) {
848          if (mask[i]) {
849             unsigned long p;
850             PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
851             XMesaSetForeground( dpy, gc, p );
852             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
853          }
854       }
855    }
856    else {
857       /* draw all pixels */
858       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
859       register GLushort *ptr2 = (GLushort *) rowimg->data;
860       for (i=0;i<n;i++) {
861          PACK_TRUEDITHER( ptr2[i], x+i, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
862       }
863       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
864    }
865 }
866
867
868 /*
869  * Write a span of PF_DITHER pixels to a pixmap.
870  */
871 static void put_row_DITHER_pixmap( PUT_ROW_ARGS )
872 {
873    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
874    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
875    GET_XRB(xrb);
876    XMesaDisplay *dpy = xmesa->xm_visual->display;
877    XMesaDrawable buffer = xrb->drawable;
878    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
879    register GLuint i;
880    XDITHER_SETUP(y);
881    y = YFLIP(xrb, y);
882    if (mask) {
883       for (i=0;i<n;i++,x++) {
884          if (mask[i]) {
885             XMesaSetForeground( dpy, gc, XDITHER(x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) );
886             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
887          }
888       }
889    }
890    else {
891       /* draw all pixels */
892       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
893       for (i=0;i<n;i++) {
894          XMesaPutPixel( rowimg, i, 0, XDITHER(x+i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) );
895       }
896       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
897    }
898 }
899
900
901 /*
902  * Write a span of PF_DITHER pixels to a pixmap (no alpha).
903  */
904 static void put_row_rgb_DITHER_pixmap( RGB_SPAN_ARGS )
905 {
906    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
907    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
908    GET_XRB(xrb);
909    XMesaDisplay *dpy = xmesa->xm_visual->display;
910    XMesaDrawable buffer = xrb->drawable;
911    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
912    register GLuint i;
913    XDITHER_SETUP(y);
914    y = YFLIP(xrb, y);
915    if (mask) {
916       for (i=0;i<n;i++,x++) {
917          if (mask[i]) {
918             XMesaSetForeground( dpy, gc, XDITHER(x, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
919             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
920          }
921       }
922    }
923    else {
924       /* draw all pixels */
925       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
926       for (i=0;i<n;i++) {
927          XMesaPutPixel( rowimg, i, 0, XDITHER(x+i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
928       }
929       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
930    }
931 }
932
933
934 /*
935  * Write a span of PF_1BIT pixels to a pixmap.
936  */
937 static void put_row_1BIT_pixmap( PUT_ROW_ARGS )
938 {
939    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
940    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
941    GET_XRB(xrb);
942    XMesaDisplay *dpy = xmesa->xm_visual->display;
943    XMesaDrawable buffer = xrb->drawable;
944    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
945    register GLuint i;
946    SETUP_1BIT;
947    y = YFLIP(xrb, y);
948    if (mask) {
949       for (i=0;i<n;i++,x++) {
950          if (mask[i]) {
951             XMesaSetForeground( dpy, gc,
952                             DITHER_1BIT( x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
953             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
954          }
955       }
956    }
957    else {
958       /* draw all pixels */
959       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
960       for (i=0;i<n;i++) {
961          XMesaPutPixel( rowimg, i, 0,
962                     DITHER_1BIT( x+i, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
963       }
964       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
965    }
966 }
967
968
969 /*
970  * Write a span of PF_1BIT pixels to a pixmap (no alpha).
971  */
972 static void put_row_rgb_1BIT_pixmap( RGB_SPAN_ARGS )
973 {
974    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
975    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
976    GET_XRB(xrb);
977    XMesaDisplay *dpy = xmesa->xm_visual->display;
978    XMesaDrawable buffer = xrb->drawable;
979    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
980    register GLuint i;
981    SETUP_1BIT;
982    y = YFLIP(xrb, y);
983    if (mask) {
984       for (i=0;i<n;i++,x++) {
985          if (mask[i]) {
986             XMesaSetForeground( dpy, gc,
987               DITHER_1BIT(x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
988             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
989          }
990       }
991    }
992    else {
993       /* draw all pixels */
994       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
995       for (i=0;i<n;i++) {
996          XMesaPutPixel( rowimg, i, 0,
997           DITHER_1BIT(x+i, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
998       }
999       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
1000    }
1001 }
1002
1003
1004 /*
1005  * Write a span of PF_HPCR pixels to a pixmap.
1006  */
1007 static void put_row_HPCR_pixmap( PUT_ROW_ARGS )
1008 {
1009    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1010    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1011    GET_XRB(xrb);
1012    XMesaDisplay *dpy = xmesa->xm_visual->display;
1013    XMesaDrawable buffer = xrb->drawable;
1014    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1015    register GLuint i;
1016    y = YFLIP(xrb, y);
1017    if (mask) {
1018       for (i=0;i<n;i++,x++) {
1019          if (mask[i]) {
1020             XMesaSetForeground( dpy, gc,
1021                             DITHER_HPCR( x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
1022             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
1023          }
1024       }
1025    }
1026    else {
1027       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
1028       register GLubyte *ptr = (GLubyte *) XMESA_BUFFER(ctx->DrawBuffer)->rowimage->data;
1029       for (i=0;i<n;i++) {
1030          ptr[i] = DITHER_HPCR( (x+i), y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1031       }
1032       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
1033    }
1034 }
1035
1036
1037 /*
1038  * Write a span of PF_HPCR pixels to a pixmap (no alpha).
1039  */
1040 static void put_row_rgb_HPCR_pixmap( RGB_SPAN_ARGS )
1041 {
1042    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1043    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1044    GET_XRB(xrb);
1045    XMesaDisplay *dpy = xmesa->xm_visual->display;
1046    XMesaDrawable buffer = xrb->drawable;
1047    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1048    register GLuint i;
1049    y = YFLIP(xrb, y);
1050    if (mask) {
1051       for (i=0;i<n;i++,x++) {
1052          if (mask[i]) {
1053             XMesaSetForeground( dpy, gc,
1054               DITHER_HPCR(x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
1055             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
1056          }
1057       }
1058    }
1059    else {
1060       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
1061       register GLubyte *ptr = (GLubyte *) XMESA_BUFFER(ctx->DrawBuffer)->rowimage->data;
1062       for (i=0;i<n;i++) {
1063          ptr[i] = DITHER_HPCR( (x+i), y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1064       }
1065       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
1066    }
1067 }
1068
1069 /*
1070  * Write a span of PF_LOOKUP pixels to a pixmap.
1071  */
1072 static void put_row_LOOKUP_pixmap( PUT_ROW_ARGS )
1073 {
1074    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1075    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1076    GET_XRB(xrb);
1077    XMesaDisplay *dpy = xmesa->xm_visual->display;
1078    XMesaDrawable buffer = xrb->drawable;
1079    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1080    register GLuint i;
1081    LOOKUP_SETUP;
1082    y = YFLIP(xrb, y);
1083    if (mask) {
1084       for (i=0;i<n;i++,x++) {
1085          if (mask[i]) {
1086             XMesaSetForeground( dpy, gc, LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
1087             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
1088          }
1089       }
1090    }
1091    else {
1092       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
1093       for (i=0;i<n;i++) {
1094          XMesaPutPixel( rowimg, i, 0, LOOKUP(rgba[i][RCOMP],rgba[i][GCOMP],rgba[i][BCOMP]) );
1095       }
1096       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
1097    }
1098 }
1099
1100
1101 /*
1102  * Write a span of PF_LOOKUP pixels to a pixmap (no alpha).
1103  */
1104 static void put_row_rgb_LOOKUP_pixmap( RGB_SPAN_ARGS )
1105 {
1106    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1107    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1108    GET_XRB(xrb);
1109    XMesaDisplay *dpy = xmesa->xm_visual->display;
1110    XMesaDrawable buffer = xrb->drawable;
1111    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1112    register GLuint i;
1113    LOOKUP_SETUP;
1114    y = YFLIP(xrb, y);
1115    if (mask) {
1116       for (i=0;i<n;i++,x++) {
1117          if (mask[i]) {
1118             XMesaSetForeground( dpy, gc, LOOKUP( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) );
1119             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
1120          }
1121       }
1122    }
1123    else {
1124       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
1125       for (i=0;i<n;i++) {
1126          XMesaPutPixel( rowimg, i, 0, LOOKUP(rgb[i][RCOMP],rgb[i][GCOMP],rgb[i][BCOMP]) );
1127       }
1128       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
1129    }
1130 }
1131
1132
1133 /*
1134  * Write a span of PF_GRAYSCALE pixels to a pixmap.
1135  */
1136 static void put_row_GRAYSCALE_pixmap( PUT_ROW_ARGS )
1137 {
1138    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1139    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1140    GET_XRB(xrb);
1141    XMesaDisplay *dpy = xmesa->xm_visual->display;
1142    XMesaDrawable buffer = xrb->drawable;
1143    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1144    register GLuint i;
1145    y = YFLIP(xrb, y);
1146    if (mask) {
1147       for (i=0;i<n;i++,x++) {
1148          if (mask[i]) {
1149             XMesaSetForeground( dpy, gc, GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
1150             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
1151          }
1152       }
1153    }
1154    else {
1155       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
1156       for (i=0;i<n;i++) {
1157          XMesaPutPixel( rowimg, i, 0, GRAY_RGB(rgba[i][RCOMP],rgba[i][GCOMP],rgba[i][BCOMP]) );
1158       }
1159       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
1160    }
1161 }
1162
1163
1164 /*
1165  * Write a span of PF_GRAYSCALE pixels to a pixmap (no alpha).
1166  */
1167 static void put_row_rgb_GRAYSCALE_pixmap( RGB_SPAN_ARGS )
1168 {
1169    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1170    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1171    GET_XRB(xrb);
1172    XMesaDisplay *dpy = xmesa->xm_visual->display;
1173    XMesaDrawable buffer = xrb->drawable;
1174    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
1175    register GLuint i;
1176    y = YFLIP(xrb, y);
1177    if (mask) {
1178       for (i=0;i<n;i++,x++) {
1179          if (mask[i]) {
1180             XMesaSetForeground( dpy, gc, GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) );
1181             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
1182          }
1183       }
1184    }
1185    else {
1186       XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage;
1187       for (i=0;i<n;i++) {
1188          XMesaPutPixel( rowimg, i, 0, GRAY_RGB(rgb[i][RCOMP],rgb[i][GCOMP],rgb[i][BCOMP]) );
1189       }
1190       XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 );
1191    }
1192 }
1193
1194 /*
1195  * Write a span of PF_TRUECOLOR pixels to an XImage.
1196  */
1197 static void put_row_TRUECOLOR_ximage( PUT_ROW_ARGS )
1198 {
1199    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1200    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1201    GET_XRB(xrb);
1202    XMesaImage *img = xrb->ximage;
1203    register GLuint i;
1204    y = YFLIP(xrb, y);
1205    if (mask) {
1206       for (i=0;i<n;i++,x++) {
1207          if (mask[i]) {
1208             unsigned long p;
1209             PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1210             XMesaPutPixel( img, x, y, p );
1211          }
1212       }
1213    }
1214    else {
1215       /* draw all pixels */
1216       for (i=0;i<n;i++,x++) {
1217          unsigned long p;
1218          PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1219          XMesaPutPixel( img, x, y, p );
1220       }
1221    }
1222 }
1223
1224
1225 /*
1226  * Write a span of PF_TRUECOLOR pixels to an XImage (no alpha).
1227  */
1228 static void put_row_rgb_TRUECOLOR_ximage( RGB_SPAN_ARGS )
1229 {
1230    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1231    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1232    GET_XRB(xrb);
1233    XMesaImage *img = xrb->ximage;
1234    register GLuint i;
1235    y = YFLIP(xrb, y);
1236    if (mask) {
1237       for (i=0;i<n;i++,x++) {
1238          if (mask[i]) {
1239             unsigned long p;
1240             PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1241             XMesaPutPixel( img, x, y, p );
1242          }
1243       }
1244    }
1245    else {
1246       /* draw all pixels */
1247       for (i=0;i<n;i++,x++) {
1248          unsigned long p;
1249          PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1250          XMesaPutPixel( img, x, y, p );
1251       }
1252    }
1253 }
1254
1255
1256 /*
1257  * Write a span of PF_TRUEDITHER pixels to an XImage.
1258  */
1259 static void put_row_TRUEDITHER_ximage( PUT_ROW_ARGS )
1260 {
1261    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1262    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1263    GET_XRB(xrb);
1264    XMesaImage *img = xrb->ximage;
1265    register GLuint i;
1266    y = YFLIP(xrb, y);
1267    if (mask) {
1268       for (i=0;i<n;i++,x++) {
1269          if (mask[i]) {
1270             unsigned long p;
1271             PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1272             XMesaPutPixel( img, x, y, p );
1273          }
1274       }
1275    }
1276    else {
1277       /* draw all pixels */
1278       for (i=0;i<n;i++,x++) {
1279          unsigned long p;
1280          PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1281          XMesaPutPixel( img, x, y, p );
1282       }
1283    }
1284 }
1285
1286
1287 /*
1288  * Write a span of PF_TRUEDITHER pixels to an XImage (no alpha).
1289  */
1290 static void put_row_rgb_TRUEDITHER_ximage( RGB_SPAN_ARGS )
1291 {
1292    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1293    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1294    GET_XRB(xrb);
1295    XMesaImage *img = xrb->ximage;
1296    register GLuint i;
1297    y = YFLIP(xrb, y);
1298    if (mask) {
1299       for (i=0;i<n;i++,x++) {
1300          if (mask[i]) {
1301             unsigned long p;
1302             PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1303             XMesaPutPixel( img, x, y, p );
1304          }
1305       }
1306    }
1307    else {
1308       /* draw all pixels */
1309       for (i=0;i<n;i++,x++) {
1310          unsigned long p;
1311          PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1312          XMesaPutPixel( img, x, y, p );
1313       }
1314    }
1315 }
1316
1317
1318 /*
1319  * Write a span of PF_8A8B8G8R-format pixels to an ximage.
1320  */
1321 static void put_row_8A8B8G8R_ximage( PUT_ROW_ARGS )
1322 {
1323    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1324    GET_XRB(xrb);
1325    register GLuint i;
1326    register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1327    (void) ctx;
1328    if (mask) {
1329       for (i=0;i<n;i++) {
1330          if (mask[i]) {
1331             ptr[i] = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1332          }
1333       }
1334    }
1335    else {
1336       /* draw all pixels */
1337       for (i=0;i<n;i++) {
1338          ptr[i] = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1339       }
1340    }
1341 }
1342
1343
1344 /*
1345  * Write a span of PF_8A8B8G8R-format pixels to an ximage (no alpha).
1346  */
1347 static void put_row_rgb_8A8B8G8R_ximage( RGB_SPAN_ARGS )
1348 {
1349    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1350    GET_XRB(xrb);
1351    register GLuint i;
1352    register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1353    if (mask) {
1354       for (i=0;i<n;i++) {
1355          if (mask[i]) {
1356             ptr[i] = PACK_8A8B8G8R( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
1357          }
1358       }
1359    }
1360    else {
1361       /* draw all pixels */
1362       for (i=0;i<n;i++) {
1363          ptr[i] = PACK_8A8B8G8R( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
1364       }
1365    }
1366 }
1367
1368 /*
1369  * Write a span of PF_8A8R8G8B-format pixels to an ximage.
1370  */
1371 static void put_row_8A8R8G8B_ximage( PUT_ROW_ARGS )
1372 {
1373    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1374    GET_XRB(xrb);
1375    register GLuint i;
1376    register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1377    if (mask) {
1378       for (i=0;i<n;i++) {
1379          if (mask[i]) {
1380             ptr[i] = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1381          }
1382       }
1383    }
1384    else {
1385       /* draw all pixels */
1386       for (i=0;i<n;i++) {
1387          ptr[i] = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
1388       }
1389    }
1390 }
1391
1392
1393 /*
1394  * Write a span of PF_8A8R8G8B-format pixels to an ximage (no alpha).
1395  */
1396 static void put_row_rgb_8A8R8G8B_ximage( RGB_SPAN_ARGS )
1397 {
1398    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1399    GET_XRB(xrb);
1400    register GLuint i;
1401    register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1402    if (mask) {
1403       for (i=0;i<n;i++) {
1404          if (mask[i]) {
1405             ptr[i] = PACK_8A8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
1406          }
1407       }
1408    }
1409    else {
1410       /* draw all pixels */
1411       for (i=0;i<n;i++) {
1412          ptr[i] = PACK_8A8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
1413       }
1414    }
1415 }
1416
1417
1418 /*
1419  * Write a span of PF_8R8G8B-format pixels to an ximage.
1420  */
1421 static void put_row_8R8G8B_ximage( PUT_ROW_ARGS )
1422 {
1423    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1424    GET_XRB(xrb);
1425    register GLuint i;
1426    register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1427    if (mask) {
1428       for (i=0;i<n;i++) {
1429          if (mask[i]) {
1430             ptr[i] = PACK_8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1431          }
1432       }
1433    }
1434    else {
1435       for (i=0;i<n;i++) {
1436          ptr[i] = PACK_8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1437       }
1438    }
1439 }
1440
1441
1442 /*
1443  * Write a span of PF_8R8G8B24-format pixels to an ximage.
1444  */
1445 static void put_row_8R8G8B24_ximage( PUT_ROW_ARGS )
1446 {
1447    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1448    GET_XRB(xrb);
1449    register GLuint i;
1450    register GLubyte *ptr = (GLubyte *) PIXEL_ADDR3(xrb, x, y );
1451    if (mask) {
1452       for (i=0;i<n;i++) {
1453          if (mask[i]) {
1454             GLuint *ptr4 = (GLuint *) ptr;
1455             register GLuint pixel = *ptr4;
1456             switch (3 & (int)(ptr - (GLubyte*)ptr4)) {
1457                case 0:
1458                   pixel &= 0xff000000;
1459                   pixel |= rgba[i][BCOMP];
1460                   pixel |= rgba[i][GCOMP] << 8;
1461                   pixel |= rgba[i][RCOMP] << 16;
1462                   *ptr4 = pixel;
1463                   break;
1464                case 3:
1465                   pixel &= 0x00ffffff;
1466                   pixel |= rgba[i][BCOMP] << 24;
1467                   *ptr4++ = pixel;
1468                   pixel = *ptr4 & 0xffff0000;
1469                   pixel |= rgba[i][GCOMP];
1470                   pixel |= rgba[i][RCOMP] << 8;
1471                   *ptr4 = pixel;
1472                   break;
1473                case 2:
1474                   pixel &= 0x0000ffff;
1475                   pixel |= rgba[i][BCOMP] << 16;
1476                   pixel |= rgba[i][GCOMP] << 24;
1477                   *ptr4++ = pixel;
1478                   pixel = *ptr4 & 0xffffff00;
1479                   pixel |= rgba[i][RCOMP];
1480                   *ptr4 = pixel;
1481                   break;
1482                case 1:
1483                   pixel &= 0x000000ff;
1484                   pixel |= rgba[i][BCOMP] << 8;
1485                   pixel |= rgba[i][GCOMP] << 16;
1486                   pixel |= rgba[i][RCOMP] << 24;
1487                   *ptr4 = pixel;
1488                   break;
1489             }
1490          }
1491          ptr += 3;
1492       }
1493    }
1494    else {
1495       /* write all pixels */
1496       int w = n;
1497       GLuint *ptr4 = (GLuint *) ptr;
1498       register GLuint pixel = *ptr4;
1499       int index = (int)(ptr - (GLubyte *)ptr4);
1500       register GLuint i = 0;
1501       switch (index) {
1502          case 0:
1503             break;
1504          case 1:
1505             pixel &= 0x00ffffff;
1506             pixel |= rgba[i][BCOMP] << 24;
1507             *ptr4++ = pixel;
1508             pixel = *ptr4 & 0xffff0000;
1509             pixel |= rgba[i][GCOMP];
1510             pixel |= rgba[i++][RCOMP] << 8;
1511             *ptr4 = pixel;
1512             if (0 == --w)
1513                break;
1514          case 2:
1515             pixel &= 0x0000ffff;
1516             pixel |= rgba[i][BCOMP] << 16;
1517             pixel |= rgba[i][GCOMP] << 24;
1518             *ptr4++ = pixel;
1519             pixel = *ptr4 & 0xffffff00;
1520             pixel |= rgba[i++][RCOMP];
1521             *ptr4 = pixel;
1522             if (0 == --w)
1523                break;
1524          case 3:
1525             pixel &= 0x000000ff;
1526             pixel |= rgba[i][BCOMP] << 8;
1527             pixel |= rgba[i][GCOMP] << 16;
1528             pixel |= rgba[i++][RCOMP] << 24;
1529             *ptr4++ = pixel;
1530             if (0 == --w)
1531                break;
1532             break;
1533       }
1534       while (w > 3) {
1535          pixel = rgba[i][BCOMP];
1536          pixel |= rgba[i][GCOMP] << 8;
1537          pixel |= rgba[i++][RCOMP] << 16;
1538          pixel |= rgba[i][BCOMP] << 24;
1539          *ptr4++ = pixel;
1540          pixel = rgba[i][GCOMP];
1541          pixel |= rgba[i++][RCOMP] << 8;
1542          pixel |= rgba[i][BCOMP] << 16;
1543          pixel |= rgba[i][GCOMP] << 24;
1544          *ptr4++ = pixel;
1545          pixel = rgba[i++][RCOMP];
1546          pixel |= rgba[i][BCOMP] << 8;
1547          pixel |= rgba[i][GCOMP] << 16;
1548          pixel |= rgba[i++][RCOMP] << 24;
1549          *ptr4++ = pixel;
1550          w -= 4;
1551       }
1552       switch (w) {
1553          case 0:
1554             break;
1555          case 1:
1556             pixel = *ptr4 & 0xff000000;
1557             pixel |= rgba[i][BCOMP];
1558             pixel |= rgba[i][GCOMP] << 8;
1559             pixel |= rgba[i][RCOMP] << 16;
1560             *ptr4 = pixel;
1561             break;
1562          case 2:
1563             pixel = rgba[i][BCOMP];
1564             pixel |= rgba[i][GCOMP] << 8;
1565             pixel |= rgba[i++][RCOMP] << 16;
1566             pixel |= rgba[i][BCOMP] << 24;
1567             *ptr4++ = pixel;
1568             pixel = *ptr4 & 0xffff0000;
1569             pixel |= rgba[i][GCOMP];
1570             pixel |= rgba[i][RCOMP] << 8;
1571             *ptr4 = pixel;
1572             break;
1573          case 3:
1574             pixel = rgba[i][BCOMP];
1575             pixel |= rgba[i][GCOMP] << 8;
1576             pixel |= rgba[i++][RCOMP] << 16;
1577             pixel |= rgba[i][BCOMP] << 24;
1578             *ptr4++ = pixel;
1579             pixel = rgba[i][GCOMP];
1580             pixel |= rgba[i++][RCOMP] << 8;
1581             pixel |= rgba[i][BCOMP] << 16;
1582             pixel |= rgba[i][GCOMP] << 24;
1583             *ptr4++ = pixel;
1584             pixel = *ptr4 & 0xffffff00;
1585             pixel |= rgba[i][RCOMP];
1586             *ptr4 = pixel;
1587             break;
1588       }
1589    }
1590 }
1591
1592
1593 /*
1594  * Write a span of PF_8R8G8B-format pixels to an ximage (no alpha).
1595  */
1596 static void put_row_rgb_8R8G8B_ximage( RGB_SPAN_ARGS )
1597 {
1598    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1599    GET_XRB(xrb);
1600    register GLuint i;
1601    register GLuint *ptr = PIXEL_ADDR4(xrb, x, y);
1602    if (mask) {
1603       for (i=0;i<n;i++) {
1604          if (mask[i]) {
1605             ptr[i] = PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1606          }
1607       }
1608    }
1609    else {
1610       /* draw all pixels */
1611       for (i=0;i<n;i++) {
1612          ptr[i] = PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1613       }
1614    }
1615 }
1616
1617
1618 /*
1619  * Write a span of PF_8R8G8B24-format pixels to an ximage (no alpha).
1620  */
1621 static void put_row_rgb_8R8G8B24_ximage( RGB_SPAN_ARGS )
1622 {
1623    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1624    GET_XRB(xrb);
1625    register GLuint i;
1626    register GLubyte *ptr = (GLubyte *) PIXEL_ADDR3(xrb, x, y);
1627    if (mask) {
1628       for (i=0;i<n;i++) {
1629          if (mask[i]) {
1630             *ptr++ = rgb[i][BCOMP];
1631             *ptr++ = rgb[i][GCOMP];
1632             *ptr++ = rgb[i][RCOMP];
1633          }
1634          else {
1635             ptr += 3;
1636          }
1637       }
1638    }
1639    else {
1640       /* draw all pixels */
1641       for (i=0;i<n;i++) {
1642          *ptr++ = rgb[i][BCOMP];
1643          *ptr++ = rgb[i][GCOMP];
1644          *ptr++ = rgb[i][RCOMP];
1645       }
1646    }
1647 }
1648
1649
1650 /*
1651  * Write a span of PF_5R6G5B-format pixels to an ximage.
1652  */
1653 static void put_row_5R6G5B_ximage( PUT_ROW_ARGS )
1654 {
1655    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1656    GET_XRB(xrb);
1657    register GLuint i;
1658    register GLushort *ptr = PIXEL_ADDR2(xrb, x, y);
1659    if (mask) {
1660       for (i=0;i<n;i++) {
1661          if (mask[i]) {
1662             ptr[i] = PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1663          }
1664       }
1665    }
1666    else {
1667       /* draw all pixels */
1668 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
1669       GLuint *ptr32 = (GLuint *) ptr;
1670       GLuint extraPixel = (n & 1);
1671       n -= extraPixel;
1672       for (i = 0; i < n; i += 2) {
1673          GLuint p0, p1;
1674          p0 = PACK_5R6G5B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1675          p1 = PACK_5R6G5B(rgba[i+1][RCOMP], rgba[i+1][GCOMP], rgba[i+1][BCOMP]);
1676          *ptr32++ = (p1 << 16) | p0;
1677       }
1678       if (extraPixel) {
1679          ptr[n] = PACK_5R6G5B(rgba[n][RCOMP], rgba[n][GCOMP], rgba[n][BCOMP]);
1680       }
1681 #else
1682       for (i = 0; i < n; i++) {
1683          ptr[i] = PACK_5R6G5B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1684       }
1685 #endif
1686    }
1687 }
1688
1689
1690 /*
1691  * Write a span of PF_DITHER_5R6G5B-format pixels to an ximage.
1692  */
1693 static void put_row_DITHER_5R6G5B_ximage( PUT_ROW_ARGS )
1694 {
1695    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1696    GET_XRB(xrb);
1697    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1698    register GLuint i;
1699    register GLushort *ptr = PIXEL_ADDR2(xrb, x, y);
1700    const GLint y2 = YFLIP(xrb, y);
1701    if (mask) {
1702       for (i=0;i<n;i++,x++) {
1703          if (mask[i]) {
1704             PACK_TRUEDITHER( ptr[i], x, y2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1705          }
1706       }
1707    }
1708    else {
1709       /* draw all pixels */
1710 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
1711       GLuint *ptr32 = (GLuint *) ptr;
1712       GLuint extraPixel = (n & 1);
1713       n -= extraPixel;
1714       for (i = 0; i < n; i += 2, x += 2) {
1715          GLuint p0, p1;
1716          PACK_TRUEDITHER( p0, x, y2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1717          PACK_TRUEDITHER( p1, x+1, y2, rgba[i+1][RCOMP], rgba[i+1][GCOMP], rgba[i+1][BCOMP] );
1718          *ptr32++ = (p1 << 16) | p0;
1719       }
1720       if (extraPixel) {
1721          PACK_TRUEDITHER( ptr[n], x+n, y2, rgba[n][RCOMP], rgba[n][GCOMP], rgba[n][BCOMP]);
1722       }
1723 #else
1724       for (i = 0; i < n; i++, x++) {
1725          PACK_TRUEDITHER( ptr[i], x, y2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1726       }
1727 #endif
1728    }
1729 }
1730
1731
1732 /*
1733  * Write a span of PF_5R6G5B-format pixels to an ximage (no alpha).
1734  */
1735 static void put_row_rgb_5R6G5B_ximage( RGB_SPAN_ARGS )
1736 {
1737    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1738    GET_XRB(xrb);
1739    register GLuint i;
1740    register GLushort *ptr = PIXEL_ADDR2(xrb, x, y);
1741    if (mask) {
1742       for (i=0;i<n;i++) {
1743          if (mask[i]) {
1744             ptr[i] = PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1745          }
1746       }
1747    }
1748    else {
1749       /* draw all pixels */
1750 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
1751       GLuint *ptr32 = (GLuint *) ptr;
1752       GLuint extraPixel = (n & 1);
1753       n -= extraPixel;
1754       for (i = 0; i < n; i += 2) {
1755          GLuint p0, p1;
1756          p0 = PACK_5R6G5B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1757          p1 = PACK_5R6G5B(rgb[i+1][RCOMP], rgb[i+1][GCOMP], rgb[i+1][BCOMP]);
1758          *ptr32++ = (p1 << 16) | p0;
1759       }
1760       if (extraPixel) {
1761          ptr[n] = PACK_5R6G5B(rgb[n][RCOMP], rgb[n][GCOMP], rgb[n][BCOMP]);
1762       }
1763 #else
1764       for (i=0;i<n;i++) {
1765          ptr[i] = PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1766       }
1767 #endif
1768    }
1769 }
1770
1771
1772 /*
1773  * Write a span of PF_DITHER_5R6G5B-format pixels to an ximage (no alpha).
1774  */
1775 static void put_row_rgb_DITHER_5R6G5B_ximage( RGB_SPAN_ARGS )
1776 {
1777    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1778    GET_XRB(xrb);
1779    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1780    register GLuint i;
1781    register GLushort *ptr = PIXEL_ADDR2(xrb, x, y );
1782    if (mask) {
1783       for (i=0;i<n;i++,x++) {
1784          if (mask[i]) {
1785             PACK_TRUEDITHER( ptr[i], x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1786          }
1787       }
1788    }
1789    else {
1790       /* draw all pixels */
1791 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
1792       GLuint *ptr32 = (GLuint *) ptr;
1793       GLuint extraPixel = (n & 1);
1794       n -= extraPixel;
1795       for (i = 0; i < n; i += 2, x += 2) {
1796          GLuint p0, p1;
1797          PACK_TRUEDITHER( p0, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1798          PACK_TRUEDITHER( p1, x+1, y, rgb[i+1][RCOMP], rgb[i+1][GCOMP], rgb[i+1][BCOMP] );
1799          *ptr32++ = (p1 << 16) | p0;
1800       }
1801       if (extraPixel) {
1802          PACK_TRUEDITHER( ptr[n], x+n, y, rgb[n][RCOMP], rgb[n][GCOMP], rgb[n][BCOMP]);
1803       }
1804 #else
1805       for (i=0;i<n;i++,x++) {
1806          PACK_TRUEDITHER( ptr[i], x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1807       }
1808 #endif
1809    }
1810 }
1811
1812
1813 /*
1814  * Write a span of PF_DITHER pixels to an XImage.
1815  */
1816 static void put_row_DITHER_ximage( PUT_ROW_ARGS )
1817 {
1818    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1819    GET_XRB(xrb);
1820    XMesaImage *img = xrb->ximage;
1821    register GLuint i;
1822    int yy = YFLIP(xrb, y);
1823    XDITHER_SETUP(yy);
1824    if (mask) {
1825       for (i=0;i<n;i++,x++) {
1826          if (mask[i]) {
1827             XMesaPutPixel( img, x, yy, XDITHER( x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
1828          }
1829       }
1830    }
1831    else {
1832       /* draw all pixels */
1833       for (i=0;i<n;i++,x++) {
1834          XMesaPutPixel( img, x, yy, XDITHER( x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
1835       }
1836    }
1837 }
1838
1839
1840 /*
1841  * Write a span of PF_DITHER pixels to an XImage (no alpha).
1842  */
1843 static void put_row_rgb_DITHER_ximage( RGB_SPAN_ARGS )
1844 {
1845    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1846    GET_XRB(xrb);
1847    XMesaImage *img = xrb->ximage;
1848    register GLuint i;
1849    int yy = YFLIP(xrb, y);
1850    XDITHER_SETUP(yy);
1851    if (mask) {
1852       for (i=0;i<n;i++,x++) {
1853          if (mask[i]) {
1854             XMesaPutPixel( img, x, yy, XDITHER( x, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) );
1855          }
1856       }
1857    }
1858    else {
1859       /* draw all pixels */
1860       for (i=0;i<n;i++,x++) {
1861          XMesaPutPixel( img, x, yy, XDITHER( x, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) );
1862       }
1863    }
1864 }
1865
1866
1867
1868 /*
1869  * Write a span of 8-bit PF_DITHER pixels to an XImage.
1870  */
1871 static void put_row_DITHER8_ximage( PUT_ROW_ARGS )
1872 {
1873    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1874    GET_XRB(xrb);
1875    register GLuint i;
1876    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
1877    XDITHER_SETUP(y);
1878    if (mask) {
1879       for (i=0;i<n;i++,x++) {
1880          if (mask[i]) {
1881             ptr[i] = (GLubyte) XDITHER( x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1882          }
1883       }
1884    }
1885    else {
1886       for (i=0;i<n;i++,x++) {
1887          ptr[i] = (GLubyte) XDITHER( x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1888       }
1889    }
1890 }
1891
1892
1893 static void put_row_rgb_DITHER8_ximage( RGB_SPAN_ARGS )
1894 {
1895    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1896    GET_XRB(xrb);
1897    register GLuint i;
1898    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
1899    XDITHER_SETUP(y);
1900    if (mask) {
1901       for (i=0;i<n;i++,x++) {
1902          if (mask[i]) {
1903             ptr[i] = (GLubyte) XDITHER( x, rgb[i][0], rgb[i][1], rgb[i][2] );
1904          }
1905       }
1906    }
1907    else {
1908       const GLubyte *data = (GLubyte *) rgb;
1909       for (i=0;i<n;i++,x++) {
1910          /*ptr[i] = XDITHER( x, rgb[i][0], rgb[i][1], rgb[i][2] );*/
1911          ptr[i] = (GLubyte) XDITHER( x, data[i+i+i], data[i+i+i+1], data[i+i+i+2] );
1912       }
1913    }
1914 }
1915
1916
1917
1918 /*
1919  * Write a span of PF_1BIT pixels to an XImage.
1920  */
1921 static void put_row_1BIT_ximage( PUT_ROW_ARGS )
1922 {
1923    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1924    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1925    GET_XRB(xrb);
1926    XMesaImage *img = xrb->ximage;
1927    register GLuint i;
1928    SETUP_1BIT;
1929    y = YFLIP(xrb, y);
1930    if (mask) {
1931       for (i=0;i<n;i++,x++) {
1932          if (mask[i]) {
1933             XMesaPutPixel(img, x, y, DITHER_1BIT(x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
1934          }
1935       }
1936    }
1937    else {
1938       for (i=0;i<n;i++,x++) {
1939          XMesaPutPixel( img, x, y, DITHER_1BIT(x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) );
1940       }
1941    }
1942 }
1943
1944
1945 /*
1946  * Write a span of PF_1BIT pixels to an XImage (no alpha).
1947  */
1948 static void put_row_rgb_1BIT_ximage( RGB_SPAN_ARGS )
1949 {
1950    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
1951    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1952    GET_XRB(xrb);
1953    XMesaImage *img = xrb->ximage;
1954    register GLuint i;
1955    SETUP_1BIT;
1956    y = YFLIP(xrb, y);
1957    if (mask) {
1958       for (i=0;i<n;i++,x++) {
1959          if (mask[i]) {
1960             XMesaPutPixel(img, x, y, DITHER_1BIT(x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]));
1961          }
1962       }
1963    }
1964    else {
1965       for (i=0;i<n;i++,x++) {
1966          XMesaPutPixel( img, x, y, DITHER_1BIT(x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) );
1967       }
1968    }
1969 }
1970
1971
1972 /*
1973  * Write a span of PF_HPCR pixels to an XImage.
1974  */
1975 static void put_row_HPCR_ximage( PUT_ROW_ARGS )
1976 {
1977    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
1978    GET_XRB(xrb);
1979    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
1980    register GLuint i;
1981    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
1982    if (mask) {
1983       for (i=0;i<n;i++,x++) {
1984          if (mask[i]) {
1985             ptr[i] = DITHER_HPCR( x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1986          }
1987       }
1988    }
1989    else {
1990       /* draw all pixels */
1991       for (i=0;i<n;i++,x++) {
1992          ptr[i] = DITHER_HPCR( x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1993       }
1994    }
1995 }
1996
1997
1998 /*
1999  * Write a span of PF_HPCR pixels to an XImage (no alpha).
2000  */
2001 static void put_row_rgb_HPCR_ximage( RGB_SPAN_ARGS )
2002 {
2003    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
2004    GET_XRB(xrb);
2005    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2006    register GLuint i;
2007    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
2008    if (mask) {
2009       for (i=0;i<n;i++,x++) {
2010          if (mask[i]) {
2011             ptr[i] = DITHER_HPCR( x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
2012          }
2013       }
2014    }
2015    else {
2016       /* draw all pixels */
2017       for (i=0;i<n;i++,x++) {
2018          ptr[i] = DITHER_HPCR( x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
2019       }
2020    }
2021 }
2022
2023
2024 /*
2025  * Write a span of PF_LOOKUP pixels to an XImage.
2026  */
2027 static void put_row_LOOKUP_ximage( PUT_ROW_ARGS )
2028 {
2029    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2030    GET_XRB(xrb);
2031    XMesaImage *img = xrb->ximage;
2032    register GLuint i;
2033    LOOKUP_SETUP;
2034    y = YFLIP(xrb, y);
2035    if (mask) {
2036       for (i=0;i<n;i++,x++) {
2037          if (mask[i]) {
2038             XMesaPutPixel( img, x, y, LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2039          }
2040       }
2041    }
2042    else {
2043       /* draw all pixels */
2044       for (i=0;i<n;i++,x++) {
2045          XMesaPutPixel( img, x, y, LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2046       }
2047    }
2048 }
2049
2050
2051 /*
2052  * Write a span of PF_LOOKUP pixels to an XImage (no alpha).
2053  */
2054 static void put_row_rgb_LOOKUP_ximage( RGB_SPAN_ARGS )
2055 {
2056    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
2057    GET_XRB(xrb);
2058    XMesaImage *img = xrb->ximage;
2059    register GLuint i;
2060    LOOKUP_SETUP;
2061    y = YFLIP(xrb, y);
2062    if (mask) {
2063       for (i=0;i<n;i++,x++) {
2064          if (mask[i]) {
2065             XMesaPutPixel( img, x, y, LOOKUP( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) );
2066          }
2067       }
2068    }
2069    else {
2070       /* draw all pixels */
2071       for (i=0;i<n;i++,x++) {
2072          XMesaPutPixel( img, x, y, LOOKUP( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) );
2073       }
2074    }
2075 }
2076
2077
2078 /*
2079  * Write a span of 8-bit PF_LOOKUP pixels to an XImage.
2080  */
2081 static void put_row_LOOKUP8_ximage( PUT_ROW_ARGS )
2082 {
2083    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2084    GET_XRB(xrb);
2085    register GLuint i;
2086    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
2087    LOOKUP_SETUP;
2088    if (mask) {
2089       for (i=0;i<n;i++,x++) {
2090          if (mask[i]) {
2091             ptr[i] = (GLubyte) LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2092          }
2093       }
2094    }
2095    else {
2096       /* draw all pixels */
2097       for (i=0;i<n;i++,x++) {
2098          ptr[i] = (GLubyte) LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2099       }
2100    }
2101 }
2102
2103
2104 static void put_row_rgb_LOOKUP8_ximage( RGB_SPAN_ARGS )
2105 {
2106    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
2107    GET_XRB(xrb);
2108    register GLuint i;
2109    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
2110    LOOKUP_SETUP;
2111    if (mask) {
2112       for (i=0;i<n;i++,x++) {
2113          if (mask[i]) {
2114             ptr[i] = (GLubyte) LOOKUP( rgb[i][0], rgb[i][1], rgb[i][2] );
2115          }
2116       }
2117    }
2118    else {
2119       /* draw all pixels */
2120       const GLubyte *data = (GLubyte *) rgb;
2121       for (i=0;i<n;i++,x++) {
2122          /*ptr[i] = LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );*/
2123          ptr[i] = (GLubyte) LOOKUP( data[i+i+i], data[i+i+i+1], data[i+i+i+2] );
2124       }
2125    }
2126 }
2127
2128
2129 /*
2130  * Write a span of PF_GRAYSCALE pixels to an XImage.
2131  */
2132 static void put_row_GRAYSCALE_ximage( PUT_ROW_ARGS )
2133 {
2134    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2135    GET_XRB(xrb);
2136    XMesaImage *img = xrb->ximage;
2137    register GLuint i;
2138    y = YFLIP(xrb, y);
2139    if (mask) {
2140       for (i=0;i<n;i++,x++) {
2141          if (mask[i]) {
2142             XMesaPutPixel( img, x, y, GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2143          }
2144       }
2145    }
2146    else {
2147       /* draw all pixels */
2148       for (i=0;i<n;i++,x++) {
2149          XMesaPutPixel( img, x, y, GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2150       }
2151    }
2152 }
2153
2154
2155 /*
2156  * Write a span of PF_GRAYSCALE pixels to an XImage (no alpha).
2157  */
2158 static void put_row_rgb_GRAYSCALE_ximage( RGB_SPAN_ARGS )
2159 {
2160    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
2161    GET_XRB(xrb);
2162    XMesaImage *img = xrb->ximage;
2163    register GLuint i;
2164    y = YFLIP(xrb, y);
2165    if (mask) {
2166       for (i=0;i<n;i++,x++) {
2167          if (mask[i]) {
2168             XMesaPutPixel( img, x, y, GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) );
2169          }
2170       }
2171    }
2172    else {
2173       /* draw all pixels */
2174       for (i=0;i<n;i++,x++) {
2175          XMesaPutPixel( img, x, y, GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) );
2176       }
2177    }
2178 }
2179
2180
2181 /*
2182  * Write a span of 8-bit PF_GRAYSCALE pixels to an XImage.
2183  */
2184 static void put_row_GRAYSCALE8_ximage( PUT_ROW_ARGS )
2185 {
2186    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2187    GET_XRB(xrb);
2188    register GLuint i;
2189    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
2190    if (mask) {
2191       for (i=0;i<n;i++) {
2192          if (mask[i]) {
2193             ptr[i] = (GLubyte) GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2194          }
2195       }
2196    }
2197    else {
2198       /* draw all pixels */
2199       for (i=0;i<n;i++) {
2200          ptr[i] = (GLubyte) GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2201       }
2202    }
2203 }
2204
2205
2206 /*
2207  * Write a span of 8-bit PF_GRAYSCALE pixels to an XImage (no alpha).
2208  */
2209 static void put_row_rgb_GRAYSCALE8_ximage( RGB_SPAN_ARGS )
2210 {
2211    const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
2212    GET_XRB(xrb);
2213    register GLuint i;
2214    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
2215    if (mask) {
2216       for (i=0;i<n;i++) {
2217          if (mask[i]) {
2218             ptr[i] = (GLubyte) GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
2219          }
2220       }
2221    }
2222    else {
2223       /* draw all pixels */
2224       for (i=0;i<n;i++) {
2225          ptr[i] = (GLubyte) GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
2226       }
2227    }
2228 }
2229
2230
2231
2232
2233 /**********************************************************************/
2234 /*** Write COLOR PIXEL functions                                    ***/
2235 /**********************************************************************/
2236
2237
2238 #define PUT_VALUES_ARGS \
2239         struct gl_context *ctx, struct gl_renderbuffer *rb,     \
2240         GLuint n, const GLint x[], const GLint y[],     \
2241         const void *values, const GLubyte mask[]
2242
2243
2244 /*
2245  * Write an array of PF_TRUECOLOR pixels to a pixmap.
2246  */
2247 static void put_values_TRUECOLOR_pixmap( PUT_VALUES_ARGS )
2248 {
2249    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2250    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2251    GET_XRB(xrb);
2252    XMesaDisplay *dpy = xmesa->xm_visual->display;
2253    XMesaDrawable buffer = xrb->drawable;
2254    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2255    register GLuint i;
2256    for (i=0;i<n;i++) {
2257       if (mask[i]) {
2258          unsigned long p;
2259          PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2260          XMesaSetForeground( dpy, gc, p );
2261          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2262       }
2263    }
2264 }
2265
2266
2267 /*
2268  * Write an array of PF_TRUEDITHER pixels to a pixmap.
2269  */
2270 static void put_values_TRUEDITHER_pixmap( PUT_VALUES_ARGS )
2271 {
2272    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2273    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2274    GET_XRB(xrb);
2275    XMesaDisplay *dpy = xmesa->xm_visual->display;
2276    XMesaDrawable buffer = xrb->drawable;
2277    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2278    register GLuint i;
2279    for (i=0;i<n;i++) {
2280       if (mask[i]) {
2281          unsigned long p;
2282          PACK_TRUEDITHER(p, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
2283          XMesaSetForeground( dpy, gc, p );
2284          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2285       }
2286    }
2287 }
2288
2289
2290 /*
2291  * Write an array of PF_8A8B8G8R pixels to a pixmap.
2292  */
2293 static void put_values_8A8B8G8R_pixmap( PUT_VALUES_ARGS )
2294 {
2295    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2296    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2297    GET_XRB(xrb);
2298    XMesaDisplay *dpy = xmesa->xm_visual->display;
2299    XMesaDrawable buffer = xrb->drawable;
2300    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2301    register GLuint i;
2302    for (i=0;i<n;i++) {
2303       if (mask[i]) {
2304          XMesaSetForeground( dpy, gc,
2305                          PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ));
2306          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2307       }
2308    }
2309 }
2310
2311 /*
2312  * Write an array of PF_8A8R8G8B pixels to a pixmap.
2313  */
2314 static void put_values_8A8R8G8B_pixmap( PUT_VALUES_ARGS )
2315 {
2316    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2317    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2318    GET_XRB(xrb);
2319    XMesaDisplay *dpy = xmesa->xm_visual->display;
2320    XMesaDrawable buffer = xrb->drawable;
2321    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2322    register GLuint i;
2323    for (i=0;i<n;i++) {
2324       if (mask[i]) {
2325          XMesaSetForeground( dpy, gc,
2326                          PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ));
2327          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2328       }
2329    }
2330 }
2331
2332 /*
2333  * Write an array of PF_8R8G8B pixels to a pixmap.
2334  */
2335 static void put_values_8R8G8B_pixmap( PUT_VALUES_ARGS )
2336 {
2337    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2338    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2339    GET_XRB(xrb);
2340    XMesaDisplay *dpy = xmesa->xm_visual->display;
2341    XMesaDrawable buffer = xrb->drawable;
2342    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2343    register GLuint i;
2344    for (i=0;i<n;i++) {
2345       if (mask[i]) {
2346          XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2347          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2348       }
2349    }
2350 }
2351
2352
2353 /*
2354  * Write an array of PF_8R8G8B24 pixels to a pixmap.
2355  */
2356 static void put_values_8R8G8B24_pixmap( PUT_VALUES_ARGS )
2357 {
2358    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2359    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2360    GET_XRB(xrb);
2361    XMesaDisplay *dpy = xmesa->xm_visual->display;
2362    XMesaDrawable buffer = xrb->drawable;
2363    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2364    register GLuint i;
2365    for (i=0;i<n;i++) {
2366       if (mask[i]) {
2367          XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2368          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2369       }
2370    }
2371 }
2372
2373
2374 /*
2375  * Write an array of PF_5R6G5B pixels to a pixmap.
2376  */
2377 static void put_values_5R6G5B_pixmap( PUT_VALUES_ARGS )
2378 {
2379    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2380    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2381    GET_XRB(xrb);
2382    XMesaDisplay *dpy = xmesa->xm_visual->display;
2383    XMesaDrawable buffer = xrb->drawable;
2384    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2385    register GLuint i;
2386    for (i=0;i<n;i++) {
2387       if (mask[i]) {
2388          XMesaSetForeground( dpy, gc, PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2389          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2390       }
2391    }
2392 }
2393
2394
2395 /*
2396  * Write an array of PF_DITHER_5R6G5B pixels to a pixmap.
2397  */
2398 static void put_values_DITHER_5R6G5B_pixmap( PUT_VALUES_ARGS )
2399 {
2400    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2401    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2402    GET_XRB(xrb);
2403    XMesaDisplay *dpy = xmesa->xm_visual->display;
2404    XMesaDrawable buffer = xrb->drawable;
2405    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2406    register GLuint i;
2407    for (i=0;i<n;i++) {
2408       if (mask[i]) {
2409          unsigned long p;
2410          PACK_TRUEDITHER(p, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2411          XMesaSetForeground( dpy, gc, p );
2412          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2413       }
2414    }
2415 }
2416
2417
2418 /*
2419  * Write an array of PF_DITHER pixels to a pixmap.
2420  */
2421 static void put_values_DITHER_pixmap( PUT_VALUES_ARGS )
2422 {
2423    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2424    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2425    GET_XRB(xrb);
2426    XMesaDisplay *dpy = xmesa->xm_visual->display;
2427    XMesaDrawable buffer = xrb->drawable;
2428    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2429    register GLuint i;
2430    DITHER_SETUP;
2431    for (i=0;i<n;i++) {
2432       if (mask[i]) {
2433          XMesaSetForeground( dpy, gc,
2434                          DITHER(x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) );
2435          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2436       }
2437    }
2438 }
2439
2440
2441 /*
2442  * Write an array of PF_1BIT pixels to a pixmap.
2443  */
2444 static void put_values_1BIT_pixmap( PUT_VALUES_ARGS )
2445 {
2446    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2447    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2448    GET_XRB(xrb);
2449    XMesaDisplay *dpy = xmesa->xm_visual->display;
2450    XMesaDrawable buffer = xrb->drawable;
2451    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2452    register GLuint i;
2453    SETUP_1BIT;
2454    for (i=0;i<n;i++) {
2455       if (mask[i]) {
2456          XMesaSetForeground( dpy, gc,
2457                          DITHER_1BIT( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
2458          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2459       }
2460    }
2461 }
2462
2463
2464 /*
2465  * Write an array of PF_HPCR pixels to a pixmap.
2466  */
2467 static void put_values_HPCR_pixmap( PUT_VALUES_ARGS )
2468 {
2469    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2470    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2471    GET_XRB(xrb);
2472    XMesaDisplay *dpy = xmesa->xm_visual->display;
2473    XMesaDrawable buffer = xrb->drawable;
2474    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2475    register GLuint i;
2476    for (i=0;i<n;i++) {
2477       if (mask[i]) {
2478          XMesaSetForeground( dpy, gc,
2479                          DITHER_HPCR( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
2480          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2481       }
2482    }
2483 }
2484
2485
2486 /*
2487  * Write an array of PF_LOOKUP pixels to a pixmap.
2488  */
2489 static void put_values_LOOKUP_pixmap( PUT_VALUES_ARGS )
2490 {
2491    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2492    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2493    GET_XRB(xrb);
2494    XMesaDisplay *dpy = xmesa->xm_visual->display;
2495    XMesaDrawable buffer = xrb->drawable;
2496    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2497    register GLuint i;
2498    LOOKUP_SETUP;
2499    for (i=0;i<n;i++) {
2500       if (mask[i]) {
2501          XMesaSetForeground( dpy, gc, LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2502          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2503       }
2504    }
2505 }
2506
2507
2508 /*
2509  * Write an array of PF_GRAYSCALE pixels to a pixmap.
2510  */
2511 static void put_values_GRAYSCALE_pixmap( PUT_VALUES_ARGS )
2512 {
2513    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2514    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2515    GET_XRB(xrb);
2516    XMesaDisplay *dpy = xmesa->xm_visual->display;
2517    XMesaDrawable buffer = xrb->drawable;
2518    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2519    register GLuint i;
2520    for (i=0;i<n;i++) {
2521       if (mask[i]) {
2522          XMesaSetForeground( dpy, gc, GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2523          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
2524       }
2525    }
2526 }
2527
2528
2529 /*
2530  * Write an array of PF_TRUECOLOR pixels to an ximage.
2531  */
2532 static void put_values_TRUECOLOR_ximage( PUT_VALUES_ARGS )
2533 {
2534    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2535    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2536    GET_XRB(xrb);
2537    XMesaImage *img = xrb->ximage;
2538    register GLuint i;
2539    for (i=0;i<n;i++) {
2540       if (mask[i]) {
2541          unsigned long p;
2542          PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2543          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), p );
2544       }
2545    }
2546 }
2547
2548
2549 /*
2550  * Write an array of PF_TRUEDITHER pixels to an XImage.
2551  */
2552 static void put_values_TRUEDITHER_ximage( PUT_VALUES_ARGS )
2553 {
2554    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2555    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2556    GET_XRB(xrb);
2557    XMesaImage *img = xrb->ximage;
2558    register GLuint i;
2559    for (i=0;i<n;i++) {
2560       if (mask[i]) {
2561          unsigned long p;
2562          PACK_TRUEDITHER(p, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
2563          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), p );
2564       }
2565    }
2566 }
2567
2568
2569 /*
2570  * Write an array of PF_8A8B8G8R pixels to an ximage.
2571  */
2572 static void put_values_8A8B8G8R_ximage( PUT_VALUES_ARGS )
2573 {
2574    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2575    GET_XRB(xrb);
2576    register GLuint i;
2577    for (i=0;i<n;i++) {
2578       if (mask[i]) {
2579          GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i] );
2580          *ptr = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
2581       }
2582    }
2583 }
2584
2585 /*
2586  * Write an array of PF_8A8R8G8B pixels to an ximage.
2587  */
2588 static void put_values_8A8R8G8B_ximage( PUT_VALUES_ARGS )
2589 {
2590    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2591    GET_XRB(xrb);
2592    register GLuint i;
2593    for (i=0;i<n;i++) {
2594       if (mask[i]) {
2595          GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i]);
2596          *ptr = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
2597       }
2598    }
2599 }
2600
2601
2602 /*
2603  * Write an array of PF_8R8G8B pixels to an ximage.
2604  */
2605 static void put_values_8R8G8B_ximage( PUT_VALUES_ARGS )
2606 {
2607    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2608    GET_XRB(xrb);
2609    register GLuint i;
2610    for (i=0;i<n;i++) {
2611       if (mask[i]) {
2612          GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i]);
2613          *ptr = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2614       }
2615    }
2616 }
2617
2618
2619 /*
2620  * Write an array of PF_8R8G8B24 pixels to an ximage.
2621  */
2622 static void put_values_8R8G8B24_ximage( PUT_VALUES_ARGS )
2623 {
2624    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2625    GET_XRB(xrb);
2626    register GLuint i;
2627    for (i=0;i<n;i++) {
2628       if (mask[i]) {
2629          bgr_t *ptr = PIXEL_ADDR3(xrb, x[i], y[i] );
2630          ptr->r = rgba[i][RCOMP];
2631          ptr->g = rgba[i][GCOMP];
2632          ptr->b = rgba[i][BCOMP];
2633       }
2634    }
2635 }
2636
2637
2638 /*
2639  * Write an array of PF_5R6G5B pixels to an ximage.
2640  */
2641 static void put_values_5R6G5B_ximage( PUT_VALUES_ARGS )
2642 {
2643    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2644    GET_XRB(xrb);
2645    register GLuint i;
2646    for (i=0;i<n;i++) {
2647       if (mask[i]) {
2648          GLushort *ptr = PIXEL_ADDR2(xrb, x[i], y[i] );
2649          *ptr = PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2650       }
2651    }
2652 }
2653
2654
2655 /*
2656  * Write an array of PF_DITHER_5R6G5B pixels to an ximage.
2657  */
2658 static void put_values_DITHER_5R6G5B_ximage( PUT_VALUES_ARGS )
2659 {
2660    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2661    GET_XRB(xrb);
2662    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2663    register GLuint i;
2664    for (i=0;i<n;i++) {
2665       if (mask[i]) {
2666          GLushort *ptr = PIXEL_ADDR2(xrb, x[i], y[i] );
2667          PACK_TRUEDITHER( *ptr, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2668       }
2669    }
2670 }
2671
2672
2673 /*
2674  * Write an array of PF_DITHER pixels to an XImage.
2675  */
2676 static void put_values_DITHER_ximage( PUT_VALUES_ARGS )
2677 {
2678    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2679    GET_XRB(xrb);
2680    XMesaImage *img = xrb->ximage;
2681    register GLuint i;
2682    DITHER_SETUP;
2683    for (i=0;i<n;i++) {
2684       if (mask[i]) {
2685          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]),
2686                     DITHER( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2687       }
2688    }
2689 }
2690
2691
2692 /*
2693  * Write an array of 8-bit PF_DITHER pixels to an XImage.
2694  */
2695 static void put_values_DITHER8_ximage( PUT_VALUES_ARGS )
2696 {
2697    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2698    GET_XRB(xrb);
2699    register GLuint i;
2700    DITHER_SETUP;
2701    for (i=0;i<n;i++) {
2702       if (mask[i]) {
2703          GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]);
2704          *ptr = (GLubyte) DITHER( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2705       }
2706    }
2707 }
2708
2709
2710 /*
2711  * Write an array of PF_1BIT pixels to an XImage.
2712  */
2713 static void put_values_1BIT_ximage( PUT_VALUES_ARGS )
2714 {
2715    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2716    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2717    GET_XRB(xrb);
2718    XMesaImage *img = xrb->ximage;
2719    register GLuint i;
2720    SETUP_1BIT;
2721    for (i=0;i<n;i++) {
2722       if (mask[i]) {
2723          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]),
2724                     DITHER_1BIT( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));
2725       }
2726    }
2727 }
2728
2729
2730 /*
2731  * Write an array of PF_HPCR pixels to an XImage.
2732  */
2733 static void put_values_HPCR_ximage( PUT_VALUES_ARGS )
2734 {
2735    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2736    GET_XRB(xrb);
2737    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
2738    register GLuint i;
2739    for (i=0;i<n;i++) {
2740       if (mask[i]) {
2741          GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]);
2742          *ptr = (GLubyte) DITHER_HPCR( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2743       }
2744    }
2745 }
2746
2747
2748 /*
2749  * Write an array of PF_LOOKUP pixels to an XImage.
2750  */
2751 static void put_values_LOOKUP_ximage( PUT_VALUES_ARGS )
2752 {
2753    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2754    GET_XRB(xrb);
2755    XMesaImage *img = xrb->ximage;
2756    register GLuint i;
2757    LOOKUP_SETUP;
2758    for (i=0;i<n;i++) {
2759       if (mask[i]) {
2760          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), LOOKUP(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) );
2761       }
2762    }
2763 }
2764
2765
2766 /*
2767  * Write an array of 8-bit PF_LOOKUP pixels to an XImage.
2768  */
2769 static void put_values_LOOKUP8_ximage( PUT_VALUES_ARGS )
2770 {
2771    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2772    GET_XRB(xrb);
2773    register GLuint i;
2774    LOOKUP_SETUP;
2775    for (i=0;i<n;i++) {
2776       if (mask[i]) {
2777          GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]);
2778          *ptr = (GLubyte) LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2779       }
2780    }
2781 }
2782
2783
2784 /*
2785  * Write an array of PF_GRAYSCALE pixels to an XImage.
2786  */
2787 static void put_values_GRAYSCALE_ximage( PUT_VALUES_ARGS )
2788 {
2789    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2790    GET_XRB(xrb);
2791    XMesaImage *img = xrb->ximage;
2792    register GLuint i;
2793    for (i=0;i<n;i++) {
2794       if (mask[i]) {
2795          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]),
2796                     GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) );
2797       }
2798    }
2799 }
2800
2801
2802 /*
2803  * Write an array of 8-bit PF_GRAYSCALE pixels to an XImage.
2804  */
2805 static void put_values_GRAYSCALE8_ximage( PUT_VALUES_ARGS )
2806 {
2807    const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
2808    GET_XRB(xrb);
2809    register GLuint i;
2810    for (i=0;i<n;i++) {
2811       if (mask[i]) {
2812          GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i] );
2813          *ptr = (GLubyte) GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
2814       }
2815    }
2816 }
2817
2818
2819
2820
2821 /**********************************************************************/
2822 /*** Write MONO COLOR SPAN functions                                ***/
2823 /**********************************************************************/
2824
2825 #define PUT_MONO_ROW_ARGS \
2826         struct gl_context *ctx, struct gl_renderbuffer *rb,     \
2827         GLuint n, GLint x, GLint y, const void *value,  \
2828         const GLubyte mask[]
2829
2830
2831
2832 /*
2833  * Write a span of identical pixels to a pixmap.
2834  */
2835 static void put_mono_row_pixmap( PUT_MONO_ROW_ARGS )
2836 {
2837    const GLubyte *color = (const GLubyte *) value;
2838    GET_XRB(xrb);
2839    XMesaContext xmesa = XMESA_CONTEXT(ctx);
2840    XMesaDisplay *dpy = xmesa->xm_visual->display;
2841    XMesaDrawable buffer = xrb->drawable;
2842    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2843    const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP],
2844                color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat);
2845    register GLuint i;
2846    XMesaSetForeground( xmesa->display, gc, pixel );
2847    y = YFLIP(xrb, y);
2848
2849    /* New code contributed by Jeff Epler and cleaned up by Keith
2850     * Whitwell.  
2851     */
2852    for (i = 0; i < n; ) {
2853       GLuint start = i;
2854
2855       /* Identify and emit contiguous rendered pixels
2856        */
2857       while (i < n && (!mask || mask[i]))
2858          i++;
2859
2860       if (start < i) 
2861          XMesaFillRectangle( dpy, buffer, gc,
2862                              (int)(x+start), (int) y,
2863                              (int)(i-start), 1);
2864
2865       /* Eat up non-rendered pixels
2866        */
2867       while (i < n && !mask[i])
2868          i++;
2869    }
2870 }
2871
2872
2873
2874 static void
2875 put_mono_row_ci_pixmap( PUT_MONO_ROW_ARGS )
2876 {
2877    GLuint colorIndex = *((GLuint *) value);
2878    XMesaContext xmesa = XMESA_CONTEXT(ctx);
2879    GET_XRB(xrb);
2880    XMesaDisplay *dpy = xmesa->xm_visual->display;
2881    XMesaDrawable buffer = xrb->drawable;
2882    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2883    register GLuint i;
2884    XMesaSetForeground( xmesa->display, gc, colorIndex );
2885    y = YFLIP(xrb, y);
2886
2887    for (i = 0 ; i < n ;) {
2888       GLuint start = i;
2889       
2890       /* Identify and emit contiguous rendered pixels 
2891        */
2892       while (i < n && (!mask || mask[i]))
2893          i++;
2894
2895       if (start < i) 
2896          XMesaFillRectangle( dpy, buffer, gc, 
2897                              (int)(x+start), (int) y, 
2898                              (int)(i-start), 1);
2899
2900       /* Eat up non-rendered pixels
2901        */
2902       while (i < n && !mask[i])
2903          i++;
2904    }
2905 }
2906
2907
2908
2909 /*
2910  * Write a span of PF_TRUEDITHER pixels to a pixmap.
2911  */
2912 static void put_mono_row_TRUEDITHER_pixmap( PUT_MONO_ROW_ARGS )
2913 {
2914    const GLubyte *color = (const GLubyte *) value;
2915    GET_XRB(xrb);
2916    XMesaContext xmesa = XMESA_CONTEXT(ctx);
2917    XMesaDisplay *dpy = xmesa->xm_visual->display;
2918    XMesaDrawable buffer = xrb->drawable;
2919    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2920    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
2921    register GLuint i;
2922    int yy = YFLIP(xrb, y);
2923    for (i=0;i<n;i++,x++) {
2924       if (!mask || mask[i]) {
2925          unsigned long p;
2926          PACK_TRUEDITHER(p, x, yy, r, g, b);
2927          XMesaSetForeground( dpy, gc, p );
2928          XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) yy );
2929       }
2930    }
2931 }
2932
2933
2934 /*
2935  * Write a span of PF_DITHER pixels to a pixmap.
2936  */
2937 static void put_mono_row_DITHER_pixmap( PUT_MONO_ROW_ARGS )
2938 {
2939    const GLubyte *color = (const GLubyte *) value;
2940    GET_XRB(xrb);
2941    XMesaContext xmesa = XMESA_CONTEXT(ctx);
2942    XMesaDisplay *dpy = xmesa->xm_visual->display;
2943    XMesaDrawable buffer = xrb->drawable;
2944    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2945    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
2946    register GLuint i;
2947    int yy = YFLIP(xrb, y);
2948    XDITHER_SETUP(yy);
2949    for (i=0;i<n;i++,x++) {
2950       if (!mask || mask[i]) {
2951          XMesaSetForeground( dpy, gc, XDITHER( x, r, g, b ) );
2952          XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) yy );
2953       }
2954    }
2955 }
2956
2957
2958 /*
2959  * Write a span of PF_1BIT pixels to a pixmap.
2960  */
2961 static void put_mono_row_1BIT_pixmap( PUT_MONO_ROW_ARGS )
2962 {
2963    const GLubyte *color = (const GLubyte *) value;
2964    GET_XRB(xrb);
2965    XMesaContext xmesa = XMESA_CONTEXT(ctx);
2966    XMesaDisplay *dpy = xmesa->xm_visual->display;
2967    XMesaDrawable buffer = xrb->drawable;
2968    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
2969    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
2970    register GLuint i;
2971    SETUP_1BIT;
2972    y = YFLIP(xrb, y);
2973    for (i=0;i<n;i++,x++) {
2974       if (!mask || mask[i]) {
2975          XMesaSetForeground( dpy, gc, DITHER_1BIT( x, y, r, g, b ) );
2976          XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
2977       }
2978    }
2979 }
2980
2981
2982 /*
2983  * Write a span of identical pixels to an XImage.
2984  */
2985 static void put_mono_row_ximage( PUT_MONO_ROW_ARGS )
2986 {
2987    const GLubyte *color = (const GLubyte *) value;
2988    GET_XRB(xrb);
2989    XMesaContext xmesa = XMESA_CONTEXT(ctx);
2990    XMesaImage *img = xrb->ximage;
2991    register GLuint i;
2992    const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP],
2993                color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat);
2994    y = YFLIP(xrb, y);
2995    for (i=0;i<n;i++,x++) {
2996       if (!mask || mask[i]) {
2997          XMesaPutPixel( img, x, y, pixel );
2998       }
2999    }
3000 }
3001
3002
3003 static void
3004 put_mono_row_ci_ximage( PUT_MONO_ROW_ARGS )
3005 {
3006    const GLuint colorIndex = *((GLuint *) value);
3007    GET_XRB(xrb);
3008    XMesaImage *img = xrb->ximage;
3009    register GLuint i;
3010    y = YFLIP(xrb, y);
3011    for (i=0;i<n;i++,x++) {
3012       if (!mask || mask[i]) {
3013          XMesaPutPixel( img, x, y, colorIndex );
3014       }
3015    }
3016 }
3017
3018
3019 /*
3020  * Write a span of identical PF_TRUEDITHER pixels to an XImage.
3021  */
3022 static void put_mono_row_TRUEDITHER_ximage( PUT_MONO_ROW_ARGS )
3023 {
3024    const GLubyte *color = (const GLubyte *) value;
3025    GET_XRB(xrb);
3026    XMesaContext xmesa = XMESA_CONTEXT(ctx);
3027    XMesaImage *img = xrb->ximage;
3028    const GLint r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3029    GLuint i;
3030    y = YFLIP(xrb, y);
3031    for (i=0;i<n;i++) {
3032       if (!mask || mask[i]) {
3033          unsigned long p;
3034          PACK_TRUEDITHER( p, x+i, y, r, g, b);
3035          XMesaPutPixel( img, x+i, y, p );
3036       }
3037    }
3038 }
3039
3040
3041 /*
3042  * Write a span of identical 8A8B8G8R pixels to an XImage.
3043  */
3044 static void put_mono_row_8A8B8G8R_ximage( PUT_MONO_ROW_ARGS )
3045 {
3046    const GLubyte *color = (const GLubyte *) value;
3047    GET_XRB(xrb);
3048    XMesaContext xmesa = XMESA_CONTEXT(ctx);
3049    GLuint i, *ptr;
3050    const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP],
3051                color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat);
3052    ptr = PIXEL_ADDR4(xrb, x, y );
3053    for (i=0;i<n;i++) {
3054       if (!mask || mask[i]) {
3055          ptr[i] = pixel;
3056       }
3057    }
3058 }
3059
3060 /*
3061  * Write a span of identical 8A8R8G8B pixels to an XImage.
3062  */
3063 static void put_mono_row_8A8R8G8B_ximage( PUT_MONO_ROW_ARGS )
3064 {
3065    const GLubyte *color = (const GLubyte *) value;
3066    GET_XRB(xrb);
3067    GLuint i, *ptr;
3068    XMesaContext xmesa = XMESA_CONTEXT(ctx);
3069    const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP],
3070                color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat);
3071    ptr = PIXEL_ADDR4(xrb, x, y );
3072    for (i=0;i<n;i++) {
3073       if (!mask || mask[i]) {
3074          ptr[i] = pixel;
3075       }
3076    }
3077 }
3078
3079
3080 /*
3081  * Write a span of identical 8R8G8B pixels to an XImage.
3082  */
3083 static void put_mono_row_8R8G8B_ximage( PUT_MONO_ROW_ARGS )
3084 {
3085    const GLubyte *color = (const GLubyte *) value;
3086    GET_XRB(xrb);
3087    const GLuint pixel = PACK_8R8G8B(color[RCOMP], color[GCOMP], color[BCOMP]);
3088    GLuint *ptr = PIXEL_ADDR4(xrb, x, y );
3089    GLuint i;
3090    for (i=0;i<n;i++) {
3091       if (!mask || mask[i]) {
3092          ptr[i] = pixel;
3093       }
3094    }
3095 }
3096
3097
3098 /*
3099  * Write a span of identical 8R8G8B pixels to an XImage.
3100  */
3101 static void put_mono_row_8R8G8B24_ximage( PUT_MONO_ROW_ARGS )
3102 {
3103    const GLubyte *color = (const GLubyte *) value;
3104    GET_XRB(xrb);
3105    const GLubyte r = color[RCOMP];
3106    const GLubyte g = color[GCOMP];
3107    const GLubyte b = color[BCOMP];
3108    GLuint i;
3109    bgr_t *ptr = PIXEL_ADDR3(xrb, x, y );
3110    for (i=0;i<n;i++) {
3111       if (!mask || mask[i]) {
3112          ptr[i].r = r;
3113          ptr[i].g = g;
3114          ptr[i].b = b;
3115       }
3116    }
3117 }
3118
3119
3120 /*
3121  * Write a span of identical DITHER pixels to an XImage.
3122  */
3123 static void put_mono_row_DITHER_ximage( PUT_MONO_ROW_ARGS )
3124 {
3125    const GLubyte *color = (const GLubyte *) value;
3126    GET_XRB(xrb);
3127    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3128    XMesaImage *img = xrb->ximage;
3129    int yy = YFLIP(xrb, y);
3130    register GLuint i;
3131    XDITHER_SETUP(yy);
3132    for (i=0;i<n;i++,x++) {
3133       if (!mask || mask[i]) {
3134          XMesaPutPixel( img, x, yy, XDITHER( x, r, g, b ) );
3135       }
3136    }
3137 }
3138
3139
3140 /*
3141  * Write a span of identical 8-bit DITHER pixels to an XImage.
3142  */
3143 static void put_mono_row_DITHER8_ximage( PUT_MONO_ROW_ARGS )
3144 {
3145    const GLubyte *color = (const GLubyte *) value;
3146    GET_XRB(xrb);
3147    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3148    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
3149    register GLuint i;
3150    XDITHER_SETUP(y);
3151    for (i=0;i<n;i++,x++) {
3152       if (!mask || mask[i]) {
3153          ptr[i] = (GLubyte) XDITHER( x, r, g, b );
3154       }
3155    }
3156 }
3157
3158
3159 /*
3160  * Write a span of identical 8-bit LOOKUP pixels to an XImage.
3161  */
3162 static void put_mono_row_LOOKUP8_ximage( PUT_MONO_ROW_ARGS )
3163 {
3164    const GLubyte *color = (const GLubyte *) value;
3165    GET_XRB(xrb);
3166    register GLuint i;
3167    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
3168    GLubyte pixel;
3169    LOOKUP_SETUP;
3170    pixel = LOOKUP(color[RCOMP], color[GCOMP], color[BCOMP]);
3171    for (i=0;i<n;i++) {
3172       if (!mask || mask[i]) {
3173          ptr[i] = pixel;
3174       }
3175    }
3176 }
3177
3178
3179 /*
3180  * Write a span of identical PF_1BIT pixels to an XImage.
3181  */
3182 static void put_mono_row_1BIT_ximage( PUT_MONO_ROW_ARGS )
3183 {
3184    const GLubyte *color = (const GLubyte *) value;
3185    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3186    GET_XRB(xrb);
3187    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3188    XMesaImage *img = xrb->ximage;
3189    register GLuint i;
3190    SETUP_1BIT;
3191    y = YFLIP(xrb, y);
3192    for (i=0;i<n;i++,x++) {
3193       if (!mask || mask[i]) {
3194          XMesaPutPixel( img, x, y, DITHER_1BIT( x, y, r, g, b ) );
3195       }
3196    }
3197 }
3198
3199
3200 /*
3201  * Write a span of identical HPCR pixels to an XImage.
3202  */
3203 static void put_mono_row_HPCR_ximage( PUT_MONO_ROW_ARGS )
3204 {
3205    const GLubyte *color = (const GLubyte *) value;
3206    GET_XRB(xrb);
3207    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3208    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3209    register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y);
3210    register GLuint i;
3211    for (i=0;i<n;i++,x++) {
3212       if (!mask || mask[i]) {
3213          ptr[i] = DITHER_HPCR( x, y, r, g, b );
3214       }
3215    }
3216 }
3217
3218
3219 /*
3220  * Write a span of identical 8-bit GRAYSCALE pixels to an XImage.
3221  */
3222 static void put_mono_row_GRAYSCALE8_ximage( PUT_MONO_ROW_ARGS )
3223 {
3224    const GLubyte *color = (const GLubyte *) value;
3225    GET_XRB(xrb);
3226    const GLubyte p = GRAY_RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
3227    GLubyte *ptr = (GLubyte *) PIXEL_ADDR1(xrb, x, y);
3228    GLuint i;
3229    for (i=0;i<n;i++) {
3230       if (!mask || mask[i]) {
3231          ptr[i] = p;
3232       }
3233    }
3234 }
3235
3236
3237
3238 /*
3239  * Write a span of identical PF_DITHER_5R6G5B pixels to an XImage.
3240  */
3241 static void put_mono_row_DITHER_5R6G5B_ximage( PUT_MONO_ROW_ARGS )
3242 {
3243    const GLubyte *color = (const GLubyte *) value;
3244    GET_XRB(xrb);
3245    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3246    register GLushort *ptr = PIXEL_ADDR2(xrb, x, y );
3247    const GLint r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3248    GLuint i;
3249    y = YFLIP(xrb, y);
3250    for (i=0;i<n;i++) {
3251       if (!mask || mask[i]) {
3252          PACK_TRUEDITHER(ptr[i], x+i, y, r, g, b);
3253       }
3254    }
3255 }
3256
3257
3258
3259 /**********************************************************************/
3260 /*** Write MONO COLOR PIXELS functions                              ***/
3261 /**********************************************************************/
3262
3263 #define PUT_MONO_VALUES_ARGS \
3264         struct gl_context *ctx, struct gl_renderbuffer *rb,     \
3265         GLuint n, const GLint x[], const GLint y[],     \
3266         const void *value, const GLubyte mask[]
3267
3268
3269
3270 /*
3271  * Write an array of identical pixels to a pixmap.
3272  */
3273 static void put_mono_values_pixmap( PUT_MONO_VALUES_ARGS )
3274 {
3275    const GLubyte *color = (const GLubyte *) value;
3276    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3277    GET_XRB(xrb);
3278    XMesaDisplay *dpy = xmesa->xm_visual->display;
3279    XMesaDrawable buffer = xrb->drawable;
3280    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
3281    register GLuint i;
3282    const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP],
3283                color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat);
3284    XMesaSetForeground( xmesa->display, gc, pixel );
3285    for (i=0;i<n;i++) {
3286       if (mask[i]) {
3287          XMesaDrawPoint( dpy, buffer, gc,
3288                          (int) x[i], (int) YFLIP(xrb, y[i]) );
3289       }
3290    }
3291 }
3292
3293
3294 static void
3295 put_mono_values_ci_pixmap( PUT_MONO_VALUES_ARGS )
3296 {
3297    const GLuint colorIndex = *((GLuint *) value);
3298    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3299    GET_XRB(xrb);
3300    XMesaDisplay *dpy = xmesa->xm_visual->display;
3301    XMesaDrawable buffer = xrb->drawable;
3302    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
3303    register GLuint i;
3304    XMesaSetForeground( xmesa->display, gc, colorIndex );
3305    for (i=0;i<n;i++) {
3306       if (mask[i]) {
3307          XMesaDrawPoint( dpy, buffer, gc,
3308                          (int) x[i], (int) YFLIP(xrb, y[i]) );
3309       }
3310    }
3311 }
3312
3313
3314 /*
3315  * Write an array of PF_TRUEDITHER pixels to a pixmap.
3316  */
3317 static void put_mono_values_TRUEDITHER_pixmap( PUT_MONO_VALUES_ARGS )
3318 {
3319    const GLubyte *color = (const GLubyte *) value;
3320    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3321    GET_XRB(xrb);
3322    XMesaDisplay *dpy = xmesa->xm_visual->display;
3323    XMesaDrawable buffer = xrb->drawable;
3324    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
3325    register GLuint i;
3326    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3327    for (i=0;i<n;i++) {
3328       if (mask[i]) {
3329          unsigned long p;
3330          PACK_TRUEDITHER(p, x[i], y[i], r, g, b);
3331          XMesaSetForeground( dpy, gc, p );
3332          XMesaDrawPoint( dpy, buffer, gc,
3333                          (int) x[i], (int) YFLIP(xrb, y[i]) );
3334       }
3335    }
3336 }
3337
3338
3339 /*
3340  * Write an array of PF_DITHER pixels to a pixmap.
3341  */
3342 static void put_mono_values_DITHER_pixmap( PUT_MONO_VALUES_ARGS )
3343 {
3344    const GLubyte *color = (const GLubyte *) value;
3345    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3346    GET_XRB(xrb);
3347    XMesaDisplay *dpy = xmesa->xm_visual->display;
3348    XMesaDrawable buffer = xrb->drawable;
3349    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
3350    register GLuint i;
3351    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3352    DITHER_SETUP;
3353    for (i=0;i<n;i++) {
3354       if (mask[i]) {
3355          XMesaSetForeground( dpy, gc, DITHER( x[i], y[i], r, g, b ) );
3356          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
3357       }
3358    }
3359 }
3360
3361
3362 /*
3363  * Write an array of PF_1BIT pixels to a pixmap.
3364  */
3365 static void put_mono_values_1BIT_pixmap( PUT_MONO_VALUES_ARGS )
3366 {
3367    const GLubyte *color = (const GLubyte *) value;
3368    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3369    GET_XRB(xrb);
3370    XMesaDisplay *dpy = xmesa->xm_visual->display;
3371    XMesaDrawable buffer = xrb->drawable;
3372    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
3373    register GLuint i;
3374    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3375    SETUP_1BIT;
3376    for (i=0;i<n;i++) {
3377       if (mask[i]) {
3378          XMesaSetForeground( dpy, gc, DITHER_1BIT( x[i], y[i], r, g, b ) );
3379          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
3380       }
3381    }
3382 }
3383
3384
3385 /*
3386  * Write an array of identical pixels to an XImage.
3387  */
3388 static void put_mono_values_ximage( PUT_MONO_VALUES_ARGS )
3389 {
3390    const GLubyte *color = (const GLubyte *) value;
3391    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3392    GET_XRB(xrb);
3393    XMesaImage *img = xrb->ximage;
3394    register GLuint i;
3395    const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP],
3396                color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat);
3397    for (i=0;i<n;i++) {
3398       if (mask[i]) {
3399          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), pixel );
3400       }
3401    }
3402 }
3403
3404
3405 static void
3406 put_mono_values_ci_ximage( PUT_MONO_VALUES_ARGS )
3407 {
3408    const GLuint colorIndex = *((GLuint *) value);
3409    GET_XRB(xrb);
3410    XMesaImage *img = xrb->ximage;
3411    register GLuint i;
3412    for (i=0;i<n;i++) {
3413       if (mask[i]) {
3414          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), colorIndex );
3415       }
3416    }
3417 }
3418
3419
3420 /*
3421  * Write an array of identical TRUEDITHER pixels to an XImage.
3422  */
3423 static void put_mono_values_TRUEDITHER_ximage( PUT_MONO_VALUES_ARGS )
3424 {
3425    const GLubyte *color = (const GLubyte *) value;
3426    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3427    GET_XRB(xrb);
3428    XMesaImage *img = xrb->ximage;
3429    register GLuint i;
3430    const int r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3431    for (i=0;i<n;i++) {
3432       if (mask[i]) {
3433          unsigned long p;
3434          PACK_TRUEDITHER(p, x[i], YFLIP(xrb, y[i]), r, g, b);
3435          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), p );
3436       }
3437    }
3438 }
3439
3440
3441
3442 /*
3443  * Write an array of identical 8A8B8G8R pixels to an XImage
3444  */
3445 static void put_mono_values_8A8B8G8R_ximage( PUT_MONO_VALUES_ARGS )
3446 {
3447    const GLubyte *color = (const GLubyte *) value;
3448    GET_XRB(xrb);
3449    const GLuint p = PACK_8A8B8G8R(color[RCOMP], color[GCOMP],
3450                                   color[BCOMP], color[ACOMP]);
3451    register GLuint i;
3452    for (i=0;i<n;i++) {
3453       if (mask[i]) {
3454          GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i] );
3455          *ptr = p;
3456       }
3457    }
3458 }
3459
3460 /*
3461  * Write an array of identical 8A8R8G8B pixels to an XImage
3462  */
3463 static void put_mono_values_8A8R8G8B_ximage( PUT_MONO_VALUES_ARGS )
3464 {
3465    const GLubyte *color = (const GLubyte *) value;
3466    GET_XRB(xrb);
3467    const GLuint p = PACK_8A8R8G8B(color[RCOMP], color[GCOMP],
3468                                   color[BCOMP], color[ACOMP]);
3469    register GLuint i;
3470    for (i=0;i<n;i++) {
3471       if (mask[i]) {
3472          GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i] );
3473          *ptr = p;
3474       }
3475    }
3476 }
3477
3478 /*
3479  * Write an array of identical 8R8G8B pixels to an XImage.
3480  */
3481 static void put_mono_values_8R8G8B_ximage( PUT_MONO_VALUES_ARGS )
3482 {
3483    const GLubyte *color = (const GLubyte *) value;
3484    GET_XRB(xrb);
3485    register GLuint i;
3486    const GLuint p = PACK_8R8G8B(color[RCOMP], color[GCOMP], color[BCOMP]);
3487    for (i=0;i<n;i++) {
3488       if (mask[i]) {
3489          GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i] );
3490          *ptr = p;
3491       }
3492    }
3493 }
3494
3495
3496 /*
3497  * Write an array of identical 8R8G8B pixels to an XImage.
3498  */
3499 static void put_mono_values_8R8G8B24_ximage( PUT_MONO_VALUES_ARGS )
3500 {
3501    const GLubyte *color = (const GLubyte *) value;
3502    GET_XRB(xrb);
3503    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3504    register GLuint i;
3505    for (i=0;i<n;i++) {
3506       if (mask[i]) {
3507          bgr_t *ptr = PIXEL_ADDR3(xrb, x[i], y[i] );
3508          ptr->r = r;
3509          ptr->g = g;
3510          ptr->b = b;
3511       }
3512    }
3513 }
3514
3515
3516 /*
3517  * Write an array of identical PF_DITHER pixels to an XImage.
3518  */
3519 static void put_mono_values_DITHER_ximage( PUT_MONO_VALUES_ARGS )
3520 {
3521    const GLubyte *color = (const GLubyte *) value;
3522    GET_XRB(xrb);
3523    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3524    XMesaImage *img = xrb->ximage;
3525    register GLuint i;
3526    DITHER_SETUP;
3527    for (i=0;i<n;i++) {
3528       if (mask[i]) {
3529          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), DITHER( x[i], y[i], r, g, b ) );
3530       }
3531    }
3532 }
3533
3534
3535 /*
3536  * Write an array of identical 8-bit PF_DITHER pixels to an XImage.
3537  */
3538 static void put_mono_values_DITHER8_ximage( PUT_MONO_VALUES_ARGS )
3539 {
3540    const GLubyte *color = (const GLubyte *) value;
3541    GET_XRB(xrb);
3542    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3543    register GLuint i;
3544    DITHER_SETUP;
3545    for (i=0;i<n;i++) {
3546       if (mask[i]) {
3547          GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]);
3548          *ptr = (GLubyte) DITHER( x[i], y[i], r, g, b );
3549       }
3550    }
3551 }
3552
3553
3554 /*
3555  * Write an array of identical 8-bit PF_LOOKUP pixels to an XImage.
3556  */
3557 static void put_mono_values_LOOKUP8_ximage( PUT_MONO_VALUES_ARGS )
3558 {
3559    const GLubyte *color = (const GLubyte *) value;
3560    GET_XRB(xrb);
3561    register GLuint i;
3562    GLubyte pixel;
3563    LOOKUP_SETUP;
3564    pixel = LOOKUP(color[RCOMP], color[GCOMP], color[BCOMP]);
3565    for (i=0;i<n;i++) {
3566       if (mask[i]) {
3567          GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]);
3568          *ptr = pixel;
3569       }
3570    }
3571 }
3572
3573
3574
3575 /*
3576  * Write an array of identical PF_1BIT pixels to an XImage.
3577  */
3578 static void put_mono_values_1BIT_ximage( PUT_MONO_VALUES_ARGS )
3579 {
3580    const GLubyte *color = (const GLubyte *) value;
3581    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3582    GET_XRB(xrb);
3583    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3584    XMesaImage *img = xrb->ximage;
3585    register GLuint i;
3586    SETUP_1BIT;
3587    for (i=0;i<n;i++) {
3588       if (mask[i]) {
3589          XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]),
3590                         DITHER_1BIT( x[i], y[i], r, g, b ));
3591       }
3592    }
3593 }
3594
3595
3596 /*
3597  * Write an array of identical PF_HPCR pixels to an XImage.
3598  */
3599 static void put_mono_values_HPCR_ximage( PUT_MONO_VALUES_ARGS )
3600 {
3601    const GLubyte *color = (const GLubyte *) value;
3602    GET_XRB(xrb);
3603    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3604    const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3605    register GLuint i;
3606    for (i=0;i<n;i++) {
3607       if (mask[i]) {
3608          GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]);
3609          *ptr = DITHER_HPCR( x[i], y[i], r, g, b );
3610       }
3611    }
3612 }
3613
3614
3615 /*
3616  * Write an array of identical 8-bit PF_GRAYSCALE pixels to an XImage.
3617  */
3618 static void put_mono_values_GRAYSCALE8_ximage( PUT_MONO_VALUES_ARGS )
3619 {
3620    const GLubyte *color = (const GLubyte *) value;
3621    GET_XRB(xrb);
3622    register GLuint i;
3623    register GLubyte p = GRAY_RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
3624    for (i=0;i<n;i++) {
3625       if (mask[i]) {
3626          GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]);
3627          *ptr = p;
3628       }
3629    }
3630 }
3631
3632
3633 /*
3634  * Write an array of identical PF_DITHER_5R6G5B pixels to an XImage.
3635  */
3636 static void put_mono_values_DITHER_5R6G5B_ximage( PUT_MONO_VALUES_ARGS )
3637 {
3638    const GLubyte *color = (const GLubyte *) value;
3639    GET_XRB(xrb);
3640    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3641    const int r = color[RCOMP], g = color[GCOMP], b = color[BCOMP];
3642    register GLuint i;
3643    for (i=0;i<n;i++) {
3644       if (mask[i]) {
3645          GLushort *ptr = PIXEL_ADDR2(xrb, x[i], y[i] );
3646          PACK_TRUEDITHER(*ptr, x[i], y[i], r, g, b);
3647       }
3648    }
3649 }
3650
3651
3652
3653 /**********************************************************************/
3654 /*** Write INDEX SPAN functions                                     ***/
3655 /**********************************************************************/
3656
3657 /*
3658  * Write a span of CI pixels to a Pixmap.
3659  */
3660 static void put_row_ci_pixmap( PUT_ROW_ARGS )
3661 {
3662    const GLuint *index = (GLuint *) values;
3663    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3664    GET_XRB(xrb);
3665    XMesaDisplay *dpy = xmesa->xm_visual->display;
3666    XMesaDrawable buffer = xrb->drawable;
3667    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
3668    register GLuint i;
3669    y = YFLIP(xrb, y);
3670    if (mask) {
3671       for (i=0;i<n;i++,x++) {
3672          if (mask[i]) {
3673             XMesaSetForeground( dpy, gc, (unsigned long) index[i] );
3674             XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
3675          }
3676       }
3677    }
3678    else {
3679       for (i=0;i<n;i++,x++) {
3680          XMesaSetForeground( dpy, gc, (unsigned long) index[i] );
3681          XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y );
3682       }
3683    }
3684 }
3685
3686
3687 /*
3688  * Write a span of CI pixels to an XImage.
3689  */
3690 static void put_row_ci_ximage( PUT_ROW_ARGS )
3691 {
3692    const GLuint *index = (const GLuint *) values;
3693    GET_XRB(xrb);
3694    XMesaImage *img = xrb->ximage;
3695    register GLuint i;
3696    y = YFLIP(xrb, y);
3697    if (mask) {
3698       for (i=0;i<n;i++,x++) {
3699          if (mask[i]) {
3700             XMesaPutPixel( img, x, y, (unsigned long) index[i] );
3701          }
3702       }
3703    }
3704    else {
3705       for (i=0;i<n;i++,x++) {
3706          XMesaPutPixel( img, x, y, (unsigned long) index[i] );
3707       }
3708    }
3709 }
3710
3711
3712 /**********************************************************************/
3713 /*** Write INDEX PIXELS functions                                   ***/
3714 /**********************************************************************/
3715
3716 /*
3717  * Write an array of CI pixels to a Pixmap.
3718  */
3719 static void put_values_ci_pixmap( PUT_VALUES_ARGS )
3720 {
3721    const GLuint *index = (const GLuint *) values;
3722    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3723    GET_XRB(xrb);
3724    XMesaDisplay *dpy = xmesa->xm_visual->display;
3725    XMesaDrawable buffer = xrb->drawable;
3726    XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc;
3727    register GLuint i;
3728    for (i=0;i<n;i++) {
3729       if (mask[i]) {
3730          XMesaSetForeground( dpy, gc, (unsigned long) index[i] );
3731          XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) );
3732       }
3733    }
3734 }
3735
3736
3737 /*
3738  * Write an array of CI pixels to an XImage.
3739  */
3740 static void put_values_ci_ximage( PUT_VALUES_ARGS )
3741 {
3742    const GLuint *index = (const GLuint *) values;
3743    GET_XRB(xrb);
3744    XMesaImage *img = xrb->ximage;
3745    register GLuint i;
3746    for (i=0;i<n;i++) {
3747       if (mask[i]) {
3748          XMesaPutPixel(img, x[i], YFLIP(xrb, y[i]), (unsigned long) index[i]);
3749       }
3750    }
3751 }
3752
3753
3754
3755
3756 /**********************************************************************/
3757 /*****                      Pixel reading                         *****/
3758 /**********************************************************************/
3759
3760 /**
3761  * Do clip testing prior to calling XGetImage.  If any of the region lies
3762  * outside the screen's bounds, XGetImage will return NULL.
3763  * We use XTranslateCoordinates() to check if that's the case and
3764  * adjust the x, y and length parameters accordingly.
3765  * \return  -1 if span is totally clipped away,
3766  *          else return number of pixels to skip in the destination array.
3767  */
3768 static int
3769 clip_for_xgetimage(struct gl_context *ctx, XMesaPixmap pixmap, GLuint *n, GLint *x, GLint *y)
3770 {
3771    XMesaContext xmesa = XMESA_CONTEXT(ctx);
3772    XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer);
3773    Window rootWin = RootWindow(xmesa->display, 0);
3774    Window child;
3775    GLint screenWidth = WidthOfScreen(DefaultScreenOfDisplay(xmesa->display));
3776    GLint dx, dy;
3777    if (source->type == PBUFFER || source->type == PIXMAP)
3778       return 0;
3779    XTranslateCoordinates(xmesa->display, pixmap, rootWin,
3780                          *x, *y, &dx, &dy, &child);
3781    if (dx >= screenWidth) {
3782       /* totally clipped on right */
3783       return -1;
3784    }
3785    if (dx < 0) {
3786       /* clipped on left */
3787       GLint clip = -dx;
3788       if (clip >= (GLint) *n)
3789          return -1;  /* totally clipped on left */
3790       *x += clip;
3791       *n -= clip;
3792       dx = 0;
3793       return clip;
3794    }
3795    if ((GLint) (dx + *n) > screenWidth) {
3796       /* clipped on right */
3797       GLint clip = dx + *n - screenWidth;
3798       *n -= clip;
3799    }
3800    return 0;
3801 }
3802
3803
3804 /*
3805  * Read a horizontal span of color-index pixels.
3806  */
3807 static void
3808 get_row_ci(struct gl_context *ctx, struct gl_renderbuffer *rb,
3809            GLuint n, GLint x, GLint y, void *values)
3810 {
3811    GLuint *index = (GLuint *) values;
3812    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3813    GET_XRB(xrb);
3814    GLuint i;
3815
3816    y = YFLIP(xrb, y);
3817
3818    if (xrb->pixmap) {
3819       XMesaImage *span = NULL;
3820       int error;
3821       int k = clip_for_xgetimage(ctx, xrb->pixmap, &n, &x, &y);
3822       if (k < 0)
3823          return;
3824       index += k;
3825
3826       catch_xgetimage_errors( xmesa->display );
3827       span = XGetImage( xmesa->display, xrb->pixmap,
3828                         x, y, n, 1, AllPlanes, ZPixmap );
3829       error = check_xgetimage_errors();
3830       if (span && !error) {
3831          for (i=0;i<n;i++) {
3832             index[i] = (GLuint) XMesaGetPixel( span, i, 0 );
3833          }
3834       }
3835       else {
3836          /* return 0 pixels */
3837          for (i=0;i<n;i++) {
3838             index[i] = 0;
3839          }
3840       }
3841       if (span) {
3842          XMesaDestroyImage( span );
3843       }
3844    }
3845    else if (xrb->ximage) {
3846       XMesaImage *img = xrb->ximage;
3847       for (i=0;i<n;i++,x++) {
3848          index[i] = (GLuint) XMesaGetPixel( img, x, y );
3849       }
3850    }
3851 }
3852
3853
3854
3855 /*
3856  * Read a horizontal span of color pixels.
3857  */
3858 static void
3859 get_row_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
3860              GLuint n, GLint x, GLint y, void *values)
3861 {
3862    GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
3863    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
3864    GET_XRB(xrb);
3865    XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer);
3866
3867    if (xrb->pixmap) {
3868       /* Read from Pixmap or Window */
3869       XMesaImage *span = NULL;
3870       int error;
3871       int k;
3872       y = YFLIP(xrb, y);
3873       k = clip_for_xgetimage(ctx, xrb->pixmap, &n, &x, &y);
3874       if (k < 0)
3875          return;
3876       rgba += k;
3877       catch_xgetimage_errors( xmesa->display );
3878       span = XGetImage( xmesa->display, xrb->pixmap,
3879                         x, y, n, 1, AllPlanes, ZPixmap );
3880       error = check_xgetimage_errors();
3881       if (span && !error) {
3882          switch (xmesa->pixelformat) {
3883             case PF_Truecolor:
3884             case PF_Dither_True:
3885                {
3886                   const GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
3887                   const GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
3888                   const GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
3889                   unsigned long rMask = GET_REDMASK(xmesa->xm_visual);
3890                   unsigned long gMask = GET_GREENMASK(xmesa->xm_visual);
3891                   unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual);
3892                   GLint rShift = xmesa->xm_visual->rshift;
3893                   GLint gShift = xmesa->xm_visual->gshift;
3894                   GLint bShift = xmesa->xm_visual->bshift;
3895                   GLuint i;
3896                   for (i=0;i<n;i++) {
3897                      unsigned long p;
3898                      p = XMesaGetPixel( span, i, 0 );
3899                      rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift];
3900                      rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift];
3901                      rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift];
3902                      rgba[i][ACOMP] = 255;
3903                   }
3904                }
3905                break;
3906             case PF_5R6G5B:
3907             case PF_Dither_5R6G5B:
3908                {
3909                   const GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
3910                   const GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
3911                   const GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
3912                   GLuint i;
3913                   for (i=0;i<n;i++) {
3914                      unsigned long p = XMesaGetPixel( span, i, 0 );
3915                      /* fast, but not quite accurate
3916                      rgba[i][RCOMP] = ((p >> 8) & 0xf8);
3917                      rgba[i][GCOMP] = ((p >> 3) & 0xfc);
3918                      rgba[i][BCOMP] = ((p << 3) & 0xff);
3919                      */
3920                      rgba[i][RCOMP] = pixelToR[p >> 11];
3921                      rgba[i][GCOMP] = pixelToG[(p >> 5) & 0x3f];
3922                      rgba[i][BCOMP] = pixelToB[p & 0x1f];
3923                      rgba[i][ACOMP] = 255;
3924                   }
3925                }
3926                break;
3927             case PF_8A8B8G8R:
3928                {
3929                   const GLuint *ptr4 = (GLuint *) span->data;
3930                   GLuint i;
3931                   for (i=0;i<n;i++) {
3932                      GLuint p4 = *ptr4++;
3933                      rgba[i][RCOMP] = (GLubyte) ( p4        & 0xff);
3934                      rgba[i][GCOMP] = (GLubyte) ((p4 >> 8)  & 0xff);
3935                      rgba[i][BCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
3936                      rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff);
3937                   }
3938                }
3939                break;
3940             case PF_8A8R8G8B:
3941                {
3942                   const GLuint *ptr4 = (GLuint *) span->data;
3943                   GLuint i;
3944                   for (i=0;i<n;i++) {
3945                      GLuint p4 = *ptr4++;
3946                      rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
3947                      rgba[i][GCOMP] = (GLubyte) ((p4 >> 8)  & 0xff);
3948                      rgba[i][BCOMP] = (GLubyte) ( p4        & 0xff);
3949                      rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff);
3950                   }
3951                }
3952                break;
3953             case PF_8R8G8B:
3954                {
3955                   const GLuint *ptr4 = (GLuint *) span->data;
3956                   GLuint i;
3957                   for (i=0;i<n;i++) {
3958                      GLuint p4 = *ptr4++;
3959                      rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
3960                      rgba[i][GCOMP] = (GLubyte) ((p4 >> 8)  & 0xff);
3961                      rgba[i][BCOMP] = (GLubyte) ( p4        & 0xff);
3962                      rgba[i][ACOMP] = 255;
3963                   }
3964                }
3965                break;
3966             case PF_8R8G8B24:
3967                {
3968                   const bgr_t *ptr3 = (bgr_t *) span->data;
3969                   GLuint i;
3970                   for (i=0;i<n;i++) {
3971                      rgba[i][RCOMP] = ptr3[i].r;
3972                      rgba[i][GCOMP] = ptr3[i].g;
3973                      rgba[i][BCOMP] = ptr3[i].b;
3974                      rgba[i][ACOMP] = 255;
3975                   }
3976                }
3977                break;
3978             case PF_HPCR:
3979                {
3980                   GLubyte *ptr1 = (GLubyte *) span->data;
3981                   GLuint i;
3982                   for (i=0;i<n;i++) {
3983                      GLubyte p = *ptr1++;
3984                      rgba[i][RCOMP] =  p & 0xE0;
3985                      rgba[i][GCOMP] = (p & 0x1C) << 3;
3986                      rgba[i][BCOMP] = (p & 0x03) << 6;
3987                      rgba[i][ACOMP] = 255;
3988                   }
3989                }
3990                break;
3991             case PF_Dither:
3992             case PF_Lookup:
3993             case PF_Grayscale:
3994                {
3995                   GLubyte *rTable = source->pixel_to_r;
3996                   GLubyte *gTable = source->pixel_to_g;
3997                   GLubyte *bTable = source->pixel_to_b;
3998                   if (GET_VISUAL_DEPTH(xmesa->xm_visual)==8) {
3999                      const GLubyte *ptr1 = (GLubyte *) span->data;
4000                      GLuint i;
4001                      for (i=0;i<n;i++) {
4002                         unsigned long p = *ptr1++;
4003                         rgba[i][RCOMP] = rTable[p];
4004                         rgba[i][GCOMP] = gTable[p];
4005                         rgba[i][BCOMP] = bTable[p];
4006                         rgba[i][ACOMP] = 255;
4007                      }
4008                   }
4009                   else {
4010                      GLuint i;
4011                      for (i=0;i<n;i++) {
4012                         unsigned long p = XMesaGetPixel( span, i, 0 );
4013                         rgba[i][RCOMP] = rTable[p];
4014                         rgba[i][GCOMP] = gTable[p];
4015                         rgba[i][BCOMP] = bTable[p];
4016                         rgba[i][ACOMP] = 255;
4017                      }
4018                   }
4019                }
4020                break;
4021             case PF_1Bit:
4022                {
4023                   int bitFlip = xmesa->xm_visual->bitFlip;
4024                   GLuint i;
4025                   for (i=0;i<n;i++) {
4026                      unsigned long p;
4027                      p = XMesaGetPixel( span, i, 0 ) ^ bitFlip;
4028                      rgba[i][RCOMP] = (GLubyte) (p * 255);
4029                      rgba[i][GCOMP] = (GLubyte) (p * 255);
4030                      rgba[i][BCOMP] = (GLubyte) (p * 255);
4031                      rgba[i][ACOMP] = 255;
4032                   }
4033                }
4034                break;
4035             default:
4036                _mesa_problem(NULL,"Problem in DD.read_color_span (1)");
4037                return;
4038          }
4039       }
4040       else {
4041          /* return black pixels */
4042          GLuint i;
4043          for (i=0;i<n;i++) {
4044             rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = rgba[i][ACOMP] = 0;
4045          }
4046       }
4047       if (span) {
4048          XMesaDestroyImage( span );
4049       }
4050    }
4051    else if (xrb->ximage) {
4052       /* Read from XImage back buffer */
4053       switch (xmesa->pixelformat) {
4054          case PF_Truecolor:
4055          case PF_Dither_True:
4056             {
4057                const GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
4058                const GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
4059                const GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
4060                unsigned long rMask = GET_REDMASK(xmesa->xm_visual);
4061                unsigned long gMask = GET_GREENMASK(xmesa->xm_visual);
4062                unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual);
4063                GLint rShift = xmesa->xm_visual->rshift;
4064                GLint gShift = xmesa->xm_visual->gshift;
4065                GLint bShift = xmesa->xm_visual->bshift;
4066                XMesaImage *img = xrb->ximage;
4067                GLuint i;
4068                y = YFLIP(xrb, y);
4069                for (i=0;i<n;i++) {
4070                   unsigned long p;
4071                   p = XMesaGetPixel( img, x+i, y );
4072                   rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift];
4073                   rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift];
4074                   rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift];
4075                   rgba[i][ACOMP] = 255;
4076                }
4077             }
4078             break;
4079          case PF_5R6G5B:
4080          case PF_Dither_5R6G5B:
4081             {
4082                const GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
4083                const GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
4084                const GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
4085                const GLushort *ptr2 = PIXEL_ADDR2(xrb, x, y);
4086                GLuint i;
4087 #if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */
4088                const GLuint *ptr4 = (const GLuint *) ptr2;
4089                GLuint extraPixel = (n & 1);
4090                n -= extraPixel;
4091                for (i = 0; i < n; i += 2) {
4092                   const GLuint p = *ptr4++;
4093                   const GLuint p0 = p & 0xffff;
4094                   const GLuint p1 = p >> 16;
4095                   /* fast, but not quite accurate
4096                   rgba[i][RCOMP] = ((p >> 8) & 0xf8);
4097                   rgba[i][GCOMP] = ((p >> 3) & 0xfc);
4098                   rgba[i][BCOMP] = ((p << 3) & 0xff);
4099                   */
4100                   rgba[i][RCOMP] = pixelToR[p0 >> 11];
4101                   rgba[i][GCOMP] = pixelToG[(p0 >> 5) & 0x3f];
4102                   rgba[i][BCOMP] = pixelToB[p0 & 0x1f];
4103                   rgba[i][ACOMP] = 255;
4104                   rgba[i+1][RCOMP] = pixelToR[p1 >> 11];
4105                   rgba[i+1][GCOMP] = pixelToG[(p1 >> 5) & 0x3f];
4106                   rgba[i+1][BCOMP] = pixelToB[p1 & 0x1f];
4107                   rgba[i+1][ACOMP] = 255;
4108                }
4109                if (extraPixel) {
4110                   GLushort p = ptr2[n];
4111                   rgba[n][RCOMP] = pixelToR[p >> 11];
4112                   rgba[n][GCOMP] = pixelToG[(p >> 5) & 0x3f];
4113                   rgba[n][BCOMP] = pixelToB[p & 0x1f];
4114                   rgba[n][ACOMP] = 255;
4115                }
4116 #else
4117                for (i = 0; i < n; i++) {
4118                   const GLushort p = ptr2[i];
4119                   rgba[i][RCOMP] = pixelToR[p >> 11];
4120                   rgba[i][GCOMP] = pixelToG[(p >> 5) & 0x3f];
4121                   rgba[i][BCOMP] = pixelToB[p & 0x1f];
4122                   rgba[i][ACOMP] = 255;
4123                }
4124 #endif
4125             }
4126             break;
4127          case PF_8A8B8G8R:
4128             {
4129                const GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y);
4130                GLuint i;
4131                for (i=0;i<n;i++) {
4132                   GLuint p4 = *ptr4++;
4133                   rgba[i][RCOMP] = (GLubyte) ( p4        & 0xff);
4134                   rgba[i][GCOMP] = (GLubyte) ((p4 >> 8)  & 0xff);
4135                   rgba[i][BCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
4136                   rgba[i][ACOMP] = (GLint)   ((p4 >> 24) & 0xff);
4137                }
4138             }
4139             break;
4140          case PF_8A8R8G8B:
4141             {
4142                const GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y);
4143                GLuint i;
4144                for (i=0;i<n;i++) {
4145                   GLuint p4 = *ptr4++;
4146                   rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
4147                   rgba[i][GCOMP] = (GLubyte) ((p4 >> 8)  & 0xff);
4148                   rgba[i][BCOMP] = (GLubyte) ( p4        & 0xff);
4149                   rgba[i][ACOMP] = (GLint)   ((p4 >> 24) & 0xff);
4150                }
4151             }
4152             break;
4153          case PF_8R8G8B:
4154             {
4155                const GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y);
4156                GLuint i;
4157                for (i=0;i<n;i++) {
4158                   GLuint p4 = *ptr4++;
4159                   rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
4160                   rgba[i][GCOMP] = (GLubyte) ((p4 >> 8)  & 0xff);
4161                   rgba[i][BCOMP] = (GLubyte) ( p4        & 0xff);
4162                   rgba[i][ACOMP] = 255;
4163                }
4164             }
4165             break;
4166          case PF_8R8G8B24:
4167             {
4168                const bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y);
4169                GLuint i;
4170                for (i=0;i<n;i++) {
4171                   rgba[i][RCOMP] = ptr3[i].r;
4172                   rgba[i][GCOMP] = ptr3[i].g;
4173                   rgba[i][BCOMP] = ptr3[i].b;
4174                   rgba[i][ACOMP] = 255;
4175                }
4176             }
4177             break;
4178          case PF_HPCR:
4179             {
4180                const GLubyte *ptr1 = PIXEL_ADDR1(xrb, x, y);
4181                GLuint i;
4182                for (i=0;i<n;i++) {
4183                   GLubyte p = *ptr1++;
4184                   rgba[i][RCOMP] =  p & 0xE0;
4185                   rgba[i][GCOMP] = (p & 0x1C) << 3;
4186                   rgba[i][BCOMP] = (p & 0x03) << 6;
4187                   rgba[i][ACOMP] = 255;
4188                }
4189             }
4190             break;
4191          case PF_Dither:
4192          case PF_Lookup:
4193          case PF_Grayscale:
4194             {
4195                const GLubyte *rTable = source->pixel_to_r;
4196                const GLubyte *gTable = source->pixel_to_g;
4197                const GLubyte *bTable = source->pixel_to_b;
4198                if (GET_VISUAL_DEPTH(xmesa->xm_visual)==8) {
4199                   GLubyte *ptr1 = PIXEL_ADDR1(xrb, x, y);
4200                   GLuint i;
4201                   for (i=0;i<n;i++) {
4202                      unsigned long p = *ptr1++;
4203                      rgba[i][RCOMP] = rTable[p];
4204                      rgba[i][GCOMP] = gTable[p];
4205                      rgba[i][BCOMP] = bTable[p];
4206                      rgba[i][ACOMP] = 255;
4207                   }
4208                }
4209                else {
4210                   XMesaImage *img = xrb->ximage;
4211                   GLuint i;
4212                   y = YFLIP(xrb, y);
4213                   for (i=0;i<n;i++,x++) {
4214                      unsigned long p = XMesaGetPixel( img, x, y );
4215                      rgba[i][RCOMP] = rTable[p];
4216                      rgba[i][GCOMP] = gTable[p];
4217                      rgba[i][BCOMP] = bTable[p];
4218                      rgba[i][ACOMP] = 255;
4219                   }
4220                }
4221             }
4222             break;
4223          case PF_1Bit:
4224             {
4225                XMesaImage *img = xrb->ximage;
4226                int bitFlip = xmesa->xm_visual->bitFlip;
4227                GLuint i;
4228                y = YFLIP(xrb, y);
4229                for (i=0;i<n;i++,x++) {
4230                   unsigned long p;
4231                   p = XMesaGetPixel( img, x, y ) ^ bitFlip;
4232                   rgba[i][RCOMP] = (GLubyte) (p * 255);
4233                   rgba[i][GCOMP] = (GLubyte) (p * 255);
4234                   rgba[i][BCOMP] = (GLubyte) (p * 255);
4235                   rgba[i][ACOMP] = 255;
4236                }
4237             }
4238             break;
4239          default:
4240             _mesa_problem(NULL,"Problem in DD.read_color_span (2)");
4241             return;
4242       }
4243    }
4244 }
4245
4246
4247
4248 /*
4249  * Read an array of color index pixels.
4250  */
4251 static void
4252 get_values_ci(struct gl_context *ctx, struct gl_renderbuffer *rb,
4253               GLuint n, const GLint x[], const GLint y[], void *values)
4254 {
4255    GLuint *indx = (GLuint *) values;
4256    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
4257    GET_XRB(xrb);
4258    GLuint i;
4259    if (xrb->pixmap) {
4260       for (i=0;i<n;i++) {
4261          indx[i] = (GLuint) read_pixel( xmesa->display, xrb->drawable,
4262                                         x[i], YFLIP(xrb, y[i]) );
4263       }
4264    }
4265    else if (xrb->ximage) {
4266       XMesaImage *img = xrb->ximage;
4267       for (i=0;i<n;i++) {
4268          indx[i] = (GLuint) XMesaGetPixel( img, x[i], YFLIP(xrb, y[i]) );
4269       }
4270    }
4271 }
4272
4273
4274
4275 static void
4276 get_values_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
4277                 GLuint n, const GLint x[], const GLint y[], void *values)
4278 {
4279    GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
4280    GET_XRB(xrb);
4281    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
4282    XMesaDisplay *dpy = xmesa->xm_visual->display;
4283    XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer);
4284    register GLuint i;
4285
4286    if (xrb->pixmap) {
4287       XMesaDrawable buffer = xrb->drawable;
4288       switch (xmesa->pixelformat) {
4289          case PF_Truecolor:
4290          case PF_Dither_True:
4291          case PF_5R6G5B:
4292          case PF_Dither_5R6G5B:
4293             {
4294                unsigned long rMask = GET_REDMASK(xmesa->xm_visual);
4295                unsigned long gMask = GET_GREENMASK(xmesa->xm_visual);
4296                unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual);
4297                GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
4298                GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
4299                GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
4300                GLint rShift = xmesa->xm_visual->rshift;
4301                GLint gShift = xmesa->xm_visual->gshift;
4302                GLint bShift = xmesa->xm_visual->bshift;
4303                for (i=0;i<n;i++) {
4304                   unsigned long p = read_pixel( dpy, buffer,
4305                                                 x[i], YFLIP(xrb, y[i]) );
4306                   rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift];
4307                   rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift];
4308                   rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift];
4309                   rgba[i][ACOMP] = 255;
4310                }
4311             }
4312             break;
4313          case PF_8A8B8G8R:
4314             for (i=0;i<n;i++) {
4315                unsigned long p = read_pixel( dpy, buffer,
4316                                              x[i], YFLIP(xrb, y[i]) );
4317                rgba[i][RCOMP] = (GLubyte) ( p        & 0xff);
4318                rgba[i][GCOMP] = (GLubyte) ((p >> 8)  & 0xff);
4319                rgba[i][BCOMP] = (GLubyte) ((p >> 16) & 0xff);
4320                rgba[i][ACOMP] = (GLubyte) ((p >> 24) & 0xff);
4321             }
4322             break;
4323          case PF_8A8R8G8B:
4324             for (i=0;i<n;i++) {
4325                unsigned long p = read_pixel( dpy, buffer,
4326                                              x[i], YFLIP(xrb, y[i]) );
4327                rgba[i][RCOMP] = (GLubyte) ((p >> 16) & 0xff);
4328                rgba[i][GCOMP] = (GLubyte) ((p >> 8)  & 0xff);
4329                rgba[i][BCOMP] = (GLubyte) ( p        & 0xff);
4330                rgba[i][ACOMP] = (GLubyte) ((p >> 24) & 0xff);
4331             }
4332             break;
4333          case PF_8R8G8B:
4334             for (i=0;i<n;i++) {
4335                unsigned long p = read_pixel( dpy, buffer,
4336                                              x[i], YFLIP(xrb, y[i]) );
4337                rgba[i][RCOMP] = (GLubyte) ((p >> 16) & 0xff);
4338                rgba[i][GCOMP] = (GLubyte) ((p >> 8)  & 0xff);
4339                rgba[i][BCOMP] = (GLubyte) ( p        & 0xff);
4340                rgba[i][ACOMP] = 255;
4341             }
4342             break;
4343          case PF_8R8G8B24:
4344             for (i=0;i<n;i++) {
4345                unsigned long p = read_pixel( dpy, buffer,
4346                                              x[i], YFLIP(xrb, y[i]) );
4347                rgba[i][RCOMP] = (GLubyte) ((p >> 16) & 0xff);
4348                rgba[i][GCOMP] = (GLubyte) ((p >> 8)  & 0xff);
4349                rgba[i][BCOMP] = (GLubyte) ( p        & 0xff);
4350                rgba[i][ACOMP] = 255;
4351             }
4352             break;
4353          case PF_HPCR:
4354             for (i=0;i<n;i++) {
4355                unsigned long p = read_pixel( dpy, buffer,
4356                                              x[i], YFLIP(xrb, y[i]) );
4357                rgba[i][RCOMP] = (GLubyte) ( p & 0xE0      );
4358                rgba[i][GCOMP] = (GLubyte) ((p & 0x1C) << 3);
4359                   rgba[i][BCOMP] = (GLubyte) ((p & 0x03) << 6);
4360                   rgba[i][ACOMP] = (GLubyte) 255;
4361             }
4362             break;
4363          case PF_Dither:
4364          case PF_Lookup:
4365          case PF_Grayscale:
4366             {
4367                GLubyte *rTable = source->pixel_to_r;
4368                GLubyte *gTable = source->pixel_to_g;
4369                GLubyte *bTable = source->pixel_to_b;
4370                for (i=0;i<n;i++) {
4371                   unsigned long p = read_pixel( dpy, buffer,
4372                                                 x[i], YFLIP(xrb, y[i]) );
4373                   rgba[i][RCOMP] = rTable[p];
4374                   rgba[i][GCOMP] = gTable[p];
4375                   rgba[i][BCOMP] = bTable[p];
4376                   rgba[i][ACOMP] = 255;
4377                }
4378             }
4379             break;
4380          case PF_1Bit:
4381             {
4382                int bitFlip = xmesa->xm_visual->bitFlip;
4383                for (i=0;i<n;i++) {
4384                   unsigned long p = read_pixel( dpy, buffer,
4385                                            x[i], YFLIP(xrb, y[i])) ^ bitFlip;
4386                   rgba[i][RCOMP] = (GLubyte) (p * 255);
4387                   rgba[i][GCOMP] = (GLubyte) (p * 255);
4388                   rgba[i][BCOMP] = (GLubyte) (p * 255);
4389                   rgba[i][ACOMP] = 255;
4390                }
4391             }
4392             break;
4393          default:
4394             _mesa_problem(NULL,"Problem in DD.read_color_pixels (1)");
4395             return;
4396       }
4397    }
4398    else if (xrb->ximage) {
4399       /* Read from XImage back buffer */
4400       switch (xmesa->pixelformat) {
4401          case PF_Truecolor:
4402          case PF_Dither_True:
4403          case PF_5R6G5B:
4404          case PF_Dither_5R6G5B:
4405             {
4406                unsigned long rMask = GET_REDMASK(xmesa->xm_visual);
4407                unsigned long gMask = GET_GREENMASK(xmesa->xm_visual);
4408                unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual);
4409                GLubyte *pixelToR = xmesa->xm_visual->PixelToR;
4410                GLubyte *pixelToG = xmesa->xm_visual->PixelToG;
4411                GLubyte *pixelToB = xmesa->xm_visual->PixelToB;
4412                GLint rShift = xmesa->xm_visual->rshift;
4413                GLint gShift = xmesa->xm_visual->gshift;
4414                GLint bShift = xmesa->xm_visual->bshift;
4415                XMesaImage *img = xrb->ximage;
4416                for (i=0;i<n;i++) {
4417                   unsigned long p;
4418                   p = XMesaGetPixel( img, x[i], YFLIP(xrb, y[i]) );
4419                   rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift];
4420                   rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift];
4421                   rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift];
4422                   rgba[i][ACOMP] = 255;
4423                }
4424             }
4425             break;
4426          case PF_8A8B8G8R:
4427             for (i=0;i<n;i++) {
4428                GLuint *ptr4 = PIXEL_ADDR4(xrb, x[i], y[i]);
4429                GLuint p4 = *ptr4;
4430                rgba[i][RCOMP] = (GLubyte) ( p4        & 0xff);
4431                rgba[i][GCOMP] = (GLubyte) ((p4 >> 8)  & 0xff);
4432                rgba[i][BCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
4433                rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff);
4434             }
4435             break;
4436          case PF_8A8R8G8B:
4437             for (i=0;i<n;i++) {
4438                GLuint *ptr4 = PIXEL_ADDR4(xrb, x[i], y[i]);
4439                GLuint p4 = *ptr4;
4440                rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
4441                rgba[i][GCOMP] = (GLubyte) ((p4 >> 8)  & 0xff);
4442                rgba[i][BCOMP] = (GLubyte) ( p4        & 0xff);
4443                rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff);
4444             }
4445             break;
4446          case PF_8R8G8B:
4447             for (i=0;i<n;i++) {
4448                GLuint *ptr4 = PIXEL_ADDR4(xrb, x[i], y[i]);
4449                GLuint p4 = *ptr4;
4450                rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff);
4451                rgba[i][GCOMP] = (GLubyte) ((p4 >> 8)  & 0xff);
4452                rgba[i][BCOMP] = (GLubyte) ( p4        & 0xff);
4453                rgba[i][ACOMP] = 255;
4454             }
4455             break;
4456          case PF_8R8G8B24:
4457             for (i=0;i<n;i++) {
4458                bgr_t *ptr3 = PIXEL_ADDR3(xrb, x[i], y[i]);
4459                rgba[i][RCOMP] = ptr3->r;
4460                rgba[i][GCOMP] = ptr3->g;
4461                rgba[i][BCOMP] = ptr3->b;
4462                rgba[i][ACOMP] = 255;
4463             }
4464             break;
4465          case PF_HPCR:
4466             for (i=0;i<n;i++) {
4467                GLubyte *ptr1 = PIXEL_ADDR1(xrb, x[i], y[i]);
4468                GLubyte p = *ptr1;
4469                rgba[i][RCOMP] =  p & 0xE0;
4470                rgba[i][GCOMP] = (p & 0x1C) << 3;
4471                rgba[i][BCOMP] = (p & 0x03) << 6;
4472                rgba[i][ACOMP] = 255;
4473             }
4474             break;
4475          case PF_Dither:
4476          case PF_Lookup:
4477          case PF_Grayscale:
4478             {
4479                GLubyte *rTable = source->pixel_to_r;
4480                GLubyte *gTable = source->pixel_to_g;
4481                GLubyte *bTable = source->pixel_to_b;
4482                XMesaImage *img = xrb->ximage;
4483                for (i=0;i<n;i++) {
4484                   unsigned long p;
4485                   p = XMesaGetPixel( img, x[i], YFLIP(xrb, y[i]) );
4486                   rgba[i][RCOMP] = rTable[p];
4487                   rgba[i][GCOMP] = gTable[p];
4488                   rgba[i][BCOMP] = bTable[p];
4489                   rgba[i][ACOMP] = 255;
4490                }
4491             }
4492             break;
4493          case PF_1Bit:
4494             {
4495                XMesaImage *img = xrb->ximage;
4496                int bitFlip = xmesa->xm_visual->bitFlip;
4497                for (i=0;i<n;i++) {
4498                   unsigned long p;
4499                   p = XMesaGetPixel( img, x[i], YFLIP(xrb, y[i]) ) ^ bitFlip;
4500                   rgba[i][RCOMP] = (GLubyte) (p * 255);
4501                   rgba[i][GCOMP] = (GLubyte) (p * 255);
4502                   rgba[i][BCOMP] = (GLubyte) (p * 255);
4503                   rgba[i][ACOMP] = 255;
4504                }
4505             }
4506             break;
4507          default:
4508             _mesa_problem(NULL,"Problem in DD.read_color_pixels (1)");
4509             return;
4510       }
4511    }
4512 }
4513
4514
4515 /**
4516  * Initialize the renderbuffer's PutRow, GetRow, etc. functions.
4517  * This would generally only need to be called once when the renderbuffer
4518  * is created.  However, we can change pixel formats on the fly if dithering
4519  * is enabled/disabled.  Therefore, we may call this more often than that.
4520  */
4521 void
4522 xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
4523                              enum pixel_format pixelformat, GLint depth)
4524 {
4525    const GLboolean pixmap = xrb->pixmap ? GL_TRUE : GL_FALSE;
4526
4527    switch (pixelformat) {
4528    case PF_Index:
4529       ASSERT(xrb->Base.DataType == GL_UNSIGNED_INT);
4530       if (pixmap) {
4531          xrb->Base.PutRow        = put_row_ci_pixmap;
4532          xrb->Base.PutRowRGB     = NULL;
4533          xrb->Base.PutMonoRow    = put_mono_row_ci_pixmap;
4534          xrb->Base.PutValues     = put_values_ci_pixmap;
4535          xrb->Base.PutMonoValues = put_mono_values_ci_pixmap;
4536       }
4537       else {
4538          xrb->Base.PutRow        = put_row_ci_ximage;
4539          xrb->Base.PutRowRGB     = NULL;
4540          xrb->Base.PutMonoRow    = put_mono_row_ci_ximage;
4541          xrb->Base.PutValues     = put_values_ci_ximage;
4542          xrb->Base.PutMonoValues = put_mono_values_ci_ximage;
4543       }
4544       break;
4545    case PF_Truecolor:
4546       if (pixmap) {
4547          xrb->Base.PutRow        = put_row_TRUECOLOR_pixmap;
4548          xrb->Base.PutRowRGB     = put_row_rgb_TRUECOLOR_pixmap;
4549          xrb->Base.PutMonoRow    = put_mono_row_pixmap;
4550          xrb->Base.PutValues     = put_values_TRUECOLOR_pixmap;
4551          xrb->Base.PutMonoValues = put_mono_values_pixmap;
4552       }
4553       else {
4554          xrb->Base.PutRow        = put_row_TRUECOLOR_ximage;
4555          xrb->Base.PutRowRGB     = put_row_rgb_TRUECOLOR_ximage;
4556          xrb->Base.PutMonoRow    = put_mono_row_ximage;
4557          xrb->Base.PutValues     = put_values_TRUECOLOR_ximage;
4558          xrb->Base.PutMonoValues = put_mono_values_ximage;
4559       }
4560       break;
4561    case PF_Dither_True:
4562       if (pixmap) {
4563          xrb->Base.PutRow        = put_row_TRUEDITHER_pixmap;
4564          xrb->Base.PutRowRGB     = put_row_rgb_TRUEDITHER_pixmap;
4565          xrb->Base.PutMonoRow    = put_mono_row_TRUEDITHER_pixmap;
4566          xrb->Base.PutValues     = put_values_TRUEDITHER_pixmap;
4567          xrb->Base.PutMonoValues = put_mono_values_TRUEDITHER_pixmap;
4568       }
4569       else {
4570          xrb->Base.PutRow        = put_row_TRUEDITHER_ximage;
4571          xrb->Base.PutRowRGB     = put_row_rgb_TRUEDITHER_ximage;
4572          xrb->Base.PutMonoRow    = put_mono_row_TRUEDITHER_ximage;
4573          xrb->Base.PutValues     = put_values_TRUEDITHER_ximage;
4574          xrb->Base.PutMonoValues = put_mono_values_TRUEDITHER_ximage;
4575       }
4576       break;
4577    case PF_8A8B8G8R:
4578       if (pixmap) {
4579          xrb->Base.PutRow        = put_row_8A8B8G8R_pixmap;
4580          xrb->Base.PutRowRGB     = put_row_rgb_8A8B8G8R_pixmap;
4581          xrb->Base.PutMonoRow    = put_mono_row_pixmap;
4582          xrb->Base.PutValues     = put_values_8A8B8G8R_pixmap;
4583          xrb->Base.PutMonoValues = put_mono_values_pixmap;
4584       }
4585       else {
4586          xrb->Base.PutRow        = put_row_8A8B8G8R_ximage;
4587          xrb->Base.PutRowRGB     = put_row_rgb_8A8B8G8R_ximage;
4588          xrb->Base.PutMonoRow    = put_mono_row_8A8B8G8R_ximage;
4589          xrb->Base.PutValues     = put_values_8A8B8G8R_ximage;
4590          xrb->Base.PutMonoValues = put_mono_values_8A8B8G8R_ximage;
4591       }
4592       break;
4593    case PF_8A8R8G8B:
4594       if (pixmap) {
4595          xrb->Base.PutRow        = put_row_8A8R8G8B_pixmap;
4596          xrb->Base.PutRowRGB     = put_row_rgb_8A8R8G8B_pixmap;
4597          xrb->Base.PutMonoRow    = put_mono_row_pixmap;
4598          xrb->Base.PutValues     = put_values_8A8R8G8B_pixmap;
4599          xrb->Base.PutMonoValues = put_mono_values_pixmap;
4600       }
4601       else {
4602          xrb->Base.PutRow        = put_row_8A8R8G8B_ximage;
4603          xrb->Base.PutRowRGB     = put_row_rgb_8A8R8G8B_ximage;
4604          xrb->Base.PutMonoRow    = put_mono_row_8A8R8G8B_ximage;
4605          xrb->Base.PutValues     = put_values_8A8R8G8B_ximage;
4606          xrb->Base.PutMonoValues = put_mono_values_8A8R8G8B_ximage;
4607       }
4608       break;
4609    case PF_8R8G8B:
4610       if (pixmap) {
4611          xrb->Base.PutRow        = put_row_8R8G8B_pixmap;
4612          xrb->Base.PutRowRGB     = put_row_rgb_8R8G8B_pixmap;
4613          xrb->Base.PutMonoRow    = put_mono_row_pixmap;
4614          xrb->Base.PutValues     = put_values_8R8G8B_pixmap;
4615          xrb->Base.PutMonoValues = put_mono_values_pixmap;
4616       }
4617       else {
4618          xrb->Base.PutRow        = put_row_8R8G8B_ximage;
4619          xrb->Base.PutRowRGB     = put_row_rgb_8R8G8B_ximage;
4620          xrb->Base.PutMonoRow    = put_mono_row_8R8G8B_ximage;
4621          xrb->Base.PutValues     = put_values_8R8G8B_ximage;
4622          xrb->Base.PutMonoValues = put_mono_values_8R8G8B_ximage;
4623       }
4624       break;
4625    case PF_8R8G8B24:
4626       if (pixmap) {
4627          xrb->Base.PutRow        = put_row_8R8G8B24_pixmap;
4628          xrb->Base.PutRowRGB     = put_row_rgb_8R8G8B24_pixmap;
4629          xrb->Base.PutMonoRow    = put_mono_row_pixmap;
4630          xrb->Base.PutValues     = put_values_8R8G8B24_pixmap;
4631          xrb->Base.PutMonoValues = put_mono_values_pixmap;
4632       }
4633       else {
4634          xrb->Base.PutRow        = put_row_8R8G8B24_ximage;
4635          xrb->Base.PutRowRGB     = put_row_rgb_8R8G8B24_ximage;
4636          xrb->Base.PutMonoRow    = put_mono_row_8R8G8B24_ximage;
4637          xrb->Base.PutValues     = put_values_8R8G8B24_ximage;
4638          xrb->Base.PutMonoValues = put_mono_values_8R8G8B24_ximage;
4639       }
4640       break;
4641    case PF_5R6G5B:
4642       if (pixmap) {
4643          xrb->Base.PutRow        = put_row_5R6G5B_pixmap;
4644          xrb->Base.PutRowRGB     = put_row_rgb_5R6G5B_pixmap;
4645          xrb->Base.PutMonoRow    = put_mono_row_pixmap;
4646          xrb->Base.PutValues     = put_values_5R6G5B_pixmap;
4647          xrb->Base.PutMonoValues = put_mono_values_pixmap;
4648       }
4649       else {
4650          xrb->Base.PutRow        = put_row_5R6G5B_ximage;
4651          xrb->Base.PutRowRGB     = put_row_rgb_5R6G5B_ximage;
4652          xrb->Base.PutMonoRow    = put_mono_row_ximage;
4653          xrb->Base.PutValues     = put_values_5R6G5B_ximage;
4654          xrb->Base.PutMonoValues = put_mono_values_ximage;
4655       }
4656       break;
4657    case PF_Dither_5R6G5B:
4658       if (pixmap) {
4659          xrb->Base.PutRow        = put_row_DITHER_5R6G5B_pixmap;
4660          xrb->Base.PutRowRGB     = put_row_rgb_DITHER_5R6G5B_pixmap;
4661          xrb->Base.PutMonoRow    = put_mono_row_TRUEDITHER_pixmap;
4662          xrb->Base.PutValues     = put_values_DITHER_5R6G5B_pixmap;
4663          xrb->Base.PutMonoValues = put_mono_values_TRUEDITHER_pixmap;
4664       }
4665       else {
4666          xrb->Base.PutRow        = put_row_DITHER_5R6G5B_ximage;
4667          xrb->Base.PutRowRGB     = put_row_rgb_DITHER_5R6G5B_ximage;
4668          xrb->Base.PutMonoRow    = put_mono_row_DITHER_5R6G5B_ximage;
4669          xrb->Base.PutValues     = put_values_DITHER_5R6G5B_ximage;
4670          xrb->Base.PutMonoValues = put_mono_values_DITHER_5R6G5B_ximage;
4671       }
4672       break;
4673    case PF_Dither:
4674       if (pixmap) {
4675          xrb->Base.PutRow        = put_row_DITHER_pixmap;
4676          xrb->Base.PutRowRGB     = put_row_rgb_DITHER_pixmap;
4677          xrb->Base.PutMonoRow    = put_mono_row_DITHER_pixmap;
4678          xrb->Base.PutValues     = put_values_DITHER_pixmap;
4679          xrb->Base.PutMonoValues = put_mono_values_DITHER_pixmap;
4680       }
4681       else {
4682          if (depth == 8) {
4683             xrb->Base.PutRow        = put_row_DITHER8_ximage;
4684             xrb->Base.PutRowRGB     = put_row_rgb_DITHER8_ximage;
4685             xrb->Base.PutMonoRow    = put_mono_row_DITHER8_ximage;
4686             xrb->Base.PutValues     = put_values_DITHER8_ximage;
4687             xrb->Base.PutMonoValues = put_mono_values_DITHER8_ximage;
4688          }
4689          else {
4690             xrb->Base.PutRow        = put_row_DITHER_ximage;
4691             xrb->Base.PutRowRGB     = put_row_rgb_DITHER_ximage;
4692             xrb->Base.PutMonoRow    = put_mono_row_DITHER_ximage;
4693             xrb->Base.PutValues     = put_values_DITHER_ximage;
4694             xrb->Base.PutMonoValues = put_mono_values_DITHER_ximage;
4695          }
4696       }
4697       break;
4698    case PF_1Bit:
4699       if (pixmap) {
4700          xrb->Base.PutRow        = put_row_1BIT_pixmap;
4701          xrb->Base.PutRowRGB     = put_row_rgb_1BIT_pixmap;
4702          xrb->Base.PutMonoRow    = put_mono_row_1BIT_pixmap;
4703          xrb->Base.PutValues     = put_values_1BIT_pixmap;
4704          xrb->Base.PutMonoValues = put_mono_values_1BIT_pixmap;
4705       }
4706       else {
4707          xrb->Base.PutRow        = put_row_1BIT_ximage;
4708          xrb->Base.PutRowRGB     = put_row_rgb_1BIT_ximage;
4709          xrb->Base.PutMonoRow    = put_mono_row_1BIT_ximage;
4710          xrb->Base.PutValues     = put_values_1BIT_ximage;
4711          xrb->Base.PutMonoValues = put_mono_values_1BIT_ximage;
4712       }
4713       break;
4714    case PF_HPCR:
4715       if (pixmap) {
4716          xrb->Base.PutRow        = put_row_HPCR_pixmap;
4717          xrb->Base.PutRowRGB     = put_row_rgb_HPCR_pixmap;
4718          xrb->Base.PutMonoRow    = put_mono_row_pixmap;
4719          xrb->Base.PutValues     = put_values_HPCR_pixmap;
4720          xrb->Base.PutMonoValues = put_mono_values_pixmap;
4721       }
4722       else {
4723          xrb->Base.PutRow        = put_row_HPCR_ximage;
4724          xrb->Base.PutRowRGB     = put_row_rgb_HPCR_ximage;
4725          xrb->Base.PutMonoRow    = put_mono_row_HPCR_ximage;
4726          xrb->Base.PutValues     = put_values_HPCR_ximage;
4727          xrb->Base.PutMonoValues = put_mono_values_HPCR_ximage;
4728       }
4729       break;
4730    case PF_Lookup:
4731       if (pixmap) {
4732          xrb->Base.PutRow        = put_row_LOOKUP_pixmap;
4733          xrb->Base.PutRowRGB     = put_row_rgb_LOOKUP_pixmap;
4734          xrb->Base.PutMonoRow    = put_mono_row_pixmap;
4735          xrb->Base.PutValues     = put_values_LOOKUP_pixmap;
4736          xrb->Base.PutMonoValues = put_mono_values_pixmap;
4737       }
4738       else {
4739          if (depth==8) {
4740             xrb->Base.PutRow        = put_row_LOOKUP8_ximage;
4741             xrb->Base.PutRowRGB     = put_row_rgb_LOOKUP8_ximage;
4742             xrb->Base.PutMonoRow    = put_mono_row_LOOKUP8_ximage;
4743             xrb->Base.PutValues     = put_values_LOOKUP8_ximage;
4744             xrb->Base.PutMonoValues = put_mono_values_LOOKUP8_ximage;
4745          }
4746          else {
4747             xrb->Base.PutRow        = put_row_LOOKUP_ximage;
4748             xrb->Base.PutRowRGB     = put_row_rgb_LOOKUP_ximage;
4749             xrb->Base.PutMonoRow    = put_mono_row_ximage;
4750             xrb->Base.PutValues     = put_values_LOOKUP_ximage;
4751             xrb->Base.PutMonoValues = put_mono_values_ximage;
4752          }
4753       }
4754       break;
4755    case PF_Grayscale:
4756       if (pixmap) {
4757          xrb->Base.PutRow        = put_row_GRAYSCALE_pixmap;
4758          xrb->Base.PutRowRGB     = put_row_rgb_GRAYSCALE_pixmap;
4759          xrb->Base.PutMonoRow    = put_mono_row_pixmap;
4760          xrb->Base.PutValues     = put_values_GRAYSCALE_pixmap;
4761          xrb->Base.PutMonoValues = put_mono_values_pixmap;
4762       }
4763       else {
4764          if (depth == 8) {
4765             xrb->Base.PutRow        = put_row_GRAYSCALE8_ximage;
4766             xrb->Base.PutRowRGB     = put_row_rgb_GRAYSCALE8_ximage;
4767             xrb->Base.PutMonoRow    = put_mono_row_GRAYSCALE8_ximage;
4768             xrb->Base.PutValues     = put_values_GRAYSCALE8_ximage;
4769             xrb->Base.PutMonoValues = put_mono_values_GRAYSCALE8_ximage;
4770          }
4771          else {
4772             xrb->Base.PutRow        = put_row_GRAYSCALE_ximage;
4773             xrb->Base.PutRowRGB     = put_row_rgb_GRAYSCALE_ximage;
4774             xrb->Base.PutMonoRow    = put_mono_row_ximage;
4775             xrb->Base.PutValues     = put_values_GRAYSCALE_ximage;
4776             xrb->Base.PutMonoValues = put_mono_values_ximage;
4777          }
4778       }
4779       break;
4780    default:
4781       _mesa_problem(NULL, "Bad pixel format in xmesa_update_state (1)");
4782       return;
4783    }
4784
4785
4786    /* Get functions */
4787    if (pixelformat == PF_Index) {
4788       xrb->Base.GetRow = get_row_ci;
4789       xrb->Base.GetValues = get_values_ci;
4790    }
4791    else {
4792       xrb->Base.GetRow = get_row_rgba;
4793       xrb->Base.GetValues = get_values_rgba;
4794    }
4795 }
4796