/** * This function sets the height, width, x_start, y_start (upper left coords), * x_end, and y_end (lower right) variables of the student's window. These * values are used in operations such as mouse movement. returns false on * failure and does not set variables. */ bool populateWindowData(std::string window_name, int& height, int& width, int& x_start, int& x_end, int& y_start, int& y_end){ if(windowExists(window_name)) { std::vector<int> height_vec, width_vec, x_start_vec, y_start_vec; // getWindowData returns a vector of ints associated with the query term // (e.g. 'Height') height_vec = getWindowData("Height", window_name); width_vec = getWindowData("Width", window_name); //These two values represent the upper left corner x_start_vec = getWindowData("Absolute upper-left X", window_name); y_start_vec = getWindowData("Absolute upper-left Y", window_name); //The lines below should never return false, as the Height, Width, etc. //fields should always be populated if the window exists. The only way that // I can see for these to fail would be if xdotool changes or the window // fails/shuts in this block. if(height_vec.size() > 0){ height = height_vec[0];} else{ return false; } if(width_vec.size() > 0) { width = width_vec[0];} else{ return false; } if(x_start_vec.size() > 0){ x_start= x_start_vec[0];} else{ return false; } if(y_start_vec.size() > 0){ y_start= y_start_vec[0];} else{ return false; } //These values represent the upper right corner x_end = x_start+width; y_end = y_start + height; return true; } else { std::cout << "Attempted to populate window data using a nonexistent window" << std::endl; return false; } }
GlaerContext * getCurrentGlaerContext() { GLFWwindow *handle = glfwGetCurrentContext(); if (!handle) { throw window_error("no current context"); } return &(getWindowData(handle)->context); }
void Window::makeContextCurrent() { glfwMakeContextCurrent(m_handle); WindowData *wd = getWindowData(m_handle); // init glaer if (!wd->init_done) { gecom::log("Window") << "GLAER initializing..."; //GLenum t_err = glGetError(); //gecom::log("Window") << "GLEW t_err: " << t_err; if (!glaerInitCurrentContext()) { gecom::log("Window").error() << "GLAER initialization failed:"; glfwTerminate(); std::abort(); } // clear any GL errors from init GLenum gl_err = glGetError(); while (gl_err) { gecom::log("Window") << "GLAER initialization left GL error " << gl_err; gl_err = glGetError(); } //gecom::log("Window") << "GL Error: " << gluErrorString(gl_err); gecom::log("Window") << "GL version string: " << glGetString(GL_VERSION); gecom::log("Window").information(0) << "GLAER initialized"; wd->init_done = true; // enable GL_ARB_debug_output if available if (glfwExtensionSupported("GL_ARB_debug_output")) { // this allows the error location to be determined from a stacktrace glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); // set the callback glDebugMessageCallback(callbackDebugGL, this); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, true); log("Window") << "GL debug callback installed"; } else { log("Window") << "GL_ARB_debug_output not available"; } } }
bool Window::pollMouseButton(int button) { WindowData *wd = getWindowData(m_handle); bool b = wd->mb.test(button); wd->mb.reset(button); return b; }
bool Window::getMouseButton(int button) { return getWindowData(m_handle)->mb.test(button); }
bool Window::pollKey(int key) { WindowData *wd = getWindowData(m_handle); bool b = wd->vk.test(key); wd->vk.reset(key); return b; }
bool Window::getKey(int key) { return getWindowData(m_handle)->vk.test(key); }
void Window::destroy() { // must only be called from the main thread delete getWindowData(m_handle); glfwDestroyWindow(m_handle); }
static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { void *data; DWORD which; uintptr_t heldButtons = (uintptr_t) wParam; LRESULT lResult; data = getWindowData(hwnd, uMsg, wParam, lParam, &lResult); if (data == NULL) return lResult; switch (uMsg) { case WM_PAINT: paintArea(hwnd, data); return 0; case WM_ERASEBKGND: // don't draw a background; we'll do so when painting // this is to make things flicker-free; see http://msdn.microsoft.com/en-us/library/ms969905.aspx return 1; case WM_HSCROLL: scrollArea(hwnd, data, wParam, SB_HORZ); return 0; case WM_VSCROLL: scrollArea(hwnd, data, wParam, SB_VERT); return 0; case WM_SIZE: adjustAreaScrollbars(hwnd, data); return 0; case WM_ACTIVATE: // don't keep the double-click timer running if the user switched programs in between clicks areaResetClickCounter(data); return 0; case WM_MOUSEMOVE: areaMouseEvent(hwnd, data, 0, FALSE, heldButtons, lParam); return 0; case WM_LBUTTONDOWN: SetFocus(hwnd); areaMouseEvent(hwnd, data, 1, FALSE, heldButtons, lParam); return 0; case WM_LBUTTONUP: areaMouseEvent(hwnd, data, 1, TRUE, heldButtons, lParam); return 0; case WM_MBUTTONDOWN: SetFocus(hwnd); areaMouseEvent(hwnd, data, 2, FALSE, heldButtons, lParam); return 0; case WM_MBUTTONUP: areaMouseEvent(hwnd, data, 2, TRUE, heldButtons, lParam); return 0; case WM_RBUTTONDOWN: SetFocus(hwnd); areaMouseEvent(hwnd, data, 3, FALSE, heldButtons, lParam); return 0; case WM_RBUTTONUP: areaMouseEvent(hwnd, data, 3, TRUE, heldButtons, lParam); return 0; case WM_XBUTTONDOWN: SetFocus(hwnd); // values start at 1; we want them to start at 4 which = (DWORD) GET_XBUTTON_WPARAM(wParam) + 3; heldButtons = (uintptr_t) GET_KEYSTATE_WPARAM(wParam); areaMouseEvent(hwnd, data, which, FALSE, heldButtons, lParam); return TRUE; // XBUTTON messages are different! case WM_XBUTTONUP: which = (DWORD) GET_XBUTTON_WPARAM(wParam) + 3; heldButtons = (uintptr_t) GET_KEYSTATE_WPARAM(wParam); areaMouseEvent(hwnd, data, which, TRUE, heldButtons, lParam); return TRUE; case msgAreaKeyDown: return (LRESULT) areaKeyEvent(data, FALSE, wParam, lParam); case msgAreaKeyUp: return (LRESULT) areaKeyEvent(data, TRUE, wParam, lParam); case msgAreaSizeChanged: adjustAreaScrollbars(hwnd, data); repaintArea(hwnd, NULL); // this calls for an update return 0; case msgAreaGetScroll: getScrollPos(hwnd, (int *) wParam, (int *) lParam); return 0; case msgAreaRepaint: repaintArea(hwnd, (RECT *) lParam); return 0; case msgAreaRepaintAll: repaintArea(hwnd, NULL); return 0; default: return DefWindowProcW(hwnd, uMsg, wParam, lParam); } xmissedmsg("Area", "areaWndProc()", uMsg); return 0; // unreached }