Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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