Subversion Repositories Kolibri OS

Rev

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

  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 <olv@lunarg.com>
  27.  */
  28.  
  29. #include <stdlib.h>
  30. #include <string.h>
  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. }
  191.