void gl_close_window() { #ifdef XDLG close_x_dialog(_gl_display); #endif #ifdef XFIB x_fib_close (_gl_display); #endif glXDestroyContext(_gl_display, _gl_ctx); XDestroyWindow(_gl_display, _gl_win); XCloseDisplay(_gl_display); }
void puglDestroy(PuglView* view) { if (!view) { return; } x_fib_close(view->impl->display); destroyContext(view); XDestroyWindow(view->impl->display, view->impl->win); XCloseDisplay(view->impl->display); free(view->impl); free(view); }
PuglStatus puglProcessEvents(PuglView* view) { XEvent event; while (XPending(view->impl->display) > 0) { XNextEvent(view->impl->display, &event); if (x_fib_handle_events(view->impl->display, &event)) { const int status = x_fib_status(); if (status > 0) { char* const filename = x_fib_filename(); x_fib_close(view->impl->display); if (view->fileSelectedFunc) { view->fileSelectedFunc(view, filename); } free(filename); } else if (status < 0) { x_fib_close(view->impl->display); if (view->fileSelectedFunc) { view->fileSelectedFunc(view, NULL); } } break; } if (event.xany.window != view->impl->win) { continue; } switch (event.type) { case MapNotify: puglReshape(view, view->width, view->height); break; case ConfigureNotify: if ((event.xconfigure.width != view->width) || (event.xconfigure.height != view->height)) { puglReshape(view, event.xconfigure.width, event.xconfigure.height); } break; case Expose: if (event.xexpose.count != 0) { break; } puglDisplay(view); break; case MotionNotify: setModifiers(view, event.xmotion.state, event.xmotion.time); if (view->motionFunc) { view->motionFunc(view, event.xmotion.x, event.xmotion.y); } break; case ButtonPress: setModifiers(view, event.xbutton.state, event.xbutton.time); if (event.xbutton.button >= 4 && event.xbutton.button <= 7) { if (view->scrollFunc) { float dx = 0, dy = 0; switch (event.xbutton.button) { case 4: dy = 1.0f; break; case 5: dy = -1.0f; break; case 6: dx = -1.0f; break; case 7: dx = 1.0f; break; } view->scrollFunc(view, event.xbutton.x, event.xbutton.y, dx, dy); } break; } // nobreak case ButtonRelease: setModifiers(view, event.xbutton.state, event.xbutton.time); if (view->mouseFunc && (event.xbutton.button < 4 || event.xbutton.button > 7)) { view->mouseFunc(view, event.xbutton.button, event.type == ButtonPress, event.xbutton.x, event.xbutton.y); } break; case KeyPress: setModifiers(view, event.xkey.state, event.xkey.time); dispatchKey(view, &event, true); break; case KeyRelease: { setModifiers(view, event.xkey.state, event.xkey.time); bool repeated = false; if (view->ignoreKeyRepeat && XEventsQueued(view->impl->display, QueuedAfterReading)) { XEvent next; XPeekEvent(view->impl->display, &next); if (next.type == KeyPress && next.xkey.time == event.xkey.time && next.xkey.keycode == event.xkey.keycode) { XNextEvent(view->impl->display, &event); repeated = true; } } if (!repeated) { dispatchKey(view, &event, false); } } break; case ClientMessage: { char* type = XGetAtomName(view->impl->display, event.xclient.message_type); if (!strcmp(type, "WM_PROTOCOLS")) { if (view->closeFunc) { view->closeFunc(view); view->redisplay = false; } } XFree(type); } break; #ifdef PUGL_GRAB_FOCUS case EnterNotify: XSetInputFocus(view->impl->display, view->impl->win, RevertToPointerRoot, CurrentTime); break; #endif default: break; } } if (view->redisplay) { puglDisplay(view); } return PUGL_SUCCESS; }