main.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * MIT License
  3. *
  4. * Copyright (c) 2016-2017 Patrick Rudolph <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. * The above copyright notice and this permission notice shall be included in all
  13. * copies or substantial portions of the Software.
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. *
  22. * Based on x11/main.c.
  23. *
  24. */
  25. #include <assert.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <stdarg.h>
  29. #include <string.h>
  30. #include <limits.h>
  31. #include <math.h>
  32. #include <sys/time.h>
  33. #include <unistd.h>
  34. #include <time.h>
  35. #define NK_INCLUDE_FIXED_TYPES
  36. #define NK_INCLUDE_STANDARD_IO
  37. #define NK_INCLUDE_STANDARD_VARARGS
  38. #define NK_INCLUDE_DEFAULT_ALLOCATOR
  39. #define NK_IMPLEMENTATION
  40. #define NK_XLIBSHM_IMPLEMENTATION
  41. #define NK_RAWFB_IMPLEMENTATION
  42. #define NK_INCLUDE_FONT_BAKING
  43. #define NK_INCLUDE_DEFAULT_FONT
  44. #define NK_INCLUDE_SOFTWARE_FONT
  45. #include "../../nuklear.h"
  46. #include "nuklear_rawfb.h"
  47. #include "nuklear_xlib.h"
  48. #define DTIME 20
  49. #define WINDOW_WIDTH 800
  50. #define WINDOW_HEIGHT 600
  51. #define UNUSED(a) (void)a
  52. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  53. #define MAX(a,b) ((a) < (b) ? (b) : (a))
  54. #define LEN(a) (sizeof(a)/sizeof(a)[0])
  55. typedef struct XWindow XWindow;
  56. struct XWindow {
  57. Display *dpy;
  58. Window root;
  59. Visual *vis;
  60. Colormap cmap;
  61. XWindowAttributes attr;
  62. XSetWindowAttributes swa;
  63. Window win;
  64. int screen;
  65. unsigned int width;
  66. unsigned int height;
  67. };
  68. static void
  69. die(const char *fmt, ...)
  70. {
  71. va_list ap;
  72. va_start(ap, fmt);
  73. vfprintf(stderr, fmt, ap);
  74. va_end(ap);
  75. fputs("\n", stderr);
  76. exit(EXIT_FAILURE);
  77. }
  78. static long
  79. timestamp(void)
  80. {
  81. struct timeval tv;
  82. if (gettimeofday(&tv, NULL) < 0) return 0;
  83. return (long)((long)tv.tv_sec * 1000 + (long)tv.tv_usec/1000);
  84. }
  85. static void
  86. sleep_for(long t)
  87. {
  88. struct timespec req;
  89. const time_t sec = (int)(t/1000);
  90. const long ms = t - (sec * 1000);
  91. req.tv_sec = sec;
  92. req.tv_nsec = ms * 1000000L;
  93. while(-1 == nanosleep(&req, &req));
  94. }
  95. /* ===============================================================
  96. *
  97. * EXAMPLE
  98. *
  99. * ===============================================================*/
  100. /* This are some code examples to provide a small overview of what can be
  101. * done with this library. To try out an example uncomment the defines */
  102. /*#define INCLUDE_ALL */
  103. /*#define INCLUDE_STYLE */
  104. /*#define INCLUDE_CALCULATOR */
  105. /*#define INCLUDE_CANVAS */
  106. /*#define INCLUDE_OVERVIEW */
  107. /*#define INCLUDE_NODE_EDITOR */
  108. #ifdef INCLUDE_ALL
  109. #define INCLUDE_STYLE
  110. #define INCLUDE_CALCULATOR
  111. #define INCLUDE_CANVAS
  112. #define INCLUDE_OVERVIEW
  113. #define INCLUDE_NODE_EDITOR
  114. #endif
  115. #ifdef INCLUDE_STYLE
  116. #include "../../demo/common/style.c"
  117. #endif
  118. #ifdef INCLUDE_CALCULATOR
  119. #include "../../demo/common/calculator.c"
  120. #endif
  121. #ifdef INCLUDE_CANVAS
  122. #include "../../demo/common/canvas.c"
  123. #endif
  124. #ifdef INCLUDE_OVERVIEW
  125. #include "../../demo/common/overview.c"
  126. #endif
  127. #ifdef INCLUDE_NODE_EDITOR
  128. #include "../../demo/common/node_editor.c"
  129. #endif
  130. /* ===============================================================
  131. *
  132. * DEMO
  133. *
  134. * ===============================================================*/
  135. int
  136. main(void)
  137. {
  138. long dt;
  139. long started;
  140. int running = 1;
  141. int status;
  142. XWindow xw;
  143. struct rawfb_context *rawfb;
  144. void *fb = NULL;
  145. rawfb_pl pl;
  146. unsigned char tex_scratch[512 * 512];
  147. /* X11 */
  148. memset(&xw, 0, sizeof xw);
  149. xw.dpy = XOpenDisplay(NULL);
  150. if (!xw.dpy) die("Could not open a display; perhaps $DISPLAY is not set?");
  151. xw.root = DefaultRootWindow(xw.dpy);
  152. xw.screen = XDefaultScreen(xw.dpy);
  153. xw.vis = XDefaultVisual(xw.dpy, xw.screen);
  154. xw.cmap = XCreateColormap(xw.dpy,xw.root,xw.vis,AllocNone);
  155. xw.swa.colormap = xw.cmap;
  156. xw.swa.event_mask =
  157. ExposureMask | KeyPressMask | KeyReleaseMask |
  158. ButtonPress | ButtonReleaseMask| ButtonMotionMask |
  159. Button1MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask|
  160. PointerMotionMask | KeymapStateMask | EnterWindowMask | LeaveWindowMask;
  161. xw.win = XCreateWindow(xw.dpy, xw.root, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
  162. XDefaultDepth(xw.dpy, xw.screen), InputOutput,
  163. xw.vis, CWEventMask | CWColormap, &xw.swa);
  164. XStoreName(xw.dpy, xw.win, "X11");
  165. XMapWindow(xw.dpy, xw.win);
  166. XGetWindowAttributes(xw.dpy, xw.win, &xw.attr);
  167. xw.width = (unsigned int)xw.attr.width;
  168. xw.height = (unsigned int)xw.attr.height;
  169. /* Framebuffer emulator */
  170. status = nk_xlib_init(xw.dpy, xw.vis, xw.screen, xw.win, xw.width, xw.height, &fb, &pl);
  171. if (!status || !fb)
  172. return 0;
  173. /* GUI */
  174. rawfb = nk_rawfb_init(fb, tex_scratch, xw.width, xw.height, xw.width * 4, pl);
  175. if (!rawfb) running = 0;
  176. #ifdef INCLUDE_STYLE
  177. /* ease regression testing during Nuklear release process; not needed for anything else */
  178. #ifdef STYLE_WHITE
  179. set_style(&rawfb->ctx, THEME_WHITE);
  180. #elif defined(STYLE_RED)
  181. set_style(&rawfb->ctx, THEME_RED);
  182. #elif defined(STYLE_BLUE)
  183. set_style(&rawfb->ctx, THEME_BLUE);
  184. #elif defined(STYLE_DARK)
  185. set_style(&rawfb->ctx, THEME_DARK);
  186. #endif
  187. #endif
  188. while (running) {
  189. /* Input */
  190. XEvent evt;
  191. started = timestamp();
  192. nk_input_begin(&rawfb->ctx);
  193. while (XCheckWindowEvent(xw.dpy, xw.win, xw.swa.event_mask, &evt)) {
  194. if (XFilterEvent(&evt, xw.win)) continue;
  195. nk_xlib_handle_event(xw.dpy, xw.screen, xw.win, &evt, rawfb);
  196. }
  197. nk_input_end(&rawfb->ctx);
  198. /* GUI */
  199. if (nk_begin(&rawfb->ctx, "Demo", nk_rect(50, 50, 200, 200),
  200. NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|
  201. NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) {
  202. enum {EASY, HARD};
  203. static int op = EASY;
  204. static int property = 20;
  205. nk_layout_row_static(&rawfb->ctx, 30, 80, 1);
  206. if (nk_button_label(&rawfb->ctx, "button"))
  207. fprintf(stdout, "button pressed\n");
  208. nk_layout_row_dynamic(&rawfb->ctx, 30, 2);
  209. if (nk_option_label(&rawfb->ctx, "easy", op == EASY)) op = EASY;
  210. if (nk_option_label(&rawfb->ctx, "hard", op == HARD)) op = HARD;
  211. nk_layout_row_dynamic(&rawfb->ctx, 25, 1);
  212. nk_property_int(&rawfb->ctx, "Compression:", 0, &property, 100, 10, 1);
  213. }
  214. nk_end(&rawfb->ctx);
  215. if (nk_window_is_closed(&rawfb->ctx, "Demo")) break;
  216. /* -------------- EXAMPLES ---------------- */
  217. #ifdef INCLUDE_CALCULATOR
  218. calculator(&rawfb->ctx);
  219. #endif
  220. #ifdef INCLUDE_CANVAS
  221. canvas(&rawfb->ctx);
  222. #endif
  223. #ifdef INCLUDE_OVERVIEW
  224. overview(&rawfb->ctx);
  225. #endif
  226. #ifdef INCLUDE_NODE_EDITOR
  227. node_editor(&rawfb->ctx);
  228. #endif
  229. /* ----------------------------------------- */
  230. /* Draw framebuffer */
  231. nk_rawfb_render(rawfb, nk_rgb(30,30,30), 1);
  232. /* Emulate framebuffer */
  233. XClearWindow(xw.dpy, xw.win);
  234. nk_xlib_render(xw.win);
  235. XFlush(xw.dpy);
  236. /* Timing */
  237. dt = timestamp() - started;
  238. if (dt < DTIME)
  239. sleep_for(DTIME - dt);
  240. }
  241. nk_rawfb_shutdown(rawfb);
  242. nk_xlib_shutdown();
  243. XUnmapWindow(xw.dpy, xw.win);
  244. XFreeColormap(xw.dpy, xw.cmap);
  245. XDestroyWindow(xw.dpy, xw.win);
  246. XCloseDisplay(xw.dpy);
  247. return 0;
  248. }