Subversion Repositories Kolibri OS

Rev

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

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