mutter/cltr-list.c
2005-03-22 14:53:51 +00:00

350 lines
7.0 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include "pixbuf.h"
#include "fonts.h"
#define TEX_W 1024 /* must be > than frame_w & power of 2 */
#define TEX_H 1024
/*
*
*/
#define WINW 640
#define WINH 480
#define NBOXITEMS 10
#define NUMRECTS 4
#define MAXSCALE 2
#define MAXDIST (WINH)
#define MAXH (WINH/NUMRECTS)
#define MAXW (WINW - 20)
#ifndef ABS
#define ABS(a) ((a > 0) ? (a) : -1 * (a))
#endif
typedef struct TableWidget TableWidget;
typedef struct TableWidgetCell TableWidgetCell;
int ScrollDir = 1;
struct TableWidget
{
int x,y,width,height;
TableWidgetCell *cells, *active_cell;
int active_cell_y;
};
struct TableWidgetCell
{
XRectangle rect;
TableWidgetCell *next, *prev;
};
Display *xdpy;
Window xwin;
XEvent xevent;
GC xgc;
Pixbuf *pix, *pix_orig;
float
distfunc(TableWidget *table, int d)
{
/* printf("returning %f\n", (exp((float)d/MAXDIST)/exp(1.0))); */
int maxdist = table->height;
d = (maxdist-ABS(d)) ;
return ( exp( (float)d/maxdist * 2.0 ) / exp(2.0) );
}
TableWidgetCell*
table_cell_new()
{
TableWidgetCell *cell = NULL;
cell = malloc(sizeof(TableWidgetCell));
memset(cell, 0, sizeof(TableWidgetCell));
return cell;
}
TableWidget*
table_new(int n_items)
{
TableWidget *table = NULL;
TableWidgetCell *last = NULL, *cell = NULL;
int i;
table = malloc(sizeof(TableWidget));
memset(table, 0, sizeof(TableWidget));
table->width = WINW;
table->height = WINH;
table->active_cell_y = 100;
for (i=0; i<n_items; i++)
{
cell = table_cell_new();
if (last)
{
last->next = cell;
cell->prev = last;
}
else
table->cells = table->active_cell = cell;
last = cell;
}
table->cells->rect.y = table->active_cell_y;
return table;
}
void
table_redraw(TableWidget *table)
{
TableWidgetCell *cur = table->cells;
int last = table->cells->rect.y;
glClearColor( 0.0, 0.0, 0.0, 1.0);
glClear (GL_COLOR_BUFFER_BIT);
while (cur)
{
cur->rect.y = last;
if (cur->rect.y+cur->rect.height >= 0)
{
cur->rect.width = MAXW * distfunc(table, cur->rect.y - table->active_cell_y);
cur->rect.height = MAXH * distfunc(table, cur->rect.y - table->active_cell_y);
cur->rect.x = (WINW - cur->rect.width)/6;
}
last = cur->rect.y + cur->rect.height;
if (last > 0 && cur->rect.y < WINH) /* crappy clip */
{
float tx = 1.0, ty = 1.0, sx, sy;
int x1 = cur->rect.x, x2 = cur->rect.x + cur->rect.width;
int y1 = cur->rect.y, y2 = cur->rect.y + cur->rect.height;
tx = (float) pix->width / TEX_W;
ty = (float) pix->height / TEX_H;
glBegin (GL_QUADS);
glTexCoord2f (tx, ty); glVertex2i (x2, y2);
glTexCoord2f (0, ty); glVertex2i (x1, y2);
glTexCoord2f (0, 0); glVertex2i (x1, y1);
glTexCoord2f (tx, 0); glVertex2i (x2, y1);
glEnd ();
/* draw with X primitives
XDrawRectangle(xdpy, xwin, xgc,
cur->rect.x, cur->rect.y,
cur->rect.width, cur->rect.height);
XDrawLine(xdpy, xwin, xgc,
cur->rect.x, cur->rect.y,
cur->rect.x + cur->rect.width,
cur->rect.y + cur->rect.height);
*/
}
cur = cur->next;
}
glXSwapBuffers(xdpy, xwin);
}
void
table_scroll_down(TableWidget *table)
{
TableWidgetCell *next_active = table->active_cell->next;
if (!next_active)
{
ScrollDir = 0;
return;
}
while (next_active->rect.y > table->active_cell_y)
{
table->cells->rect.y--;
table_redraw(table);
}
table->active_cell = next_active;
}
void
table_scroll_up(TableWidget *table)
{
TableWidgetCell *next_active = table->active_cell->prev;
if (!next_active)
return;
while (next_active->rect.y < table->active_cell_y)
{
table->cells->rect.y++;
table_redraw(table);
}
table->active_cell = next_active;
}
int
main(int argc, char **argv)
{
TableWidget *table;
int i, j, last, offset=0;
XGCValues gcvals;
ClutterFont *font = NULL;
/* GL */
GLXContext context; /* OpenGL context */
GLubyte *texture_data = NULL;
XVisualInfo *vinfo;
static int attributes[] =
{
GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
0
};
if ((xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
{
fprintf(stderr, "%s: Cant open display\n", argv[0]);
exit(-1);
}
if ((vinfo = glXChooseVisual(xdpy, DefaultScreen(xdpy), attributes)) == NULL)
{
fprintf(stderr, "Unable to find visual\n");
exit(-1);
}
xwin = XCreateSimpleWindow(xdpy,
RootWindow(xdpy, DefaultScreen(xdpy)),
0, 0,
WINW, WINH,
0, 0, WhitePixel(xdpy, DefaultScreen(xdpy)));
gcvals.foreground = BlackPixel(xdpy, DefaultScreen(xdpy));
gcvals.background = WhitePixel(xdpy, DefaultScreen(xdpy));
gcvals.line_width = 1;
xgc = XCreateGC(xdpy, RootWindow(xdpy, DefaultScreen(xdpy)),
GCForeground|GCBackground|GCLineWidth,
&gcvals);
context = glXCreateContext(xdpy, vinfo, 0, True);
glXMakeCurrent(xdpy, xwin, context);
glViewport (0, 0, WINW, WINH);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glClearColor (0, 0, 0, 0);
glClearDepth (1.0f);
glDisable (GL_DEPTH_TEST);
glDepthMask (GL_FALSE);
glDisable (GL_CULL_FACE);
glShadeModel (GL_FLAT);
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
// glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, WINW, WINH, 0, -1, 1);
glEnable (GL_TEXTURE_2D);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
texture_data = malloc (TEX_W * TEX_H * 4);
for (i=0; i < (TEX_W * TEX_H * 4); i++)
texture_data[i] = rand()%255;
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA,
TEX_W, TEX_H,
0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);
pix_orig = pixbuf_new_from_file(argv[1]);
if (!pix_orig)
{
fprintf(stderr, "image load failed\n");
exit(-1);
}
pix = pixbuf_scale_down(pix_orig, 100, 100);
/*
font = font_new("Sans Bold 48");
font_draw(font, pix, "Hello World\nlove matmoo", 0, 0);
*/
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
(GLsizei)pix->width,
(GLsizei)pix->height,
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
pix->data);
table = table_new(NBOXITEMS);
table_redraw(table);
XMapWindow(xdpy, xwin);
for (;;)
{
XEvent ev;
// XNextEvent(xdpy, &ev);
// XClearWindow(xdpy, xwin);
table_redraw(table);
ScrollDir ? table_scroll_down(table) : table_scroll_up(table);
// scroll_to_next();
XFlush(xdpy);
sleep(1);
}
}