~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/GL/dri/dri_glx.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 
 
3
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 
4
All Rights Reserved.
 
5
 
 
6
Permission is hereby granted, free of charge, to any person obtaining a
 
7
copy of this software and associated documentation files (the
 
8
"Software"), to deal in the Software without restriction, including
 
9
without limitation the rights to use, copy, modify, merge, publish,
 
10
distribute, sub license, and/or sell copies of the Software, and to
 
11
permit persons to whom the Software is furnished to do so, subject to
 
12
the following conditions:
 
13
 
 
14
The above copyright notice and this permission notice (including the
 
15
next paragraph) shall be included in all copies or substantial portions
 
16
of the Software.
 
17
 
 
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
19
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
20
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 
21
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 
22
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 
23
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
24
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
25
 
 
26
**************************************************************************/
 
27
/* $XFree86: xc/lib/GL/dri/dri_glx.c,v 1.12 2003/02/06 12:42:10 alanh Exp $ */
 
28
 
 
29
/*
 
30
 * Authors:
 
31
 *   Kevin E. Martin <kevin@precisioninsight.com>
 
32
 *   Brian Paul <brian@precisioninsight.com>
 
33
 *
 
34
 */
 
35
 
 
36
#ifdef GLX_DIRECT_RENDERING
 
37
 
 
38
#include <unistd.h>
 
39
#include <X11/Xlibint.h>
 
40
#include <X11/extensions/Xext.h>
 
41
#include "extutil.h"
 
42
#include "glxclient.h"
 
43
#include "xf86dri.h"
 
44
#include "sarea.h"
 
45
#include <stdio.h>
 
46
#include <dlfcn.h>
 
47
#include "dri_glx.h"
 
48
#include <sys/types.h>
 
49
#include <stdarg.h>
 
50
 
 
51
 
 
52
typedef void *(*CreateScreenFunc)(Display *dpy, int scrn, __DRIscreen *psc,
 
53
                                  int numConfigs, __GLXvisualConfig *config);
 
54
 
 
55
typedef void *(*RegisterExtensionsFunc)(void);
 
56
 
 
57
 
 
58
#ifdef BUILT_IN_DRI_DRIVER
 
59
 
 
60
extern void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
 
61
                               int numConfigs, __GLXvisualConfig *config);
 
62
 
 
63
 
 
64
#else /* BUILT_IN_DRI_DRIVER */
 
65
 
 
66
 
 
67
#ifndef DEFAULT_DRIVER_DIR
 
68
/* this is normally defined in the Imakefile */
 
69
#define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri"
 
70
#endif
 
71
 
 
72
/*
 
73
 * We keep a linked list of these structures, one per DRI device driver.
 
74
 */
 
75
typedef struct __DRIdriverRec {
 
76
   const char *name;
 
77
   void *handle;
 
78
   CreateScreenFunc createScreenFunc;
 
79
   RegisterExtensionsFunc registerExtensionsFunc;
 
80
   struct __DRIdriverRec *next;
 
81
} __DRIdriver;
 
82
 
 
83
static __DRIdriver *Drivers = NULL;
 
84
 
 
85
 
 
86
/*
 
87
 * printf wrappers
 
88
 */
 
89
 
 
90
static void InfoMessageF(const char *f, ...)
 
91
{
 
92
    va_list args;
 
93
    const char *env;
 
94
 
 
95
    if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
 
96
        fprintf(stderr, "libGL: ");
 
97
        va_start(args, f);
 
98
        vfprintf(stderr, f, args);
 
99
        va_end(args);
 
100
    }
 
101
}
 
102
 
 
103
static void ErrorMessageF(const char *f, ...)
 
104
{
 
105
    va_list args;
 
106
 
 
107
    if (getenv("LIBGL_DEBUG")) {
 
108
        fprintf(stderr, "libGL error: ");
 
109
        va_start(args, f);
 
110
        vfprintf(stderr, f, args);
 
111
        va_end(args);
 
112
    }
 
113
}
 
114
 
 
115
 
 
116
/*
 
117
 * We'll save a pointer to this function when we couldn't find a
 
118
 * direct rendering driver for a given screen.
 
119
 */
 
120
static void *DummyCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
 
121
                               int numConfigs, __GLXvisualConfig *config)
 
122
{
 
123
    (void) dpy;
 
124
    (void) scrn;
 
125
    (void) psc;
 
126
    (void) numConfigs;
 
127
    (void) config;
 
128
    return NULL;
 
129
}
 
130
 
 
131
 
 
132
 
 
133
/*
 
134
 * Extract the ith directory path out of a colon-separated list of
 
135
 * paths.
 
136
 * Input:
 
137
 *   index - index of path to extract (starting at zero)
 
138
 *   paths - the colon-separated list of paths
 
139
 *   dirLen - max length of result to store in <dir>
 
140
 * Output:
 
141
 *   dir - the extracted directory path, dir[0] will be zero when
 
142
 *         extraction fails.
 
143
 */
 
144
static void ExtractDir(int index, const char *paths, int dirLen, char *dir)
 
145
{
 
146
   int i, len;
 
147
   const char *start, *end;
 
148
 
 
149
   /* find ith colon */
 
150
   start = paths;
 
151
   i = 0;
 
152
   while (i < index) {
 
153
      if (*start == ':') {
 
154
         i++;
 
155
         start++;
 
156
      }
 
157
      else if (*start == 0) {
 
158
         /* end of string and couldn't find ith colon */
 
159
         dir[0] = 0;
 
160
         return;
 
161
      }
 
162
      else {
 
163
         start++;
 
164
      }
 
165
   }
 
166
 
 
167
   while (*start == ':')
 
168
      start++;
 
169
 
 
170
   /* find next colon, or end of string */
 
171
   end = start + 1;
 
172
   while (*end != ':' && *end != 0) {
 
173
      end++;
 
174
   }
 
175
 
 
176
   /* copy string between <start> and <end> into result string */
 
177
   len = end - start;
 
178
   if (len > dirLen - 1)
 
179
      len = dirLen - 1;
 
180
   strncpy(dir, start, len);
 
181
   dir[len] = 0;
 
182
}
 
183
 
 
184
 
 
185
/*
 
186
 * Try to dlopen() the named driver.  This function adds the
 
187
 * "_dri.so" suffix to the driver name and searches the
 
188
 * directories specified by the LIBGL_DRIVERS_PATH env var
 
189
 * in order to find the driver.
 
190
 * Input:
 
191
 *   driverName - a name like "tdfx", "i810", "mga", etc.
 
192
 * Return:
 
193
 *   handle from dlopen, or NULL if driver file not found.
 
194
 */
 
195
static __DRIdriver *OpenDriver(const char *driverName)
 
196
{
 
197
   char *libPaths = NULL;
 
198
   int i;
 
199
   __DRIdriver *driver;
 
200
 
 
201
   /* First, search Drivers list to see if we've already opened this driver */
 
202
   for (driver = Drivers; driver; driver = driver->next) {
 
203
      if (strcmp(driver->name, driverName) == 0) {
 
204
         /* found it */
 
205
         return driver;
 
206
      }
 
207
   }
 
208
 
 
209
   if (geteuid() == getuid()) {
 
210
      /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
 
211
      libPaths = getenv("LIBGL_DRIVERS_PATH");
 
212
      if (!libPaths)
 
213
         libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
 
214
   }
 
215
   if (!libPaths)
 
216
      libPaths = DEFAULT_DRIVER_DIR;
 
217
 
 
218
   for (i = 0; ; i++) {
 
219
      char libDir[1000], realDriverName[200];
 
220
      void *handle;
 
221
      ExtractDir(i, libPaths, 1000, libDir);
 
222
      if (!libDir[0])
 
223
         break; /* ran out of paths to search */
 
224
      snprintf(realDriverName, 200, "%s/%s_dri.so", libDir, driverName);
 
225
      InfoMessageF("OpenDriver: trying %s\n", realDriverName);
 
226
      handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
 
227
      if (handle) {
 
228
         /* allocate __DRIdriver struct */
 
229
         driver = (__DRIdriver *) Xmalloc(sizeof(__DRIdriver));
 
230
         if (!driver)
 
231
            return NULL; /* out of memory! */
 
232
         /* init the struct */
 
233
         driver->name = __glXstrdup(driverName);
 
234
         if (!driver->name) {
 
235
            Xfree(driver);
 
236
            return NULL; /* out of memory! */
 
237
         }
 
238
         driver->createScreenFunc = (CreateScreenFunc)
 
239
            dlsym(handle, "__driCreateScreen");
 
240
         if (!driver->createScreenFunc) {
 
241
            /* If the driver doesn't have this symbol then something's
 
242
             * really, really wrong.
 
243
             */
 
244
            ErrorMessageF("__driCreateScreen() not defined in %s_dri.so!\n",
 
245
                          driverName);
 
246
            Xfree(driver);
 
247
            dlclose(handle);
 
248
            continue;
 
249
         }
 
250
         driver->registerExtensionsFunc = (RegisterExtensionsFunc)
 
251
            dlsym(handle, "__driRegisterExtensions");
 
252
         driver->handle = handle;
 
253
         /* put at head of linked list */
 
254
         driver->next = Drivers;
 
255
         Drivers = driver;
 
256
         return driver;
 
257
      }
 
258
      else {
 
259
         ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
 
260
      }
 
261
   }
 
262
 
 
263
   ErrorMessageF("unable to find driver: %s_dri.so\n", driverName);
 
264
   return NULL;
 
265
}
 
266
 
 
267
 
 
268
/*
 
269
 * Given a display pointer and screen number, determine the name of
 
270
 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
 
271
 * Return True for success, False for failure.
 
272
 */
 
273
static Bool GetDriverName(Display *dpy, int scrNum, char **driverName)
 
274
{
 
275
   int directCapable;
 
276
   Bool b;
 
277
   int driverMajor, driverMinor, driverPatch;
 
278
 
 
279
   *driverName = NULL;
 
280
 
 
281
   if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
 
282
      ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed");
 
283
      return False;
 
284
   }
 
285
   if (!directCapable) {
 
286
      ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false");
 
287
      return False;
 
288
   }
 
289
 
 
290
   b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
 
291
                                  &driverPatch, driverName);
 
292
   if (!b) {
 
293
      ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum);
 
294
      return False;
 
295
   }
 
296
 
 
297
   InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
 
298
             driverMajor, driverMinor, driverPatch, *driverName, scrNum);
 
299
 
 
300
   return True;
 
301
}
 
302
 
 
303
 
 
304
/*
 
305
 * Given a display pointer and screen number, return a __DRIdriver handle.
 
306
 * Return NULL if anything goes wrong.
 
307
 */
 
308
static __DRIdriver *GetDriver(Display *dpy, int scrNum)
 
309
{
 
310
   char *driverName;
 
311
   __DRIdriver *ret;
 
312
 
 
313
   if (GetDriverName(dpy, scrNum, &driverName)) {
 
314
      ret = OpenDriver(driverName);
 
315
      if (driverName)
 
316
         Xfree(driverName);
 
317
      return ret;
 
318
   }
 
319
 
 
320
   return NULL;
 
321
}
 
322
 
 
323
 
 
324
#endif /* BUILT_IN_DRI_DRIVER */
 
325
 
 
326
 
 
327
/* This function isn't currently used.
 
328
 */
 
329
static void driDestroyDisplay(Display *dpy, void *private)
 
330
{
 
331
    __DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private;
 
332
 
 
333
    if (pdpyp) {
 
334
        const int numScreens = ScreenCount(dpy);
 
335
        int i;
 
336
        for (i = 0; i < numScreens; i++) {
 
337
            if (pdpyp->libraryHandles[i])
 
338
                dlclose(pdpyp->libraryHandles[i]);
 
339
        }
 
340
        Xfree(pdpyp->libraryHandles);
 
341
        Xfree(pdpyp);
 
342
    }
 
343
}
 
344
 
 
345
 
 
346
/*
 
347
 * Allocate, initialize and return a __DRIdisplayPrivate object.
 
348
 * This is called from __glXInitialize() when we are given a new
 
349
 * display pointer.
 
350
 */
 
351
void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)
 
352
{
 
353
    const int numScreens = ScreenCount(dpy);
 
354
    __DRIdisplayPrivate *pdpyp;
 
355
    int eventBase, errorBase;
 
356
    int major, minor, patch;
 
357
    int scrn;
 
358
 
 
359
    /* Initialize these fields to NULL in case we fail.
 
360
     * If we don't do this we may later get segfaults trying to free random
 
361
     * addresses when the display is closed.
 
362
     */
 
363
    pdisp->private = NULL;
 
364
    pdisp->destroyDisplay = NULL;
 
365
    pdisp->createScreen = NULL;
 
366
 
 
367
    if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
 
368
        return NULL;
 
369
    }
 
370
 
 
371
    if (!XF86DRIQueryVersion(dpy, &major, &minor, &patch)) {
 
372
        return NULL;
 
373
    }
 
374
 
 
375
    pdpyp = (__DRIdisplayPrivate *)Xmalloc(sizeof(__DRIdisplayPrivate));
 
376
    if (!pdpyp) {
 
377
        return NULL;
 
378
    }
 
379
 
 
380
    pdpyp->driMajor = major;
 
381
    pdpyp->driMinor = minor;
 
382
    pdpyp->driPatch = patch;
 
383
 
 
384
    pdisp->destroyDisplay = driDestroyDisplay;
 
385
 
 
386
    /* allocate array of pointers to createScreen funcs */
 
387
    pdisp->createScreen = (CreateScreenFunc *) Xmalloc(numScreens * sizeof(void *));
 
388
    if (!pdisp->createScreen) {
 
389
       XFree(pdpyp);
 
390
       return NULL;
 
391
    }
 
392
 
 
393
    /* allocate array of library handles */
 
394
    pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*));
 
395
    if (!pdpyp->libraryHandles) {
 
396
       Xfree(pdisp->createScreen);
 
397
       XFree(pdpyp);
 
398
       return NULL;
 
399
    }
 
400
 
 
401
#ifdef BUILT_IN_DRI_DRIVER
 
402
    /* we'll statically bind to the built-in __driCreateScreen function */
 
403
    for (scrn = 0; scrn < numScreens; scrn++) {
 
404
       pdisp->createScreen[scrn] = __driCreateScreen;
 
405
       pdpyp->libraryHandles[scrn] = NULL;
 
406
    }
 
407
 
 
408
#else
 
409
    /* dynamically discover DRI drivers for all screens, saving each
 
410
     * driver's "__driCreateScreen" function pointer.  That's the bootstrap
 
411
     * entrypoint for all DRI drivers.
 
412
     */
 
413
    __glXRegisterExtensions();
 
414
    for (scrn = 0; scrn < numScreens; scrn++) {
 
415
        __DRIdriver *driver = GetDriver(dpy, scrn);
 
416
        if (driver) {
 
417
           pdisp->createScreen[scrn] = driver->createScreenFunc;
 
418
           pdpyp->libraryHandles[scrn] = driver->handle;
 
419
        }
 
420
        else {
 
421
           pdisp->createScreen[scrn] = DummyCreateScreen;
 
422
           pdpyp->libraryHandles[scrn] = NULL;
 
423
        }
 
424
    }
 
425
#endif
 
426
 
 
427
    return (void *)pdpyp;
 
428
}
 
429
 
 
430
 
 
431
 
 
432
/*
 
433
** Here we'll query the DRI driver for each screen and let each
 
434
** driver register its GL extension functions.  We only have to
 
435
** do this once.  But it MUST be done before we create any contexts
 
436
** (i.e. before any dispatch tables are created) and before
 
437
** glXGetProcAddressARB() returns.
 
438
**
 
439
** Currently called by glXGetProcAddress(), __glXInitialize(), and
 
440
** __glXNewIndirectAPI().
 
441
*/
 
442
void
 
443
__glXRegisterExtensions(void)
 
444
{
 
445
#ifndef BUILT_IN_DRI_DRIVER
 
446
   static GLboolean alreadyCalled = GL_FALSE;
 
447
   int displayNum, maxDisplays;
 
448
 
 
449
   if (alreadyCalled)
 
450
      return;
 
451
   alreadyCalled = GL_TRUE;
 
452
 
 
453
   if (getenv("LIBGL_MULTIHEAD")) {
 
454
      /* we'd like to always take this path but doing so causes a second
 
455
       * or more of delay while the XOpenDisplay() function times out.
 
456
       */
 
457
      maxDisplays = 10;  /* infinity, really */
 
458
   }
 
459
   else {
 
460
      /* just open the :0 display */
 
461
      maxDisplays = 1;
 
462
   }
 
463
 
 
464
   for (displayNum = 0; displayNum < maxDisplays; displayNum++) {
 
465
      char displayName[200];
 
466
      Display *dpy;
 
467
      snprintf(displayName, 199, ":%d.0", displayNum);
 
468
      dpy = XOpenDisplay(displayName);
 
469
      if (dpy) {
 
470
         const int numScreens = ScreenCount(dpy);
 
471
         int screenNum;
 
472
         for (screenNum = 0; screenNum < numScreens; screenNum++) {
 
473
            __DRIdriver *driver = GetDriver(dpy, screenNum);
 
474
            if (driver && driver->registerExtensionsFunc) {
 
475
               (*driver->registerExtensionsFunc)();
 
476
            }
 
477
         }
 
478
         XCloseDisplay(dpy);
 
479
      }
 
480
      else {
 
481
         break;
 
482
      }
 
483
   }
 
484
#endif
 
485
}
 
486
 
 
487
 
 
488
#endif /* GLX_DIRECT_RENDERING */