mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-11-26 22:01:38 +00:00
33efc90892
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/ZeroRadiant@185 8a3a26a2-13c4-0310-b231-cf6edde360e5
287 lines
7.9 KiB
C++
287 lines
7.9 KiB
C++
/*
|
|
Copyright (c) 2001, Loki software, inc.
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
are permitted provided that the following conditions are met:
|
|
|
|
Redistributions of source code must retain the above copyright notice, this list
|
|
of conditions and the following disclaimer.
|
|
|
|
Redistributions in binary form must reproduce the above copyright notice, this
|
|
list of conditions and the following disclaimer in the documentation and/or
|
|
other materials provided with the distribution.
|
|
|
|
Neither the name of Loki software nor the names of its contributors may be used
|
|
to endorse or promote products derived from this software without specific prior
|
|
written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
//
|
|
// GLWindow - Base class for the small views used by Radiant
|
|
//
|
|
// Leonardo Zide (leo@lokigames.com
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "glwidget.h"
|
|
#include "glwindow.h"
|
|
|
|
// =============================================================================
|
|
// static functions
|
|
|
|
static void realize (GtkWidget *widget, gpointer data)
|
|
{
|
|
GLWindow *wnd = (GLWindow*)data;
|
|
|
|
wnd->OnCreate ();
|
|
}
|
|
|
|
static gint expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
|
{
|
|
GLWindow *wnd = (GLWindow*)data;
|
|
|
|
#ifndef _WIN32
|
|
if (event->count > 0)
|
|
return TRUE;
|
|
#endif
|
|
|
|
if (!g_pParentWnd->IsSleeping ())
|
|
wnd->OnExpose ();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)
|
|
{
|
|
GLWindow *wnd = (GLWindow*)data;
|
|
guint32 flags = 0;
|
|
|
|
gdk_pointer_grab (widget->window, FALSE,
|
|
(GdkEventMask)(GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK),
|
|
NULL, NULL, GDK_CURRENT_TIME);
|
|
|
|
gtk_window_set_focus (GTK_WINDOW (g_pParentWnd->m_pWidget), widget);
|
|
|
|
switch (event->button)
|
|
{
|
|
case 1: flags |= MK_LBUTTON; break;
|
|
case 2: flags |= MK_MBUTTON; break;
|
|
case 3: flags |= MK_RBUTTON; break;
|
|
#if !GTK_CHECK_VERSION (1,3,0)
|
|
case 4: wnd->OnMouseWheel(true); break;
|
|
case 5: wnd->OnMouseWheel(false); break;
|
|
#endif
|
|
}
|
|
|
|
if ((event->state & GDK_CONTROL_MASK) != 0)
|
|
flags |= MK_CONTROL;
|
|
|
|
if ((event->state & GDK_SHIFT_MASK) != 0)
|
|
flags |= MK_SHIFT;
|
|
|
|
if (event->type == GDK_BUTTON_PRESS)
|
|
{
|
|
switch (event->button)
|
|
{
|
|
case 1:
|
|
wnd->OnLButtonDown (flags, (int)event->x, (int)event->y); break;
|
|
case 2:
|
|
wnd->OnMButtonDown (flags, (int)event->x, (int)event->y); break;
|
|
case 3:
|
|
wnd->OnRButtonDown (flags, (int)event->x, (int)event->y); break;
|
|
}
|
|
}
|
|
else if (event->type == GDK_2BUTTON_PRESS)
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
static void button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
|
|
{
|
|
GLWindow *wnd = (GLWindow*)data;
|
|
guint32 flags = 0;
|
|
|
|
gdk_pointer_ungrab (GDK_CURRENT_TIME);
|
|
|
|
if ((event->state & GDK_CONTROL_MASK) != 0)
|
|
flags |= MK_CONTROL;
|
|
|
|
if ((event->state & GDK_SHIFT_MASK) != 0)
|
|
flags |= MK_SHIFT;
|
|
|
|
switch (event->button)
|
|
{
|
|
case 1:
|
|
wnd->OnLButtonUp (flags, (int)event->x, (int)event->y); break;
|
|
case 2:
|
|
wnd->OnMButtonUp (flags, (int)event->x, (int)event->y); break;
|
|
case 3:
|
|
wnd->OnRButtonUp (flags, (int)event->x, (int)event->y); break;
|
|
}
|
|
}
|
|
|
|
static void motion (GtkWidget *widget, GdkEventMotion *event, gpointer data)
|
|
{
|
|
GLWindow *wnd = (GLWindow*)data;
|
|
guint32 flags = 0;
|
|
|
|
if ((event->state & GDK_BUTTON1_MASK) != 0)
|
|
flags |= MK_LBUTTON;
|
|
|
|
if ((event->state & GDK_BUTTON2_MASK) != 0)
|
|
flags |= MK_MBUTTON;
|
|
|
|
if ((event->state & GDK_BUTTON3_MASK) != 0)
|
|
flags |= MK_RBUTTON;
|
|
|
|
if ((event->state & GDK_CONTROL_MASK) != 0)
|
|
flags |= MK_CONTROL;
|
|
|
|
if ((event->state & GDK_SHIFT_MASK) != 0)
|
|
flags |= MK_SHIFT;
|
|
|
|
wnd->OnMouseMove (flags, (int)event->x, (int)event->y);
|
|
}
|
|
|
|
static void resize (GtkWidget *widget, GtkAllocation *allocation, gpointer data)
|
|
{
|
|
GLWindow *wnd = (GLWindow*)data;
|
|
wnd->OnSize (allocation->width, allocation->height);
|
|
}
|
|
|
|
static gint timer (gpointer data)
|
|
{
|
|
GLWindow *wnd = (GLWindow*)data;
|
|
wnd->OnTimer ();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//! GtkGLExt port.
|
|
/*
|
|
static void create_context (GtkWidget *widget, gpointer data)
|
|
{
|
|
if (g_qeglobals_gui.d_glBase == NULL)
|
|
g_qeglobals_gui.d_glBase = widget;
|
|
}
|
|
|
|
static void destroy_context (GtkWidget *widget, gpointer data)
|
|
{
|
|
if (g_qeglobals_gui.d_glBase == widget)
|
|
g_qeglobals_gui.d_glBase = NULL;
|
|
}
|
|
*/
|
|
|
|
#if GTK_CHECK_VERSION (1,3,0)
|
|
static gint scroll_event( GtkWidget *widget,
|
|
GdkEventScroll *event,
|
|
gpointer data )
|
|
{
|
|
GLWindow *wnd = (GLWindow*)data;
|
|
wnd->OnMouseWheel((event->direction == GDK_SCROLL_UP) ? true : false);
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
|
|
// =============================================================================
|
|
// GLWindow class
|
|
|
|
#ifdef _DEBUG
|
|
//#define DBG_GLWINDOW
|
|
#endif
|
|
|
|
GLWindow::GLWindow (bool zbuffer)
|
|
{
|
|
m_nTimer = 0;
|
|
m_bMouseCapture = FALSE;
|
|
m_pParent = NULL;
|
|
|
|
m_pWidget = gtk_glwidget_new (zbuffer, g_qeglobals_gui.d_glBase);
|
|
GTK_WIDGET_SET_FLAGS (m_pWidget, GTK_CAN_FOCUS);
|
|
|
|
#ifdef DBG_GLWINDOW
|
|
Sys_Printf("GLWindow::GLWindow m_pWidget = %p\n", m_pWidget);
|
|
#endif
|
|
|
|
//! GtkGLExt port.
|
|
//#if defined (__linux__) || defined (__APPLE__)
|
|
if (g_qeglobals_gui.d_glBase == NULL)
|
|
g_qeglobals_gui.d_glBase = m_pWidget;
|
|
//#endif
|
|
|
|
#if GTK_CHECK_VERSION (1,3,0)
|
|
gtk_widget_set_events (m_pWidget, GDK_DESTROY | GDK_EXPOSURE_MASK |
|
|
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK);
|
|
#else
|
|
gtk_widget_set_events (m_pWidget, GDK_DESTROY | GDK_EXPOSURE_MASK |
|
|
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
|
|
#endif
|
|
|
|
// Connect signal handlers
|
|
gtk_signal_connect (GTK_OBJECT (m_pWidget), "realize", GTK_SIGNAL_FUNC (realize), this);
|
|
gtk_signal_connect (GTK_OBJECT (m_pWidget), "expose_event", GTK_SIGNAL_FUNC (expose), this);
|
|
gtk_signal_connect (GTK_OBJECT (m_pWidget), "motion_notify_event", GTK_SIGNAL_FUNC (motion), this);
|
|
gtk_signal_connect (GTK_OBJECT (m_pWidget), "button_press_event", GTK_SIGNAL_FUNC (button_press), this);
|
|
gtk_signal_connect (GTK_OBJECT (m_pWidget), "button_release_event",GTK_SIGNAL_FUNC (button_release), this);
|
|
gtk_signal_connect (GTK_OBJECT (m_pWidget), "size_allocate", GTK_SIGNAL_FUNC (resize), this);
|
|
//! GtkGLExt port.
|
|
// gtk_signal_connect (GTK_OBJECT (m_pWidget), "create_context", GTK_SIGNAL_FUNC (create_context), this);
|
|
// gtk_signal_connect (GTK_OBJECT (m_pWidget), "destroy_context", GTK_SIGNAL_FUNC (destroy_context), this);
|
|
#if GTK_CHECK_VERSION (1,3,0)
|
|
gtk_signal_connect (GTK_OBJECT (m_pWidget), "scroll_event", GTK_SIGNAL_FUNC (scroll_event), this);
|
|
#endif
|
|
}
|
|
|
|
GLWindow::~GLWindow ()
|
|
{
|
|
#ifdef DBG_GLWINDOW
|
|
Sys_Printf("GLWindow::~GLWindow m_pWidget = %p\n", m_pWidget);
|
|
#endif
|
|
|
|
if (m_pWidget && GTK_IS_WIDGET (m_pWidget))
|
|
gtk_widget_destroy (m_pWidget);
|
|
}
|
|
|
|
void GLWindow::DestroyContext ()
|
|
{
|
|
gtk_glwidget_destroy_context (m_pWidget);
|
|
}
|
|
|
|
void GLWindow::CreateContext ()
|
|
{
|
|
gtk_glwidget_create_context (m_pWidget);
|
|
}
|
|
|
|
void GLWindow::SetTimer (guint millisec)
|
|
{
|
|
m_nTimer = gtk_timeout_add (millisec, timer, this);
|
|
}
|
|
|
|
void GLWindow::KillTimer ()
|
|
{
|
|
gtk_timeout_remove (m_nTimer);
|
|
m_nTimer = 0;
|
|
}
|
|
|
|
bool GLWindow::MakeCurrent ()
|
|
{
|
|
return gtk_glwidget_make_current (m_pWidget);
|
|
}
|
|
|
|
void GLWindow::SwapBuffers ()
|
|
{
|
|
gtk_glwidget_swap_buffers (m_pWidget);
|
|
}
|