#include fixes
[mesa.git] / src / mesa / drivers / ggi / ggimesa.c
1 /* GGI-Driver for MESA
2 *
3 * Copyright (C) 1997-1998 Uwe Maurer - uwe_maurer@t-online.de
4 * 2002 Filip Spacek
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * ---------------------------------------------------------------------
20 * This code was derived from the following source of information:
21 *
22 * svgamesa.c and ddsample.c by Brian Paul
23 *
24 */
25
26 #ifdef HAVE_CONFIG_H
27 #include "conf.h"
28 #endif
29
30 #include <ggi/mesa/ggimesa_int.h>
31 #include <ggi/mesa/debug.h>
32 #include "extensions.h"
33 #include "colormac.h"
34 #include "imports.h"
35 #include "matrix.h"
36 #include "swrast/swrast.h"
37 #include "swrast_setup/swrast_setup.h"
38 #include "tnl/tnl.h"
39 #include "tnl/t_context.h"
40 #include "tnl/t_pipeline.h"
41 #include "array_cache/acache.h"
42 #include "texformat.h"
43 #include "texstore.h"
44
45 ggi_extid ggiMesaID = -1;
46 static int _ggimesaLibIsUp = 0;
47 static void *_ggimesaConfigHandle;
48
49 static char ggimesaconffile[] = GGIMESACONFFILE;
50
51 int _ggimesaDebugSync = 0;
52 uint32 _ggimesaDebugState = 0;
53
54 static void gl_ggiUpdateState(GLcontext *ctx, GLuint new_state);
55 static int changed(ggi_visual_t vis, int whatchanged);
56
57
58 static int _ggi_error(void)
59 {
60 GGIMESADPRINT_CORE("_ggi_error() called\n");
61
62 return -1;
63 }
64
65 static void gl_ggiGetSize(GLframebuffer *fb, GLuint *width, GLuint *height)
66 {
67 /* FIXME: this is a hack to work around the new interface */
68 GLcontext *ctx;
69 ggi_mesa_context_t ggi_ctx;
70 ctx = _mesa_get_current_context();
71 ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
72
73 GGIMESADPRINT_CORE("gl_ggiGetSize() called\n");
74
75 *width = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.x;
76 *height = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y;
77 printf("returning %d, %d\n", *width, *height);
78 }
79
80 static void gl_ggiSetIndex(GLcontext *ctx, GLuint ci)
81 {
82 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
83
84 GGIMESADPRINT_CORE("gl_ggiSetIndex() called\n");
85
86 ggiSetGCForeground(ggi_ctx->ggi_visual, ci);
87 ggi_ctx->color = (ggi_pixel)ci;
88 }
89
90 static void gl_ggiSetClearIndex(GLcontext *ctx, GLuint ci)
91 {
92 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
93
94 GGIMESADPRINT_CORE("gl_ggiSetClearIndex() called\n");
95
96 ggiSetGCForeground(ggi_ctx->ggi_visual, ci);
97 ggi_ctx->clearcolor = (ggi_pixel)ci;
98 }
99
100 static void gl_ggiSetClearColor(GLcontext *ctx, const GLfloat color[4])
101 {
102 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
103 ggi_color rgb;
104 ggi_pixel col;
105 GLubyte byteColor[3];
106
107 GGIMESADPRINT_CORE("gl_ggiSetClearColor() called\n");
108
109 CLAMPED_FLOAT_TO_UBYTE(byteColor[0], color[0]);
110 CLAMPED_FLOAT_TO_UBYTE(byteColor[1], color[1]);
111 CLAMPED_FLOAT_TO_UBYTE(byteColor[2], color[2]);
112
113 rgb.r = (uint16)byteColor[0] << SHIFT;
114 rgb.g = (uint16)byteColor[1] << SHIFT;
115 rgb.b = (uint16)byteColor[2] << SHIFT;
116 col = ggiMapColor(ggi_ctx->ggi_visual, &rgb);
117 ggiSetGCForeground(ggi_ctx->ggi_visual, col);
118 ggi_ctx->clearcolor = col;
119 }
120
121 static void gl_ggiClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
122 GLint x, GLint y, GLint width, GLint height)
123 {
124 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
125
126 GGIMESADPRINT_CORE("gl_ggiClear() called\n");
127
128 if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT))
129 {
130 ggiSetGCForeground(ggi_ctx->ggi_visual, ggi_ctx->clearcolor);
131
132 if (all)
133 {
134 int w, h;
135 w = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.x;
136 h = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y;
137 ggiDrawBox(ggi_ctx->ggi_visual, 0, 0, w, h);
138 }
139 else
140 {
141 ggiDrawBox(ggi_ctx->ggi_visual, x, y, //FLIP(y),
142 width, height);
143 }
144 ggiSetGCForeground(ggi_ctx->ggi_visual, ggi_ctx->color);
145
146 mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
147 }
148 _swrast_Clear(ctx, mask, all, x, y, width, height);
149
150 }
151
152
153 /* Set the buffer used for reading */
154 /* XXX support for separate read/draw buffers hasn't been tested */
155 static GLboolean gl_ggiSetBuffer(GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit)
156 {
157 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
158
159 printf("set read %d\n", bufferBit);
160 GGIMESADPRINT_CORE("gl_ggiSetBuffer() called\n");
161
162 if (bufferBit == FRONT_LEFT_BIT)
163 {
164 ggiSetReadFrame(ggi_ctx->ggi_visual,
165 ggiGetDisplayFrame(ggi_ctx->ggi_visual));
166 ggiSetWriteFrame(ggi_ctx->ggi_visual,
167 ggiGetDisplayFrame(ggi_ctx->ggi_visual));
168 return GL_TRUE;
169 }
170 else if (bufferBit == BACK_LEFT_BIT)
171 {
172 ggiSetReadFrame(ggi_ctx->ggi_visual,
173 ggiGetDisplayFrame(ggi_ctx->ggi_visual)?0 : 1);
174 ggiSetWriteFrame(ggi_ctx->ggi_visual,
175 ggiGetDisplayFrame(ggi_ctx->ggi_visual)?0 : 1);
176 return GL_TRUE;
177 }
178 else
179 return GL_FALSE;
180 }
181
182
183 static const GLubyte * gl_ggiGetString(GLcontext *ctx, GLenum name)
184 {
185 GGIMESADPRINT_CORE("gl_ggiGetString() called\n");
186
187 if (name == GL_RENDERER)
188 return (GLubyte *) "Mesa GGI";
189 else
190 return NULL;
191 }
192
193 static void gl_ggiFlush(GLcontext *ctx)
194 {
195 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
196
197 GGIMESADPRINT_CORE("gl_ggiFlush() called\n");
198
199 ggiFlush(ggi_ctx->ggi_visual);
200 }
201
202 static void gl_ggiIndexMask(GLcontext *ctx, GLuint mask)
203 {
204 GGIMESADPRINT_CORE("gl_ggiIndexMask() called\n");
205 }
206
207 static void gl_ggiColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
208 GLboolean bmask, GLboolean amask)
209 {
210 GGIMESADPRINT_CORE("gl_ggiColorMask() called\n");
211 }
212
213 static void gl_ggiEnable(GLcontext *ctx, GLenum pname, GLboolean state)
214 {
215 GGIMESADPRINT_CORE("gl_ggiEnable() called\n");
216 }
217
218 static void gl_ggiSetupPointers(GLcontext *ctx)
219 {
220 TNLcontext *tnl;
221
222 GGIMESADPRINT_CORE("gl_ggiSetupPointers() called\n");
223
224 /* General information */
225 ctx->Driver.GetString = gl_ggiGetString;
226 ctx->Driver.GetBufferSize = gl_ggiGetSize;
227 ctx->Driver.Finish = gl_ggiFlush;
228 ctx->Driver.Flush = gl_ggiFlush;
229
230 /* Software rasterizer pixel paths */
231 ctx->Driver.Accum = _swrast_Accum;
232 ctx->Driver.Bitmap = _swrast_Bitmap;
233 ctx->Driver.Clear = gl_ggiClear;
234 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
235 ctx->Driver.CopyPixels = _swrast_CopyPixels;
236 ctx->Driver.DrawPixels = _swrast_DrawPixels;
237 ctx->Driver.ReadPixels = _swrast_ReadPixels;
238 ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
239
240 /* Software texturing */
241 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
242 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
243 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
244 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
245 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
246 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
247 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
248 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
249
250 ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
251 ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
252 ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
253 ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
254 ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
255 ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
256
257 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
258 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
259 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
260 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
261 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
262
263 /* Imaging extensions */
264 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
265 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
266 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
267 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
268
269 /* State change callbacks */
270 ctx->Driver.ClearIndex = gl_ggiSetClearIndex;
271 ctx->Driver.ClearColor = gl_ggiSetClearColor;
272 ctx->Driver.IndexMask = gl_ggiIndexMask;
273 ctx->Driver.ColorMask = gl_ggiColorMask;
274 ctx->Driver.Enable = gl_ggiEnable;
275
276 ctx->Driver.UpdateState = gl_ggiUpdateState;
277
278 /* Initialize TNL driver interface */
279 tnl = TNL_CONTEXT(ctx);
280 tnl->Driver.RunPipeline = _tnl_run_pipeline;
281
282 /* Install setup for tnl */
283 _swsetup_Wakeup(ctx);
284 }
285
286 static void get_mode_info(ggi_visual_t vis, int *r, int *g, int *b,
287 GLboolean *rgb, GLboolean *db, int *ci)
288 {
289 int i;
290
291 *r = 0;
292 *g = 0;
293 *b = 0;
294
295 for(i = 0; i < sizeof(ggi_pixel)*8; ++i){
296 int mask = 1 << i;
297 if(LIBGGI_PIXFMT(vis)->red_mask & mask)
298 ++(*r);
299 if(LIBGGI_PIXFMT(vis)->green_mask & mask)
300 ++(*g);
301 if(LIBGGI_PIXFMT(vis)->blue_mask & mask)
302 ++(*b);
303 }
304
305 *rgb = GT_SCHEME(LIBGGI_MODE(vis)->graphtype) == GT_TRUECOLOR;
306 *db = LIBGGI_MODE(vis)->frames > 1;
307 *ci = GT_SIZE(LIBGGI_MODE(vis)->graphtype);
308
309 printf("rgb (%d, %d, %d) db %d, rgb %d ci %d\n",*r,*g,*b,*db,*rgb,*ci);
310 }
311
312 int ggiMesaInit()
313 {
314 int err;
315 char *str;
316
317 GGIMESADPRINT_CORE("ggiMesaInit() called\n");
318
319 str = getenv("GGIMESA_DEBUG");
320 if (str != NULL) {
321 _ggimesaDebugState = atoi(str);
322 GGIMESADPRINT_CORE("Debugging=%d\n", _ggimesaDebugState);
323 }
324
325 str = getenv("GGIMESA_DEBUGSYNC");
326 if (str != NULL) {
327 _ggimesaDebugSync = 1;
328 }
329
330 GGIMESADPRINT_CORE("ggiMesaInit()\n");
331
332 _ggimesaLibIsUp++;
333 if (_ggimesaLibIsUp > 1)
334 return 0; /* Initialize only at first call */
335
336 err = ggLoadConfig(ggimesaconffile, &_ggimesaConfigHandle);
337 if (err != GGI_OK)
338 {
339 GGIMESADPRINT_CORE("GGIMesa: Couldn't open %s\n",
340 ggimesaconffile);
341 _ggimesaLibIsUp--;
342 return err;
343 }
344
345 ggiMesaID = ggiExtensionRegister("GGIMesa",
346 sizeof(struct ggi_mesa_ext), changed);
347
348 if (ggiMesaID < 0)
349 {
350 GGIMESADPRINT_CORE("GGIMesa: failed to register as extension\n");
351 _ggimesaLibIsUp--;
352 ggFreeConfig(_ggimesaConfigHandle);
353 return ggiMesaID;
354 }
355
356 return 0;
357 }
358
359 int ggiMesaExit(void)
360 {
361 int rc;
362
363 GGIMESADPRINT_CORE("ggiMesaExit() called\n");
364
365 if (!_ggimesaLibIsUp)
366 return -1;
367
368 if (_ggimesaLibIsUp > 1)
369 {
370 /* Exit only at last call */
371 _ggimesaLibIsUp--;
372 return 0;
373 }
374
375 rc = ggiExtensionUnregister(ggiMesaID);
376 ggFreeConfig(_ggimesaConfigHandle);
377
378 _ggimesaLibIsUp = 0;
379
380 return rc;
381 }
382
383 int ggiMesaAttach(ggi_visual_t vis)
384 {
385 int rc;
386
387 GGIMESADPRINT_CORE("ggiMesaAttach() called\n");
388
389 rc = ggiExtensionAttach(vis, ggiMesaID);
390 if (rc == 0)
391 {
392 int r, g, b, ci;
393 GLboolean rgb, db;
394 GLvisual *gl_visual;
395 GLframebuffer *gl_fb;
396
397 /* We are creating the primary instance */
398 memset(LIBGGI_MESAEXT(vis), 0, sizeof(struct ggi_mesa_ext));
399 LIBGGI_MESAEXT(vis)->update_state = (void *)_ggi_error;
400 LIBGGI_MESAEXT(vis)->setup_driver = (void *)_ggi_error;
401
402 /* Initialize default mesa visual */
403 get_mode_info(vis, &r, &g, &b, &rgb, &db, &ci);
404 gl_visual = &(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual);
405 _mesa_initialize_visual(gl_visual,
406 rgb, db, 0 /* No stereo */,
407 r, g, b, 0 /* No alpha */, ci,
408 0 /* No depth */, 0 /* No stencil */,
409 0, 0, 0, 0 /* No accum */, 0);
410
411 /* Now fake an "API change" so the right libs get loaded */
412 changed(vis, GGI_CHG_APILIST);
413 }
414
415 return rc;
416 }
417
418 int ggiMesaDetach(ggi_visual_t vis)
419 {
420 GGIMESADPRINT_CORE("ggiMesaDetach() called\n");
421
422 return ggiExtensionDetach(vis, ggiMesaID);
423 }
424
425 int ggiMesaExtendVisual(ggi_visual_t vis, GLboolean alpha_flag,
426 GLboolean stereo_flag, GLint depth_size,
427 GLint stencil_size, GLint accum_red_size,
428 GLint accum_green_size, GLint accum_blue_size,
429 GLint accum_alpha_size, GLint num_samples)
430 {
431 GLvisual *gl_vis = &(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual);
432 int r, g, b, ci;
433 GLboolean db, rgb;
434
435 get_mode_info(vis, &r, &g, &b, &rgb, &db, &ci);
436
437 /* Initialize the visual with the provided information */
438 _mesa_initialize_visual(&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual),
439 rgb, db, stereo_flag,
440 r, g, b, 0 /* FIXME */, ci,
441 depth_size, stencil_size,
442 accum_red_size, accum_green_size,
443 accum_blue_size, accum_alpha_size, 0);
444
445 /* Now fake an "API change" so the right libs get loaded. After all,
446 extending the visual by all these new buffers could be considered
447 a "mode change" which requires an "API change".
448 */
449 changed(vis, GGI_CHG_APILIST);
450
451 return 0;
452 }
453
454
455 ggi_mesa_context_t ggiMesaCreateContext(ggi_visual_t vis)
456 {
457 ggi_mesa_context_t ctx;
458 int err;
459 ggi_color pal[256];
460 int i;
461
462 GGIMESADPRINT_CORE("ggiMesaCreateContext() called\n");
463
464 ctx = (ggi_mesa_context_t)malloc(sizeof(struct ggi_mesa_context));
465 if (!ctx)
466 return NULL;
467
468 ctx->ggi_visual = vis;
469 ctx->color = 0;
470
471 ctx->gl_ctx =
472 _mesa_create_context(&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual),
473 NULL, (void *) ctx, GL_FALSE);
474 if (!ctx->gl_ctx)
475 goto free_context;
476
477 _mesa_enable_sw_extensions(ctx->gl_ctx);
478
479 _swrast_CreateContext(ctx->gl_ctx);
480 _ac_CreateContext(ctx->gl_ctx);
481 _tnl_CreateContext(ctx->gl_ctx);
482 _swsetup_CreateContext(ctx->gl_ctx);
483
484 gl_ggiSetupPointers(ctx->gl_ctx);
485
486 /* Make sure that an appropriate sublib has been loaded */
487 if (!LIBGGI_MESAEXT(ctx->ggi_visual)->setup_driver){
488 GGIMESADPRINT_CORE("setup_driver==NULL!\n");
489 GGIMESADPRINT_CORE("Please check your config files!\n");
490 goto free_context;
491 }
492
493 /* Set up the sublib driver */
494 err = LIBGGI_MESAEXT(ctx->ggi_visual)->setup_driver(ctx);
495 if (err){
496 GGIMESADPRINT_CORE("setup_driver failed (err = %d)", err);
497 goto free_gl_context;
498 }
499
500 return ctx;
501
502 free_gl_context:
503 _mesa_destroy_context(ctx->gl_ctx);
504 free_context:
505 free(ctx);
506
507 return NULL;
508 }
509
510 void ggiMesaDestroyContext(ggi_mesa_context_t ctx)
511 {
512 GGIMESADPRINT_CORE("ggiMesaDestroyContext() called\n");
513
514 if(!ctx)
515 return;
516
517 _mesa_destroy_context(ctx->gl_ctx);
518 free(ctx);
519 }
520
521 void ggiMesaMakeCurrent(ggi_mesa_context_t ctx, ggi_visual_t vis)
522 {
523 GGIMESADPRINT_CORE("ggiMesaMakeCurrent(ctx = %p) called\n", ctx);
524
525 /* FIXME: clean up where are ggi_vis */
526 if (ctx->ggi_visual != vis) {
527 GGIMESADPRINT_CORE("Cannot migrate GL contexts\n");
528 return;
529 }
530
531 _mesa_make_current(ctx->gl_ctx, &LIBGGI_MESAEXT(vis)->mesa_buffer);
532
533 if (ctx->gl_ctx->Viewport.Width == 0)
534 {
535 _mesa_Viewport(0, 0,
536 LIBGGI_MODE(vis)->visible.x,
537 LIBGGI_MODE(vis)->visible.y);
538 ctx->gl_ctx->Scissor.Width = LIBGGI_MODE(vis)->visible.x;
539 ctx->gl_ctx->Scissor.Height = LIBGGI_MODE(vis)->visible.y;
540 }
541 }
542
543
544 /*
545 * Swap front/back buffers for current context if double buffered.
546 */
547 void ggiMesaSwapBuffers(void)
548 {
549 GLcontext *ctx;
550 ggi_mesa_context_t ggi_ctx;
551 ctx = _mesa_get_current_context();
552 ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
553
554 GGIMESADPRINT_CORE("ggiMesaSwapBuffers() called\n");
555
556 _mesa_notifySwapBuffers(ctx);
557 gl_ggiFlush(ctx);
558
559 ggiSetDisplayFrame(ggi_ctx->ggi_visual,
560 !ggiGetDisplayFrame(ggi_ctx->ggi_visual));
561 ggiSetWriteFrame(ggi_ctx->ggi_visual,
562 !ggiGetWriteFrame(ggi_ctx->ggi_visual));
563 ggiSetReadFrame(ggi_ctx->ggi_visual,
564 !ggiGetReadFrame(ggi_ctx->ggi_visual));
565
566 GGIMESADPRINT_CORE("swap disp: %d, write %d\n",
567 ggiGetDisplayFrame(ggi_ctx->ggi_visual),
568 ggiGetWriteFrame(ggi_ctx->ggi_visual));
569 }
570
571 static void gl_ggiUpdateState(GLcontext *ctx, GLuint new_state)
572 {
573 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
574
575 GGIMESADPRINT_CORE("gl_ggiUpdateState() called\n");
576
577 /* Propogate statechange information to swrast and swrast_setup
578 * modules. The GGI driver has no internal GL-dependent state.
579 */
580 _swrast_InvalidateState(ctx, new_state);
581 _swsetup_InvalidateState(ctx, new_state);
582 _tnl_InvalidateState(ctx, new_state);
583
584 if (!LIBGGI_MESAEXT(ggi_ctx->ggi_visual)->update_state) {
585 GGIMESADPRINT_CORE("update_state == NULL!\n");
586 GGIMESADPRINT_CORE("Please check your config files!\n");
587 ggiPanic("");
588 }
589
590 LIBGGI_MESAEXT(ggi_ctx->ggi_visual)->update_state(ggi_ctx);
591 }
592
593 static int changed(ggi_visual_t vis, int whatchanged)
594 {
595 GLcontext *ctx;
596 ctx = _mesa_get_current_context();
597
598 GGIMESADPRINT_CORE("changed() called\n");
599
600 switch (whatchanged)
601 {
602 case GGI_CHG_APILIST:
603 {
604 char api[256];
605 char args[256];
606 int i;
607 const char *fname;
608 ggi_dlhandle *lib;
609 GLvisual *gl_vis=&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual);
610 GLframebuffer *gl_fb = &(LIBGGI_MESAEXT(vis)->mesa_buffer);
611
612 /* Initialize the framebuffer to provide all necessary
613 buffers in software. The target libraries that are loaded
614 next are free to modify this according to their
615 capabilities.
616 */
617 /* FIXME: if the target changes capabilities we'll leak
618 swrast's memory !!! Need to deallocate first */
619 _mesa_initialize_framebuffer(gl_fb, gl_vis,
620 gl_vis->depthBits > 0,
621 gl_vis->stencilBits > 0,
622 gl_vis->accumRedBits > 0,
623 gl_vis->alphaBits > 0);
624
625 for (i = 0; ggiGetAPI(vis, i, api, args) == 0; i++)
626 {
627 strcat(api, "-mesa");
628 fname = ggMatchConfig(_ggimesaConfigHandle, api, NULL);
629 if (fname == NULL)
630 {
631 /* No special implementation for this sublib */
632 continue;
633 }
634 lib = ggiExtensionLoadDL(vis, fname, args, NULL,
635 GGI_SYMNAME_PREFIX);
636 }
637
638 /* The targets have cleared everything they can do from
639 the framebuffer structure so we provide the rest in sw
640 */
641 _swrast_alloc_buffers(gl_fb);
642
643 break;
644 }
645 }
646 return 0;
647 }
648