Xlesses -- Graphical-ncurses-TempleOS-Gr-function-like creation library in XCB. Very unfinished, I have a life, friends and job, but it'll be done...
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

219 行
10KB

  1. /*
  2. Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic
  3. Xlesses is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
  4. And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
  5. It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
  6. */
  7. #ifndef XLESSES_SOURCE
  8. #define XLESSES_SOURCE
  9. #include <xolatile/xlesses.h>
  10. char * blesses_window_title = "xolatile";
  11. int blesses_window_width = 1800;
  12. int blesses_window_height = 900;
  13. int blesses_active = 1;
  14. int blesses_cursor_x = 0;
  15. int blesses_cursor_y = 0;
  16. int blesses_signal = 0;
  17. int * blesses_sub_framebuffer = NULL;
  18. int * blesses_framebuffer = NULL;
  19. void (* blesses_action [BLESSES_SIGNAL_COUNT]) (void) = { NULL };
  20. xcb_window_t blesses_window = 0;
  21. xcb_gcontext_t blesses_context = 0;
  22. xcb_pixmap_t blesses_pixmap = 0;
  23. xcb_connection_t * blesses_connection = NULL;
  24. xcb_screen_t * blesses_screen = NULL;
  25. xcb_image_t * blesses_image = NULL;
  26. void blesses_initialize (void) {
  27. unsigned int window_flags [2] = {
  28. 0,
  29. XCB_EVENT_MASK_NO_EVENT |
  30. XCB_EVENT_MASK_EXPOSURE |
  31. XCB_EVENT_MASK_RESIZE_REDIRECT |
  32. XCB_EVENT_MASK_KEY_RELEASE |
  33. XCB_EVENT_MASK_KEY_PRESS |
  34. XCB_EVENT_MASK_BUTTON_RELEASE |
  35. XCB_EVENT_MASK_BUTTON_PRESS
  36. };
  37. unsigned short int window_width = (unsigned short int) blesses_window_width;
  38. unsigned short int window_height = (unsigned short int) blesses_window_height;
  39. blesses_connection = xcb_connect (NULL, NULL);
  40. log_in (LOG_FAILURE, blesses_connection == NULL, "blesses : blesses_initialize : XCB connection is null pointer.");
  41. blesses_screen = xcb_setup_roots_iterator (xcb_get_setup (blesses_connection)).data;
  42. blesses_window = xcb_generate_id (blesses_connection);
  43. blesses_context = xcb_generate_id (blesses_connection);
  44. blesses_pixmap = xcb_generate_id (blesses_connection);
  45. window_flags [0] = blesses_screen->black_pixel;
  46. xcb_create_window (blesses_connection, blesses_screen->root_depth, blesses_window, blesses_screen->root, 0, 0, window_width, window_height, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT,
  47. blesses_screen->root_visual, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, window_flags);
  48. xcb_map_window (blesses_connection, blesses_window);
  49. xcb_change_property (blesses_connection, XCB_PROP_MODE_REPLACE, blesses_window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, string_length (blesses_window_title), blesses_window_title);
  50. xcb_create_pixmap (blesses_connection, blesses_screen->root_depth, blesses_pixmap, blesses_window, window_width, window_height);
  51. xcb_create_gc (blesses_connection, blesses_context, blesses_pixmap, 0, NULL);
  52. xcb_flush (blesses_connection);
  53. /*blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer) / 4);*/
  54. blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer));
  55. blesses_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_framebuffer));
  56. log_out ("./blesses.log");
  57. }
  58. void blesses_deinitialize (void) {
  59. blesses_sub_framebuffer = deallocate (blesses_sub_framebuffer);
  60. blesses_framebuffer = deallocate (blesses_framebuffer);
  61. xcb_free_gc (blesses_connection, blesses_context);
  62. xcb_free_pixmap (blesses_connection, blesses_pixmap);
  63. xcb_destroy_window (blesses_connection, blesses_window);
  64. xcb_disconnect (blesses_connection);
  65. }
  66. void blesses_synchronize (void) {
  67. int i = 0;
  68. int j = 0;
  69. xcb_generic_event_t * generic_event = NULL;
  70. /*
  71. for (i = 0; i != blesses_window_width * blesses_window_height; i++) {
  72. blesses_framebuffer [i] = blesses_sub_framebuffer [((i / blesses_window_width) / 2) * (blesses_window_width / 2) + (i % blesses_window_width) / 2];
  73. }
  74. */
  75. for (i = 0; i != blesses_window_width * blesses_window_height; i++) {
  76. blesses_framebuffer [i] = blesses_sub_framebuffer [i];
  77. }
  78. blesses_sub_framebuffer = deallocate (blesses_sub_framebuffer);
  79. blesses_image = xcb_image_create_native (blesses_connection, blesses_window_width, blesses_window_height, XCB_IMAGE_FORMAT_Z_PIXMAP, blesses_screen->root_depth,
  80. blesses_framebuffer, (unsigned int) (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_framebuffer)),
  81. (unsigned char *) blesses_framebuffer);
  82. xcb_image_put (blesses_connection, blesses_pixmap, blesses_context, blesses_image, 0, 0, 0);
  83. xcb_image_destroy (blesses_image);
  84. xcb_copy_area (blesses_connection, blesses_pixmap, blesses_window, blesses_context, 0, 0, 0, 0, blesses_window_width, blesses_window_height);
  85. blesses_framebuffer = NULL;
  86. generic_event = xcb_wait_for_event (blesses_connection);
  87. switch (generic_event->response_type & 127) {
  88. case XCB_EXPOSE: {
  89. xcb_flush (blesses_connection);
  90. } break;
  91. case XCB_KEY_PRESS: {
  92. blesses_signal = (int) ((xcb_key_press_event_t *) generic_event)->detail;
  93. if (blesses_signal == 24) {
  94. blesses_active = 0;
  95. }
  96. } break;
  97. default: {
  98. } break;
  99. }
  100. generic_event = deallocate (generic_event);
  101. if ((blesses_sub_framebuffer == NULL) && (blesses_framebuffer == NULL)) {
  102. /*blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer) / 4);*/
  103. blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer));
  104. blesses_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_framebuffer));
  105. }
  106. log_out ("./blesses.log");
  107. }
  108. void blesses_render_background_colour (int colour) {
  109. int x, y;
  110. for (y = 0; y != blesses_window_height/* / 2*/; ++y) {
  111. for (x = 0; x != blesses_window_width/* / 2*/; ++x) {
  112. blesses_sub_framebuffer [y * (blesses_window_width/* / 2*/) + x] = 0XFF000000 | colour;
  113. }
  114. }
  115. }
  116. void blesses_render_character (char character, int x, int y, int foreground, int background) {
  117. const unsigned long int font_code ['~' - ' ' + 1] = {
  118. 0X0000000000000000, 0X00180018183C3C18, 0X0000000000363636, 0X006C6CFE6CFE6C6C, 0X00187ED07C16FC30, 0X0060660C18306606, 0X00DC66B61C36361C, 0X0000000000181818,
  119. 0X0030180C0C0C1830, 0X000C18303030180C, 0X0000187E3C7E1800, 0X000018187E181800, 0X0C18180000000000, 0X000000007E000000, 0X0018180000000000, 0X0000060C18306000,
  120. 0X003C666E7E76663C, 0X007E181818181C18, 0X007E0C183060663C, 0X003C66603860663C, 0X0030307E363C3830, 0X003C6660603E067E, 0X003C66663E060C38, 0X000C0C0C1830607E,
  121. 0X003C66663C66663C, 0X001C30607C66663C, 0X0018180018180000, 0X0C18180018180000, 0X0030180C060C1830, 0X0000007E007E0000, 0X000C18306030180C, 0X001800181830663C,
  122. 0X003C06765676663C, 0X006666667E66663C, 0X003E66663E66663E, 0X003C66060606663C, 0X001E36666666361E, 0X007E06063E06067E, 0X000606063E06067E, 0X003C66667606663C,
  123. 0X006666667E666666, 0X007E18181818187E, 0X001C36303030307C, 0X0066361E0E1E3666, 0X007E060606060606, 0X00C6C6D6D6FEEEC6, 0X006666767E6E6666, 0X003C66666666663C,
  124. 0X000606063E66663E, 0X006C36566666663C, 0X006666363E66663E, 0X003C66603C06663C, 0X001818181818187E, 0X003C666666666666, 0X00183C6666666666, 0X00C6EEFED6D6C6C6,
  125. 0X0066663C183C6666, 0X001818183C666666, 0X007E060C1830607E, 0X003E06060606063E, 0X00006030180C0600, 0X007C60606060607C, 0X000000000000663C, 0XFFFF000000000000,
  126. 0X000000000030180C, 0X007C667C603C0000, 0X003E6666663E0606, 0X003C6606663C0000, 0X007C6666667C6060, 0X003C067E663C0000, 0X000C0C0C3E0C0C38, 0X3C607C66667C0000,
  127. 0X00666666663E0606, 0X003C1818181C0018, 0X0E181818181C0018, 0X0066361E36660606, 0X003C18181818181C, 0X00C6D6D6FE6C0000, 0X00666666663E0000, 0X003C6666663C0000,
  128. 0X06063E66663E0000, 0XE0607C66667C0000, 0X000606066E360000, 0X003E603C067C0000, 0X00380C0C0C3E0C0C, 0X007C666666660000, 0X00183C6666660000, 0X006CFED6D6C60000,
  129. 0X00663C183C660000, 0X3C607C6666660000, 0X007E0C18307E0000, 0X003018180E181830, 0X0018181818181818, 0X000C18187018180C, 0X000000000062D68C, 0X0000000000000000
  130. };
  131. int offset;
  132. if ((x <= -1) || (x >= blesses_window_width/* / 2*/ - BLESSES_FONT_WIDTH)) return;
  133. if ((y <= -1) || (y >= blesses_window_height/* / 2*/ - BLESSES_FONT_HEIGHT)) return;
  134. log_in (LOG_WARNING, blesses_sub_framebuffer == NULL, "blesses : render_character : Sub framebuffer was not allocated.");
  135. log_in (LOG_WARNING, blesses_framebuffer == NULL, "blesses : render_character : Framebuffer was not allocated.");
  136. log_in (LOG_WARNING, character_is_invisible (character), "blesses : render_character : Character is not in visible ASCII range.");
  137. log_in (LOG_WARNING, x <= -1, "blesses : render_character : X position is under lower limit.");
  138. log_in (LOG_WARNING, y <= -1, "blesses : render_character : Y position is under lower limit.");
  139. log_in (LOG_WARNING, x >= blesses_window_width - BLESSES_FONT_WIDTH, "blesses : render_character : X position is above upper limit.");
  140. log_in (LOG_WARNING, y >= blesses_window_height - BLESSES_FONT_HEIGHT, "blesses : render_character : Y position is above upper limit.");
  141. for (offset = 0; offset != BLESSES_FONT_WIDTH * BLESSES_FONT_HEIGHT; ++offset) {
  142. int u = offset / BLESSES_FONT_WIDTH + y;
  143. int v = offset % BLESSES_FONT_WIDTH + x;
  144. blesses_sub_framebuffer [u * (blesses_window_width/* / 2*/) + v] = ((font_code [(int) (character - ' ')] >> offset) % 2) ? foreground : background;
  145. }
  146. log_out ("./blesses.log");
  147. }
  148. void blesses_render_string_limit (char * string, int limit, int * x, int * y, int foreground, int background) {
  149. int offset;
  150. for (offset = 0; offset != limit; ++offset) {
  151. if (string [offset] == '\t') {
  152. * x += BLESSES_FONT_WIDTH * BLESSES_FONT_TABULATOR;
  153. } else if (string [offset] == '\n') {
  154. * y += BLESSES_FONT_HEIGHT;
  155. * x *= 0;
  156. } else {
  157. blesses_render_character (string [offset], * x, * y, foreground, background);
  158. * x += BLESSES_FONT_WIDTH;
  159. }
  160. }
  161. }
  162. void blesses_render_string (char * string, int * x, int * y, int foreground, int background) {
  163. blesses_render_string_limit (string, string_length (string), x, y, foreground, background);
  164. }
  165. #endif