blob: 764ccba803e74a6d58a2075514b434d559169294 [file] [log] [blame]
Jon Taylor7b9c36d1999-08-23 21:13:19 +00001/* GGI-Driver for MESA
2 *
3 * Copyright (C) 1997-1998 Uwe Maurer - uwe_maurer@t-online.de
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * ---------------------------------------------------------------------
19 * This code was derived from the following source of information:
20 *
21 * svgamesa.c and ddsample.c by Brian Paul
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "conf.h"
27#endif
28
29#ifdef GGI
30
31#include <ggi/mesa/ggimesa_int.h>
Jon Taylorc6c06c92000-01-07 08:34:43 +000032#include <ggi/mesa/debug.h>
Jon Taylor7b9c36d1999-08-23 21:13:19 +000033
34#undef VIS
35#undef FLIP
36#define VIS (GGIMesa->ggi_vis)
37#define FLIP(y) (GGIMesa->flip_y-(y))
38
39GGIMesaContext GGIMesa = NULL; /* the current context */
40
41ggi_extid ggiMesaID = -1;
42static int _ggimesaLibIsUp = 0;
43static void *_ggimesaConfigHandle;
44
45/* FIXME: These should really be defined in the make system using -Dxxx */
46#define GGIMESACONFFILE "/usr/local/etc/ggi/ggimesa.conf"
47#define GGIMESATAGLEN 0
48static char ggimesaconfstub[512] = GGIMESACONFFILE;
49static char *ggimesaconffile = ggimesaconfstub + GGIMESATAGLEN;
50
51int gl_ggi_init = GL_FALSE;
52int gl_ggi_debug = GL_FALSE;
53
54static void gl_ggiUpdateState(GLcontext *ctx);
55static int changed(ggi_visual_t vis, int whatchanged);
56
Jon Taylorc6c06c92000-01-07 08:34:43 +000057#if 0
Jon Taylor7b9c36d1999-08-23 21:13:19 +000058/* FIXME: Move this debugging stuff to include/ggi/mesa/internal/ */
59void gl_ggiPrint(char *format,...)
60{
61 va_list args;
62 va_start(args,format);
63 fprintf(stderr,"GGIMesa: ");
64 vfprintf(stderr,format,args);
65 va_end(args);
66}
67
68void gl_ggiDEBUG(char *format,...)
69{
70 va_list args;
71 if (gl_ggi_debug)
72 {
73 va_start(args,format);
74 fprintf(stderr,"GGIMesa: ");
75 vfprintf(stderr,format,args);
76 va_end(args);
77 }
78}
Jon Taylorc6c06c92000-01-07 08:34:43 +000079#endif
Jon Taylor7b9c36d1999-08-23 21:13:19 +000080
81static void gl_ggiGetSize(GLcontext *ctx, GLuint *width, GLuint *height)
82{
83 *width = GGIMesa->width;
84 *height = GGIMesa->height;
85}
86
87static void gl_ggiSetIndex(GLcontext *ctx, GLuint ci)
88{
89 ggiSetGCForeground(VIS, ci);
90 GGICTX->color = (ggi_pixel)ci;
91}
92
93static void gl_ggiSetClearIndex(GLcontext *ctx, GLuint ci)
94{
95 ggiSetGCForeground(VIS, ci);
96 GGICTX->clearcolor = (ggi_pixel)ci;
97}
98
99static void gl_ggiSetColor(GLcontext *ctx, GLubyte red, GLubyte green,
100 GLubyte blue, GLubyte alpha)
101{
102 ggi_color rgb;
103 ggi_pixel col;
104
105 rgb.r = (uint16)red << SHIFT;
106 rgb.g = (uint16)green << SHIFT;
107 rgb.b = (uint16)blue << SHIFT;
108 col = ggiMapColor(VIS, &rgb);
109 ggiSetGCForeground(VIS, col);
110 GGICTX->color = col;
111}
112
113static void gl_ggiSetClearColor(GLcontext *ctx, GLubyte red, GLubyte green,
114 GLubyte blue, GLubyte alpha)
115{
116 ggi_color rgb;
117 ggi_pixel col;
118 rgb.r = (uint16)red << SHIFT;
119 rgb.g = (uint16)green << SHIFT;
120 rgb.b = (uint16)blue << SHIFT;
121 col = ggiMapColor(VIS, &rgb);
122 ggiSetGCForeground(VIS, col);
123 GGICTX->clearcolor = col;
124}
125
126static GLbitfield gl_ggiClear(GLcontext *ctx,GLbitfield mask, GLboolean all,
127 GLint x, GLint y, GLint width, GLint height)
128{
129
130 if (mask & GL_COLOR_BUFFER_BIT)
131 {
132 ggiSetGCForeground(VIS, GGICTX->clearcolor);
133
134 if (all)
135 {
136 ggiDrawBox(VIS, 0, GGIMesa->origin.y,
137 GGIMesa->width, GGIMesa->height);
138 }
139 else
140 {
141 ggiDrawBox(VIS, x, FLIP(y), width, height);
142 }
143
144 ggiSetGCForeground(VIS, GGICTX->color);
145 }
146 return mask & (~GL_COLOR_BUFFER_BIT);
147}
148
Jon Taylorc6c06c92000-01-07 08:34:43 +0000149#if 0
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000150static GLboolean gl_ggiSetBuffer(GLcontext *ctx, GLenum mode)
151{
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000152 if (mode == GL_FRONT)
Jon Taylor668b4ab1999-08-24 02:03:34 +0000153 GGICTX->active_buffer = 1;
154 else
155 GGICTX->active_buffer = 0;
156
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000157 return GL_TRUE;
158}
Jon Taylorc6c06c92000-01-07 08:34:43 +0000159#endif
160
161/* Set the buffer used for drawing */
162static GLboolean gl_ggiSetDrawBuffer(GLcontext *ctx, GLenum mode)
163{
164 if (mode == GL_FRONT_LEFT)
165 {
166 GGICTX->active_buffer = 1;
167 return GL_TRUE;
168 }
169 else if (mode == GL_BACK_LEFT)
170 {
171 GGICTX->active_buffer = 0;
172 return GL_TRUE;
173 }
174 else
175 {
176 return GL_FALSE;
177 }
178}
179
180
181/* Set the buffer used for reading */
182/* XXX support for separate read/draw buffers hasn't been tested */
183static void gl_ggiSetReadBuffer(GLcontext *ctx, GLframebuffer *buffer, GLenum mode)
184{
185 if (mode == GL_FRONT_LEFT)
186 {
187 GGICTX->active_buffer = 1;
188 }
189 else if (mode == GL_BACK_LEFT)
190 {
191 GGICTX->active_buffer = 0;
192 }
193}
194
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000195
Brian Paulb6273022000-02-17 20:52:49 +0000196static const GLubyte * gl_ggiGetString(GLcontext *ctx, GLenum name)
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000197{
Brian Paulb6273022000-02-17 20:52:49 +0000198 if (name == GL_RENDERER)
199 return (GLubyte *) "Mesa GGI";
200 else
201 return NULL;
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000202}
203
204static void gl_ggiFlush(GLcontext *ctx)
205{
206 ggiFlush(VIS);
207}
208
209static void gl_ggiSetupPointers( GLcontext *ctx )
210{
211 /* Initialize all the pointers in the DD struct. Do this whenever */
212 /* a new context is made current or we change buffers via set_buffer! */
213
Brian Paulb6273022000-02-17 20:52:49 +0000214 ctx->Driver.GetString = gl_ggiGetString;
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000215 ctx->Driver.UpdateState = gl_ggiUpdateState;
216
217 ctx->Driver.ClearIndex = gl_ggiSetClearIndex;
218 ctx->Driver.ClearColor = gl_ggiSetClearColor;
219 ctx->Driver.Clear = gl_ggiClear;
Jon Taylorc6c06c92000-01-07 08:34:43 +0000220
221 ctx->Driver.SetDrawBuffer = gl_ggiSetDrawBuffer;
222 ctx->Driver.SetReadBuffer = gl_ggiSetReadBuffer;
223
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000224 ctx->Driver.GetBufferSize = gl_ggiGetSize;
225 ctx->Driver.Finish = gl_ggiFlush;
226 ctx->Driver.Flush = gl_ggiFlush;
227
228}
229
230static int gl_ggiInitInfo(GGIMesaContext ctx, struct ggi_mesa_info *info)
231{
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000232 ggi_mode mode;
233
234 ggiGetMode(ctx->ggi_vis, &mode);
Jon Taylor668b4ab1999-08-24 02:03:34 +0000235
Jon Taylor56edca92000-03-27 04:31:15 +0000236 info->depth_bits = DEFAULT_SOFTWARE_DEPTH_BITS;
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000237 info->stencil_bits = STENCIL_BITS;
238 info->accum_bits = ACCUM_BITS;
239
240 if (info->rgb_flag)
241 {
242 info->rgb_flag = GL_TRUE;
243 info->alpha_flag = GL_FALSE;
244 info->index_bits = 0;
245
246 info->red_bits = 8;
247 info->green_bits = 8;
248 info->blue_bits = 8;
249
250 info->alpha_bits = 0;
251 }
252 else
253 {
254 info->alpha_flag = GL_FALSE;
255
256 info->index_bits = GT_SIZE(mode.graphtype);
257 info->red_bits = info->green_bits =
258 info->blue_bits = info->alpha_bits = 0;
259 }
260
261 return 0;
262}
263
Jon Taylorc6c06c92000-01-07 08:34:43 +0000264int ggiMesaInit()
265{
266 int err;
267
268 _ggimesaLibIsUp++;
269 if (_ggimesaLibIsUp > 1)
270 return 0; /* Initialize only at first call */
271
272 err = ggLoadConfig(ggimesaconffile, &_ggimesaConfigHandle);
273 if (err != GGI_OK)
274 {
275 fprintf(stderr, "GGIMesa: Couldn't open %s\n", ggimesaconffile);
276 _ggimesaLibIsUp--;
277 return err;
278 }
279
280 ggiMesaID = ggiExtensionRegister("GGIMesa", sizeof(struct mesa_ext), changed);
281
282 if (ggiMesaID < 0)
283 {
284 fprintf(stderr, "GGIMesa: failed to register as extension\n");
285 _ggimesaLibIsUp--;
286 ggFreeConfig(_ggimesaConfigHandle);
287 return ggiMesaID;
288 }
289
290 return 0;
291}
292
293
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000294GGIMesaContext GGIMesaCreateContext(void)
295{
296 GGIMesaContext ctx;
297 char *s;
298
299 s = getenv("GGIMESA_DEBUG");
300 gl_ggi_debug = (s && atoi(s));
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000301
302 if (ggiMesaInit() < 0) /* register extensions*/
303 {
304 return NULL;
305 }
306
307 ctx = (GGIMesaContext)calloc(1, sizeof(struct ggi_mesa_context));
308 if (!ctx)
309 return NULL;
310
311 ctx->gl_vis = (GLvisual *)calloc(1, sizeof(GLvisual));
312 if (!ctx->gl_vis)
313 return NULL;
314
315 ctx->viewport_init = GL_FALSE;
316 ctx->gl_vis->DBflag = GL_FALSE;
317
Brian Paulb1394fa2000-09-26 20:53:53 +0000318 ctx->gl_ctx = _mesa_create_context(ctx->gl_vis, NULL, (void *)ctx, GL_TRUE);
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000319 if (!ctx->gl_ctx)
320 return NULL;
321
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000322 return ctx;
323}
324
325void GGIMesaDestroyContext(GGIMesaContext ctx)
326{
327 if (ctx)
328 {
Brian Paulb1394fa2000-09-26 20:53:53 +0000329 _mesa_destroy_visual(ctx->gl_vis);
330 _mesa_destroy_context(ctx->gl_ctx);
331 _mesa_destroy_framebuffer(ctx->gl_buffer);
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000332 if (ctx == GGIMesa)
Jon Taylor668b4ab1999-08-24 02:03:34 +0000333 GGIMesa = NULL;
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000334 if (ctx->ggi_vis)
335 ggiExtensionDetach(ctx->ggi_vis, ggiMesaID);
336 ggiExtensionUnregister(ggiMesaID);
337 free(ctx);
338 }
339}
340
341int GGIMesaSetVisual(GGIMesaContext ctx, ggi_visual_t vis,
342 GLboolean rgb_flag, GLboolean db_flag)
343{
344 struct ggi_mesa_info info;
345 int err;
346 uint16 r,g,b;
347 ggi_color pal[256];
348 int i;
349 void *func;
350 ggi_mode mode;
351 int num_buf;
352
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000353 if (!ctx) return -1;
354 if (!vis) return -1;
355
356 if (ctx->ggi_vis)
357 ggiExtensionDetach(ctx->ggi_vis, ggiMesaID);
358
359 ctx->ggi_vis=vis;
360
361 err = ggiExtensionAttach(vis, ggiMesaID);
362 if (err < 0)
363 return -1;
364 if (err == 0)
365 changed(vis, GGI_CHG_APILIST);
366
367 if (ctx->gl_vis)
Brian Paulb1394fa2000-09-26 20:53:53 +0000368 _mesa_destroy_visual(ctx->gl_vis);
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000369
370 if (ctx->gl_buffer)
Jon Taylor1aa958b2000-10-28 10:02:44 +0000371 _mesa_destroy_framebuffer(ctx->gl_buffer);
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000372
373 info.rgb_flag = rgb_flag;
374 info.db_flag = db_flag;
375
376 err = gl_ggiInitInfo(ctx, &info);
377 if (err)
378 return -1;
379
380 gl_ggiSetupPointers(ctx->gl_ctx);
381
382 func = (void *)LIBGGI_MESAEXT(ctx->ggi_vis)->setup_driver;
383
Jon Taylor668b4ab1999-08-24 02:03:34 +0000384 if (!func)
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000385 {
Jon Taylorc6c06c92000-01-07 08:34:43 +0000386 fprintf(stderr, "setup_driver==NULL!\n");
387 fprintf(stderr, "Please check your config files!\n");
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000388 return -1;
389 }
390
391 err = LIBGGI_MESAEXT(ctx->ggi_vis)->setup_driver(ctx, &info);
392 if (err)
393 return -1;
394
Brian Paulb1394fa2000-09-26 20:53:53 +0000395 ctx->gl_vis = _mesa_create_visual(info.rgb_flag,
396 info.db_flag,
397 GL_FALSE, /*stereo*/
398 info.red_bits, info.green_bits,
399 info.blue_bits, info.alpha_bits,
400 info.index_bits,
401 info.depth_bits,
402 info.stencil_bits,
403 info.accum_bits,
404 info.accum_bits,
405 info.accum_bits,
406 info.accum_bits,
407 1);
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000408 if (!ctx->gl_vis)
409 {
Jon Taylorc6c06c92000-01-07 08:34:43 +0000410 fprintf(stderr, "Can't create gl_visual!\n");
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000411 return -1;
412 }
413
Brian Paulb1394fa2000-09-26 20:53:53 +0000414 ctx->gl_buffer = _mesa_create_framebuffer(ctx->gl_vis,
Jon Taylorc6c06c92000-01-07 08:34:43 +0000415 ctx->gl_vis->DepthBits > 0,
416 ctx->gl_vis->StencilBits > 0,
Brian Paulb2e46002000-03-31 01:07:13 +0000417 ctx->gl_vis->AccumRedBits > 0,
Jon Taylorc6c06c92000-01-07 08:34:43 +0000418 ctx->gl_vis->AlphaBits > 0);
419
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000420
421 if (!ctx->gl_buffer)
422 {
Jon Taylorc6c06c92000-01-07 08:34:43 +0000423 fprintf(stderr, "Can't create gl_buffer!\n");
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000424 return -1;
425 }
426
427 ggiGetMode(ctx->ggi_vis, &mode);
428 ctx->width = mode.visible.x;
429 ctx->height = mode.visible.y;
430 ctx->stride = mode.virt.x;
431 ctx->origin.x = 0;
Jon Taylor668b4ab1999-08-24 02:03:34 +0000432 ctx->origin.y = 0;
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000433 ctx->flip_y = ctx->origin.y + ctx->height - 1;
434
435 ctx->color = 0;
436
Jon Taylor668b4ab1999-08-24 02:03:34 +0000437 ctx->lfb[0] = ctx->lfb[1] = NULL;
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000438 num_buf = ggiDBGetNumBuffers(ctx->ggi_vis);
Jon Taylor668b4ab1999-08-24 02:03:34 +0000439
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000440 for (i = 0; i < num_buf; i++)
441 {
442 if (ggiDBGetBuffer(ctx->ggi_vis,i)->layout == blPixelLinearBuffer)
443 {
444 ctx->stride = ggiDBGetBuffer(ctx->ggi_vis, i)->buffer.plb.stride /
445 (ggiDBGetBuffer(ctx->ggi_vis, i)->buffer.plb.pixelformat->size / 8);
Jon Taylor668b4ab1999-08-24 02:03:34 +0000446 ctx->lfb[0] = ggiDBGetBuffer(ctx->ggi_vis, i)->write;
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000447 }
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000448 }
449
Jon Taylor668b4ab1999-08-24 02:03:34 +0000450 if (ctx->lfb[0] == NULL)
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000451 {
Jon Taylorc6c06c92000-01-07 08:34:43 +0000452 fprintf(stderr, "No linear frame buffer!\n");
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000453 return -1;
454 }
Jon Taylor668b4ab1999-08-24 02:03:34 +0000455
456 /* FIXME: Use separate buffers */
Jon Taylora43cfd71999-08-27 21:06:30 +0000457 ctx->lfb[1] = malloc(ctx->stride * ctx->height);
458 ctx->bufsize = (ctx->stride * ctx->height);
Jon Taylor668b4ab1999-08-24 02:03:34 +0000459
Jon Taylor1aa958b2000-10-28 10:02:44 +0000460 ctx->gl_ctx->Visual = *ctx->gl_vis;
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000461 ctx->gl_ctx->Pixel.ReadBuffer =
462 ctx->gl_ctx->Color.DrawBuffer = (db_flag) ? GL_BACK : GL_FRONT;
463
464 if (GGIMesa == ctx)
Brian Paulb1394fa2000-09-26 20:53:53 +0000465 _mesa_make_current(ctx->gl_ctx, ctx->gl_buffer);
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000466
467 if (rgb_flag && mode.graphtype==GT_8BIT)
468 {
469 for (i = r = 0; r < 8; r++)
470 for (g = 0; g < 8; g++)
471 for (b = 0; b < 4; b++, i++)
472 {
473 pal[i].r = r << (GGI_COLOR_PRECISION - 3);
474 pal[i].g = g << (GGI_COLOR_PRECISION - 3);
475 pal[i].b = b << (GGI_COLOR_PRECISION - 2);
476 }
477 ggiSetPalette(ctx->ggi_vis, 0, 256, pal);
478 }
479
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000480 return 0;
481}
482
483void GGIMesaMakeCurrent(GGIMesaContext ctx)
484{
485 if (!ctx->ggi_vis)
486 return;
487
488 GGIMesa = ctx;
Brian Paulb1394fa2000-09-26 20:53:53 +0000489 _mesa_make_current(ctx->gl_ctx, ctx->gl_buffer);
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000490
491 if (!ctx->viewport_init)
492 {
493 gl_Viewport(ctx->gl_ctx, 0, 0, ctx->width, ctx->height);
494 ctx->viewport_init = GL_TRUE;
495 }
496}
497
498
499GGIMesaContext GGIMesaGetCurrentContext(void)
500{
501 return GGIMesa;
502}
503
504/*
505 * Swap front/back buffers for current context if double buffered.
506 */
507void GGIMesaSwapBuffers(void)
508{
Jon Taylorc6c06c92000-01-07 08:34:43 +0000509 GGIMESADPRINT_CORE("GGIMesaSwapBuffers\n");
510
Keith Whitwell23caf202000-11-16 21:05:34 +0000511 _mesa_swapbuffers( GGIMesa->gl_ctx );
Jon Taylora43cfd71999-08-27 21:06:30 +0000512 gl_ggiFlush(GGIMesa->gl_ctx);
Jon Taylorc6c06c92000-01-07 08:34:43 +0000513
Jon Taylor668b4ab1999-08-24 02:03:34 +0000514 if (GGIMesa->gl_vis->DBflag)
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000515 {
Jon Taylora43cfd71999-08-27 21:06:30 +0000516 memcpy(GGIMesa->lfb[0], GGIMesa->lfb[1], GGIMesa->bufsize);
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000517 }
518}
519
520static void gl_ggiUpdateState(GLcontext *ctx)
521{
522 void *func;
523
524 func = (void *)CTX_OPMESA(ctx)->update_state;
525
526 if (!func) {
Jon Taylorc6c06c92000-01-07 08:34:43 +0000527 fprintf(stderr, "update_state == NULL!\n");
528 fprintf(stderr, "Please check your config files!\n");
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000529 ggiPanic("");
530 }
531
532 CTX_OPMESA(ctx)->update_state(ctx);
533}
534
535static int changed(ggi_visual_t vis, int whatchanged)
536{
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000537 switch (whatchanged)
538 {
539 case GGI_CHG_APILIST:
540 {
541 char api[256];
542 char args[256];
543 int i;
544 const char *fname;
545 ggi_dlhandle *lib;
546
547 for (i = 0; ggiGetAPI(vis, i, api, args) == 0; i++)
548 {
549 strcat(api, "-mesa");
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000550 fname = ggMatchConfig(_ggimesaConfigHandle, api, NULL);
551 if (fname == NULL)
552 {
553 /* No special implementation for this sublib */
554 continue;
555 }
Jon Taylorffd561e2000-06-11 20:11:55 +0000556 lib = ggiExtensionLoadDL(vis, fname, args, NULL, GGI_SYMNAME_PREFIX);
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000557 }
558 }
559 break;
560 }
561 return 0;
562}
563
Jon Taylor7b9c36d1999-08-23 21:13:19 +0000564
565int ggiMesaExit(void)
566{
567 int rc;
568
569 if (!_ggimesaLibIsUp)
570 return -1;
571
572 if (_ggimesaLibIsUp > 1)
573 {
574 /* Exit only at last call */
575 _ggimesaLibIsUp--;
576 return 0;
577 }
578
579 rc = ggiExtensionUnregister(ggiMesaID);
580 ggFreeConfig(_ggimesaConfigHandle);
581
582 _ggimesaLibIsUp = 0;
583
584 return rc;
585}
586
587static int _ggi_error(void)
588{
589 return -1;
590}
591
592int ggiMesaAttach(ggi_visual_t vis)
593{
594 int rc;
595
596 rc = ggiExtensionAttach(vis, ggiMesaID);
597 if (rc == 0)
598 {
599 /* We are creating the primary instance */
600 memset(LIBGGI_MESAEXT(vis), 0, sizeof(mesaext));
601 LIBGGI_MESAEXT(vis)->update_state = (void *)_ggi_error;
602 LIBGGI_MESAEXT(vis)->setup_driver = (void *)_ggi_error;
603
604 /* Now fake an "API change" so the right libs get loaded */
605 changed(vis, GGI_CHG_APILIST);
606 }
607
608 return rc;
609}
610
611int ggiMesaDetach(ggi_visual_t vis)
612{
613 return ggiExtensionDetach(vis, ggiMesaID);
614}
615
616
617#else
618/*
619 * Need this to provide at least one external definition when GGI is
620 * not defined on the compiler command line.
621 */
622
623int gl_ggi_dummy_function(void)
624{
625 return 0;
626}
627
628#endif