PageRenderTime 50ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/mot/iupmot_draw.c

https://gitlab.com/willemmali-c/iup
C | 282 lines | 213 code | 60 blank | 9 comment | 22 complexity | 08fd49ab00e7798923da12f422def7c1 MD5 | raw file
  1. /** \file
  2. * \brief Draw Functions
  3. *
  4. * See Copyright Notice in "iup.h"
  5. */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <memory.h>
  10. #include <Xm/Xm.h>
  11. #include <X11/Xlib.h>
  12. #include "iup.h"
  13. #include "iup_attrib.h"
  14. #include "iup_class.h"
  15. #include "iup_str.h"
  16. #include "iup_object.h"
  17. #include "iup_image.h"
  18. #include "iup_drvdraw.h"
  19. #include "iupmot_drv.h"
  20. #include "iupmot_color.h"
  21. struct _IdrawCanvas{
  22. Ihandle* ih;
  23. int w, h;
  24. Window wnd;
  25. Pixmap pixmap;
  26. GC pixmap_gc, gc;
  27. };
  28. static void motDrawGetGeometry(Display *dpy, Drawable wnd, int *_w, int *_h, int *_d)
  29. {
  30. Window root;
  31. int x, y;
  32. unsigned int w, h, b, d;
  33. XGetGeometry(dpy, wnd, &root, &x, &y, &w, &h, &b, &d);
  34. *_w = w;
  35. *_h = h;
  36. *_d = d;
  37. }
  38. IdrawCanvas* iupdrvDrawCreateCanvas(Ihandle* ih)
  39. {
  40. IdrawCanvas* dc = calloc(1, sizeof(IdrawCanvas));
  41. int depth;
  42. dc->ih = ih;
  43. dc->wnd = (Window)IupGetAttribute(ih, "DRAWABLE");
  44. dc->gc = XCreateGC(iupmot_display, dc->wnd, 0, NULL);
  45. motDrawGetGeometry(iupmot_display, dc->wnd, &dc->w, &dc->h, &depth);
  46. dc->pixmap = XCreatePixmap(iupmot_display, dc->wnd, dc->w, dc->h, depth);
  47. dc->pixmap_gc = XCreateGC(iupmot_display, dc->pixmap, 0, NULL);
  48. return dc;
  49. }
  50. void iupdrvDrawKillCanvas(IdrawCanvas* dc)
  51. {
  52. XFreeGC(iupmot_display, dc->pixmap_gc);
  53. XFreePixmap(iupmot_display, dc->pixmap);
  54. XFreeGC(iupmot_display, dc->gc);
  55. free(dc);
  56. }
  57. void iupdrvDrawUpdateSize(IdrawCanvas* dc)
  58. {
  59. int w, h, depth;
  60. motDrawGetGeometry(iupmot_display, dc->wnd, &w, &h, &depth);
  61. if (w != dc->w || h != dc->h)
  62. {
  63. dc->w = w;
  64. dc->h = h;
  65. XFreeGC(iupmot_display, dc->pixmap_gc);
  66. XFreePixmap(iupmot_display, dc->pixmap);
  67. dc->pixmap = XCreatePixmap(iupmot_display, dc->wnd, dc->w, dc->h, depth);
  68. dc->pixmap_gc = XCreateGC(iupmot_display, dc->pixmap, 0, NULL);
  69. }
  70. }
  71. void iupdrvDrawFlush(IdrawCanvas* dc)
  72. {
  73. XCopyArea(iupmot_display, dc->pixmap, dc->wnd, dc->gc, 0, 0, dc->w, dc->h, 0, 0);
  74. }
  75. void iupdrvDrawGetSize(IdrawCanvas* dc, int *w, int *h)
  76. {
  77. if (w) *w = dc->w;
  78. if (h) *h = dc->h;
  79. }
  80. void iupdrvDrawParentBackground(IdrawCanvas* dc)
  81. {
  82. unsigned char r=0, g=0, b=0;
  83. char* color = iupBaseNativeParentGetBgColorAttrib(dc->ih);
  84. iupStrToRGB(color, &r, &g, &b);
  85. iupdrvDrawRectangle(dc, 0, 0, dc->w-1, dc->h-1, r, g, b, IUP_DRAW_FILL);
  86. }
  87. static void iDrawSetLineStyle(IdrawCanvas* dc, int style)
  88. {
  89. XGCValues gcval;
  90. if (style == IUP_DRAW_STROKE || style == IUP_DRAW_FILL)
  91. gcval.line_style = LineSolid;
  92. else
  93. {
  94. char dashes[2] = { 6, 2 };
  95. char dots[2] = { 2, 2 };
  96. if (style == IUP_DRAW_STROKE_DASH)
  97. XSetDashes(iupmot_display, dc->pixmap_gc, 0, dashes, 2);
  98. else
  99. XSetDashes(iupmot_display, dc->pixmap_gc, 0, dots, 2);
  100. gcval.line_style = LineOnOffDash;
  101. }
  102. XChangeGC(iupmot_display, dc->pixmap_gc, GCLineStyle, &gcval);
  103. }
  104. void iupdrvDrawRectangle(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b, int style)
  105. {
  106. XSetForeground(iupmot_display, dc->pixmap_gc, iupmotColorGetPixel(r, g, b));
  107. if (style==IUP_DRAW_FILL)
  108. XFillRectangle(iupmot_display, dc->pixmap, dc->pixmap_gc, x1, y1, x2-x1+1, y2-y1+1);
  109. else
  110. {
  111. iDrawSetLineStyle(dc, style);
  112. XDrawRectangle(iupmot_display, dc->pixmap, dc->pixmap_gc, x1, y1, x2-x1, y2-y1);
  113. }
  114. }
  115. void iupdrvDrawLine(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b, int style)
  116. {
  117. XSetForeground(iupmot_display, dc->pixmap_gc, iupmotColorGetPixel(r, g, b));
  118. iDrawSetLineStyle(dc, style);
  119. XDrawLine(iupmot_display, dc->pixmap, dc->pixmap_gc, x1, y1, x2, y2);
  120. }
  121. void iupdrvDrawArc(IdrawCanvas* dc, int x1, int y1, int x2, int y2, double a1, double a2, unsigned char r, unsigned char g, unsigned char b, int style)
  122. {
  123. XSetForeground(iupmot_display, dc->pixmap_gc, iupmotColorGetPixel(r, g, b));
  124. if (style==IUP_DRAW_FILL)
  125. {
  126. XSetArcMode(iupmot_display, dc->pixmap_gc, ArcPieSlice);
  127. XFillArc(iupmot_display, dc->pixmap, dc->pixmap_gc, x1, y1, x2 - x1 + 1, y2 - y1 + 1, iupRound(a1 * 64), iupRound((a2 - a1) * 64));
  128. }
  129. else
  130. {
  131. iDrawSetLineStyle(dc, style);
  132. XDrawArc(iupmot_display, dc->pixmap, dc->pixmap_gc, x1, y1, x2 - x1 + 1, y2 - y1 + 1, iupRound(a1 * 64), iupRound((a2 - a1) * 64));
  133. }
  134. }
  135. void iupdrvDrawPolygon(IdrawCanvas* dc, int* points, int count, unsigned char r, unsigned char g, unsigned char b, int style)
  136. {
  137. int i;
  138. XPoint* pnt = (XPoint*)malloc(count*sizeof(XPoint)); /* XPoint uses short for coordinates */
  139. for (i = 0; i < count; i++)
  140. {
  141. pnt[i].x = (short)points[2*i];
  142. pnt[i].y = (short)points[2*i+1];
  143. }
  144. XSetForeground(iupmot_display, dc->pixmap_gc, iupmotColorGetPixel(r, g, b));
  145. if (style==IUP_DRAW_FILL)
  146. XFillPolygon(iupmot_display, dc->pixmap, dc->pixmap_gc, pnt, count, Complex, CoordModeOrigin);
  147. else
  148. {
  149. iDrawSetLineStyle(dc, style);
  150. XDrawLines(iupmot_display, dc->pixmap, dc->pixmap_gc, pnt, count, CoordModeOrigin);
  151. }
  152. free(pnt);
  153. }
  154. void iupdrvDrawSetClipRect(IdrawCanvas* dc, int x1, int y1, int x2, int y2)
  155. {
  156. XRectangle rect;
  157. rect.x = (short)x1;
  158. rect.y = (short)y1;
  159. rect.width = (unsigned short)(x2-x1+1);
  160. rect.height = (unsigned short)(y2-y1+1);
  161. XSetClipRectangles(iupmot_display, dc->pixmap_gc, 0, 0, &rect, 1, Unsorted);
  162. }
  163. void iupdrvDrawResetClip(IdrawCanvas* dc)
  164. {
  165. XSetClipMask(iupmot_display, dc->pixmap_gc, None);
  166. }
  167. void iupdrvDrawText(IdrawCanvas* dc, const char* text, int len, int x, int y, unsigned char r, unsigned char g, unsigned char b, const char* font)
  168. {
  169. int num_line;
  170. XFontStruct* xfont = (XFontStruct*)iupmotGetFontStruct(font);
  171. XSetForeground(iupmot_display, dc->pixmap_gc, iupmotColorGetPixel(r, g, b));
  172. XSetFont(iupmot_display, dc->pixmap_gc, xfont->fid);
  173. num_line = iupStrLineCount(text);
  174. if (num_line == 1)
  175. XDrawString(iupmot_display, dc->pixmap, dc->pixmap_gc, x, y+xfont->ascent, text, len);
  176. else
  177. {
  178. int i, line_height, len;
  179. const char *p, *q;
  180. line_height = xfont->ascent + xfont->descent;
  181. p = text;
  182. for (i = 0; i < num_line; i++)
  183. {
  184. q = strchr(p, '\n');
  185. if (q)
  186. len = (int)(q - p); /* Cut the string to contain only one line */
  187. else
  188. len = (int)strlen(p); /* use the remaining characters */
  189. /* Draw the line */
  190. XDrawString(iupmot_display, dc->pixmap, dc->pixmap_gc, x, y + xfont->ascent, p, len);
  191. /* Advance the string */
  192. if (q)
  193. p = q + 1;
  194. /* Advance a line */
  195. y += line_height;
  196. }
  197. }
  198. }
  199. void iupdrvDrawImage(IdrawCanvas* dc, const char* name, int make_inactive, int x, int y)
  200. {
  201. int img_w, img_h;
  202. int bpp;
  203. Pixmap pixmap = (Pixmap)iupImageGetImage(name, dc->ih, make_inactive);
  204. if (!pixmap)
  205. return;
  206. /* must use this info, since image can be a driver image loaded from resources */
  207. iupdrvImageGetInfo((void*)pixmap, &img_w, &img_h, &bpp);
  208. XCopyArea(iupmot_display, pixmap, dc->pixmap, dc->pixmap_gc, 0, 0, img_w, img_h, x, y);
  209. }
  210. void iupdrvDrawSelectRect(IdrawCanvas* dc, int x1, int y1, int x2, int y2)
  211. {
  212. XSetFunction(iupmot_display, dc->pixmap_gc, GXxor);
  213. XSetForeground(iupmot_display, dc->pixmap_gc, iupmotColorGetPixel(255, 255, 255));
  214. XFillRectangle(iupmot_display, dc->pixmap, dc->pixmap_gc, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
  215. XSetFunction(iupmot_display, dc->pixmap_gc, GXcopy);
  216. }
  217. #include <Xm/XmP.h>
  218. #include <Xm/DrawP.h>
  219. void iupdrvDrawFocusRect(IdrawCanvas* dc, int x1, int y1, int x2, int y2)
  220. {
  221. XmeDrawHighlight(iupmot_display, dc->pixmap, dc->pixmap_gc, x1, y1, x2 - x1 + 1, y2 - y1 + 1, 1);
  222. }