6c2bd2b9bcdf987fb9c4b5a747e9b7d07e534fe0
[xonotic/netradiant.git] / radiant / mainframe.cpp
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
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.
11
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.
16
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
20 */
21
22 //
23 // Main Window for Q3Radiant
24 //
25 // Leonardo Zide (leo@lokigames.com)
26 //
27
28 #include "stdafx.h"
29 #ifdef _WIN32
30 extern "C" {
31 #include <gdk/gdkwin32.h> 
32 #define COMPILE_MULTIMON_STUBS
33 #include <multimon.h>
34 }
35 #endif
36 #include <gtk/gtk.h>
37 #include <gdk/gdkkeysyms.h>
38 #include <gdk/gdkprivate.h>
39 #include <sys/stat.h>
40 #if defined (__linux__) || defined (__APPLE__)
41   #include <unistd.h>
42 #endif
43 #include "gtkmisc.h"
44 #include "groupdialog.h"
45 #include "patchdialog.h"
46 #include "filters.h"
47
48 // use this to verbose what happens with the beyboard
49 #ifdef _DEBUG
50 //  #define DBG_KBD
51 #endif
52
53 // globals
54 CString g_strAppPath;                   ///< holds the full path of the executable
55 CString g_strDTDPath;                   ///< path to the DTD files
56 /*!
57 see http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297 for the two below
58 */
59 CString g_pidFile;                      ///< the global .pid file (only for global part of the startup)
60 CString g_pidGameFile;                  ///< the game-specific .pid file
61 CString g_strBitmapsPath;               // directory where the bitmaps are stored
62
63 /*!
64 points to the game tools directory, for instance
65 C:\Program Files\Quake III Arena\GtkRadiant
66 (or other games)
67 this is one of the main variables that are configured by the game selection on startup
68 <g_strGameToolsPath>/plugins
69 <g_strGameToolsPath>/modules
70 and also q3map, bspc
71 */
72 CString g_strGameToolsPath;             ///< this is set by g_PrefsDlg.mGamesDialog
73 CGameDescription *g_pGameDescription;   ///< shortcut to g_PrefsDlg.mGamesDialog.m_pCurrentDescription
74 CString g_strPluginsDir;                ///< name of plugins directory, always sub-directory of toolspath
75 CString g_strModulesDir;                ///< name of modules directory, always sub-directory of toolspath
76
77 /*!
78 directory for temp files
79 NOTE: on *nix this is were we check for .pid
80 */
81 CString g_strTempPath;
82 MainFrame* g_pParentWnd = NULL;         // used to precast to CMainFrame
83 PrefsDlg g_Preferences;                 // global prefs instance
84 PrefsDlg& g_PrefsDlg = g_Preferences;   // reference used throughout
85 int g_nUpdateBits = 0;                  // window update flags
86 bool g_bScreenUpdates = true;           // whether window painting is active, used in a few places
87                                         // to disable updates for speed reasons
88                                         // both of the above should be made members of CMainFrame
89 int g_bIgnoreCommands;                  // Used to ignore commands when checking menus/toolbars
90 GSList *g_BSPFrontendCommands;          // List of commands in the BSP menu
91
92 const int CMD_TEXTUREWAD_END = CMD_TEXTUREWAD + MAX_TEXTUREDIRS - 1;
93 const int CMD_BSPCOMMAND_END = CMD_BSPCOMMAND + 127;
94
95 extern bool g_bCrossHairs;
96 extern int g_argc;
97 extern char** g_argv;
98 extern PatchDialog g_PatchDialog;
99
100 GtkAccelGroup* global_accel;
101
102 void Select_Ungroup ();
103
104 // command mapping stuff
105 //
106 // m_strCommand is the command string
107 // m_nKey is the GDK_??? equivelant
108 // m_nModifiers are key states as follows
109 //  bit
110 //    1 - shift
111 //    2 - alt
112 //    4 - control
113 //    8 - press only
114 //
115 #define SPEED_MOVE      32
116 #define SPEED_TURN      22.5
117
118 // NOTE: the menu item field is REQUIRED, Gtk uses it to bind the keyboard shortcut
119 // - if you add a command here and you don't want a menu item, use the "hidden" menu
120 // - if you decide to add a menu item, check if it's not in the "hidden" menu already
121 SCommandInfo g_Commands[] =
122 {
123   {"CycleOutlineStyle", 'J', 0x00, ID_SELECTION_OUTLINESTYLE, "menu_selection_outlinestyle"},
124   {"CSGMerge", 'U', 0x04, ID_SELECTION_CSGMERGE, "menu_selection_csgmerge"},
125   {"CSGSubtract", 'U', 0x01, ID_SELECTION_CSGSUBTRACT, "menu_selection_csgsubstract"},
126   //  {"ViewGroups", 'G', 0x00, ID_VIEW_GROUPS, "menu_view_groups"}, (temporary disabled)
127   {"HideSelected", 'H', 0x00, ID_VIEW_HIDESHOW_HIDESELECTED, "menu_view_hideshow_hideselected"},
128   {"ShowHidden", 'H', 0x01, ID_VIEW_HIDESHOW_SHOWHIDDEN, "menu_view_hideshow_showhidden"},
129   {"BendMode", 'B', 0x00, ID_PATCH_BEND, "menu_patch_bend"},
130   {"FitTexture", 'B', 0x01, IDC_BTN_FACEFIT, "menu_idc_btn_facefit"},
131   {"ViewTextures", 'T', 0, ID_VIEW_TEXTURE, "menu_view_texture"},
132   {"ThickenPatch", 'T', 0x04, ID_CURVE_THICKEN, "menu_curve_thicken"},
133   {"MakeOverlayPatch", 'Y', 0, ID_CURVE_OVERLAY_SET, "menu_curve_overlay_set"},
134   {"ClearPatchOverlays", 'L', 0x04, ID_CURVE_OVERLAY_CLEAR, "menu_curve_overlay_clear"},
135   {"SurfaceInspector", 'S', 0, ID_TEXTURES_INSPECTOR, "menu_textures_inspector"},
136   {"PatchInspector", 'S', 0x01, ID_PATCH_INSPECTOR, "menu_patch_inspector"},
137   {"RedisperseRows", 'E', 0x04, ID_CURVE_REDISPERSE_ROWS, "menu_curve_redisperse_rows"},
138   {"RedisperseIntermediateCols", 'E', 0x05, ID_CURVE_REDISPERSE_INTERMEDIATE_COLS, "menu_curve_redisperse_cols"},
139   {"InvertCurveTextureX", 'I', 0x05, ID_CURVE_NEGATIVETEXTUREY, "menu_curve_negativetexturey"},
140   {"InvertCurveTextureY", 'I', 0x01, ID_CURVE_NEGATIVETEXTUREX, "menu_curve_negativetexturex"},
141   {"InvertCurve", 'I', 0x04, ID_CURVE_NEGATIVE, "menu_curve_negative"},
142   {"IncPatchColumn", GDK_KP_Add, 0x05, ID_CURVE_INSERTCOLUMN, "menu_curve_insertcolumn"},
143   {"IncPatchRow", GDK_KP_Add, 0x04, ID_CURVE_INSERTROW, "menu_curve_insertrow"},
144   {"DecPatchColumn", GDK_KP_Subtract, 0x05, ID_CURVE_DELETECOLUMN, "menu_curve_deletecolumn"},
145   {"DecPatchRow", GDK_KP_Subtract, 0x04, ID_CURVE_DELETEROW, "menu_curve_deleterow"},
146   {"Patch TAB", GDK_Tab, 0x00, ID_PATCH_TAB, "menu_patch_tab"},
147   {"Patch TAB", GDK_Tab, 0x01, ID_PATCH_TAB, "menu_patch_tab"},
148   {"SelectNudgeDown", GDK_Down, 0x02, ID_SELECTION_SELECT_NUDGEDOWN, "menu_selection_select_nudgedown"},
149   {"EntityColor",'K', 0, ID_MISC_SELECTENTITYCOLOR, "menu_misc_select_entitycolor"},
150   {"CameraForward", GDK_Up, 0, ID_CAMERA_FORWARD, "menu_camera_forward"},
151   {"CameraBack", GDK_Down, 0, ID_CAMERA_BACK, "menu_camera_back"},
152   {"CameraLeft", GDK_Left, 0, ID_CAMERA_LEFT, "menu_camera_left"},
153   {"CameraRight", GDK_Right, 0, ID_CAMERA_RIGHT, "menu_camera_right"},
154   {"CameraUp", 'D', 0, ID_CAMERA_UP, "menu_camera_up"},
155   {"CameraDown", 'C', 0, ID_CAMERA_DOWN, "menu_camera_down"},
156   {"CameraAngleUp", 'A', 0, ID_CAMERA_ANGLEUP, "menu_camera_angleup"},
157   {"CameraAngleDown", 'Z', 0, ID_CAMERA_ANGLEDOWN, "menu_camera_angledown"},
158   {"CameraStrafeRight", GDK_period, 0, ID_CAMERA_STRAFERIGHT, "menu_camera_straferight"},
159   {"CameraStrafeLeft", GDK_comma, 0, ID_CAMERA_STRAFELEFT, "menu_camera_strafeleft"},
160   {"ToggleGrid", '0', 0, ID_GRID_TOGGLE, "menu_grid_toggle"},
161   {"SetGrid1", '1', 0, ID_GRID_1, "menu_grid_1"},
162   {"SetGrid2", '2', 0, ID_GRID_2, "menu_grid_2"},
163   {"SetGrid4", '3', 0, ID_GRID_4, "menu_grid_4"},
164   {"SetGrid8", '4', 0, ID_GRID_8, "menu_grid_8"},
165   {"SetGrid16", '5', 0, ID_GRID_16, "menu_grid_16"},
166   {"SetGrid32", '6', 0, ID_GRID_32, "menu_grid_32"},
167   {"SetGrid64", '7', 0, ID_GRID_64, "menu_grid_64"},
168   {"SetGrid128", '8', 0, ID_GRID_128, "menu_grid_128"},
169   {"SetGrid256", '9', 0, ID_GRID_256, "menu_grid_256"},
170   {"DragEdges", 'E', 0, ID_SELECTION_DRAGEDGES, "menu_selection_dragedges"},
171   {"DragVertices", 'V', 0, ID_SELECTION_DRAGVERTECIES, "menu_selection_dragvertecies"},
172   {"ViewEntityInfo", 'N', 0, ID_VIEW_ENTITY, "menu_view_entity"},
173   //  {"ViewConsole", 'O', 0, ID_VIEW_CONSOLE, "menu_0,"},
174   {"CloneSelection", GDK_space, 0, ID_SELECTION_CLONE, "menu_selection_clone"},
175   {"DeleteSelection", GDK_BackSpace, 0, ID_SELECTION_DELETE, "menu_selection_delete"},
176   {"UnSelectSelection", GDK_Escape, 0, ID_SELECTION_DESELECT, "menu_selection_deselect"},
177   {"CenterView", GDK_End, 0, ID_VIEW_CENTER, "menu_view_center"},
178   {"ZoomOut", GDK_Insert, 0, ID_VIEW_ZOOMOUT, "menu_view_zoomout"},
179   {"ZoomIn", GDK_Delete, 0, ID_VIEW_ZOOMIN, "menu_view_zoomin"},
180   {"UpFloor", GDK_Prior, 0, ID_VIEW_UPFLOOR, "menu_view_upfloor"},
181   {"DownFloor", GDK_Next, 0, ID_VIEW_DOWNFLOOR, "menu_view_downfloor"},
182   {"ToggleClipper", 'X', 0, ID_VIEW_CLIPPER, "menu_view_clipper"},
183   {"ToggleCrosshairs", 'X', 0x01, ID_VIEW_CROSSHAIR, "menu_view_crosshair"},
184   {"TogTexLock", 'T', 0x01, ID_TOGGLE_LOCK, "menu_toggle_lock"},
185   {"TogTexRotLock", 'R', 0x01, ID_TOGGLE_ROTATELOCK, "menu_toggle_rotatelock"},
186   {"ToggleRealtime", 'R', 0x04, ID_VIEW_CAMERAUPDATE, "menu_view_cameraupdate"},
187   {"EntityList", 'L', 0, ID_EDIT_ENTITYINFO, "menu_edit_entityinfo"},
188   {"Preferences", 'P', 0, ID_PREFS, "menu_prefs"},
189   {"ToggleCamera", 'C', 0x05, ID_TOGGLECAMERA, "menu_togglecamera"},
190   {"ToggleConsole", 'O', 0, ID_TOGGLECONSOLE, "menu_toggleconsole"},
191   {"ToggleView", 'V', 0x05, ID_TOGGLEVIEW, "menu_toggleview"},
192   {"ToggleZ", 'Z', 0x05, ID_TOGGLEZ, "menu_togglez"},
193   {"ConnectSelection", 'K', 0x04, ID_SELECTION_CONNECT, "menu_selection_connect"},
194   {"Brush3Sided", '3', 0x04, ID_BRUSH_3SIDED, "menu_brush_3sided"},
195   {"Brush4Sided", '4', 0x04, ID_BRUSH_4SIDED, "menu_brush_4sided"},
196   {"Brush5Sided", '5', 0x04, ID_BRUSH_5SIDED, "menu_brush_5sided"},
197   {"Brush6Sided", '6', 0x04, ID_BRUSH_6SIDED, "menu_brush_6sided"},
198   {"Brush7Sided", '7', 0x04, ID_BRUSH_7SIDED, "menu_brush_7sided"},
199   {"Brush8Sided", '8', 0x04, ID_BRUSH_8SIDED, "menu_brush_8sided"},
200   {"Brush9Sided", '9', 0x04, ID_BRUSH_9SIDED, "menu_brush_9sided"},
201   {"MatrixTranspose", 'M', 0x05, ID_CURVE_MATRIX_TRANSPOSE, "menu_curve_matrix_transpose"},
202   {"MakeDetail", 'M', 0x04, ID_SELECTION_MAKE_DETAIL, "menu_selection_make_detail"},
203   {"MapInfo", 'M', 0, ID_EDIT_MAPINFO, "menu_edit_mapinfo"},
204   {"NextLeakSpot", 'K', 0x05, ID_MISC_NEXTLEAKSPOT, "menu_misc_nextleakspot"},
205   {"PrevLeakSpot", 'L', 0x05, ID_MISC_PREVIOUSLEAKSPOT, "menu_misc_previousleakspot"},
206   {"FileOpen", 'O', 0x04, ID_FILE_OPEN, "menu_file_open"},
207   {"FileSave", 'S', 0x04, ID_FILE_SAVE, "menu_file_save"},
208   //% {"Exit", 'X', 0x04, ID_FILE_EXIT, "menu_file_exit"}, // ydnar: Ctrl+X should be cut
209   {"CenterXYView", GDK_Tab, 0x05, ID_VIEW_CENTERVIEW, "menu_view_centerview"},
210   {"NextView", GDK_Tab, 0x04, ID_VIEW_NEXTVIEW, "menu_view_nextview"},
211   {"ClipSelected", GDK_Return, 0x00, ID_CLIP_SELECTED, "menu_clip_selected"},
212   {"SplitSelected", GDK_Return, 0x01, ID_SPLIT_SELECTED, "menu_split_selected"},
213   {"FlipClip", GDK_Return, 0x04, ID_FLIP_CLIP, "menu_flip_clip"},
214   {"MouseRotate", 'R', 0x00, ID_SELECT_MOUSEROTATE, "menu_select_mouserotate"},
215   {"Copy", 'C', 0x04, ID_EDIT_COPYBRUSH, "menu_edit_copybrush"},
216   {"Paste", 'V', 0x04, ID_EDIT_PASTEBRUSH, "menu_edit_pastebrush"},
217   {"PasteToCamera", 'V', RAD_ALT, ID_EDIT_PASTEBRUSHTOCAMERA, "menu_edit_pastebrushtocamera"},
218   {"Undo", 'Z', 0x04, ID_EDIT_UNDO, "menu_edit_undo"},
219   {"Redo", 'Y', 0x04, ID_EDIT_REDO, "menu_edit_redo"},
220   {"ZZoomOut", GDK_Insert, 0x04, ID_VIEW_ZZOOMOUT, "menu_view_zzoomout"},
221   {"ZZoomIn", GDK_Delete, 0x04, ID_VIEW_ZZOOMIN, "menu_view_zzoomin"},
222   {"TexRotateClock", GDK_Next, 0x01, ID_SELECTION_TEXTURE_ROTATECLOCK, "menu_selection_texture_rotateclock"},
223   {"TexRotateCounter", GDK_Prior, 0x01, ID_SELECTION_TEXTURE_ROTATECOUNTER, "menu_selection_texture_rotatecounter"},
224   {"TexScaleUp", GDK_Up, 0x04, ID_SELECTION_TEXTURE_SCALEUP, "menu_selection_texture_scaleup"},
225   {"TexScaleDown", GDK_Down, 0x04, ID_SELECTION_TEXTURE_SCALEDOWN, "menu_selection_texture_scaledown"},
226   {"TexShiftLeft", GDK_Left, 0x01, ID_SELECTION_TEXTURE_SHIFTLEFT, "menu_selection_texture_shiftleft"},
227   {"TexShiftRight", GDK_Right, 0x01, ID_SELECTION_TEXTURE_SHIFTRIGHT, "menu_selection_texture_shiftright"},
228   {"TexShiftUp", GDK_Up, 0x01, ID_SELECTION_TEXTURE_SHIFTUP, "menu_selection_texture_shiftup"},
229   {"TexShiftDown", GDK_Down, 0x01, ID_SELECTION_TEXTURE_SHIFTDOWN, "menu_selection_texture_shiftdown"},
230   {"GridDown", '[', 0x00, ID_GRID_PREV, "menu_grid_prev"},
231   {"GridUp", ']', 0x00, ID_GRID_NEXT, "menu_grid_next"},
232   {"TexScaleLeft", GDK_Left, 0x04, ID_SELECTION_TEXTURE_SCALELEFT, "menu_selection_texture_scaleleft"},
233   {"TexScaleRight", GDK_Right, 0x04, ID_SELECTION_TEXTURE_SCALERIGHT, "menu_selection_texture_scaleright"},
234   {"CubicClipZoomOut", ']', 0x04, ID_VIEW_CUBEOUT, "menu_view_cubeout"},
235   {"CubicClipZoomIn", '[', 0x04, ID_VIEW_CUBEIN, "menu_view_cubein"},
236   {"ToggleCubicClip", '\\', 0x04, ID_VIEW_CUBICCLIPPING, "menu_view_cubicclipping"},
237   {"MoveSelectionDOWN", GDK_KP_Subtract, 0x00, ID_SELECTION_MOVEDOWN, "menu_selection_movedown"},
238   {"MoveSelectionUP", GDK_KP_Add, 0x00, ID_SELECTION_MOVEUP, "menu_selection_moveup"},
239   {"DumpSelectedBrush", 'D', 0x01, ID_SELECTION_PRINT, "menu_selection_print"},
240   {"ToggleSizePaint", 'Q', 0x00, ID_SELECTION_TOGGLESIZEPAINT, "menu_selection_togglesizepaint"},
241   {"SelectNudgeLeft", GDK_Left, 0x02, ID_SELECTION_SELECT_NUDGELEFT, "menu_selection_select_nudgeleft"},
242   {"SelectNudgeRight", GDK_Right, 0x02, ID_SELECTION_SELECT_NUDGERIGHT, "menu_selection_select_nudgeright"},
243   {"SelectNudgeUp", GDK_Up, 0x02, ID_SELECTION_SELECT_NUDGEUP, "menu_selection_select_nudgeup"},
244   {"CycleCapTexturePatch", 'N', 0x05, ID_CURVE_CYCLECAP, "menu_curve_cyclecap"},
245   {"NaturalizePatch", 'N', 0x04, ID_PATCH_NATURALIZE, "menu_patch_naturalize"},
246   {"SnapToGrid", 'G', 0x04, ID_SELECT_SNAPTOGRID, "menu_select_snaptogrid"},
247   {"ShowAllTextures", 'A', 0x04, ID_TEXTURES_SHOWALL, "menu_textures_showall"},
248   {"SelectAllOfType", 'A', 0x01, ID_SELECT_ALL, "menu_select_all"},
249   {"CapCurrentCurve", 'C', 0x01, ID_CURVE_CAP, "menu_curve_cap"},
250   {"MakeStructural", 'S', 0x05, ID_SELECTION_MAKE_STRUCTURAL, "menu_selection_make_structural"},
251   {"RegionSetSelection", 'R', 0x05, ID_REGION_SETSELECTION, "menu_region_setselection"},
252   {"ShowInUse", 'U', 0, ID_TEXTURES_SHOWINUSE, "menu_textures_showinuse"},
253   {"InvertSelection", 'I', 0, ID_SELECTION_INVERT, "menu_selection_invert"},
254   {"Sleep", 'P', 0x05, ID_FILE_SLEEP, "menu_file_sleep"},
255   {"SimplePatchMesh", 'P', 0x01, ID_CURVE_SIMPLEPATCHMESH, "menu_simplepatchmesh"},
256   {"FilterWorldBrushes", '1', RAD_ALT, ID_FILTER_WORLD, "menu_filter_world"},
257   {"FilterEntities", '2', RAD_ALT, ID_FILTER_ENTITIES, "menu_filter_entities"},
258   {"FilterAreaportals", '3', RAD_ALT, ID_FILTER_AREAPORTALS, "menu_filter_areaportals"},
259   {"FilterTranslucent", '4', RAD_ALT, ID_FILTER_TRANSLUCENT, "menu_filter_translucent"},
260   {"FilterLiquids", '5', RAD_ALT, ID_FILTER_LIQUIDS, "menu_filter_liquids"},
261   {"FilterCaulk", '6', RAD_ALT , ID_FILTER_CAULK, "menu_filter_caulk"},
262   {"FilterClips", '7', RAD_ALT, ID_FILTER_CLIPS, "menu_filter_clips"},
263   {"FilterBotClips", 'M', RAD_ALT, ID_FILTER_BOTCLIPS, "menu_filter_botclips"},
264   {"FilterPaths", '8', RAD_ALT, ID_FILTER_PATHS, "menu_filter_paths"},
265   {"FilterClusterportals", '9', RAD_ALT, ID_FILTER_CLUSTERPORTALS, "menu_filter_clusterportals"},
266   {"FilterLights", '0', RAD_ALT, ID_FILTER_LIGHTS, "menu_filter_lights"},
267   {"FilterPatches", 'P', RAD_CONTROL, ID_FILTER_PATCHES, "menu_filter_patches"},
268   {"FilterDetails", 'D', RAD_CONTROL, ID_FILTER_DETAILS, "menu_filter_details"},
269   {"FilterStructural", 'D', RAD_CONTROL|RAD_SHIFT, ID_FILTER_STRUCTURAL, "menu_filter_structural"},
270   {"FilterHintsSkips", 'H', RAD_CONTROL, ID_FILTER_HINTSSKIPS, "menu_filter_hintsskips"},
271   {"FilterModels", 'M', RAD_SHIFT, ID_FILTER_MODELS, "menu_filter_models"},
272   {"FilterTriggers", 'T', RAD_CONTROL|RAD_SHIFT, ID_FILTER_TRIGGERS, "menu_filter_triggers"},
273   {"LoadPointfile", 'L', RAD_SHIFT, ID_FILE_POINTFILE, "menu_load_pointfile"},
274   {"TextureWindowScaledown", GDK_Insert, RAD_ALT, ID_TEXTUREWINDOW_SCALEDOWN, "menu_texturewindow_scaledown"},
275   {"TextureWindowScaleup", GDK_Delete, RAD_ALT, ID_TEXTUREWINDOW_SCALEUP, "menu_texturewindow_scaleup"},
276 };
277
278 int g_nCommandCount = sizeof(g_Commands) / sizeof(SCommandInfo);
279
280 SKeyInfo g_Keys[] =
281 {
282   {"Space", GDK_space},
283   {"Backspace", GDK_BackSpace},
284   {"Escape", GDK_Escape},
285   {"End", GDK_End},
286   {"Insert", GDK_Insert},
287   {"Delete", GDK_Delete},
288   {"PageUp", GDK_Prior},
289   {"PageDown", GDK_Next},
290   {"Up", GDK_Up},
291   {"Down", GDK_Down},
292   {"Left", GDK_Left},
293   {"Right", GDK_Right},
294   {"F1", GDK_F1},
295   {"F2", GDK_F2},
296   {"F3", GDK_F3},
297   {"F4", GDK_F4},
298   {"F5", GDK_F5},
299   {"F6", GDK_F6},
300   {"F7", GDK_F7},
301   {"F8", GDK_F8},
302   {"F9", GDK_F9},
303   {"F10", GDK_F10},
304   {"F11", GDK_F11},
305   {"F12", GDK_F12},
306   {"Tab", GDK_Tab},
307   {"Return", GDK_Return},                           
308   {"Comma", GDK_comma},
309   {"Period", GDK_period},
310   {"Plus", GDK_KP_Add},
311   {"Multiply", GDK_multiply},
312   {"Subtract", GDK_KP_Subtract},
313   {"NumPad0", GDK_KP_0},
314   {"NumPad1", GDK_KP_1},
315   {"NumPad2", GDK_KP_2},
316   {"NumPad3", GDK_KP_3},
317   {"NumPad4", GDK_KP_4},
318   {"NumPad5", GDK_KP_5},
319   {"NumPad6", GDK_KP_6},
320   {"NumPad7", GDK_KP_7},
321   {"NumPad8", GDK_KP_8},
322   {"NumPad9", GDK_KP_9},
323   {"[", 219},
324   {"]", 221},
325   {"\\", 220},
326   {"Home", GDK_Home}
327 };
328
329 int g_nKeyCount = sizeof(g_Keys) / sizeof(SKeyInfo);
330
331 // =============================================================================
332 // global functions
333
334 void WINAPI Sys_UpdateWindows (int nBits)
335 {
336   g_nUpdateBits |= nBits;
337
338
339 // =============================================================================
340 // Static functions
341
342 // Gef: Separate handling for keyup events
343 void HandleKeyUp (GtkWidget *widget, gpointer data)
344 {
345   int id = GPOINTER_TO_INT (data);
346 #ifdef DBG_KBD
347   Sys_Printf("HandleKeyUp: %d\n", id);
348 #endif
349   
350   if(g_bIgnoreCommands)
351     return;
352   
353   switch (id)
354   {
355     case ID_CAMERA_FORWARD: g_pParentWnd->OnCameraForward (FALSE); break;
356     case ID_CAMERA_BACK: g_pParentWnd->OnCameraBack (FALSE); break;
357     case ID_CAMERA_LEFT: g_pParentWnd->OnCameraLeft (FALSE); break;
358     case ID_CAMERA_RIGHT: g_pParentWnd->OnCameraRight (FALSE); break;
359     case ID_CAMERA_STRAFELEFT: g_pParentWnd->OnCameraStrafeleft (FALSE); break;
360     case ID_CAMERA_STRAFERIGHT: g_pParentWnd->OnCameraStraferight (FALSE); break;
361   }
362 }
363
364 gint HandleCommand (GtkWidget *widget, gpointer data)
365 {
366   int id = GPOINTER_TO_INT (data);
367 #ifdef DBG_KBD
368   Sys_Printf("HandleCommand %d\n", id);
369 #endif
370
371   if ( g_bIgnoreCommands ) {
372 #ifdef DBG_KBD
373     Sys_Printf( "g_bIgnoreCommands %d, returning FALSE\n", g_bIgnoreCommands );
374 #endif
375     return FALSE;
376   }
377
378   if (id >= CMD_TEXTUREWAD && id <= CMD_TEXTUREWAD_END) g_pParentWnd->OnTextureWad (id);
379   else if (id >= CMD_BSPCOMMAND && id <= CMD_BSPCOMMAND_END) g_pParentWnd->OnBspCommand (id);
380   else if (id >= ID_FILE_RECENT1 && id <= ID_FILE_RECENT4) g_pParentWnd->OnMru (id);
381   else if (id >= ID_VIEW_NEAREST && id <= ID_TEXTURES_FLATSHADE)
382   {
383     if (GTK_CHECK_MENU_ITEM (widget)->active)
384       g_pParentWnd->OnViewNearest (id);
385   } else if (id >= ID_GRID_025 && id <= ID_GRID_256) g_pParentWnd->OnGrid (id);
386   else if (id >= ID_PLUGIN_START && id <= ID_PLUGIN_END)
387   {
388     char *str;
389     gtk_label_get (GTK_LABEL (GTK_BIN (widget)->child), &str);
390     g_pParentWnd->OnPlugIn (id, str);
391   } else if (id >= ID_ENTITY_START && id <= ID_ENTITY_END)
392   {
393     char *str;
394     gtk_label_get (GTK_LABEL (GTK_BIN (widget)->child), &str);
395     g_pParentWnd->ActiveXY()->OnEntityCreate (str);
396   }
397   else switch (id)
398     {
399     case ID_FILE_NEW: g_pParentWnd->OnFileNew (); break;
400     case ID_FILE_SLEEP: g_pParentWnd->OnSleep(); break;
401     case ID_FILE_OPEN: g_pParentWnd->OnFileOpen (); break;
402     case ID_FILE_SAVE: g_pParentWnd->OnFileSave (); break;
403     case ID_FILE_SAVEAS: g_pParentWnd->OnFileSaveas (); break;
404     case ID_FILE_EXPORTMAP: g_pParentWnd->OnFileExportmap (); break;
405     case ID_FILE_SAVEREGION: g_pParentWnd->OnFileSaveregion (); break;
406     case ID_FILE_NEWPROJECT: g_pParentWnd->OnFileNewproject (); break;
407     case ID_FILE_LOADPROJECT: g_pParentWnd->OnFileLoadproject (); break;
408     case ID_FILE_PROJECTSETTINGS: g_pParentWnd->OnFileProjectsettings (); break;
409     case ID_FILE_POINTFILE: g_pParentWnd->OnFilePointfile (); break;
410     case ID_FILE_CHECKUPDATE: g_pParentWnd->OnFileCheckUpdate (); break;
411     case ID_FILE_EXIT: g_pParentWnd->OnFileExit (); break;
412     case ID_FILE_IMPORTMAP: g_pParentWnd->OnFileImportmap (); break;
413     case ID_EDIT_UNDO: g_pParentWnd->OnEditUndo (); break;
414     case ID_EDIT_REDO: g_pParentWnd->OnEditRedo (); break;
415     case ID_EDIT_COPYBRUSH: g_pParentWnd->OnEditCopybrush (); break;
416     case ID_EDIT_PASTEBRUSH: g_pParentWnd->OnEditPastebrush (); break;
417     case ID_EDIT_PASTEBRUSHTOCAMERA: g_pParentWnd->OnEditPastebrushToCamera (); break;
418     case ID_SELECTION_DELETE: g_pParentWnd->OnSelectionDelete (); break;
419     case ID_EDIT_MAPINFO: g_pParentWnd->OnEditMapinfo (); break;
420     case ID_EDIT_ENTITYINFO: g_pParentWnd->OnEditEntityinfo (); break;
421     case ID_BRUSH_SCRIPTS: g_pParentWnd->OnBrushScripts (); break;
422     case ID_EDIT_LOADPREFAB: g_pParentWnd->OnEditLoadprefab (); break;
423     case ID_EDIT_SAVEPREFAB: g_pParentWnd->OnEditSaveprefab (); break;
424     case ID_PREFS: g_pParentWnd->OnPrefs (); break;
425     case ID_TOGGLECAMERA: g_pParentWnd->OnTogglecamera (); break;
426     case ID_TOGGLECONSOLE: g_pParentWnd->OnToggleconsole (); break;
427     case ID_VIEW_ENTITY: g_pParentWnd->OnViewEntity (); break;
428     case ID_VIEW_GROUPS: g_pParentWnd->OnViewGroups (); break;
429     case ID_TOGGLEVIEW: g_pParentWnd->OnToggleview (); break;
430     case ID_TOGGLEVIEW_YZ: g_pParentWnd->OnToggleviewYz (); break;
431     case ID_TOGGLEVIEW_XZ: g_pParentWnd->OnToggleviewXz (); break;
432     case ID_TOGGLEZ: g_pParentWnd->OnTogglez (); break;
433     case ID_VIEW_CENTER: g_pParentWnd->OnViewCenter (); break;
434     case ID_VIEW_UPFLOOR: g_pParentWnd->OnViewUpfloor (); break;
435     case ID_VIEW_DOWNFLOOR: g_pParentWnd->OnViewDownfloor (); break;
436     case ID_VIEW_CENTERVIEW: g_pParentWnd->OnViewCenterview (); break;
437     case ID_VIEW_NEXTVIEW: g_pParentWnd->OnViewNextview (); break;
438     case ID_VIEW_XY: g_pParentWnd->OnViewXy (); break;
439     case ID_VIEW_SIDE: g_pParentWnd->OnViewSide (); break;
440     case ID_VIEW_FRONT: g_pParentWnd->OnViewFront (); break;
441     case ID_VIEW_100: g_pParentWnd->OnView100 (); break;
442     case ID_VIEW_ZOOMIN: g_pParentWnd->OnViewZoomin (); break;
443     case ID_VIEW_ZOOMOUT: g_pParentWnd->OnViewZoomout (); break;
444     case ID_VIEW_Z100: g_pParentWnd->OnViewZ100 (); break;
445     case ID_VIEW_ZZOOMIN: g_pParentWnd->OnViewZzoomin (); break;
446     case ID_VIEW_ZZOOMOUT: g_pParentWnd->OnViewZzoomout (); break;
447     case ID_VIEW_CUBEIN: g_pParentWnd->OnViewCubein (); break;
448     case ID_VIEW_CUBEOUT: g_pParentWnd->OnViewCubeout (); break;
449     case ID_VIEW_SHOWNAMES: g_pParentWnd->OnViewShownames (); break;
450     case ID_VIEW_SHOWBLOCKS: g_pParentWnd->OnViewShowblocks (); break;
451     case ID_VIEW_SHOWCOORDINATES: g_pParentWnd->OnViewShowcoordinates (); break;
452     case ID_VIEW_SHOWOUTLINE: g_pParentWnd->OnViewShowOutline (); break;
453     case ID_VIEW_SHOWAXES: g_pParentWnd->OnViewShowAxes (); break;
454     case ID_VIEW_SHOWWORKZONE: g_pParentWnd->OnViewShowWorkzone (); break;
455     case ID_VIEW_SHOWANGLES: g_pParentWnd->OnViewShowAngles (); break;
456     case ID_VIEW_HIDESHOW_HIDESELECTED: g_pParentWnd->OnViewHideshowHideselected (); break;
457     case ID_VIEW_HIDESHOW_SHOWHIDDEN: g_pParentWnd->OnViewHideshowShowhidden (); break;
458     case ID_VIEW_ENTITIESAS_BOUNDINGBOX:
459     case ID_VIEW_ENTITIESAS_WIREFRAME:
460     case ID_VIEW_ENTITIESAS_SELECTEDWIREFRAME:
461     case ID_VIEW_ENTITIESAS_SELECTEDSKINNED:
462     case ID_VIEW_ENTITIESAS_SKINNED:
463     case ID_VIEW_ENTITIESAS_SKINNEDANDBOXED:
464       g_pParentWnd->OnEntitiesSetViewAs(id);
465       break;
466     case ID_VIEW_CUBICCLIPPING: g_pParentWnd->OnViewCubicclipping (); break;
467     case ID_VIEW_OPENGLLIGHTING: g_pParentWnd->OnViewOpengllighting (); break;
468     case ID_SELECTION_DRAGEDGES: g_pParentWnd->OnSelectionDragedges (); break;
469     case ID_SELECTION_DRAGVERTECIES: g_pParentWnd->OnSelectionDragvertecies (); break;
470     case ID_SELECTION_CLONE: g_pParentWnd->OnSelectionClone (); break;
471     case ID_SELECTION_DESELECT: g_pParentWnd->OnSelectionDeselect (); break;
472     case ID_BRUSH_FLIPX: g_pParentWnd->OnBrushFlipx (); break;
473     case ID_BRUSH_FLIPY: g_pParentWnd->OnBrushFlipy (); break;
474     case ID_BRUSH_FLIPZ: g_pParentWnd->OnBrushFlipz (); break;
475     case ID_BRUSH_ROTATEX: g_pParentWnd->OnBrushRotatex (); break;
476     case ID_BRUSH_ROTATEY: g_pParentWnd->OnBrushRotatey (); break;
477     case ID_BRUSH_ROTATEZ: g_pParentWnd->OnBrushRotatez (); break;
478     case ID_SELECTION_ARBITRARYROTATION: g_pParentWnd->OnSelectionArbitraryrotation (); break;
479     case ID_SELECT_SCALE: g_pParentWnd->OnSelectScale (); break;
480     case ID_SELECTION_MAKEHOLLOW: g_pParentWnd->OnSelectionMakehollow (); break;
481     case ID_SELECTION_CSGSUBTRACT: g_pParentWnd->OnSelectionCsgsubtract (); break;
482     case ID_SELECTION_CSGMERGE: g_pParentWnd->OnSelectionCsgmerge (); break;
483     case ID_SELECTION_NOOUTLINE: g_pParentWnd->OnSelectionNoOutline (); break;
484     case ID_SELECTION_OUTLINESTYLE: g_pParentWnd->OnSelectionOutlineStyle (); break;      
485     case ID_SELECTION_SELECTCOMPLETETALL: g_pParentWnd->OnSelectionSelectcompletetall (); break;
486     case ID_SELECTION_SELECTTOUCHING: g_pParentWnd->OnSelectionSelecttouching (); break;
487     case ID_SELECTION_SELECTPARTIALTALL: g_pParentWnd->OnSelectionSelectpartialtall (); break;
488     case ID_SELECTION_SELECTINSIDE: g_pParentWnd->OnSelectionSelectinside (); break;
489     case ID_SELECTION_SELECT_NUDGELEFT: g_pParentWnd->OnSelectionSelectNudgeleft (); break;
490     case ID_SELECTION_SELECT_NUDGERIGHT: g_pParentWnd->OnSelectionSelectNudgeright (); break;
491     case ID_SELECTION_SELECT_NUDGEUP: g_pParentWnd->OnSelectionSelectNudgeup (); break;
492     case ID_SELECTION_SELECT_NUDGEDOWN: g_pParentWnd->OnSelectionSelectNudgedown (); break;
493     case ID_VIEW_CLIPPER: g_pParentWnd->OnViewClipper (); break;
494     case ID_CLIP_SELECTED: g_pParentWnd->OnClipSelected (); break;
495     case ID_SPLIT_SELECTED: g_pParentWnd->OnSplitSelected (); break;
496     case ID_FLIP_CLIP: g_pParentWnd->OnFlipClip (); break;
497     case ID_SELECTION_CONNECT: g_pParentWnd->OnSelectionConnect (); break;
498     case ID_SELECTION_UNGROUPENTITY: g_pParentWnd->OnSelectionUngroupentity (); break;
499     case ID_SELECTION_MERGE: Select_MergeEntity(); break;
500     case ID_SELECTION_SEPERATE: Select_Seperate(); break;
501     case ID_SELECTION_MAKE_DETAIL: g_pParentWnd->OnSelectionMakeDetail (); break;
502     case ID_SELECTION_MAKE_STRUCTURAL: g_pParentWnd->OnSelectionMakeStructural (); break;
503     case ID_SNAPTOGRID: g_pParentWnd->OnSnaptogrid (); break;
504     case ID_TEXTURES_SHOWINUSE: g_pParentWnd->OnTexturesShowinuse (); break;
505     case ID_TEXTURES_SHOWALL: g_pParentWnd->OnTexturesShowall (); break;
506     case ID_TEXTURES_INSPECTOR: g_pParentWnd->OnTexturesInspector (); break;
507     case ID_TEXTURE_REPLACEALL: g_pParentWnd->OnTextureReplaceall (); break;
508     case ID_TOGGLE_LOCK: g_pParentWnd->OnToggleLock (); break;
509     case ID_TOGGLE_ROTATELOCK: g_pParentWnd->OnToggleRotatelock (); break;
510     case ID_TEXTURES_LOAD: g_pParentWnd->OnTexturesLoad (); break;
511     case ID_TEXTURES_RELOADSHADERS: g_pParentWnd->OnTexturesReloadshaders (); break;
512     case ID_TEXTURES_SHADERS_SHOW: g_pParentWnd->OnTexturesShadersShow (); break;
513     case ID_TEXTURES_TEXTUREWINDOWSCALE_200: 
514     case ID_TEXTURES_TEXTUREWINDOWSCALE_100:
515     case ID_TEXTURES_TEXTUREWINDOWSCALE_50:
516     case ID_TEXTURES_TEXTUREWINDOWSCALE_25:
517     case ID_TEXTURES_TEXTUREWINDOWSCALE_10:
518       g_pParentWnd->SetTextureScale (id);
519       break;
520     case ID_TEXTURES_LOADLIST: g_pParentWnd->OnTexturesLoadlist (); break;
521     case ID_TEXTURES_SHADERLISTONLY: g_pParentWnd->OnTexturesShaderlistonly (); break;
522     case ID_TEXTUREWINDOW_SCALEUP: g_pParentWnd->OnTexturewindowScaleup (); break;
523     case ID_TEXTUREWINDOW_SCALEDOWN: g_pParentWnd->OnTexturewindowScaledown (); break;
524     case ID_MISC_BENCHMARK: g_pParentWnd->OnMiscBenchmark (); break;
525     case ID_COLOR_SETORIGINAL: g_pParentWnd->OnColorSetoriginal (); break;
526     case ID_COLOR_SETQER: g_pParentWnd->OnColorSetqer (); break;
527     case ID_COLOR_SETBLACK: g_pParentWnd->OnColorSetblack (); break;
528     case ID_COLOR_SETYDNAR: g_pParentWnd->OnColorSetydnar (); break;  /* ydnar */
529     case ID_TEXTUREBK: g_pParentWnd->OnTexturebk (); break;
530     case ID_COLORS_XYBK: g_pParentWnd->OnColorsXybk (); break;
531     case ID_COLORS_MAJOR: g_pParentWnd->OnColorsMajor (); break;
532     case ID_COLORS_MINOR: g_pParentWnd->OnColorsMinor (); break;
533     case ID_COLORS_GRIDTEXT: g_pParentWnd->OnColorsGridtext (); break;
534     case ID_COLORS_GRIDBLOCK: g_pParentWnd->OnColorsGridblock (); break;
535     case ID_COLORS_CAMERABACK: g_pParentWnd->OnColorsCameraBack (); break;
536     case ID_COLORS_BRUSH: g_pParentWnd->OnColorsBrush (); break;
537     case ID_COLORS_SELECTEDBRUSH: g_pParentWnd->OnColorsSelectedbrush (); break;
538     case ID_COLORS_SELECTEDBRUSH3D: g_pParentWnd->OnColorsSelectedbrush3D (); break;
539     case ID_COLORS_CLIPPER: g_pParentWnd->OnColorsClipper (); break;
540     case ID_COLORS_VIEWNAME: g_pParentWnd->OnColorsViewname (); break;
541     case ID_MISC_GAMMA: g_pParentWnd->OnMiscGamma (); break;
542     case ID_MISC_FINDBRUSH: g_pParentWnd->OnMiscFindbrush (); break;
543     case ID_MISC_NEXTLEAKSPOT: g_pParentWnd->OnMiscNextleakspot (); break;
544     case ID_MISC_PREVIOUSLEAKSPOT: g_pParentWnd->OnMiscPreviousleakspot (); break;
545     case ID_MISC_PRINTXY: g_pParentWnd->OnMiscPrintxy (); break;
546     case ID_MISC_SELECTENTITYCOLOR: g_pParentWnd->OnMiscSelectentitycolor (); break;
547     case ID_CONVERTCURVES: g_pParentWnd->OnConvertcurves (); break;
548     case ID_REGION_OFF: g_pParentWnd->OnRegionOff (); break;
549     case ID_REGION_SETXY: g_pParentWnd->OnRegionSetxy (); break;
550     case ID_REGION_SETTALLBRUSH: g_pParentWnd->OnRegionSettallbrush (); break;
551     case ID_REGION_SETBRUSH: g_pParentWnd->OnRegionSetbrush (); break;
552     case ID_REGION_SETSELECTION: g_pParentWnd->OnRegionSetselection (); break;
553     case ID_BRUSH_3SIDED: g_pParentWnd->OnBrush3sided (); break;
554     case ID_BRUSH_4SIDED: g_pParentWnd->OnBrush4sided (); break;
555     case ID_BRUSH_5SIDED: g_pParentWnd->OnBrush5sided (); break;
556     case ID_BRUSH_6SIDED: g_pParentWnd->OnBrush6sided (); break;
557     case ID_BRUSH_7SIDED: g_pParentWnd->OnBrush7sided (); break;
558     case ID_BRUSH_8SIDED: g_pParentWnd->OnBrush8sided (); break;
559     case ID_BRUSH_9SIDED: g_pParentWnd->OnBrush9sided (); break;
560     case ID_BRUSH_ARBITRARYSIDED: g_pParentWnd->OnBrushArbitrarysided (); break;
561     case ID_BRUSH_MAKECONE: g_pParentWnd->OnBrushMakecone (); break;
562     case ID_BRUSH_PRIMITIVES_SPHERE: g_pParentWnd->OnBrushPrimitivesSphere (); break;
563     case ID_CURVE_PATCHTUBE: g_pParentWnd->OnCurvePatchtube (); break;
564     case ID_CURVE_PATCHDENSETUBE: g_pParentWnd->OnCurvePatchdensetube (); break;
565     case ID_CURVE_PATCHVERYDENSETUBE: g_pParentWnd->OnCurvePatchverydensetube (); break;
566     case ID_CURVE_PATCHSQUARE: g_pParentWnd->OnCurvePatchsquare (); break;
567     case ID_CURVE_PATCHENDCAP: g_pParentWnd->OnCurvePatchendcap (); break;
568     case ID_CURVE_PATCHBEVEL: g_pParentWnd->OnCurvePatchbevel (); break;
569     case ID_CURVE_MOREENDCAPSBEVELS_SQUAREBEVEL: g_pParentWnd->OnCurveMoreendcapsbevelsSquarebevel (); break;
570     case ID_CURVE_MOREENDCAPSBEVELS_SQUAREENDCAP: g_pParentWnd->OnCurveMoreendcapsbevelsSquareendcap();break;
571     case ID_CURVE_PATCHCONE: g_pParentWnd->OnCurvePatchcone (); break;
572     case ID_CURVE_SIMPLEPATCHMESH: g_pParentWnd->OnCurveSimplepatchmesh (); break;
573     case ID_CURVE_INSERT_INSERTCOLUMN: g_pParentWnd->OnCurveInsertInsertcolumn (); break;
574     case ID_CURVE_INSERT_ADDCOLUMN: g_pParentWnd->OnCurveInsertAddcolumn (); break;
575     case ID_CURVE_INSERT_INSERTROW: g_pParentWnd->OnCurveInsertInsertrow (); break;
576     case ID_CURVE_INSERT_ADDROW: g_pParentWnd->OnCurveInsertAddrow (); break;
577     case ID_CURVE_DELETE_FIRSTCOLUMN: g_pParentWnd->OnCurveDeleteFirstcolumn (); break;
578     case ID_CURVE_DELETE_LASTCOLUMN: g_pParentWnd->OnCurveDeleteLastcolumn (); break;
579     case ID_CURVE_DELETE_FIRSTROW: g_pParentWnd->OnCurveDeleteFirstrow (); break;
580     case ID_CURVE_DELETE_LASTROW: g_pParentWnd->OnCurveDeleteLastrow (); break;
581     case ID_CURVE_NEGATIVE: g_pParentWnd->OnCurveNegative (); break;
582     case ID_CURVE_REDISPERSE_ROWS: g_pParentWnd->OnCurveRedisperseRows (); break;
583     case ID_CURVE_REDISPERSE_INTERMEDIATE_COLS: g_pParentWnd->OnCurveRedisperseIntermediateCols (); break;
584     case ID_CURVE_REDISPERSE_INTERMEDIATE_ROWS: g_pParentWnd->OnCurveRedisperseIntermediateRows (); break;
585     case ID_CURVE_MATRIX_TRANSPOSE: g_pParentWnd->OnCurveMatrixTranspose (); break;
586     case ID_CURVE_CAP: g_pParentWnd->OnCurveCap (); break;
587     case ID_CURVE_CYCLECAP: g_pParentWnd->OnCurveCyclecap (); break;
588     case ID_CURVE_OVERLAY_SET: g_pParentWnd->OnCurveOverlaySet (); break;
589     case ID_CURVE_OVERLAY_CLEAR: g_pParentWnd->OnCurveOverlayClear (); break;
590     case ID_CURVE_THICKEN: g_pParentWnd->OnCurveThicken (); break;
591     case ID_PLUGINS_REFRESH: g_pParentWnd->OnPluginsRefresh (); break;
592     case ID_HELP: g_pParentWnd->OnHelp (); break;
593     case ID_HELP_LINKS: g_pParentWnd->OnHelpLinks(); break;
594     case ID_HELP_BUGREPORT: g_pParentWnd->OnHelpBugreport(); break;
595     case ID_HELP_COMMANDLIST: g_pParentWnd->OnHelpCommandlist (); break;
596     case ID_HELP_ABOUT: g_pParentWnd->OnHelpAbout (); break;
597     case ID_DONTSELECTMODEL: g_pParentWnd->OnDontselectmodel (); break;
598     case ID_FILTER_AREAPORTALS: g_pParentWnd->OnFilterAreaportals (); break;
599     case ID_FILTER_CAULK: g_pParentWnd->OnFilterCaulk (); break;
600     case ID_FILTER_STRUCTURAL: g_pParentWnd->OnFilterStructural (); break;
601     case ID_FILTER_CLIPS: g_pParentWnd->OnFilterClips (); break;
602     case ID_FILTER_BOTCLIPS: g_pParentWnd->OnFilterBotClips (); break;
603     case ID_FILTER_DETAILS: g_pParentWnd->OnFilterDetails (); break;
604     case ID_FILTER_ENTITIES: g_pParentWnd->OnFilterEntities (); break;
605     case ID_FILTER_HINTSSKIPS: g_pParentWnd->OnFilterHintsskips (); break;
606     case ID_FILTER_LIGHTS: g_pParentWnd->OnFilterLights (); break;
607     case ID_FILTER_LIQUIDS: g_pParentWnd->OnFilterLiquids (); break;
608     case ID_FILTER_MODELS: g_pParentWnd->OnFilterModels (); break;
609     case ID_FILTER_PATCHES: g_pParentWnd->OnFilterPatches (); break;
610     case ID_FILTER_TRANSLUCENT: g_pParentWnd->OnFilterTranslucent (); break;
611     case ID_FILTER_TRIGGERS: g_pParentWnd->OnFilterTriggers (); break;
612     case ID_FILTER_WORLD: g_pParentWnd->OnFilterWorld (); break;
613     case ID_FILTER_PATHS: g_pParentWnd->OnFilterPaths (); break;
614     case ID_FILTER_CLUSTERPORTALS: g_pParentWnd->OnFilterClusterportals (); break;
615     case ID_FILTER_LIGHTGRID: g_pParentWnd->OnFilterLightgrid (); break;
616
617     case ID_POPUP_SELECTION: g_pParentWnd->OnPopupSelection (); break;
618     case ID_VIEW_CHANGE: g_pParentWnd->OnViewChange (); break;
619     case ID_TEXTURES_POPUP: g_pParentWnd->OnTexturesPopup (); break;
620     case ID_VIEW_CAMERATOGGLE: g_pParentWnd->ToggleCamera (); break;
621     case ID_VIEW_CAMERAUPDATE: g_pParentWnd->OnViewCameraupdate (); break;
622     case ID_SELECT_MOUSEROTATE: g_pParentWnd->OnSelectMouserotate (); break;
623     case ID_SELECT_MOUSESCALE: g_pParentWnd->OnSelectMousescale (); break;
624     case ID_SCALELOCKX: g_pParentWnd->OnScalelockx (); break;
625     case ID_SCALELOCKY: g_pParentWnd->OnScalelocky (); break;
626     case ID_SCALELOCKZ: g_pParentWnd->OnScalelockz (); break;
627     case ID_DONTSELECTCURVE: g_pParentWnd->OnDontselectcurve (); break;
628     case ID_PATCH_SHOWBOUNDINGBOX: g_pParentWnd->OnPatchToggleBox (); break;
629     case ID_PATCH_WIREFRAME: g_pParentWnd->OnPatchWireframe (); break;
630     case ID_PATCH_BEND: g_pParentWnd->OnPatchBend (); break;
631     case ID_PATCH_WELD: g_pParentWnd->OnPatchWeld (); break;
632     case ID_PATCH_DRILLDOWN: g_pParentWnd->OnPatchDrilldown (); break;
633     case ID_DROP_GROUP_NAME: g_pParentWnd->OnDropGroupName (); break;
634     case ID_DROP_GROUP_NEWGROUP: g_pParentWnd->OnDropGroupNewgroup (); break;
635     case ID_DROP_GROUP_REMOVE: g_pParentWnd->OnDropGroupRemove (); break;
636     case ID_SHOW_ENTITIES: g_pParentWnd->OnShowEntities (); break;
637
638     case IDC_BTN_FACEFIT: g_pParentWnd->OnFaceFit (); break;
639     case ID_VIEW_TEXTURE: g_pParentWnd->OnViewTexture (); break;
640     case ID_PATCH_INSPECTOR: g_pParentWnd->OnPatchInspector (); break;
641     case ID_CURVE_NEGATIVETEXTUREX: g_pParentWnd->OnCurveNegativeTextureX (); break;
642     case ID_CURVE_NEGATIVETEXTUREY: g_pParentWnd->OnCurveNegativeTextureY (); break;
643     case ID_CURVE_INSERTCOLUMN: g_pParentWnd->OnCurveInsertcolumn (); break;
644     case ID_CURVE_INSERTROW: g_pParentWnd->OnCurveInsertrow (); break;
645     case ID_CURVE_DELETECOLUMN: g_pParentWnd->OnCurveDeletecolumn (); break;
646     case ID_CURVE_DELETEROW: g_pParentWnd->OnCurveDeleterow (); break;
647     case ID_PATCH_TAB: g_pParentWnd->OnPatchTab (); break;
648     case ID_CAMERA_FORWARD: g_pParentWnd->OnCameraForward (TRUE); break;
649     case ID_CAMERA_BACK: g_pParentWnd->OnCameraBack (TRUE); break;
650     case ID_CAMERA_LEFT: g_pParentWnd->OnCameraLeft (TRUE); break;
651     case ID_CAMERA_RIGHT: g_pParentWnd->OnCameraRight (TRUE); break;
652     case ID_CAMERA_UP: g_pParentWnd->OnCameraUp (); break;
653     case ID_CAMERA_DOWN: g_pParentWnd->OnCameraDown (); break;
654     case ID_CAMERA_ANGLEUP: g_pParentWnd->OnCameraAngleup (); break;
655     case ID_CAMERA_ANGLEDOWN: g_pParentWnd->OnCameraAngledown (); break;
656     case ID_CAMERA_STRAFELEFT: g_pParentWnd->OnCameraStrafeleft (TRUE); break;
657     case ID_CAMERA_STRAFERIGHT: g_pParentWnd->OnCameraStraferight (TRUE); break;
658     case ID_GRID_TOGGLE: g_pParentWnd->OnGridToggle (); break;
659     case ID_VIEW_CONSOLE: g_pParentWnd->OnViewConsole (); break;
660     case ID_VIEW_CROSSHAIR: g_pParentWnd->OnViewCrosshair (); break;
661     case ID_SELECTION_TEXTURE_FIT: g_pParentWnd->OnSelectionTextureFit (); break;
662     case ID_SELECTION_TEXTURE_ROTATECLOCK: g_pParentWnd->OnSelectionTextureRotateclock (); break;
663     case ID_SELECTION_TEXTURE_ROTATECOUNTER: g_pParentWnd->OnSelectionTextureRotatecounter (); break;
664     case ID_SELECTION_TEXTURE_SCALEUP: g_pParentWnd->OnSelectionTextureScaleup (); break;
665     case ID_SELECTION_TEXTURE_SCALEDOWN: g_pParentWnd->OnSelectionTextureScaledown (); break;
666     case ID_SELECTION_TEXTURE_SHIFTLEFT: g_pParentWnd->OnSelectionTextureShiftleft (); break;
667     case ID_SELECTION_TEXTURE_SHIFTRIGHT: g_pParentWnd->OnSelectionTextureShiftright (); break;
668     case ID_SELECTION_TEXTURE_SHIFTUP: g_pParentWnd->OnSelectionTextureShiftup (); break;
669     case ID_SELECTION_TEXTURE_SHIFTDOWN: g_pParentWnd->OnSelectionTextureShiftdown (); break;
670     case ID_GRID_PREV: g_pParentWnd->OnGridPrev (); break;
671     case ID_GRID_NEXT: g_pParentWnd->OnGridNext (); break;
672     case ID_SELECTION_TEXTURE_SCALELEFT: g_pParentWnd->OnSelectionTextureScaleLeft (); break;
673     case ID_SELECTION_TEXTURE_SCALERIGHT: g_pParentWnd->OnSelectionTextureScaleRight (); break;
674     case ID_SELECTION_MOVEDOWN: g_pParentWnd->OnSelectionMovedown (); break;
675     case ID_SELECTION_MOVEUP: g_pParentWnd->OnSelectionMoveup (); break;
676     case ID_SELECTION_PRINT: g_pParentWnd->OnSelectionPrint (); break;
677     case ID_SELECTION_TOGGLESIZEPAINT: g_pParentWnd->OnSelectionTogglesizepaint (); break;
678     case ID_PATCH_NATURALIZE: g_pParentWnd->OnPatchNaturalize (); break;
679     case ID_SELECT_SNAPTOGRID: g_pParentWnd->OnSnapToGrid (); break;
680     case ID_SELECT_ALL: g_pParentWnd->OnSelectAll (); break;
681     case ID_SELECTION_INVERT: g_pParentWnd->OnSelectionInvert (); break;
682     }
683
684     return TRUE;
685 }
686
687 static gint timer (gpointer data)
688 {
689   MainFrame *wnd = (MainFrame*)data;
690   wnd->OnTimer ();
691   return TRUE;
692 }
693
694 static gint mainframe_delete (GtkWidget *widget, GdkEvent *event, gpointer data)
695 {
696   MainFrame *wnd = (MainFrame*)data;
697
698   wnd->OnDelete();
699
700   if (ConfirmModified())
701     return FALSE;
702
703   g_qeglobals_gui.d_edit = NULL;
704
705   return TRUE;
706 }
707
708 static void mainframe_destroy (GtkWidget *widget, gpointer data)
709 {
710   MainFrame *wnd = (MainFrame*)data;
711
712   // avoid saving prefs when the app is minimized
713   if (g_pParentWnd->IsSleeping())
714   {
715     Sys_Printf("Shutdown while sleeping, not saving prefs\n");
716     g_qeglobals.disable_ini = true;
717   }
718
719   // NOTE TTimo this is very clumsy, in MainFrame::OnDestroy we might call SavePrefs again
720   //   we will do more stuff in OnDestroy for window position saving too, so I guess this call is still relevant?
721   g_PrefsDlg.SavePrefs ();
722   
723   wnd->OnDestroy ();
724   
725   // shutdown modules
726   // NOTE: I've decided to do this before SavePrefs in case we broadcast some shutdown info
727   // and modules / plugins decide to save some stuff
728   g_pParentWnd->GetPlugInMgr().Shutdown();
729     
730   delete wnd;
731
732   QGL_Shutdown();
733   g_PrefsDlg.Destroy ();
734   g_dlgSurface.Destroy ();
735   g_dlgFind.Destroy ();
736   g_PatchDialog.Destroy ();
737
738   gtk_main_quit ();
739 }
740
741 static gint mainframe_keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)
742 {
743   unsigned int code = gdk_keyval_to_upper(event->keyval);
744
745   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=924
746   if(code == GDK_ISO_Left_Tab) {
747     code = GDK_Tab;
748   }
749   
750 #ifdef DBG_KBD
751   Sys_Printf("key: %d (keyval: %d) (ctrl: %d)\n", code, event->keyval, event->state & GDK_CONTROL_MASK);
752 #endif
753
754   // BUG: http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=865
755   // return only if Texture Viewport  is in main window, otherwise if Tex viewport is in it's own window
756   // the Filter GtkEntry won't release focus
757   if ( g_pParentWnd->GetTexWnd()->m_pFilter == gtk_window_get_focus(GTK_WINDOW(widget)) )
758     if ( gtk_widget_is_focus( g_pParentWnd->GetTexWnd()->m_pFilter ) )
759       return FALSE;
760
761 #ifdef DBG_KBD
762   Sys_Printf("mainframe_keypress processing into a command\n");
763 #endif
764   for (int i = 0; i < g_nCommandCount; i++)
765   {
766     if (g_Commands[i].m_nKey == code)    // find a match?
767     {
768       // check modifiers
769       unsigned int nState = 0;
770       if (Sys_AltDown ())
771         nState |= RAD_ALT;
772       if ((event->state & GDK_CONTROL_MASK) != 0)
773         nState |= RAD_CONTROL;
774       if ((event->state & GDK_SHIFT_MASK) != 0)
775         nState |= RAD_SHIFT;
776       if ((g_Commands[i].m_nModifiers & 0x7) == nState)
777       {
778         HandleCommand (NULL, GINT_TO_POINTER (g_Commands[i].m_nCommand));
779         gtk_signal_emit_stop_by_name (GTK_OBJECT(widget), "key_press_event");
780         return FALSE;
781       }
782     }
783   }
784
785   return TRUE;
786 }
787
788 static gint mainframe_keyrelease (GtkWidget* widget, GdkEventKey* event, gpointer data)
789 {
790   unsigned int code = gdk_keyval_to_upper(event->keyval);
791   
792   if (gtk_accelerator_valid (event->keyval, (GdkModifierType)0))
793     return TRUE;
794   
795   for (int i = 0; i < g_nCommandCount; i++)
796   {
797     if (g_Commands[i].m_nKey == code)    // find a match?
798     {
799       if(!g_Commands[i].m_nModifiers)
800       {
801         // Gef: Only call the handler if it's a key that needs keyup events
802         switch (g_Commands[i].m_nCommand)
803         {
804           case ID_CAMERA_FORWARD:
805           case ID_CAMERA_BACK:
806           case ID_CAMERA_LEFT:
807           case ID_CAMERA_RIGHT:
808           case ID_CAMERA_STRAFELEFT:
809           case ID_CAMERA_STRAFERIGHT:
810           {
811             HandleKeyUp (NULL, GINT_TO_POINTER (g_Commands[i].m_nCommand));
812             gtk_signal_emit_stop_by_name (GTK_OBJECT(widget), "key_release_event");
813           }
814
815         }
816         return FALSE;
817       }
818     }
819   }
820
821   return TRUE;
822 }
823
824
825 // =============================================================================
826 // Window creation functions
827
828 void AddMenuItem (GtkWidget* item, unsigned int id)
829 {
830   for (int i = 0; i < g_nCommandCount; i++)
831     if (g_Commands[i].m_nCommand == id)
832     {
833       g_object_set_data (G_OBJECT (g_pParentWnd->m_pWidget), g_Commands[i].m_strMenu, item);
834       break;
835     }
836 }
837
838 void MainFrame::handle_help_command(int id)
839 {
840   OpenURL(mHelpURLs[id]->GetBuffer());
841 }
842
843 /*!
844 needed for hooking in Gtk+
845 */
846 void HandleHelpCommand (GtkWidget *widget, gpointer data)
847 {
848   int id = GPOINTER_TO_INT (data);
849   g_pParentWnd->handle_help_command(id);
850 }
851
852 void MainFrame::process_xlink (Str &FileName, char *menu_name, const char *base_url, GtkWidget *menu, GtkAccelGroup *accel)
853 {
854   xmlDocPtr pDoc;
855   pDoc = xmlParseFile(FileName.GetBuffer());
856   if (pDoc)
857   {
858     Sys_Printf("Processing .xlink file '%s'\n", FileName.GetBuffer());
859     // create sub menu
860     GtkWidget* menu_in_menu = create_menu_in_menu_with_mnemonic(menu, menu_name);
861     // start walking the nodes, find the 'links' one
862     xmlNodePtr pNode = pDoc->children;
863     while (pNode && strcmp((const char*)pNode->name, "links"))
864       pNode=pNode->next;
865     if (pNode)
866     {
867       pNode = pNode->children;
868       while(pNode)
869       {
870         if (!strcmp((const char*)pNode->name, "item"))
871         {
872           // process the URL
873           Str *url;
874           if (strstr((char *)xmlGetProp(pNode, (xmlChar *)"url"), "http://"))
875           {
876             // complete URL
877             url = new Str;
878             *url = (char *)xmlGetProp(pNode, (xmlChar *)"url");
879           }
880           else
881           {
882             // relative URL
883             url = new Str;
884             *url = base_url;
885             *url += (char *)xmlGetProp(pNode, (xmlChar *)"url");
886           }
887           mHelpURLs.push_back(url);
888           create_menu_item_with_mnemonic (menu_in_menu, (char *)xmlGetProp(pNode, (xmlChar *)"name"), GTK_SIGNAL_FUNC(HandleHelpCommand), mHelpURLs.size()-1);
889         }
890         pNode=pNode->next;
891       }
892     }
893     xmlFreeDoc(pDoc);
894   }
895   else
896   {
897     Sys_Printf("'%s' not found / parse failed\n", FileName.GetBuffer());
898   }
899 }
900
901 void MainFrame::create_game_help_menu (GtkWidget *menu, GtkAccelGroup *accel)
902 {
903   Str FileName;
904   list<CGameDescription *>::iterator iGame;
905
906   // start in the global dir
907   FileName = g_strAppPath;
908   FileName += "global.xlink";
909   process_xlink(FileName, "General", g_strAppPath.GetBuffer(), menu, accel);
910
911   for (iGame = g_PrefsDlg.mGamesDialog.mGames.begin(); iGame != g_PrefsDlg.mGamesDialog.mGames.end(); iGame++)
912   {
913     FileName = (*iGame)->mGameToolsPath;
914     FileName += "game.xlink";
915     process_xlink(FileName, (*iGame)->mGameName, (*iGame)->mGameToolsPath.GetBuffer(), menu, accel);
916   }
917 }
918
919 void MainFrame::create_main_menu (GtkWidget *window, GtkWidget *vbox)
920 {
921   GtkWidget *handle_box, *menu_bar, *menu, *menu_in_menu, *menu_3, *item;
922   GtkAccelGroup *accel;
923
924   g_bIgnoreCommands++;
925   accel = gtk_accel_group_new ();
926   global_accel = accel;
927   gtk_window_add_accel_group (GTK_WINDOW (window), accel);
928
929   handle_box = gtk_handle_box_new ();  
930   gtk_box_pack_start (GTK_BOX (vbox), handle_box, FALSE, FALSE, 0);
931   gtk_widget_show (handle_box);
932
933   menu_bar = gtk_menu_bar_new ();
934   gtk_container_add (GTK_CONTAINER (handle_box), menu_bar);
935   gtk_widget_show (menu_bar);
936
937   // File menu
938   menu = create_sub_menu_with_mnemonic (menu_bar, "_File");
939   if (g_PrefsDlg.m_bDetachableMenus)
940     menu_tearoff (menu);
941
942   create_menu_item_with_mnemonic (menu, "_New Map",
943                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_NEW);
944   menu_separator (menu);
945
946   //++timo temporary experimental stuff for sleep mode..
947   item = create_menu_item_with_mnemonic (menu, "_Sleep",
948                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_SLEEP);
949   g_object_set_data (G_OBJECT (window), "menu_file_sleep", item );
950   menu_separator (menu);
951   // end experimental
952
953   item = create_menu_item_with_mnemonic (menu, "_Open...",
954                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_OPEN);
955   g_object_set_data (G_OBJECT (window), "menu_file_open", item);
956   create_menu_item_with_mnemonic (menu, "_Import...", // Hydra: give it it's proper name
957                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_IMPORTMAP);
958   item = create_menu_item_with_mnemonic (menu, "_Save",
959                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_SAVE);
960   g_object_set_data (G_OBJECT (window), "menu_file_save", item);
961   create_menu_item_with_mnemonic (menu, "Save _as...",
962                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_SAVEAS);
963   create_menu_item_with_mnemonic (menu, "Save s_elected...",
964                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_EXPORTMAP);
965   menu_separator (menu);
966   item = create_menu_item_with_mnemonic (menu, "Save re_gion...",
967                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_SAVEREGION);
968   g_object_set_data (G_OBJECT (window), "menu_file_saveregion", item);
969   menu_separator (menu);
970   create_menu_item_with_mnemonic (menu, "New p_roject...",
971                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_NEWPROJECT);
972   create_menu_item_with_mnemonic (menu, "Load _project...",
973                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_LOADPROJECT);
974   create_menu_item_with_mnemonic (menu, "Pro_ject settings...",
975                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_PROJECTSETTINGS);
976   menu_separator (menu);
977   create_menu_item_with_mnemonic (menu, "_Pointfile...",
978                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_POINTFILE);
979   menu_separator (menu);
980   item = create_menu_item_with_mnemonic (menu, "Recent Files",
981                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_RECENT1);
982   g_object_set_data (G_OBJECT (item), "accel", accel);
983   gtk_widget_set_sensitive (item, FALSE);
984   MRU_AddWidget (item, 0);
985   item = create_menu_item_with_mnemonic (menu, "2",
986                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_RECENT2);
987   gtk_widget_hide (item);
988   MRU_AddWidget (item, 1);
989   item = create_menu_item_with_mnemonic (menu, "3",
990                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_RECENT3);
991   gtk_widget_hide (item);
992   MRU_AddWidget (item, 2);
993   item = create_menu_item_with_mnemonic (menu, "4",
994                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_RECENT4);
995   gtk_widget_hide (item);
996   MRU_AddWidget (item, 3);
997   menu_separator (menu);
998   item = create_menu_item_with_mnemonic (menu, "Check for GtkRadiant update (web)",
999     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_CHECKUPDATE);
1000   // disable, the functionality is no longer available
1001   gtk_widget_set_sensitive( item, FALSE );
1002   
1003   create_menu_item_with_mnemonic (menu, "E_xit",
1004                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_EXIT);
1005
1006   // Edit menu
1007   menu = create_sub_menu_with_mnemonic (menu_bar, "_Edit");
1008   if (g_PrefsDlg.m_bDetachableMenus)
1009     menu_tearoff (menu);
1010   item = create_menu_item_with_mnemonic (menu, "_Undo",
1011                            GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_UNDO);
1012   g_object_set_data (G_OBJECT (window), "menu_edit_undo", item);
1013   item = create_menu_item_with_mnemonic (menu, "_Redo",
1014                            GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_REDO);
1015   g_object_set_data (G_OBJECT (window), "menu_edit_redo", item);
1016   menu_separator (menu);
1017   item = create_menu_item_with_mnemonic (menu, "_Copy", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_COPYBRUSH);
1018   item = create_menu_item_with_mnemonic (menu, "_Paste", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_PASTEBRUSH);
1019   item = create_menu_item_with_mnemonic (menu, "P_aste To Camera", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_PASTEBRUSHTOCAMERA);
1020   item = create_menu_item_with_mnemonic (menu, "_Delete", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DELETE);
1021   g_object_set_data (G_OBJECT (window), "menu_selection_delete", item);
1022   menu_separator (menu);
1023   create_menu_item_with_mnemonic (menu, "Map Info...", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_MAPINFO);
1024   create_menu_item_with_mnemonic (menu, "Entity Info...", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_ENTITYINFO);
1025   menu_separator (menu);
1026   create_menu_item_with_mnemonic (menu, "Brush Scripts...", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_SCRIPTS);
1027   menu_separator (menu);
1028   create_menu_item_with_mnemonic (menu, "Load Pre_fab...", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_LOADPREFAB);
1029   create_menu_item_with_mnemonic (menu, "Save Selection as Prefab...", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_SAVEPREFAB);
1030   menu_separator (menu);
1031   create_menu_item_with_mnemonic (menu, "Preferences...", GTK_SIGNAL_FUNC (HandleCommand), ID_PREFS);
1032
1033   // View menu
1034   menu = create_sub_menu_with_mnemonic (menu_bar, "_View");
1035   if (g_PrefsDlg.m_bDetachableMenus)
1036     menu_tearoff (menu);
1037
1038   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Toggle");
1039   create_menu_item_with_mnemonic (menu_in_menu, "Camera View", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLECAMERA);
1040   create_menu_item_with_mnemonic (menu_in_menu, "Console View", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLECONSOLE);
1041   item = create_menu_item_with_mnemonic (menu_in_menu, "Entity View", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITY);
1042   g_object_set_data (G_OBJECT (window), "menu_view_entity", item);
1043   //  create_menu_item_with_mnemonic (menu_in_menu, "Groups View", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_GROUPS);
1044   create_menu_item_with_mnemonic (menu_in_menu, "XY (Top)", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLEVIEW);
1045   create_menu_item_with_mnemonic (menu_in_menu, "YZ (Side)", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLEVIEW_YZ);
1046   create_menu_item_with_mnemonic (menu_in_menu, "XZ (Front)", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLEVIEW_XZ);
1047   create_menu_item_with_mnemonic (menu_in_menu, "Z View", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLEZ);
1048   menu_separator (menu);
1049   item = create_menu_item_with_mnemonic (menu, "_Center", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CENTER);
1050   item = create_menu_item_with_mnemonic (menu, "_Center 2d", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CENTERVIEW);
1051   item = create_menu_item_with_mnemonic (menu, "_Up Floor", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_UPFLOOR);
1052   item = create_menu_item_with_mnemonic (menu, "_Down Floor", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_DOWNFLOOR);
1053   menu_separator (menu);
1054   item = create_menu_item_with_mnemonic (menu, "_Next (XY, YZ, XY)", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_NEXTVIEW);
1055   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Layout");
1056   create_menu_item_with_mnemonic (menu_in_menu, "XY (Top)", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_XY);
1057   create_menu_item_with_mnemonic (menu_in_menu, "YZ", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SIDE);
1058   create_menu_item_with_mnemonic (menu_in_menu, "XZ", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_FRONT);
1059   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Zoom");
1060   create_menu_item_with_mnemonic (menu_in_menu, "_XY 100%", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_100);
1061   item = create_menu_item_with_mnemonic (menu_in_menu, "XY Zoom _In", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ZOOMIN);
1062   item = create_menu_item_with_mnemonic (menu_in_menu, "XY Zoom _Out", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ZOOMOUT);
1063   menu_separator (menu_in_menu);
1064   create_menu_item_with_mnemonic (menu_in_menu, "_Z 100%", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_Z100);
1065   item = create_menu_item_with_mnemonic (menu_in_menu, "Z Zoo_m In", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ZZOOMIN);
1066   g_object_set_data (G_OBJECT (window), "menu_view_zzoomin", item);
1067   item = create_menu_item_with_mnemonic (menu_in_menu, "Z Zoom O_ut", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ZZOOMOUT);
1068   g_object_set_data (G_OBJECT (window), "menu_view_zzoomout", item);
1069   menu_separator (menu_in_menu);
1070   item = create_menu_item_with_mnemonic (menu_in_menu, "Cubic Clip Zoom In", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CUBEIN);
1071   item = create_menu_item_with_mnemonic (menu_in_menu, "Cubic Clip Zoom Out", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CUBEOUT);
1072   menu_separator (menu);
1073
1074   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Show");
1075   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show _Angles", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWANGLES, FALSE);
1076   g_object_set_data (G_OBJECT (window), "menu_view_showangles", item);
1077   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show _Names", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWNAMES, TRUE);
1078   g_object_set_data (G_OBJECT (window), "menu_view_shownames", item);
1079   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show Blocks", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWBLOCKS, FALSE);
1080   g_object_set_data (G_OBJECT (window), "menu_view_showblocks", item);
1081   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show C_oordinates", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWCOORDINATES, TRUE);
1082   g_object_set_data (G_OBJECT (window), "menu_view_showcoordinates", item);
1083   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show Window Outline", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWOUTLINE, TRUE);
1084   g_object_set_data (G_OBJECT (window), "menu_view_showoutline", item);
1085   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show ZBuffered Outline", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_NOOUTLINE, TRUE);
1086   g_object_set_data (G_OBJECT (window), "menu_selection_nooutline", item);
1087   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show Axes", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWAXES, TRUE);
1088   g_object_set_data (G_OBJECT (window), "menu_view_showaxes", item);
1089   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show Workzone", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWWORKZONE, FALSE);
1090   g_object_set_data (G_OBJECT (window), "menu_view_showworkzone", item);
1091
1092   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Filter");
1093   create_check_menu_item_with_mnemonic (menu_in_menu, "World", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_WORLD, FALSE);
1094   create_check_menu_item_with_mnemonic (menu_in_menu, "Entities", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_ENTITIES, FALSE);
1095   create_check_menu_item_with_mnemonic (menu_in_menu, "Areaportals", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_AREAPORTALS, FALSE);
1096   create_check_menu_item_with_mnemonic (menu_in_menu, "Translucent", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_TRANSLUCENT, FALSE);
1097   create_check_menu_item_with_mnemonic (menu_in_menu, "Liquids", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_LIQUIDS, FALSE);
1098   create_check_menu_item_with_mnemonic (menu_in_menu, "Caulk", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_CAULK, FALSE);
1099   create_check_menu_item_with_mnemonic (menu_in_menu, "Clips", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_CLIPS, FALSE);
1100   create_check_menu_item_with_mnemonic (menu_in_menu, "Paths", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_PATHS, FALSE);
1101   create_check_menu_item_with_mnemonic (menu_in_menu, "Clusterportals", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_CLUSTERPORTALS, FALSE);
1102   create_check_menu_item_with_mnemonic (menu_in_menu, "Lights", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_LIGHTS, FALSE);
1103   create_check_menu_item_with_mnemonic (menu_in_menu, "Structural", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_STRUCTURAL, FALSE);
1104   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Lightgrid", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_LIGHTGRID, FALSE);
1105   g_object_set_data (G_OBJECT (window), "menu_filter_lightgrid", item);
1106   create_check_menu_item_with_mnemonic (menu_in_menu, "Patches", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_PATCHES, FALSE);
1107   create_check_menu_item_with_mnemonic (menu_in_menu, "Details", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_DETAILS, FALSE);
1108   create_check_menu_item_with_mnemonic (menu_in_menu, "Hints", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_HINTSSKIPS, FALSE);
1109   create_check_menu_item_with_mnemonic (menu_in_menu, "Models", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_MODELS, FALSE);
1110   create_check_menu_item_with_mnemonic (menu_in_menu, "Triggers", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_TRIGGERS, FALSE);
1111   create_check_menu_item_with_mnemonic (menu_in_menu, "Botclips", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_BOTCLIPS, FALSE);
1112
1113   menu_separator (menu);
1114   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Hide/Show");
1115   create_menu_item_with_mnemonic (menu_in_menu, "Hide Selected",
1116                     GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_HIDESHOW_HIDESELECTED);
1117   create_menu_item_with_mnemonic (menu_in_menu, "Show Hidden",
1118                     GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_HIDESHOW_SHOWHIDDEN);
1119   menu_separator (menu);
1120   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Entities as");
1121   g_object_set_data (G_OBJECT (window), "view_entitiesas_menu", menu_in_menu);
1122   item = create_radio_menu_item_with_mnemonic (menu_in_menu, NULL, "Bounding box",
1123                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_BOUNDINGBOX,FALSE);
1124   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_boundingbox", item);
1125   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Wireframe",
1126                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_WIREFRAME,FALSE);
1127   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_wireframe", item);
1128   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Selected Wireframe",
1129                                  GTK_SIGNAL_FUNC (HandleCommand),ID_VIEW_ENTITIESAS_SELECTEDWIREFRAME,FALSE);
1130   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_selectedwireframe", item);
1131   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Selected Skinned",
1132                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_SELECTEDSKINNED,FALSE);
1133   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_selectedskinned", item);
1134   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Skinned",
1135                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_SKINNED,FALSE);
1136   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_skinned", item);
1137   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Skinned and Boxed",
1138                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_SKINNEDANDBOXED,FALSE);
1139   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_skinnedandboxed", item);
1140   menu_separator (menu);
1141   item = create_check_menu_item_with_mnemonic (menu, "Cubic Clipping",
1142                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CUBICCLIPPING, TRUE);
1143   g_object_set_data (G_OBJECT (window), "menu_view_cubicclipping", item);
1144   menu_separator (menu);
1145   item = create_check_menu_item_with_mnemonic (menu, "OpenGL Lighting",
1146                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_OPENGLLIGHTING, FALSE);
1147   g_object_set_data (G_OBJECT (window), "menu_view_opengllighting", item);
1148
1149   // Selection menu
1150   menu = create_sub_menu_with_mnemonic (menu_bar, "_Selection");
1151   if (g_PrefsDlg.m_bDetachableMenus)
1152     menu_tearoff (menu);
1153
1154   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Drag");
1155   create_menu_item_with_mnemonic (menu_in_menu, "Drag _Edges",
1156                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DRAGEDGES);
1157   create_menu_item_with_mnemonic (menu_in_menu, "Drag _Vertices",
1158                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DRAGVERTECIES);
1159   menu_separator (menu);
1160   create_menu_item_with_mnemonic (menu, "_Clone",
1161                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_CLONE);
1162   item = create_menu_item_with_mnemonic (menu, "Deselect",
1163                            GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DESELECT);
1164   item = create_menu_item_with_mnemonic (menu, "Invert",
1165                            GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_INVERT);
1166 #ifndef QUAKE3
1167   create_menu_item_with_mnemonic (menu, "_Delete",
1168                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DELETE);
1169 #endif
1170   menu_separator (menu);
1171   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Flip");
1172   create_menu_item_with_mnemonic (menu_in_menu, "Flip _X",
1173                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_FLIPX);
1174   create_menu_item_with_mnemonic (menu_in_menu, "Flip _Y",
1175                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_FLIPY);
1176   create_menu_item_with_mnemonic (menu_in_menu, "Flip _Z",
1177                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_FLIPZ);
1178   menu_separator (menu);
1179   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Rotate");
1180   create_menu_item_with_mnemonic (menu_in_menu, "Rotate X",
1181                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_ROTATEX);
1182   create_menu_item_with_mnemonic (menu_in_menu, "Rotate Y",
1183                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_ROTATEY);
1184   create_menu_item_with_mnemonic (menu_in_menu, "Rotate Z",
1185                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_ROTATEZ);
1186   create_menu_item_with_mnemonic (menu_in_menu, "Arbitrary rotation...",
1187                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_ARBITRARYROTATION);
1188   menu_separator (menu);
1189   create_menu_item_with_mnemonic (menu, "Scale...", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECT_SCALE);
1190   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "CSG");
1191   create_menu_item_with_mnemonic (menu_in_menu, "Make _Hollow",
1192                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MAKEHOLLOW);
1193   create_menu_item_with_mnemonic (menu_in_menu, "CSG _Subtract",
1194                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_CSGSUBTRACT);
1195   create_menu_item_with_mnemonic (menu_in_menu, "CSG _Merge",
1196                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_CSGMERGE);
1197   menu_separator (menu);
1198   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Select");
1199   create_menu_item_with_mnemonic (menu_in_menu, "Select Complete _Tall",
1200                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECTCOMPLETETALL);
1201   create_menu_item_with_mnemonic (menu_in_menu, "Select T_ouching",
1202                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECTTOUCHING);
1203   create_menu_item_with_mnemonic (menu_in_menu, "Select _Partial Tall",
1204                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECTPARTIALTALL);
1205   create_menu_item_with_mnemonic (menu_in_menu, "Select _Inside",
1206                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECTINSIDE);
1207 #ifndef QUAKE3
1208   create_menu_item_with_mnemonic (menu_in_menu, "Nudge Left",
1209                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGELEFT);
1210   create_menu_item_with_mnemonic (menu_in_menu, "Nudge Right",
1211                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGERIGHT);
1212   create_menu_item_with_mnemonic (menu_in_menu, "Nudge Up",
1213                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGEUP);
1214   create_menu_item_with_mnemonic (menu_in_menu, "Nudge Down",
1215                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGEDOWN);
1216 #endif
1217   menu_separator (menu);
1218   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Clipper");
1219   create_menu_item_with_mnemonic (menu_in_menu, "Toggle Clipper",
1220                     GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CLIPPER);
1221   menu_separator (menu_in_menu);
1222   create_menu_item_with_mnemonic (menu_in_menu, "Clip selection",
1223                     GTK_SIGNAL_FUNC (HandleCommand), ID_CLIP_SELECTED);
1224   create_menu_item_with_mnemonic (menu_in_menu, "Split selection",
1225                     GTK_SIGNAL_FUNC (HandleCommand), ID_SPLIT_SELECTED);
1226   create_menu_item_with_mnemonic (menu_in_menu, "Flip Clip orientation",
1227                     GTK_SIGNAL_FUNC (HandleCommand), ID_FLIP_CLIP);
1228   menu_separator (menu);
1229   create_menu_item_with_mnemonic (menu, "Connect entities",
1230                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_CONNECT);
1231   create_menu_item_with_mnemonic (menu, "Ungroup entity",
1232                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_UNGROUPENTITY);
1233   create_menu_item_with_mnemonic (menu, "Make detail",
1234                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MAKE_DETAIL);
1235   create_menu_item_with_mnemonic (menu, "Make structural",
1236                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MAKE_STRUCTURAL);
1237
1238   // BSP menu
1239   menu = create_sub_menu_with_mnemonic (menu_bar, "_Bsp");
1240
1241   menu_separator (menu);
1242   g_object_set_data (G_OBJECT (window), "menu_bsp", menu);
1243
1244   // Grid menu
1245   menu = create_sub_menu_with_mnemonic (menu_bar, "_Grid");
1246   if (g_PrefsDlg.m_bDetachableMenus)
1247     menu_tearoff (menu);
1248
1249   item = create_radio_menu_item_with_mnemonic (menu, NULL, "Grid0.25",
1250                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_025, FALSE);
1251   g_object_set_data (G_OBJECT (window), "menu_grid_025", item);
1252   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid0.5",
1253                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_05, FALSE);
1254   g_object_set_data (G_OBJECT (window), "menu_grid_05", item);
1255   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid1",
1256                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_1, FALSE);
1257   g_object_set_data (G_OBJECT (window), "menu_grid_1", item);
1258   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid2",
1259                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_2, FALSE);
1260   g_object_set_data (G_OBJECT (window), "menu_grid_2", item);
1261   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid4",
1262                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_4, FALSE);
1263   g_object_set_data (G_OBJECT (window), "menu_grid_4", item);
1264   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid8",
1265                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_8, TRUE);
1266   g_object_set_data (G_OBJECT (window), "menu_grid_8", item);
1267   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid16",
1268                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_16, FALSE);
1269   g_object_set_data (G_OBJECT (window), "menu_grid_16", item);
1270   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid32",
1271                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_32, FALSE);
1272   g_object_set_data (G_OBJECT (window), "menu_grid_32", item);
1273   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid64",
1274                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_64, FALSE);
1275   g_object_set_data (G_OBJECT (window), "menu_grid_64", item);
1276   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid128",
1277                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_128, FALSE);
1278   g_object_set_data (G_OBJECT (window), "menu_grid_128", item);
1279   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid256",
1280                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_256, FALSE);
1281   g_object_set_data (G_OBJECT (window), "menu_grid_256", item);
1282   menu_separator (menu);
1283   item = create_check_menu_item_with_mnemonic (menu, "Snap to grid",
1284                                  GTK_SIGNAL_FUNC (HandleCommand), ID_SNAPTOGRID, TRUE);
1285   g_object_set_data (G_OBJECT (window), "menu_snaptogrid", item);
1286
1287   // Textures menu
1288   menu = create_sub_menu_with_mnemonic (menu_bar, "_Textures");
1289   if (g_PrefsDlg.m_bDetachableMenus)
1290     menu_tearoff (menu);
1291
1292   item = create_check_menu_item_with_mnemonic (menu, "Show In _Use",
1293                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_SHOWINUSE, FALSE);
1294   g_object_set_data (G_OBJECT (window), "menu_textures_showinuse", item);
1295   item = create_check_menu_item_with_mnemonic (menu, "Show _All",
1296                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_SHOWALL, FALSE);
1297   g_object_set_data (G_OBJECT (window), "menu_textures_showall", item);
1298   menu_separator (menu);
1299   item = create_check_menu_item_with_mnemonic (menu, "Show shaders",
1300                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_SHADERS_SHOW, FALSE);
1301   g_object_set_data (G_OBJECT (window), "menu_textures_shaders_show", item);
1302   item = create_menu_item_with_mnemonic (menu, "Flush & Reload Shaders",
1303                            GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_RELOADSHADERS);
1304   g_object_set_data (G_OBJECT (window), "menu_textures_reloadshaders", item);
1305   item = create_menu_item_with_mnemonic (menu, "Load directory...",
1306                            GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_LOAD);
1307   g_object_set_data (G_OBJECT (window), "menu_textures_load", item);
1308   item = create_menu_item_with_mnemonic (menu, "Directory list...",
1309                            GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_LOADLIST);
1310   menu_separator (menu);
1311
1312   item = create_menu_item_with_mnemonic (menu, "_Surface Inspector",
1313                            GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_INSPECTOR);
1314   menu_separator (menu);
1315   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Render Quality");
1316   g_object_set_data (G_OBJECT (window), "render_quality_menu", menu_in_menu);
1317   item = create_radio_menu_item_with_mnemonic (menu_in_menu, NULL, "_Wireframe",
1318                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_WIREFRAME, FALSE);
1319   g_object_set_data (G_OBJECT (window), "menu_textures_wireframe", item);
1320   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "_Flat shade",
1321                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_FLATSHADE, FALSE);
1322   g_object_set_data (G_OBJECT (window), "menu_textures_flatshade", item);
1323   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "_Nearest",
1324                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_NEAREST, FALSE);
1325   g_object_set_data (G_OBJECT (window), "menu_view_nearest", item);
1326   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Nearest _Mipmap",
1327                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_NEARESTMIPMAP, FALSE);
1328   g_object_set_data (G_OBJECT (window), "menu_view_nearestmipmap", item);
1329   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "_Linear",
1330                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_LINEAR, FALSE);
1331   g_object_set_data (G_OBJECT (window), "menu_view_linear", item);
1332   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "_Bilinear",
1333                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_BILINEAR, FALSE);
1334   g_object_set_data (G_OBJECT (window), "menu_view_bilinear", item);
1335   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "B_ilinear Mipmap",
1336                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_BILINEARMIPMAP, FALSE);
1337   g_object_set_data (G_OBJECT (window), "menu_view_bilinearmipmap", item);
1338   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "T_rilinear",
1339                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_TRILINEAR, FALSE);
1340   g_object_set_data (G_OBJECT (window), "menu_view_trilinear", item);
1341   create_menu_item_with_mnemonic (menu, "Find / Replace...",
1342                     GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURE_REPLACEALL);
1343
1344   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Texture Lock");
1345   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Moves",
1346                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLE_LOCK, TRUE);
1347   g_object_set_data (G_OBJECT (window), "menu_toggle_lock", item);
1348   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Rotations",
1349                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLE_ROTATELOCK, TRUE);
1350   g_object_set_data (G_OBJECT (window), "menu_toggle_rotatelock", item);
1351   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Texture Window Scale");
1352   item = create_radio_menu_item_with_mnemonic (menu_in_menu, NULL, "200%",
1353                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_200, FALSE);
1354   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_200", item);
1355   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "100%",
1356                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_100, FALSE);
1357   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_100", item);
1358   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "50%",
1359                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_50, FALSE);
1360   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_50", item);
1361   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "25%",
1362                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_25, FALSE);
1363   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_25", item);
1364   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "10%",
1365                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_10, FALSE);
1366   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_10", item);
1367   item = menu_separator (menu);
1368   item = create_check_menu_item_with_mnemonic (menu, "shaderlist.txt only",
1369                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_SHADERLISTONLY, FALSE);
1370   g_object_set_data (G_OBJECT (window), "menu_textures_shaderlistonly", item);
1371   item = menu_separator (menu);
1372   g_object_set_data (G_OBJECT (window), "menu_textures_separator", item);
1373   g_object_set_data (G_OBJECT (window), "menu_textures", menu);
1374
1375   // Misc menu
1376   menu = create_sub_menu_with_mnemonic (menu_bar, "_Misc");
1377   if (g_PrefsDlg.m_bDetachableMenus)
1378     menu_tearoff (menu);
1379
1380   create_menu_item_with_mnemonic (menu, "_Benchmark", GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_BENCHMARK);
1381   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Colors");
1382   menu_3 = create_menu_in_menu_with_mnemonic (menu_in_menu, "Themes");
1383   create_menu_item_with_mnemonic (menu_3, "QE4 Original", GTK_SIGNAL_FUNC (HandleCommand), ID_COLOR_SETORIGINAL);
1384   create_menu_item_with_mnemonic (menu_3, "Q3Radiant Original", GTK_SIGNAL_FUNC (HandleCommand), ID_COLOR_SETQER);
1385   create_menu_item_with_mnemonic (menu_3, "Black and Green", GTK_SIGNAL_FUNC (HandleCommand), ID_COLOR_SETBLACK);
1386   create_menu_item_with_mnemonic (menu_3, "Maya/Max/Lightwave Emulation", GTK_SIGNAL_FUNC (HandleCommand), ID_COLOR_SETYDNAR);
1387
1388   menu_separator (menu_in_menu);
1389   create_menu_item_with_mnemonic (menu_in_menu, "_Texture Background...",
1390                     GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTUREBK);
1391   create_menu_item_with_mnemonic (menu_in_menu, "Grid Background...",
1392                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_XYBK);
1393   create_menu_item_with_mnemonic (menu_in_menu, "Grid Major...",
1394                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_MAJOR);
1395   create_menu_item_with_mnemonic (menu_in_menu, "Grid Minor...",
1396                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_MINOR);
1397   create_menu_item_with_mnemonic (menu_in_menu, "Grid Major Small...",
1398                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_MAJOR_ALT);
1399   create_menu_item_with_mnemonic (menu_in_menu, "Grid Minor Small...",
1400                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_MINOR_ALT);
1401   create_menu_item_with_mnemonic (menu_in_menu, "Grid Text...",
1402                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_GRIDTEXT);
1403   create_menu_item_with_mnemonic (menu_in_menu, "Grid Block...",
1404                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_GRIDBLOCK);
1405   create_menu_item_with_mnemonic (menu_in_menu, "Default Brush...",
1406                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_BRUSH);
1407   create_menu_item_with_mnemonic (menu_in_menu, "Camera Background...",
1408                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_CAMERABACK);    
1409   create_menu_item_with_mnemonic (menu_in_menu, "Selected Brush...",
1410                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_SELECTEDBRUSH);
1411   create_menu_item_with_mnemonic (menu_in_menu, "Selected Brush (Camera)...",
1412                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_SELECTEDBRUSH3D);
1413   create_menu_item_with_mnemonic (menu_in_menu, "Clipper...",
1414                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_CLIPPER);
1415   create_menu_item_with_mnemonic (menu_in_menu, "Active View name...",
1416                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_VIEWNAME);
1417
1418   create_menu_item_with_mnemonic (menu, "_Gamma...",
1419                     GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_GAMMA);
1420   create_menu_item_with_mnemonic (menu, "Find brush...",
1421                     GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_FINDBRUSH);
1422   item = create_menu_item_with_mnemonic (menu, "Next leak spot",
1423                            GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_NEXTLEAKSPOT);
1424   item = create_menu_item_with_mnemonic (menu, "Previous leak spot",
1425                            GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_PREVIOUSLEAKSPOT);
1426   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=394
1427 //  create_menu_item_with_mnemonic (menu, "_Print XY View", GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_PRINTXY);
1428   item = create_menu_item_with_mnemonic (menu, "_Select Entity Color...",
1429                            GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_SELECTENTITYCOLOR);
1430   g_object_set_data (G_OBJECT (window), "menu_misc_selectentitycolor", item);
1431
1432   // Region menu
1433   menu = create_sub_menu_with_mnemonic (menu_bar, "_Region");
1434   if (g_PrefsDlg.m_bDetachableMenus)
1435     menu_tearoff (menu);
1436
1437   create_menu_item_with_mnemonic (menu, "_Off",
1438                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_OFF);
1439   create_menu_item_with_mnemonic (menu, "_Set XY",
1440                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_SETXY);
1441   create_menu_item_with_mnemonic (menu, "Set _Tall Brush",
1442                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_SETTALLBRUSH);
1443   create_menu_item_with_mnemonic (menu, "Set _Brush",
1444                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_SETBRUSH);
1445   create_menu_item_with_mnemonic (menu, "Set Se_lected Brushes",
1446                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_SETSELECTION);
1447
1448   // Brush menu
1449   menu = create_sub_menu_with_mnemonic (menu_bar, "_Brush");
1450   if (g_PrefsDlg.m_bDetachableMenus)
1451     menu_tearoff (menu);
1452
1453   item = create_menu_item_with_mnemonic (menu, "3 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_3SIDED);
1454   item = create_menu_item_with_mnemonic (menu, "4 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_4SIDED);
1455   item = create_menu_item_with_mnemonic (menu, "5 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_5SIDED);
1456   item = create_menu_item_with_mnemonic (menu, "6 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_6SIDED);
1457   item = create_menu_item_with_mnemonic (menu, "7 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_7SIDED);
1458   item = create_menu_item_with_mnemonic (menu, "8 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_8SIDED);
1459   item = create_menu_item_with_mnemonic (menu, "9 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_9SIDED);
1460   menu_separator (menu);
1461   create_menu_item_with_mnemonic (menu, "Arbitrary sided...",
1462                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_ARBITRARYSIDED);
1463   menu_separator (menu);
1464   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Primitives");
1465   create_menu_item_with_mnemonic (menu_in_menu, "Cone...",
1466                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_MAKECONE);
1467   create_menu_item_with_mnemonic (menu_in_menu, "Sphere...",
1468                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_PRIMITIVES_SPHERE);
1469
1470   // Curve menu
1471   if (!g_pGameDescription->mNoPatch)
1472   {
1473   menu = create_sub_menu_with_mnemonic (menu_bar, "_Curve");
1474   if (g_PrefsDlg.m_bDetachableMenus)
1475     menu_tearoff (menu);
1476
1477   create_menu_item_with_mnemonic (menu, "Cylinder", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHTUBE);
1478   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "More Cylinders");
1479   create_menu_item_with_mnemonic (menu_in_menu, "Dense Cylinder",
1480                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHDENSETUBE);
1481   create_menu_item_with_mnemonic (menu_in_menu, "Very Dense Cylinder",
1482                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHVERYDENSETUBE);
1483   create_menu_item_with_mnemonic (menu_in_menu, "Square Cylinder",
1484                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHSQUARE);
1485   menu_separator (menu);
1486   create_menu_item_with_mnemonic (menu, "End cap", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHENDCAP);
1487   create_menu_item_with_mnemonic (menu, "Bevel", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHBEVEL);
1488   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "More End caps, Bevels");
1489   create_menu_item_with_mnemonic (menu_in_menu, "Square Endcap",
1490                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_MOREENDCAPSBEVELS_SQUAREBEVEL);
1491   create_menu_item_with_mnemonic (menu_in_menu, "Square Bevel",
1492                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_MOREENDCAPSBEVELS_SQUAREENDCAP);
1493   menu_separator (menu);
1494   create_menu_item_with_mnemonic (menu, "Cone", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHCONE);
1495   item = create_menu_item_with_mnemonic (menu, "Sphere",
1496                            GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PRIMITIVES_SPHERE);
1497   gtk_widget_set_sensitive (item, FALSE);
1498   menu_separator (menu);
1499   item = create_menu_item_with_mnemonic (menu, "Simple Patch Mesh...",
1500                            GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_SIMPLEPATCHMESH);
1501   g_object_set_data (G_OBJECT (window), "menu_simplepatchmesh", item);
1502   menu_separator (menu);
1503   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Insert");
1504   create_menu_item_with_mnemonic (menu_in_menu, "Insert (2) Columns",
1505                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERT_INSERTCOLUMN);
1506   create_menu_item_with_mnemonic (menu_in_menu, "Add (2) Columns",
1507                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERT_ADDCOLUMN);
1508   menu_separator (menu_in_menu);
1509   create_menu_item_with_mnemonic (menu_in_menu, "Insert (2) Rows",
1510                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERT_INSERTROW);
1511   create_menu_item_with_mnemonic (menu_in_menu, "Add (2) Rows",
1512                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERT_ADDROW);
1513   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Delete");
1514   create_menu_item_with_mnemonic (menu_in_menu, "First (2) Columns",
1515                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETE_FIRSTCOLUMN);
1516   create_menu_item_with_mnemonic (menu_in_menu, "Last (2) Columns",
1517                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETE_LASTCOLUMN);
1518   menu_separator (menu_in_menu);
1519   create_menu_item_with_mnemonic (menu_in_menu, "First (2) Rows",
1520                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETE_FIRSTROW);
1521   create_menu_item_with_mnemonic (menu_in_menu, "Last (2) Rows",
1522                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETE_LASTROW);
1523   menu_separator (menu);
1524   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Matrix");
1525   create_menu_item_with_mnemonic (menu_in_menu, "Invert",
1526                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_NEGATIVE);
1527   menu_3 = create_menu_in_menu_with_mnemonic (menu_in_menu, "Re-disperse");
1528   create_menu_item_with_mnemonic (menu_3, "Rows", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_REDISPERSE_ROWS);
1529   create_menu_item_with_mnemonic (menu_3, "Cols (Intermediate)", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_REDISPERSE_INTERMEDIATE_COLS);
1530   create_menu_item_with_mnemonic (menu_3, "Rows (Intermediate)", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_REDISPERSE_INTERMEDIATE_ROWS);
1531   create_menu_item_with_mnemonic (menu_in_menu, "Transpose",
1532                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_MATRIX_TRANSPOSE);
1533   menu_separator (menu);
1534   create_menu_item_with_mnemonic (menu, "Cap Selection",
1535                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_CAP);
1536   create_menu_item_with_mnemonic (menu, "Cycle Cap Texture",
1537                         GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_CYCLECAP);
1538   menu_separator (menu);
1539   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Overlay");
1540   create_menu_item_with_mnemonic (menu_in_menu, "Set",
1541                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_OVERLAY_SET);
1542   create_menu_item_with_mnemonic (menu_in_menu, "Clear",
1543                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_OVERLAY_CLEAR);
1544   menu_separator (menu);
1545   create_menu_item_with_mnemonic (menu, "Thicken...", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_THICKEN);
1546   }
1547   // Plugins menu
1548   menu = create_sub_menu_with_mnemonic (menu_bar, "_Plugins");
1549   if (g_PrefsDlg.m_bDetachableMenus)
1550     menu_tearoff (menu);
1551
1552   /*
1553   create_menu_item_with_mnemonic (menu, "Refresh", GTK_SIGNAL_FUNC (HandleCommand), ID_PLUGINS_REFRESH);
1554   */
1555   // NOTE: the seperator is used when doing a refresh of the list, everything past the seperator is removed
1556   item = menu_separator (menu);
1557   g_object_set_data (G_OBJECT (window), "menu_plugin_separator", item);
1558   g_object_set_data (G_OBJECT (window), "menu_plugin", menu);
1559
1560   // Help menu
1561   menu = create_sub_menu_with_mnemonic (menu_bar, "_Help");
1562   if (g_PrefsDlg.m_bDetachableMenus)
1563     menu_tearoff (menu);
1564
1565   item = create_menu_item_with_mnemonic (menu, "Manual",
1566                            GTK_SIGNAL_FUNC (HandleCommand), ID_HELP);
1567   gtk_widget_add_accelerator (item, "activate", accel, GDK_F1, (GdkModifierType)0, GTK_ACCEL_VISIBLE);
1568
1569   // this creates all the per-game drop downs for the game pack helps
1570   // it will take care of hooking the Sys_OpenURL calls etc.
1571   create_game_help_menu(menu, accel);
1572
1573   // TTimo: this is in global.xlink now
1574   //create_menu_item_with_mnemonic (menu, "Links",
1575   //                  GTK_SIGNAL_FUNC (HandleCommand), ID_HELP_LINKS);
1576   create_menu_item_with_mnemonic (menu, "Bug report",
1577                     GTK_SIGNAL_FUNC (HandleCommand), ID_HELP_BUGREPORT);
1578   create_menu_item_with_mnemonic (menu, "Shortcuts list",
1579                     GTK_SIGNAL_FUNC (HandleCommand), ID_HELP_COMMANDLIST);
1580   create_menu_item_with_mnemonic (menu, "_About",
1581                     GTK_SIGNAL_FUNC (HandleCommand), ID_HELP_ABOUT);
1582
1583
1584   // leo: Hidden menu to make the accelerators work,
1585   // this is a hack that needs to be changed later if someone has a better idea.
1586   // NOTE TTimo
1587   // maybe the better idea would be NOT to use any such accelerator scheme and do all key listening and interpret ourselves
1588   menu = create_sub_menu_with_mnemonic (menu_bar, "Hidden");
1589   if (g_PrefsDlg.m_bDetachableMenus)
1590     menu_tearoff (menu);
1591
1592   gtk_widget_hide (gtk_menu_get_attach_widget (GTK_MENU (menu)));
1593
1594   create_menu_item_with_mnemonic (menu, "BendMode", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_BEND);
1595   create_menu_item_with_mnemonic (menu, "FitTexture", GTK_SIGNAL_FUNC (HandleCommand), IDC_BTN_FACEFIT);
1596   create_menu_item_with_mnemonic (menu, "ViewTextures", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_TEXTURE);
1597   create_menu_item_with_mnemonic (menu, "PatchInspector", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_INSPECTOR);
1598   create_menu_item_with_mnemonic (menu, "InvertCurveTextureX", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_NEGATIVETEXTUREY);
1599   create_menu_item_with_mnemonic (menu, "InvertCurveTextureY", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_NEGATIVETEXTUREX);
1600   create_menu_item_with_mnemonic (menu, "IncPatchColumn", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERTCOLUMN);
1601   create_menu_item_with_mnemonic (menu, "IncPatchRow", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERTROW);
1602   create_menu_item_with_mnemonic (menu, "DecPatchColumn", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETECOLUMN);
1603   create_menu_item_with_mnemonic (menu, "DecPatchRow", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETEROW);
1604   create_menu_item_with_mnemonic (menu, "Patch TAB", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_TAB);
1605   create_menu_item_with_mnemonic (menu, "Patch TAB", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_TAB);
1606   create_menu_item_with_mnemonic (menu, "SelectNudgeDown", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGEDOWN);
1607   create_menu_item_with_mnemonic (menu, "CameraForward", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_FORWARD);
1608   create_menu_item_with_mnemonic (menu, "CameraBack", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_BACK);
1609   create_menu_item_with_mnemonic (menu, "CameraLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_LEFT);
1610   create_menu_item_with_mnemonic (menu, "CameraRight", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_RIGHT);
1611   create_menu_item_with_mnemonic (menu, "CameraUp", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_UP);
1612   create_menu_item_with_mnemonic (menu, "CameraDown", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_DOWN);
1613   create_menu_item_with_mnemonic (menu, "CameraAngleUp", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_ANGLEUP);
1614   create_menu_item_with_mnemonic (menu, "CameraAngleDown", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_ANGLEDOWN);
1615   create_menu_item_with_mnemonic (menu, "CameraStrafeRight", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_STRAFERIGHT);
1616   create_menu_item_with_mnemonic (menu, "CameraStrafeLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_STRAFELEFT);
1617   create_menu_item_with_mnemonic (menu, "ToggleGrid", GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_TOGGLE);
1618   create_menu_item_with_mnemonic (menu, "ToggleCrosshairs", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CROSSHAIR);
1619   create_menu_item_with_mnemonic (menu, "ToggleRealtime", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CAMERAUPDATE);
1620   create_menu_item_with_mnemonic (menu, "MouseRotate", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECT_MOUSEROTATE);
1621   create_menu_item_with_mnemonic (menu, "TexRotateClock", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_ROTATECLOCK);
1622   create_menu_item_with_mnemonic (menu, "TexRotateCounter", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_ROTATECOUNTER);
1623   create_menu_item_with_mnemonic (menu, "TexScaleUp", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SCALEUP);
1624   create_menu_item_with_mnemonic (menu, "TexScaleDown", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SCALEDOWN);
1625   create_menu_item_with_mnemonic (menu, "TexShiftLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SHIFTLEFT);
1626   create_menu_item_with_mnemonic (menu, "TexShiftRight", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SHIFTRIGHT);
1627   create_menu_item_with_mnemonic (menu, "TexShiftUp", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SHIFTUP);
1628   create_menu_item_with_mnemonic (menu, "TexShiftDown", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SHIFTDOWN);
1629   create_menu_item_with_mnemonic (menu, "GridDown", GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_PREV);
1630   create_menu_item_with_mnemonic (menu, "GridUp", GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_NEXT);
1631   create_menu_item_with_mnemonic (menu, "TexScaleLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SCALELEFT);
1632   create_menu_item_with_mnemonic (menu, "TexScaleRight", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SCALERIGHT);
1633   create_menu_item_with_mnemonic (menu, "MoveSelectionDOWN", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MOVEDOWN);
1634   create_menu_item_with_mnemonic (menu, "MoveSelectionUP", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MOVEUP);
1635   create_menu_item_with_mnemonic (menu, "DumpSelectedBrush", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_PRINT);
1636   create_menu_item_with_mnemonic (menu, "ToggleSizePaint", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TOGGLESIZEPAINT);
1637   create_menu_item_with_mnemonic (menu, "SelectNudgeLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGELEFT);
1638   create_menu_item_with_mnemonic (menu, "SelectNudgeRight", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGERIGHT);
1639   create_menu_item_with_mnemonic (menu, "SelectNudgeUp", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGEUP);
1640   create_menu_item_with_mnemonic (menu, "NaturalizePatch", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_NATURALIZE);
1641   create_menu_item_with_mnemonic (menu, "SnapPatchToGrid", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECT_SNAPTOGRID);
1642   create_menu_item_with_mnemonic (menu, "SelectAllOfType", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECT_ALL);
1643   create_menu_item_with_mnemonic (menu, "CycleOutlineStyle", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_OUTLINESTYLE);
1644   create_menu_item_with_mnemonic (menu, "TextureWindowScaleup", GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTUREWINDOW_SCALEUP);
1645   create_menu_item_with_mnemonic (menu, "TextureWindowScaledown", GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTUREWINDOW_SCALEDOWN);
1646
1647   g_bIgnoreCommands--;
1648 }
1649
1650 void MainFrame::create_main_toolbar (GtkWidget *window, GtkWidget *vbox)
1651 {
1652   GtkWidget *handle_box, *toolbar, *w;
1653
1654   handle_box = gtk_handle_box_new ();
1655   gtk_box_pack_start (GTK_BOX (vbox), handle_box, FALSE, FALSE, 0);
1656   gtk_widget_show (handle_box);
1657   g_object_set_data (G_OBJECT (window), "tb_handle_box", handle_box);
1658
1659   toolbar = gtk_toolbar_new ();
1660   gtk_toolbar_set_orientation (GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1661   gtk_toolbar_set_style (GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
1662   //  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), user_rc.toolbar_style);
1663   gtk_container_add (GTK_CONTAINER (handle_box), toolbar);
1664
1665   gtk_widget_show (toolbar);
1666
1667   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "Open", "Open an existing map", "",
1668                                new_pixmap (window, "file_open.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1669                                GINT_TO_POINTER (ID_FILE_OPEN));
1670   g_object_set_data (G_OBJECT (window), "tb_file_open", w);
1671   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "Save", "Save the active map", "",
1672                                new_pixmap (window, "file_save.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1673                                GINT_TO_POINTER (ID_FILE_SAVE));
1674   g_object_set_data (G_OBJECT (window), "tb_file_save", w);
1675   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1676   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "x-axis Flip", "",
1677                                new_pixmap (window, "brush_flipx.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1678                                GINT_TO_POINTER (ID_BRUSH_FLIPX));
1679   g_object_set_data (G_OBJECT (window), "tb_brush_flipx", w);
1680   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "x-axis Rotate", "",
1681                                new_pixmap (window, "brush_rotatex.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1682                                GINT_TO_POINTER (ID_BRUSH_ROTATEX));
1683   g_object_set_data (G_OBJECT (window), "tb_brush_rotatex", w);
1684   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "y-axis Flip", "",
1685                                new_pixmap (window, "brush_flipy.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1686                                GINT_TO_POINTER (ID_BRUSH_FLIPY));
1687   g_object_set_data (G_OBJECT (window), "tb_brush_flipy", w);
1688   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "y-axis Rotate", "",
1689                                new_pixmap (window, "brush_rotatey.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1690                                GINT_TO_POINTER (ID_BRUSH_ROTATEY));
1691   g_object_set_data (G_OBJECT (window), "tb_brush_rotatey", w);
1692   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "z-axis Flip", "",
1693                                new_pixmap (window, "brush_flipz.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1694                                GINT_TO_POINTER (ID_BRUSH_FLIPZ));
1695   g_object_set_data (G_OBJECT (window), "tb_brush_flipz", w);
1696   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "z-axis Rotate", "",
1697                                new_pixmap (window, "brush_rotatez.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1698                                GINT_TO_POINTER (ID_BRUSH_ROTATEZ));
1699   g_object_set_data (G_OBJECT (window), "tb_brush_rotatez", w);
1700   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1701
1702   if (g_PrefsDlg.m_bWideToolbar)
1703   {
1704     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Complete Tall", "",
1705                                  new_pixmap (window, "selection_selectcompletetall.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1706                                  GINT_TO_POINTER (ID_SELECTION_SELECTCOMPLETETALL));
1707     g_object_set_data (G_OBJECT (window), "tb_selection_selectcompletetall", w);
1708     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Select Touching", "",
1709                                  new_pixmap (window, "selection_selecttouching.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1710                                  GINT_TO_POINTER (ID_SELECTION_SELECTTOUCHING));
1711     g_object_set_data (G_OBJECT (window), "tb_selection_selecttouching", w);
1712     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Select Partial Tall", "",
1713                                  new_pixmap (window, "selection_selectpartialtall.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1714                                  GINT_TO_POINTER (ID_SELECTION_SELECTPARTIALTALL));
1715     g_object_set_data (G_OBJECT (window), "tb_selection_selectpartialtall", w);
1716     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Select Inside", "",
1717                                  new_pixmap (window, "selection_selectinside.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1718                                  GINT_TO_POINTER (ID_SELECTION_SELECTINSIDE));
1719     g_object_set_data (G_OBJECT (window), "tb_selection_selectinside", w);
1720   } else
1721   {
1722     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Selection", "",
1723                                  new_pixmap (window, "popup_selection.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1724                                  GINT_TO_POINTER (ID_POPUP_SELECTION));
1725     g_object_set_data (G_OBJECT (window), "tb_popup_selection", w);
1726   }
1727   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1728
1729   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "CSG Subtract", "",
1730                                new_pixmap (window, "selection_csgsubtract.bmp"),
1731                                GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECTION_CSGSUBTRACT));
1732   g_object_set_data (G_OBJECT (window), "tb_selection_csgsubtract", w);
1733
1734   if (g_PrefsDlg.m_bWideToolbar)
1735   {
1736     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "CSG Merge", "",
1737                                  new_pixmap (window, "selection_csgmerge.bmp"),
1738                                  GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECTION_CSGMERGE));
1739     g_object_set_data (G_OBJECT (window), "tb_selection_csgmerge", w);
1740   }
1741
1742   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Hollow", "",
1743                                new_pixmap (window, "selection_makehollow.bmp"),
1744                                GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECTION_MAKEHOLLOW));
1745   g_object_set_data (G_OBJECT (window), "tb_selection_makehollow", w);
1746
1747   if (g_PrefsDlg.m_bWideToolbar)
1748   {
1749     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1750                                     "", "Clipper", "", new_pixmap (window, "view_clipper.bmp"),
1751                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CLIPPER));
1752     g_object_set_data (G_OBJECT (window), "tb_view_clipper", w);
1753   }
1754
1755   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1756
1757   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Change views", "",
1758                                new_pixmap (window, "view_change.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1759                                GINT_TO_POINTER (ID_VIEW_CHANGE));
1760   g_object_set_data (G_OBJECT (window), "tb_view_change", w);
1761
1762   if (!g_PrefsDlg.m_bWideToolbar)
1763   {
1764     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1765   }
1766
1767   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Texture view mode", "",
1768                                new_pixmap (window, "textures_popup.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1769                                GINT_TO_POINTER (ID_TEXTURES_POPUP));
1770   g_object_set_data (G_OBJECT (window), "tb_textures_popup", w);
1771
1772   if (g_PrefsDlg.m_bWideToolbar)
1773   {
1774     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1775                                     "", "Cubic clip the camera view", "",
1776                                     new_pixmap (window, "view_cubicclipping.bmp"),
1777                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CUBICCLIPPING));
1778     g_object_set_data (G_OBJECT (window), "tb_view_cubicclipping", w);
1779   }
1780
1781   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1782
1783   if (!g_PrefsDlg.m_bWideToolbar)
1784   {
1785     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1786                                 "", "Camera preview", "", new_pixmap (window, "view_cameratoggle.bmp"),
1787                                 GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CAMERATOGGLE));
1788     g_object_set_data (G_OBJECT (window), "tb_view_cameratoggle", w);
1789     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Update Camera", "",
1790                              new_pixmap (window, "view_cameraupdate.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1791                              GINT_TO_POINTER (ID_VIEW_CAMERAUPDATE));
1792     g_object_set_data (G_OBJECT (window), "tb_view_cameraupdate", w);
1793     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1794                                 "", "Cubic clip the camera view", "",
1795                                 new_pixmap (window, "view_cubicclipping.bmp"),
1796                                 GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CUBICCLIPPING));
1797     g_object_set_data (G_OBJECT (window), "tb_view_cubicclipping", w);
1798     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1799     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1800                                     "", "Entity inspector", "", new_pixmap (window, "view_entity.bmp"),
1801                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_ENTITY));
1802     g_object_set_data (G_OBJECT (window), "tb_view_entity", w);
1803     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1804     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1805                                     "", "Clipper", "", new_pixmap (window, "view_clipper.bmp"),
1806                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CLIPPER));
1807     g_object_set_data (G_OBJECT (window), "tb_view_clipper", w);
1808     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1809   }
1810
1811   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1812                               "", "Free Rotation", "", new_pixmap (window, "select_mouserotate.bmp"),
1813                               GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECT_MOUSEROTATE));
1814   g_object_set_data (G_OBJECT (window), "tb_select_mouserotate", w);
1815   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1816   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1817                               "", "Free Scaling", "", new_pixmap (window, "select_mousescale.bmp"),
1818                               GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECT_MOUSESCALE));
1819   g_object_set_data (G_OBJECT (window), "tb_select_mousescale", w);
1820   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1821                                   "", "Scale X", "", new_pixmap (window, "scalelockx.bmp"),
1822                                   GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SCALELOCKX));
1823   g_object_set_data (G_OBJECT (window), "tb_scalelockx", w);
1824   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1825                                   "", "Scale Y", "", new_pixmap (window, "scalelocky.bmp"),
1826                                   GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SCALELOCKY));
1827   g_object_set_data (G_OBJECT (window), "tb_scalelocky", w);
1828   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1829                                   "", "Scale Z", "", new_pixmap (window, "scalelockz.bmp"),
1830                                   GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SCALELOCKZ));
1831   g_object_set_data (G_OBJECT (window), "tb_scalelockz", w);
1832
1833   if (g_PrefsDlg.m_bWideToolbar)
1834   {
1835     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1836     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1837                              "", "Don't select model brushes", "",
1838                              new_pixmap (window, "dontselectmodel.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1839                              GINT_TO_POINTER (ID_DONTSELECTMODEL));
1840     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1841     g_object_set_data (G_OBJECT (window), "tb_dontselectmodel", w);
1842
1843     if (!g_pGameDescription->mNoPatch)
1844     {
1845       w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1846                              "", "Don't select curved brushes", "",
1847                              new_pixmap (window, "dontselectcurve.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1848                              GINT_TO_POINTER (ID_DONTSELECTCURVE));
1849       g_object_set_data (G_OBJECT (window), "tb_dontselectcurve", w);
1850     }
1851   }
1852
1853   // bug #292, patch toolbar option
1854   if (g_PrefsDlg.m_bPatchToolbar)
1855   {
1856     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1857                              "", "Show patch bounding box", "",
1858                              new_pixmap (window, "patch_showboundingbox.bmp"),
1859                              GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_PATCH_SHOWBOUNDINGBOX));
1860     g_object_set_data (G_OBJECT (window), "tb_patch_showboundingbox", w);
1861     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1862                                     "", "Show patches as wireframes", "",
1863                                     new_pixmap (window, "patch_wireframe.bmp"),
1864                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_PATCH_WIREFRAME));
1865     g_object_set_data (G_OBJECT (window), "tb_patch_wireframe", w);
1866     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1867                              "", "Patch Bend mode", "",
1868                              new_pixmap (window, "patch_bend.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1869                              GINT_TO_POINTER (ID_PATCH_BEND));
1870     g_object_set_data (G_OBJECT (window), "tb_patch_bend", w);
1871     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Put caps on the current patch", "",
1872                              new_pixmap (window, "curve_cap.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1873                              GINT_TO_POINTER (ID_CURVE_CAP));
1874     g_object_set_data (G_OBJECT (window), "tb_curve_cap", w);
1875     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1876                                  "", "Welds equal patch points during moves", "",
1877                                  new_pixmap (window, "patch_weld.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1878                                  GINT_TO_POINTER (ID_PATCH_WELD));
1879     g_object_set_data (G_OBJECT (window), "tb_patch_weld", w);
1880     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1881                              "", "Selects drill down rows and columns", "",
1882                              new_pixmap (window, "patch_drilldown.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1883                              GINT_TO_POINTER (ID_PATCH_DRILLDOWN));
1884     g_object_set_data (G_OBJECT (window), "tb_patch_drilldown", w);
1885   }
1886
1887   if (g_PrefsDlg.m_bWideToolbar)
1888   {
1889     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1890     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Show Entities as", "",
1891                              new_pixmap (window, "show_entities.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1892                              GINT_TO_POINTER (ID_SHOW_ENTITIES));
1893     g_object_set_data (G_OBJECT (window), "tb_show_entities", w);
1894   }
1895
1896   /*
1897   uh? that is OLD
1898 #ifndef QUAKE3
1899   w = g_object_get_data (G_OBJECT (window), "tb_dontselectcurve");
1900   gtk_widget_hide (w);
1901   w = g_object_get_data (G_OBJECT (window), "tb_patch_showboundingbox");
1902   gtk_widget_hide (w);
1903   w = g_object_get_data (G_OBJECT (window), "tb_patch_weld");
1904   gtk_widget_hide (w);
1905   w = g_object_get_data (G_OBJECT (window), "tb_patch_wireframe");
1906   gtk_widget_hide (w);
1907 #endif
1908   */
1909
1910   m_bCamPreview = true;
1911   g_nScaleHow = (SCALE_X | SCALE_Y | SCALE_Z);
1912 }
1913
1914 void MainFrame::create_plugin_toolbar (GtkWidget *window, GtkWidget *vbox)
1915 {
1916   GtkWidget *handle_box, *toolbar;
1917
1918   handle_box = gtk_handle_box_new ();
1919   gtk_box_pack_start (GTK_BOX (vbox), handle_box, FALSE, FALSE, 0);
1920   if (g_PrefsDlg.m_bPluginToolbar)
1921     gtk_widget_show (handle_box);
1922   g_object_set_data (G_OBJECT (window), "tb_handle_box", handle_box);
1923
1924   toolbar = gtk_toolbar_new();
1925   gtk_toolbar_set_orientation (GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1926   gtk_toolbar_set_style (GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
1927   //  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), user_rc.toolbar_style);
1928   gtk_container_add (GTK_CONTAINER (handle_box), toolbar);
1929   g_object_set_data (G_OBJECT (window), "toolbar_plugin", toolbar);
1930   gtk_widget_show (toolbar);
1931 }
1932
1933 void MainFrame::create_main_statusbar (GtkWidget *window, GtkWidget *vbox)
1934 {
1935   GtkWidget *hbox, *hbox1;
1936   GtkWidget *frame;
1937   GtkWidget *label;
1938
1939   hbox = gtk_hbox_new (FALSE, 0);
1940   gtk_widget_show (hbox);
1941   gtk_widget_set_usize (hbox, -1, 24);
1942   gtk_container_border_width (GTK_CONTAINER (hbox), 1);
1943   gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, TRUE, 2);
1944
1945   frame = gtk_frame_new ((char*)NULL);
1946   gtk_widget_show (frame);
1947   gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1948   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1949
1950   hbox1 = gtk_hbox_new (FALSE, 0);
1951   gtk_container_add (GTK_CONTAINER (frame), hbox1);
1952   gtk_container_border_width (GTK_CONTAINER (hbox1), 0);
1953   gtk_widget_show (hbox1);
1954
1955   label = gtk_label_new (" Label ");
1956   gtk_widget_show (label);
1957   gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, TRUE, 0);
1958   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1959   gtk_misc_set_padding (GTK_MISC (label), 3, 0);
1960   m_pStatusLabel[0] = label;
1961
1962   for (int i = 1; i < 6; i++)
1963   {
1964     frame = gtk_frame_new ((char*)NULL);
1965     gtk_widget_show (frame);
1966     gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
1967     gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1968
1969     label = gtk_label_new (" Label ");
1970     gtk_widget_show (label);
1971     gtk_container_add (GTK_CONTAINER (frame), label);
1972     m_pStatusLabel[i] = label;
1973   }
1974 }
1975
1976 guint s_idle_id;
1977 static gint mainframe_idle (gpointer user_data)
1978 {
1979   g_pParentWnd->RoutineProcessing ();
1980   return TRUE;
1981 }
1982
1983 static void Sys_Iconify (GtkWidget *w);
1984 static void Sys_Restore (GtkWidget *w);
1985
1986 inline void CHECK_RESTORE(GtkWidget* w)
1987 {
1988   if (g_object_get_data (G_OBJECT (w), "was_mapped") != NULL)
1989     gtk_widget_show (w);
1990 }
1991
1992
1993 // this is called when the window is restored from the iconified state
1994 static void mainframe_map (GtkWidget *widget)
1995 {
1996   if (g_pParentWnd->IsSleeping ())
1997     g_pParentWnd->OnSleep ();
1998
1999   if ((g_pParentWnd->CurrentStyle() == MainFrame::eFloating) && (widget == g_pParentWnd->m_pWidget))
2000   {
2001     // restore previously visible windows
2002     CHECK_RESTORE (g_pParentWnd->GetCamWnd ()->m_pParent);
2003     if (g_PrefsDlg.m_bFloatingZ)
2004       CHECK_RESTORE (g_pParentWnd->GetZWnd ()->m_pParent);
2005     CHECK_RESTORE (g_pParentWnd->GetXYWnd ()->m_pParent);
2006     CHECK_RESTORE (g_pParentWnd->GetXZWnd ()->m_pParent);
2007     CHECK_RESTORE (g_pParentWnd->GetYZWnd ()->m_pParent);
2008     CHECK_RESTORE (g_pGroupDlg->m_pWidget);
2009   }
2010 }
2011
2012 inline void CHECK_MINIMIZE(GtkWidget* w)
2013 {
2014   g_object_set_data (G_OBJECT (w), "was_mapped", (void*)(GTK_WIDGET_VISIBLE (w) != 0));
2015   gtk_widget_hide (w);
2016 }
2017
2018 static void mainframe_unmap (GtkWidget *widget)
2019 {
2020
2021   if ((g_pParentWnd->CurrentStyle() == MainFrame::eFloating) && (widget == g_pParentWnd->m_pWidget))
2022   {
2023     // minimize all other windows when the main window is minimized
2024     CHECK_MINIMIZE (g_pParentWnd->GetCamWnd ()->m_pParent);
2025     if (g_PrefsDlg.m_bFloatingZ)
2026       CHECK_MINIMIZE (g_pParentWnd->GetZWnd ()->m_pParent);
2027     CHECK_MINIMIZE (g_pParentWnd->GetXYWnd ()->m_pParent);
2028     CHECK_MINIMIZE (g_pParentWnd->GetXZWnd ()->m_pParent);
2029     CHECK_MINIMIZE (g_pParentWnd->GetYZWnd ()->m_pParent);
2030     CHECK_MINIMIZE (g_pGroupDlg->m_pWidget);
2031   }
2032 }
2033
2034 static GtkWidget* create_floating (MainFrame* mainframe)
2035 {
2036   GtkWidget *wnd = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2037   //if (mainframe->CurrentStyle() != MainFrame::eFloating)
2038     gtk_window_set_transient_for (GTK_WINDOW (wnd), GTK_WINDOW (mainframe->m_pWidget));
2039   gtk_widget_set_events (wnd, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
2040   gtk_signal_connect (GTK_OBJECT (wnd), "delete_event", GTK_SIGNAL_FUNC (widget_delete_hide), NULL);
2041   gtk_signal_connect (GTK_OBJECT (wnd), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2042   gtk_signal_connect (GTK_OBJECT (wnd), "key_press_event",
2043                       GTK_SIGNAL_FUNC (mainframe_keypress), mainframe);
2044   gtk_signal_connect (GTK_OBJECT (wnd), "key_release_event",
2045                       GTK_SIGNAL_FUNC (mainframe_keyrelease), mainframe);
2046   gtk_signal_connect (GTK_OBJECT (wnd), "map_event",
2047                       GTK_SIGNAL_FUNC (mainframe_map), mainframe);
2048
2049   gtk_window_set_default_size (GTK_WINDOW (wnd), 100, 100);
2050
2051 #ifdef DBG_WINDOWPOS
2052   Sys_Printf("create_floating: %p, gtk_window_set_default_size 100, 100\n", wnd);
2053 #endif
2054
2055   return wnd;
2056 }
2057
2058 void console_populate_popup(GtkTextView* textview, GtkMenu* menu, gpointer user_data)
2059 {
2060   menu_separator(GTK_WIDGET(menu));
2061
2062   GtkWidget* item = gtk_menu_item_new_with_label ("Clear");
2063   gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (Sys_ClearPrintf), NULL);
2064   gtk_widget_show (item);
2065   gtk_menu_append (GTK_MENU (menu), item);
2066 }
2067
2068 void console_construct(GtkWidget* textview)
2069 {
2070   g_signal_connect(G_OBJECT(textview), "populate-popup", G_CALLBACK(console_populate_popup), NULL);
2071 }
2072
2073 extern MemStream g_Clipboard;
2074
2075 void Clipboard_CopyMap()
2076 {
2077   g_Clipboard.SetLength(0);
2078   Map_Export (&g_Clipboard, "xmap", false, true);
2079 }
2080
2081 void Clipboard_PasteMap()
2082 {
2083   if (g_Clipboard.GetLength() > 0)
2084   {
2085     g_Clipboard.Seek(0, SEEK_SET);
2086     Map_Import(&g_Clipboard, "xmap", true);
2087   }
2088 }
2089
2090 /*!
2091 Platform-independent GTK clipboard support.
2092 \todo Using GDK_SELECTION_CLIPBOARD fails on win32, so we use the win32 API directly for now.
2093 */
2094 #if defined (__linux__) || defined (__APPLE__)
2095
2096 enum
2097 {
2098   RADIANT_CLIPPINGS = 23,
2099 };
2100
2101 static const GtkTargetEntry clipboard_targets[] = {
2102   { "RADIANT_CLIPPINGS", 0, RADIANT_CLIPPINGS, },
2103 };
2104
2105 static void clipboard_get (GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer user_data_or_owner)
2106 {
2107   guchar *buffer;
2108   gint len;
2109   GdkAtom type = GDK_NONE;
2110
2111   len = g_Clipboard.GetLength();
2112
2113   if (!len)
2114   {
2115     buffer = NULL;
2116   } else
2117   {
2118     buffer = g_Clipboard.GetBuffer ();
2119   }
2120
2121   if(info == clipboard_targets[0].info)
2122   {
2123     type = gdk_atom_intern(clipboard_targets[0].target, FALSE);
2124   }
2125
2126   gtk_selection_data_set (selection_data, type, 8, buffer, len);
2127 }
2128
2129 static void clipboard_clear (GtkClipboard *clipboard, gpointer user_data_or_owner)
2130 {
2131 }
2132
2133 static void clipboard_received (GtkClipboard *clipboard, GtkSelectionData *data, gpointer user_data)
2134 {
2135   g_Clipboard.SetLength (0);
2136
2137   if (data->length < 0)
2138     Sys_FPrintf(SYS_ERR, "Error retrieving selection\n");
2139   else if(strcmp(gdk_atom_name(data->type), clipboard_targets[0].target) == 0)
2140     g_Clipboard.Write (data->data, data->length);
2141
2142   Clipboard_PasteMap();
2143 }
2144
2145 void clipboard_copy()
2146 {
2147   Clipboard_CopyMap();
2148
2149   GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
2150
2151   gtk_clipboard_set_with_data (clipboard, clipboard_targets, 1, clipboard_get, clipboard_clear, NULL);
2152 }
2153
2154 void clipboard_paste()
2155 {
2156   GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
2157
2158   gtk_clipboard_request_contents (clipboard, gdk_atom_intern(clipboard_targets[0].target, FALSE), clipboard_received, NULL);
2159 }
2160
2161
2162 #elif defined(WIN32)
2163
2164 void clipboard_copy()
2165 {
2166   Clipboard_CopyMap();
2167
2168   bool bClipped = false;
2169   UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings");
2170   if (nClipboard > 0)
2171   {
2172     if (::OpenClipboard(NULL))
2173     {
2174       EmptyClipboard();
2175                 long lSize = g_Clipboard.GetLength();
2176       HANDLE h = ::GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, lSize + sizeof(long));
2177       if (h != NULL)
2178       {
2179         unsigned char *cp = reinterpret_cast<unsigned char*>(::GlobalLock(h));
2180                                 memcpy(cp, &lSize, sizeof(long));
2181                                 cp += sizeof(long);
2182         g_Clipboard.Seek(0, SEEK_SET);
2183         g_Clipboard.Read(cp, lSize);
2184         ::GlobalUnlock(h);
2185         ::SetClipboardData(nClipboard, h);
2186         ::CloseClipboard();
2187         bClipped = true;
2188       }
2189     }
2190   }
2191
2192   if (!bClipped)
2193   {
2194     Sys_Printf("Unable to register Windows clipboard formats, copy/paste between editors will not be possible\n");
2195   }
2196 }
2197
2198 void clipboard_paste()
2199 {
2200   bool bPasted = false;
2201   UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings");
2202   if (nClipboard > 0 && ::OpenClipboard(NULL))
2203   {
2204     if(IsClipboardFormatAvailable(nClipboard))
2205     {
2206       HANDLE h = ::GetClipboardData(nClipboard);
2207       if (h)
2208       {
2209         g_Clipboard.SetLength(0);
2210                           unsigned char *cp = reinterpret_cast<unsigned char*>(::GlobalLock(h));
2211                           long lSize = 0;
2212                           memcpy(&lSize, cp, sizeof(long));
2213                           cp += sizeof(long);
2214         g_Clipboard.Write(cp, lSize);
2215         ::GlobalUnlock(h);
2216       }
2217     }
2218     ::CloseClipboard();
2219   }
2220
2221   Clipboard_PasteMap();
2222 }
2223
2224 #endif
2225
2226 void MainFrame::Copy()
2227 {
2228   clipboard_copy();
2229 }
2230
2231 void MainFrame::Paste()
2232 {
2233   clipboard_paste();
2234   UpdateSurfaceDialog();
2235 }
2236
2237
2238 #ifdef DBG_WINDOWPOS
2239 GtkWidget *watchit = NULL;
2240
2241 void CheckWatchit(char *msg)
2242 {
2243   static int width = 0;
2244   if ((watchit!=NULL) && (watchit->allocation.width != width))
2245   {
2246     Sys_Printf("CheckWatchit %s: %d\n", msg, watchit->allocation.width);
2247     width = watchit->allocation.width;
2248   }
2249 }
2250 #endif
2251
2252 #ifdef _WIN32
2253 BOOL CALLBACK m_pCountMonitor (HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
2254 {
2255   int *n = (int *) dwData;
2256
2257   (*n)++;
2258
2259   return TRUE;
2260 }
2261
2262 struct monitorInfo_s { 
2263   GdkRectangle *win_monitors;
2264   int i_win_mon;
2265 };
2266
2267 BOOL CALLBACK m_pEnumMonitor (HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
2268 {
2269   monitorInfo_s *monitorInfo = (monitorInfo_s *) dwData;
2270   GdkRectangle *monitor;
2271   MONITORINFOEX lpmi;
2272
2273   monitor = monitorInfo->win_monitors + monitorInfo->i_win_mon;
2274
2275   memset(&lpmi, 0, sizeof(MONITORINFOEX));
2276   lpmi.cbSize = sizeof(MONITORINFOEX);
2277
2278   GetMonitorInfo( hMonitor, &lpmi );
2279
2280   if( lpmi.dwFlags & MONITORINFOF_PRIMARY ) {
2281     RECT rect;
2282
2283     SystemParametersInfo (SPI_GETWORKAREA, 0, &rect, 0);
2284     monitor->x = rect.left;
2285     monitor->y = rect.top;
2286     monitor->width = rect.right - rect.left;
2287     monitor->height = rect.bottom - rect.top;
2288
2289     if (monitorInfo->i_win_mon != 0)
2290           {
2291             GdkRectangle temp = *monitor;
2292       *monitor = monitorInfo->win_monitors[0];
2293             monitorInfo->win_monitors[0] = temp;
2294           }
2295   } else {
2296     monitor->x = lpmi.rcMonitor.left;
2297     monitor->y = lpmi.rcMonitor.top;
2298     monitor->width = lpmi.rcMonitor.right - lpmi.rcMonitor.left;
2299     monitor->height = lpmi.rcMonitor.bottom - lpmi.rcMonitor.top;
2300   }
2301
2302   monitorInfo->i_win_mon++;
2303
2304   return TRUE;
2305 }
2306
2307 void PositionWindowOnPrimaryScreen(window_position_t& position)
2308 {
2309   const GdkRectangle primaryMonitorRect = g_pParentWnd->GetPrimaryMonitorRect();
2310
2311   if( position.x <= primaryMonitorRect.x + 6 )
2312     position.x = primaryMonitorRect.x + 6;
2313   else if( position.x >= ( primaryMonitorRect.x + primaryMonitorRect.width ) - 6 )
2314     position.x = primaryMonitorRect.x + 6;
2315
2316   if( position.y <= primaryMonitorRect.y + 6 )
2317     position.y = primaryMonitorRect.y + 6;
2318   else if( position.y >= ( primaryMonitorRect.y + primaryMonitorRect.height ) - 6 )
2319     position.y = primaryMonitorRect.y + 6;
2320
2321   if( position.x + position.w >= ( primaryMonitorRect.x + primaryMonitorRect.width ) - 18 )
2322     position.w = primaryMonitorRect.width - 18;
2323   if( position.y + position.h >= ( primaryMonitorRect.y + primaryMonitorRect.height ) - 18 )
2324     position.h = primaryMonitorRect.height - 18;
2325 }
2326 #endif
2327
2328 GtkWidget* create_framed_widget(GtkWidget* widget)
2329 {
2330   GtkWidget* frame = gtk_frame_new ((char*)NULL);
2331   gtk_widget_show (frame);
2332   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
2333   gtk_container_add (GTK_CONTAINER (frame), widget);
2334   gtk_widget_show(widget);
2335   return frame;
2336 }
2337
2338 gboolean entry_focus_in(GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
2339 {
2340   gtk_window_remove_accel_group (GTK_WINDOW (g_pParentWnd->m_pWidget), global_accel);
2341   return FALSE;
2342 }
2343
2344 gboolean entry_focus_out(GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
2345 {
2346   gtk_window_add_accel_group (GTK_WINDOW (g_pParentWnd->m_pWidget), global_accel);
2347   return FALSE;
2348 }
2349
2350 GtkWidget* create_framed_texwnd(TexWnd* texwnd)
2351 {
2352   GtkWidget* frame = gtk_frame_new ((char*)NULL);
2353   gtk_widget_show (frame);
2354   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
2355
2356   GtkWidget* hbox = gtk_hbox_new (FALSE, 0);
2357   gtk_widget_show (hbox);
2358   gtk_container_add (GTK_CONTAINER (frame), hbox);
2359
2360   GtkWidget* w = gtk_vscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0,0,0,1,1,1)));
2361   gtk_widget_show (w);
2362   gtk_box_pack_end (GTK_BOX (hbox), w, FALSE, TRUE, 0);
2363   g_qeglobals_gui.d_texture_scroll = w;
2364
2365   GtkWidget* texbox = gtk_vbox_new (FALSE, 0);
2366   gtk_widget_show (texbox);
2367   gtk_box_pack_start (GTK_BOX (hbox), texbox, TRUE, TRUE, 0);
2368
2369   w = gtk_entry_new ();
2370   gtk_box_pack_start (GTK_BOX (texbox), w, FALSE, FALSE, 0);
2371   texwnd->m_pFilter = w;
2372   g_signal_connect(G_OBJECT(w), "focus_in_event", G_CALLBACK(entry_focus_in), NULL);
2373   g_signal_connect(G_OBJECT(w), "focus_out_event", G_CALLBACK(entry_focus_out), NULL);
2374
2375   w = texwnd->GetWidget ();
2376   gtk_box_pack_start (GTK_BOX (texbox), w, TRUE, TRUE, 0);
2377   gtk_widget_show (w);
2378
2379   return frame;
2380 }
2381
2382 static ZWnd *create_floating_zwnd(MainFrame *mainframe)
2383 {
2384   ZWnd *pZWnd = new ZWnd ();
2385   GtkWidget* wnd = create_floating (mainframe);
2386
2387   gtk_window_set_title (GTK_WINDOW (wnd), "Z");
2388
2389   pZWnd->m_pParent = wnd;
2390
2391   {
2392     GtkWidget* frame = create_framed_widget(pZWnd->GetWidget());
2393     gtk_container_add (GTK_CONTAINER (wnd), frame);
2394   }
2395
2396   gtk_widget_realize (wnd);
2397
2398   // turn OFF minimize and maximize boxes. 
2399   // Must be *after* realize, or wnd->window is NULL
2400   // should do the right thing on *nix, need to verify.
2401   gdk_window_set_decorations ( wnd->window,
2402                                 GdkWMDecoration(GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE ) );
2403   //TODO 50 by observation, will vary depending on decoration sizes
2404   {
2405     GdkGeometry geometry;
2406     geometry.min_width = 50;
2407     //we only care about width, but have to set this too, or get nasty bugs
2408     geometry.min_height = 10; 
2409     gdk_window_set_geometry_hints( wnd->window,&geometry,GDK_HINT_MIN_SIZE);
2410   }
2411
2412 #ifdef _WIN32
2413   if( g_PrefsDlg.m_bStartOnPrimMon ) {
2414     PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posZWnd );
2415   }
2416 #endif
2417   load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posZWnd);
2418
2419   if (g_PrefsDlg.m_bZVis)
2420     gtk_widget_show (wnd);
2421
2422   return pZWnd;
2423 }
2424
2425 static const int gutter = 12;
2426
2427 void MainFrame::Create ()
2428 {
2429   GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2430   m_pWidget = window;
2431   gtk_widget_set_events (window, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
2432   gtk_signal_connect (GTK_OBJECT (window), "delete_event",
2433                       GTK_SIGNAL_FUNC (mainframe_delete), this);
2434   gtk_signal_connect (GTK_OBJECT (window), "destroy",
2435                       GTK_SIGNAL_FUNC (mainframe_destroy), this);
2436   gtk_signal_connect (GTK_OBJECT (window), "key_press_event",
2437                       GTK_SIGNAL_FUNC (mainframe_keypress), this);
2438   gtk_signal_connect (GTK_OBJECT (window), "key_release_event",
2439                       GTK_SIGNAL_FUNC (mainframe_keyrelease), this);
2440   gtk_signal_connect (GTK_OBJECT (window), "map_event",
2441                       GTK_SIGNAL_FUNC (mainframe_map), this);
2442   gtk_signal_connect (GTK_OBJECT (window), "unmap_event",
2443                       GTK_SIGNAL_FUNC (mainframe_unmap), this);
2444
2445   g_qeglobals_gui.d_main_window = window;
2446
2447 #ifdef _WIN32
2448   // calculate gdk offset
2449   int n_win_monitors = 0;
2450
2451   monitorInfo_s monitorInfo;
2452
2453   // detect multiple monitors
2454   EnumDisplayMonitors (NULL, NULL, m_pCountMonitor, reinterpret_cast<LPARAM>(&n_win_monitors));
2455
2456   monitorInfo.win_monitors = new GdkRectangle [ n_win_monitors ];
2457   monitorInfo.i_win_mon = 0;
2458   EnumDisplayMonitors (NULL, NULL, m_pEnumMonitor, reinterpret_cast<LPARAM>(&monitorInfo));
2459
2460   gdk_offset_x = G_MININT;
2461   gdk_offset_y = G_MININT;
2462
2463   // calculate offset
2464   for( monitorInfo.i_win_mon = 0; monitorInfo.i_win_mon < n_win_monitors; monitorInfo.i_win_mon++ ) {
2465     gdk_offset_x = MAX (gdk_offset_x, -monitorInfo.win_monitors[monitorInfo.i_win_mon].x);
2466     gdk_offset_y = MAX (gdk_offset_y, -monitorInfo.win_monitors[monitorInfo.i_win_mon].y);
2467   }
2468
2469   Sys_Printf( "GDK's coordinate system is offset by %d over the x-axis and %d over the y-axis from Windows' coordinate system.\n", gdk_offset_x, gdk_offset_y );
2470
2471   if( g_PrefsDlg.m_bStartOnPrimMon )
2472   {
2473     // get gdk monitors
2474     GdkDisplay *display;
2475     GdkScreen *screen;
2476     gint n_gdk_monitors = 0;
2477     gint i_mon;
2478     GdkRectangle rect;
2479
2480     // detect multiple monitors
2481     display = gdk_display_get_default ();
2482     Sys_Printf( "GDK detects that server %s manages %d screens\n", gdk_display_get_name (display), gdk_display_get_n_screens (display) );
2483
2484     screen = gdk_display_get_screen( display, 1 );
2485     n_gdk_monitors = gdk_screen_get_n_monitors( screen );
2486       
2487     Sys_Printf( "GDK detects that screen 1 has %d monitors\n", n_gdk_monitors );
2488
2489     for( i_mon = 0; i_mon < n_gdk_monitors; i_mon++ ) {
2490       memset( &rect, 0, sizeof(rect) );
2491       gdk_screen_get_monitor_geometry( screen, i_mon, &rect );
2492       Sys_Printf( "  monitor %d: x: %d y: %d w: %d h: %d\n", i_mon, rect.x, rect.y, rect.width, rect.height );
2493
2494       if( i_mon == 0 ) {
2495         memcpy( &primaryMonitorRect, &rect, sizeof(primaryMonitorRect) );
2496       }
2497     }
2498
2499     PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.position );
2500   }
2501   else {
2502     primaryMonitorRect.x = primaryMonitorRect.y = 0; 
2503     primaryMonitorRect.width = gdk_screen_width ();
2504     primaryMonitorRect.height = gdk_screen_height (); 
2505   }
2506
2507 #endif
2508
2509   load_window_pos(window, g_PrefsDlg.mWindowInfo.position);
2510
2511   GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
2512   gtk_container_add (GTK_CONTAINER (window), vbox);
2513   gtk_widget_show (vbox);
2514
2515   create_main_menu (window, vbox);
2516   MRU_Load ();
2517   create_main_toolbar (window, vbox);
2518   create_plugin_toolbar (window,vbox);
2519
2520   m_nCurrentStyle = g_PrefsDlg.m_nView;
2521
2522   g_pGroupDlg->Create ();
2523   OnPluginsRefresh();
2524
2525   CreateQEChildren();
2526
2527   gtk_widget_show (window);
2528
2529   // not needed on win32, it's in the .rc
2530 #ifndef _WIN32
2531   {
2532     GdkPixmap *pixmap;
2533     GdkBitmap *mask;
2534     load_pixmap ("icon.bmp", window, &pixmap, &mask);
2535     gdk_window_set_icon (window->window, NULL, pixmap, mask);
2536   }
2537 #endif
2538
2539   if (CurrentStyle() == eRegular || CurrentStyle() == eRegularLeft)
2540   {
2541     {
2542       GtkWidget* vsplit = gtk_vpaned_new ();
2543       m_pSplits[0] = vsplit;
2544       gtk_box_pack_start (GTK_BOX (vbox), vsplit, TRUE, TRUE, 0);
2545       gtk_widget_show (vsplit);
2546
2547       {
2548         GtkWidget* hsplit = gtk_hpaned_new ();
2549         m_pSplits[2] = hsplit;
2550         gtk_paned_add1 (GTK_PANED (vsplit), hsplit);
2551         gtk_widget_show (hsplit);
2552
2553         {
2554           GtkWidget* hsplit2 = gtk_hpaned_new ();
2555           m_pSplits[3] = hsplit2;
2556           gtk_paned_add2 (GTK_PANED (hsplit), hsplit2);
2557           gtk_widget_show (hsplit2);
2558
2559           {
2560             GtkWidget* vsplit2 = gtk_vpaned_new ();
2561             m_pSplits[1] = vsplit2;
2562             if (CurrentStyle() == eRegular)
2563               gtk_paned_add2 (GTK_PANED (hsplit2), vsplit2);
2564             else
2565               gtk_paned_add1 (GTK_PANED (hsplit), vsplit2);
2566             gtk_widget_show (vsplit2);
2567
2568             // camera
2569             m_pCamWnd = new CamWnd ();
2570             {
2571               GtkWidget* frame = create_framed_widget(m_pCamWnd->GetWidget());
2572               gtk_paned_add1 (GTK_PANED (vsplit2), frame);
2573             }
2574
2575             // xy
2576             m_pXYWnd = new XYWnd ();
2577             m_pXYWnd->SetViewType(XY);
2578             {
2579               GtkWidget* frame = create_framed_widget(m_pXYWnd->GetWidget ());
2580               gtk_paned_add1 (GTK_PANED (hsplit2), frame);
2581             }
2582
2583             // z
2584             m_pZWnd = new ZWnd ();
2585             {
2586               GtkWidget* frame = create_framed_widget(m_pZWnd->GetWidget ());
2587               if (CurrentStyle() == eRegular)
2588                 gtk_paned_add1 (GTK_PANED (hsplit), frame);
2589               else
2590                 gtk_paned_add2 (GTK_PANED (hsplit2), frame);
2591             }
2592
2593             // textures
2594             m_pTexWnd = new TexWnd ();
2595             {
2596               GtkWidget* frame = create_framed_texwnd(m_pTexWnd);
2597               gtk_paned_add2 (GTK_PANED (vsplit2), frame);
2598             }
2599
2600             // console
2601             {
2602               GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
2603               gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2604               gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
2605               gtk_widget_show (scr);
2606               gtk_paned_pack2 (GTK_PANED (vsplit), scr, FALSE, TRUE);
2607
2608               {
2609                 GtkWidget* text = gtk_text_view_new ();
2610                 gtk_widget_set_size_request(text, 0, -1); // allow shrinking
2611                 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
2612                 gtk_text_view_set_editable (GTK_TEXT_VIEW(text), FALSE);
2613                 gtk_container_add (GTK_CONTAINER (scr), text);
2614                 gtk_widget_show (text);
2615                 g_qeglobals_gui.d_edit = text;
2616               }
2617             }
2618           }
2619         }
2620       }
2621     }
2622
2623     gtk_paned_set_position (GTK_PANED (m_pSplits[0]), g_PrefsDlg.mWindowInfo.nXYHeight+28);
2624
2625     if (CurrentStyle() == eRegular)
2626     {
2627       gtk_paned_set_position (GTK_PANED (m_pSplits[2]), g_PrefsDlg.mWindowInfo.nZWidth);
2628       gtk_paned_set_position (GTK_PANED (m_pSplits[3]), g_PrefsDlg.mWindowInfo.nXYWidth);
2629     }
2630     else
2631     {
2632       gtk_paned_set_position (GTK_PANED (m_pSplits[2]), g_PrefsDlg.mWindowInfo.nCamWidth);
2633       while (gtk_events_pending ())  gtk_main_iteration ();
2634       gtk_paned_set_position (GTK_PANED (m_pSplits[3]), g_PrefsDlg.mWindowInfo.nXYWidth);
2635     }
2636
2637     while (gtk_events_pending ())  gtk_main_iteration ();
2638
2639     gtk_paned_set_position (GTK_PANED (m_pSplits[1]), g_PrefsDlg.mWindowInfo.nCamHeight);
2640   }
2641   else if (CurrentStyle() == eFloating)
2642   {
2643     {
2644       GtkWidget* wnd = create_floating (this);
2645       gtk_window_set_title (GTK_WINDOW (wnd), "Camera");
2646
2647 #ifdef _WIN32
2648       if( g_PrefsDlg.m_bStartOnPrimMon ) {
2649         PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posCamWnd );
2650       }
2651 #endif
2652       load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posCamWnd);
2653
2654       gtk_widget_show (wnd);
2655
2656       m_pCamWnd = new CamWnd ();
2657
2658       {
2659         GtkWidget* frame = create_framed_widget(m_pCamWnd->GetWidget ());
2660         gtk_container_add (GTK_CONTAINER (wnd), frame);
2661       }
2662
2663       m_pCamWnd->m_pParent = wnd;
2664     }
2665
2666     if (g_PrefsDlg.m_bFloatingZ)
2667     {
2668       m_pZWnd = create_floating_zwnd(this);
2669
2670       {
2671         GtkWidget* wnd = create_floating (this);
2672         gtk_window_set_title (GTK_WINDOW (wnd), "XY View");
2673
2674 #ifdef _WIN32
2675         if( g_PrefsDlg.m_bStartOnPrimMon ) {
2676           PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posXYWnd );
2677         }
2678 #endif
2679         load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posXYWnd);
2680
2681         m_pXYWnd = new XYWnd ();
2682         m_pXYWnd->SetViewType(XY);
2683
2684         {
2685           GtkWidget* frame = create_framed_widget(m_pXYWnd->GetWidget());
2686           gtk_container_add (GTK_CONTAINER (wnd), frame);
2687         }
2688
2689         m_pXYWnd->m_pParent = wnd;
2690
2691         gtk_widget_show (wnd);
2692       }
2693     }
2694     else
2695     {
2696       GtkWidget* wnd = create_floating (this);
2697       gtk_window_set_title (GTK_WINDOW (wnd), "XY View");
2698
2699 #ifdef _WIN32
2700       if( g_PrefsDlg.m_bStartOnPrimMon ) {
2701         PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posXYWnd );
2702       }
2703 #endif
2704       load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posXYWnd);
2705
2706       m_pZWnd = new ZWnd ();
2707       m_pZWnd->m_pParent = wnd;
2708
2709       m_pXYWnd = new XYWnd ();
2710       m_pXYWnd->SetViewType(XY);
2711       m_pXYWnd->m_pParent = wnd;
2712
2713
2714       {
2715         GtkWidget* hsplit = gtk_hpaned_new ();
2716         m_pSplits[0] = hsplit;
2717         gtk_container_add (GTK_CONTAINER (wnd), hsplit);
2718         gtk_widget_show (hsplit);
2719
2720         {
2721           GtkWidget* frame = create_framed_widget(m_pZWnd->GetWidget());
2722           gtk_paned_add1 (GTK_PANED (hsplit), frame);
2723         }
2724         {
2725           GtkWidget* frame = create_framed_widget(m_pXYWnd->GetWidget());
2726           gtk_paned_add2 (GTK_PANED (hsplit), frame);
2727         }
2728       }
2729
2730       gtk_widget_show (wnd);
2731
2732       gtk_paned_set_position (GTK_PANED (m_pSplits[0]), g_PrefsDlg.mWindowInfo.nZFloatWidth);
2733     }
2734
2735     {
2736       GtkWidget* wnd = create_floating (this);
2737       gtk_window_set_title (GTK_WINDOW (wnd), "XZ View");
2738
2739 #ifdef _WIN32
2740       if( g_PrefsDlg.m_bStartOnPrimMon ) {
2741         PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posXZWnd );
2742       }
2743 #endif
2744       load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posXZWnd);
2745
2746       m_pXZWnd = new XYWnd ();
2747       m_pXZWnd->m_pParent = wnd;
2748       m_pXZWnd->SetViewType(XZ);
2749
2750       {
2751         GtkWidget* frame = create_framed_widget(m_pXZWnd->GetWidget());
2752         gtk_container_add (GTK_CONTAINER (wnd), frame);
2753       }
2754
2755       if (g_PrefsDlg.m_bXZVis)
2756         gtk_widget_show (wnd);
2757     }
2758
2759     {
2760       GtkWidget* wnd = create_floating (this);
2761       gtk_window_set_title (GTK_WINDOW (wnd), "YZ View");
2762
2763 #ifdef _WIN32
2764       if( g_PrefsDlg.m_bStartOnPrimMon ) {
2765         PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posYZWnd );
2766       }
2767 #endif
2768       load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posYZWnd);
2769
2770       m_pYZWnd = new XYWnd ();
2771       m_pYZWnd->m_pParent = wnd;
2772       m_pYZWnd->SetViewType(YZ);
2773
2774       {
2775         GtkWidget* frame = create_framed_widget(m_pYZWnd->GetWidget());
2776         gtk_container_add (GTK_CONTAINER (wnd), frame);
2777       }
2778
2779       if (g_PrefsDlg.m_bYZVis)
2780         gtk_widget_show (wnd);
2781     }
2782
2783     m_pTexWnd = new TexWnd ();
2784     {
2785       GtkWidget* frame = create_framed_texwnd(m_pTexWnd);
2786       m_pTexWnd->m_pParent = g_pGroupDlg->m_pWidget;
2787
2788       {
2789         GtkWidget* w = gtk_label_new ("Textures");
2790         gtk_widget_show (w);
2791         gtk_notebook_insert_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), frame, w, 1);
2792       }
2793     }
2794
2795     g_pGroupDlg->Show ();
2796   }
2797   else // 4 way
2798   {
2799     {
2800       GtkWidget* hsplit = gtk_hpaned_new ();
2801       m_pSplits[0] = hsplit;
2802       gtk_box_pack_start (GTK_BOX (vbox), hsplit, TRUE, TRUE, 0);
2803       gtk_widget_show (hsplit);
2804
2805       {
2806         GtkWidget* vsplit1 = gtk_vpaned_new ();
2807         m_pSplits[1] = vsplit1;
2808         gtk_paned_add1 (GTK_PANED (hsplit), vsplit1);
2809         gtk_widget_show (vsplit1);
2810
2811         {
2812           GtkWidget* vsplit2 = gtk_vpaned_new ();
2813           m_pSplits[2] = vsplit2;
2814           gtk_paned_add2 (GTK_PANED (hsplit), vsplit2);
2815           gtk_widget_show (vsplit2);
2816
2817           m_pCamWnd = new CamWnd ();
2818           {
2819             GtkWidget* frame = create_framed_widget(m_pCamWnd->GetWidget());
2820             gtk_paned_add1 (GTK_PANED (vsplit1), frame);
2821           }
2822
2823           m_pXYWnd = new XYWnd ();
2824           m_pXYWnd->SetViewType(XY);
2825           {
2826             GtkWidget* frame = create_framed_widget(m_pXYWnd->GetWidget());
2827             gtk_paned_add1 (GTK_PANED (vsplit2), frame);
2828           }
2829
2830           m_pYZWnd = new XYWnd ();
2831           m_pYZWnd->SetViewType(YZ);
2832           {
2833             GtkWidget* frame = create_framed_widget(m_pYZWnd->GetWidget());
2834             gtk_paned_add2 (GTK_PANED (vsplit1), frame);
2835           }
2836
2837           m_pXZWnd = new XYWnd ();
2838           m_pXZWnd->SetViewType(XZ);
2839           {
2840             GtkWidget* frame = create_framed_widget(m_pXZWnd->GetWidget());
2841             gtk_paned_add2 (GTK_PANED (vsplit2), frame);
2842           }
2843         }
2844       }
2845     }
2846
2847     //    g_qeglobals_gui.d_edit = NULL;
2848
2849     {
2850       m_pTexWnd = new TexWnd ();
2851       GtkWidget* frame = create_framed_texwnd(m_pTexWnd);
2852
2853       {
2854         GtkWidget* w = gtk_label_new ("Textures");
2855         gtk_widget_show (w);
2856         gtk_notebook_insert_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), frame, w, 1);
2857       }
2858     }
2859
2860     m_pTexWnd->m_pParent = g_pGroupDlg->m_pWidget;
2861 //    gtk_widget_realize (m_pTexWnd->GetWidget ());
2862     m_pZWnd = create_floating_zwnd(this);
2863
2864     while (gtk_events_pending ())
2865       gtk_main_iteration ();
2866
2867     {
2868       int x = GTK_PANED (m_pSplits[0])->max_position/2 - gutter;
2869       gtk_paned_set_position (GTK_PANED (m_pSplits[0]), x);
2870     }
2871
2872     {
2873       int y = GTK_PANED (m_pSplits[1])->max_position/2 - gutter;
2874       gtk_paned_set_position (GTK_PANED (m_pSplits[1]), y);
2875       gtk_paned_set_position (GTK_PANED (m_pSplits[2]), y);
2876     }
2877   }
2878
2879   if(g_PrefsDlg.mWindowInfo.nState & GDK_WINDOW_STATE_MAXIMIZED)
2880     gtk_window_maximize(GTK_WINDOW(window));
2881
2882   gtk_widget_show (window);
2883
2884   Texture_Init();
2885
2886   if (m_pXYWnd) // this is always true?
2887   {
2888     m_pXYWnd->SetActive(true);
2889   }
2890   m_bSplittersOK = true;
2891   Texture_SetMode(g_qeglobals.d_savedinfo.iTexMenu);
2892
2893   g_pParentWnd->OnEntitiesSetViewAs(0);
2894
2895 //  m_wndTextureBar.Create (vbox);
2896   create_main_statusbar (window, vbox);
2897
2898   LoadCommandMap();
2899   ShowMenuItemKeyBindings(window);
2900
2901   if (g_qeglobals_gui.d_edit != NULL)
2902     console_construct(g_qeglobals_gui.d_edit);
2903
2904   //  bool load_last = FALSE;
2905
2906   SetGridStatus();
2907   SetButtonMenuStates();
2908
2909   // m_bShowShader and m_bTextureShaderlistOnly have a menu checkbox, update it now
2910   GtkWidget *item;
2911   g_bIgnoreCommands++;
2912   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_shaders_show"));
2913   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bShowShaders ? TRUE : FALSE);
2914   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_shaderlistonly"));
2915   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bTexturesShaderlistOnly ? TRUE : FALSE);
2916   g_bIgnoreCommands--;
2917
2918 //  if (g_PrefsDlg.m_bTextureBar)
2919 //    gtk_widget_show (m_wndTextureBar.m_pWidget);
2920
2921   SetActiveXY(m_pXYWnd);
2922
2923   s_idle_id = gtk_timeout_add (25, mainframe_idle, this);  
2924
2925   QGL_InitExtensions ();
2926
2927   if (g_PrefsDlg.mLocalPrefs.mbEmpty)
2928   {
2929     g_PrefsDlg.mLocalPrefs.mbEmpty = false;
2930     g_PrefsDlg.SavePrefs();
2931   }
2932
2933   // remove the pid file
2934   remove (g_pidGameFile.GetBuffer ());  
2935
2936   Sys_Printf ("Entering message loop\n");
2937
2938   m_bDoLoop = true;
2939
2940   m_nTimer = gtk_timeout_add (1000, timer, this);
2941 }
2942
2943 // =============================================================================
2944 // MainFrame class
2945
2946 MainFrame::MainFrame()
2947 {
2948   m_bDoLoop = false;
2949   m_bSplittersOK = false;
2950   g_pParentWnd = this;
2951   m_pXYWnd = (XYWnd*)NULL;
2952   m_pCamWnd = NULL;
2953   m_pTexWnd = (TexWnd*)NULL;
2954   m_pZWnd = (ZWnd*)NULL;
2955   m_pYZWnd = (XYWnd*)NULL;
2956   m_pXZWnd = (XYWnd*)NULL;
2957   m_pActiveXY = (XYWnd*)NULL;
2958   m_bCamPreview = true;
2959   m_pWatchBSP = NULL;
2960   for (int n = 0; n < 6; n++)
2961     m_pStatusLabel[n] = NULL;
2962   m_bNeedStatusUpdate = false;
2963   m_nTimer = 0;
2964   m_bSleeping = false;
2965   Create ();
2966 }
2967
2968 MainFrame::~MainFrame()
2969 {
2970   while (g_BSPFrontendCommands)
2971   {
2972     free (g_BSPFrontendCommands->data);
2973     g_BSPFrontendCommands = g_slist_remove (g_BSPFrontendCommands, g_BSPFrontendCommands->data);
2974   }
2975 }
2976
2977 void MainFrame::ReleaseContexts ()
2978 {
2979   if (m_pXYWnd)
2980     m_pXYWnd->DestroyContext ();
2981   if (m_pYZWnd)
2982     m_pYZWnd->DestroyContext ();
2983   if (m_pXZWnd)
2984     m_pXZWnd->DestroyContext ();
2985   if (m_pCamWnd)
2986     m_pCamWnd->DestroyContext ();
2987   if (m_pTexWnd)
2988     m_pTexWnd->DestroyContext ();
2989   if (m_pZWnd)
2990     m_pZWnd->DestroyContext ();
2991 }
2992
2993 void MainFrame::CreateContexts ()
2994 {
2995   if (m_pCamWnd)
2996     m_pCamWnd->CreateContext ();
2997   if (m_pXYWnd)
2998     m_pXYWnd->CreateContext ();
2999   if (m_pYZWnd)
3000     m_pYZWnd->CreateContext ();
3001   if (m_pXZWnd)
3002     m_pXZWnd->CreateContext ();
3003   if (m_pTexWnd)
3004     m_pTexWnd->CreateContext ();
3005   if (m_pZWnd)
3006     m_pZWnd->CreateContext ();
3007 }
3008
3009 static void Sys_Iconify (GtkWidget *w)
3010 {
3011   // we might not have been realized yet
3012   if (w->window == NULL)
3013     return;
3014
3015   if (!GTK_WIDGET_MAPPED (w))
3016     return;
3017
3018 #if defined (__linux__) || defined (__APPLE__)
3019   Sys_FPrintf(SYS_WRN, "FIXME: Sys_Iconify\n");  
3020 #if 0  
3021   XWindowAttributes xattr;
3022   GdkWindowPrivate *Private;
3023
3024   Private = (GdkWindowPrivate*)w->window;
3025   g_object_set_data (G_OBJECT (w), "was_mapped", GINT_TO_POINTER (0));
3026
3027   if (!Private->destroyed)
3028   {
3029     xattr.map_state = IsUnmapped;
3030     XGetWindowAttributes(Private->xdisplay, Private->xwindow, &xattr);
3031
3032     if (xattr.map_state != IsUnmapped)
3033       g_object_set_data (G_OBJECT (w), "was_mapped", GINT_TO_POINTER (1));
3034
3035     XIconifyWindow (Private->xdisplay, Private->xwindow, 0);
3036   }
3037 #endif
3038 #endif
3039
3040 #ifdef _WIN32
3041   ShowWindow ((HWND)GDK_WINDOW_HWND (w->window), SW_MINIMIZE);
3042 #endif
3043 }
3044
3045 static void Sys_Restore (GtkWidget *w)
3046 {
3047   // we might not have been realized yet
3048   if (w->window == NULL)
3049     return;
3050
3051   if (!GTK_WIDGET_VISIBLE (w))
3052     return;
3053
3054 #if defined (__linux__) || defined (__APPLE__)
3055   Sys_FPrintf(SYS_WRN, "FIXME: Sys_Restore\n");
3056   #if 0
3057   XWindowAttributes xattr;
3058   GdkWindowPrivate *Private;
3059
3060   Private = (GdkWindowPrivate*)w->window;
3061
3062   xattr.map_state = IsUnmapped;
3063   XGetWindowAttributes(Private->xdisplay, Private->xwindow, &xattr);
3064
3065   if (xattr.map_state == IsUnmapped)
3066     XMapRaised (Private->xdisplay, Private->xwindow);
3067   #endif
3068 #endif
3069
3070 #ifdef _WIN32
3071   ShowWindow ((HWND)GDK_WINDOW_HWND (w->window), SW_RESTORE);
3072 #endif
3073 }
3074
3075 #ifdef _DEBUG
3076 //#define DBG_SLEEP
3077 #endif
3078
3079 void RefreshModelSkin (GSList **pModels, entitymodel_t *model)
3080 {
3081   //++timo FIXME: the are some bogus entitymodel_t that appear in the list cause of buggy HasModel
3082   // so we avoid the fucked up ones, assuming they are at the end
3083   if (!model->strSkin)
3084   {
3085 #ifdef DBG_SLEEP
3086     Sys_Printf("Dropping model %p with empty skin in RefreshModelSkin\n", model);
3087 #endif
3088
3089     // and also keeping it so we have an actual count of empty models
3090     g_slist_append (*pModels, model);
3091     return;
3092   }
3093   // do we have this model already?
3094   if (g_slist_find (*pModels, model))
3095   {
3096 #ifdef DBG_SLEEP
3097
3098     // looks like we don't have the filename for the model, only the skin name and tris.. so we put the adress
3099     Sys_Printf("Already processed model: %p %s\n", model, ((GString *)model->strSkin)->str);
3100 #endif
3101     return;
3102   }
3103   model->nTextureBind = Texture_LoadSkin(((GString *)model->strSkin)->str, &model->nSkinWidth, &model->nSkinHeight );
3104   if (model->nTextureBind != -1)
3105     Sys_Printf("LOADED SKIN: %s\n", ((GString *)model->strSkin)->str );
3106   else
3107     Sys_Printf("Load skin failed: %s\n", ((GString *)model->strSkin)->str );
3108   *pModels = g_slist_append (*pModels, model);
3109 #ifdef DBG_SLEEP
3110   Sys_Printf("Processed model %p %s\n", model, ((GString *)model->strSkin)->str);
3111 #endif
3112 }
3113
3114 void MainFrame::OnSleep()
3115 {
3116   m_bSleeping ^= 1;
3117   if (m_bSleeping)
3118   {
3119     // useful when trying to debug crashes in the sleep code
3120     Sys_Printf("Going into sleep mode..\n");
3121
3122     Sys_Printf("Dispatching sleep msg...");
3123     DispatchRadiantMsg (RADIANT_SLEEP);
3124     Sys_Printf("Done.\n");
3125
3126     if (CurrentStyle() == eSplit)
3127       Sys_Iconify (m_pZWnd->m_pParent);
3128
3129     Sys_Iconify (m_pWidget);  
3130     Select_Deselect();
3131     QERApp_FreeShaders ();
3132     g_bScreenUpdates = false;
3133
3134     // release contexts
3135     Sys_Printf("Releasing contexts...");
3136     ReleaseContexts();
3137     Sys_Printf("Done.\n");
3138
3139     // free all the skins in the caches
3140     // their GL resources have been freed but the structs are not, so Radiant would think they are still valid
3141     g_lstSkinCache.RemoveAll();
3142   } else
3143   {
3144     Sys_Printf("Waking up\n");
3145     if (CurrentStyle() == eSplit)
3146       Sys_Restore (m_pZWnd->m_pParent);
3147
3148     Sys_Restore (m_pWidget);
3149
3150     // create contexts
3151     Sys_Printf("Creating contexts...");
3152     CreateContexts();
3153     Sys_Printf("Done.\n");
3154
3155     Sys_Printf("Making current on camera...");
3156     m_pCamWnd->MakeCurrent ();
3157     Sys_Printf("Done.\n");
3158
3159     Sys_Printf("Reloading shaders...");
3160     // reload the shader scripts and textures
3161     QERApp_ReloadShaders ();
3162     // current shader
3163     // NOTE: we are kinda making it loop on itself, it will update the pShader and scroll the texture window
3164     Texture_SetTexture (&g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false, NULL, false);
3165     Sys_Printf("Done.\n");
3166
3167     // rebuild the patches by setting the bDirty flag on them
3168     for (brush_t* b=active_brushes.next ; b != &active_brushes ; b=b->next)
3169     {
3170       if (b->patchBrush)
3171         b->pPatch->bDirty = true;
3172     }
3173
3174     Sys_Printf("Reloading skins...");
3175     // we have purged all the skins before going to sleep
3176     // to rebuild, go through everything that needs a skin and call Texture_LoadSkin
3177     // namely, all entitymodel_t
3178     // since there's no direct list we go through entities to get the eclass_t and from there the entitymodel_t
3179     // (a single eclass_t can reference several entitymodel_t)
3180     // FIXME: and what's up with md3Class then? what is it used for?
3181 /*
3182     eclass_t *e;
3183     entity_t *ent;
3184     GSList *Models = NULL;
3185     for (ent = entities.next; ent != &entities; ent = ent->next)
3186     {
3187       // if it's a model with skin then the fixedsize flag must be on
3188       // only if there IS a model .. we are not trying to load
3189       if (ent->eclass->fixedsize)
3190       {
3191         if (ent->eclass->model)
3192         {
3193 #ifdef DBG_SLEEP
3194           if (ent->md3Class)
3195             Sys_Printf("WARNING: unexpected ent->md3Class!=NULL with ent->eclass->model!=NULL\n");
3196 #endif
3197           entitymodel_t *model;
3198           for (model = ent->eclass->model; model; model=model->pNext)
3199             RefreshModelSkin (&Models, model);
3200         } else if (ent->md3Class)
3201         {
3202           entitymodel_t *model;
3203           for (model = ent->md3Class->model; model; model=model->pNext)
3204             RefreshModelSkin (&Models, model);
3205         }
3206 #ifdef DBG_SLEEP
3207         else
3208           Sys_Printf("WARNING: entity %p %s with fixedsize and no model no md3Class\n", ent, ent->eclass->name);
3209 #endif
3210       }
3211     }
3212 #ifdef DBG_SLEEP
3213     for (e = g_md3Cache; e ; e = e->next)
3214     {
3215       entitymodel_t *model;
3216       for (model = e->model; model; model=model->pNext)
3217         if (!g_slist_find (Models, model))
3218         {
3219           Sys_Printf("model %p ", model);
3220           if (model->strSkin)
3221             Sys_Printf("%s not found in main loop\n", ((GString *)model->strSkin)->str);
3222           else
3223             Sys_Printf("not found in main loop (no skin)\n");
3224         }
3225     }
3226 #endif
3227     // clean the model list
3228     g_slist_free (Models);
3229 */
3230     Sys_Printf("Done.\n");
3231
3232     // bring back the GL font
3233     gtk_glwidget_create_font (m_pCamWnd->GetWidget ());
3234
3235     g_bScreenUpdates = true;
3236
3237     Sys_Printf("Dispatching wake msg...");
3238     DispatchRadiantMsg (RADIANT_WAKEUP);
3239     Sys_Printf("Done\n");
3240   }
3241 }
3242
3243 void WINAPI QERApp_Sleep()
3244 {
3245   g_pParentWnd->OnSleep();
3246 }
3247
3248 /*!
3249 NOTE TTimo
3250 the exit path is a bit complicated, I guess we have to run the window pos saving in OnDelete
3251 and not in OnDestroy because the info may be lost already?
3252 \todo try sinking OnDelete into OnDestroy and see if it breaks anything
3253 */
3254 void MainFrame::OnDelete ()
3255 {
3256   save_window_pos(m_pWidget, g_PrefsDlg.mWindowInfo.position);
3257
3258   // surface inspector and patch inspector
3259   save_window_pos (g_dlgSurface.GetWidget(), g_PrefsDlg.mWindowInfo.posSurfaceWnd);
3260   save_window_pos (g_PatchDialog.GetWidget(), g_PrefsDlg.mWindowInfo.posPatchWnd);
3261
3262   // entity inspector / group dialog
3263   // NOTE TTimo do we have to save a different window depending on the view mode?
3264   save_window_pos (g_pGroupDlg->m_pWidget, g_PrefsDlg.mWindowInfo.posEntityWnd);
3265
3266   if (g_PrefsDlg.m_bFloatingZ)
3267     save_window_pos (m_pZWnd->m_pParent, g_PrefsDlg.mWindowInfo.posZWnd);
3268   else
3269     g_PrefsDlg.mWindowInfo.nZFloatWidth = GTK_PANED (m_pSplits[0])->child1_size;
3270
3271   if (CurrentStyle() == eFloating)
3272   {
3273     save_window_pos (m_pCamWnd->m_pParent, g_PrefsDlg.mWindowInfo.posCamWnd);
3274     save_window_pos (m_pXYWnd->m_pParent, g_PrefsDlg.mWindowInfo.posXYWnd);
3275     save_window_pos (m_pXZWnd->m_pParent, g_PrefsDlg.mWindowInfo.posXZWnd);
3276     save_window_pos (m_pYZWnd->m_pParent, g_PrefsDlg.mWindowInfo.posYZWnd);
3277   }
3278
3279   g_PrefsDlg.mWindowInfo.nState = gdk_window_get_state(g_pParentWnd->m_pWidget->window);
3280 }
3281
3282 void MainFrame::OnDestroy ()
3283 {
3284   // shut down console output first
3285   // (we'll still get the info if we are running a log file anyway)
3286   g_qeglobals_gui.d_edit = NULL;
3287
3288 #ifdef _DEBUG
3289   Sys_Printf("MainFrame::OnDestroy\n");
3290 #endif
3291   if (s_idle_id)
3292     gtk_timeout_remove (s_idle_id);
3293   if (m_nTimer)
3294     gtk_timeout_remove (m_nTimer);
3295
3296   if (!g_qeglobals.disable_ini)
3297   {
3298     Sys_Printf("Start writing prefs\n");
3299     Sys_Printf("MRU_Save... ");
3300     MRU_Save ();
3301     Sys_Printf("OK\n");
3302
3303     gpointer w;
3304
3305     w = g_object_get_data (G_OBJECT (g_pGroupDlg->m_pWidget), "split1");
3306     g_PrefsDlg.mWindowInfo.nEntitySplit1 = GTK_PANED (w)->child1_size;
3307     w = g_object_get_data (G_OBJECT (g_pGroupDlg->m_pWidget), "split2");
3308     g_PrefsDlg.mWindowInfo.nEntitySplit2 = GTK_PANED (w)->child1_size;
3309
3310     if (!FloatingGroupDialog())
3311     {
3312       GtkWidget *vsplit, *hsplit, *vsplit2, *hsplit2;
3313
3314       vsplit = m_pSplits[0];
3315       vsplit2 = m_pSplits[1];
3316       hsplit = m_pSplits[2];
3317       hsplit2 = m_pSplits[3];
3318
3319       g_PrefsDlg.mWindowInfo.nXYHeight  = GTK_PANED (vsplit)->child1_size;
3320       g_PrefsDlg.mWindowInfo.nXYWidth   = GTK_PANED (hsplit2)->child1_size;
3321
3322       if(CurrentStyle() == eRegular)
3323         g_PrefsDlg.mWindowInfo.nZWidth = GTK_PANED (hsplit)->child1_size;
3324       else
3325         g_PrefsDlg.mWindowInfo.nCamWidth = GTK_PANED (hsplit)->child1_size;
3326
3327       g_PrefsDlg.mWindowInfo.nCamHeight = GTK_PANED (vsplit2)->child1_size;
3328     } else
3329     {
3330       if (g_PrefsDlg.m_bFloatingZ || CurrentStyle() == eSplit)
3331       {
3332         if (GTK_WIDGET_VISIBLE (m_pZWnd->m_pParent))
3333           g_PrefsDlg.m_bZVis = TRUE;
3334         else
3335           g_PrefsDlg.m_bZVis = FALSE;
3336       }
3337     }
3338     g_PrefsDlg.SavePrefs();
3339     Sys_Printf("Done prefs\n");
3340   }
3341
3342   // spog - this may be better in another place..
3343   // deletes filters list and assigns g_qeglobals.d_savedinfo.filters = NULL
3344   g_qeglobals.d_savedinfo.filters = FilterListDelete(g_qeglobals.d_savedinfo.filters);
3345
3346   delete m_pXYWnd; m_pXYWnd = NULL;
3347   delete m_pYZWnd; m_pYZWnd = NULL;
3348   delete m_pXZWnd; m_pXZWnd = NULL;
3349   delete m_pZWnd; m_pZWnd = NULL;
3350   delete m_pTexWnd; m_pTexWnd = NULL;
3351   delete m_pCamWnd; m_pCamWnd = NULL;
3352
3353   if (g_pGroupDlg->m_pWidget)
3354   {
3355     //!\todo fix "Gtk-CRITICAL **: file gtknotebook.c: line 4643 (gtk_notebook_get_tab_label): assertion `GTK_IS_WIDGET (child)' failed"
3356     gtk_widget_destroy (g_pGroupDlg->m_pWidget);
3357     g_pGroupDlg->m_pWidget = NULL;
3358   }
3359
3360   if (strcmpi(currentmap, "unnamed.map") != 0)
3361   {
3362     g_PrefsDlg.m_strLastMap = currentmap;
3363     g_PrefsDlg.SavePrefs ();
3364   }
3365   Sys_Printf("CleanUpEntities...");
3366   CleanUpEntities();
3367   Sys_Printf("Done.\n");
3368
3369   Sys_Printf("Releasing brushes...");
3370   while (active_brushes.next != &active_brushes)
3371     Brush_Free (active_brushes.next, false);
3372   while (selected_brushes.next != &selected_brushes)
3373     Brush_Free (selected_brushes.next, false);
3374   while (filtered_brushes.next != &filtered_brushes)
3375     Brush_Free (filtered_brushes.next, false);
3376   Sys_Printf("Done.\n");
3377
3378   Sys_Printf("Releasing entities...");
3379   while (entities.next != &entities)
3380     Entity_Free (entities.next);
3381   Sys_Printf("Done.\n");
3382
3383   epair_t* pEPair = g_qeglobals.d_project_entity->epairs;
3384   while (pEPair)
3385   {
3386     epair_t* pNextEPair = pEPair->next;
3387     free (pEPair->key);
3388     free (pEPair->value);
3389     free (pEPair);
3390     pEPair = pNextEPair;
3391   }
3392
3393   entity_t* pEntity = g_qeglobals.d_project_entity->next;
3394   while (pEntity != NULL && pEntity != g_qeglobals.d_project_entity)
3395   {
3396     entity_t* pNextEntity = pEntity->next;
3397     Entity_Free(pEntity);
3398     pEntity = pNextEntity;
3399   }
3400
3401   Sys_Printf("Freeing world entity...");
3402   if (world_entity)
3403     Entity_Free(world_entity);
3404   Sys_Printf("Done.\n");
3405
3406   Sys_Printf("Shutdown VFS...");
3407   vfsShutdown ();
3408   Sys_Printf("Done.\n");
3409
3410   Sys_Printf("FreeShaders...");
3411   QERApp_FreeShaders();
3412   Sys_Printf("Done.\n");
3413 }
3414
3415 // TTimo: now using profile.cpp code
3416 void MainFrame::LoadCommandMap()
3417 {
3418   FILE *f;
3419   CString strINI;
3420   bool bUserCmdList = false;
3421   int nLen;
3422   // verbose a little: count of user commands we recognized
3423   int iCount = 0;
3424   int iOverrideCount = 0;
3425   int j;
3426
3427
3428 #if defined (__linux__) || defined (__APPLE__)
3429   strINI = g_PrefsDlg.m_rc_path->str;
3430 #elif defined(WIN32)
3431   strINI = g_strGameToolsPath;
3432 #else
3433 #error "WTF are you compiling this on"
3434 #endif
3435   AddSlash (strINI);
3436   strINI += "shortcuts.ini";
3437
3438   f = fopen (strINI.GetBuffer(), "r");
3439   if (f != NULL)
3440   {
3441     fclose(f);
3442     // loop through all the commands
3443     for (int i = 0; i < g_nCommandCount; i++)
3444     {
3445       char value[1024];
3446       if (read_var( strINI.GetBuffer(), "Commands", g_Commands[i].m_strCommand, value ))
3447       {
3448         if (!bUserCmdList)
3449         {
3450           Sys_Printf("Found user's shortcuts list at %s\n", strINI.GetBuffer() );
3451           bUserCmdList = true;
3452         }
3453         CString strBuff;
3454         strBuff = value;
3455         strBuff.TrimLeft();
3456         strBuff.TrimRight();
3457         strBuff.MakeLower();
3458         int nSpecial = strBuff.Find("+alt");
3459         g_Commands[i].m_nModifiers = 0;
3460         if (nSpecial >= 0)
3461         {
3462           g_Commands[i].m_nModifiers |= RAD_ALT;
3463           FindReplace(strBuff, "+alt", "");
3464         }
3465         nSpecial = strBuff.Find("+ctrl");
3466         if (nSpecial >= 0)
3467         {
3468           g_Commands[i].m_nModifiers |= RAD_CONTROL;
3469           FindReplace(strBuff, "+ctrl", "");
3470         }
3471         nSpecial = strBuff.Find("+shift");
3472         if (nSpecial >= 0)
3473         {
3474           g_Commands[i].m_nModifiers |= RAD_SHIFT;
3475           FindReplace(strBuff, "+shift", "");
3476         }
3477         strBuff.TrimLeft();
3478         strBuff.TrimRight();
3479         strBuff.MakeUpper();
3480         // strBuff has been cleaned of it's modifiers .. switch between a regular key and a virtual one
3481         // based on length
3482         nLen = strBuff.GetLength();
3483         if (nLen == 1) // most often case.. deal with first
3484         {
3485           g_Commands[i].m_nKey = __toascii(strBuff.GetAt(0));
3486           iCount++;
3487         } else // special key
3488         {
3489           for (j = 0; j < g_nKeyCount; j++)
3490           {
3491             if (strBuff.CompareNoCase(g_Keys[j].m_strName) == 0)
3492             {
3493               g_Commands[i].m_nKey = g_Keys[j].m_nVKKey;
3494               iCount++;
3495               break;
3496             }
3497           }
3498           if (j == g_nKeyCount)
3499           {
3500             Sys_Printf("WARNING: failed to parse user command %s\n", value);
3501             continue;
3502           }
3503         }
3504         // maybe this new shortcut is overriding another one
3505         // then we need to disable the other binded key
3506         for (j = 0; j < g_nCommandCount; j++)
3507         {
3508           if (j == i)
3509             continue;
3510           if (g_Commands[i].m_nKey == g_Commands[j].m_nKey && g_Commands[i].m_nModifiers == g_Commands[j].m_nModifiers)
3511           {
3512             // found!
3513             g_Commands[j].m_nKey = 0;
3514             // verbose
3515             iOverrideCount++;
3516             // it's the only one
3517             break;
3518           }
3519         }
3520       }
3521     }
3522     if (iOverrideCount)
3523       Sys_Printf("User's command list overrides %d default commands\n", iOverrideCount);
3524     Sys_Printf("Parsed %d custom shortcuts\n", iCount );
3525   }
3526   else
3527     Sys_Printf("Looked for a '%s' keyboard shortcuts file, not found\n", strINI.GetBuffer());
3528 }
3529
3530 // TTimo: an m_nKey can be set to zero if there's no shorcut binded
3531 // we also output the count of commands that are not binded .. dunno if it's much use ..
3532 // (non-binded keys are usually keys that were defined by shortcuts overriden by user prefs)
3533 void MainFrame::ShowMenuItemKeyBindings(GtkWidget* window)
3534 {
3535   //!\todo Find a better way to get the global accelerator group..
3536   GtkAccelGroup *accel = GTK_ACCEL_GROUP(gtk_accel_groups_from_object(G_OBJECT(window))->data);
3537   gpointer item;
3538   guint mods;
3539   int i;
3540   int iCount = 0;
3541
3542   for (i = 0; i < g_nCommandCount; i++)
3543   {
3544     if (g_Commands[i].m_nKey == 0)
3545     {
3546       iCount++;
3547       continue;
3548     }
3549
3550     item = g_object_get_data (G_OBJECT (m_pWidget), g_Commands[i].m_strMenu);
3551     if (item == NULL)
3552     {
3553       Sys_FPrintf (SYS_WRN, "WARNING: keyboard shortcuts init, no menu item found for command: \"%s\"\n",
3554                    g_Commands[i].m_strCommand);
3555       continue;
3556     }
3557
3558     mods = 0;
3559     if (g_Commands[i].m_nModifiers)     // are there modifiers present?
3560     {
3561       if (g_Commands[i].m_nModifiers & RAD_SHIFT)
3562         mods |= GDK_SHIFT_MASK;
3563       if (g_Commands[i].m_nModifiers & RAD_ALT)
3564         mods |= GDK_MOD1_MASK;
3565       if (g_Commands[i].m_nModifiers & RAD_CONTROL)
3566         mods |= GDK_CONTROL_MASK;
3567     }
3568
3569     // GTK won't add accelerators for some keys (ex.: delete), so we have to do it manually
3570     if (gtk_accelerator_valid (g_Commands[i].m_nKey, (GdkModifierType)mods))
3571     {
3572 #ifdef DBG_KBD
3573       // NOTE TTimo this is the important place where all the shortcuts are binded
3574       Sys_Printf("Calling gtk_widget_add_accelerator on command: %s menu: %s key: %d mods: %d\n", g_Commands[i].m_strCommand, g_Commands[i].m_strMenu, g_Commands[i].m_nKey, mods);
3575 #endif
3576       gtk_widget_add_accelerator (GTK_WIDGET (item), "activate", accel, g_Commands[i].m_nKey,
3577                                   (GdkModifierType)mods, GTK_ACCEL_VISIBLE);
3578     } else
3579     {
3580       GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (GTK_BIN (item)->child);
3581       GString *gstring;
3582       gboolean had_mod;
3583
3584       g_free (accel_label->accel_string);
3585       accel_label->accel_string = NULL;
3586
3587       gstring = g_string_new (accel_label->accel_string);
3588       g_string_append (gstring, "   ");
3589
3590       had_mod = FALSE;
3591       if (mods & GDK_SHIFT_MASK)
3592       {
3593         g_string_append (gstring, "Shft");
3594         had_mod = TRUE;
3595       }
3596       if (mods & GDK_CONTROL_MASK)
3597       {
3598         if (had_mod)
3599           g_string_append (gstring, "+");
3600         g_string_append (gstring, "Ctl");
3601         had_mod = TRUE;
3602       }
3603       if (mods & GDK_MOD1_MASK)
3604       {
3605         if (had_mod)
3606           g_string_append (gstring, "+");
3607         g_string_append (gstring, "Alt");
3608         had_mod = TRUE;
3609       }
3610
3611       if (had_mod)
3612         g_string_append (gstring, "+");
3613       if (g_Commands[i].m_nKey < 0x80 || (g_Commands[i].m_nKey > 0x80 && g_Commands[i].m_nKey <= 0xff))
3614       {
3615         switch (g_Commands[i].m_nKey)
3616         {
3617         case ' ':
3618           g_string_append (gstring, "Space");
3619           break;
3620         case '\\':
3621           g_string_append (gstring, "Backslash");
3622           break;
3623         default:
3624           g_string_append_c (gstring, toupper (g_Commands[i].m_nKey));
3625           break;
3626         }
3627       } else
3628       {
3629         gchar *tmp;
3630
3631         tmp = gtk_accelerator_name (g_Commands[i].m_nKey, (GdkModifierType)0);
3632         if (tmp[0] != 0 && tmp[1] == 0)
3633           tmp[0] = toupper (tmp[0]);
3634         g_string_append (gstring, tmp);
3635         g_free (tmp);
3636       }
3637
3638       g_free (accel_label->accel_string);
3639       accel_label->accel_string = gstring->str;
3640       g_string_free (gstring, FALSE);
3641
3642       if (!accel_label->accel_string)
3643         accel_label->accel_string = g_strdup ("");
3644
3645       gtk_widget_queue_resize (GTK_WIDGET (accel_label));
3646     }
3647   }
3648
3649   if (iCount)
3650     Sys_Printf("%d commands not bound to a key\n", iCount);
3651 }
3652
3653 void MainFrame::CreateQEChildren()
3654 {
3655   // load the project file
3656   if (g_argc > 1)
3657   {
3658     Sys_Printf("loading project file from the command line: %s\n", g_argv[1]);
3659     if (!QE_LoadProject(g_argv[1]))
3660       Error("Unable to load project file %s\n", g_argv[1]);
3661   }
3662   else
3663   {
3664     const char* filename = NULL;
3665     char buf[PATH_MAX];
3666     const char *r;
3667     bool bTriedTemplate = false;
3668     
3669     if (g_PrefsDlg.m_nLastProjectVer != 0 && g_PrefsDlg.m_nLastProjectVer != PROJECT_VERSION) {
3670       // we need to regenerate from template
3671       Sys_Printf("last project has version %d, this binary wants version %d - regenerating from the template\n", g_PrefsDlg.m_nLastProjectVer, PROJECT_VERSION);
3672       g_PrefsDlg.m_strLastProject = "";
3673     }
3674     
3675     r = g_PrefsDlg.m_strLastProject.GetBuffer();    
3676     
3677     while(r == NULL || *r == '\0' || access(r, R_OK) != 0 || !QE_LoadProject(r))
3678     {
3679       if(!bTriedTemplate)
3680       {
3681         // try default project location
3682         bTriedTemplate = true;
3683         // for all OSes, we look for the template in the base installation (no homepath here)
3684         strcpy(buf, g_pGameDescription->mEnginePath.GetBuffer());
3685         strcat(buf, g_pGameDescription->mBaseGame.GetBuffer());
3686         strcat(buf, "/scripts/");
3687         strcat(buf, PROJECT_TEMPLATE_NAME);
3688         r = buf;
3689       }
3690       else
3691       {
3692         gtk_MessageBox (NULL, "Failed to load project file.\nPlease enter a valid project file.", "Load Project");
3693
3694         filename = file_dialog (m_pWidget, TRUE, "Choose Project File", buf, "project");
3695         if (filename != NULL)
3696           r = filename;
3697         else
3698           Error("Cannot continue without loading a project...");
3699       }
3700     }
3701   }
3702
3703   QE_Init ();
3704 }
3705
3706 void MainFrame::OnTimer() 
3707 {
3708   GdkModifierType mask;
3709
3710   gdk_window_get_pointer (NULL, NULL, NULL, &mask);
3711
3712   if ((mask & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK)) == 0)
3713   {
3714     QE_CountBrushesAndUpdateStatusBar();
3715     QE_CheckAutoSave();
3716   }
3717
3718   // see MainFrame::UpdateStatusText below
3719   if (m_bNeedStatusUpdate)
3720   {
3721     for (int n = 0; n < 6; n++)
3722     {
3723       if (m_strStatus[n].GetLength() >= 0 && m_pStatusLabel[n] != NULL)
3724         gtk_label_set_text (GTK_LABEL (m_pStatusLabel[n]), m_strStatus[n]);
3725     }
3726     m_bNeedStatusUpdate = false;
3727   }
3728 }
3729
3730 void MainFrame::UpdateStatusText()
3731 {
3732   m_bNeedStatusUpdate = true;
3733 }
3734
3735 void MainFrame::SetStatusText(int nPane, const char* pText)
3736 {
3737   if (pText && nPane <= 5 && nPane >= 0)
3738   {
3739     m_strStatus[nPane] = pText;
3740     UpdateStatusText();
3741   }
3742 }
3743 void MainFrame::SetButtonMenuStates()
3744 {
3745   GtkWidget *item;
3746   g_bIgnoreCommands++;
3747
3748   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showangles"));
3749   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_angles);
3750   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_shownames"));
3751   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_names);
3752   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showcoordinates"));
3753   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_coordinates);
3754   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showoutline"));
3755   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_outline);
3756   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_selection_nooutline"));
3757   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_qeglobals.d_savedinfo.iSelectedOutlinesStyle & OUTLINE_ZBUF));
3758   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showaxes"));
3759   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_axis);
3760   //item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showpath"));
3761   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3762                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) ? FALSE : TRUE);
3763   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_clusterportals"));
3764   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3765                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLUSTERPORTALS) != 0);
3766   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_lightgrid"));
3767   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3768                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTGRID) != 0);  
3769   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_world"));
3770   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3771                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD) != 0);
3772   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_entities"));
3773   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3774                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT) != 0);
3775   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_areaportals"));
3776   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3777                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_AREAPORTALS) != 0);
3778   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_translucent"));
3779   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3780                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_TRANSLUCENT) != 0);
3781   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_liquids"));
3782   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3783                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIQUIDS) != 0);
3784   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_caulk"));
3785   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3786                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) != 0);
3787   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_clips"));
3788   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3789                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP) != 0);
3790   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_botclips"));
3791   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3792                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_BOTCLIP) != 0);    
3793   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_structural"));
3794   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3795                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_STRUCTURAL) != 0);
3796   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_paths"));
3797   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3798                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) != 0);
3799   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_clusterportals"));
3800   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3801                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLUSTERPORTALS) != 0);
3802   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_lightgrid"));
3803   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3804                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTGRID) != 0);
3805   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_lights"));
3806   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3807                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS) != 0);
3808   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_patches"));
3809   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3810                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CURVES) != 0);
3811   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_details"));
3812   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3813                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DETAILS) != 0);
3814   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_hintsskips"));
3815   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3816                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_HINTSSKIPS) != 0);
3817   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_models"));
3818   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3819                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_MODELS) != 0);
3820   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_triggers"));
3821   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3822                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_TRIGGERS) != 0);
3823   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_toggle_lock"));
3824   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bTextureLock) ? TRUE : FALSE);
3825   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_toggle_rotatelock"));
3826   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bRotateLock) ? TRUE : FALSE);
3827   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_cubicclipping"));
3828   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bCubicClipping) ? TRUE : FALSE);
3829   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_opengllighting"));
3830   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bGLLighting) ? TRUE : FALSE);
3831   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
3832   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (!g_PrefsDlg.m_bNoClamp) ? TRUE : FALSE);
3833
3834   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_view_cubicclipping"));
3835   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bCubicClipping) ? TRUE : FALSE);
3836   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_dontselectmodel"));
3837   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bSelectModels) ? FALSE : TRUE);
3838
3839   if (!g_pGameDescription->mNoPatch)
3840   {
3841     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_dontselectcurve"));
3842     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bSelectCurves) ? FALSE : TRUE);
3843
3844     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_showboundingbox"));
3845     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchShowBounds) ? TRUE : FALSE);
3846     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_weld"));
3847     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchWeld) ? TRUE : FALSE);
3848     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_drilldown"));
3849     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchDrillDown) ? TRUE : FALSE);
3850   }
3851
3852   int id, n = g_PrefsDlg.m_nTextureScale;
3853   switch (n)
3854   {
3855   case 10 : id = ID_TEXTURES_TEXTUREWINDOWSCALE_10; break;
3856   case 25 : id = ID_TEXTURES_TEXTUREWINDOWSCALE_25; break;
3857   case 50 : id = ID_TEXTURES_TEXTUREWINDOWSCALE_50; break;
3858   case 200 : id = ID_TEXTURES_TEXTUREWINDOWSCALE_200; break;
3859   default : id = ID_TEXTURES_TEXTUREWINDOWSCALE_100; break;
3860   }
3861   SetTextureScale (id);
3862
3863   // FIXME TTimo cleaned up .. the right place to do this in QE_LoadProject?
3864 /*
3865   if (g_qeglobals.d_project_entity)
3866   {
3867     FillTextureMenu();      // redundant but i'll clean it up later.. yeah right.. 
3868     FillBSPMenu();
3869   }
3870   */
3871   g_bIgnoreCommands--;
3872 }
3873
3874 void MainFrame::UpdateWindows(int nBits)
3875 {
3876   if (!g_bScreenUpdates)
3877     return;
3878 #ifdef DBG_WINDOWPOS
3879   static int bean_count = 0;
3880   char bean_buf[100];
3881   sprintf(bean_buf,"UpdateWindows %d",bean_count);
3882   CheckWatchit(bean_buf);
3883   bean_count++;
3884 #endif
3885
3886   if (nBits & (W_XY | W_XY_OVERLAY))
3887   {
3888     if (m_pXYWnd)
3889       m_pXYWnd->RedrawWindow ();
3890     if (m_pXZWnd)
3891       m_pXZWnd->RedrawWindow ();
3892     if (m_pYZWnd)
3893       m_pYZWnd->RedrawWindow ();
3894   }
3895
3896   if (nBits & W_CAMERA || ((nBits & W_CAMERA_IFON) && m_bCamPreview))
3897   {
3898     if (m_pCamWnd)
3899       m_pCamWnd->RedrawWindow ();
3900   }
3901
3902   if (nBits & (W_Z | W_Z_OVERLAY))
3903   {
3904     if (m_pZWnd)
3905       m_pZWnd->RedrawWindow ();
3906   }
3907
3908   if (nBits & W_TEXTURE)
3909   {
3910     if (m_pTexWnd)
3911       m_pTexWnd->RedrawWindow ();
3912   }
3913 #ifdef DBG_WINDOWPOS
3914   sprintf(bean_buf,"%d (end UpdateWidows)",bean_count);
3915   CheckWatchit(bean_buf);
3916 #endif
3917 }
3918
3919 void MainFrame::RoutineProcessing()
3920 {
3921 #ifdef DBG_WINDOWPOS
3922   static int bean_count = 0;
3923   char bean_buf[100];
3924   sprintf(bean_buf,"RoutineProcessing %d",bean_count);
3925   CheckWatchit(bean_buf);
3926   bean_count++;
3927 #endif
3928
3929   if (m_bDoLoop)
3930   {
3931     double time = 0.0;
3932     double oldtime = 0.0;
3933     double delta= 0.0;
3934
3935 /*    // checking KeyState works right
3936     static short a1,a2;
3937     a2 = GetKeyState(VK_MENU);
3938     if (a1!=a2)
3939     {
3940       Sys_Printf("VK_MENU: %d\n",a2);
3941       a1 = a2;
3942     }
3943     static short b1,b2;
3944     b2 = GetKeyState(VK_UP);
3945     if (b1!=b2)
3946     {
3947       Sys_Printf("VK_UP: %d\n",b2);
3948       b1 = b2;
3949     } */
3950
3951     time = Sys_DoubleTime ();
3952     delta = time - oldtime;
3953     oldtime = time;
3954     if (delta > 0.2)
3955       delta = 0.2;
3956
3957     // update the BSP process watcher
3958     if (m_pWatchBSP)
3959       m_pWatchBSP->RoutineProcessing();
3960
3961     // run time dependant behavior
3962     if (m_pCamWnd)
3963       m_pCamWnd->Cam_MouseControl(delta);
3964
3965     if (g_nUpdateBits)
3966     {
3967       int nBits = g_nUpdateBits;      // this is done to keep this routine from being
3968       g_nUpdateBits = 0;              // re-entered due to the paint process.. only
3969       UpdateWindows(nBits);           // happens in rare cases but causes a stack overflow
3970     }
3971 /*
3972     // Enable/disable the menu items
3973     GtkWidget *item;
3974
3975     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_cameraupdate"));
3976     gtk_widget_set_sensitive (item, (m_bCamPreview == false));
3977     if (!g_PrefsDlg.m_bWideToolbar)
3978     {
3979       item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_view_cameraupdate"));
3980       gtk_widget_set_sensitive (item, (m_bCamPreview == false));
3981     }
3982     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_edit_undo"));
3983     gtk_widget_set_sensitive (item, Undo_UndoAvailable());
3984     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_edit_redo"));
3985     gtk_widget_set_sensitive (item, Undo_RedoAvailable());
3986     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_file_saveregion"));
3987     gtk_widget_set_sensitive (item, region_active);
3988     g_bIgnoreCommands++;
3989     // update the toolbar before displaying the menu:
3990     // show in use check box
3991     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_showinuse"));
3992     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), !g_bShowAllShaders);
3993     // show all check box
3994     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_showall"));
3995     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_bShowAllShaders);
3996     g_bIgnoreCommands--;
3997     */
3998   }
3999 #ifdef DBG_WINDOWPOS
4000   sprintf(bean_buf,"%d (end RoutineProcessing)",bean_count);
4001   CheckWatchit(bean_buf);
4002 #endif
4003 }
4004
4005 void MainFrame::DoWatchBSP()
4006 {
4007   // network monitoring of the BSP process
4008   if (!m_pWatchBSP)
4009     m_pWatchBSP = new CWatchBSP();
4010 }
4011
4012 void MainFrame::CleanPlugInMenu()
4013 {
4014   GtkWidget *menu, *sep;
4015   GList *lst;
4016
4017   // delete everything after the separator
4018   menu = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_plugin"));
4019   sep = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_plugin_separator"));
4020   m_nNextPlugInID = ID_PLUGIN_START;
4021
4022   lst = g_list_find (gtk_container_children (GTK_CONTAINER (menu)), sep);
4023   while (lst->next)
4024   {
4025     gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (lst->next->data));
4026     lst = g_list_find (gtk_container_children (GTK_CONTAINER (menu)), sep);
4027   }
4028 }
4029
4030 void MainFrame::AddPlugInMenuItem(IPlugIn* pPlugIn)
4031 {
4032   GtkWidget *menu, *item, *parent;
4033   const char *menuText;