1 /// Simple example of a GLFW application that creates a black window and reads some input and output 2 /// 3 /// Does not load OpenGL / Vulkan. 4 module app; 5 6 import glfw3.api; 7 import core.stdc.stdio; 8 9 int main() { 10 GLFWwindow* window; 11 glfwSetErrorCallback(&errorCallback); 12 13 if (!glfwInit()) { 14 return -1; 15 } 16 scope(exit) glfwTerminate(); 17 18 printClipboardState(); 19 printJoystickState(); 20 printMonitorState(); 21 22 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 23 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); 24 25 WindowData data; 26 window = glfwCreateWindow(800, 600, "Black window - press F11 to toggle fullscreen, press ESC to exit", null, null); 27 scope(exit) glfwDestroyWindow(window); 28 if (!window) { 29 glfwTerminate(); 30 return -1; 31 } 32 glfwSetWindowUserPointer(window, &data); 33 34 glfwSetKeyCallback(window, &keyCallback); 35 glfwMakeContextCurrent(window); 36 glfwSwapInterval(1); // Set vsync on so glfwSwapBuffers will wait for monitor updates. 37 // note: 1 is not a boolean! Set e.g. to 2 to run at half the monitor refresh rate. 38 39 double oldTime = glfwGetTime(); 40 while (!glfwWindowShouldClose(window)) { 41 const newTime = glfwGetTime(); 42 const elapsedTime = newTime - oldTime; 43 oldTime = newTime; 44 45 glfwSwapBuffers(window); 46 glfwPollEvents(); 47 } 48 return 0; 49 } 50 51 /// Data stored in the window's user pointer 52 /// 53 /// Note: assuming you only have one window, you could make these global variables. 54 struct WindowData { 55 // These are stored in the window's user data so that when exiting fullscreen, 56 // the window can be set to the position where it was before entering fullscreen 57 // instead of resetting to e.g. (0, 0) 58 int xpos; 59 int ypos; 60 int width; 61 int height; 62 63 @nogc nothrow void update(GLFWwindow* window) { 64 glfwGetWindowPos(window, &this.xpos, &this.ypos); 65 glfwGetWindowSize(window, &this.width, &this.height); 66 } 67 } 68 69 extern(C) @nogc nothrow void errorCallback(int error, const(char)* description) { 70 fprintf(stderr, "Error: %s\n", description); 71 } 72 73 extern(C) @nogc nothrow void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { 74 if (action == GLFW_PRESS) { 75 switch (key) { 76 case GLFW_KEY_ESCAPE: 77 glfwSetWindowShouldClose(window, GLFW_TRUE); 78 break; 79 case GLFW_KEY_F11: 80 toggleFullScreen(window); 81 break; 82 default: break; 83 } 84 } 85 } 86 87 @nogc nothrow void toggleFullScreen(GLFWwindow* window) { 88 WindowData* wd = cast(WindowData*) glfwGetWindowUserPointer(window); 89 assert(wd); 90 if (glfwGetWindowMonitor(window)) { 91 glfwSetWindowMonitor(window, null, wd.xpos, wd.ypos, wd.width, wd.height, 0); 92 } else { 93 GLFWmonitor* monitor = glfwGetPrimaryMonitor(); 94 if (monitor) { 95 const GLFWvidmode* mode = glfwGetVideoMode(monitor); 96 wd.update(window); 97 glfwSetWindowMonitor(window, monitor, 0, 0, mode.width, mode.height, mode.refreshRate); 98 } 99 } 100 } 101 102 void printClipboardState() { 103 printf("Clipboard contents: `%s.80`\n", glfwGetClipboardString(null)); 104 } 105 106 void printMonitorState() { 107 int monitorsLength; 108 GLFWmonitor** monitorsPtr = glfwGetMonitors(&monitorsLength); 109 GLFWmonitor*[] monitors = monitorsPtr[0..monitorsLength]; 110 111 foreach(GLFWmonitor* mt; monitors) { 112 int widthMM, heightMM; 113 int xpos, ypos, width, height; 114 glfwGetMonitorPos(mt, &xpos, &ypos); 115 glfwGetMonitorPhysicalSize(mt, &widthMM, &heightMM); 116 const(GLFWvidmode)* mode = glfwGetVideoMode(mt); 117 printf("Monitor `%s` has size %dx%d mm\n", glfwGetMonitorName(mt), widthMM, heightMM); 118 printf(" current video mode: %dx%d %dHz r%dg%db%d\n", mode.width, mode.height, mode.refreshRate, mode.redBits, mode.greenBits, mode.blueBits); 119 printf(" position: %d, %d\n", xpos, ypos); 120 glfwGetMonitorWorkarea(mt, &xpos, &ypos, &width, &height); 121 printf(" work area: %d, %d to %d, %d\n", xpos, ypos, width, height); 122 } 123 } 124 125 void printJoystickState() { 126 for (int js = GLFW_JOYSTICK_1; js <= GLFW_JOYSTICK_LAST; js++) { 127 if (glfwJoystickPresent(js)) { 128 printf("Joystick %d has name `%s` and GUID `%s`\n", js, glfwGetJoystickName(js), glfwGetJoystickGUID(js)); 129 int buttonsLength, axesLength, hatsLength; 130 const(ubyte)* buttonsPtr = glfwGetJoystickButtons(js, &buttonsLength); 131 const(float)* axesPtr = glfwGetJoystickAxes(js, &axesLength); 132 const(ubyte)* hatsPtr = glfwGetJoystickHats(js, &hatsLength); 133 const(ubyte)[] buttons = buttonsPtr[0..buttonsLength]; 134 const(float)[] axes = axesPtr[0..axesLength]; 135 const(ubyte)[] hats = hatsPtr[0..hatsLength]; 136 137 if (glfwJoystickIsGamepad(js)) { 138 printf(" It is a gamepad with name `%s`\n", glfwGetGamepadName(js)); 139 GLFWgamepadstate state; 140 if (glfwGetGamepadState(js, &state)) { 141 // 142 printf("Left stick: %f,%f\n", state.axes[GLFW_GAMEPAD_AXIS_LEFT_X], state.axes[GLFW_GAMEPAD_AXIS_LEFT_Y]); 143 printf("A: %d, B: %d\n", state.buttons[GLFW_GAMEPAD_BUTTON_A], state.buttons[GLFW_GAMEPAD_BUTTON_B]); 144 } 145 } 146 } else { 147 //printf("Joystick %d not present\n", js); 148 } 149 } 150 }