fix potential problem overwriting dma region
[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_MODE(ggi_ctx->ggi_visual)->visible.x;
77 *height = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y;
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 {
131 ggiSetGCForeground(ggi_ctx->ggi_visual, ggi_ctx->clearcolor);
132
133 if (all)
134 {
135 int w, h;
136 w = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.x;
137 h = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y;
138 ggiDrawBox(ggi_ctx->ggi_visual, 0, 0, w, h);
139 }
140 else
141 {
142 ggiDrawBox(ggi_ctx->ggi_visual, x, y, //FLIP(y),
143 width, height);
144 }
145 ggiSetGCForeground(ggi_ctx->ggi_visual, ggi_ctx->color);
146
147 mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
148 }
149 _swrast_Clear(ctx, mask, all, x, y, width, height);
150
151 }
152
153
154 /* Set the buffer used for reading */
155 /* XXX support for separate read/draw buffers hasn't been tested */
156 static GLboolean gl_ggiSetBuffer(GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit)
157 {
158 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
159
160 printf("set read %d\n", bufferBit);
161 GGIMESADPRINT_CORE("gl_ggiSetBuffer() called\n");
162
163 if (bufferBit == FRONT_LEFT_BIT)
164 {
165 ggiSetReadFrame(ggi_ctx->ggi_visual,
166 ggiGetDisplayFrame(ggi_ctx->ggi_visual));
167 ggiSetWriteFrame(ggi_ctx->ggi_visual,
168 ggiGetDisplayFrame(ggi_ctx->ggi_visual));
169 return GL_TRUE;
170 }
171 else if (bufferBit == BACK_LEFT_BIT)
172 {
173 ggiSetReadFrame(ggi_ctx->ggi_visual,
174 ggiGetDisplayFrame(ggi_ctx->ggi_visual)?0 : 1);
175 ggiSetWriteFrame(ggi_ctx->ggi_visual,
176 ggiGetDisplayFrame(ggi_ctx->ggi_visual)?0 : 1);
177 return GL_TRUE;
178 }
179 else
180 return GL_FALSE;
181 }
182
183
184 static const GLubyte * gl_ggiGetString(GLcontext *ctx, GLenum name)
185 {
186 GGIMESADPRINT_CORE("gl_ggiGetString() called\n");
187
188 if (name == GL_RENDERER)
189 return (GLubyte *) "Mesa GGI";
190 else
191 return NULL;
192 }
193
194 static void gl_ggiFlush(GLcontext *ctx)
195 {
196 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
197
198 GGIMESADPRINT_CORE("gl_ggiFlush() called\n");
199
200 ggiFlush(ggi_ctx->ggi_visual);
201 }
202
203 static void gl_ggiIndexMask(GLcontext *ctx, GLuint mask)
204 {
205 GGIMESADPRINT_CORE("gl_ggiIndexMask() called\n");
206 }
207
208 static void gl_ggiColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
209 GLboolean bmask, GLboolean amask)
210 {
211 GGIMESADPRINT_CORE("gl_ggiColorMask() called\n");
212 }
213
214 static void gl_ggiEnable(GLcontext *ctx, GLenum pname, GLboolean state)
215 {
216 GGIMESADPRINT_CORE("gl_ggiEnable() called\n");
217 }
218
219 static void gl_ggiSetupPointers(GLcontext *ctx)
220 {
221 TNLcontext *tnl;
222
223 GGIMESADPRINT_CORE("gl_ggiSetupPointers() called\n");
224
225 /* General information */
226 ctx->Driver.GetString = gl_ggiGetString;
227 ctx->Driver.GetBufferSize = gl_ggiGetSize;
228 ctx->Driver.Finish = gl_ggiFlush;
229 ctx->Driver.Flush = gl_ggiFlush;
230
231 /* Software rasterizer pixel paths */
232 ctx->Driver.Accum = _swrast_Accum;
233 ctx->Driver.Bitmap = _swrast_Bitmap;
234 ctx->Driver.Clear = gl_ggiClear;
235 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
236 ctx->Driver.CopyPixels = _swrast_CopyPixels;
237 ctx->Driver.DrawPixels = _swrast_DrawPixels;
238 ctx->Driver.ReadPixels = _swrast_ReadPixels;
239 ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
240
241 /* Software texturing */
242 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
243 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
244 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
245 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
246 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
247 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
248 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
249 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
250
251 ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
252 ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
253 ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
254 ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
255 ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
256 ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
257
258 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
259 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
260 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
261 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
262 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
263
264 /* Imaging extensions */
265 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
266 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
267 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
268 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
269
270 /* State change callbacks */
271 ctx->Driver.ClearIndex = gl_ggiSetClearIndex;
272 ctx->Driver.ClearColor = gl_ggiSetClearColor;
273 ctx->Driver.IndexMask = gl_ggiIndexMask;
274 ctx->Driver.ColorMask = gl_ggiColorMask;
275 ctx->Driver.Enable = gl_ggiEnable;
276
277 ctx->Driver.UpdateState = gl_ggiUpdateState;
278
279 /* Initialize TNL driver interface */
280 tnl = TNL_CONTEXT(ctx);
281 tnl->Driver.RunPipeline = _tnl_run_pipeline;
282
283 /* Install setup for tnl */
284 _swsetup_Wakeup(ctx);
285 }
286
287 static void get_mode_info(ggi_visual_t vis, int *r, int *g, int *b,
288 GLboolean *rgb, GLboolean *db, int *ci)
289 {
290 unsigned int i;
291
292 *r = 0;
293 *g = 0;
294 *b = 0;
295
296 for(i = 0; i < sizeof(ggi_pixel)*8; ++i){
297 int mask = 1 << i;
298 if(LIBGGI_PIXFMT(vis)->red_mask & mask)
299 ++(*r);
300 if(LIBGGI_PIXFMT(vis)->green_mask & mask)
301 ++(*g);
302 if(LIBGGI_PIXFMT(vis)->blue_mask & mask)
303 ++(*b);
304 }
305
306 *rgb = GT_SCHEME(LIBGGI_MODE(vis)->graphtype) == GT_TRUECOLOR;
307 *db = LIBGGI_MODE(vis)->frames > 1;
308 *ci = GT_SIZE(LIBGGI_MODE(vis)->graphtype);
309
310 printf("rgb (%d, %d, %d) db %d, rgb %d ci %d\n",*r,*g,*b,*db,*rgb,*ci);
311 }
312
313 int ggiMesaInit()
314 {
315 int err;
316 char *str;
317
318 GGIMESADPRINT_CORE("ggiMesaInit() called\n");
319
320 str = getenv("GGIMESA_DEBUG");
321 if (str != NULL) {
322 _ggimesaDebugState = atoi(str);
323 GGIMESADPRINT_CORE("Debugging=%d\n", _ggimesaDebugState);
324 }
325
326 str = getenv("GGIMESA_DEBUGSYNC");
327 if (str != NULL) {
328 _ggimesaDebugSync = 1;
329 }
330
331 GGIMESADPRINT_CORE("ggiMesaInit()\n");
332
333 _ggimesaLibIsUp++;
334 if (_ggimesaLibIsUp > 1)
335 return 0; /* Initialize only at first call */
336
337 err = ggLoadConfig(ggimesaconffile, &_ggimesaConfigHandle);
338 if (err != GGI_OK)
339 {
340 GGIMESADPRINT_CORE("GGIMesa: Couldn't open %s\n",
341 ggimesaconffile);
342 _ggimesaLibIsUp--;
343 return err;
344 }
345
346 ggiMesaID = ggiExtensionRegister("GGIMesa",
347 sizeof(struct ggi_mesa_ext), changed);
348
349 if (ggiMesaID < 0)
350 {
351 GGIMESADPRINT_CORE("GGIMesa: failed to register as extension\n");
352 _ggimesaLibIsUp--;
353 ggFreeConfig(_ggimesaConfigHandle);
354 return ggiMesaID;
355 }
356
357 return 0;
358 }
359
360 int ggiMesaExit(void)
361 {
362 int rc;
363
364 GGIMESADPRINT_CORE("ggiMesaExit() called\n");
365
366 if (!_ggimesaLibIsUp)
367 return -1;
368
369 if (_ggimesaLibIsUp > 1)
370 {
371 /* Exit only at last call */
372 _ggimesaLibIsUp--;
373 return 0;
374 }
375
376 rc = ggiExtensionUnregister(ggiMesaID);
377 ggFreeConfig(_ggimesaConfigHandle);
378
379 _ggimesaLibIsUp = 0;
380
381 return rc;
382 }
383
384 int ggiMesaAttach(ggi_visual_t vis)
385 {
386 int rc;
387
388 GGIMESADPRINT_CORE("ggiMesaAttach() called\n");
389
390 rc = ggiExtensionAttach(vis, ggiMesaID);
391 if (rc == 0)
392 {
393 int r, g, b, ci;
394 GLboolean rgb, db;
395 GLvisual *gl_visual;
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(gl_vis,
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
460 GGIMESADPRINT_CORE("ggiMesaCreateContext() called\n");
461
462 ctx = (ggi_mesa_context_t)malloc(sizeof(struct ggi_mesa_context));
463 if (!ctx)
464 return NULL;
465
466 ctx->ggi_visual = vis;
467 ctx->color = 0;
468
469 ctx->gl_ctx =
470 _mesa_create_context(&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual),
471 NULL, (void *) ctx, GL_FALSE);
472 if (!ctx->gl_ctx)
473 goto free_context;
474
475 _mesa_enable_sw_extensions(ctx->gl_ctx);
476
477 _swrast_CreateContext(ctx->gl_ctx);
478 _ac_CreateContext(ctx->gl_ctx);
479 _tnl_CreateContext(ctx->gl_ctx);
480 _swsetup_CreateContext(ctx->gl_ctx);
481
482 gl_ggiSetupPointers(ctx->gl_ctx);
483
484 /* Make sure that an appropriate sublib has been loaded */
485 if (!LIBGGI_MESAEXT(ctx->ggi_visual)->setup_driver){
486 GGIMESADPRINT_CORE("setup_driver==NULL!\n");
487 GGIMESADPRINT_CORE("Please check your config files!\n");
488 goto free_context;
489 }
490
491 /* Set up the sublib driver */
492 err = LIBGGI_MESAEXT(ctx->ggi_visual)->setup_driver(ctx);
493 if (err){
494 GGIMESADPRINT_CORE("setup_driver failed (err = %d)", err);
495 goto free_gl_context;
496 }
497
498 return ctx;
499
500 free_gl_context:
501 _mesa_destroy_context(ctx->gl_ctx);
502 free_context:
503 free(ctx);
504
505 return NULL;
506 }
507
508 void ggiMesaDestroyContext(ggi_mesa_context_t ctx)
509 {
510 GGIMESADPRINT_CORE("ggiMesaDestroyContext() called\n");
511
512 if(!ctx)
513 return;
514
515 _mesa_destroy_context(ctx->gl_ctx);
516 free(ctx);
517 }
518
519 void ggiMesaMakeCurrent(ggi_mesa_context_t ctx, ggi_visual_t vis)
520 {
521 GGIMESADPRINT_CORE("ggiMesaMakeCurrent(ctx = %p) called\n", ctx);
522
523 /* FIXME: clean up where are ggi_vis */
524 if (ctx->ggi_visual != vis) {
525 GGIMESADPRINT_CORE("Cannot migrate GL contexts\n");
526 return;
527 }
528
529 _mesa_make_current(ctx->gl_ctx, &LIBGGI_MESAEXT(vis)->mesa_buffer);
530
531 if (ctx->gl_ctx->Viewport.Width == 0)
532 {
533 _mesa_Viewport(0, 0,
534 LIBGGI_MODE(vis)->visible.x,
535 LIBGGI_MODE(vis)->visible.y);
536 ctx->gl_ctx->Scissor.Width = LIBGGI_MODE(vis)->visible.x;
537 ctx->gl_ctx->Scissor.Height = LIBGGI_MODE(vis)->visible.y;
538 }
539 }
540
541
542 /*
543 * Swap front/back buffers for current context if double buffered.
544 */
545 void ggiMesaSwapBuffers(void)
546 {
547 GLcontext *ctx;
548 ggi_mesa_context_t ggi_ctx;
549 ctx = _mesa_get_current_context();
550 ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
551
552 GGIMESADPRINT_CORE("ggiMesaSwapBuffers() called\n");
553
554 _mesa_notifySwapBuffers(ctx);
555 gl_ggiFlush(ctx);
556
557 ggiSetDisplayFrame(ggi_ctx->ggi_visual,
558 !ggiGetDisplayFrame(ggi_ctx->ggi_visual));
559 ggiSetWriteFrame(ggi_ctx->ggi_visual,
560 !ggiGetWriteFrame(ggi_ctx->ggi_visual));
561 ggiSetReadFrame(ggi_ctx->ggi_visual,
562 !ggiGetReadFrame(ggi_ctx->ggi_visual));
563
564 GGIMESADPRINT_CORE("swap disp: %d, write %d\n",
565 ggiGetDisplayFrame(ggi_ctx->ggi_visual),
566 ggiGetWriteFrame(ggi_ctx->ggi_visual));
567 }
568
569 static void gl_ggiUpdateState(GLcontext *ctx, GLuint new_state)
570 {
571 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
572
573 GGIMESADPRINT_CORE("gl_ggiUpdateState() called\n");
574
575 /* Propogate statechange information to swrast and swrast_setup
576 * modules. The GGI driver has no internal GL-dependent state.
577 */
578 _swrast_InvalidateState(ctx, new_state);
579 _swsetup_InvalidateState(ctx, new_state);
580 _tnl_InvalidateState(ctx, new_state);
581
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 {
600 case GGI_CHG_APILIST:
601 {
602 char api[256];
603 char args[256];
604 int i;
605 const char *fname;
606 ggi_dlhandle *lib;
607 GLvisual *gl_vis=&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual);
608 GLframebuffer *gl_fb = &(LIBGGI_MESAEXT(vis)->mesa_buffer);
609
610 /* Initialize the framebuffer to provide all necessary
611 buffers in software. The target libraries that are loaded
612 next are free to modify this according to their
613 capabilities.
614 */
615 /* FIXME: if the target changes capabilities we'll leak
616 swrast's memory !!! Need to deallocate first */
617 _mesa_initialize_framebuffer(gl_fb, gl_vis,
618 gl_vis->depthBits > 0,
619 gl_vis->stencilBits > 0,
620 gl_vis->accumRedBits > 0,
621 gl_vis->alphaBits > 0);
622
623 for (i = 0; ggiGetAPI(vis, i, api, args) == 0; i++)
624 {
625 strcat(api, "-mesa");
626 fname = ggMatchConfig(_ggimesaConfigHandle, api, NULL);
627 if (fname == NULL)
628 {
629 /* No special implementation for this sublib */
630 continue;
631 }
632 lib = ggiExtensionLoadDL(vis, fname, args, NULL,
633 GGI_SYMNAME_PREFIX);
634 }
635
636 /* The targets have cleared everything they can do from
637 the framebuffer structure so we provide the rest in sw
638 */
639 _swrast_alloc_buffers(gl_fb);
640
641 break;
642 }
643 }
644 return 0;
645 }
646