mapi.c revision 8f2a974cf2c9b6c00dfac11be4316a7d121dfbb4
1d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu/* 2d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Mesa 3-D graphics library 3d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Version: 7.9 4d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * 5d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Copyright (C) 2010 LunarG Inc. 6d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * 7d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a 8d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * copy of this software and associated documentation files (the "Software"), 9d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * to deal in the Software without restriction, including without limitation 10d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * and/or sell copies of the Software, and to permit persons to whom the 12d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Software is furnished to do so, subject to the following conditions: 13d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * 14d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * The above copyright notice and this permission notice shall be included 15d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * in all copies or substantial portions of the Software. 16d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * 17d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * DEALINGS IN THE SOFTWARE. 24d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * 25d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Authors: 26d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Chia-I Wu <olv@lunarg.com> 27d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu */ 28d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 29d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu#include <stdlib.h> 30d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu#include <string.h> 31d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 32d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu#include "u_current.h" 33d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu#include "u_thread.h" 34d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu#include "mapi.h" 35d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu#include "stub.h" 36d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu#include "table.h" 37d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 38d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu/* dynamic stubs will run out before this array */ 398f2a974cf2c9b6c00dfac11be4316a7d121dfbb4Chia-I Wustatic const struct mapi_stub *mapi_stub_map[MAPI_TABLE_NUM_SLOTS]; 40d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wustatic int mapi_num_stubs; 41d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 42d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wustatic const struct mapi_stub * 43d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wuget_stub(const char *name, const struct mapi_stub *alias) 44d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu{ 45d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu const struct mapi_stub *stub; 46d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 47d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu stub = stub_find_public(name); 48d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu if (!stub) { 49d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu struct mapi_stub *dyn = stub_find_dynamic(name, 1); 50d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu if (dyn) { 51d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu stub_fix_dynamic(dyn, alias); 52d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu stub = dyn; 53d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu } 54d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu } 55d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 56d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu return stub; 57d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu} 58d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 59d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu/** 60d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Initialize mapi. spec consists of NULL-separated strings. The first string 61d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * denotes the version. It is followed by variable numbers of entries. Each 62d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * entry can have multiple names. An empty name terminates an entry. An empty 63d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * entry terminates the spec. A spec of two entries, Foo and Bar, is as 64d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * follows 65d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * 66d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * "1\0" 67d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * "Foo\0" 68d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * "FooEXT\0" 69d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * "\0" 70d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * "Bar\0" 71d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * "\0" 72d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu */ 73d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wuvoid 74d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wumapi_init(const char *spec) 75d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu{ 76d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu u_mutex_declare_static(mutex); 77d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu const char *p; 78d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu int ver, count; 79d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 80d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu u_mutex_lock(mutex); 81d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 82d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu /* already initialized */ 83d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu if (mapi_num_stubs) { 84d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu u_mutex_unlock(mutex); 85d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu return; 86d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu } 87d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 88d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu count = 0; 89d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu p = spec; 90d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 91d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu /* parse version string */ 92d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu ver = atoi(p); 93d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu if (ver != 1) { 94d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu u_mutex_unlock(mutex); 95d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu return; 96d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu } 97d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu p += strlen(p) + 1; 98d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 99d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu while (*p) { 100d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu const struct mapi_stub *stub; 101d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 102d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu stub = get_stub(p, NULL); 103d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu /* out of dynamic entries */ 104d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu if (!stub) 105d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu break; 106d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu p += strlen(p) + 1; 107d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 108d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu while (*p) { 109d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu get_stub(p, stub); 110d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu p += strlen(p) + 1; 111d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu } 112d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 113d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu mapi_stub_map[count++] = stub; 114d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu p++; 115d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu } 116d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 117d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu mapi_num_stubs = count; 118d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 119d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu u_mutex_unlock(mutex); 120d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu} 121d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 122d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu/** 123d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Return the address of an entry. Optionally generate the entry if it does 124d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * not exist. 125d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu */ 126d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wumapi_proc 127d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wumapi_get_proc_address(const char *name) 128d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu{ 129d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu const struct mapi_stub *stub; 130d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 131d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu stub = stub_find_public(name); 132d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu if (!stub) 133d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu stub = stub_find_dynamic(name, 0); 134d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 135d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu return (stub) ? (mapi_proc) stub->addr : NULL; 136d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu} 137d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 138d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu/** 139d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Create a dispatch table. 140d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu */ 141d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wustruct mapi_table * 142d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wumapi_table_create(void) 143d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu{ 144d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu const struct mapi_table *noop = table_get_noop(); 145d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu struct mapi_table *tbl; 146d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 1478f2a974cf2c9b6c00dfac11be4316a7d121dfbb4Chia-I Wu tbl = malloc(MAPI_TABLE_SIZE); 148d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu if (tbl) 1498f2a974cf2c9b6c00dfac11be4316a7d121dfbb4Chia-I Wu memcpy(tbl, noop, MAPI_TABLE_SIZE); 150d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 151d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu return tbl; 152d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu} 153d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 154d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu/** 155d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Destroy a dispatch table. 156d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu */ 157d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wuvoid 158d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wumapi_table_destroy(struct mapi_table *tbl) 159d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu{ 160d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu free(tbl); 161d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu} 162d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 163d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu/** 164d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Fill a dispatch table. The order of the procs is determined when mapi_init 165d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * is called. 166d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu */ 167d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wuvoid 168d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wumapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs) 169d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu{ 170d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu const struct mapi_table *noop = table_get_noop(); 171d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu int i; 172d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 173d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu for (i = 0; i < mapi_num_stubs; i++) { 174d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu const struct mapi_stub *stub = mapi_stub_map[i]; 175d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu mapi_func func = (mapi_func) procs[i]; 176d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 177d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu if (!func) 178d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu func = table_get_func(noop, stub); 179d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu table_set_func(tbl, stub, func); 180d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu } 181d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu} 182d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu 183d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu/** 184d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu * Make a dispatch table current. 185d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu */ 186d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wuvoid 187d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wumapi_table_make_current(const struct mapi_table *tbl) 188d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu{ 189d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu u_current_set(tbl); 190d4589d381697b4b3dd291a3c93a34370508ef1e8Chia-I Wu} 191