2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 //-----------------------------------------------------------------------------
25 // implementation of IMessaging specific interface
30 CPtrArray l_Listeners[RADIANT_MSGCOUNT];
31 CPtrArray l_WindowListeners;
32 CXYWndWrapper l_XYWndWrapper;
34 // CGtkWindow implementation -------------------------------------
36 static void button_press( GtkWidget *widget, GdkEventButton *event, gpointer data ){
37 IWindowListener *pListen = static_cast<IWindowListener *>( data );
38 switch ( event->button )
41 pListen->OnLButtonDown( event->state, event->x, event->y ); break;
43 pListen->OnRButtonDown( event->state, event->x, event->y ); break;
47 static void button_release( GtkWidget *widget, GdkEventButton *event, gpointer data ){
48 IWindowListener *pListen = static_cast<IWindowListener *>( data );
49 switch ( event->button )
52 pListen->OnLButtonUp( event->state, event->x, event->y ); break;
54 pListen->OnRButtonUp( event->state, event->x, event->y ); break;
58 static void motion( GtkWidget *widget, GdkEventMotion *event, gpointer data ){
59 IWindowListener *pListen = static_cast<IWindowListener *>( data );
60 pListen->OnMouseMove( event->state, event->x, event->y );
63 static gint expose( GtkWidget *widget, GdkEventExpose *event, gpointer data ){
64 if ( event->count > 0 ) {
68 CGtkWindow *pWindow = static_cast<CGtkWindow *>( data );
74 // we use the string versions of the keys for now..
75 static gint keypress( GtkWidget* widget, GdkEventKey* event, gpointer data ){
78 IWindowListener *pListen = static_cast<IWindowListener *>( data );
79 ret = pListen->OnKeyPressed( gdk_keyval_name( event->keyval ) );
81 gtk_signal_emit_stop_by_name( GTK_OBJECT( widget ), "key_press_event" );
86 // close_widget is not hooked on the listener but on the CGtkWindow object to handle the closure
87 static gint close_widget( GtkWidget *widget, GdkEvent* event, gpointer data ){
88 CGtkWindow *pWindow = static_cast<CGtkWindow *>( data );
94 void CGtkWindow::DoExpose(){
95 gtk_glwidget_make_current( m_pGLWidget );
96 if ( m_pListen->Paint() ) {
97 gtk_glwidget_swap_buffers( m_pGLWidget );
101 void CGtkWindow::Redraw(){
102 gtk_widget_queue_draw( m_pGLWidget );
105 void CGtkWindow::Close(){
106 // similar to a destructor, except we warn first
108 m_pListen->DecRef(); m_pListen = NULL;
109 gtk_widget_destroy( m_pWnd ); m_pWnd = NULL;
112 bool CGtkWindow::Show(){
113 // check we got everything and are reading to instanciate
114 if ( m_nWidthParam == 0 || m_nHeightParam == 0 ) {
115 Sys_FPrintf( SYS_ERR, "Height and Width params not set in CGtkWindow::Show\n" );
119 Sys_FPrintf( SYS_ERR, "No listener set in CGtkWindow::Show\n" );
123 // seems all good, here we go
124 m_pWnd = gtk_window_new( GTK_WINDOW_TOPLEVEL );
125 gtk_window_set_title( GTK_WINDOW( m_pWnd ), m_Name.GetBuffer() );
126 gtk_window_set_default_size( GTK_WINDOW( m_pWnd ), m_nWidthParam, m_nHeightParam );
127 gtk_widget_show( m_pWnd );
129 // GL widget creation
130 m_pGLWidget = gtk_glwidget_new( FALSE, g_qeglobals_gui.d_glBase );
132 gtk_widget_set_events( m_pGLWidget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK |
133 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK );
135 // Connect signal handlers
136 gtk_signal_connect( GTK_OBJECT( m_pGLWidget ), "expose_event", GTK_SIGNAL_FUNC( expose ), this );
137 gtk_signal_connect( GTK_OBJECT( m_pGLWidget ), "motion_notify_event",
138 GTK_SIGNAL_FUNC( motion ), m_pListen );
139 gtk_signal_connect( GTK_OBJECT( m_pGLWidget ), "button_press_event",
140 GTK_SIGNAL_FUNC( button_press ), m_pListen );
141 gtk_signal_connect( GTK_OBJECT( m_pGLWidget ), "button_release_event",
142 GTK_SIGNAL_FUNC( button_release ), m_pListen );
144 gtk_signal_connect( GTK_OBJECT( m_pWnd ), "delete_event", GTK_SIGNAL_FUNC( close_widget ), this );
145 gtk_signal_connect( GTK_OBJECT( m_pWnd ), "key_press_event",
146 GTK_SIGNAL_FUNC( keypress ), m_pListen );
148 gtk_widget_show( m_pGLWidget );
149 gtk_container_add( GTK_CONTAINER( m_pWnd ), m_pGLWidget );
154 IWindow* WINAPI QERApp_CreateGLWindow(){
155 return new CGtkWindow;
158 void WINAPI QERApp_HookWindow( IWindowListener* pListen ){
159 l_WindowListeners.Add( pListen );
163 void WINAPI QERApp_UnHookWindow( IWindowListener* pListen ){
164 for ( int i = 0; i < l_WindowListeners.GetSize(); i++ )
166 if ( l_WindowListeners.GetAt( i ) == pListen ) {
167 l_WindowListeners.RemoveAt( i );
173 Sys_Printf( "WARNING: IWindowListener not found in QERApp_UnHookWindow\n" );
177 void DispatchOnMouseMove( guint32 nFlags, int x, int y ){
178 for ( int i = 0; i < l_WindowListeners.GetSize(); i++ )
179 static_cast<IWindowListener*>( l_WindowListeners.GetAt( i ) )->OnMouseMove( nFlags, x, y );
182 bool DispatchOnLButtonDown( guint32 nFlags, int x, int y ){
183 for ( int i = 0; i < l_WindowListeners.GetSize(); i++ )
184 if ( static_cast<IWindowListener*>( l_WindowListeners.GetAt( i ) )->OnLButtonDown( nFlags, x, y ) ) {
190 bool DispatchOnLButtonUp( guint32 nFlags, int x, int y ){
191 for ( int i = 0; i < l_WindowListeners.GetSize(); i++ )
192 if ( static_cast<IWindowListener*>( l_WindowListeners.GetAt( i ) )->OnLButtonUp( nFlags, x, y ) ) {
198 void WINAPI QERApp_HookListener( IListener* pListen, int Msg ){
200 if ( Msg >= RADIANT_MSGCOUNT ) {
201 Sys_Printf( "ERROR: bad index in QERApp_HookListener\n" );
205 l_Listeners[Msg].Add( pListen );
209 int WINAPI QERApp_UnHookListener( IListener* pListen ){
211 for ( int i = 0; i < RADIANT_MSGCOUNT; i++ )
212 for ( int j = 0; j < l_Listeners[i].GetSize(); j++ )
213 if ( l_Listeners[i].GetAt( j ) == pListen ) {
214 l_Listeners[i].RemoveAt( j );
221 void DispatchRadiantMsg( int Msg ){
223 if ( Msg >= RADIANT_MSGCOUNT ) {
224 Sys_Printf( "ERROR: bad index in DispatchRadiantMsg\n" );
228 for ( int i = 0; i < l_Listeners[Msg].GetSize(); i++ )
229 static_cast<IListener *>( l_Listeners[Msg].GetAt( i ) )->DispatchRadiantMsg( Msg );
232 void CXYWndWrapper::SnapToGrid( int x1, int y1, vec3_t pt ){
233 int height = g_pParentWnd->ActiveXY()->GetWidget()->allocation.height;
234 g_pParentWnd->ActiveXY()->SnapToPoint( x1, height - 1 - y1, pt );
237 VIEWTYPE CXYWndWrapper::GetViewType( void ){
238 return (VIEWTYPE)g_pParentWnd->ActiveXY()->GetViewType();
241 IXYWndWrapper* WINAPI QERApp_GetXYWndWrapper(){
242 return &l_XYWndWrapper;