/* Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * dga_ab.c - the client side code for Ancillary Buffers (ABMG ) */ #include #include #include #include #include #include #include "dga_incls.h" extern int XDgaGrabABuffers(Display *dpy, Window win, int type, int buffer_site); extern int XDgaUnGrabABuffers(Display *dpy, Window win, int type); extern void *_dga_is_X_window(Dga_token token, Display **dpyp, Window *winp); #ifdef DEBUG #define assert(expr) \ if(!(expr)) \ {fprintf(stderr, "Assertion fails in file %s, line %d: expr\n",__FILE__,__LINE__); \ abort();} #else #define assert(expr) #endif /* DEBUG */ #define UNMAP_BUFFER(addr, allocsize) \ if ( addr ) { \ munmap((char *)addr, allocsize); \ addr = NULL; \ } #define GET_SW_HW_BUFFER(dgawin_buf, fname, bufsize) \ bufferp = (dga_buffer)get_specified_buffer((char *)fname, bufsize); \ (dgawin_buf)->bufferp = bufferp; \ (dgawin_buf)->pDraw = dgadraw; \ (dgawin_buf)->buf_size = bufsize; \ ret_buf = dgawin_buf; #define STORE_BUFFERS(buf_addr, filename, fn_addr0, allocsize) \ bufferp = (buf_addr)->bufferp; \ if ( bufferp) { \ if (resize_flag) \ UNMAP_BUFFER(bufferp, (buf_addr)->buf_size) \ if ( filename && fn_addr0) { \ if ( bufferp ) { \ buffers[count++] = (Dga_buffer *)buf_addr; \ bufferp->pDraw = dgadraw; \ } \ else {\ (buf_addr)->bufferp = bufferp = (void *) \ get_specified_buffer((char *)filename, allocsize); \ (buf_addr)->pDraw = dgadraw; \ if (bufferp) { \ buffers[count++] = (Dga_buffer *)buf_addr; \ bufferp->pDraw = dgadraw; \ (buf_addr)->buf_size = allocsize; \ } \ else { \ (buf_addr)->buf_size = 0; \ } \ }\ }\ } static dga_buffer get_specified_buffer(char *filename, int allocsize) { int filefd = -1; dga_buffer return_buf = NULL; if ( filename && filename[0] ) { if ((filefd = open(filename,O_RDWR,0666)) != -1 ) { return_buf = (dga_buffer)mmap(0, allocsize, PROT_READ|PROT_WRITE, MAP_SHARED, filefd, (off_t)0); close (filefd); /* May need to keep trap of fds... */ if ( return_buf == (dga_buffer) -1) return ( (dga_buffer)NULL ); /* mmap failed. */ /* Set the data filed properly */ assert(sizeof(dga_buffer_rec) & 0x7 == 0); return_buf->data = (char *)(return_buf + 1); } } return return_buf; } static void remap_buffers(Dga_drawable dgadraw) { int filefd = -1; char *filename; int count = 0; dga_buffer bufferp = NULL; static void *buffers[DGA_NUM_BUFFER_TYPES]; _Dga_window dgawin = (_Dga_window)dgadraw; WXINFO *infop = wx_infop(dgawin); int resize_flag = True; if ( dgawin->buf_resize_flag >= infop->wx_abuf.s_modified ) return; STORE_BUFFERS((dga_internal_buffer)dgawin->back, infop->wx_abuf.back_fn, infop->wx_abuf.back_fn[0], infop->wx_abuf.back_size); STORE_BUFFERS((dga_internal_buffer)dgawin->depth, infop->wx_abuf.depth_fn, infop->wx_abuf.depth_fn[0], infop->wx_abuf.depth_size); STORE_BUFFERS((dga_internal_buffer)dgawin->stencil, infop->wx_abuf.stencil_fn, infop->wx_abuf.stencil_fn[0], infop->wx_abuf.stencil_size); STORE_BUFFERS((dga_internal_buffer)dgawin->accum, infop->wx_abuf.accum_fn, infop->wx_abuf.accum_fn[0], infop->wx_abuf.accum_size); STORE_BUFFERS((dga_internal_buffer)dgawin->alpha, infop->wx_abuf.alpha_fn, infop->wx_abuf.alpha_fn[0], infop->wx_abuf.alpha_size); dgawin->buf_resize_flag = infop->wx_abuf.s_modified; return; } /* * Name : dga_draw_grab_buffer * Synopsis: This function requests the window system to provide * ancillary buffer service for the grabbed drawable name in the * dgadraw argument. The call requests the type of the buffer * specified to be grabbed to the client. If buffer_site is * DGA_SITE_SYSTEM, server allocates the buffer in the shared * memory. If it is DGA_SITE_DEVICE, the server tries to grab * hardware buffers. If the device does not support the given * buffer type in hardware, the request fails. * The drawable must have been grabbed previously via XDgaGrabDrawable. * * Implementation: If buffer_stie is DGA_SITE_SYSTEM, this function * increments the grab_cnt if the buffer is already grabbed by other clients. * If this client has grabbed the specified buffer already, this function * returns the grabbed buffer pointer. * Otherwise, it sends a request to the server to grab a buffer. * If the request is successful, this function returns the buffer * address. * A special case where if the grab_cnt is "0", this function still sends * a request to the server to grab the buffer because there is a chance * that the visual capabilities of the window might have been changed. */ Dga_buffer dga_draw_grab_buffer(Dga_drawable dgadraw, Dga_buffer_type type, int buffer_site) { _Dga_window dgawin = (struct dga_window *)dgadraw; Dga_window clientpi = (Dga_window)dgawin; _Dga_window clientp = (struct dga_window *)clientpi; WXINFO *infop; Display *dpy; Window win; int depth = 0; dga_buffer bufferp = NULL; dga_internal_buffer ret_buf = NULL; dga_internal_buffer c_bufferp = NULL; /* Ancillary Buffers are not supported for drawable_type * DGA_DRAW_PIXMAP */ if ( ((_Dga_drawable)dgadraw)->drawable_type != DGA_DRAW_WINDOW ) return (0); if (!DGA_LOCKSUBJ_WINDOW(dgawin, dgawin->eLockSubj)) return (0); if ((clientp == (_Dga_window) NULL)) { #ifdef DEBUG (void) fprintf(stderr, "dga_draw_grab_buffer: passed null pointer\n"); #endif return (0); } /* * Find out if this is an X window. If so get the Display and window * id. */ if (!_dga_is_X_window(clientp->w_token, &dpy, &win)) { #ifdef DEBUG (void) fprintf(stderr, "dga_draw_grab_buffer: Unsupported window type\n"); #endif return (0); } infop = wx_infop(dgawin) ; if ( dgawin->buf_resize_flag < infop->wx_abuf.s_modified ) remap_buffers(dgadraw); switch ( type ) { case DGA_BACK_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->back; if ( c_bufferp->bufferp ) return dgawin->back; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.back_fn, infop->wx_abuf.back_size); break; case DGA_DEPTH_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->depth; if ( c_bufferp->bufferp ) return dgawin->depth; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.depth_fn, infop->wx_abuf.depth_size); break; case DGA_STENCIL_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->stencil; if ( c_bufferp->bufferp ) return dgawin->stencil; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.stencil_fn, infop->wx_abuf.stencil_size); break; case DGA_ACCUM_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->accum; if ( c_bufferp->bufferp ) return dgawin->accum; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.accum_fn, infop->wx_abuf.accum_size); break; case DGA_ALPHA_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->alpha; if ( c_bufferp->bufferp ) return dgawin->alpha; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.alpha_fn, infop->wx_abuf.alpha_size); break; default: return (0); } /* If grab_cnt is "0", then the reinitialization should go thru' * server. We can not just increment the grab_cnt. * There is a chance that the buffers capabilities might have * been changed in which case the server gets the bitsPerPixel * from SunExtVis info struct and reallocates the buffer. * If buffer_site is not DGA_SITE_SYSTEM, then it might be * a Hardware Buffers. */ if ( bufferp && (bufferp->buffer_site == DGA_SITE_SYSTEM) && bufferp->grab_cnt > 0 ) { bufferp->grab_cnt++; return (Dga_buffer ) ret_buf; } /* * Request the server to allow DGA to the buffers associated * with this Dga_window. */ if (!XDgaGrabABuffers(dpy, win, type, buffer_site)) { #ifdef DEBUG (void)fprintf(stderr, "dga_draw_grab_buffer: XDgaGrabABuffers failed\n"); #endif return (0); } /* infop will contain the proper pointer to the selected buffer since * it is in the dga shared page. */ infop = wx_infop(dgawin) ; /* get_specified_buffer: This function checks on the filenames * where if it is software buffer this member should have a * valid file name. * If it is NULL, then it may be a hardware buffer and just * return from this point where the hardware buffer would have * been allocated already. */ switch ( type ) { case DGA_BACK_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->back; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.back_fn, infop->wx_abuf.back_size); break; case DGA_DEPTH_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->depth; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.depth_fn, infop->wx_abuf.depth_size); break; case DGA_STENCIL_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->stencil; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.stencil_fn, infop->wx_abuf.stencil_size); break; case DGA_ACCUM_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->accum; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.accum_fn, infop->wx_abuf.accum_size); break; case DGA_ALPHA_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->alpha; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.alpha_fn, infop->wx_abuf.alpha_size); break; } if ( bufferp ) { bufferp->pDraw = ret_buf->pDraw = dgadraw; return (Dga_buffer) ret_buf; } else { if (buffer_site == DGA_SITE_DEVICE) return (Dga_buffer) c_bufferp; } return NULL; } /* * Name : dga_draw_ungrab_buffer * Synopsis: This function ungrabs the buffer for the specified drawable * which has been grabbed previously. Note that ungrabbing a buffer does * not necessarily cause it to be freed. If any of these steps fail, * zero is returned. True is returned upon success. * * Implementation: If the buffer is grabbed already, this function * decrements the grab_cnt. If grab_cnt is negative, it will be * reset to "0". * If this client hasn't grabbed the buffer already, this function returns 0. * This function will send a request to the server to ungrab the * buffer only if buffer grabbed is in DGA_SITE_DEVICE ( Hardware ). */ int dga_draw_ungrab_buffer(Dga_drawable dgadraw, Dga_buffer_type type) { _Dga_window dgawin = (_Dga_window)dgadraw; WXINFO *infop; Display *dpy; Window win; dga_buffer bufferp = NULL; dga_internal_buffer ret_buf = NULL; dga_internal_buffer c_bufferp = NULL; /* Ancillary Buffers are not supported for drawable_type * DGA_DRAW_PIXMAP */ if ( ((_Dga_drawable)dgadraw)->drawable_type != DGA_DRAW_WINDOW ) return (0); if (!DGA_LOCKSUBJ_WINDOW(dgawin, dgawin->eLockSubj)) return (0); if ((dgawin == (_Dga_window) NULL)) { #ifdef DEBUG (void) fprintf(stderr, "dga_draw_ungrab_buffer: passed null pointer\n"); #endif return (0); } /* * Find out if this is an X window. If so get the Display and window * id. */ if (!_dga_is_X_window(dgawin->w_token, &dpy, &win)) { #ifdef DEBUG (void) fprintf(stderr, "dga_draw_ungrab_buffer: Unsupported window type\n"); #endif return (0); } infop = wx_infop(dgawin) ; switch ( type ) { case DGA_BACK_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->back; if ( c_bufferp->bufferp ) return 0; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.back_fn, infop->wx_abuf.back_size); break; case DGA_DEPTH_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->depth; if ( c_bufferp->bufferp ) return 0; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.depth_fn, infop->wx_abuf.depth_size); break; case DGA_STENCIL_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->stencil; if ( c_bufferp->bufferp ) return 0; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.stencil_fn, infop->wx_abuf.stencil_size); break; case DGA_ACCUM_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->accum; if ( c_bufferp->bufferp ) return 0; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.accum_fn, infop->wx_abuf.accum_size); break; case DGA_ALPHA_BUFFER: c_bufferp = (dga_internal_buffer)dgawin->alpha; if ( c_bufferp->bufferp ) return 0; GET_SW_HW_BUFFER(c_bufferp, infop->wx_abuf.alpha_fn, infop->wx_abuf.alpha_size); break; default: return (0); } /* end of switch ( type ).. */ /* Currently Just decrement the grab_cnt and if there is no grab * don't free it. Next time when it is getting grabbed, we will * increment the count * If the when the grab_cnt is "0" and the dga_drawable is getting * resized then the buffers are thrown away. */ if ( !bufferp ) return (0); if ( bufferp->buffer_site == DGA_SITE_SYSTEM ) { bufferp->grab_cnt--; if ( bufferp->grab_cnt < 0 ) bufferp->grab_cnt = 0; switch ( type ) { case DGA_BACK_BUFFER: ((dga_internal_buffer)dgawin->back)->bufferp = NULL; break; case DGA_DEPTH_BUFFER: ((dga_internal_buffer)dgawin->depth)->bufferp = NULL; break; case DGA_STENCIL_BUFFER: ((dga_internal_buffer)dgawin->stencil)->bufferp = NULL; break; case DGA_ACCUM_BUFFER: ((dga_internal_buffer)dgawin->accum)->bufferp = NULL; break; case DGA_ALPHA_BUFFER: ((dga_internal_buffer)dgawin->alpha)->bufferp = NULL; break; default: return (0); } /* end of switch */ } else { /* Buffer site is DGA_SITE_DEVICE */ if (!XDgaUnGrabABuffers(dpy, win, type)) { #ifdef DEBUG (void) fprintf(stderr, "dga_draw_ungrab_buffer: XDgaUnGrabABuffers failed\n"); #endif return (0); } } /* end of ( ret_buf->buffer_site == DGA_SITE_SYSTEM ).. */ return 1; } /* * Name : dga_draw_get_buffers * Synopsis: This function returns the number of ancillary buffers * associated with the specified dgadraw and an arry of buffer * pointers. Note that only buffers which have been grabbed by * the client are returned. Buffers which might exist (because of * grabs by other clients or the server) are not returned. */ int dga_draw_get_buffers(Dga_drawable dgadraw, Dga_buffer **pBufs ) { char *filename; int count = 0; dga_buffer bufferp = NULL; static void *buffers[DGA_NUM_BUFFER_TYPES]; _Dga_window dgawin = (_Dga_window)dgadraw; WXINFO *infop = wx_infop(dgawin); int resize_flag = False; if ( dgawin->buf_resize_flag < infop->wx_abuf.s_modified ) resize_flag = True; STORE_BUFFERS((dga_internal_buffer)dgawin->back, infop->wx_abuf.back_fn, infop->wx_abuf.back_fn[0], infop->wx_abuf.back_size); STORE_BUFFERS((dga_internal_buffer)dgawin->depth, infop->wx_abuf.depth_fn, infop->wx_abuf.depth_fn[0], infop->wx_abuf.depth_size); STORE_BUFFERS((dga_internal_buffer)dgawin->stencil, infop->wx_abuf.stencil_fn, infop->wx_abuf.stencil_fn[0], infop->wx_abuf.stencil_size); STORE_BUFFERS((dga_internal_buffer)dgawin->accum, infop->wx_abuf.accum_fn, infop->wx_abuf.accum_fn[0], infop->wx_abuf.accum_size); STORE_BUFFERS((dga_internal_buffer)dgawin->alpha, infop->wx_abuf.alpha_fn, infop->wx_abuf.alpha_fn[0], infop->wx_abuf.alpha_size); if ( resize_flag ) dgawin->buf_resize_flag = infop->wx_abuf.s_modified; *pBufs = buffers; return count; } /* * Name : dga_buffer_type * Synopsis: This function returns the type of the buffer specified. */ Dga_buffer_type dga_buffer_type(Dga_buffer bufferp) { _Dga_window dgawin; WXINFO *infop; dga_buffer local_buf; if ( !bufferp || !(local_buf = ((dga_internal_buffer)bufferp)->bufferp)) return -1; dgawin = (_Dga_window)((dga_internal_buffer)bufferp)->pDraw; infop = wx_infop(dgawin); if ( dgawin->buf_resize_flag < infop->wx_abuf.s_modified ) { remap_buffers((Dga_drawable)((dga_internal_buffer)bufferp)->pDraw); local_buf = ((dga_internal_buffer)bufferp)->bufferp; } return local_buf->buffer_type; } #if 0 /* We had this function for completeness. */ /* * Name : dga_buffer_get_drawable * Synopsis: This function returns the Dga_drawable associated with the * buffer specified. */ Dga_drawable dga_buffer_get_drawable(Dga_buffer bufferp ) { if ( !bufferp ) return NULL; return ((dga_buffer)bufferp)->pDraw; } #endif /* * Name : dga_buffer_site (Lock Only) * Synopsis: This function returns the site of the buffer specified. * The values are the same as those returned by dga_draw_site(). * DGA_SITE_SYSTEM, DGA_SITE_DEVICE and DGA_SITE_NULL. */ int dga_buffer_site(Dga_buffer bufferp) { _Dga_window dgawin; WXINFO *infop; dga_buffer local_buf; if ( !bufferp || !(local_buf = ((dga_internal_buffer)bufferp)->bufferp)) return DGA_SITE_NULL; dgawin = (_Dga_window)((dga_internal_buffer)bufferp)->pDraw; infop = wx_infop(dgawin); if ( dgawin->buf_resize_flag < infop->wx_abuf.s_modified ) { remap_buffers((Dga_drawable)((dga_internal_buffer)bufferp)->pDraw); local_buf = ((dga_internal_buffer)bufferp)->bufferp; } return local_buf->buffer_site; } /* * Name : dga_draw_bufferchg * Synopsis: This function returns True if any of the buffers * associated with the dgadraw have undergone a state change * since the last lock. When dga_draw_bufferchg returns True, * the client should call dga_buffer_sitechg for each of the * Drawable's buffers. */ int dga_draw_bufferchg(Dga_drawable dgadraw) { _Dga_window dgawin = (_Dga_window)dgadraw; WXINFO *infop = wx_infop(dgawin); if (infop && (infop->wx_abuf.s_modified)) return True; return False; } /* * Name : dga_buffer_sitechg * Synopsis: This function returns True if the buffer has sitechg * flag set. Note that this function always returns False for * device buffers. Only memory buffers ever have a site chagne. * dga_buffer_sitechg() also returns the reason for site change. * Currenly the only possible values for reason are DGA_SITECHG_INITIAL, * which is reported the first time a Drawable is locaked after a buffer * has been created and DGA_SITECHG_CACHE which indicates that the * buffer has been resized since the time that the Dga_drawable was last * locked. */ int dga_buffer_sitechg(Dga_buffer bufferp, int *reason) { _Dga_window dgawin; WXINFO *infop; dga_buffer local_buf; if ( !bufferp || !(local_buf = ((dga_internal_buffer)bufferp)->bufferp)) return False; /* Returning False may mislead the developer */ dgawin = (_Dga_window)((dga_internal_buffer)bufferp)->pDraw; infop = wx_infop(dgawin); if ( dgawin->buf_resize_flag < infop->wx_abuf.s_modified ) { remap_buffers((Dga_drawable)((dga_internal_buffer)bufferp)->pDraw); local_buf = ((dga_internal_buffer)bufferp)->bufferp; } if (local_buf->buffer_site != DGA_SITE_SYSTEM) return False; if (local_buf->sitechg) { *reason = local_buf->sitechg; local_buf->sitechg = DGA_SITECHG_UNKNOWN; return True; } else return False; } /* * Name : dga_buffer_address (Lock Only) * Synopsis: This function returns the data pointer from the shared * buffer page of the buffer specified. An address will be returned * only for buffers which are located in system memory. * If dga_buffer_address is called on a buffer located with * DGA_SITE_DEVICE, NULL will be returned. The value returned * remains valid across locks until a sitechg is reported as * described above. */ void * dga_buffer_address(Dga_buffer bufferp) { _Dga_window dgawin; WXINFO *infop; dga_buffer local_buf; if ( !bufferp || !(local_buf = ((dga_internal_buffer)bufferp)->bufferp)) return NULL; dgawin = (_Dga_window)((dga_internal_buffer)bufferp)->pDraw; infop = wx_infop(dgawin); if ( dgawin->buf_resize_flag < infop->wx_abuf.s_modified ) { remap_buffers((Dga_drawable)((dga_internal_buffer)bufferp)->pDraw); local_buf = ((dga_internal_buffer)bufferp)->bufferp; } if (local_buf->buffer_site == DGA_SITE_SYSTEM) { local_buf->data = (char *)(local_buf + 1); return local_buf->data; } else return NULL; } /* * Name : dga_buffer_linebytes * Synopsis: This function returns the number of bytes per scanline * of the buffer specified. Only buffers which are located in * system memory are addressable. If dga_buffer_linebytes is called * for a buffer located on the device, "0" is returned. */ int dga_buffer_linebytes(Dga_buffer bufferp) { _Dga_window dgawin; WXINFO *infop; dga_buffer local_buf; if ( !bufferp || !(local_buf = ((dga_internal_buffer)bufferp)->bufferp)) return 0; dgawin = (_Dga_window)((dga_internal_buffer)bufferp)->pDraw; infop = wx_infop(dgawin); if ( dgawin->buf_resize_flag < infop->wx_abuf.s_modified ) { remap_buffers((Dga_drawable)((dga_internal_buffer)bufferp)->pDraw); local_buf = ((dga_internal_buffer)bufferp)->bufferp; } if (local_buf->buffer_site == DGA_SITE_SYSTEM) return local_buf->linebytes; else return 0; } /* * Name : dga_buffer_bitsperpixel * Synopsis: This function returns bitsperpixel of the buffer * specified if the buffer is located in system memory. If the * buffer is located on the device, zero is returned. Note that * the value might be different than the number of significant bits. * For example, an unpacked 4 bit stencil buffer would return * 8 bits per pixel, and a 24 bit Z buffer would return * 32 bits per pixel. */ int dga_buffer_bitsperpixel(Dga_buffer bufferp) { _Dga_window dgawin; WXINFO *infop; dga_buffer local_buf; if ( !bufferp || !(local_buf = ((dga_internal_buffer)bufferp)->bufferp)) return 0; dgawin = (_Dga_window)((dga_internal_buffer)bufferp)->pDraw; infop = wx_infop(dgawin); if ( dgawin->buf_resize_flag < infop->wx_abuf.s_modified ) { remap_buffers((Dga_drawable)((dga_internal_buffer)bufferp)->pDraw); local_buf = ((dga_internal_buffer)bufferp)->bufferp; } if (local_buf->buffer_site == DGA_SITE_SYSTEM) return local_buf->bitsPerPixel; else return 0; } void dga_draw_buffer_swap(Dga_drawable dgadraw, int (*visfunc)(Dga_window)) { _Dga_window dgawin = (_Dga_window)dgadraw; WXINFO *infop = wx_infop(dgawin); if (visfunc) (*visfunc)(dgawin); if ( infop && infop->wx_abuf.back_fn && infop->wx_abuf.back_fn[0] && infop->wx_abuf.back ) { infop->wx_abuf.buffer_swap++; dgawin->c_buffer_swap = infop->wx_abuf.buffer_swap; } return; } int dga_draw_swap_check(Dga_drawable dgadraw) { _Dga_window dgawin = (_Dga_window)dgadraw; WXINFO *infop = wx_infop(dgawin); if ( infop && infop->wx_abuf.back_fn && infop->wx_abuf.back_fn[0] && infop->wx_abuf.back && ( dgawin->c_buffer_swap != infop->wx_abuf.buffer_swap)) { dgawin->c_buffer_swap = infop->wx_abuf.buffer_swap; return 1; } return 0; }