home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume13
/
ishido
/
part01
/
gl.c
next >
Wrap
C/C++ Source or Header
|
1992-04-10
|
10KB
|
450 lines
/*
* gl.c - Simple graphics library, based on X11.
*
* Author: John Sullivan, Amdahl Corporation (jjs40@cd.amdahl.com)
*
*/
/*****************************************************************************/
#include "gl.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <stdlib.h>
#include <stdio.h>
/*****************************************************************************/
Display *gl_display;
int gl_screen;
Window gl_window;
GC gl_gc;
GL_REDRAW_FUNC gl_redraw_fn;
GL_EVENT_FUNC gl_event_fn;
int gl_main;
int gl_screen_width;
int gl_screen_height;
int gl_fg;
int gl_bg;
/*****************************************************************************/
void
gl_bomb(s)
char *s;
{
printf("gl_bomb(): %s\n");
exit(1);
};
/*****************************************************************************/
GL_PIXEL
gl_alloc_color(name)
char *name;
{
XColor c1, c2;
int res;
res = XAllocNamedColor(gl_display,
DefaultColormap(gl_display, gl_screen),
name, &c1, &c2);
if (!res) {
gl_bomb("Unable to allocate color.");
};
return (c1.pixel);
};
/*****************************************************************************/
void
gl_redraw_func(func)
GL_REDRAW_FUNC func;
{
gl_redraw_fn = func;
};
/*****************************************************************************/
void
gl_event_func(func)
GL_EVENT_FUNC func;
{
gl_event_fn = func;
};
/*****************************************************************************/
char gl_event_str_buf[GL_BUFSIZE];
char *
gl_event_str(gl_ev)
GL_EVENT *gl_ev;
{
switch (gl_ev->type) {
case GL_EVENT_KEY:
sprintf(gl_event_str_buf,
"gl_event: key '%c' at (%d,%d)",
gl_ev->key, gl_ev->x, gl_ev->y);
break;
case GL_EVENT_BUTTON:
sprintf(gl_event_str_buf,
"gl_event: button %d at (%d,%d)",
gl_ev->button, gl_ev->x, gl_ev->y);
};
return (gl_event_str_buf);
};
/*****************************************************************************/
void
gl_main_loop()
{
XEvent xev;
XButtonEvent *xbev;
XKeyEvent *xkev;
GL_EVENT gl_ev;
char buf[GL_BUFSIZE];
gl_main = 1;
while (gl_main) {
XNextEvent(gl_display, &xev);
switch (xev.type) {
case Expose:
if (gl_redraw_fn != NULL) {
(*gl_redraw_fn) ();
};
break;
case KeyPress:
gl_ev.type = GL_EVENT_KEY;
xkev = (XKeyEvent *) & xev;
XLookupString(xkev, buf, GL_BUFSIZE, NULL, NULL);
gl_ev.key = buf[0];
gl_ev.x = xkev->x;
gl_ev.y = xkev->y;
if (gl_event_fn != NULL) {
(*gl_event_fn) (&gl_ev);
};
break;
case ButtonPress:
gl_ev.type = GL_EVENT_BUTTON;
xbev = (XButtonEvent *) & xev;
gl_ev.button = xbev->button;
gl_ev.x = xbev->x;
gl_ev.y = xbev->y;
if (gl_event_fn != NULL) {
(*gl_event_fn) (&gl_ev);
};
break;
};
};
};
/*****************************************************************************/
void
gl_exit_main()
{
gl_main = 0;
};
/*****************************************************************************/
void
gl_set_fg(c)
GL_PIXEL c;
{
XGCValues gcv;
gl_fg = c;
gcv.foreground = gl_fg;
XChangeGC(gl_display, gl_gc, GCForeground, &gcv);
};
/*****************************************************************************/
void
gl_set_bg(c)
GL_PIXEL c;
{
XGCValues gcv;
gl_bg = c;
gcv.background = gl_bg;
XChangeGC(gl_display, gl_gc, GCBackground, &gcv);
};
/*****************************************************************************/
void
gl_set_fg_bg(c1, c2)
GL_PIXEL c1, c2;
{
gl_set_fg(c1);
gl_set_bg(c2);
};
/*****************************************************************************/
void
gl_draw_point(x, y)
int x, y;
{
XDrawPoint(gl_display, gl_window, gl_gc, x, y);
};
/*****************************************************************************/
void
gl_draw_line(x1, y1, x2, y2)
int x1, y1;
int x2, y2;
{
XDrawLine(gl_display, gl_window, gl_gc, x1, y1, x2, y2);
};
/*****************************************************************************/
void
gl_draw_rect(x1, y1, w, h)
int x1, y1;
int w, h;
{
XDrawRectangle(gl_display, gl_window, gl_gc, x1, y1, w - 1, h - 1);
};
/*****************************************************************************/
void
gl_fill_rect(x1, y1, w, h)
int x1, y1;
int w, h;
{
XFillRectangle(gl_display, gl_window, gl_gc, x1, y1, w, h);
};
/*****************************************************************************/
void
gl_draw_text(x, y, s)
int x, y;
char *s;
{
int len;
len = strlen(s);
y = y + GL_FONT_DESCENT;
XDrawImageString(gl_display, gl_window, gl_gc, x, y, s, len);
};
/*****************************************************************************/
void
gl_ring_bell()
{
XBell(gl_display, 75);
};
/*****************************************************************************/
GL_BITMAP
gl_load_bitmap(data, w, h)
char *data;
int w, h;
{
return (XCreateBitmapFromData(gl_display, gl_window, data, w, h));
};
/*****************************************************************************/
void
gl_draw_bitmap(bitmap, x, y, w, h)
GL_BITMAP bitmap;
int x, y;
int w, h;
{
XCopyPlane(gl_display, bitmap, gl_window, gl_gc, 0, 0, w, h, x, y,
1);
};
/*****************************************************************************/
void
gl_init(argc, argv, w, h)
int argc;
char **argv;
int w, h;
{
XSizeHints hints;
XGCValues gcv;
unsigned long gcvm;
gl_display = XOpenDisplay(NULL);
if (!gl_display) {
gl_bomb("Unable to connect to display.");
};
gl_redraw_fn = NULL;
gl_event_fn = NULL;
gl_screen_width = w;
gl_screen_height = h;
hints.width = gl_screen_width;
hints.height = gl_screen_height;
hints.flags = PSize;
gl_fg = gl_alloc_color(GL_FOREGROUND);
gl_bg = gl_alloc_color(GL_BACKGROUND);
gcv.foreground = gl_fg;
gcv.background = gl_bg;
gcv.font = XLoadFont(gl_display, GL_FONT);
gcvm = GCForeground | GCBackground | GCFont;
gl_screen = DefaultScreen(gl_display);
gl_window = XCreateSimpleWindow(gl_display,
RootWindow(gl_display, gl_screen), 0, 0, hints.width,
hints.height, 2, gcv.foreground, gcv.background);
XSetStandardProperties(gl_display, gl_window, "GL", "GL",
None, argv, argc, &hints);
XSelectInput(gl_display, gl_window,
ExposureMask | KeyPressMask | ButtonPressMask);
gl_gc = XCreateGC(gl_display, gl_window, gcvm, &gcv);
};
/*****************************************************************************/
void
gl_start()
{
XMapWindow(gl_display, gl_window);
XSync(gl_display);
};
/*****************************************************************************/
void
gl_exit()
{
XCloseDisplay(gl_display);
exit(0);
};
/*****************************************************************************/
void
gu_draw_border(x, y, w, h, z)
int x, y;
int w, h;
int z;
{
int i;
for (i = 1; i <= z; i++) {
gl_draw_rect(x - i, y - i, w + i * 2, h + i * 2);
};
};
/*****************************************************************************/
void
gu_draw_centered_text(x, y, s)
int x, y;
char *s;
{
int sx, sy;
sx = x - (strlen(s) * GL_FONT_WIDTH) / 2;
sy = y - GL_FONT_HEIGHT / 2;
gl_draw_text(sx, sy, s);
};
/*****************************************************************************/
GL_BOOL
gu_event_in_rect(event, x, y, w, h)
GL_EVENT *event;
int x, y;
int w, h;
{
x = event->x - x;
y = event->y - y;
return ((x >= 0) && (x < w) && (y >= 0) && (y < h));
};
/*****************************************************************************/
void
gb_draw_button(btn)
GB_BUTTON *btn;
{
gl_set_fg(btn->border);
gu_draw_border(btn->x, btn->y, btn->w, btn->h, 2);
gl_set_fg(btn->background);
gl_fill_rect(btn->x, btn->y, btn->w, btn->h);
gl_set_fg_bg(btn->text, btn->background);
gu_draw_centered_text(btn->x + btn->w / 2, btn->y + btn->h / 2,
btn->label);
};
/*****************************************************************************/
void
gb_draw_buttons(n, btn)
int n;
GB_BUTTON *btn;
{
int i;
for (i = 0; i < n; i++) {
gb_draw_button(&(btn[i]));
};
};
/*****************************************************************************/
GL_BOOL
gb_event_in_button(event, btn)
GL_EVENT *event;
GB_BUTTON *btn;
{
return (gu_event_in_rect(event, btn->x, btn->y, btn->w, btn->h));
};
/*****************************************************************************/
void
gb_button_press(event, btn)
GL_EVENT *event;
GB_BUTTON *btn;
{
if (btn->event_fn != NULL) {
(*(btn->event_fn)) (event);
};
};
/*****************************************************************************/
GL_BOOL
gb_button_event(event, n, btn)
GL_EVENT *event;
int n;
GB_BUTTON *btn;
{
int i;
for (i = 0; i < n; i++) {
if (gb_event_in_button(event, &(btn[i]))) {
gb_button_press(event, &(btn[i]));
return (GL_TRUE);
};
};
return (GL_FALSE);
};
/*****************************************************************************/