/* Copyright (C) 2009 Red Hat, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef _H_RED_WINDOW #define _H_RED_WINDOW #include "red_drawable.h" #include #include "red_key.h" #include "red_window_p.h" #include "cursor.h" class Menu; class Icon; class RedWindow: public RedDrawable, private RedWindow_p { public: class Listener; enum { DEFAULT_SCREEN = -1, }; RedWindow(RedWindow::Listener& listener, int screen_id = DEFAULT_SCREEN); virtual ~RedWindow(); void move_and_resize(int x, int y, int width, int height); void resize(int width, int height); void move(int x, int y); void position_after(RedWindow *after); void raise(); void show(int screen_id); void external_show(); void hide(); void minimize(); void activate(); void set_title(std::string& title); void set_icon(Icon *icon); virtual RedDrawable::Format get_format(); enum Type { TYPE_INVALID, TYPE_NORMAL, TYPE_FULLSCREEN, }; void set_type(Type type) { _type = type;} SpicePoint get_position(); virtual SpicePoint get_size(); bool get_mouse_anchor_point(SpicePoint& pt); void set_mouse_position(int x, int y); void set_cursor(LocalCursor* local_cursor); void hide_cursor(); void show_cursor(); void capture_mouse(); void release_mouse(); void start_key_interception(); void stop_key_interception(); int set_menu(Menu* menu); #ifdef USE_OPENGL void untouch_context(); RedGlContext create_context_gl(); RedPbuffer create_pbuff(int width, int height); void set_render_pbuff(RedPbuffer pbuff); void set_render_fbo(GLuint fbo); void set_gl_context(RedGlContext context); void set_type_gl(); void unset_type_gl(); #endif int get_screen_num(); static void init(); static void cleanup(); Listener& get_listener() { return _listener;} private: void on_focus_in(); void on_focus_out(); void on_pointer_enter(int x, int y, unsigned int buttons_state); void on_pointer_leave(); void do_start_key_interception(); void do_stop_key_interception(); private: Listener& _listener; SpicePoint _window_size; Type _type; LocalCursor* _local_cursor; bool _cursor_visible; bool _trace_key_interception; bool _key_interception_on; Menu* _menu; friend class RedWindow_p; }; class RedWindow::Listener { public: virtual ~Listener() {} virtual void on_exposed_rect(const SpiceRect& area) = 0; virtual void on_pointer_enter(int x, int y, unsigned int buttons_state) = 0; virtual void on_pointer_motion(int x, int y, unsigned int buttons_state) = 0; virtual void on_pointer_leave() = 0; virtual void on_mouse_button_press(SpiceMouseButton button, unsigned int buttons_state) = 0; virtual void on_mouse_button_release(SpiceMouseButton button, unsigned int buttons_state) = 0; virtual void on_key_press(RedKey key) = 0; virtual void on_key_release(RedKey key) = 0; virtual void on_char(uint32_t ch) = 0; virtual void on_deactivate() = 0; virtual void on_activate() = 0; virtual void on_start_key_interception() = 0; virtual void on_stop_key_interception() = 0; virtual void enter_modal_loop() = 0; virtual void exit_modal_loop() = 0; virtual void pre_migrate() { } virtual void post_migrate() { } }; /*class REGION { void get_bbox(SpiceRect& bbox) const; bool contains_point(int x, int y) const; };*/ template static bool find_anchor_point(const REGION& region, SpicePoint& pt) { static const unsigned int lookup_size = 20; unsigned int width; unsigned int height; SpiceRect bbox; region.get_bbox(bbox); width = bbox.right - bbox.left; height = bbox.bottom - bbox.top; int div = 2; for (;;) { unsigned int h_unit; unsigned int v_unit; if ((v_unit = height / div) * 2 < lookup_size || (h_unit = width / div) * 2 < lookup_size) { return false; } for (unsigned int y = v_unit; y < v_unit * div; y += v_unit * 2) { for (unsigned int x = h_unit; x < h_unit * div; x += h_unit * 2) { if (!region.contains_point(bbox.left + x, bbox.top + y)) { continue; } SpiceRect r; r.left = bbox.left + x - lookup_size / 2; r.right = r.left + lookup_size; r.top = bbox.top + y - lookup_size / 2; r.bottom = r.top + lookup_size; if (!region.contains_point(r.left, r.top) || !region.contains_point(r.right, r.top) || !region.contains_point(r.left, r.bottom) || !region.contains_point(r.right, r.bottom)) { continue; } pt.x = bbox.left + x; pt.y = bbox.top + y; return true; } } div *= 2; } } #endif