1f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu/**************************************************************************
2f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
3f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2010-2011 LunarG, Inc.
6f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * All Rights Reserved.
7f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
8f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a
9f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * copy of this software and associated documentation files (the
10f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * "Software"), to deal in the Software without restriction, including
11f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * without limitation the rights to use, copy, modify, merge, publish,
12f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * distribute, sub license, and/or sell copies of the Software, and to
13f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * permit persons to whom the Software is furnished to do so, subject to
14f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * the following conditions:
15f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
16f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * The above copyright notice and this permission notice (including the
17f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * next paragraph) shall be included in all copies or substantial portions
18f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * of the Software.
19f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
20f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * DEALINGS IN THE SOFTWARE.
27f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
28f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu **************************************************************************/
29f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu
30f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu
316052af172f0241e6678cd16efac0a0f14f40146cBrian Paul/**
326052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * Functions for choosing and opening/loading device drivers.
336052af172f0241e6678cd16efac0a0f14f40146cBrian Paul */
346052af172f0241e6678cd16efac0a0f14f40146cBrian Paul
356052af172f0241e6678cd16efac0a0f14f40146cBrian Paul
36adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <assert.h>
3711a261ef4f1d4100c46f73ad51e7e4ed57cc1b5eBrian Paul#include <string.h>
38adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <stdio.h>
390c8908c411c434eda318b41b4f2a370a1e794831Brian Paul#include <stdlib.h>
401e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu
411e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu#include "eglstring.h"
42e084fe54f93c9d51df99812b76d3299b0cff57a3Brian Paul#include "egldefines.h"
43adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldisplay.h"
44adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldriver.h"
45b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul#include "egllog.h"
46f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu#include "eglmutex.h"
47adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
486f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX)
496b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#include <dlfcn.h>
50b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu#include <sys/types.h>
51b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu#include <dirent.h>
525d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu#include <unistd.h>
53b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz#endif
54adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
555541988578054345ca70b7ed7972710396e61b44Chia-I Wu
56f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wutypedef struct _egl_module {
57f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   char *Path;
58c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   _EGLMain_t BuiltIn;
59f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   void *Handle;
60f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLDriver *Driver;
61f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} _EGLModule;
62f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
63f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGL_DECLARE_MUTEX(_eglModuleMutex);
64f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLArray *_eglModules;
65f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
66c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wuconst struct {
67c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   const char *name;
68c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   _EGLMain_t main;
69c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu} _eglBuiltInDrivers[] = {
70a8b6b6555c7d6a02a3d095c72ebbdc218bc45cd3Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_GALLIUM
71a8b6b6555c7d6a02a3d095c72ebbdc218bc45cd3Chia-I Wu   { "egl_gallium", _eglBuiltInDriverGALLIUM },
72a8b6b6555c7d6a02a3d095c72ebbdc218bc45cd3Chia-I Wu#endif
73c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_DRI2
74c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   { "egl_dri2", _eglBuiltInDriverDRI2 },
75c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#endif
76c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_GLX
77c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   { "egl_glx", _eglBuiltInDriverGLX },
78c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#endif
79c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   { NULL, NULL }
80c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu};
81f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
82a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul/**
83a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul * Wrappers for dlopen/dlclose()
84a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul */
856f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_WINDOWS)
86a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
875541988578054345ca70b7ed7972710396e61b44Chia-I Wu
885541988578054345ca70b7ed7972710396e61b44Chia-I Wutypedef HMODULE lib_handle;
895541988578054345ca70b7ed7972710396e61b44Chia-I Wu
905541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic HMODULE
915541988578054345ca70b7ed7972710396e61b44Chia-I Wuopen_library(const char *filename)
925541988578054345ca70b7ed7972710396e61b44Chia-I Wu{
935541988578054345ca70b7ed7972710396e61b44Chia-I Wu   return LoadLibrary(filename);
945541988578054345ca70b7ed7972710396e61b44Chia-I Wu}
955541988578054345ca70b7ed7972710396e61b44Chia-I Wu
965541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic void
975541988578054345ca70b7ed7972710396e61b44Chia-I Wuclose_library(HMODULE lib)
985541988578054345ca70b7ed7972710396e61b44Chia-I Wu{
995541988578054345ca70b7ed7972710396e61b44Chia-I Wu   FreeLibrary(lib);
1005541988578054345ca70b7ed7972710396e61b44Chia-I Wu}
1015541988578054345ca70b7ed7972710396e61b44Chia-I Wu
102ab0d13dd60c707f2c414fa9fe8e489a9e24a8aeeJonathan White
103b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wustatic const char *
104b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wulibrary_suffix(void)
105b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{
1065d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   return ".dll";
10721b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu}
10821b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu
10921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu
1106f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#elif defined(_EGL_OS_UNIX)
111a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
112a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
1135541988578054345ca70b7ed7972710396e61b44Chia-I Wutypedef void * lib_handle;
1145541988578054345ca70b7ed7972710396e61b44Chia-I Wu
1155541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic void *
1165541988578054345ca70b7ed7972710396e61b44Chia-I Wuopen_library(const char *filename)
1175541988578054345ca70b7ed7972710396e61b44Chia-I Wu{
1185541988578054345ca70b7ed7972710396e61b44Chia-I Wu   return dlopen(filename, RTLD_LAZY);
1195541988578054345ca70b7ed7972710396e61b44Chia-I Wu}
1205541988578054345ca70b7ed7972710396e61b44Chia-I Wu
1215541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic void
1225541988578054345ca70b7ed7972710396e61b44Chia-I Wuclose_library(void *lib)
1235541988578054345ca70b7ed7972710396e61b44Chia-I Wu{
1245541988578054345ca70b7ed7972710396e61b44Chia-I Wu   dlclose(lib);
1255541988578054345ca70b7ed7972710396e61b44Chia-I Wu}
1265541988578054345ca70b7ed7972710396e61b44Chia-I Wu
127b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
128b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wustatic const char *
129b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wulibrary_suffix(void)
130b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{
1315d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   return ".so";
13221b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu}
13321b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu
13421b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu
135a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul#endif
136a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
1370eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
138adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul/**
1390eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu * Open the named driver and find its bootstrap function: _eglMain().
140adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul */
1410eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wustatic _EGLMain_t
142b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu_eglOpenLibrary(const char *driverPath, lib_handle *handle)
143adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul{
144a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   lib_handle lib;
1455541988578054345ca70b7ed7972710396e61b44Chia-I Wu   _EGLMain_t mainFunc = NULL;
1465541988578054345ca70b7ed7972710396e61b44Chia-I Wu   const char *error = "unknown error";
147adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
148b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu   assert(driverPath);
1496052af172f0241e6678cd16efac0a0f14f40146cBrian Paul
150b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
151b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu   lib = open_library(driverPath);
1525541988578054345ca70b7ed7972710396e61b44Chia-I Wu
1536f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_WINDOWS)
1545541988578054345ca70b7ed7972710396e61b44Chia-I Wu   /* XXX untested */
1555541988578054345ca70b7ed7972710396e61b44Chia-I Wu   if (lib)
1565541988578054345ca70b7ed7972710396e61b44Chia-I Wu      mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
1576f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#elif defined(_EGL_OS_UNIX)
1585541988578054345ca70b7ed7972710396e61b44Chia-I Wu   if (lib) {
159496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu      union {
160496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu         _EGLMain_t func;
161496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu         void *ptr;
162496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu      } tmp = { NULL };
163496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu      /* direct cast gives a warning when compiled with -pedantic */
164496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu      tmp.ptr = dlsym(lib, "_eglMain");
165496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu      mainFunc = tmp.func;
1665541988578054345ca70b7ed7972710396e61b44Chia-I Wu      if (!mainFunc)
1675541988578054345ca70b7ed7972710396e61b44Chia-I Wu         error = dlerror();
1685541988578054345ca70b7ed7972710396e61b44Chia-I Wu   }
1695541988578054345ca70b7ed7972710396e61b44Chia-I Wu   else {
1705541988578054345ca70b7ed7972710396e61b44Chia-I Wu      error = dlerror();
171ab0d13dd60c707f2c414fa9fe8e489a9e24a8aeeJonathan White   }
172ab0d13dd60c707f2c414fa9fe8e489a9e24a8aeeJonathan White#endif
1735541988578054345ca70b7ed7972710396e61b44Chia-I Wu
174485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   if (!lib) {
1755541988578054345ca70b7ed7972710396e61b44Chia-I Wu      _eglLog(_EGL_WARNING, "Could not open driver %s (%s)",
1765541988578054345ca70b7ed7972710396e61b44Chia-I Wu              driverPath, error);
177485528f2acb69940a7c757638127f716c0cb2654Jon Smirl      return NULL;
178485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   }
1796b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul
180485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   if (!mainFunc) {
1815541988578054345ca70b7ed7972710396e61b44Chia-I Wu      _eglLog(_EGL_WARNING, "_eglMain not found in %s (%s)",
1825541988578054345ca70b7ed7972710396e61b44Chia-I Wu              driverPath, error);
1830eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu      if (lib)
1840eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu         close_library(lib);
185485528f2acb69940a7c757638127f716c0cb2654Jon Smirl      return NULL;
186adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   }
187485528f2acb69940a7c757638127f716c0cb2654Jon Smirl
1880eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu   *handle = lib;
1890eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu   return mainFunc;
1900eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu}
1910eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
1920eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
1930eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/**
194f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Load a module and create the driver object.
1950eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */
196f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean
197f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglLoadModule(_EGLModule *mod)
1980eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{
1990eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu   _EGLMain_t mainFunc;
2000eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu   lib_handle lib;
201f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLDriver *drv;
2020eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
203c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   if (mod->Driver)
204c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      return EGL_TRUE;
205c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu
206c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   if (mod->BuiltIn) {
207c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      lib = (lib_handle) NULL;
208c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      mainFunc = mod->BuiltIn;
209c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   }
210c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   else {
211c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      mainFunc = _eglOpenLibrary(mod->Path, &lib);
212c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      if (!mainFunc)
213c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu         return EGL_FALSE;
214c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   }
2150eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
216f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   drv = mainFunc(NULL);
217485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   if (!drv) {
2180eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu      if (lib)
2190eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu         close_library(lib);
220f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      return EGL_FALSE;
221adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   }
2226b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul
2230eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu   if (!drv->Name) {
224f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", mod->Path);
2250eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu      drv->Name = "UNNAMED";
2266b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul   }
2270eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
228f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   mod->Handle = (void *) lib;
229f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   mod->Driver = drv;
230f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
231f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return EGL_TRUE;
232f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
233b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
2340eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
235f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
236f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload a module.
237f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
238f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void
239f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadModule(_EGLModule *mod)
240f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
241d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#if defined(_EGL_OS_UNIX)
242f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   /* destroy the driver */
243f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (mod->Driver && mod->Driver->Unload)
244f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      mod->Driver->Unload(mod->Driver);
245d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu
246d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu   /*
247d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu    * XXX At this point (atexit), the module might be the last reference to
248d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu    * libEGL.  Closing the module might unmap libEGL and give problems.
249d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu    */
250d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#if 0
251f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (mod->Handle)
252f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      close_library(mod->Handle);
253d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#endif
254d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#elif defined(_EGL_OS_WINDOWS)
255d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu   /* XXX Windows unloads DLLs before atexit */
256d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#endif
257f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
258f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   mod->Driver = NULL;
259f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   mod->Handle = NULL;
2600eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu}
2610eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
2620eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
2630eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/**
264f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add a module to the module array.
2650eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */
266f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLModule *
267f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddModule(const char *path)
2680eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{
269f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLModule *mod;
270f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   EGLint i;
2710eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
272f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (!_eglModules) {
273f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglModules = _eglCreateArray("Module", 8);
274f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (!_eglModules)
275f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         return NULL;
276f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
277cf22fd5e5b13ccdb02ba0368ea722ede3bbc6de0Chia-I Wu
278f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   /* find duplicates */
279f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   for (i = 0; i < _eglModules->Size; i++) {
280f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      mod = _eglModules->Elements[i];
281f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (strcmp(mod->Path, path) == 0)
282f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         return mod;
283f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
284f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
285f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   /* allocate a new one */
286f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   mod = calloc(1, sizeof(*mod));
287f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (mod) {
288f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      mod->Path = _eglstrdup(path);
289f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (!mod->Path) {
290f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         free(mod);
291f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         mod = NULL;
2920eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu      }
2930eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu   }
294f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (mod) {
295f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglAppendArray(_eglModules, (void *) mod);
296f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglLog(_EGL_DEBUG, "added %s to module array", mod->Path);
297f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
2980eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
299f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return mod;
300f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
301f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
302f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
303f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
304f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Free a module.
305f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
306f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void
307f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglFreeModule(void *module)
308f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
309f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLModule *mod = (_EGLModule *) module;
310f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
311f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _eglUnloadModule(mod);
312f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   free(mod->Path);
313f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   free(mod);
3140eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu}
3150eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
3160eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
3170eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/**
3180d089cbb48d099b833768556266114d537c91299Chia-I Wu * A loader function for use with _eglPreloadForEach.  The loader data is the
3195d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * filename of the driver.   This function stops on the first valid driver.
3205d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu */
3215d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wustatic EGLBoolean
3220d089cbb48d099b833768556266114d537c91299Chia-I Wu_eglLoaderFile(const char *dir, size_t len, void *loader_data)
3235d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu{
3245d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   char path[1024];
3250d089cbb48d099b833768556266114d537c91299Chia-I Wu   const char *filename = (const char *) loader_data;
3265d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   size_t flen = strlen(filename);
3275d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
3285d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   /* make a full path */
3295d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   if (len + flen + 2 > sizeof(path))
3305d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      return EGL_TRUE;
3315d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   if (len) {
3325d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      memcpy(path, dir, len);
3335d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      path[len++] = '/';
3345d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   }
3355d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   memcpy(path + len, filename, flen);
3365d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   len += flen;
3375d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   path[len] = '\0';
3385d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
339f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (library_suffix()) {
3405d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      const char *suffix = library_suffix();
3415d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      size_t slen = strlen(suffix);
3425d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      const char *p;
3435d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      EGLBoolean need_suffix;
3445d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
3455d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      p = filename + flen - slen;
3465d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      need_suffix = (p < filename || strcmp(p, suffix) != 0);
347f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (need_suffix) {
348f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         /* overflow */
349f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         if (len + slen + 1 > sizeof(path))
350f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu            return EGL_TRUE;
3515d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu         strcpy(path + len, suffix);
3525d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      }
3535d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   }
354f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
355f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu#if defined(_EGL_OS_UNIX)
356f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   /* check if the file exists */
357f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (access(path, F_OK))
3585d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      return EGL_TRUE;
359f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu#endif
360f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
361f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _eglAddModule(path);
362f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
363f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return EGL_TRUE;
364f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
365f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
3665d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
367f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
368f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Run the callback function on each driver directory.
3695d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu *
3705d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * The process may end prematurely if the callback function returns false.
3715d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu */
372f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void
3735d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu_eglPreloadForEach(const char *search_path,
3740d089cbb48d099b833768556266114d537c91299Chia-I Wu                   EGLBoolean (*loader)(const char *, size_t, void *),
3750d089cbb48d099b833768556266114d537c91299Chia-I Wu                   void *loader_data)
3765d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu{
3775d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   const char *cur, *next;
3785d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   size_t len;
3795d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
3805d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   cur = search_path;
3815d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   while (cur) {
3825d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      next = strchr(cur, ':');
3835d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      len = (next) ? next - cur : strlen(cur);
3845d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
38588af76ce94834d795c11445b1c82b7aa874b87d5Igor Oliveira      if (!loader(cur, len, loader_data))
3865d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu         break;
3875d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
3885d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      cur = (next) ? next + 1 : NULL;
3895d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   }
3905d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu}
3915d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
3925d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
3935d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu/**
3945d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * Return a list of colon-separated driver directories.
3955d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu */
3965d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wustatic const char *
3975d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu_eglGetSearchPath(void)
3985d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu{
399ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu   static char search_path[1024];
4005d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
4016f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS)
402ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu   if (search_path[0] == '\0') {
403ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      char *buf = search_path;
404ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      size_t len = sizeof(search_path);
405ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      EGLBoolean use_env;
406ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      char dir_sep;
4075d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      int ret;
4085d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
4096f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX)
410ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      use_env = (geteuid() == getuid() && getegid() == getgid());
411ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      dir_sep = '/';
412ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu#else
413ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      use_env = EGL_TRUE;
414ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      dir_sep = '\\';
415ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu#endif
416ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu
417ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      if (use_env) {
418ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         char *p;
419ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu
420ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         /* extract the dirname from EGL_DRIVER */
421ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         p = getenv("EGL_DRIVER");
422ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         if (p && strchr(p, dir_sep)) {
423ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu            ret = _eglsnprintf(buf, len, "%s", p);
424ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu            if (ret > 0 && ret < len) {
425ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu               p = strrchr(buf, dir_sep);
426ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu               *p++ = ':';
427ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu
428ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu               len -= p - buf;
429ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu               buf = p;
430ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu            }
431ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         }
432ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu
433ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         /* append EGL_DRIVERS_PATH */
434ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         p = getenv("EGL_DRIVERS_PATH");
435ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         if (p) {
436ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu            ret = _eglsnprintf(buf, len, "%s:", p);
437ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu            if (ret > 0 && ret < len) {
438ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu               buf += ret;
439ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu               len -= ret;
440ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu            }
441ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         }
442ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      }
443ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      else {
4446fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu         _eglLog(_EGL_DEBUG,
4456fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu               "ignore EGL_DRIVERS_PATH for setuid/setgid binaries");
4466fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu      }
4476fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu
448ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      ret = _eglsnprintf(buf, len, "%s", _EGL_DRIVER_SEARCH_DIR);
449ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      if (ret < 0 || ret >= len)
450ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu         search_path[0] = '\0';
451ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu
452ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu      _eglLog(_EGL_DEBUG, "EGL search path is %s", search_path);
4535d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   }
454ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu#endif /* defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) */
4555d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
4565d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   return search_path;
4575d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu}
4585d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
4595d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu
4605d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu/**
461f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add the user driver to the module array.
462b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu *
463f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * The user driver is specified by EGL_DRIVER.
464b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */
4651e4f412242391000eea3fd28452865c3d27f987dChia-I Wustatic EGLBoolean
466f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddUserDriver(void)
467b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{
4685d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu   const char *search_path = _eglGetSearchPath();
46921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu   char *env;
470f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   size_t name_len = 0;
471b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
472b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu   env = getenv("EGL_DRIVER");
4736f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX)
4746fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu   if (env && strchr(env, '/')) {
4755d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu      search_path = "";
4766fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu      if ((geteuid() != getuid() || getegid() != getgid())) {
4776fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu         _eglLog(_EGL_DEBUG,
4786fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu               "ignore EGL_DRIVER for setuid/setgid binaries");
4796fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu         env = NULL;
4806fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu      }
4816fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu   }
482f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   else if (env) {
483f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu      char *suffix = strchr(env, '.');
484f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu      name_len = (suffix) ? suffix - env : strlen(env);
485f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   }
486f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu#else
487f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   if (env)
488f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu      name_len = strlen(env);
4896f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#endif /* _EGL_OS_UNIX */
490f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu
491f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   /*
492f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu    * Try built-in drivers first if we know the driver name.  This makes sure
493f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu    * we do not load the outdated external driver that is still on the
494f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu    * filesystem.
495f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu    */
496f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   if (name_len) {
497c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      _EGLModule *mod;
498c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      EGLint i;
499c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu
500c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      for (i = 0; _eglBuiltInDrivers[i].name; i++) {
501f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu         if (strlen(_eglBuiltInDrivers[i].name) == name_len &&
502f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu             !strncmp(_eglBuiltInDrivers[i].name, env, name_len)) {
503c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu            mod = _eglAddModule(env);
504c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu            if (mod)
505c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu               mod->BuiltIn = _eglBuiltInDrivers[i].main;
506f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu
507f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu            return EGL_TRUE;
508c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu         }
509c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      }
510f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   }
511f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu
512f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   /* otherwise, treat env as a path */
513f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   if (env) {
514f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu      _eglPreloadForEach(search_path, _eglLoaderFile, (void *) env);
5151e4f412242391000eea3fd28452865c3d27f987dChia-I Wu
5161e4f412242391000eea3fd28452865c3d27f987dChia-I Wu      return EGL_TRUE;
517c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   }
5181e4f412242391000eea3fd28452865c3d27f987dChia-I Wu
5191e4f412242391000eea3fd28452865c3d27f987dChia-I Wu   return EGL_FALSE;
520f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
521b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
522f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
523f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
52449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu * Add egl_gallium to the module array.
52549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu */
52649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wustatic void
52749ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu_eglAddGalliumDriver(void)
52849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu{
52949ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu#ifndef _EGL_BUILT_IN_DRIVER_GALLIUM
53049ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   void *external = (void *) "egl_gallium";
53149ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   _eglPreloadForEach(_eglGetSearchPath(), _eglLoaderFile, external);
53249ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu#endif
53349ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu}
53449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu
53549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu
53649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu/**
537c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu * Add built-in drivers to the module array.
538f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
539f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void
540c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu_eglAddBuiltInDrivers(void)
541f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
542c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   _EGLModule *mod;
543f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   EGLint i;
544f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
545c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   for (i = 0; _eglBuiltInDrivers[i].name; i++) {
546c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      mod = _eglAddModule(_eglBuiltInDrivers[i].name);
547c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      if (mod)
548c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu         mod->BuiltIn = _eglBuiltInDrivers[i].main;
54921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu   }
550f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
551b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
552f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
553f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
554f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add drivers to the module array.  Drivers will be loaded as they are matched
555f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * to displays.
556f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
557f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean
558f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddDrivers(void)
559f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
560f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (_eglModules)
561f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      return EGL_TRUE;
562f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
5631e4f412242391000eea3fd28452865c3d27f987dChia-I Wu   if (!_eglAddUserDriver()) {
5641e4f412242391000eea3fd28452865c3d27f987dChia-I Wu      /*
5651e4f412242391000eea3fd28452865c3d27f987dChia-I Wu       * Add other drivers only when EGL_DRIVER is not set.  The order here
5661e4f412242391000eea3fd28452865c3d27f987dChia-I Wu       * decides the priorities.
5671e4f412242391000eea3fd28452865c3d27f987dChia-I Wu       */
5681e4f412242391000eea3fd28452865c3d27f987dChia-I Wu      _eglAddGalliumDriver();
5691e4f412242391000eea3fd28452865c3d27f987dChia-I Wu      _eglAddBuiltInDrivers();
5701e4f412242391000eea3fd28452865c3d27f987dChia-I Wu   }
571f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
572f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return (_eglModules != NULL);
573b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu}
574b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
575b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
576b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu/**
577655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * A helper function for _eglMatchDriver.  It finds the first driver that can
578655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * initialize the display and return.
579b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */
580655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wustatic _EGLDriver *
581655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchAndInitialize(_EGLDisplay *dpy)
582b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{
583655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   _EGLDriver *drv = NULL;
584655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   EGLint i = 0;
5854afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu
586f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (!_eglAddDrivers()) {
5871e4f412242391000eea3fd28452865c3d27f987dChia-I Wu      _eglLog(_EGL_WARNING, "failed to find any driver");
588655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      return NULL;
5894afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu   }
590b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
591655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   if (dpy->Driver) {
592655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      drv = dpy->Driver;
593655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      /* no re-matching? */
594655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      if (!drv->API.Initialize(drv, dpy))
595655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         drv = NULL;
596655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      return drv;
597655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   }
598b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
599655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   while (i < _eglModules->Size) {
600655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
601655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu
602655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      if (!_eglLoadModule(mod)) {
603655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         /* remove invalid modules */
604655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         _eglEraseArray(_eglModules, i, _eglFreeModule);
605655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         continue;
606655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      }
607655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu
608655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      if (mod->Driver->API.Initialize(mod->Driver, dpy)) {
609655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         drv = mod->Driver;
610655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         break;
611f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      }
612f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      else {
613655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         i++;
614f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      }
615f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
6164afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu
617655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   return drv;
618655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu}
619b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
6204afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu
621655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu/**
622655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * Match a display to a driver.  The display is initialized unless test_only is
623655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * true.  The matching is done by finding the first driver that can initialize
624655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * the display.
625655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu */
626655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_EGLDriver *
627655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only)
628655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu{
629655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   _EGLDriver *best_drv;
630f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
631655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   assert(!dpy->Initialized);
632f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
633655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   _eglLockMutex(&_eglModuleMutex);
634655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu
635655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   /* set options */
636655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   dpy->Options.TestOnly = test_only;
637a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu   dpy->Options.UseFallback = EGL_FALSE;
638655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu
639655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   best_drv = _eglMatchAndInitialize(dpy);
640a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu   if (!best_drv) {
641a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu      dpy->Options.UseFallback = EGL_TRUE;
642a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu      best_drv = _eglMatchAndInitialize(dpy);
643a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu   }
6440eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
645f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _eglUnlockMutex(&_eglModuleMutex);
646f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
647f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (best_drv) {
648655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      _eglLog(_EGL_DEBUG, "the best driver is %s%s",
649655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu            best_drv->Name, (test_only) ? " (test only) " : "");
650655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      if (!test_only) {
651f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         dpy->Driver = best_drv;
652f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         dpy->Initialized = EGL_TRUE;
653f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      }
654f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
655f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
656f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return best_drv;
657e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul}
658e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul
659f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
660f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu__eglMustCastToProperFunctionPointerType
661f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglGetDriverProc(const char *procname)
662681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg{
663f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   EGLint i;
664f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLProc proc = NULL;
665f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
666f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (!_eglModules) {
667f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      /* load the driver for the default display */
668f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
669f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _EGLDisplay *dpy = _eglLookupDisplay(egldpy);
670f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE))
671f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         return NULL;
672f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
673681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg
674f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   for (i = 0; i < _eglModules->Size; i++) {
675f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
676681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg
677f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (!mod->Driver)
678f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         break;
679f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      proc = mod->Driver->API.GetProcAddress(mod->Driver, procname);
680f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (proc)
681afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu         break;
682afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu   }
683681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg
684f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return proc;
685f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
686f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
687681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg
688f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
689f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload all drivers.
690f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
691f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wuvoid
692f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadDrivers(void)
693f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
694f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   /* this is called at atexit time */
695f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (_eglModules) {
696f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglDestroyArray(_eglModules, _eglFreeModule);
697f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglModules = NULL;
698f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
699681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg}
700681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg
701e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul
702e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul/**
703e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * Invoke a callback function on each EGL search path.
704e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu *
705e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * The first argument of the callback function is the name of the search path.
706e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * The second argument is the length of the name.
707e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu */
708e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wuvoid
709e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu_eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *),
710e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu                      void *callback_data)
711e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu{
712e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu   const char *search_path = _eglGetSearchPath();
713e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu   _eglPreloadForEach(search_path, callback, callback_data);
714e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu}
715