forked from Mirrors/openclonk
gtk: Fold C4GtkWindow into C4Window
parent
dc41afded5
commit
c865021716
|
@ -26,16 +26,9 @@
|
|||
#include "C4MainMenu.h"
|
||||
#include <C4Window.h>
|
||||
|
||||
#ifdef WITH_DEVELOPER_MODE
|
||||
#include <C4WindowGTK.h>
|
||||
typedef C4GtkWindow C4FullScreenBase;
|
||||
#else
|
||||
typedef C4Window C4FullScreenBase;
|
||||
#endif
|
||||
|
||||
bool IsKeyDown(int iKey);
|
||||
|
||||
class C4FullScreen: public C4FullScreenBase
|
||||
class C4FullScreen: public C4Window
|
||||
{
|
||||
public:
|
||||
C4MainMenu *pMenu;
|
||||
|
@ -50,7 +43,7 @@ public:
|
|||
bool MenuCommand(const char *szCommand);
|
||||
void CloseMenu();
|
||||
bool MenuKeyControl(BYTE byCom); // direct keyboard callback
|
||||
using C4FullScreenBase::Init;
|
||||
using C4Window::Init;
|
||||
C4Window * Init(C4AbstractApp * pApp);
|
||||
// User requests close
|
||||
virtual void Close();
|
||||
|
|
|
@ -68,24 +68,6 @@ C4Console::~C4Console()
|
|||
{
|
||||
}
|
||||
|
||||
#if defined(USE_X11) && !defined(WITH_DEVELOPER_MODE)
|
||||
void C4Console::HandleMessage (XEvent & e)
|
||||
{
|
||||
// Parent handling
|
||||
C4ConsoleBase::HandleMessage(e);
|
||||
|
||||
switch (e.type)
|
||||
{
|
||||
case FocusIn:
|
||||
Application.Active = true;
|
||||
break;
|
||||
case FocusOut:
|
||||
Application.Active = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // USE_X11
|
||||
|
||||
C4Window * C4Console::Init(C4AbstractApp * pApp)
|
||||
{
|
||||
return C4ConsoleGUI::CreateConsoleWindow(pApp);
|
||||
|
@ -363,7 +345,7 @@ void C4Console::Default()
|
|||
|
||||
void C4Console::Clear()
|
||||
{
|
||||
C4ConsoleBase::Clear();
|
||||
C4Window::Clear();
|
||||
EditCursor.Clear();
|
||||
ToolsDlg.Clear();
|
||||
PropertyDlgClose();
|
||||
|
|
|
@ -43,13 +43,6 @@ const int C4CNS_ModePlay = 0,
|
|||
#define IDM_VIEWPORT_NEW1 10400
|
||||
#define IDM_VIEWPORT_NEW2 10500
|
||||
|
||||
#ifdef WITH_DEVELOPER_MODE
|
||||
#include <C4WindowGTK.h>
|
||||
typedef C4GtkWindow C4ConsoleBase;
|
||||
#else
|
||||
typedef C4Window C4ConsoleBase;
|
||||
#endif
|
||||
|
||||
class C4Console: public C4ConsoleGUI
|
||||
{
|
||||
public:
|
||||
|
@ -58,7 +51,7 @@ public:
|
|||
void Default();
|
||||
virtual void Clear();
|
||||
virtual void Close();
|
||||
using C4ConsoleBase::Init;
|
||||
using C4Window::Init;
|
||||
virtual C4Window * Init(C4AbstractApp * app);
|
||||
void Execute();
|
||||
void ClearPointers(C4Object *pObj);
|
||||
|
@ -101,9 +94,6 @@ public:
|
|||
|
||||
int FrameCounter;
|
||||
int Time,FPS;
|
||||
#if defined(USE_X11) && !defined(WITH_DEVELOPER_MODE)
|
||||
virtual void HandleMessage (XEvent &);
|
||||
#endif
|
||||
};
|
||||
|
||||
#define C4ConsoleWindowClassname "C4Console"
|
||||
|
|
|
@ -312,20 +312,14 @@ void C4ConsoleGUI::State::OnScriptActivate(GtkWidget* widget, gpointer data)
|
|||
|
||||
C4Window* C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp* pApp)
|
||||
{
|
||||
// Calls InitGUI
|
||||
C4Window* retval = C4ConsoleBase::Init(C4Window::W_Console, pApp, LoadResStr("IDS_CNS_CONSOLE"), NULL, false);
|
||||
C4Window* retval = C4Window::Init(C4Window::W_Console, pApp, LoadResStr("IDS_CNS_CONSOLE"));
|
||||
state->InitGUI();
|
||||
UpdateHaltCtrls(true);
|
||||
EnableControls(fGameOpen);
|
||||
ClearViewportMenu();
|
||||
return retval;
|
||||
}
|
||||
|
||||
GtkWidget* C4ConsoleGUI::InitGUI()
|
||||
{
|
||||
state->InitGUI();
|
||||
return C4ConsoleBase::InitGUI();
|
||||
}
|
||||
|
||||
void C4ConsoleGUI::State::InitGUI()
|
||||
{
|
||||
// ------------ Play/Pause and Mode ---------------------
|
||||
|
@ -484,6 +478,7 @@ void C4ConsoleGUI::State::InitGUI()
|
|||
gtk_window_set_default_size(GTK_WINDOW(GetOwner()->window), 320, 320);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(GetOwner()->window), box);
|
||||
gtk_widget_show_all(GTK_WIDGET(GetOwner()->window));
|
||||
|
||||
// ------------ Signals ---------------------
|
||||
handlerDestroy = g_signal_connect(G_OBJECT(GetOwner()->window), "destroy", G_CALLBACK(OnDestroy), this);
|
||||
|
@ -586,7 +581,7 @@ void C4ConsoleGUI::AddMenuItemForPlayer(C4Player *player, StdStrBuf &player_text
|
|||
void C4ConsoleGUI::SetCursor(Cursor cursor)
|
||||
{
|
||||
// Seems not to work. Don't know why...
|
||||
GdkDisplay * display = gtk_widget_get_display(window);
|
||||
GdkDisplay * display = gtk_widget_get_display(GTK_WIDGET(window));
|
||||
GdkCursor * gdkcursor;
|
||||
|
||||
if (cursor == CURSOR_Wait)
|
||||
|
@ -595,9 +590,9 @@ void C4ConsoleGUI::SetCursor(Cursor cursor)
|
|||
gdkcursor = NULL;
|
||||
|
||||
#if GTK_CHECK_VERSION(2,14,0)
|
||||
GdkWindow* window_wnd = gtk_widget_get_window(window);
|
||||
GdkWindow* window_wnd = gtk_widget_get_window(GTK_WIDGET(window));
|
||||
#else
|
||||
GdkWindow* window_wnd = window->window;
|
||||
GdkWindow* window_wnd = GTK_WIDGET(window)->window;
|
||||
#endif
|
||||
|
||||
gdk_window_set_cursor(window_wnd, gdkcursor);
|
||||
|
|
|
@ -24,13 +24,6 @@
|
|||
#include "C4GameControl.h"
|
||||
#include "StdBuf.h"
|
||||
|
||||
#ifdef WITH_DEVELOPER_MODE
|
||||
#include <C4WindowGTK.h>
|
||||
typedef C4GtkWindow C4ConsoleBase;
|
||||
#else
|
||||
typedef C4Window C4ConsoleBase;
|
||||
#endif
|
||||
|
||||
namespace OpenFileFlags
|
||||
{
|
||||
const DWORD OFN_HIDEREADONLY = 1 << 0;
|
||||
|
@ -42,7 +35,7 @@ namespace OpenFileFlags
|
|||
}
|
||||
|
||||
// Separate class containing GUI code for C4Console while C4Console itself only contains functionality
|
||||
class C4ConsoleGUI: public C4ConsoleBase
|
||||
class C4ConsoleGUI: public C4Window
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -146,9 +139,6 @@ public:
|
|||
virtual bool Win32DialogMessageHandling(MSG *msg);
|
||||
void UpdateMenuText(HMENU hMenu);
|
||||
#endif
|
||||
#ifdef WITH_DEVELOPER_MODE
|
||||
virtual GtkWidget* InitGUI();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -49,13 +49,6 @@
|
|||
#include <StdResStr2.h>
|
||||
#include <C4Window.h>
|
||||
|
||||
#ifdef WITH_DEVELOPER_MODE
|
||||
#include <C4WindowGTK.h>
|
||||
typedef C4GtkWindow DialogWindowBase;
|
||||
#else
|
||||
typedef C4Window DialogWindowBase;
|
||||
#endif
|
||||
|
||||
// consts (load those from a def file some time)
|
||||
// font colors - alpha is font alpha, which is inversed opaque
|
||||
#define C4GUI_CaptionFontClr 0xffffffff
|
||||
|
@ -1953,11 +1946,11 @@ namespace C4GUI
|
|||
class Dialog;
|
||||
|
||||
// EM window class
|
||||
class DialogWindow : public DialogWindowBase
|
||||
class DialogWindow : public C4Window
|
||||
{
|
||||
public:
|
||||
Dialog* pDialog;
|
||||
DialogWindow(): DialogWindowBase(), pDialog(NULL) {}
|
||||
DialogWindow(): C4Window(), pDialog(NULL) {}
|
||||
using C4Window::Init;
|
||||
C4Window * Init(C4AbstractApp * pApp, const char * Title, C4Window * pParent, const C4Rect &rcBounds, const char *szID);
|
||||
virtual void Close();
|
||||
|
|
|
@ -217,7 +217,9 @@ C4Window * C4ViewportWindow::Init(int32_t Player)
|
|||
{
|
||||
C4Window* result;
|
||||
const char * Title = Player == NO_OWNER ? LoadResStr("IDS_CNS_VIEWPORT") : ::Players.Get(Player)->GetName();
|
||||
result = C4ViewportBase::Init(C4Window::W_Viewport, &Application, Title, &Console, false);
|
||||
|
||||
result = C4Window::Init(C4Window::W_Viewport, &Application, Title);
|
||||
|
||||
if (!result) return result;
|
||||
|
||||
pSurface = new C4Surface(&Application, this);
|
||||
|
|
|
@ -28,15 +28,12 @@
|
|||
#include <C4Viewport.h>
|
||||
|
||||
#ifdef WITH_DEVELOPER_MODE
|
||||
#include <C4WindowGTK.h>
|
||||
typedef C4GtkWindow C4ViewportBase;
|
||||
#else
|
||||
typedef C4Window C4ViewportBase;
|
||||
#include <gtk/gtk.h>
|
||||
#endif
|
||||
#define C4ViewportWindowStyle (WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX)
|
||||
enum { ViewportScrollSpeed=10 };
|
||||
|
||||
class C4ViewportWindow: public C4ViewportBase
|
||||
class C4ViewportWindow: public C4Window
|
||||
{
|
||||
public:
|
||||
C4Viewport * cvp;
|
||||
|
|
|
@ -298,22 +298,25 @@ public:
|
|||
HWND hWindow;
|
||||
HWND hRenderWindow;
|
||||
virtual bool Win32DialogMessageHandling(MSG * msg) { return false; };
|
||||
#elif defined(USE_X11)
|
||||
#elif defined(WITH_GLIB)
|
||||
public:
|
||||
/*GtkWidget*/void * window;
|
||||
// Set by Init to the widget which is used as a
|
||||
// render target, which can be the whole window.
|
||||
/*GtkWidget*/void * render_widget;
|
||||
virtual void HandleMessage (XEvent &);
|
||||
protected:
|
||||
bool FindInfo(int samples, void** info);
|
||||
|
||||
unsigned long wnd;
|
||||
unsigned long renderwnd;
|
||||
Display * dpy;
|
||||
virtual void HandleMessage (XEvent &);
|
||||
// The currently set window hints
|
||||
void * Hints;
|
||||
bool HasFocus; // To clear urgency hint
|
||||
// The XVisualInfo the window was created with
|
||||
void * Info;
|
||||
unsigned long handlerDestroy;
|
||||
#elif defined(USE_SDL_MAINLOOP)
|
||||
private:
|
||||
int width, height;
|
||||
|
@ -334,7 +337,6 @@ public:
|
|||
friend class CStdGL;
|
||||
friend class CStdGLCtx;
|
||||
friend class C4AbstractApp;
|
||||
friend class C4GtkWindow;
|
||||
};
|
||||
|
||||
#endif // INC_STDWINDOW
|
||||
|
|
|
@ -36,17 +36,45 @@
|
|||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
/* C4GtkWindow */
|
||||
|
||||
C4GtkWindow::C4GtkWindow():
|
||||
C4Window(), window(NULL)
|
||||
static void OnDestroyStatic(GtkWidget* widget, gpointer data)
|
||||
{
|
||||
C4Window* wnd = static_cast<C4Window*>(data);
|
||||
wnd->Clear();
|
||||
}
|
||||
|
||||
C4GtkWindow::~C4GtkWindow()
|
||||
static GdkFilterReturn OnFilter(GdkXEvent* xevent, GdkEvent* event, gpointer user_data)
|
||||
{
|
||||
Clear();
|
||||
// Handle raw X message, then let GTK+ process it
|
||||
static_cast<C4Window*>(user_data)->HandleMessage(*reinterpret_cast<XEvent*>(xevent));
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static gboolean OnUpdateKeyMask(GtkWidget* widget, GdkEventKey* event, gpointer user_data)
|
||||
{
|
||||
// Update mask so that Application.IsShiftDown,
|
||||
// Application.IsControlDown etc. work.
|
||||
unsigned int mask = 0;
|
||||
if (event->state & GDK_SHIFT_MASK) mask |= MK_SHIFT;
|
||||
if (event->state & GDK_CONTROL_MASK) mask |= MK_CONTROL;
|
||||
if (event->state & GDK_MOD1_MASK) mask |= (1 << 3);
|
||||
|
||||
// For keypress/relases, event->state contains the state _before_
|
||||
// the event, but we need to store the current state.
|
||||
#if !GTK_CHECK_VERSION(2,21,8)
|
||||
# define GDK_KEY_Shift_L GDK_Shift_L
|
||||
# define GDK_KEY_Shift_R GDK_Shift_R
|
||||
# define GDK_KEY_Control_L GDK_Control_L
|
||||
# define GDK_KEY_Control_R GDK_Control_R
|
||||
# define GDK_KEY_Alt_L GDK_Alt_L
|
||||
# define GDK_KEY_Alt_R GDK_Alt_R
|
||||
#endif
|
||||
|
||||
if (event->keyval == GDK_KEY_Shift_L || event->keyval == GDK_KEY_Shift_R) mask ^= MK_SHIFT;
|
||||
if (event->keyval == GDK_KEY_Control_L || event->keyval == GDK_KEY_Control_R) mask ^= MK_CONTROL;
|
||||
if (event->keyval == GDK_KEY_Alt_L || event->keyval == GDK_KEY_Alt_R) mask ^= (1 << 3);
|
||||
|
||||
static_cast<C4AbstractApp*>(user_data)->KeyMask = mask;
|
||||
return false;
|
||||
}
|
||||
|
||||
static gboolean OnKeyPress(GtkWidget* widget, GdkEventKey* event, gpointer data)
|
||||
|
@ -441,7 +469,16 @@ static gboolean OnConfigureGD(GtkWidget* widget, GdkEventConfigure* event, gpoin
|
|||
return false;
|
||||
}
|
||||
|
||||
C4Window* C4GtkWindow::Init(WindowKind windowKind, C4AbstractApp * pApp, const char * Title, C4Window * pParent, bool HideCursor)
|
||||
C4Window::C4Window ():
|
||||
Active(false), pSurface(0), wnd(0), renderwnd(0), dpy(0), Hints(0), HasFocus(false), Info(0), window(NULL)
|
||||
{
|
||||
}
|
||||
C4Window::~C4Window ()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
C4Window* C4Window::Init(WindowKind windowKind, C4AbstractApp * pApp, const char * Title, C4Window * pParent, bool HideCursor)
|
||||
{
|
||||
Active = true;
|
||||
dpy = pApp->dpy;
|
||||
|
@ -556,7 +593,12 @@ C4Window* C4GtkWindow::Init(WindowKind windowKind, C4AbstractApp * pApp, const c
|
|||
|
||||
gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(Console.window));
|
||||
}
|
||||
else if (windowKind == W_Console)
|
||||
{
|
||||
render_widget = window;
|
||||
}
|
||||
assert(window);
|
||||
assert(render_widget);
|
||||
// Override gtk's default to match name/class of the XLib windows
|
||||
gtk_window_set_wmclass(GTK_WINDOW(window), C4ENGINENAME, C4ENGINENAME);
|
||||
|
||||
|
@ -565,9 +607,6 @@ C4Window* C4GtkWindow::Init(WindowKind windowKind, C4AbstractApp * pApp, const c
|
|||
g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(OnUpdateKeyMask), pApp);
|
||||
g_signal_connect(G_OBJECT(window), "key-release-event", G_CALLBACK(OnUpdateKeyMask), pApp);
|
||||
|
||||
if(!render_widget)
|
||||
render_widget = InitGUI();
|
||||
|
||||
GdkScreen * scr = gtk_widget_get_screen(GTK_WIDGET(render_widget));
|
||||
GdkVisual * vis = gdk_x11_screen_lookup_visual(scr, ((XVisualInfo*)Info)->visualid);
|
||||
#if GTK_CHECK_VERSION(2,91,0)
|
||||
|
@ -577,7 +616,7 @@ C4Window* C4GtkWindow::Init(WindowKind windowKind, C4AbstractApp * pApp, const c
|
|||
gtk_widget_set_colormap(GTK_WIDGET(render_widget), cmap);
|
||||
g_object_unref(cmap);
|
||||
#endif
|
||||
gtk_widget_show_all(window);
|
||||
gtk_widget_show_all(GTK_WIDGET(window));
|
||||
|
||||
// XVisualInfo vitmpl; int blub;
|
||||
// vitmpl.visual = gdk_x11_visual_get_xvisual(gtk_widget_get_visual(window));
|
||||
|
@ -593,13 +632,13 @@ C4Window* C4GtkWindow::Init(WindowKind windowKind, C4AbstractApp * pApp, const c
|
|||
gtk_window_set_title(GTK_WINDOW(window), Title);
|
||||
|
||||
#if GTK_CHECK_VERSION(2,14,0)
|
||||
GdkWindow* window_wnd = gtk_widget_get_window(window);
|
||||
GdkWindow* window_wnd = gtk_widget_get_window(GTK_WIDGET(window));
|
||||
#else
|
||||
GdkWindow* window_wnd = window->window;
|
||||
GdkWindow* window_wnd = GTK_WIDGET(window)->window;
|
||||
#endif
|
||||
|
||||
// Wait until window is mapped to get the window's XID
|
||||
gtk_widget_show_now(window);
|
||||
gtk_widget_show_now(GTK_WIDGET(window));
|
||||
wnd = GDK_WINDOW_XID(window_wnd);
|
||||
gdk_window_add_filter(window_wnd, OnFilter, this);
|
||||
|
||||
|
@ -637,7 +676,7 @@ C4Window* C4GtkWindow::Init(WindowKind windowKind, C4AbstractApp * pApp, const c
|
|||
return this;
|
||||
}
|
||||
|
||||
bool C4GtkWindow::ReInit(C4AbstractApp* pApp)
|
||||
bool C4Window::ReInit(C4AbstractApp* pApp)
|
||||
{
|
||||
// Check whether multisampling settings was changed. If not then we
|
||||
// don't need to ReInit anything.
|
||||
|
@ -671,12 +710,12 @@ bool C4GtkWindow::ReInit(C4AbstractApp* pApp)
|
|||
return true;
|
||||
}
|
||||
|
||||
void C4GtkWindow::Clear()
|
||||
void C4Window::Clear()
|
||||
{
|
||||
if (window != NULL)
|
||||
{
|
||||
g_signal_handler_disconnect(window, handlerDestroy);
|
||||
gtk_widget_destroy(window);
|
||||
gtk_widget_destroy(GTK_WIDGET(window));
|
||||
handlerDestroy = 0;
|
||||
}
|
||||
|
||||
|
@ -694,60 +733,6 @@ void C4GtkWindow::Clear()
|
|||
}
|
||||
}
|
||||
|
||||
void C4GtkWindow::OnDestroyStatic(GtkWidget* widget, gpointer data)
|
||||
{
|
||||
C4GtkWindow* wnd = static_cast<C4GtkWindow*>(data);
|
||||
|
||||
g_signal_handler_disconnect(wnd->window, wnd->handlerDestroy);
|
||||
//gtk_widget_destroy(wnd->window);
|
||||
wnd->handlerDestroy = 0;
|
||||
wnd->window = NULL;
|
||||
wnd->Active = false;
|
||||
wnd->wnd = wnd->renderwnd = 0;
|
||||
|
||||
wnd->Close();
|
||||
}
|
||||
|
||||
GdkFilterReturn C4GtkWindow::OnFilter(GdkXEvent* xevent, GdkEvent* event, gpointer user_data)
|
||||
{
|
||||
// Handle raw X message, then let GTK+ process it
|
||||
static_cast<C4GtkWindow*>(user_data)->HandleMessage(*reinterpret_cast<XEvent*>(xevent));
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
gboolean C4GtkWindow::OnUpdateKeyMask(GtkWidget* widget, GdkEventKey* event, gpointer user_data)
|
||||
{
|
||||
// Update mask so that Application.IsShiftDown,
|
||||
// Application.IsControlDown etc. work.
|
||||
unsigned int mask = 0;
|
||||
if (event->state & GDK_SHIFT_MASK) mask |= MK_SHIFT;
|
||||
if (event->state & GDK_CONTROL_MASK) mask |= MK_CONTROL;
|
||||
if (event->state & GDK_MOD1_MASK) mask |= (1 << 3);
|
||||
|
||||
// For keypress/relases, event->state contains the state _before_
|
||||
// the event, but we need to store the current state.
|
||||
#if !GTK_CHECK_VERSION(2,21,8)
|
||||
# define GDK_KEY_Shift_L GDK_Shift_L
|
||||
# define GDK_KEY_Shift_R GDK_Shift_R
|
||||
# define GDK_KEY_Control_L GDK_Control_L
|
||||
# define GDK_KEY_Control_R GDK_Control_R
|
||||
# define GDK_KEY_Alt_L GDK_Alt_L
|
||||
# define GDK_KEY_Alt_R GDK_Alt_R
|
||||
#endif
|
||||
|
||||
if (event->keyval == GDK_KEY_Shift_L || event->keyval == GDK_KEY_Shift_R) mask ^= MK_SHIFT;
|
||||
if (event->keyval == GDK_KEY_Control_L || event->keyval == GDK_KEY_Control_R) mask ^= MK_CONTROL;
|
||||
if (event->keyval == GDK_KEY_Alt_L || event->keyval == GDK_KEY_Alt_R) mask ^= (1 << 3);
|
||||
|
||||
static_cast<C4AbstractApp*>(user_data)->KeyMask = mask;
|
||||
return false;
|
||||
}
|
||||
|
||||
GtkWidget* C4GtkWindow::InitGUI()
|
||||
{
|
||||
return window;
|
||||
}
|
||||
|
||||
void C4Window::RequestUpdate()
|
||||
{
|
||||
// just invoke directly
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 2006 Armin Burgmeier
|
||||
* Copyright (c) 2006-2009, RedWolf Design GmbH, http://www.clonk.de
|
||||
*
|
||||
* Portions might be copyrighted by other authors who have contributed
|
||||
* to OpenClonk.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* See isc_license.txt for full license and disclaimer.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender.
|
||||
* See clonk_trademark_license.txt for full license.
|
||||
*/
|
||||
|
||||
/* GTK+ version of StdWindow */
|
||||
|
||||
#ifndef INC_STDGTKWINDOW
|
||||
#define INC_STDGTKWINDOW
|
||||
|
||||
#include <C4Window.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
class C4GtkWindow: public C4Window
|
||||
{
|
||||
public:
|
||||
C4GtkWindow();
|
||||
virtual ~C4GtkWindow();
|
||||
|
||||
virtual void Clear();
|
||||
|
||||
using C4Window::Init;
|
||||
virtual C4Window * Init(WindowKind windowKind, C4AbstractApp * pApp, const char * Title, C4Window * pParent = 0, bool HideCursor = true);
|
||||
virtual bool ReInit(C4AbstractApp* pApp);
|
||||
|
||||
GtkWidget* window;
|
||||
protected:
|
||||
// InitGUI should either return a widget which is used as a
|
||||
// render target or return what the base class returns, in which
|
||||
// case the whole window is used as render target.
|
||||
virtual GtkWidget* InitGUI();
|
||||
|
||||
private:
|
||||
static void OnDestroyStatic(GtkWidget* widget, gpointer data);
|
||||
static GdkFilterReturn OnFilter(GdkXEvent* xevent, GdkEvent* event, gpointer user_data);
|
||||
static gboolean OnUpdateKeyMask(GtkWidget* widget, GdkEventKey* event, gpointer user_data);
|
||||
|
||||
gulong handlerDestroy;
|
||||
};
|
||||
|
||||
#endif // INC_STDGTKWINDOW
|
|
@ -225,170 +225,6 @@ static Window CreateRenderWindow(Display* dpy, Window parent, XVisualInfo* info)
|
|||
|
||||
/* C4Window */
|
||||
|
||||
C4Window::C4Window ():
|
||||
Active(false), pSurface(0), wnd(0), renderwnd(0), dpy(0), Hints(0), HasFocus(false), Info(0)
|
||||
{
|
||||
}
|
||||
C4Window::~C4Window ()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
C4Window * C4Window::Init(C4Window::WindowKind windowKind, C4AbstractApp * pApp, const char * Title, C4Window * pParent, bool HideCursor)
|
||||
{
|
||||
Active = true;
|
||||
dpy = pApp->dpy;
|
||||
|
||||
// Try to get a multisampling visual
|
||||
if(!FindInfo(Config.Graphics.MultiSampling, &Info))
|
||||
{
|
||||
// Disable multisampling if we don't find a visual which
|
||||
// supports the currently configured setting.
|
||||
if(!FindInfo(0, &Info)) return NULL;
|
||||
Config.Graphics.MultiSampling = 0;
|
||||
}
|
||||
|
||||
XSetWindowAttributes attr;
|
||||
attr.border_pixel = 0;
|
||||
attr.background_pixel = 0;
|
||||
// Which events we want to receive
|
||||
attr.event_mask =
|
||||
//EnterWindowMask |
|
||||
//LeaveWindowMask |
|
||||
StructureNotifyMask |
|
||||
FocusChangeMask |
|
||||
KeyPressMask |
|
||||
KeyReleaseMask |
|
||||
PointerMotionMask |
|
||||
ButtonPressMask |
|
||||
ButtonReleaseMask;
|
||||
|
||||
unsigned long attrmask = CWBackPixel | CWBorderPixel | CWEventMask;
|
||||
Pixmap bitmap = 0;
|
||||
if (HideCursor)
|
||||
{
|
||||
// Hide the mouse cursor
|
||||
XColor cursor_color;
|
||||
// We do not care what color the invisible cursor has
|
||||
memset(&cursor_color, 0, sizeof(cursor_color));
|
||||
bitmap = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), "\000", 1, 1);
|
||||
if (bitmap)
|
||||
{
|
||||
attr.cursor = XCreatePixmapCursor(dpy, bitmap, bitmap, &cursor_color, &cursor_color, 0, 0);
|
||||
if (attr.cursor)
|
||||
attrmask |= CWCursor;
|
||||
else
|
||||
Log("Error creating cursor.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Error creating bitmap for cursor.");
|
||||
attr.cursor = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attr.cursor = 0;
|
||||
}
|
||||
|
||||
wnd = XCreateWindow(dpy, DefaultRootWindow(dpy),
|
||||
0, 0, Config.Graphics.ResX, Config.Graphics.ResY, 0, CopyFromParent, InputOutput, CopyFromParent,
|
||||
attrmask, &attr);
|
||||
|
||||
if (attr.cursor)
|
||||
XFreeCursor(dpy, attr.cursor);
|
||||
if (bitmap)
|
||||
XFreePixmap(dpy, bitmap);
|
||||
if (!wnd)
|
||||
{
|
||||
Log("Error creating window.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Set _NET_WM_STATE
|
||||
if(n_net_wm_state_atoms)
|
||||
{
|
||||
XChangeProperty(dpy, wnd_info.wnd, XInternAtom(dpy, "_NET_WM_STATE", False), XInternAtom(dpy, "ATOM", False), 32, PropModeReplace, reinterpret_cast<unsigned char*>(net_wm_state_atoms), n_net_wm_state_atoms);
|
||||
}
|
||||
#endif
|
||||
|
||||
// We want notification of closerequests and be killed if we hang
|
||||
Atom WMProtocols[2];
|
||||
const char * WMProtocolnames[] = { "WM_DELETE_WINDOW", "_NET_WM_PING" };
|
||||
XInternAtoms(dpy, const_cast<char **>(WMProtocolnames), 2, false, WMProtocols);
|
||||
XSetWMProtocols(dpy, wnd, WMProtocols, 2);
|
||||
// Let the window manager know our pid so it can kill us
|
||||
Atom PID = XInternAtom(dpy, "_NET_WM_PID", false);
|
||||
int32_t pid = getpid();
|
||||
if (PID != None) XChangeProperty(dpy, wnd, PID, XA_CARDINAL, 32, PropModeReplace, reinterpret_cast<const unsigned char*>(&pid), 1);
|
||||
// State and Icon
|
||||
XWMHints* wm_hints = XAllocWMHints();
|
||||
wm_hints->input = 1;
|
||||
wm_hints->flags = StateHint | InputHint | IconPixmapHint | IconMaskHint;
|
||||
wm_hints->initial_state = NormalState;
|
||||
// Trust XpmCreatePixmapFromData to not modify the xpm...
|
||||
XpmCreatePixmapFromData (dpy, wnd, const_cast<char **>(c4x_xpm), &wm_hints->icon_pixmap, &wm_hints->icon_mask, 0);
|
||||
// Window class
|
||||
XClassHint * class_hint = XAllocClassHint();
|
||||
class_hint->res_name = const_cast<char *>(C4ENGINENAME);
|
||||
class_hint->res_class = const_cast<char *>(C4ENGINENAME);
|
||||
Xutf8SetWMProperties(dpy, wnd, const_cast<char*>(Title), const_cast<char*>(Title), pApp->Priv->argv, pApp->Priv->argc, 0, wm_hints, class_hint);
|
||||
XFree(class_hint);
|
||||
Hints = wm_hints;
|
||||
// Set "parent". Clonk does not use "real" parent windows, but multiple toplevel windows.
|
||||
if (pParent) XSetTransientForHint(dpy, wnd, pParent->wnd);
|
||||
|
||||
// Update XWindow<->StdWindow map
|
||||
C4X11AppImpl::SetWindow(wnd, this);
|
||||
|
||||
// Create the subwindow which we render into
|
||||
renderwnd = CreateRenderWindow(dpy, wnd, static_cast<XVisualInfo*>(Info));
|
||||
if(!renderwnd)
|
||||
{
|
||||
XDestroyWindow(dpy, wnd); wnd = None;
|
||||
Log("Error creating render window.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Clean up
|
||||
// The pixmap has to stay as long as the window exists, so it does not hurt to never free it.
|
||||
//XFreePixmap(dpy,xwmh->icon_pixmap);
|
||||
//XFreePixmap(dpy,xwmh->icon_mask);
|
||||
|
||||
// Show window
|
||||
XMapWindow (dpy, renderwnd);
|
||||
XMapWindow (dpy, wnd);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bool C4Window::ReInit(C4AbstractApp* pApp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4Window::Clear()
|
||||
{
|
||||
// Destroy window
|
||||
if (wnd)
|
||||
{
|
||||
C4X11AppImpl::SetWindow(wnd, 0);
|
||||
XUnmapWindow(dpy, wnd);
|
||||
XDestroyWindow(dpy, renderwnd);
|
||||
XDestroyWindow(dpy, wnd);
|
||||
if (Hints) XFree(Hints);
|
||||
Hints = NULL;
|
||||
|
||||
// Might be necessary when the last window is closed
|
||||
XFlush(dpy);
|
||||
}
|
||||
|
||||
wnd = renderwnd = 0;
|
||||
if (Info) delete static_cast<XVisualInfo*>(Info);
|
||||
Info = NULL;
|
||||
}
|
||||
|
||||
bool C4Window::FindInfo(int samples, void** info)
|
||||
{
|
||||
#ifdef USE_GL
|
||||
|
|
Loading…
Reference in New Issue