Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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