core/vgui/impl/gtk2/vgui_gtk2_adaptor.h
Go to the documentation of this file.
00001 // This is core/vgui/impl/gtk2/vgui_gtk2_adaptor.h
00002 #ifndef vgui_gtk2_adaptor_h_
00003 #define vgui_gtk2_adaptor_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \author Philip C. Pritchett, Robotics Research Group, University of Oxford
00010 // \date   19 Dec 99
00011 // \brief  The GTK implementation of vgui_adaptor.
00012 //
00013 // \verbatim
00014 //  Modifications
00015 //   07-JAN-2011 Lianqing Yu 
00016 //   Change the way of connecting GDK events to the callback functions.
00017 //   In original code, all GDK events are connected to a single callback 
00018 //   function. This results in the unavailability of GL context after
00019 //   adaptor initialization, and thus failure of OpenGL function calls.
00020 //   The new method fixes this bug.
00021 //   Run the vgui example example_gllist_tableau.cxx to see the result of
00022 //   generating OpenGL display list during initialization of tableau tree.
00023 // \endverbatim
00024 
00025 #include <vgui/vgui_adaptor.h>
00026 #include <vgui/internals/vgui_adaptor_mixin.h>
00027 #include <vcl_map.h>
00028 
00029 #include <gtk/gtk.h>
00030 
00031 struct vgui_overlay_helper;
00032 class vgui_gtk2_window;
00033 
00034 //: The GTK implementation of vgui_adaptor.
00035 class vgui_gtk2_adaptor : public vgui_adaptor, public vgui_adaptor_mixin
00036 {
00037  public:
00038   typedef vgui_adaptor_mixin mixin;
00039 
00040   vgui_gtk2_adaptor(vgui_gtk2_window* win = 0);
00041   ~vgui_gtk2_adaptor();
00042 
00043   // vgui_adaptor methods
00044   void swap_buffers();
00045   void make_current();
00046   void post_redraw();
00047   void post_overlay_redraw();
00048   void post_timer(float,int);
00049   void post_destroy();  // schedules destruction of parent vgui_window
00050 
00051   void kill_timer(int);
00052 
00053   unsigned get_width() const {return mixin::width;}
00054   unsigned get_height() const {return mixin::height;}
00055   void bind_popups(vgui_modifier m, vgui_button b)
00056   { mixin::popup_modifier = m; mixin::popup_button = b; }
00057   void get_popup_bindings(vgui_modifier &m, vgui_button &b) const
00058   { m = mixin::popup_modifier; b = mixin::popup_button; }
00059 
00060   void set_default_popup(vgui_menu);
00061   vgui_menu get_popup();
00062 
00063   void draw();
00064   void reshape();
00065 
00066   // Do any idle processing that needs to be done.
00067   // Return true if idle processing is not complete
00068   bool do_idle();
00069 
00070   //: Flags than a child requests idle processing
00071   void post_idle_request();
00072 
00073   // Returns NULL if the empty constructor was used
00074   vgui_window* get_window() const;
00075 
00076   // gtk stuff
00077   GtkWidget *get_glarea_widget() { return widget; }
00078 
00079  private:
00080   // main GDK-to-vgui event dispatcher
00081   static gint handle(const vgui_event&, GtkWidget*, GdkEvent*, gpointer);
00082   static gint handle_configure(GtkWidget*, GdkEvent*, gpointer);
00083   static gint handle_draw(GtkWidget*, GdkEvent*, gpointer);
00084   static gint handle_motion_notify(GtkWidget*, GdkEvent*, gpointer);
00085   static gint handle_button(GtkWidget*, GdkEvent*, gpointer);
00086   static gint handle_key(GtkWidget*, GdkEvent*, gpointer);
00087   static gint handle_enter_leave(GtkWidget*, GdkEvent*, gpointer);
00088 
00089   // idle callbacks which service pending redraw/destroy posts
00090   static gint idle_callback_for_redraw(gpointer data);
00091   static gint idle_callback_for_tableaux(gpointer data);
00092   static gint idle_callback_for_destroy(gpointer data);
00093 
00094   // Flags to prevent queuing of multiple redraw/destroy callbacks
00095   bool redraw_requested;
00096   bool destroy_requested;
00097 
00098   //: True while an idle time has been requested but not implemented.
00099   bool idle_request_posted_;
00100 
00101   // pointer to the gtkglarea widget
00102   GtkWidget *widget;
00103 
00104   // pointer to the window which contains this adaptor
00105   vgui_gtk2_window* win_;
00106 
00107   // pointer to overlay emulation data
00108   vgui_overlay_helper *ovl_helper;
00109 
00110   //: internal struct for timer
00111   struct internal_timer{
00112     gint real_id_;
00113     void* callback_ptr_;
00114     
00115     internal_timer() : real_id_(0), callback_ptr_(0) { }
00116     internal_timer(gint id, void* p) 
00117     : real_id_(id), callback_ptr_(p) { }
00118   };
00119     
00120   // map of timers currently in use
00121   vcl_map<int, internal_timer>  timers_;
00122   
00123   // This is a place to store any menu passed in,
00124   // so that it doesn't go out of scope while the popup is on screen.
00125   static vgui_menu last_popup;
00126 
00127   // last position where mouse was seen.
00128   int last_mouse_x, last_mouse_y;
00129 };
00130 
00131 #endif // vgui_gtk2_adaptor_h_