LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: SetWindowLong(hWnd, GWL_USERDATA, LONG(LPCREATESTRUCT(lParam)->lpCreateParams)); break; case WM_DESTROY: PostQuitMessage(0); printf("Destroy\n"); return 0; break; default: DisplayWindow* displayWindow = (DisplayWindow*)GetWindowLong(hWnd, GWL_USERDATA); if (displayWindow != NULL) { return displayWindow->handleMessage(hWnd, msg, wParam, lParam); } else { return DefWindowProc(hWnd, msg, wParam, lParam); } break; } return 0; }
WindowManagerProvider::WindowManagerProvider(DisplayWindow window) : window(window), canvas(window.get_gc()), site(0), focus(0), mouse_capture(0), scale(1.0f), mouse_enabled(true), enabled(false) { slots.connect(window.sig_resize(), this, &WindowManagerProvider::on_displaywindow_resize); InputContext ic = window.get_ic(); slots.connect(ic.get_mouse().sig_key_up(), this, &WindowManagerProvider::on_mouse_input_received); slots.connect(ic.get_mouse().sig_key_down(), this, &WindowManagerProvider::on_mouse_input_received); slots.connect(ic.get_mouse().sig_key_dblclk(), this, &WindowManagerProvider::on_mouse_input_received); slots.connect(ic.get_mouse().sig_pointer_move(), this, &WindowManagerProvider::on_mouse_input_received); slots.connect(ic.get_keyboard().sig_key_up(), this, &WindowManagerProvider::on_input_received); slots.connect(ic.get_keyboard().sig_key_down(), this, &WindowManagerProvider::on_input_received); for (int i = 0; i < ic.get_tablet_count(); ++i) { slots.connect(ic.get_tablet(i).sig_axis_move(), this, &WindowManagerProvider::on_mouse_input_received); slots.connect(ic.get_tablet(i).sig_key_down(), this, &WindowManagerProvider::on_mouse_input_received); slots.connect(ic.get_tablet(i).sig_key_dblclk(), this, &WindowManagerProvider::on_mouse_input_received); slots.connect(ic.get_tablet(i).sig_key_up(), this, &WindowManagerProvider::on_mouse_input_received); slots.connect(ic.get_tablet(i).sig_proximity_change(), this, &WindowManagerProvider::on_mouse_input_received); } #ifdef WIN32 DataBuffer ani_file = File::read_bytes("Resources/Engine/Cursors/NormalSelect.ani"); int desired_width = 32; int desired_height = 32; cursor = (HCURSOR)CreateIconFromResourceEx((PBYTE) ani_file.get_data(), ani_file.get_size(), FALSE, 0x00030000, desired_width, desired_height, LR_DEFAULTCOLOR); if (cursor == 0) throw Exception("CreateIconFromResourceEx failed!"); #endif }
void WindowSetting::setRecorder(Recorder* recorder) { if ((recorder_ = recorder)) { mainWindow_.number_ = recorder_->recorderWindow() == Primary ? 1 : 2; mainWindow_.geometry_ = recorder_->saveGeometry(); mainWindow_.size_ = recorder_->size(); mainWindow_.pos_ = recorder_->pos(); mainWindow_.state_ = recorder_->saveState(); DisplayWindow* dw = 0; QMdiSubWindow* activeSubWindow = static_cast<QMdiArea*>( recorder_->centralWidget())->currentSubWindow(); subWindowList_ = static_cast<QMdiArea*>( recorder_->centralWidget())->subWindowList(); for (int i = 0; i < subWindowList_.size(); ++i) { dw = static_cast<DisplayWindow*>(subWindowList_[i]->widget()); subWindowKeys_ << dw->key(); if (subWindowList_[i] == activeSubWindow) activeSubWindowKey_ = dw->key(); subWindows_[i].key_ = dw->key(); subWindows_[i].geometry_ = subWindowList_[i]->saveGeometry(); subWindows_[i].size_ = subWindowList_[i]->size(); subWindows_[i].pos_ = subWindowList_[i]->pos(); } } }
static Uint32 TimerTick(Uint32 interval, void *param) { DisplayWindow *dw = (DisplayWindow *)param; dw->Tick(); return interval; }
int main(int argc, char *argv[]) { QApplication a(argc, argv); DisplayWindow w; w.show(); return a.exec(); }
bool TextWindowHandler::handleKey(const InputEvent &e) { DisplayWindow * d; e.fprint( stderr ); InputState * wimp = _wm->wimp(); wimp->setEvent(e); bool ret = false; if (wimp->ctrlDown ) { bool ret = true; switch ( wimp->lastKey ) { case KEY_CTRL_N: fprintf(stderr,"Make new window\n"); d = new DisplayWindow(); d->setContent(new TextContent()); _wm->addWindow(d); d->moveto(wimp->lastPos[0], wimp->lastPos[1] ); break; case KEY_CTRL_F: case KEY_CTRL_O: //create new window and pass the call down... if ( !_wm->top()) { DirScanner dr; fileData * f = dr.openFileDialog(); fileData * nf = f; int c = 0; while ( nf ) { EM_log( CK_LOG_INFO, "(audicle) opening file %d : %s", c, nf->fileName.c_str()); d = new DisplayWindow(); TextContent * ntext = new TextContent(); ntext->open((char*)nf->fileName.c_str()); d->setContent(ntext); Point2D np = wimp->lastPos + Point2D(0.03, -0.03 ) * (double)c; d->moveto(np[0], np[1] ); _wm->addWindow(d); _wm->setTopWindow(d); c++; nf = nf->next; } } break; default: ret = false; } } return ret; }
GUIWindowManagerProvider_Direct::GUIWindowManagerProvider_Direct(DisplayWindow &display_window, Canvas &canvas) : site(0), activated_window(0), capture_mouse_window(NULL), display_window(display_window), window_canvas(canvas) { slots.connect(display_window.sig_window_close(), this, &GUIWindowManagerProvider_Direct::on_displaywindow_window_close); InputContext ic = display_window.get_ic(); slots.connect(ic.get_mouse().sig_key_up(), this, &GUIWindowManagerProvider_Direct::on_input_mouse_up); slots.connect(ic.get_mouse().sig_key_down(), this, &GUIWindowManagerProvider_Direct::on_input_mouse_down); slots.connect(ic.get_mouse().sig_key_dblclk(), this, &GUIWindowManagerProvider_Direct::on_input_mouse_down); slots.connect(ic.get_mouse().sig_pointer_move(), this, &GUIWindowManagerProvider_Direct::on_input_mouse_move); slots.connect(ic.get_keyboard().sig_key_up(), this, &GUIWindowManagerProvider_Direct::on_input); slots.connect(ic.get_keyboard().sig_key_down(), this, &GUIWindowManagerProvider_Direct::on_input); for (int tc = 0; tc < ic.get_tablet_count(); ++tc) { slots.connect(ic.get_tablet(tc).sig_axis_move(), this, &GUIWindowManagerProvider_Direct::on_input_mouse_move); slots.connect(ic.get_tablet(tc).sig_key_dblclk(), this, &GUIWindowManagerProvider_Direct::on_input_mouse_down); slots.connect(ic.get_tablet(tc).sig_key_down(), this, &GUIWindowManagerProvider_Direct::on_input_mouse_down); slots.connect(ic.get_tablet(tc).sig_key_up(), this, &GUIWindowManagerProvider_Direct::on_input); } }
void App::render(DisplayWindow &window, GameTime &game_time) { canvas.clear(Colorf(0.0f,0.0f,0.2f, 1.0f)); root->update(); canvas.set_blend_state(premultiply_src_blend); gui_image.draw(canvas, 0, 0); canvas.reset_blend_state(); draw_font_example(); draw_font_info(); last_fps = game_time.get_updates_per_second(); window.flip(1); }
void App::render(DisplayWindow &window, GameTime &game_time) { canvas.set_map_mode(MapMode(map_2d_upper_left)); canvas.clear(Colorf(0.0f,0.0f,0.2f, 1.0f)); gui_manager.draw_windows(canvas); draw_font_example(); draw_font_info(); last_fps = game_time.get_updates_per_second(); gui_manager.process(); window.flip(1); KeepAlive::process(); }
Cursor::Cursor(const DisplayWindow &window, const CursorDescription &cursor_description) : impl(std::make_shared<Cursor_Impl>()) { impl->provider = window.get_provider()->create_cursor(cursor_description); }
void GameObject_Pacman::AttachKeyboard(DisplayWindow &window) { slots.connect(window.get_ic().get_keyboard().sig_key_down(), this, &GameObject_Pacman::on_key_down); }
void Canvas_Impl::init(DisplayWindow &window) { GraphicContext new_gc = window.get_gc().create(); current_window = window; setup(new_gc); }
void X11Window::create(XVisualInfo *visual, DisplayWindowSite *new_site, const DisplayWindowDescription &desc) { site = new_site; // Reset all variables close_window(); handle.screen = visual->screen; atoms = X11Atoms(handle.display); int disp_width_px = XDisplayWidth(handle.display, handle.screen); int disp_height_px = XDisplayHeight(handle.display, handle.screen); int disp_width_mm = XDisplayWidthMM(handle.display, handle.screen); // Get DPI of screen or use 96.0f if Xlib doesn't have a value. ppi = (disp_width_mm < 24) ? 96.0f : (25.4f * static_cast<float>(disp_width_px) / static_cast<float>(disp_width_mm)); // Update pixel ratio. set_pixel_ratio(pixel_ratio); // Get X11 root window. auto _root_window = RootWindow(handle.display, handle.screen); // Get and validate initial window position and size. int win_x = desc.get_position().left * pixel_ratio; int win_y = desc.get_position().top * pixel_ratio; int win_width = desc.get_size().width * pixel_ratio; int win_height = desc.get_size().height * pixel_ratio; if (win_width <= 0) throw Exception("Invalid window width."); if (win_height <= 0) throw Exception("Invalid window height."); // Set values if fullscreen requested. if (desc.is_fullscreen()) { win_x = 0; win_y = 0; win_width = disp_width_px; win_height = disp_height_px; } // Center window if position supplied is (-1, -1) if (win_x == -1 && win_y == -1) { win_x = (disp_width_px - win_width)/2 - 1; win_y = (disp_height_px - win_height)/2 - 1; } // Set minimum and maximum size this->resize_allowed = desc.get_allow_resize() || desc.is_fullscreen(); // Fullscreen mode needs a resizable window. if (resize_allowed) { minimum_size = Size(_ResizeMinimumSize_, _ResizeMinimumSize_); maximum_size = Size(0, 0); // No maximum size by default. } else { minimum_size = Size(win_width, win_height); maximum_size = Size(win_width, win_height); } // Setup X11 size hints. this->size_hints = XAllocSizeHints(); if (size_hints == NULL) throw Exception("Failed to allocate X11 XSizeHints structure."); size_hints->flags = PMinSize | (resize_allowed ? 0 : PMaxSize); size_hints->flags |= PResizeInc | PBaseSize | PWinGravity; // x, y, width, height are obsolete. size_hints->flags |= USSize | USPosition; // See http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472522864 size_hints->min_width = minimum_size.width; size_hints->min_height = minimum_size.height; size_hints->max_width = maximum_size.width; size_hints->max_height = maximum_size.height; size_hints->width_inc = 1; size_hints->height_inc = 1; size_hints->base_width = win_width; size_hints->base_height = win_height; size_hints->win_gravity = NorthWestGravity; // Setup X11 colormap. // // The X.Org XServer implementation used on most systems requires that // a color-map be set for the window. Additionally, windows with a // different color-depth than its parent must have the border-pixel flag // set when creating them. Failure to do either will cause XCreateWindow() // to result in a BadMatch error. // // Source: stackoverflow.com/questions/3645632 color_map = XCreateColormap(handle.display, _root_window, visual->visual, AllocNone); // Static popups are unresizable captionless popup windows. // These windows should not be decorated. bool is_static_popup = desc.is_popup() && !desc.has_caption() && !desc.get_allow_resize(); // Tell X11 to perserve graphical content under small popup windows to avoid redraws. bool save_under = desc.is_popup() && ( (win_width * win_height) < (256 * 256 * pixel_ratio * pixel_ratio) ); // Setup window attributes. XSetWindowAttributes attr = XSetWindowAttributes { .background_pixmap = None, /* default */ .background_pixel = 0ul, /* default: undefined */ .border_pixmap = CopyFromParent, /* default */ .border_pixel = 0ul, /* see color_map details above */ .bit_gravity = ForgetGravity, /* default */ .win_gravity = NorthWestGravity, /* default */ .backing_store = NotUseful, /* default */ .backing_planes = -1ul, /* default */ .backing_pixel = 0ul, /* default */ .save_under = save_under ? True : False, .event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask | ExposureMask // | VisibilityChangeMask | StructureNotifyMask | FocusChangeMask | PropertyChangeMask , .do_not_propagate_mask = NoEventMask, /* default */ .override_redirect = is_static_popup ? True : False, .colormap = color_map, /* see color_map details above */ .cursor = None /* default; Let X11 handle the cursor for now. */ }; this->system_cursor = XCreateFontCursor(handle.display, XC_left_ptr); // This is allowed to fail log_event("debug", "clan::X11Window::create(): Creating window..."); log_event("debug", " x%1 y%2 w%3 h%4 b%5 d%6", win_x, win_y, win_width, win_height, border_width, visual->depth); log_event("debug", " a.su%1, a.od%2", save_under, is_static_popup); // Create window handle.window = XCreateWindow( handle.display, _root_window, win_x, win_y, win_width, win_height, border_width, visual->depth, InputOutput, visual->visual, CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap, &attr ); if (!handle.window) throw Exception("Unable to create the X11 window"); if (!desc.get_owner().is_null()) { DisplayWindow owner = desc.get_owner(); XSetTransientForHint(handle.display, handle.window, owner.get_handle().window); } // Setup the hidden cursor (Maybe this should be done only once when required) char data[64]; // 8x8 memset(data, 0, 64); XColor black_color; memset(&black_color, 0, sizeof(black_color)); cursor_bitmap = XCreateBitmapFromData(handle.display, handle.window, data, 8, 8); hidden_cursor = XCreatePixmapCursor(handle.display, cursor_bitmap, cursor_bitmap, &black_color, &black_color, 0,0); // Set title of window: set_title(desc.get_title()); { // Inform the window manager who we are, so it can kill us if we're not good for its universe. Atom atom; int32_t pid = getpid(); if (pid > 0) { atom = atoms.get_atom(handle.display, "_NET_WM_PID", False); XChangeProperty(handle.display, handle.window, atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &pid, 1); } char hostname[256]; if (gethostname(hostname, sizeof(hostname)) > -1) { hostname[255] = 0; atom = atoms.get_atom(handle.display, "WM_CLIENT_MACHINE", False); XChangeProperty(handle.display, handle.window, atom, XA_STRING, 8, PropModeReplace, (unsigned char *) hostname, strlen(hostname)); } } // Set-up window type/styling. // TODO Support more window types, broaden ClanLib window type support, etc. if (atoms["_NET_WM_WINDOW_TYPE"] != None) { Atom type = None; std::string name; if (desc.is_dialog()) { name = "_NET_WM_WINDOW_TYPE_DIALOG"; type = atoms[name]; } else if (desc.is_popup()) { if (is_static_popup) { name = "_NET_WM_WINDOW_TYPE_TOOLTIP"; type = atoms[name]; } else if (desc.has_caption()) // A pop-up with title bar -> utility { name = "_NET_WM_WINDOW_TYPE_UTILITY"; type = atoms[name]; } // else, a pop-up without a title bar -> popup-menu, combo, dropdown, tooltip, ... if (type == None) { name = "_NET_WM_WINDOW_TYPE_POPUP_MENU"; type = atoms[name]; } if (type == None) { name = "_NET_WM_WINDOW_TYPE_COMBO"; type = atoms[name]; } if (type == None) { name = "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"; type = atoms[name]; } } // else if (desc.is_normal()) // Fallback to normal window type if WM doesn't support what we want. if (type == None) { name = "_NET_WM_WINDOW_TYPE_NORMAL"; type = atoms[name]; } if (type != None) // Ensure selected type exists. { XChangeProperty(handle.display, handle.window, atoms["_NET_WM_WINDOW_TYPE"], XA_ATOM, 32, PropModeReplace, (unsigned char *)&type, 1); log_event("debug", "clan::X11Window::create(): Creating window of type '%1'.", name); } else { log_event("debug", "clan::X11Window::create(): Failed to find a suitable window type."); } } else { log_event("debug", "clan::X11Window::create(): _NET_WM_WINDOW_TYPE does not exist."); } // Set size hints XSetWMNormalHints(handle.display, handle.window, size_hints); { // Subscribe to WM events. Atom protocol = atoms["WM_DELETE_WINDOW"]; Status result = XSetWMProtocols(handle.display, handle.window, &protocol, 1); if (result == 0) log_event("debug", "clan::X11Window::create(): Failed to set WM_PROTOCOLS."); } { // Make auto-repeat keys detectable. Bool supports_detectable_autorepeat; XkbSetDetectableAutoRepeat(handle.display, True, &supports_detectable_autorepeat); } { // Make window full-screen if requested. if (atoms["_NET_WM_STATE"] == None && atoms["_NET_WM_STATE_FULLSCREEN"]) { fullscreen = false; log_event("debug", "clan::X11Window: Fullscreen not supported by WM."); } else { fullscreen = desc.is_fullscreen(); } if (fullscreen) { Atom state = atoms["_NET_WM_STATE_FULLSCREEN"]; XChangeProperty(handle.display, handle.window, atoms["_NET_WM_STATE"], XA_ATOM, 32, PropModeReplace, (unsigned char *)&state, 1); } } update_frame_extents(); auto new_client_area = desc.get_position_client_area() // supplied position is at ? client area : window area; ? Rect::xywh(win_x, win_y, win_width, win_height) : Rect::xywh(win_x + frame_extents.left, win_y + frame_extents.right, win_width, win_height) ; process_window_resize(new_client_area); // Set window visibility if (desc.is_visible()) { show(false); } // Setup the clipboard clipboard.setup(); // Go looking for joysticks: setup_joysticks(); } void X11Window::update_frame_extents() { frame_extents = Rect { border_width, border_width, border_width, border_width }; if (atoms["_NET_FRAME_EXTENTS"] == None) return; // Request frame extents from WM. if (atoms["_NET_REQUEST_FRAME_EXTENTS"] != None) { XEvent event; memset(&event, 0, sizeof(event)); event.type = ClientMessage; event.xclient.window = handle.window; event.xclient.format = 32; event.xclient.message_type = atoms["_NET_REQUEST_FRAME_EXTENTS"]; XSendEvent(handle.display, RootWindow(handle.display, handle.screen), False, SubstructureNotifyMask | SubstructureRedirectMask, &event); int timer = 10; while(true) { if (timer < 0) { log_event("debug", "clan::X11Window: Your window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation."); break; } if (XCheckMaskEvent(handle.display, PropertyNotify, &event)) { break; } clan::System::sleep(5); timer--; } } unsigned long item_count; // _NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32 unsigned char *data = atoms.get_property(handle.window, "_NET_FRAME_EXTENTS", item_count); if (data == NULL) return; if (item_count >= 4) { long *cardinal = (long *)data; frame_extents.left = cardinal[0]; frame_extents.right = cardinal[1]; frame_extents.top = cardinal[2]; frame_extents.bottom = cardinal[3]; } XFree(data); }
void DisplayWindow::staticMouseCallback(int event, int x, int y, int flags, void* param){ DisplayWindow *self = static_cast<DisplayWindow*>(param); self->mouseCallback(event, x, y, flags, param); }