More to come...
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

265 linhas
12KB

  1. #ifndef CHAPTER_5_SOURCE
  2. #define CHAPTER_5_SOURCE
  3. #include "chapter_5.h"
  4. #define BLESSES_FONT_WIDTH (8)
  5. #define BLESSES_FONT_HEIGHT (8)
  6. #define BLESSES_FONT_TABULATOR (4)
  7. #define BLESSES_SIGNAL_COUNT (144)
  8. static char * blesses_window_title = "xolatile";
  9. static int blesses_window_width = 1800;
  10. static int blesses_window_height = 900;
  11. static int * blesses_sub_framebuffer = NULL;
  12. static int * blesses_framebuffer = NULL;
  13. static void (* blesses_action [BLESSES_SIGNAL_COUNT]) (void) = { NULL };
  14. static xcb_window_t blesses_window = 0;
  15. static xcb_gcontext_t blesses_context = 0;
  16. static xcb_pixmap_t blesses_pixmap = 0;
  17. static xcb_connection_t * blesses_connection = NULL;
  18. static xcb_screen_t * blesses_screen = NULL;
  19. static xcb_image_t * blesses_image = NULL;
  20. static void blesses_initialize (void) {
  21. unsigned int window_flags [2] = {
  22. 0,
  23. XCB_EVENT_MASK_NO_EVENT |
  24. XCB_EVENT_MASK_EXPOSURE |
  25. XCB_EVENT_MASK_RESIZE_REDIRECT |
  26. XCB_EVENT_MASK_KEY_RELEASE |
  27. XCB_EVENT_MASK_KEY_PRESS |
  28. XCB_EVENT_MASK_BUTTON_RELEASE |
  29. XCB_EVENT_MASK_BUTTON_PRESS
  30. };
  31. unsigned short int window_width = (unsigned short int) blesses_window_width;
  32. unsigned short int window_height = (unsigned short int) blesses_window_height;
  33. blesses_connection = xcb_connect (NULL, NULL);
  34. fatal_failure (blesses_connection == NULL, "blesses : blesses_initialize : XCB connection is null pointer.");
  35. print ("[/4XCB/-] /0Connected to X11./-\n");
  36. blesses_screen = xcb_setup_roots_iterator (xcb_get_setup (blesses_connection)).data;
  37. blesses_window = xcb_generate_id (blesses_connection);
  38. blesses_context = xcb_generate_id (blesses_connection);
  39. blesses_pixmap = xcb_generate_id (blesses_connection);
  40. window_flags [0] = blesses_screen->black_pixel;
  41. 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,
  42. blesses_screen->root_visual, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, window_flags);
  43. xcb_map_window (blesses_connection, blesses_window);
  44. xcb_change_property (blesses_connection, XCB_PROP_MODE_REPLACE, blesses_window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, (unsigned int) string_length (blesses_window_title), blesses_window_title);
  45. print ("[/4XCB/-] /0Created window./-\n");
  46. xcb_create_pixmap (blesses_connection, blesses_screen->root_depth, blesses_pixmap, blesses_window, window_width, window_height);
  47. print ("[/4XCB/-] /0Created pixmap./-\n");
  48. xcb_create_gc (blesses_connection, blesses_context, blesses_pixmap, 0, NULL);
  49. print ("[/4XCB/-] /0Created graphic context./-\n");
  50. xcb_flush (blesses_connection);
  51. if (blesses_zoom == TRUE) {
  52. blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer) / 4);
  53. } else {
  54. blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer));
  55. }
  56. blesses_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_framebuffer));
  57. }
  58. static 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. print ("[/4XCB/-] /0Deallocated graphic context./-\n");
  63. xcb_free_pixmap (blesses_connection, blesses_pixmap);
  64. print ("[/4XCB/-] /0Deallocated pixmap./-\n");
  65. xcb_destroy_window (blesses_connection, blesses_window);
  66. print ("[/4XCB/-] /0Deleted window./-\n");
  67. xcb_disconnect (blesses_connection);
  68. print ("[/4XCB/-] /0Disconnected from X11./-\n");
  69. }
  70. int blesses_active = FALSE;
  71. int blesses_cursor_x = 0;
  72. int blesses_cursor_y = 0;
  73. int blesses_signal = 0;
  74. int blesses_zoom = TRUE;
  75. void blesses_configure (void) {
  76. blesses_active = TRUE;
  77. blesses_initialize ();
  78. }
  79. void blesses_synchronize (void) {
  80. int i = 0;
  81. unsigned short int window_width = (unsigned short int) blesses_window_width;
  82. unsigned short int window_height = (unsigned short int) blesses_window_height;
  83. xcb_generic_event_t * generic_event = NULL;
  84. if (blesses_zoom == TRUE) {
  85. for (i = 0; i != blesses_window_width * blesses_window_height; i++) {
  86. blesses_framebuffer [i] = blesses_sub_framebuffer [((i / blesses_window_width) / 2) * (blesses_window_width / 2) + (i % blesses_window_width) / 2];
  87. }
  88. } else {
  89. for (i = 0; i != blesses_window_width * blesses_window_height; i++) {
  90. blesses_framebuffer [i] = blesses_sub_framebuffer [i];
  91. }
  92. }
  93. blesses_sub_framebuffer = deallocate (blesses_sub_framebuffer);
  94. blesses_image = xcb_image_create_native (blesses_connection, window_width, window_height, XCB_IMAGE_FORMAT_Z_PIXMAP, blesses_screen->root_depth,
  95. blesses_framebuffer, (unsigned int) (window_width * window_height * (int) sizeof (* blesses_framebuffer)),
  96. (unsigned char *) blesses_framebuffer);
  97. xcb_image_put (blesses_connection, blesses_pixmap, blesses_context, blesses_image, 0, 0, 0);
  98. xcb_image_destroy (blesses_image);
  99. xcb_copy_area (blesses_connection, blesses_pixmap, blesses_window, blesses_context, 0, 0, 0, 0, window_width, window_height);
  100. blesses_framebuffer = NULL;
  101. generic_event = xcb_wait_for_event (blesses_connection);
  102. switch (generic_event->response_type & 127) {
  103. case XCB_EXPOSE: {
  104. xcb_flush (blesses_connection);
  105. } break;
  106. case XCB_KEY_PRESS: {
  107. blesses_signal = (int) ((xcb_key_press_event_t *) generic_event)->detail;
  108. if (blesses_signal == 24) {
  109. blesses_active = FALSE;
  110. }
  111. if (blesses_signal == 25) {
  112. blesses_zoom = ! blesses_zoom;
  113. }
  114. } break;
  115. default: {
  116. } break;
  117. }
  118. generic_event = deallocate (generic_event);
  119. if ((blesses_sub_framebuffer == NULL) && (blesses_framebuffer == NULL)) {
  120. if (blesses_zoom == TRUE) {
  121. blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer) / 4);
  122. } else {
  123. blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer));
  124. }
  125. // blesses_sub_framebuffer = allocate ((blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer)) / ((blesses_zoom == TRUE) ? 4 : 1));
  126. blesses_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_framebuffer));
  127. }
  128. if (blesses_active == FALSE) {
  129. blesses_deinitialize ();
  130. }
  131. }
  132. void blesses_render_background_colour (int background) {
  133. int x, y;
  134. for (y = 0; y != blesses_window_height / ((blesses_zoom == TRUE) ? 2 : 1); ++y) {
  135. for (x = 0; x != blesses_window_width / ((blesses_zoom == TRUE) ? 2 : 1); ++x) {
  136. blesses_sub_framebuffer [y * (blesses_window_width / ((blesses_zoom == TRUE) ? 2 : 1)) + x] = (int) (0XFF000000 | (unsigned int) background);
  137. }
  138. }
  139. }
  140. void blesses_render_character (char character, int foreground, int background, int x, int y) {
  141. const unsigned long int font_code ['~' - ' ' + 2] = {
  142. 0X0000000000000000, 0X00180018183C3C18, 0X0000000000363636, 0X006C6CFE6CFE6C6C, 0X00187ED07C16FC30, 0X0060660C18306606, 0X00DC66B61C36361C, 0X0000000000181818,
  143. 0X0030180C0C0C1830, 0X000C18303030180C, 0X0000187E3C7E1800, 0X000018187E181800, 0X0C18180000000000, 0X000000007E000000, 0X0018180000000000, 0X0000060C18306000,
  144. 0X003C666E7E76663C, 0X007E181818181C18, 0X007E0C183060663C, 0X003C66603860663C, 0X0030307E363C3830, 0X003C6660603E067E, 0X003C66663E060C38, 0X000C0C0C1830607E,
  145. 0X003C66663C66663C, 0X001C30607C66663C, 0X0018180018180000, 0X0C18180018180000, 0X0030180C060C1830, 0X0000007E007E0000, 0X000C18306030180C, 0X001800181830663C,
  146. 0X003C06765676663C, 0X006666667E66663C, 0X003E66663E66663E, 0X003C66060606663C, 0X001E36666666361E, 0X007E06063E06067E, 0X000606063E06067E, 0X003C66667606663C,
  147. 0X006666667E666666, 0X007E18181818187E, 0X001C36303030307C, 0X0066361E0E1E3666, 0X007E060606060606, 0X00C6C6D6D6FEEEC6, 0X006666767E6E6666, 0X003C66666666663C,
  148. 0X000606063E66663E, 0X006C36566666663C, 0X006666363E66663E, 0X003C66603C06663C, 0X001818181818187E, 0X003C666666666666, 0X00183C6666666666, 0X00C6EEFED6D6C6C6,
  149. 0X0066663C183C6666, 0X001818183C666666, 0X007E060C1830607E, 0X003E06060606063E, 0X00006030180C0600, 0X007C60606060607C, 0X000000000000663C, 0XFFFF000000000000,
  150. 0X000000000030180C, 0X007C667C603C0000, 0X003E6666663E0606, 0X003C6606663C0000, 0X007C6666667C6060, 0X003C067E663C0000, 0X000C0C0C3E0C0C38, 0X3C607C66667C0000,
  151. 0X00666666663E0606, 0X003C1818181C0018, 0X0E181818181C0018, 0X0066361E36660606, 0X003C18181818181C, 0X00C6D6D6FE6C0000, 0X00666666663E0000, 0X003C6666663C0000,
  152. 0X06063E66663E0000, 0XE0607C66667C0000, 0X000606066E360000, 0X003E603C067C0000, 0X00380C0C0C3E0C0C, 0X007C666666660000, 0X00183C6666660000, 0X006CFED6D6C60000,
  153. 0X00663C183C660000, 0X3C607C6666660000, 0X007E0C18307E0000, 0X003018180E181830, 0X0018181818181818, 0X000C18187018180C, 0X000000000062D68C, 0X0000000000000000
  154. };
  155. int offset;
  156. if ((x <= -1) || (x >= blesses_window_width / ((blesses_zoom == TRUE) ? 2 : 1) - BLESSES_FONT_WIDTH)) return;
  157. if ((y <= -1) || (y >= blesses_window_height / ((blesses_zoom == TRUE) ? 2 : 1) - BLESSES_FONT_HEIGHT)) return;
  158. fatal_failure (blesses_sub_framebuffer == NULL, "blesses : render_character : Sub framebuffer was not allocated.");
  159. fatal_failure (blesses_framebuffer == NULL, "blesses : render_character : Framebuffer was not allocated.");
  160. fatal_failure (character_is_invisible (character), "blesses : render_character : Character is not in visible ASCII range.");
  161. fatal_failure (x <= -1, "blesses : render_character : X position is under lower limit.");
  162. fatal_failure (y <= -1, "blesses : render_character : Y position is under lower limit.");
  163. fatal_failure (x >= blesses_window_width - BLESSES_FONT_WIDTH, "blesses : render_character : X position is above upper limit.");
  164. fatal_failure (y >= blesses_window_height - BLESSES_FONT_HEIGHT, "blesses : render_character : Y position is above upper limit.");
  165. for (offset = 0; offset != BLESSES_FONT_WIDTH * BLESSES_FONT_HEIGHT; ++offset) {
  166. int u = offset / BLESSES_FONT_WIDTH + y;
  167. int v = offset % BLESSES_FONT_WIDTH + x;
  168. blesses_sub_framebuffer [u * (blesses_window_width / ((blesses_zoom == TRUE) ? 2 : 1)) + v] = ((font_code [(int) (character - ' ')] >> offset) % 2)
  169. ? foreground
  170. : background;
  171. }
  172. }
  173. void blesses_render_string (char * string, int foreground, int background, int x, int y) {
  174. blesses_render_string_limit (string, string_length (string), foreground, background, x, y);
  175. }
  176. void blesses_render_number (int number, int foreground, int background, int x, int y) {
  177. blesses_render_string (number_to_string (number), foreground, background, x, y);
  178. }
  179. void blesses_render_string_limit (char * string, int limit, int foreground, int background, int x, int y) {
  180. int offset;
  181. for (offset = 0; offset != limit; ++offset) {
  182. if (string [offset] == '\n') {
  183. x *= 0;
  184. y += BLESSES_FONT_HEIGHT;
  185. } else if (string [offset] == '\t') {
  186. x += BLESSES_FONT_WIDTH * BLESSES_FONT_TABULATOR;
  187. } else {
  188. blesses_render_character (string [offset], foreground, background, x, y);
  189. x += BLESSES_FONT_WIDTH;
  190. }
  191. }
  192. }
  193. void blesses_render_number_limit (int number, int limit, int foreground, int background, int x, int y) {
  194. blesses_render_string_limit (number_to_string (number), limit, foreground, background, x, y);
  195. }
  196. #endif