1 /*         ______   ___    ___
2  *        /\  _  \ /\_ \  /\_ \
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *
11  *      Dynamic driver list helpers.
12  *
13  *      By Peter Wang.
14  *
15  *      See readme.txt for copyright information.
16  */
17 
18 
19 #include <string.h>
20 
21 #include "allegro.h"
22 #include "allegro/internal/aintern.h"
23 
24 
25 
26 /* count_drivers:
27  *  Returns the number of drivers in a list, not including the sentinel.
28  */
count_drivers(_DRIVER_INFO * drvlist)29 static int count_drivers(_DRIVER_INFO *drvlist)
30 {
31    _DRIVER_INFO *start = drvlist;
32    while (drvlist->driver) drvlist++;
33    return drvlist - start;
34 }
35 
36 
37 
38 /* _create_driver_list:
39  *  Creates a new driver list and returns it. Returns NULL on error.
40  */
_create_driver_list(void)41 _DRIVER_INFO *_create_driver_list(void)
42 {
43    _DRIVER_INFO *drv;
44 
45    drv = _AL_MALLOC(sizeof(struct _DRIVER_INFO));
46 
47    if (drv) {
48       drv->id = 0;
49       drv->driver = NULL;
50       drv->autodetect = FALSE;
51    }
52 
53    return drv;
54 }
55 
56 
57 
58 /* _destroy_driver_list:
59  *  Frees a driver list.
60  */
_destroy_driver_list(_DRIVER_INFO * drvlist)61 void _destroy_driver_list(_DRIVER_INFO *drvlist)
62 {
63    _AL_FREE(drvlist);
64 }
65 
66 
67 
68 /* _driver_list_append_driver:
69  *  Adds a driver to the end of a driver list.
70  */
_driver_list_append_driver(_DRIVER_INFO ** drvlist,int id,void * driver,int autodetect)71 void _driver_list_append_driver(_DRIVER_INFO **drvlist, int id, void *driver, int autodetect)
72 {
73    _DRIVER_INFO *drv;
74    int c;
75 
76    ASSERT(*drvlist);
77 
78    c = count_drivers(*drvlist);
79 
80    drv = _AL_REALLOC(*drvlist, sizeof(_DRIVER_INFO) * (c+2));
81    if (!drv)
82       return;
83 
84    drv[c].id = id;
85    drv[c].driver = driver;
86    drv[c].autodetect = autodetect;
87    drv[c+1].id = 0;
88    drv[c+1].driver = NULL;
89    drv[c+1].autodetect = FALSE;
90 
91    *drvlist = drv;
92 }
93 
94 
95 
96 /* _driver_list_prepend_driver:
97  *  Adds a driver to the start of a driver list.
98  */
_driver_list_prepend_driver(_DRIVER_INFO ** drvlist,int id,void * driver,int autodetect)99 void _driver_list_prepend_driver(_DRIVER_INFO **drvlist, int id, void *driver, int autodetect)
100 {
101    _DRIVER_INFO *drv;
102    int c;
103 
104    ASSERT(*drvlist);
105 
106    c = count_drivers(*drvlist);
107 
108    drv = _AL_REALLOC(*drvlist, sizeof(_DRIVER_INFO) * (c+2));
109    if (!drv)
110       return;
111 
112    memmove(drv+1, drv, sizeof(_DRIVER_INFO) * (c+1));
113 
114    drv[0].id = id;
115    drv[0].driver = driver;
116    drv[0].autodetect = autodetect;
117 
118    *drvlist = drv;
119 }
120 
121 
122 
123 /* _driver_list_append_list:
124  *  Add drivers from one list to another list.
125  */
_driver_list_append_list(_DRIVER_INFO ** drvlist,_DRIVER_INFO * srclist)126 void _driver_list_append_list(_DRIVER_INFO **drvlist, _DRIVER_INFO *srclist)
127 {
128    ASSERT(*drvlist);
129    ASSERT(srclist);
130 
131    while (srclist->driver) {
132       _driver_list_append_driver(drvlist, srclist->id, srclist->driver, srclist->autodetect);
133       srclist++;
134    }
135 }
136