Пример #1
0
static GLboolean
CreateDRIDrawable(Display *dpy, struct glx_config *config,
		  XID drawable, XID glxdrawable,
		  const int *attrib_list, size_t num_attribs)
{
   struct glx_display *const priv = __glXInitialize(dpy);
   __GLXDRIdrawable *pdraw;
   struct glx_screen *psc;

   psc = priv->screens[config->screen];
   if (psc->driScreen == NULL)
      return GL_TRUE;

   pdraw = psc->driScreen->createDrawable(psc, drawable,
					  glxdrawable, config);
   if (pdraw == NULL) {
      fprintf(stderr, "failed to create drawable\n");
      return GL_FALSE;
   }

   if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) {
      (*pdraw->destroyDrawable) (pdraw);
      return GL_FALSE;
   }

   pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs);
   pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs);

   return GL_TRUE;
}
Пример #2
0
/**
 * Create a non-pbuffer GLX drawable.
 *
 * \todo
 * This function needs to be modified to work with direct-rendering drivers.
 */
static GLXDrawable
CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig,
               Drawable drawable, const int *attrib_list, CARD8 glxCode)
{
   xGLXCreateWindowReq *req;
   CARD32 *data;
   unsigned int i;
   CARD8 opcode;

   i = 0;
   if (attrib_list) {
      while (attrib_list[i * 2] != None)
         i++;
   }

   opcode = __glXSetupForCommand(dpy);
   if (!opcode)
      return None;

   LockDisplay(dpy);
   GetReqExtra(GLXCreateWindow, 8 * i, req);
   data = (CARD32 *) (req + 1);

   req->reqType = opcode;
   req->glxCode = glxCode;
   req->screen = (CARD32) fbconfig->screen;
   req->fbconfig = fbconfig->fbconfigID;
   req->window = (CARD32) drawable;
   req->glxwindow = (GLXWindow) XAllocID(dpy);
   req->numAttribs = (CARD32) i;

   if (attrib_list)
      memcpy(data, attrib_list, 8 * i);

   UnlockDisplay(dpy);
   SyncHandle();

#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
   do {
      /* FIXME: Maybe delay __DRIdrawable creation until the drawable
       * is actually bound to a context... */

      __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
      __GLXDRIdrawable *pdraw;
      __GLXscreenConfigs *psc;

      psc = &priv->screenConfigs[fbconfig->screen];
      if (psc->driScreen == NULL)
         break;
      pdraw = psc->driScreen->createDrawable(psc, drawable,
                                             req->glxwindow, fbconfig);
      if (pdraw == NULL) {
         fprintf(stderr, "failed to create drawable\n");
         break;
      }

      if (__glxHashInsert(psc->drawHash, req->glxwindow, pdraw)) {
         (*pdraw->destroyDrawable) (pdraw);
         return None;           /* FIXME: Check what we're supposed to do here... */
      }

      pdraw->textureTarget = determineTextureTarget(attrib_list, i);
      pdraw->textureFormat = determineTextureFormat(attrib_list, i);
   } while (0);
#endif

   return (GLXDrawable) req->glxwindow;
}
Пример #3
0
/**
 * Get a drawable's attribute.
 *
 * This function is used to implement \c glXGetSelectedEvent and
 * \c glXGetSelectedEventSGIX.
 *
 * \note
 * This function dynamically determines whether to use the SGIX_pbuffer
 * version of the protocol or the GLX 1.3 version of the protocol.
 *
 * \todo
 * The number of attributes returned is likely to be small, probably less than
 * 10.  Given that, this routine should try to use an array on the stack to
 * capture the reply rather than always calling Xmalloc.
 *
 * \todo
 * This function needs to be modified to work with direct-rendering drivers.
 */
static int
GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
                     int attribute, unsigned int *value)
{
   __GLXdisplayPrivate *priv;
   xGLXGetDrawableAttributesReply reply;
   CARD32 *data;
   CARD8 opcode;
   unsigned int length;
   unsigned int i;
   unsigned int num_attributes;
   GLboolean use_glx_1_3;

   if ((dpy == NULL) || (drawable == 0)) {
      return 0;
   }

   priv = __glXInitialize(dpy);
   use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3));

   *value = 0;


   opcode = __glXSetupForCommand(dpy);
   if (!opcode)
      return 0;

   LockDisplay(dpy);

   if (use_glx_1_3) {
      xGLXGetDrawableAttributesReq *req;

      GetReqExtra(GLXGetDrawableAttributes, 4, req);
      req->reqType = opcode;
      req->glxCode = X_GLXGetDrawableAttributes;
      req->drawable = drawable;
   }
   else {
      xGLXVendorPrivateWithReplyReq *vpreq;

      GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
      data = (CARD32 *) (vpreq + 1);
      data[0] = (CARD32) drawable;

      vpreq->reqType = opcode;
      vpreq->glxCode = X_GLXVendorPrivateWithReply;
      vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX;
   }

   _XReply(dpy, (xReply *) & reply, 0, False);

   if (reply.type == X_Error) {
      UnlockDisplay(dpy);
      SyncHandle();
      return 0;
   }

   length = reply.length;
   if (length) {
      num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2;
      data = (CARD32 *) Xmalloc(length * sizeof(CARD32));
      if (data == NULL) {
         /* Throw data on the floor */
         _XEatData(dpy, length);
      }
      else {
         _XRead(dpy, (char *) data, length * sizeof(CARD32));

         /* Search the set of returned attributes for the attribute requested by
          * the caller.
          */
         for (i = 0; i < num_attributes; i++) {
            if (data[i * 2] == attribute) {
               *value = data[(i * 2) + 1];
               break;
            }
         }

#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
         {
            __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);

            if (pdraw != NULL && !pdraw->textureTarget)
               pdraw->textureTarget =
                  determineTextureTarget((const int *) data, num_attributes);
            if (pdraw != NULL && !pdraw->textureFormat)
               pdraw->textureFormat =
                  determineTextureFormat((const int *) data, num_attributes);
         }
#endif

         Xfree(data);
      }
   }

   UnlockDisplay(dpy);
   SyncHandle();

   return 0;
}
/**
 * Get a drawable's attribute.
 *
 * This function is used to implement \c glXGetSelectedEvent and
 * \c glXGetSelectedEventSGIX.
 *
 * \note
 * This function dynamically determines whether to use the SGIX_pbuffer
 * version of the protocol or the GLX 1.3 version of the protocol.
 *
 * \todo
 * The number of attributes returned is likely to be small, probably less than
 * 10.  Given that, this routine should try to use an array on the stack to
 * capture the reply rather than always calling Xmalloc.
 */
static int
GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
                     int attribute, unsigned int *value)
{
   struct glx_display *priv;
   xGLXGetDrawableAttributesReply reply;
   CARD32 *data;
   CARD8 opcode;
   unsigned int length;
   unsigned int i;
   unsigned int num_attributes;
   GLboolean use_glx_1_3;

#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
   __GLXDRIdrawable *pdraw;
#endif

   if (dpy == NULL)
      return 0;

   /* Page 38 (page 52 of the PDF) of glxencode1.3.pdf says:
    *
    *     "If drawable is not a valid GLX drawable, a GLXBadDrawable error is
    *     generated."
    */
   if (drawable == 0) {
      __glXSendError(dpy, GLXBadDrawable, 0, X_GLXGetDrawableAttributes, false);
      return 0;
   }

   priv = __glXInitialize(dpy);
   if (priv == NULL)
      return 0;

   use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3));

   *value = 0;


   opcode = __glXSetupForCommand(dpy);
   if (!opcode)
      return 0;

#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
   pdraw = GetGLXDRIDrawable(dpy, drawable);

   if (attribute == GLX_BACK_BUFFER_AGE_EXT) {
      struct glx_context *gc = __glXGetCurrentContext();
      struct glx_screen *psc;

      /* The GLX_EXT_buffer_age spec says:
       *
       *   "If querying GLX_BACK_BUFFER_AGE_EXT and <draw> is not bound to
       *   the calling thread's current context a GLXBadDrawable error is
       *   generated."
       */
      if (pdraw == NULL || gc == &dummyContext || gc->currentDpy != dpy ||
         (gc->currentDrawable != drawable &&
         gc->currentReadable != drawable)) {
         __glXSendError(dpy, GLXBadDrawable, drawable,
                        X_GLXGetDrawableAttributes, false);
         return 0;
      }

      psc = pdraw->psc;

      if (psc->driScreen->getBufferAge != NULL)
         *value = psc->driScreen->getBufferAge(pdraw);

      return 0;
   }
#endif

   LockDisplay(dpy);

   if (use_glx_1_3) {
      xGLXGetDrawableAttributesReq *req;

      GetReq(GLXGetDrawableAttributes, req);
      req->reqType = opcode;
      req->glxCode = X_GLXGetDrawableAttributes;
      req->drawable = drawable;
   }
   else {
      xGLXVendorPrivateWithReplyReq *vpreq;

      GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
      data = (CARD32 *) (vpreq + 1);
      data[0] = (CARD32) drawable;

      vpreq->reqType = opcode;
      vpreq->glxCode = X_GLXVendorPrivateWithReply;
      vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX;
   }

   _XReply(dpy, (xReply *) & reply, 0, False);

   if (reply.type == X_Error) {
      UnlockDisplay(dpy);
      SyncHandle();
      return 0;
   }

   length = reply.length;
   if (length) {
      num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2;
      data = malloc(length * sizeof(CARD32));
      if (data == NULL) {
         /* Throw data on the floor */
         _XEatData(dpy, length);
      }
      else {
         _XRead(dpy, (char *) data, length * sizeof(CARD32));

         /* Search the set of returned attributes for the attribute requested by
          * the caller.
          */
         for (i = 0; i < num_attributes; i++) {
            if (data[i * 2] == attribute) {
               *value = data[(i * 2) + 1];
               break;
            }
         }

#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
         if (pdraw != NULL) {
            if (!pdraw->textureTarget)
               pdraw->textureTarget =
                  determineTextureTarget((const int *) data, num_attributes);
            if (!pdraw->textureFormat)
               pdraw->textureFormat =
                  determineTextureFormat((const int *) data, num_attributes);
         }
#endif

         free(data);
      }
   }

   UnlockDisplay(dpy);
   SyncHandle();

   return 0;
}