1 /*
2 OSMesa LDG loader
3
4 Copyright (C) 2004 Patrice Mandin
5
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
13
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
21 */
22
23 /*--- Includes ---*/
24
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <mint/cookie.h>
28 #include <mint/osbind.h>
29 #include <mint/mintbind.h>
30
31 #include "lib-osmesa.h"
32 #include "lib-misc.h"
33 #include "../natfeat/nf_ops.h"
34 #include "nfosmesa_nfapi.h"
35
36 /*--- Defines ---*/
37
38 #define NFOSMESA_DEVICE "u:\\dev\\nfosmesa"
39
40 /*--- Local variables ---*/
41
42 static const struct nf_ops *nfOps;
43 static unsigned long nfOSMesaId=0;
44
do_nothing(unsigned long function_number,OSMesaContext ctx,void * first_param)45 static long do_nothing(unsigned long function_number, OSMesaContext ctx, void *first_param)
46 {
47 (void) function_number;
48 (void) ctx;
49 (void) first_param;
50 return 0;
51 }
52
53 long (*HostCall_p)(unsigned long function_number, OSMesaContext ctx, void *first_param) = do_nothing;
54 void (*HostCall64_p)(unsigned long function_number, OSMesaContext ctx, void *first_param, GLuint64 *retvalue);
55
56 /*--- OSMesa functions redirectors ---*/
57
58
err_init(const char * str)59 void err_init(const char *str)
60 {
61 /*
62 * FIXME: figure out how to get at the apid of the
63 * the app that loaded us (LDG->id), and perform
64 * either Cconws() or form_alert()
65 */
66 (void) Cconws(str);
67 (void) Cconws("\r\n");
68 /* if (__mint) */ Salert(str);
69 }
70
71
InitNatfeat(void)72 static void InitNatfeat(void)
73 {
74 long ver;
75
76 nfOps = nf_init();
77 if (!nfOps) {
78 err_init("__NF cookie not present on this system");
79 return;
80 }
81
82 nfOSMesaId=nfOps->get_id("OSMESA");
83 if (nfOSMesaId==0) {
84 err_init("NF OSMesa functions not present on this system");
85 return;
86 }
87 ver = nfOps->call(nfOSMesaId+GET_VERSION, 0l, 0l);
88 if (ver < ARANFOSMESA_NFAPI_VERSION)
89 {
90 if (err_old_nfapi())
91 {
92 err_init("NF OSMesa functions in ARAnyM too old");
93 nfOSMesaId = 0;
94 return;
95 }
96 }
97 if (ver > ARANFOSMESA_NFAPI_VERSION)
98 {
99 /*
100 * they should be backward compatible, but give a warning
101 */
102 (void) Cconws("Warning: NF OSMesa functions in ARAnyM newer than library\r\n");
103 }
104 }
105
HostCall_natfeats(unsigned long function_number,OSMesaContext ctx,void * first_param)106 static long HostCall_natfeats(unsigned long function_number, OSMesaContext ctx, void *first_param)
107 {
108 return nfOps->call(nfOSMesaId+function_number,ctx,first_param);
109 }
110
HostCall_natfeats64(unsigned long function_number,OSMesaContext ctx,void * first_param,GLuint64 * retvalue)111 static void HostCall_natfeats64(unsigned long function_number, OSMesaContext ctx, void *first_param, GLuint64 *retvalue)
112 {
113 nfOps->call(nfOSMesaId+function_number, ctx, first_param, retvalue);
114 }
115
InstallHostCall(void)116 static int InstallHostCall(void)
117 {
118 /* TOS maybe, try the cookie */
119 if (nfOSMesaId==0) {
120 InitNatfeat();
121 }
122 if (nfOSMesaId!=0) {
123 HostCall_p = HostCall_natfeats;
124 HostCall64_p = HostCall_natfeats64;
125 return 1;
126 }
127
128 return 0;
129 }
130
internal_OSMesaCreateContext(gl_private * private,GLenum format,OSMesaContext sharelist)131 OSMesaContext APIENTRY internal_OSMesaCreateContext(gl_private *private, GLenum format, OSMesaContext sharelist)
132 {
133 if (!InstallHostCall()) {
134 return NULL;
135 }
136
137 return (OSMesaContext)(*HostCall_p)(NFOSMESA_OSMESACREATECONTEXT, private->cur_context, &format);
138 }
139
internal_OSMesaCreateContextExt(gl_private * private,GLenum format,GLint depthBits,GLint stencilBits,GLint accumBits,OSMesaContext sharelist)140 OSMesaContext APIENTRY internal_OSMesaCreateContextExt(gl_private *private, GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, OSMesaContext sharelist)
141 {
142 if (!InstallHostCall()) {
143 return NULL;
144 }
145
146 return (OSMesaContext)(*HostCall_p)(NFOSMESA_OSMESACREATECONTEXTEXT, private->cur_context, &format);
147 }
148
internal_OSMesaCreateContextAttribs(gl_private * private,const GLint * attribList,OSMesaContext sharelist)149 OSMesaContext APIENTRY internal_OSMesaCreateContextAttribs(gl_private *private, const GLint *attribList, OSMesaContext sharelist)
150 {
151 if (!InstallHostCall()) {
152 return NULL;
153 }
154
155 return (OSMesaContext)(*HostCall_p)(NFOSMESA_OSMESACREATECONTEXTATTRIBS, private->cur_context, &attribList);
156 }
157
internal_OSMesaDestroyContext(gl_private * private,OSMesaContext ctx)158 void APIENTRY internal_OSMesaDestroyContext(gl_private *private, OSMesaContext ctx)
159 {
160 (*HostCall_p)(NFOSMESA_OSMESADESTROYCONTEXT, private->cur_context, &ctx);
161 freeglGetString(private, ctx);
162 if (ctx == private->cur_context)
163 private->cur_context = 0;
164 }
165
internal_OSMesaMakeCurrent(gl_private * private,OSMesaContext ctx,void * buffer,GLenum type,GLsizei width,GLsizei height)166 GLboolean APIENTRY internal_OSMesaMakeCurrent(gl_private *private, OSMesaContext ctx, void *buffer, GLenum type, GLsizei width, GLsizei height)
167 {
168 GLboolean ret = (GLboolean)(*HostCall_p)(NFOSMESA_OSMESAMAKECURRENT, private->cur_context, &ctx);
169 if (ret)
170 private->cur_context = ctx;
171 return ret;
172 }
173
internal_OSMesaGetCurrentContext(gl_private * private)174 OSMesaContext APIENTRY internal_OSMesaGetCurrentContext(gl_private *private)
175 {
176 #if 0
177 /*
178 * wrong; the host manages his current context for all processes using NFOSMesa;
179 * return local copy instead
180 */
181 return (OSMesaContext)(*HostCall_p)(NFOSMESA_OSMESAGETCURRENTCONTEXT, private->cur_context, NULL);
182 #else
183 return private->cur_context;
184 #endif
185 }
186
internal_OSMesaPixelStore(gl_private * private,GLint pname,GLint value)187 void APIENTRY internal_OSMesaPixelStore(gl_private *private, GLint pname, GLint value)
188 {
189 (*HostCall_p)(NFOSMESA_OSMESAPIXELSTORE, private->cur_context, &pname);
190 }
191
internal_OSMesaGetIntegerv(gl_private * private,GLint pname,GLint * value)192 void APIENTRY internal_OSMesaGetIntegerv(gl_private *private, GLint pname, GLint *value)
193 {
194 (*HostCall_p)(NFOSMESA_OSMESAGETINTEGERV, private->cur_context, &pname);
195 }
196
internal_OSMesaGetDepthBuffer(gl_private * private,OSMesaContext c,GLint * width,GLint * height,GLint * bytesPerValue,void ** buffer)197 GLboolean APIENTRY internal_OSMesaGetDepthBuffer(gl_private *private, OSMesaContext c, GLint *width, GLint *height, GLint *bytesPerValue, void **buffer )
198 {
199 return (GLboolean)(*HostCall_p)(NFOSMESA_OSMESAGETDEPTHBUFFER, private->cur_context, &c);
200 }
201
internal_OSMesaGetColorBuffer(gl_private * private,OSMesaContext c,GLint * width,GLint * height,GLint * format,void ** buffer)202 GLboolean APIENTRY internal_OSMesaGetColorBuffer(gl_private *private, OSMesaContext c, GLint *width, GLint *height, GLint *format, void **buffer )
203 {
204 return (GLboolean)(*HostCall_p)(NFOSMESA_OSMESAGETCOLORBUFFER, private->cur_context, &c);
205 }
206
internal_OSMesaGetProcAddress(gl_private * private,const char * funcName)207 OSMESAproc APIENTRY internal_OSMesaGetProcAddress(gl_private *private, const char *funcName)
208 {
209 long func = (*HostCall_p)(NFOSMESA_OSMESAGETPROCADDRESS, private->cur_context, &funcName);
210 if (func == 0 || func > NFOSMESA_LAST)
211 return 0;
212 return (OSMESAproc)func;
213 }
214
internal_OSMesaColorClamp(gl_private * private,GLboolean32 enable)215 void APIENTRY internal_OSMesaColorClamp(gl_private *private, GLboolean32 enable)
216 {
217 (*HostCall_p)(NFOSMESA_OSMESACOLORCLAMP, private->cur_context, &enable);
218 }
219
internal_OSMesaPostprocess(gl_private * private,OSMesaContext osmesa,const char * filter,GLuint enable_value)220 void APIENTRY internal_OSMesaPostprocess(gl_private *private, OSMesaContext osmesa, const char *filter, GLuint enable_value)
221 {
222 (*HostCall_p)(NFOSMESA_OSMESAPOSTPROCESS, private->cur_context, &osmesa);
223 }
224
225
internal_glInit(gl_private * private)226 void internal_glInit(gl_private *private)
227 {
228 unsigned int i, j;
229
230 if (!private)
231 return;
232 private->cur_context = 0;
233 private->gl_exception = 0;
234 for (i = 0; i < MAX_OSMESA_CONTEXTS; i++)
235 {
236 private->contexts[i].oldmesa_buffer = 0;
237 for (j = 0; j < sizeof(private->contexts[i].gl_strings) / sizeof(private->contexts[i].gl_strings[0]); j++)
238 private->contexts[i].gl_strings[j] = 0;
239 }
240 InstallHostCall();
241 }
242