lib_LTLIBRARIES=libobrender2.la
libobrender2_la_LIBADD=-lglft -L../glft
libobrender2_la_SOURCES=\
- init.c \
instance.c \
color.c \
debug.c \
#include "instance.h"
+#include "debug.h"
+#include "glft/glft.h"
#include <stdlib.h>
#include <assert.h>
-/*
-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)
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;
+}
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, \
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);
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));
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));
break;
}
}
+
+void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h)
+{
+ *w = 0;
+ *h = 0;
+}
void RrPlanarPaint(struct RrSurface *sur, int x, int y, int w, int h);
+void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h);
+
#endif
#include <glib.h>
#include <X11/Xlib.h>
-/* initialization */
+/* instances */
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 */
struct RrSurface;
enum RrSurfaceType {
+ RR_SURFACE_NONE,
RR_SURFACE_PLANAR,
RR_SURFACE_NONPLANAR
};
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,
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 */
sur->y = 0;
sur->w = 1;
sur->h = 1;
+ sur->visible = 0;
return sur;
}
Window win = XCreateWindow(RrDisplay(inst), parent, 0, 0, 1, 1, 0,
RrDepth(inst), InputOutput, RrVisual(inst),
0, NULL);
- XMapWindow(RrDisplay(inst), win);
return win;
}
sur->inst = NULL;
sur->win = None;
sur->parent = NULL;
+ sur->visible = 0;
return sur;
}
sur->inst = inst;
sur->win = win;
sur->parent = NULL;
+ sur->visible = 0;
return sur;
}
sur->inst = parent->inst;
sur->win = create_window(sur->inst, parent->win);
sur->parent = parent;
+ RrSurfaceShow(sur);
return sur;
}
case RR_SURFACE_NONPLANAR:
assert(0);
break;
+ case RR_SURFACE_NONE:
+ break;
}
sur->ntextures = orig->ntextures;
sur->texture = malloc(sizeof(struct RrTexture) * sur->ntextures);
sur->inst = inst;
sur->win = win;
sur->parent = NULL;
+ sur->visible = 0;
return sur;
}
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)
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)
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;
+}
int y;
int w;
int h;
+
+ int visible : 1;
};
struct RrTexture *RrSurfaceTexture(struct RrSurface *sur, int texnum);
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;
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) {
}
- RrDestroy(inst);
+ RrInstanceFree(inst);
return 1;
}
#include <stdlib.h>
#include <string.h>
-void texture_free(struct RrTexture *tex)
+void RrTextureFreeContents(struct RrTexture *tex)
{
switch (tex->type) {
case RR_TEXTURE_NONE:
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;
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;
int h;
};
+struct RrTexture;
+
+void RrTextureFreeContents(struct RrTexture *tex);
+
union RrTextureData {
struct RrTextureText text;
struct RrTextureRGBA rgba;