#include <stdio.h>
#include <stdlib.h>
#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include "graphics.h"
#include "container.h"
static void ui_drawingarea_expose(Widget widget, XtPointer u, XtPointer c) {
UiDrawEvent *drawevent = u;
Display *dpy = XtDisplay(widget);
UiEvent ev;
ev.obj = drawevent->obj;
ev.window = drawevent->obj->window;
ev.document = drawevent->obj->ctx->document;
ev.eventdata =
NULL;
ev.intval =
0;
XtVaGetValues(
widget,
XmNwidth,
&drawevent->gr.g.width,
XmNheight,
&drawevent->gr.g.height,
NULL);
XGCValues gcvals;
gcvals.foreground = BlackPixelOfScreen(XtScreen(widget));
drawevent->gr.gc = XCreateGC(dpy, XtWindow(widget), (GCForeground), &gcvals);
drawevent->callback(&ev, &drawevent->gr.g, drawevent->userdata);
}
UIWIDGET ui_drawingarea(UiObject *obj, ui_drawfunc f,
void *userdata) {
UiContainer *ct = uic_get_current_container(obj);
int n =
0;
Arg args[
16];
Widget parent = ct->prepare(ct, args, &n,
TRUE);
Widget drawingarea = XmCreateDrawingArea(parent,
"drawingarea", args, n);
if(f) {
UiDrawEvent *event = malloc(
sizeof(UiDrawEvent));
event->obj = obj;
event->callback = f;
event->userdata = userdata;
event->gr.display = XtDisplay(drawingarea);
event->gr.widget = drawingarea;
Colormap colormap;
XtVaGetValues(drawingarea, XmNcolormap, &colormap,
NULL);
event->gr.colormap = colormap;
XtAddCallback(
drawingarea,
XmNexposeCallback,
ui_drawingarea_expose,
event);
XtVaSetValues(drawingarea, XmNuserData, event,
NULL);
}
XtManageChild(drawingarea);
return drawingarea;
}
static void ui_drawingarea_input(Widget widget, XtPointer u, XtPointer c) {
XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct*)c;
XEvent *xevent = cbs->event;
UiMouseEventData *event = u;
if (cbs->reason == XmCR_INPUT) {
if (xevent->xany.type == ButtonPress) {
UiMouseEvent me;
me.x = xevent->xbutton.x;
me.y = xevent->xbutton.y;
me.type = xevent->xbutton.time - event->last_event >
300 ?
UI_PRESS :
UI_PRESS2;
UiEvent e;
e.obj = event->obj;
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = &me;
e.intval =
0;
event->callback(&e, event->userdata);
event->last_event = me.type ==
UI_PRESS2 ?
0 : xevent->xbutton.time;
}
}
}
void ui_drawingarea_mousehandler(UiObject *obj,
UIWIDGET widget, ui_callback f,
void *u) {
if(f) {
UiMouseEventData *event = malloc(
sizeof(UiMouseEventData));
event->obj = obj;
event->callback = f;
event->userdata = u;
event->last_event =
0;
XtAddCallback(widget, XmNinputCallback, ui_drawingarea_input, event);
}
}
void ui_drawingarea_getsize(
UIWIDGET drawingarea,
int *width,
int *height) {
XtVaGetValues(
drawingarea,
XmNwidth,
width,
XmNheight,
height,
NULL);
}
void ui_drawingarea_redraw(
UIWIDGET drawingarea) {
UiDrawEvent *event;
XtVaGetValues(drawingarea, XmNuserData, &event,
NULL);
ui_drawingarea_expose(drawingarea, event,
NULL);
}
UiTextLayout* ui_text(UiGraphics *g) {
UiTextLayout *text = malloc(
sizeof(UiTextLayout));
memset(text,
0,
sizeof(UiTextLayout));
text->text =
NULL;
text->length =
0;
text->widget = ((UiXlibGraphics*)g)->widget;
text->fontset =
NULL;
return text;
}
static void create_default_fontset(UiTextLayout *layout) {
char **missing =
NULL;
int num_missing =
0;
char *def =
NULL;
Display *dpy = XtDisplay(layout->widget);
XFontSet fs = XCreateFontSet(
dpy,
"-dt-interface system-medium-r-normal-s*utf*:,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-1,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-10,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-15,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-2,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-3,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-4,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-5,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-9,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-e,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-r,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-ru,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-u,"
"-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-uni,"
"-misc-fixed-medium-r-normal--14-130-75-75-c-140-jisx0208",
&missing, &num_missing, &def);
layout->fontset = fs;
}
void ui_text_free(UiTextLayout *text) {
}
void ui_text_setstring(UiTextLayout *layout,
char *str) {
ui_text_setstringl(layout, str, strlen(str));
}
void ui_text_setstringl(UiTextLayout *layout,
char *str,
int len) {
layout->text = str;
layout->length = len;
layout->changed =
1;
}
void ui_text_setfont(UiTextLayout *layout,
char *font,
int size) {
create_default_fontset(layout);
layout->changed =
1;
}
void ui_text_getsize(UiTextLayout *layout,
int *width,
int *height) {
if(layout->changed) {
XRectangle ext, lext;
XmbTextExtents(layout->fontset, layout->text, layout->length, &ext, &lext);
layout->width = ext.width;
layout->height = ext.height;
layout->changed =
0;
}
*width = layout->width;
*height = layout->height;
}
void ui_text_setwidth(UiTextLayout *layout,
int width) {
layout->maxwidth = width;
}
void ui_graphics_color(UiGraphics *g,
int red,
int green,
int blue) {
UiXlibGraphics *gr = (UiXlibGraphics*)g;
XColor color;
color.flags= DoRed | DoGreen | DoBlue;
color.red = red *
257;
color.green = green *
257;
color.blue = blue *
257;
XAllocColor(gr->display, gr->colormap, &color);
XSetForeground(gr->display, gr->gc, color.pixel);
}
void ui_draw_line(UiGraphics *g,
int x1,
int y1,
int x2,
int y2) {
UiXlibGraphics *gr = (UiXlibGraphics*)g;
XDrawLine(gr->display, XtWindow(gr->widget), gr->gc, x1, y1, x2, y2);
}
void ui_draw_rect(UiGraphics *g,
int x,
int y,
int w,
int h,
int fill) {
UiXlibGraphics *gr = (UiXlibGraphics*)g;
if(fill) {
XFillRectangle(gr->display, XtWindow(gr->widget), gr->gc, x, y, w, h);
}
else {
XDrawRectangle(gr->display, XtWindow(gr->widget), gr->gc, x, y, w, h);
}
}
void ui_draw_text(UiGraphics *g,
int x,
int y, UiTextLayout *text) {
UiXlibGraphics *gr = (UiXlibGraphics*)g;
int width, height;
ui_text_getsize(text, &width, &height);
if(text->maxwidth >
0) {
XRectangle clip;
clip.x = x;
clip.y = y;
clip.width = text->maxwidth;
clip.height = height;
XSetClipRectangles(gr->display, gr->gc,
0,
0, &clip,
1, Unsorted);
}
XmbDrawString(
gr->display,
XtWindow(gr->widget),
text->fontset,
gr->gc,
x,
y + height,
text->text,
text->length);
XSetClipMask(gr->display, gr->gc, None);
}