main.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. #include <X11/X.h>
  2. #ifdef _WIN32
  3. #include <assert.h>
  4. #include <stdbool.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include "pltf/gl_funcs.h"
  8. #include "pltf/pltf.h"
  9. #include "shader.h"
  10. typedef struct {
  11. const char* up_msg;
  12. const char* down_msg;
  13. int up_count;
  14. int down_count;
  15. } MsgState;
  16. void msg_cb(const PltfKeyAction action, void* user_data) {
  17. MsgState* state = (MsgState*) user_data;
  18. switch (action) {
  19. case PLTF_KEY_DOWN:
  20. printf("Key: %s Count: %d\n", state->down_msg, state->down_count);
  21. state->down_count++;
  22. break;
  23. case PLTF_KEY_UP:
  24. printf("Key: %s Count: %d\n", state->up_msg, state->up_count);
  25. state->up_count++;
  26. break;
  27. default:
  28. printf("INVALID PltfKeyAction. Was %d\n", action);
  29. }
  30. }
  31. int main() {
  32. pltf_init();
  33. pltf_window_create();
  34. pltf_gl_ctx_create();
  35. pltf_gl_funcs_load();
  36. pltf_gl_ctx_info_print();
  37. pltf_key_callback_set(PLTF_KEY_ESC, pltf_window_close, NULL);
  38. MsgState msg_state = { .up_msg = "UP", .down_msg = "DOWN", .up_count = 0, .down_count = 0 };
  39. pltf_key_callback_set(PLTF_KEY_Q, msg_cb, &msg_state);
  40. // clang-format off
  41. const float triangle_verts[] = {
  42. // pos
  43. 0.0f, 0.5f, 0.0f, // top
  44. -0.25f, -0.25f, 0.0f, // bottom-left
  45. 0.25f, -0.25f, 0.0f // bottom-right
  46. };
  47. // clang-format on
  48. const size_t triangle_vert_count = sizeof(triangle_verts) / sizeof(triangle_verts[0]) / 3;
  49. unsigned int triangle_vao = 0;
  50. glGenVertexArrays(1, &triangle_vao);
  51. glBindVertexArray(triangle_vao);
  52. unsigned int triangle_vbo = 0;
  53. glGenBuffers(1, &triangle_vbo);
  54. glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo);
  55. glBufferData(
  56. GL_ARRAY_BUFFER,
  57. sizeof(triangle_verts),
  58. triangle_verts,
  59. GL_STATIC_DRAW
  60. );
  61. glEnableVertexAttribArray(0);
  62. glVertexAttribPointer(
  63. 0,
  64. 3,
  65. GL_FLOAT,
  66. GL_FALSE,
  67. sizeof(float) * 3,
  68. (void*) 0
  69. );
  70. glBindVertexArray(0);
  71. const unsigned int shader = shader_create(
  72. "shader.vert",
  73. "shader.frag"
  74. );
  75. glClearColor(0.0f, 0.0f, 0.8f, 1.0f);
  76. while (true) {
  77. glClear(GL_COLOR_BUFFER_BIT);
  78. glUseProgram(shader);
  79. glBindVertexArray(triangle_vao);
  80. glDrawArrays(GL_TRIANGLES, 0, triangle_vert_count);
  81. pltf_swap_buffers();
  82. const int pltf_we = pltf_window_event_handle();
  83. if (pltf_we == PLTF_WE_DESTROY) {
  84. break;
  85. }
  86. }
  87. pltf_gl_ctx_destroy();
  88. pltf_window_destroy();
  89. pltf_deinit();
  90. return 0;
  91. }
  92. #endif // _WIN32
  93. #ifdef __linux__
  94. #include <GL/glx.h>
  95. #include <X11/Xlib.h>
  96. #include <X11/Xutil.h>
  97. #include <X11/cursorfont.h>
  98. #include <stdio.h>
  99. #include <unistd.h>
  100. #include <string.h>
  101. #include <stdlib.h>
  102. #include "log.h"
  103. #include "DynString.h"
  104. void print_pixmap_format_values(const XPixmapFormatValues* px) {
  105. puts("{");
  106. printf(" depth : %d\n", px->depth);
  107. printf(" bits_per_pixel: %d\n", px->bits_per_pixel);
  108. printf(" scanline_pad : %d\n", px->scanline_pad);
  109. puts("}");
  110. }
  111. void print_visual_info(const XVisualInfo* vi) {
  112. puts("{");
  113. printf(" visual : %p\n", vi->visual);
  114. printf(" visualid : %lu\n", vi->visualid);
  115. printf(" screen : %d\n", vi->screen);
  116. printf(" depth : %u\n", vi->depth);
  117. printf(" class : %d\n", vi->class);
  118. printf(" red_mask : %lu\n", vi->red_mask);
  119. printf(" green_mask : %lu\n", vi->green_mask);
  120. printf(" blue_mask : %lu\n", vi->blue_mask);
  121. printf(" colormap_size: %d\n", vi->colormap_size);
  122. printf(" bits_per_rgb : %d\n", vi->bits_per_rgb);
  123. puts("}");
  124. }
  125. void print_info(Display* display) {
  126. const int screen_num = DefaultScreen(display);
  127. Colormap color_map = DefaultColormap(display, screen_num);
  128. int default_depth = DefaultDepth(display, screen_num);
  129. int depths_count = 0;
  130. int* depths = XListDepths(display, screen_num, &depths_count);
  131. if (depths == NULL) {
  132. LOG_FATAL("XListDepths failed");
  133. }
  134. int cells = DisplayCells(display, screen_num);
  135. int color_depth = DisplayPlanes(display, screen_num);
  136. char* display_string = DisplayString(display);
  137. int queue_length = QLength(display);
  138. int screen_count = ScreenCount(display);
  139. char* server_vendor = ServerVendor(display);
  140. int vendor_release = VendorRelease(display);
  141. printf("DefaultScreen : %d\n", screen_num);
  142. printf("DefaultColormap: %lu\n", color_map);
  143. printf("DefaultDepth : %d\n", default_depth);
  144. printf("XListDepths : ");
  145. for (int i = 0; i < depths_count; i++) {
  146. printf("%d ", depths[i]);
  147. }
  148. puts("");
  149. printf("DisplayCells : %d\n", cells);
  150. printf("DisplayPlanes : %d\n", color_depth);
  151. printf("DisplayString : %s\n", display_string);
  152. printf("QLength : %d\n", queue_length);
  153. printf("ScreenCount : %d\n", screen_count);
  154. printf("ServerVendor : %s\n", server_vendor);
  155. printf("VendorRelease : %d\n", vendor_release);
  156. XFree(depths);
  157. int d_supported_pixmap_formats_n = 0;
  158. XPixmapFormatValues* d_supported_pixmap_formats = XListPixmapFormats(display, &d_supported_pixmap_formats_n);
  159. if (d_supported_pixmap_formats == NULL) {
  160. LOG_FATAL("XListPixmapFormats failed");
  161. }
  162. int img_byte_order = ImageByteOrder(display);
  163. int bitmap_unit = XBitmapUnit(display);
  164. int bitmap_bit_order = BitmapBitOrder(display);
  165. int bitmap_pad = BitmapPad(display);
  166. int s_height_px = DisplayHeight(display, screen_num);
  167. int s_height_mm = DisplayHeightMM(display, screen_num);
  168. int s_width_px = DisplayWidth(display, screen_num);
  169. int s_width_mm = DisplayWidthMM(display, screen_num);
  170. puts("");
  171. printf("XListPixmapFormats (%d):\n", d_supported_pixmap_formats_n);
  172. for (int i = 0; i < d_supported_pixmap_formats_n; i++) {
  173. print_pixmap_format_values(d_supported_pixmap_formats + i);
  174. }
  175. printf("ImageByteOrder : %s\n", img_byte_order == LSBFirst ? "LSBFirst" : "MSBFirst");
  176. printf("XBitmapUnit : %d\n", bitmap_unit);
  177. printf("BitmapBitOrder : %s\n", bitmap_bit_order == LSBFirst ? "LSBFirst" : "MSBFirst");
  178. printf("BitmapPad : %d\n", bitmap_pad);
  179. printf("DisplayHeight (DefaultScreen): %d\n", s_height_px);
  180. printf("DisplayHeightMM (DefaultScreen): %d\n", s_height_mm);
  181. printf("DisplayWidth (DefaultScreen): %d\n", s_width_px);
  182. printf("DisplayWidthMM (DefaultScreen): %d\n", s_width_mm);
  183. XFree(d_supported_pixmap_formats);
  184. Screen* screen = ScreenOfDisplay(display, screen_num);
  185. unsigned long s_black_pixel = BlackPixelOfScreen(screen);
  186. unsigned long s_white_pixel = WhitePixelOfScreen(screen);
  187. int s_cells = CellsOfScreen(screen);
  188. int s_default_depth = DefaultDepthOfScreen(screen);
  189. int does_backing_store = DoesBackingStore(screen);
  190. bool does_save_unders = DoesSaveUnders(screen);
  191. int s_max_colormaps = MaxCmapsOfScreen(screen);
  192. int s_min_colormaps = MinCmapsOfScreen(screen);
  193. int s_planes_n = PlanesOfScreen(screen);
  194. puts("\n(Default Screen)");
  195. printf("BlackPixelOfScreen : %lu\n", s_black_pixel);
  196. printf("WhitePixelOfScreen : %lu\n", s_white_pixel);
  197. printf("CellsOfScreen : %d\n", s_cells);
  198. printf("DefaultDepthOfScreen: %d\n", s_default_depth);
  199. printf("DoesBackingStore : %s\n", does_backing_store == WhenMapped ? "WhenMapped" : (does_backing_store == NotUseful ? "NotUseful" : "Always"));
  200. printf("DoesSaveUnders : %s\n", does_save_unders ? "true" : "false");
  201. printf("MaxCmapsOfScreen : %d\n", s_max_colormaps);
  202. printf("MinCmapsOfScreen : %d\n", s_min_colormaps);
  203. printf("PlanesOfScreen : %d\n", s_planes_n);
  204. puts("");
  205. }
  206. void glx_print_client_info(Display* display) {
  207. const char* glx_client_vendor_str = glXGetClientString(display, GLX_VENDOR);
  208. printf("Client GLX_VENDOR: %s\n", glx_client_vendor_str);
  209. const char* glx_client_version_str = glXGetClientString(display, GLX_VERSION);
  210. printf("Client GLX_VERSION: %s\n", glx_client_version_str);
  211. const char* glx_client_extensions_str = glXGetClientString(display, GLX_EXTENSIONS);
  212. printf("Client GLX_EXTENSIONS: %s\n", glx_client_extensions_str);
  213. }
  214. void glx_print_server_info(Display* display) {
  215. const char* glx_server_vendor_str = glXQueryServerString(display, DefaultScreen(display), GLX_VENDOR);
  216. printf("Server GLX_VENDOR: %s\n", glx_server_vendor_str);
  217. const char* glx_server_version_str = glXQueryServerString(display, DefaultScreen(display), GLX_VERSION);
  218. printf("Server GLX_VERSION: %s\n", glx_server_version_str);
  219. const char* glx_server_extensions_str = glXQueryServerString(display, DefaultScreen(display), GLX_EXTENSIONS);
  220. printf("Server GLX_EXTENSIONS: %s\n", glx_server_extensions_str);
  221. }
  222. void print_glxfbconfig(Display* display, const GLXFBConfig* cfg) {
  223. int value = 0;
  224. #define PRINT_GLXFBCONFIG_VALUE(attrib) \
  225. value = 0; \
  226. if (glXGetFBConfigAttrib(display, *cfg, attrib, &value) != Success) { \
  227. LOG_FATALF("Invalid attrib %s", #attrib); \
  228. } \
  229. printf(" %s: %d\n", #attrib, value)
  230. puts("{");
  231. PRINT_GLXFBCONFIG_VALUE(GLX_FBCONFIG_ID);
  232. PRINT_GLXFBCONFIG_VALUE(GLX_BUFFER_SIZE);
  233. PRINT_GLXFBCONFIG_VALUE(GLX_LEVEL);
  234. PRINT_GLXFBCONFIG_VALUE(GLX_DOUBLEBUFFER);
  235. PRINT_GLXFBCONFIG_VALUE(GLX_STEREO);
  236. PRINT_GLXFBCONFIG_VALUE(GLX_AUX_BUFFERS);
  237. PRINT_GLXFBCONFIG_VALUE(GLX_RED_SIZE);
  238. PRINT_GLXFBCONFIG_VALUE(GLX_GREEN_SIZE);
  239. PRINT_GLXFBCONFIG_VALUE(GLX_BLUE_SIZE);
  240. PRINT_GLXFBCONFIG_VALUE(GLX_ALPHA_SIZE);
  241. PRINT_GLXFBCONFIG_VALUE(GLX_DEPTH_SIZE);
  242. PRINT_GLXFBCONFIG_VALUE(GLX_STENCIL_SIZE);
  243. PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_RED_SIZE);
  244. PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_GREEN_SIZE);
  245. PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_BLUE_SIZE);
  246. PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_ALPHA_SIZE);
  247. PRINT_GLXFBCONFIG_VALUE(GLX_SAMPLE_BUFFERS);
  248. PRINT_GLXFBCONFIG_VALUE(GLX_SAMPLES);
  249. PRINT_GLXFBCONFIG_VALUE(GLX_RENDER_TYPE);
  250. PRINT_GLXFBCONFIG_VALUE(GLX_DRAWABLE_TYPE);
  251. PRINT_GLXFBCONFIG_VALUE(GLX_X_RENDERABLE);
  252. PRINT_GLXFBCONFIG_VALUE(GLX_X_VISUAL_TYPE);
  253. PRINT_GLXFBCONFIG_VALUE(GLX_CONFIG_CAVEAT);
  254. PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_TYPE);
  255. PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_INDEX_VALUE);
  256. PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_RED_VALUE);
  257. PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_GREEN_VALUE);
  258. PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_BLUE_VALUE);
  259. PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_ALPHA_VALUE);
  260. PRINT_GLXFBCONFIG_VALUE(GLX_MAX_PBUFFER_WIDTH);
  261. PRINT_GLXFBCONFIG_VALUE(GLX_MAX_PBUFFER_HEIGHT);
  262. PRINT_GLXFBCONFIG_VALUE(GLX_MAX_PBUFFER_PIXELS);
  263. PRINT_GLXFBCONFIG_VALUE(GLX_VISUAL_ID);
  264. puts("}");
  265. #undef PRINT_GLXFBCONFIG_VALUE
  266. }
  267. int main() {
  268. Display* display = XOpenDisplay(NULL);
  269. if (display == NULL) {
  270. LOG_FATAL("XOpenDisplay failed.");
  271. }
  272. int err_base = 0;
  273. int event_base = 0;
  274. if (!glXQueryExtension(display, &err_base, &event_base)) {
  275. LOG_FATALF(
  276. "GLX extension not supported. err_base: %d, event_base: %d",
  277. err_base,
  278. event_base
  279. );
  280. }
  281. int glx_major = 0;
  282. int glx_minor = 0;
  283. if (glXQueryVersion(display, &glx_major, &glx_minor)) {
  284. printf("GLX Version %d.%d\n", glx_major, glx_minor);
  285. if (glx_minor < 1) {
  286. LOG_FATAL("GLX Version must be at least 1.1");
  287. }
  288. } else {
  289. LOG_ERROR("glXQueryVersion failed");
  290. }
  291. const char* glx_extensions_c_str = glXQueryExtensionsString(display, DefaultScreen(display));
  292. printf("glx_extensions_c_str: %s\n", glx_extensions_c_str);
  293. DynString glx_extensions_str = DynString_alloc(glx_extensions_c_str, strlen(glx_extensions_c_str));
  294. size_t glx_ext_n = 0;
  295. DynString* glx_extensions = DynString_split(&glx_extensions_str, " ", &glx_ext_n);
  296. printf("GLX extensions:\n");
  297. for (size_t i = 0; i < glx_ext_n; i++) {
  298. printf(" %s\n", DynString_c_str(glx_extensions + i));
  299. }
  300. // XVisualInfo visual_info = { 0 };
  301. // Status xstatus = XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &visual_info);
  302. // if (xstatus == 0) {
  303. // LOG_FATAL("XMatchVisualInfo failed");
  304. // }
  305. // printf("Matched visual:\n");
  306. // print_visual_info(&visual_info);
  307. //
  308. // Cursor cursor = XCreateFontCursor(display, XC_iron_cross);
  309. // XSetWindowAttributes win_attr = {
  310. // .background_pixel = 0x00000000,
  311. // .border_pixel = 0xFF000000,
  312. // .colormap = XCreateColormap(display, DefaultRootWindow(display), visual_info.visual, AllocNone),
  313. // .event_mask = Expose,
  314. // .backing_store = WhenMapped,
  315. // .cursor = cursor,
  316. // };
  317. //
  318. // Window window = XCreateWindow(
  319. // display,
  320. // DefaultRootWindow(display),
  321. // 0,
  322. // 0,
  323. // PLTF_DEFAULT_WINDOW_WIDTH,
  324. // PLTF_DEFAULT_WINDOW_HEIGHT,
  325. // 0,
  326. // visual_info.depth,
  327. // InputOutput,
  328. // visual_info.visual,
  329. // CWBackPixel |
  330. // CWBorderPixel |
  331. // CWColormap |
  332. // CWEventMask |
  333. // CWBackingStore |
  334. // CWCursor,
  335. // &win_attr
  336. // );
  337. //
  338. // XMapWindow(display, window);
  339. //
  340. // XFlush(display);
  341. //
  342. // pause();
  343. //
  344. // XDestroyWindow(display, window);
  345. XCloseDisplay(display);
  346. return 0;
  347. }
  348. #endif // __linux__