Home | History | Annotate | Download | only in glx
      1 /*
      2  * (C) Copyright IBM Corporation 2004
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * on the rights to use, copy, modify, merge, publish, distribute, sub
      9  * license, and/or sell copies of the Software, and to permit persons to whom
     10  * the Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
     19  * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 /**
     26  * \file glx_query.c
     27  * Generic utility functions to query internal data from the server.
     28  *
     29  * \author Ian Romanick <idr (at) us.ibm.com>
     30  */
     31 
     32 #include "glxclient.h"
     33 
     34 #if defined(USE_XCB)
     35 # include <X11/Xlib-xcb.h>
     36 # include <xcb/xcb.h>
     37 # include <xcb/glx.h>
     38 #endif
     39 
     40 #ifdef USE_XCB
     41 
     42 /**
     43  * Exchange a protocol request for glXQueryServerString.
     44  */
     45 char *
     46 __glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
     47 {
     48    xcb_connection_t *c = XGetXCBConnection(dpy);
     49    xcb_glx_query_server_string_reply_t *reply =
     50       xcb_glx_query_server_string_reply(c,
     51                                         xcb_glx_query_server_string(c,
     52                                                                     screen,
     53                                                                     name),
     54                                         NULL);
     55 
     56    /* The spec doesn't mention this, but the Xorg server replies with
     57     * a string already terminated with '\0'. */
     58    uint32_t len = xcb_glx_query_server_string_string_length(reply);
     59    char *buf = Xmalloc(len);
     60    memcpy(buf, xcb_glx_query_server_string_string(reply), len);
     61    free(reply);
     62 
     63    return buf;
     64 }
     65 
     66 /**
     67  * Exchange a protocol request for glGetString.
     68  */
     69 char *
     70 __glXGetString(Display * dpy, int opcode, CARD32 contextTag, CARD32 name)
     71 {
     72    xcb_connection_t *c = XGetXCBConnection(dpy);
     73    xcb_glx_get_string_reply_t *reply = xcb_glx_get_string_reply(c,
     74                                                                 xcb_glx_get_string
     75                                                                 (c,
     76                                                                  contextTag,
     77                                                                  name),
     78                                                                 NULL);
     79 
     80    /* The spec doesn't mention this, but the Xorg server replies with
     81     * a string already terminated with '\0'. */
     82    uint32_t len = xcb_glx_get_string_string_length(reply);
     83    char *buf = Xmalloc(len);
     84    memcpy(buf, xcb_glx_get_string_string(reply), len);
     85    free(reply);
     86 
     87    return buf;
     88 }
     89 
     90 #else
     91 
     92 /**
     93  * GLX protocol structure for the ficticious "GXLGenericGetString" request.
     94  *
     95  * This is a non-existant protocol packet.  It just so happens that all of
     96  * the real protocol packets used to request a string from the server have
     97  * an identical binary layout.  The only difference between them is the
     98  * meaning of the \c for_whom field and the value of the \c glxCode.
     99  */
    100 typedef struct GLXGenericGetString
    101 {
    102    CARD8 reqType;
    103    CARD8 glxCode;
    104    CARD16 length B16;
    105    CARD32 for_whom B32;
    106    CARD32 name B32;
    107 } xGLXGenericGetStringReq;
    108 
    109 /* These defines are only needed to make the GetReq macro happy.
    110  */
    111 #define sz_xGLXGenericGetStringReq 12
    112 #define X_GLXGenericGetString 0
    113 
    114 /**
    115  * Query the Server GLX string.
    116  * This routine will allocate the necessay space for the string.
    117  */
    118 static char *
    119 __glXGetStringFromServer(Display * dpy, int opcode, CARD32 glxCode,
    120                          CARD32 for_whom, CARD32 name)
    121 {
    122    xGLXGenericGetStringReq *req;
    123    xGLXSingleReply reply;
    124    int length;
    125    int numbytes;
    126    char *buf;
    127 
    128 
    129    LockDisplay(dpy);
    130 
    131 
    132    /* All of the GLX protocol requests for getting a string from the server
    133     * look the same.  The exact meaning of the for_whom field is usually
    134     * either the screen number (for glXQueryServerString) or the context tag
    135     * (for GLXSingle).
    136     */
    137 
    138    GetReq(GLXGenericGetString, req);
    139    req->reqType = opcode;
    140    req->glxCode = glxCode;
    141    req->for_whom = for_whom;
    142    req->name = name;
    143 
    144    _XReply(dpy, (xReply *) & reply, 0, False);
    145 
    146    length = reply.length * 4;
    147    numbytes = reply.size;
    148 
    149    buf = (char *) Xmalloc(numbytes);
    150    if (buf != NULL) {
    151       _XRead(dpy, buf, numbytes);
    152       length -= numbytes;
    153    }
    154 
    155    _XEatData(dpy, length);
    156 
    157    UnlockDisplay(dpy);
    158    SyncHandle();
    159 
    160    return buf;
    161 }
    162 
    163 char *
    164 __glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
    165 {
    166    return __glXGetStringFromServer(dpy, opcode,
    167                                    X_GLXQueryServerString, screen, name);
    168 }
    169 
    170 char *
    171 __glXGetString(Display * dpy, int opcode, CARD32 contextTag, CARD32 name)
    172 {
    173    return __glXGetStringFromServer(dpy, opcode, X_GLsop_GetString,
    174                                    contextTag, name);
    175 }
    176 
    177 #endif /* USE_XCB */
    178