From: Dana Jansens Date: Tue, 27 May 2003 03:19:33 +0000 (+0000) Subject: lots of API additions that I didn't forsee until putting it into use. X-Git-Tag: gl2~90 X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=0221b7104192f6f71ca45eabf78633c70885bbb8;p=dana%2Fopenbox.git lots of API additions that I didn't forsee until putting it into use. --- diff --git a/render2/Makefile.am b/render2/Makefile.am index 9b2792d9..36a3c081 100644 --- a/render2/Makefile.am +++ b/render2/Makefile.am @@ -17,7 +17,6 @@ rendertest_SOURCES=test.c lib_LTLIBRARIES=libobrender2.la libobrender2_la_LIBADD=-lglft -L../glft libobrender2_la_SOURCES=\ - init.c \ instance.c \ color.c \ debug.c \ diff --git a/render2/instance.c b/render2/instance.c index b694721e..f48593c3 100644 --- a/render2/instance.c +++ b/render2/instance.c @@ -1,54 +1,109 @@ #include "instance.h" +#include "debug.h" +#include "glft/glft.h" #include #include -/* -void truecolor_startup(void) +static int glft_init = 0; + +static int glx_rating(Display *display, XVisualInfo *v) { - unsigned long red_mask, green_mask, blue_mask; - XImage *timage = NULL; - - timage = XCreateImage(ob_display, render_visual, render_depth, - ZPixmap, 0, NULL, 1, 1, 32, 0); - assert(timage != NULL); - /\* find the offsets for each color in the visual's masks *\/ - render_red_mask = red_mask = timage->red_mask; - render_green_mask = green_mask = timage->green_mask; - render_blue_mask = blue_mask = timage->blue_mask; - - render_red_offset = 0; - render_green_offset = 0; - render_blue_offset = 0; - - while (! (red_mask & 1)) { render_red_offset++; red_mask >>= 1; } - while (! (green_mask & 1)) { render_green_offset++; green_mask >>= 1; } - while (! (blue_mask & 1)) { render_blue_offset++; blue_mask >>= 1; } - - render_red_shift = render_green_shift = render_blue_shift = 8; - while (red_mask) { red_mask >>= 1; render_red_shift--; } - while (green_mask) { green_mask >>= 1; render_green_shift--; } - while (blue_mask) { blue_mask >>= 1; render_blue_shift--; } - XFree(timage); + int rating = 0; + int val; + RrDebug("evaluating visual %d\n", (int)v->visualid); + glXGetConfig(display, v, GLX_BUFFER_SIZE, &val); + RrDebug("buffer size %d\n", val); + + switch (val) { + case 32: + rating += 300; + break; + case 24: + rating += 200; + break; + case 16: + rating += 100; + break; + } + + glXGetConfig(display, v, GLX_LEVEL, &val); + RrDebug("level %d\n", val); + if (val != 0) + rating = -10000; + + glXGetConfig(display, v, GLX_DEPTH_SIZE, &val); + RrDebug("depth size %d\n", val); + switch (val) { + case 32: + rating += 30; + break; + case 24: + rating += 20; + break; + case 16: + rating += 10; + break; + case 0: + rating -= 10000; + } + + glXGetConfig(display, v, GLX_DOUBLEBUFFER, &val); + RrDebug("double buffer %d\n", val); + if (val) + rating++; + return rating; } -*/ -struct RrInstance *RrInstanceNew(Display *display, - int screen, - XVisualInfo visinfo) +struct RrInstance *RrInstanceNew(Display *display, int screen) { - struct RrInstance *inst; + int count, i = 0, val, best = 0, rate = 0, temp; + XVisualInfo vimatch, *vilist; + + vimatch.screen = screen; + vimatch.class = TrueColor; + vilist = XGetVisualInfo(display, VisualScreenMask | VisualClassMask, + &vimatch, &count); + + if (vilist) { + RrDebug("looking for a GL visual in %d visuals\n", count); + for (i = 0; i < count; i++) { + glXGetConfig(display, &vilist[i], GLX_USE_GL, &val); + if (val) { + temp = glx_rating(display, &vilist[i]); + if (temp > rate) { + best = i; + rate = temp; + } + } + } + } + if (rate > 0) { + struct RrInstance *inst; + + RrDebug("picked visual %d with rating %d\n", best, rate); + + if (!glft_init) { + if (!GlftInit()) + return NULL; + glft_init = 1; + } - inst = malloc(sizeof(struct RrInstance)); - inst->display = display; - inst->screen = screen; - inst->visinfo = visinfo; - inst->cmap = XCreateColormap(display, RootWindow(display, screen), - RrVisual(inst), AllocNone); - inst->glx_context = glXCreateContext(display, &visinfo, NULL, True); + inst = malloc(sizeof(struct RrInstance)); + inst->display = display; + inst->screen = screen; + inst->visinfo = vilist[best]; + inst->cmap = XCreateColormap(display, RootWindow(display, screen), + RrVisual(inst), AllocNone); + inst->glx_context = glXCreateContext(display, &vilist[best], + NULL, True); - assert(inst->glx_context); + assert(inst->glx_context); - return inst; + return inst; + } + + RrDebug("unable to find a suitable GL visual\n"); + return NULL; } void RrInstanceFree(struct RrInstance *inst) @@ -59,3 +114,18 @@ void RrInstanceFree(struct RrInstance *inst) free(inst); } } + +int RrInstanceDepth(struct RrInstance *inst) +{ + return inst->visinfo.depth; +} + +Colormap RrInstanceColormap(struct RrInstance *inst) +{ + return inst->cmap; +} + +Visual *RrInstanceVisual(struct RrInstance *inst) +{ + return inst->visinfo.visual; +} diff --git a/render2/instance.h b/render2/instance.h index da55fd81..94b194ab 100644 --- a/render2/instance.h +++ b/render2/instance.h @@ -13,12 +13,6 @@ struct RrInstance { GLXContext glx_context; }; -struct RrInstance *RrInstanceNew(Display *display, - int screen, - XVisualInfo visinfo); -void RrInstanceFree(struct RrInstance *inst); - - #define RrDisplay(i) ((i)->display) #define RrScreen(i) ((i)->screen) #define RrScreenWidth(i) (WidthOfScreen(ScreenOfDisplay((i)->display, \ diff --git a/render2/paint.c b/render2/paint.c index d37290c8..acbe8930 100644 --- a/render2/paint.c +++ b/render2/paint.c @@ -15,7 +15,9 @@ void RrPaint(struct RrSurface *sur) void RrPaintArea(struct RrSurface *sur, int x, int y, int w, int h) { struct RrInstance *inst; + struct RrSurface *p; int ok; + int surx, sury; inst = RrSurfaceInstance(sur); @@ -30,6 +32,10 @@ void RrPaintArea(struct RrSurface *sur, int x, int y, int w, int h) if (!(x + w <= RrSurfaceWidth(sur) && y + h <= RrSurfaceHeight(sur))) return; + /* XXX recurse and paint children */ + + if (!RrSurfaceVisible(sur)) return; + RrDebug("making %p, %p, %p current\n", RrDisplay(inst), RrSurfaceWindow(sur), RrContext(inst)); @@ -48,13 +54,23 @@ void RrPaintArea(struct RrSurface *sur, int x, int y, int w, int h) RrScreenHeight(inst)-RrSurfaceHeight(sur)-RrSurfaceY(sur), 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + p = sur; + surx = sury = 0; + while (p) { + surx += RrSurfaceX(p); + sury += RrSurfaceY(p); + p = p->parent; + } + switch (RrSurfaceType(sur)) { case RR_SURFACE_PLANAR: - RrPlanarPaint(sur, RrSurfaceX(sur) + x, RrSurfaceY(sur) + y, w, h); + RrPlanarPaint(sur, surx + x, sury + y, w, h); break; case RR_SURFACE_NONPLANAR: assert(0); break; + case RR_SURFACE_NONE: + break; } glXSwapBuffers(RrDisplay(inst), RrSurfaceWindow(sur)); diff --git a/render2/planar.c b/render2/planar.c index 05498bbd..945427c9 100644 --- a/render2/planar.c +++ b/render2/planar.c @@ -285,3 +285,9 @@ void RrPlanarPaint(struct RrSurface *sur, int x, int y, int w, int h) break; } } + +void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h) +{ + *w = 0; + *h = 0; +} diff --git a/render2/planar.h b/render2/planar.h index 876601c7..c22c2386 100644 --- a/render2/planar.h +++ b/render2/planar.h @@ -16,4 +16,6 @@ struct RrPlanarSurface { void RrPlanarPaint(struct RrSurface *sur, int x, int y, int w, int h); +void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h); + #endif diff --git a/render2/render.h b/render2/render.h index bdb01527..f70dfadc 100644 --- a/render2/render.h +++ b/render2/render.h @@ -4,7 +4,7 @@ #include #include -/* initialization */ +/* instances */ struct RrInstance; @@ -13,15 +13,18 @@ struct RrInstance; @param display The X Display to use. @param screen The number of the screen to use. */ -struct RrInstance *RrInit(Display *display, - int screen); +struct RrInstance *RrInstanceNew(Display *display, + int screen); /*! Destroys an instance of the library. The instance should not be used after calling this function. @param inst The instance to destroy. */ -void RrDestroy(struct RrInstance *inst); +void RrInstanceFree(struct RrInstance *inst); +int RrInstanceDepth(struct RrInstance *inst); +Colormap RrInstanceColormap(struct RrInstance *inst); +Visual *RrInstanceVisual(struct RrInstance *inst); /* colors */ @@ -72,6 +75,7 @@ int RrFontMaxCharWidth(struct RrFont *font); struct RrSurface; enum RrSurfaceType { + RR_SURFACE_NONE, RR_SURFACE_PLANAR, RR_SURFACE_NONPLANAR }; @@ -80,22 +84,27 @@ enum RrSurfaceType { copied to a new RrSurface that can render. */ struct RrSurface *RrSurfaceNewProto(enum RrSurfaceType type, int numtex); -/*! Create a new top-level RrSurface for a Window. */ +/*! Create a new top-level RrSurface for a Window. The new RrSurface defaults + to a non-visible state.*/ struct RrSurface *RrSurfaceNew(struct RrInstance *inst, enum RrSurfaceType type, Window win, int numtex); -/*! Create a new RrSurface which is a child of another. */ +/*! Create a new RrSurface which is a child of another. The new RrSurface + defaults to a visible state. */ struct RrSurface *RrSurfaceNewChild(enum RrSurfaceType type, struct RrSurface *parent, int numtex); -/*! Copy an RrSurface, creating a new top-level RrSurface for a Window. */ +/*! Copy an RrSurface, creating a new top-level RrSurface for a Window. The + new RrSurface defaults to a non-visible state.*/ struct RrSurface *RrSurfaceCopy(struct RrInstance *inst, struct RrSurface *sur, Window win); -/*! Copy an RrSurface, creating a nwe RrSurface which is a child of another. */ +/*! Copy an RrSurface, creating a nwe RrSurface which is a child of another. + The new RrSurface defaults to a visible state.*/ struct RrSurface *RrSurfaceCopyChild(struct RrSurface *sur, struct RrSurface *parent); +/*! Destroys an RrSurface. */ void RrSurfaceFree(struct RrSurface *sur); void RrSurfaceSetArea(struct RrSurface *sur, @@ -106,6 +115,12 @@ void RrSurfaceSetArea(struct RrSurface *sur, Window RrSurfaceWindow(struct RrSurface *sur); +void RrSurfaceShow(struct RrSurface *sur); +void RrSurfaceHide(struct RrSurface *sur); +int RrSurfaceVisible(struct RrSurface *sur); + +void RrSurfaceMinSize(struct RrSurface *sur, int *w, int *h); + /* planar surfaces */ /*! The options available for the background of an RrSurface */ diff --git a/render2/surface.c b/render2/surface.c index b436f6e1..3bad5ced 100644 --- a/render2/surface.c +++ b/render2/surface.c @@ -22,6 +22,7 @@ static struct RrSurface *surface_new(enum RrSurfaceType type, sur->y = 0; sur->w = 1; sur->h = 1; + sur->visible = 0; return sur; } @@ -30,7 +31,6 @@ static Window create_window(struct RrInstance *inst, Window parent) Window win = XCreateWindow(RrDisplay(inst), parent, 0, 0, 1, 1, 0, RrDepth(inst), InputOutput, RrVisual(inst), 0, NULL); - XMapWindow(RrDisplay(inst), win); return win; } @@ -43,6 +43,7 @@ struct RrSurface *RrSurfaceNewProto(enum RrSurfaceType type, sur->inst = NULL; sur->win = None; sur->parent = NULL; + sur->visible = 0; return sur; } @@ -57,6 +58,7 @@ struct RrSurface *RrSurfaceNew(struct RrInstance *inst, sur->inst = inst; sur->win = win; sur->parent = NULL; + sur->visible = 0; return sur; } @@ -74,6 +76,7 @@ struct RrSurface *RrSurfaceNewChild(enum RrSurfaceType type, sur->inst = parent->inst; sur->win = create_window(sur->inst, parent->win); sur->parent = parent; + RrSurfaceShow(sur); return sur; } @@ -91,6 +94,8 @@ static struct RrSurface *surface_copy(struct RrSurface *orig) case RR_SURFACE_NONPLANAR: assert(0); break; + case RR_SURFACE_NONE: + break; } sur->ntextures = orig->ntextures; sur->texture = malloc(sizeof(struct RrTexture) * sur->ntextures); @@ -109,6 +114,7 @@ struct RrSurface *RrSurfaceCopy(struct RrInstance *inst, sur->inst = inst; sur->win = win; sur->parent = NULL; + sur->visible = 0; return sur; } @@ -125,12 +131,16 @@ struct RrSurface *RrSurfaceCopyChild(struct RrSurface *orig, sur->inst = parent->inst; sur->win = create_window(sur->inst, parent->win); sur->parent = parent; + RrSurfaceShow(sur); return sur; } void RrSurfaceFree(struct RrSurface *sur) { + int i; if (sur) { + for (i = 0; i < sur->ntextures; ++i) + RrTextureFreeContents(&sur->texture[i]); if (sur->ntextures) free(sur->texture); if (sur->parent && sur->win) @@ -145,10 +155,15 @@ void RrSurfaceSetArea(struct RrSurface *sur, int w, int h) { + assert(w > 0 && h > 0); + if (!(w > 0 && h > 0)) return; + sur->x = x; sur->y = y; sur->w = w; sur->h = h; + if (sur->win) + XMoveResizeWindow(RrDisplay(sur->inst), sur->win, x, y, w, h); } Window RrSurfaceWindow(struct RrSurface *sur) @@ -165,3 +180,66 @@ struct RrTexture *RrSurfaceTexture(struct RrSurface *sur, int texnum) assert(texnum < sur->ntextures); return &(sur->texture[texnum]); } + +void RrSurfaceMinSize(struct RrSurface *sur, int *w, int *h) +{ + int i; + int minw, minh; + + switch(sur->type) { + case RR_SURFACE_NONE: + *w = *h = 0; + break; + case RR_SURFACE_PLANAR: + RrPlanarMinSize(sur, w, h); + break; + case RR_SURFACE_NONPLANAR: + assert(0); + break; + } + + for (i = 0; i < sur->ntextures; ++i) { + switch (sur->texture[i].type) { + case RR_TEXTURE_NONE: + minw = MAX(minw, 0); + minh = MAX(minh, 0); + break; + case RR_TEXTURE_TEXT: + /* XXX MEASUER STRING PLS */ + minw = MAX(minw, 100 /*MEASURESTRING*/); + minh = MAX(minh, 10 /*HEIGHTOFFONT*/); + break; + case RR_TEXTURE_RGBA: + minw = MAX(minw, (sur->texture[i].data.rgba.x + + sur->texture[i].data.rgba.w)); + minh = MAX(minw, (sur->texture[i].data.rgba.y + + sur->texture[i].data.rgba.h)); + break; + } + } + + *w += minw; + *h += minh; + /* zeros are bad. */ + if (*w == 0) *w = 1; + if (*h == 0) *h = 1; +} + +void RrSurfaceShow(struct RrSurface *sur) +{ + sur->visible = 1; + if (sur->win) + XMapWindow(RrDisplay(sur->inst), sur->win); +} + +void RrSurfaceHide(struct RrSurface *sur) +{ + sur->visible = 0; + if (sur->win) + XUnmapWindow(RrDisplay(sur->inst), sur->win); +} + +int RrSurfaceVisible(struct RrSurface *sur) +{ + return sur->visible; +} diff --git a/render2/surface.h b/render2/surface.h index 850ba36f..a8c2448e 100644 --- a/render2/surface.h +++ b/render2/surface.h @@ -37,6 +37,8 @@ struct RrSurface { int y; int w; int h; + + int visible : 1; }; struct RrTexture *RrSurfaceTexture(struct RrSurface *sur, int texnum); diff --git a/render2/test.c b/render2/test.c index 9eb060f5..8001ab8f 100644 --- a/render2/test.c +++ b/render2/test.c @@ -57,7 +57,7 @@ int main() XSetWMProtocols(display, win, &delete_win, 1); /* init Render */ - if (!(inst = RrInit(display, DefaultScreen(display)))) { + if (!(inst = RrInstanceNew(display, DefaultScreen(display)))) { fprintf(stderr, "couldn't initialize the Render library " "(no suitable GL support found)\n"); return EXIT_FAILURE; @@ -67,7 +67,7 @@ int main() RrSurfaceSetArea(sur, X, Y, W, H); RrColorSet(&pri, 0, 0, 0, 0); RrColorSet(&sec, 1, 1, 1, 0); - RrPlanarSet(sur, RR_PLANAR_VERTICAL, &pri, &sec); + RrPlanarSet(sur, RR_PLANAR_PIPECROSS, &pri, &sec); quit = 0; while (!quit) { @@ -102,7 +102,7 @@ int main() } - RrDestroy(inst); + RrInstanceFree(inst); return 1; } diff --git a/render2/texture.c b/render2/texture.c index 24726d0b..12185bc3 100644 --- a/render2/texture.c +++ b/render2/texture.c @@ -3,7 +3,7 @@ #include #include -void texture_free(struct RrTexture *tex) +void RrTextureFreeContents(struct RrTexture *tex) { switch (tex->type) { case RR_TEXTURE_NONE: @@ -28,7 +28,7 @@ void RrTextureSetRGBA(struct RrSurface *sur, struct RrTexture *tex = RrSurfaceTexture(sur, texnum); if (!tex) return; - texture_free(tex); + RrTextureFreeContents(tex); tex->type = RR_TEXTURE_RGBA; tex->data.rgba.data = data; tex->data.rgba.x = x; @@ -47,7 +47,7 @@ void RrTextureSetText(struct RrSurface *sur, int l; if (!tex) return; - texture_free(tex); + RrTextureFreeContents(tex); tex->type = RR_TEXTURE_TEXT; tex->data.text.font = font; tex->data.text.layout = layout; diff --git a/render2/texture.h b/render2/texture.h index 5415dbb5..3737dd19 100644 --- a/render2/texture.h +++ b/render2/texture.h @@ -23,6 +23,10 @@ struct RrTextureRGBA { int h; }; +struct RrTexture; + +void RrTextureFreeContents(struct RrTexture *tex); + union RrTextureData { struct RrTextureText text; struct RrTextureRGBA rgba;