main.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #include <string.h>
  6. #include <X11/Xlib.h>
  7. #include <X11/extensions/Xdbe.h>
  8. #include <unistd.h>
  9. #define WIDTH 800
  10. #define HEIGHT 600
  11. #define FPS 120
  12. #define RECT_WIDTH 300
  13. #define RECT_HEIGHT 300
  14. #define DB_NONE 0
  15. #define DB_XDBE 1
  16. #define DB_PIXMAP 2
  17. #define DB_XIMAGE 3
  18. #if DB_IMPL == DB_NONE
  19. # include "./db_none.c"
  20. #elif DB_IMPL == DB_XDBE
  21. # include "./db_xdbe.c"
  22. #elif DB_IMPL == DB_PIXMAP
  23. # include "./db_pixmap.c"
  24. #elif DB_IMPL == DB_XIMAGE
  25. # include "./db_ximage.c"
  26. #else
  27. # error "Unsupported Double Buffering approach"
  28. #endif
  29. int main(void)
  30. {
  31. printf("Double Buffering Implementation: "DB_IMPL_NAME"\n");
  32. DB db = {0};
  33. Display *display = XOpenDisplay(NULL);
  34. if (display == NULL) {
  35. fprintf(stderr, "ERROR: could not open the default display\n");
  36. exit(1);
  37. }
  38. Window window = XCreateSimpleWindow(
  39. display,
  40. XDefaultRootWindow(display),
  41. 0, 0,
  42. WIDTH, HEIGHT,
  43. 0,
  44. 0,
  45. 0);
  46. db_init(&db, display, window);
  47. XStoreName(display, window, "DB Implementation: "DB_IMPL_NAME);
  48. Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
  49. XSetWMProtocols(display, window, &wm_delete_window, 1);
  50. XSelectInput(display, window, KeyPressMask);
  51. XMapWindow(display, window);
  52. int rect_x = 10;
  53. int rect_y = 10;
  54. int rect_dx = -1;
  55. int rect_dy = -1;
  56. int quit = 0;
  57. while (!quit) {
  58. while (XPending(display) > 0) {
  59. XEvent event = {0};
  60. XNextEvent(display, &event);
  61. switch (event.type) {
  62. case KeyPress: {
  63. switch (XLookupKeysym(&event.xkey, 0)) {
  64. case 'q':
  65. quit = 1;
  66. break;
  67. default:
  68. {}
  69. }
  70. } break;
  71. case ClientMessage: {
  72. if ((Atom) event.xclient.data.l[0] == wm_delete_window) {
  73. quit = 1;
  74. }
  75. }
  76. break;
  77. }
  78. }
  79. db_clear(&db);
  80. db_fill_rect(&db, rect_x, rect_y, RECT_WIDTH, RECT_HEIGHT);
  81. db_swap_buffers(&db);
  82. int rect_nx = rect_x + rect_dx;
  83. if (rect_nx <= 0 || rect_nx + RECT_WIDTH >= WIDTH) {
  84. rect_dx *= -1;
  85. } else {
  86. rect_x = rect_nx;
  87. }
  88. int rect_ny = rect_y + rect_dy;
  89. if (rect_ny <= 0 || rect_ny + RECT_HEIGHT >= HEIGHT) {
  90. rect_dy *= -1;
  91. } else {
  92. rect_y = rect_ny;
  93. }
  94. usleep(1000*1000/FPS);
  95. }
  96. XCloseDisplay(display);
  97. return 0;
  98. }