⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xm_api.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Find an XMesaBuffer by matching X display and colormap but NOT matching * the notThis buffer. */static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,                                     XMesaColormap cmap,                                     XMesaBuffer notThis){   XMesaBuffer b;   for (b=XMesaBufferList; b; b=b->Next) {      if (b->display==dpy && b->cmap==cmap && b!=notThis) {         return b;      }   }   return NULL;}/* * Free an XMesaBuffer, remove from linked list, perhaps free X colormap * entries. */static void free_xmesa_buffer(int client, XMesaBuffer buffer){   XMesaBuffer prev = NULL, b;   (void) client;   for (b=XMesaBufferList; b; b=b->Next) {      if (b==buffer) {         /* unlink bufer from list */         if (prev)            prev->Next = buffer->Next;         else            XMesaBufferList = buffer->Next;         /* Check to free X colors */         if (buffer->num_alloced>0) {            /* If no other buffer uses this X colormap then free the colors. */            if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) {#ifdef XFree86Server               (void)FreeColors(buffer->cmap, client,				buffer->num_alloced, buffer->alloced_colors,				0);#else               XFreeColors(buffer->display, buffer->cmap,                           buffer->alloced_colors, buffer->num_alloced, 0);#endif            }         }         _mesa_free_framebuffer_data(&buffer->mesa_buffer);         _mesa_free(buffer);         return;      }      /* continue search */      prev = b;   }   /* buffer not found in XMesaBufferList */   _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n");}/* Copy X color table stuff from one XMesaBuffer to another. */static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src){   MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));   MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));   MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g));   MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b));   dst->num_alloced = src->num_alloced;   MEMCPY(dst->alloced_colors, src->alloced_colors,          sizeof(src->alloced_colors));}/**********************************************************************//*****                   Misc Private Functions                   *****//**********************************************************************//** * Allocate a shared memory XImage back buffer for the given XMesaBuffer. * Return:  GL_TRUE if success, GL_FALSE if error */#ifndef XFree86Serverstatic GLbooleanalloc_shm_back_buffer(XMesaBuffer b, GLuint width, GLuint height){#ifdef USE_XSHM   /*    * We have to do a _lot_ of error checking here to be sure we can    * really use the XSHM extension.  It seems different servers trigger    * errors at different points if the extension won't work.  Therefore    * we have to be very careful...    */   GC gc;   int (*old_handler)( XMesaDisplay *, XErrorEvent * );   if (width == 0 || height == 0) {      /* this will be true the first time we're called on 'b' */      return GL_FALSE;   }   b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,                                        b->xm_visual->visinfo->visual,                                        b->xm_visual->visinfo->depth,                                        ZPixmap, NULL, &b->shminfo,                                        width, height);   if (b->backxrb->ximage == NULL) {      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");      b->shm = 0;      return GL_FALSE;   }   b->shminfo.shmid = shmget( IPC_PRIVATE, b->backxrb->ximage->bytes_per_line			     * b->backxrb->ximage->height, IPC_CREAT|0777 );   if (b->shminfo.shmid < 0) {      _mesa_warning(NULL, "shmget failed while allocating back buffer.\n");      XDestroyImage( b->backxrb->ximage );      b->backxrb->ximage = NULL;      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");      b->shm = 0;      return GL_FALSE;   }   b->shminfo.shmaddr = b->backxrb->ximage->data                      = (char*)shmat( b->shminfo.shmid, 0, 0 );   if (b->shminfo.shmaddr == (char *) -1) {      _mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");      XDestroyImage( b->backxrb->ximage );      shmctl( b->shminfo.shmid, IPC_RMID, 0 );      b->backxrb->ximage = NULL;      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");      b->shm = 0;      return GL_FALSE;   }   b->shminfo.readOnly = False;   mesaXErrorFlag = 0;   old_handler = XSetErrorHandler( mesaHandleXError );   /* This may trigger the X protocol error we're ready to catch: */   XShmAttach( b->xm_visual->display, &b->shminfo );   XSync( b->xm_visual->display, False );   if (mesaXErrorFlag) {      /* we are on a remote display, this error is normal, don't print it */      XFlush( b->xm_visual->display );      mesaXErrorFlag = 0;      XDestroyImage( b->backxrb->ximage );      shmdt( b->shminfo.shmaddr );      shmctl( b->shminfo.shmid, IPC_RMID, 0 );      b->backxrb->ximage = NULL;      b->shm = 0;      (void) XSetErrorHandler( old_handler );      return GL_FALSE;   }   shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */   /* Finally, try an XShmPutImage to be really sure the extension works */   gc = XCreateGC( b->xm_visual->display, b->frontxrb->drawable, 0, NULL );   XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, gc,		 b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False );   XSync( b->xm_visual->display, False );   XFreeGC( b->xm_visual->display, gc );   (void) XSetErrorHandler( old_handler );   if (mesaXErrorFlag) {      XFlush( b->xm_visual->display );      mesaXErrorFlag = 0;      XDestroyImage( b->backxrb->ximage );      shmdt( b->shminfo.shmaddr );      shmctl( b->shminfo.shmid, IPC_RMID, 0 );      b->backxrb->ximage = NULL;      b->shm = 0;      return GL_FALSE;   }   return GL_TRUE;#else   /* Can't compile XSHM support */   return GL_FALSE;#endif}#endif/* * Setup an off-screen pixmap or Ximage to use as the back buffer. * Input:  b - the X/Mesa buffer */voidxmesa_alloc_back_buffer( XMesaBuffer b, GLuint width, GLuint height ){   if (width == 0 || height == 0)      return;   if (b->db_mode == BACK_XIMAGE) {      /* Deallocate the old backxrb->ximage, if any */      if (b->backxrb->ximage) {#if defined(USE_XSHM) && !defined(XFree86Server)	 if (b->shm) {	    XShmDetach( b->xm_visual->display, &b->shminfo );	    XDestroyImage( b->backxrb->ximage );	    shmdt( b->shminfo.shmaddr );	 }	 else#endif	   XMesaDestroyImage( b->backxrb->ximage );	 b->backxrb->ximage = NULL;      }      /* Allocate new back buffer */#ifdef XFree86Server      /* Allocate a regular XImage for the back buffer. */      b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,                                            width, height, NULL);      {#else      if (b->shm == 0 || !alloc_shm_back_buffer(b, width, height)) {	 /* Allocate a regular XImage for the back buffer. */	 b->backxrb->ximage = XCreateImage( b->xm_visual->display,                                      b->xm_visual->visinfo->visual,                                      GET_VISUAL_DEPTH(b->xm_visual),				      ZPixmap, 0,   /* format, offset */				      NULL,                                      width, height,				      8, 0 );  /* pad, bytes_per_line */#endif	 if (!b->backxrb->ximage) {	    _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");            return;	 }         b->backxrb->ximage->data = (char *) MALLOC( b->backxrb->ximage->height                                        * b->backxrb->ximage->bytes_per_line );         if (!b->backxrb->ximage->data) {            _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n");            XMesaDestroyImage( b->backxrb->ximage );            b->backxrb->ximage = NULL;         }         else {            /* this call just updates the width/origin fields in the xrb */            b->backxrb->Base.AllocStorage(NULL, &b->backxrb->Base,                                           b->backxrb->Base.InternalFormat,                                          b->backxrb->ximage->width,                                          b->backxrb->ximage->height);         }      }      b->backxrb->pixmap = None;   }   else if (b->db_mode == BACK_PIXMAP) {      if (!width)         width = 1;      if (!height)         height = 1;      /* Free the old back pixmap */      if (b->backxrb->pixmap) {	 XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap );      }      /* Allocate new back pixmap */      b->backxrb->pixmap = XMesaCreatePixmap( b->xm_visual->display,                                              b->frontxrb->drawable,                                              width, height,                                              GET_VISUAL_DEPTH(b->xm_visual) );      b->backxrb->ximage = NULL;   }}/* * A replacement for XAllocColor.  This function should never * fail to allocate a color.  When XAllocColor fails, we return * the nearest matching color.  If we have to allocate many colors * this function isn't too efficient; the XQueryColors() could be * done just once. * Written by Michael Pichler, Brian Paul, Mark Kilgard * Input:  dpy - X display *         cmap - X colormap *         cmapSize - size of colormap * In/Out: color - the XColor struct * Output:  exact - 1=exact color match, 0=closest match *          alloced - 1=XAlloc worked, 0=XAlloc failed */static voidnoFaultXAllocColor( int client,                    XMesaDisplay *dpy,                    XMesaColormap cmap,                    int cmapSize,                    XMesaColor *color,                    int *exact, int *alloced ){#ifdef XFree86Server   Pixel *ppixIn;   xrgb *ctable;#else   /* we'll try to cache ctable for better remote display performance */   static Display *prevDisplay = NULL;   static XMesaColormap prevCmap = 0;   static int prevCmapSize = 0;   static XMesaColor *ctable = NULL;#endif   XMesaColor subColor;   int i, bestmatch;   double mindist;       /* 3*2^16^2 exceeds long int precision. */   (void) client;   /* First try just using XAllocColor. */#ifdef XFree86Server   if (AllocColor(cmap,		  &color->red, &color->green, &color->blue,		  &color->pixel,		  client) == Success) {#else   if (XAllocColor(dpy, cmap, color)) {#endif      *exact = 1;      *alloced = 1;      return;   }   /* Alloc failed, search for closest match */   /* Retrieve color table entries. */   /* XXX alloca candidate. */#ifdef XFree86Server   ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel));   ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb));   for (i = 0; i < cmapSize; i++) {      ppixIn[i] = i;   }   QueryColors(cmap, cmapSize, ppixIn, ctable);#else   if (prevDisplay != dpy || prevCmap != cmap       || prevCmapSize != cmapSize || !ctable) {      /* free previously cached color table */      if (ctable)         _mesa_free(ctable);      /* Get the color table from X */      ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor));      assert(ctable);      for (i = 0; i < cmapSize; i++) {         ctable[i].pixel = i;      }      XQueryColors(dpy, cmap, ctable, cmapSize);      prevDisplay = dpy;      prevCmap = cmap;      prevCmapSize = cmapSize;   }#endif   /* Find best match. */   bestmatch = -1;   mindist = 0.0;   for (i = 0; i < cmapSize; i++) {      double dr = 0.30 * ((double) color->red - (double) ctable[i].red);      double dg = 0.59 * ((double) color->green - (double) ctable[i].green);      double db = 0.11 * ((double) color->blue - (double) ctable[i].blue);      double dist = dr * dr + dg * dg + db * db;      if (bestmatch < 0 || dist < mindist) {         bestmatch = i;         mindist = dist;      }   }   /* Return result. */   subColor.red   = ctable[bestmatch].red;   subColor.green = ctable[bestmatch].green;   subColor.blue  = ctable[bestmatch].blue;   /* Try to allocate the closest match color.  This should only    * fail if the cell is read/write.  Otherwise, we're incrementing    * the cell's reference count.    */#ifdef XFree86Server   if (AllocColor(cmap,		  &subColor.red, &subColor.green, &subColor.blue,		  &subColor.pixel,		  client) == Success) {#else   if (XAllocColor(dpy, cmap, &subColor)) {#endif      *alloced = 1;   }   else {      /* do this to work around a problem reported by Frank Ortega */      subColor.pixel = (unsigned long) bestmatch;      subColor.red   = ctable[bestmatch].red;      subColor.green = ctable[bestmatch].green;      subColor.blue  = ctable[bestmatch].blue;      subColor.flags = DoRed | DoGreen | DoBlue;      *alloced = 0;   }#ifdef XFree86Server   _mesa_free(ppixIn);   _mesa_free(ctable);#else   /* don't free table, save it for next time */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -