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