*** empty log message ***

This commit is contained in:
Jon Taylor 1999-08-23 21:13:19 +00:00
parent 72fc9a527d
commit 7b9c36d568
1 changed files with 607 additions and 0 deletions

View File

@ -0,0 +1,607 @@
/* GGI-Driver for MESA
*
* Copyright (C) 1997-1998 Uwe Maurer - uwe_maurer@t-online.de
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* ---------------------------------------------------------------------
* This code was derived from the following source of information:
*
* svgamesa.c and ddsample.c by Brian Paul
*
*/
#ifdef HAVE_CONFIG_H
#include "conf.h"
#endif
#ifdef GGI
#include <ggi/mesa/ggimesa_int.h>
#undef VIS
#undef FLIP
#define VIS (GGIMesa->ggi_vis)
#define FLIP(y) (GGIMesa->flip_y-(y))
GGIMesaContext GGIMesa = NULL; /* the current context */
ggi_extid ggiMesaID = -1;
static int _ggimesaLibIsUp = 0;
static void *_ggimesaConfigHandle;
/* FIXME: These should really be defined in the make system using -Dxxx */
#define GGIMESACONFFILE "/usr/local/etc/ggi/ggimesa.conf"
#define GGIMESATAGLEN 0
static char ggimesaconfstub[512] = GGIMESACONFFILE;
static char *ggimesaconffile = ggimesaconfstub + GGIMESATAGLEN;
int gl_ggi_init = GL_FALSE;
int gl_ggi_debug = GL_FALSE;
static void gl_ggiUpdateState(GLcontext *ctx);
static int changed(ggi_visual_t vis, int whatchanged);
/* FIXME: Move this debugging stuff to include/ggi/mesa/internal/ */
void gl_ggiPrint(char *format,...)
{
va_list args;
va_start(args,format);
fprintf(stderr,"GGIMesa: ");
vfprintf(stderr,format,args);
va_end(args);
}
void gl_ggiDEBUG(char *format,...)
{
va_list args;
if (gl_ggi_debug)
{
va_start(args,format);
fprintf(stderr,"GGIMesa: ");
vfprintf(stderr,format,args);
va_end(args);
}
}
static void gl_ggiGetSize(GLcontext *ctx, GLuint *width, GLuint *height)
{
*width = GGIMesa->width;
*height = GGIMesa->height;
}
static void gl_ggiSetIndex(GLcontext *ctx, GLuint ci)
{
ggiSetGCForeground(VIS, ci);
GGICTX->color = (ggi_pixel)ci;
}
static void gl_ggiSetClearIndex(GLcontext *ctx, GLuint ci)
{
ggiSetGCForeground(VIS, ci);
GGICTX->clearcolor = (ggi_pixel)ci;
}
static void gl_ggiSetColor(GLcontext *ctx, GLubyte red, GLubyte green,
GLubyte blue, GLubyte alpha)
{
ggi_color rgb;
ggi_pixel col;
rgb.r = (uint16)red << SHIFT;
rgb.g = (uint16)green << SHIFT;
rgb.b = (uint16)blue << SHIFT;
col = ggiMapColor(VIS, &rgb);
ggiSetGCForeground(VIS, col);
GGICTX->color = col;
}
static void gl_ggiSetClearColor(GLcontext *ctx, GLubyte red, GLubyte green,
GLubyte blue, GLubyte alpha)
{
ggi_color rgb;
ggi_pixel col;
rgb.r = (uint16)red << SHIFT;
rgb.g = (uint16)green << SHIFT;
rgb.b = (uint16)blue << SHIFT;
col = ggiMapColor(VIS, &rgb);
ggiSetGCForeground(VIS, col);
GGICTX->clearcolor = col;
}
static GLbitfield gl_ggiClear(GLcontext *ctx,GLbitfield mask, GLboolean all,
GLint x, GLint y, GLint width, GLint height)
{
if (mask & GL_COLOR_BUFFER_BIT)
{
ggiSetGCForeground(VIS, GGICTX->clearcolor);
if (all)
{
ggiDrawBox(VIS, 0, GGIMesa->origin.y,
GGIMesa->width, GGIMesa->height);
}
else
{
ggiDrawBox(VIS, x, FLIP(y), width, height);
}
ggiSetGCForeground(VIS, GGICTX->color);
}
return mask & (~GL_COLOR_BUFFER_BIT);
}
static GLboolean gl_ggiSetBuffer(GLcontext *ctx, GLenum mode)
{
int y;
/*
if (mode == GL_FRONT)
gl_ggiPrint("GL_FRONT\n");
else
gl_ggiPrint("GL_BACK\n");
*/
if (mode == GL_FRONT)
{
y = (GGICTX->origin.y) ? 0 : GGICTX->height;
}
else
{
y = GGICTX->origin.y;
}
GGICTX->flip_y = y + GGICTX->height - 1;
return GL_TRUE;
}
static const char * gl_ggiRendererString(void)
{
return "GGI";
}
static void gl_ggiFlush(GLcontext *ctx)
{
ggiFlush(VIS);
}
static void gl_ggiSetupPointers( GLcontext *ctx )
{
/* Initialize all the pointers in the DD struct. Do this whenever */
/* a new context is made current or we change buffers via set_buffer! */
ctx->Driver.RendererString = gl_ggiRendererString;
ctx->Driver.UpdateState = gl_ggiUpdateState;
ctx->Driver.ClearIndex = gl_ggiSetClearIndex;
ctx->Driver.ClearColor = gl_ggiSetClearColor;
ctx->Driver.Clear = gl_ggiClear;
ctx->Driver.Index = gl_ggiSetIndex;
ctx->Driver.Color = gl_ggiSetColor;
ctx->Driver.SetBuffer = gl_ggiSetBuffer;
ctx->Driver.GetBufferSize = gl_ggiGetSize;
ctx->Driver.Finish = gl_ggiFlush;
ctx->Driver.Flush = gl_ggiFlush;
}
static int gl_ggiInitInfo(GGIMesaContext ctx, struct ggi_mesa_info *info)
{
int virty,visy,err;
ggi_mode mode;
ggiGetMode(ctx->ggi_vis, &mode);
if (info->db_flag)
{
virty = mode.virt.y;
visy = mode.visible.y;
if (virty < 2 * visy)
{
gl_ggiPrint(" visible y %i, virtual y %i\n",visy,virty);
gl_ggiPrint("ggiInitInfo: no doublebuffer possible!\n");
return -1;
}
}
info->depth_bits = DEPTH_BITS;
info->stencil_bits = STENCIL_BITS;
info->accum_bits = ACCUM_BITS;
if (info->rgb_flag)
{
info->rgb_flag = GL_TRUE;
info->alpha_flag = GL_FALSE;
info->index_bits = 0;
info->red_bits = 8;
info->green_bits = 8;
info->blue_bits = 8;
info->alpha_bits = 0;
}
else
{
info->alpha_flag = GL_FALSE;
info->index_bits = GT_SIZE(mode.graphtype);
info->red_bits = info->green_bits =
info->blue_bits = info->alpha_bits = 0;
}
return 0;
}
GGIMesaContext GGIMesaCreateContext(void)
{
GGIMesaContext ctx;
char *s;
s = getenv("GGIMESA_DEBUG");
gl_ggi_debug = (s && atoi(s));
gl_ggiDEBUG("GGIMesaCreateContext:\n");
if (ggiMesaInit() < 0) /* register extensions*/
{
return NULL;
}
ctx = (GGIMesaContext)calloc(1, sizeof(struct ggi_mesa_context));
if (!ctx)
return NULL;
ctx->gl_vis = (GLvisual *)calloc(1, sizeof(GLvisual));
if (!ctx->gl_vis)
return NULL;
ctx->viewport_init = GL_FALSE;
ctx->gl_vis->DBflag = GL_FALSE;
ctx->gl_ctx = gl_create_context(ctx->gl_vis, NULL, (void *)ctx, GL_TRUE);
if (!ctx->gl_ctx)
return NULL;
gl_ggiDEBUG("GGIMesaCreateContext: done.\n");
return ctx;
}
void GGIMesaDestroyContext(GGIMesaContext ctx)
{
if (ctx)
{
gl_destroy_visual(ctx->gl_vis);
gl_destroy_context(ctx->gl_ctx);
gl_destroy_framebuffer(ctx->gl_buffer);
if (ctx == GGIMesa)
GGIMesa = NULL;
if (ctx->ggi_vis)
ggiExtensionDetach(ctx->ggi_vis, ggiMesaID);
ggiExtensionUnregister(ggiMesaID);
free(ctx);
}
}
int GGIMesaSetVisual(GGIMesaContext ctx, ggi_visual_t vis,
GLboolean rgb_flag, GLboolean db_flag)
{
struct ggi_mesa_info info;
int err;
uint16 r,g,b;
ggi_color pal[256];
int i;
void *func;
ggi_mode mode;
int num_buf;
gl_ggiDEBUG("GGIMesaSetVisual:\n");
if (!ctx) return -1;
if (!vis) return -1;
if (ctx->ggi_vis)
ggiExtensionDetach(ctx->ggi_vis, ggiMesaID);
ctx->ggi_vis=vis;
err = ggiExtensionAttach(vis, ggiMesaID);
if (err < 0)
return -1;
if (err == 0)
changed(vis, GGI_CHG_APILIST);
if (ctx->gl_vis)
gl_destroy_visual(ctx->gl_vis);
if (ctx->gl_buffer)
gl_destroy_framebuffer(ctx->gl_buffer);
info.rgb_flag = rgb_flag;
info.db_flag = db_flag;
err = gl_ggiInitInfo(ctx, &info);
if (err)
return -1;
gl_ggiSetupPointers(ctx->gl_ctx);
func = (void *)LIBGGI_MESAEXT(ctx->ggi_vis)->setup_driver;
if (!func)
{
gl_ggiPrint("setup_driver==NULL !\n");
gl_ggiPrint("Please check your config files!\n");
return -1;
}
err = LIBGGI_MESAEXT(ctx->ggi_vis)->setup_driver(ctx, &info);
if (err)
return -1;
ctx->gl_vis = gl_create_visual(info.rgb_flag,
info.alpha_flag,
info.db_flag,
GL_FALSE,
info.depth_bits,
info.stencil_bits,
info.accum_bits,
info.index_bits,
info.red_bits, info.green_bits,
info.blue_bits, info.alpha_bits);
if (!ctx->gl_vis)
{
gl_ggiPrint("Can't create gl_visual!\n");
return -1;
}
ctx->gl_buffer = gl_create_framebuffer(ctx->gl_vis);
if (!ctx->gl_buffer)
{
gl_ggiPrint("Can't create gl_buffer!!!\n");
return -1;
}
ggiGetMode(ctx->ggi_vis, &mode);
ctx->width = mode.visible.x;
ctx->height = mode.visible.y;
ctx->stride = mode.virt.x;
ctx->origin.x = 0;
ctx->origin.y = (info.db_flag) ? ctx->height : 0;
ctx->flip_y = ctx->origin.y + ctx->height - 1;
ctx->color = 0;
ctx->lfb = NULL;
num_buf = ggiDBGetNumBuffers(ctx->ggi_vis);
for (i = 0; i < num_buf; i++)
{
if (ggiDBGetBuffer(ctx->ggi_vis,i)->layout == blPixelLinearBuffer)
{
ctx->stride = ggiDBGetBuffer(ctx->ggi_vis, i)->buffer.plb.stride /
(ggiDBGetBuffer(ctx->ggi_vis, i)->buffer.plb.pixelformat->size / 8);
ctx->lfb = ggiDBGetBuffer(ctx->ggi_vis, i)->write;
}
}
if (ctx->lfb == NULL)
{
gl_ggiPrint("No linear frame buffer!\n");
return -1;
}
ctx->gl_ctx->Visual = ctx->gl_vis;
ctx->gl_ctx->Pixel.ReadBuffer =
ctx->gl_ctx->Color.DrawBuffer = (db_flag) ? GL_BACK : GL_FRONT;
if (GGIMesa == ctx)
gl_make_current(ctx->gl_ctx, ctx->gl_buffer);
if (rgb_flag && mode.graphtype==GT_8BIT)
{
for (i = r = 0; r < 8; r++)
for (g = 0; g < 8; g++)
for (b = 0; b < 4; b++, i++)
{
pal[i].r = r << (GGI_COLOR_PRECISION - 3);
pal[i].g = g << (GGI_COLOR_PRECISION - 3);
pal[i].b = b << (GGI_COLOR_PRECISION - 2);
}
ggiSetPalette(ctx->ggi_vis, 0, 256, pal);
}
gl_ggiDEBUG("GGIMesaSetVisual: done.\n");
return 0;
}
void GGIMesaMakeCurrent(GGIMesaContext ctx)
{
if (!ctx->ggi_vis)
return;
GGIMesa = ctx;
gl_make_current(ctx->gl_ctx, ctx->gl_buffer);
if (!ctx->viewport_init)
{
gl_Viewport(ctx->gl_ctx, 0, 0, ctx->width, ctx->height);
ctx->viewport_init = GL_TRUE;
}
}
GGIMesaContext GGIMesaGetCurrentContext(void)
{
return GGIMesa;
}
/*
* Swap front/back buffers for current context if double buffered.
*/
void GGIMesaSwapBuffers(void)
{
if (GGIMesa->gl_vis->DBflag)
{
ggiSetOrigin(VIS, GGIMesa->origin.x, GGIMesa->origin.y);
if (GGIMesa->origin.y)
GGIMesa->origin.y = 0;
else
GGIMesa->origin.y = GGIMesa->height;
GGIMesa->flip_y = GGIMesa->origin.y + GGIMesa->height - 1;
}
}
static void gl_ggiUpdateState(GLcontext *ctx)
{
void *func;
func = (void *)CTX_OPMESA(ctx)->update_state;
if (!func) {
gl_ggiPrint("update_state==NULL !\n");
gl_ggiPrint("Please check your config files!\n");
ggiPanic("");
}
CTX_OPMESA(ctx)->update_state(ctx);
}
static int changed(ggi_visual_t vis, int whatchanged)
{
gl_ggiDEBUG("Entered ggimesa_changed()\n");
switch (whatchanged)
{
case GGI_CHG_APILIST:
{
char api[256];
char args[256];
int i;
const char *fname;
ggi_dlhandle *lib;
for (i = 0; ggiGetAPI(vis, i, api, args) == 0; i++)
{
strcat(api, "-mesa");
gl_ggiDEBUG("api=%s, i=%d\n", api, i);
fname = ggMatchConfig(_ggimesaConfigHandle, api, NULL);
if (fname == NULL)
{
/* No special implementation for this sublib */
continue;
}
lib = ggiExtensionLoadDL(vis, fname, args, NULL);
}
}
break;
}
return 0;
}
int ggiMesaInit()
{
int err;
_ggimesaLibIsUp++;
if (_ggimesaLibIsUp > 1)
return 0; /* Initialize only at first call */
err = ggLoadConfig(ggimesaconffile, &_ggimesaConfigHandle);
if (err != GGI_OK)
{
fprintf(stderr, "GGIMesa: Couldn't open %s\n", ggimesaconffile);
_ggimesaLibIsUp--;
return err;
}
ggiMesaID = ggiExtensionRegister("GGIMesa", sizeof(struct mesa_ext), changed);
if (ggiMesaID < 0)
{
fprintf(stderr, "GGIMesa: failed to register as extension\n");
_ggimesaLibIsUp--;
ggFreeConfig(_ggimesaConfigHandle);
return ggiMesaID;
}
return 0;
}
int ggiMesaExit(void)
{
int rc;
if (!_ggimesaLibIsUp)
return -1;
if (_ggimesaLibIsUp > 1)
{
/* Exit only at last call */
_ggimesaLibIsUp--;
return 0;
}
rc = ggiExtensionUnregister(ggiMesaID);
ggFreeConfig(_ggimesaConfigHandle);
_ggimesaLibIsUp = 0;
return rc;
}
static int _ggi_error(void)
{
return -1;
}
int ggiMesaAttach(ggi_visual_t vis)
{
int rc;
rc = ggiExtensionAttach(vis, ggiMesaID);
if (rc == 0)
{
/* We are creating the primary instance */
memset(LIBGGI_MESAEXT(vis), 0, sizeof(mesaext));
LIBGGI_MESAEXT(vis)->update_state = (void *)_ggi_error;
LIBGGI_MESAEXT(vis)->setup_driver = (void *)_ggi_error;
/* Now fake an "API change" so the right libs get loaded */
changed(vis, GGI_CHG_APILIST);
}
return rc;
}
int ggiMesaDetach(ggi_visual_t vis)
{
return ggiExtensionDetach(vis, ggiMesaID);
}
#else
/*
* Need this to provide at least one external definition when GGI is
* not defined on the compiler command line.
*/
int gl_ggi_dummy_function(void)
{
return 0;
}
#endif