UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2015 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <X11/Intrinsic.h> 32 #include <X11/IntrinsicP.h> 33 34 #include "graphics.h" 35 36 #include "container.h" 37 38 static void ui_drawingarea_expose(Widget widget, XtPointer u, XtPointer c) { 39 UiDrawEvent *drawevent = u; 40 //XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *)c; 41 //XEvent *event = cbs->event; 42 Display *dpy = XtDisplay(widget); 43 44 UiEvent ev; 45 ev.obj = drawevent->obj; 46 ev.window = drawevent->obj->window; 47 ev.document = drawevent->obj->ctx->document; 48 ev.eventdata = NULL; 49 ev.intval = 0; 50 51 XtVaGetValues( 52 widget, 53 XmNwidth, 54 &drawevent->gr.g.width, 55 XmNheight, 56 &drawevent->gr.g.height, 57 NULL); 58 59 XGCValues gcvals; 60 gcvals.foreground = BlackPixelOfScreen(XtScreen(widget)); 61 drawevent->gr.gc = XCreateGC(dpy, XtWindow(widget), (GCForeground), &gcvals); 62 63 drawevent->callback(&ev, &drawevent->gr.g, drawevent->userdata); 64 } 65 66 UIWIDGET ui_drawingarea(UiObject *obj, ui_drawfunc f, void *userdata) { 67 UiContainer *ct = uic_get_current_container(obj); 68 69 int n = 0; 70 Arg args[16]; 71 72 Widget parent = ct->prepare(ct, args, &n, TRUE); 73 Widget drawingarea = XmCreateDrawingArea(parent, "drawingarea", args, n); 74 75 if(f) { 76 UiDrawEvent *event = malloc(sizeof(UiDrawEvent)); 77 event->obj = obj; 78 event->callback = f; 79 event->userdata = userdata; 80 81 event->gr.display = XtDisplay(drawingarea); 82 event->gr.widget = drawingarea; 83 84 Colormap colormap; 85 XtVaGetValues(drawingarea, XmNcolormap, &colormap, NULL); 86 event->gr.colormap = colormap; 87 88 XtAddCallback( 89 drawingarea, 90 XmNexposeCallback, 91 ui_drawingarea_expose, 92 event); 93 94 XtVaSetValues(drawingarea, XmNuserData, event, NULL); 95 } 96 97 XtManageChild(drawingarea); 98 return drawingarea; 99 } 100 101 static void ui_drawingarea_input(Widget widget, XtPointer u, XtPointer c) { 102 XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct*)c; 103 XEvent *xevent = cbs->event; 104 UiMouseEventData *event = u; 105 106 if (cbs->reason == XmCR_INPUT) { 107 if (xevent->xany.type == ButtonPress) { 108 UiMouseEvent me; 109 me.x = xevent->xbutton.x; 110 me.y = xevent->xbutton.y; 111 // TODO: configurable double click time 112 me.type = xevent->xbutton.time - event->last_event > 300 ? UI_PRESS : UI_PRESS2; 113 114 UiEvent e; 115 e.obj = event->obj; 116 e.window = event->obj->window; 117 e.document = event->obj->ctx->document; 118 e.eventdata = &me; 119 e.intval = 0; 120 event->callback(&e, event->userdata); 121 122 123 event->last_event = me.type == UI_PRESS2 ? 0 : xevent->xbutton.time; 124 } 125 } 126 127 } 128 129 void ui_drawingarea_mousehandler(UiObject *obj, UIWIDGET widget, ui_callback f, void *u) { 130 if(f) { 131 UiMouseEventData *event = malloc(sizeof(UiMouseEventData)); 132 event->obj = obj; 133 event->callback = f; 134 event->userdata = u; 135 event->last_event = 0; 136 137 XtAddCallback(widget, XmNinputCallback, ui_drawingarea_input, event); 138 } 139 } 140 141 void ui_drawingarea_getsize(UIWIDGET drawingarea, int *width, int *height) { 142 XtVaGetValues( 143 drawingarea, 144 XmNwidth, 145 width, 146 XmNheight, 147 height, 148 NULL); 149 } 150 151 void ui_drawingarea_redraw(UIWIDGET drawingarea) { 152 //XClearArea(XtDisplay(drawingarea), drawingarea->core.window, 0, 0, drawingarea->core.width, drawingarea->core.height, True); 153 UiDrawEvent *event; 154 XtVaGetValues(drawingarea, XmNuserData, &event, NULL); 155 ui_drawingarea_expose(drawingarea, event, NULL); 156 } 157 158 159 /* -------------------- text layout functions -------------------- */ 160 UiTextLayout* ui_text(UiGraphics *g) { 161 UiTextLayout *text = malloc(sizeof(UiTextLayout)); 162 memset(text, 0, sizeof(UiTextLayout)); 163 text->text = NULL; 164 text->length = 0; 165 text->widget = ((UiXlibGraphics*)g)->widget; 166 text->fontset = NULL; 167 return text; 168 } 169 170 static void create_default_fontset(UiTextLayout *layout) { 171 char **missing = NULL; 172 int num_missing = 0; 173 char *def = NULL; 174 Display *dpy = XtDisplay(layout->widget); 175 XFontSet fs = XCreateFontSet( 176 dpy, 177 "-dt-interface system-medium-r-normal-s*utf*:," 178 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-1," 179 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-10," 180 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-15," 181 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-2," 182 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-3," 183 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-4," 184 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-5," 185 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-iso8859-9," 186 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-e," 187 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-r," 188 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-ru," 189 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-u," 190 "-misc-liberation sans-medium-r-normal--0-0-0-0-p-0-koi8-uni," 191 "-misc-fixed-medium-r-normal--14-130-75-75-c-140-jisx0208", 192 &missing, &num_missing, &def); 193 layout->fontset = fs; 194 } 195 196 void ui_text_free(UiTextLayout *text) { 197 // TODO 198 } 199 200 void ui_text_setstring(UiTextLayout *layout, char *str) { 201 ui_text_setstringl(layout, str, strlen(str)); 202 } 203 204 void ui_text_setstringl(UiTextLayout *layout, char *str, int len) { 205 layout->text = str; 206 layout->length = len; 207 layout->changed = 1; 208 } 209 210 void ui_text_setfont(UiTextLayout *layout, char *font, int size) { 211 create_default_fontset(layout);//TODO 212 layout->changed = 1; 213 } 214 215 void ui_text_getsize(UiTextLayout *layout, int *width, int *height) { 216 if(layout->changed) { 217 XRectangle ext, lext; 218 XmbTextExtents(layout->fontset, layout->text, layout->length, &ext, &lext); 219 layout->width = ext.width; 220 layout->height = ext.height; 221 layout->changed = 0; 222 } 223 *width = layout->width; 224 *height = layout->height; 225 } 226 227 void ui_text_setwidth(UiTextLayout *layout, int width) { 228 layout->maxwidth = width; 229 } 230 231 232 /* -------------------- drawing functions -------------------- */ 233 234 void ui_graphics_color(UiGraphics *g, int red, int green, int blue) { 235 UiXlibGraphics *gr = (UiXlibGraphics*)g; 236 XColor color; 237 color.flags= DoRed | DoGreen | DoBlue; 238 color.red = red * 257; 239 color.green = green * 257; 240 color.blue = blue * 257; 241 XAllocColor(gr->display, gr->colormap, &color); 242 XSetForeground(gr->display, gr->gc, color.pixel); 243 } 244 245 void ui_draw_line(UiGraphics *g, int x1, int y1, int x2, int y2) { 246 UiXlibGraphics *gr = (UiXlibGraphics*)g; 247 XDrawLine(gr->display, XtWindow(gr->widget), gr->gc, x1, y1, x2, y2); 248 } 249 250 void ui_draw_rect(UiGraphics *g, int x, int y, int w, int h, int fill) { 251 UiXlibGraphics *gr = (UiXlibGraphics*)g; 252 if(fill) { 253 XFillRectangle(gr->display, XtWindow(gr->widget), gr->gc, x, y, w, h); 254 } else { 255 XDrawRectangle(gr->display, XtWindow(gr->widget), gr->gc, x, y, w, h); 256 } 257 } 258 259 void ui_draw_text(UiGraphics *g, int x, int y, UiTextLayout *text) { 260 UiXlibGraphics *gr = (UiXlibGraphics*)g; 261 int width, height; 262 ui_text_getsize(text, &width, &height); 263 if(text->maxwidth > 0) { 264 XRectangle clip; 265 clip.x = x; 266 clip.y = y; 267 clip.width = text->maxwidth; 268 clip.height = height; 269 XSetClipRectangles(gr->display, gr->gc, 0, 0, &clip, 1, Unsorted); 270 } 271 272 XmbDrawString( 273 gr->display, 274 XtWindow(gr->widget), 275 text->fontset, 276 gr->gc, 277 x, 278 y + height, 279 text->text, 280 text->length); 281 282 XSetClipMask(gr->display, gr->gc, None); 283 } 284