GTK: wrap gtk_box_pack_start
[xonotic/netradiant.git] / contrib / hydratoolz / plugin.cpp
index 9e05e6d..43403d0 100644 (file)
-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-*/\r
-\r
-#include "plugin.h"\r
-#include "version.h"\r
-\r
-/*! \file plugin.cpp\r
-    \brief HydraToolz!\r
-\r
-    HydraToolz by Dominic Clifton - Hydra (Hydra@Hydras-World.com)\r
-\r
-    Overview\r
-    ========\r
-\r
-    This plugin allows the user to rebuild the "wad" key pair in the worldspawn\r
-    so that it has a list of all the .wad files in use.\r
-\r
-    Version History\r
-    ===============\r
-\r
-    v0.1 - 28/May/2002\r
-      - Initial version.\r
-\r
-    v1.0 - 10/March/2003\r
-      - Added more console output\r
-      - Removed some old test code\r
-      - Tweaked dialog box.\r
-      - Fixed up for Radiant 1.3.5\r
-\r
-\r
-    ToDo\r
-    ====\r
-\r
-    Nothing...\r
-\r
-*/\r
-\r
-// =============================================================================\r
-// Globals\r
-\r
-_QERFuncTable_1 g_FuncTable;\r
-_QERFileSystemTable g_FileSystemTable;\r
-_QEREntityTable g_EntityTable;\r
-\r
-\r
-// =============================================================================\r
-// Ripped from cmdlib.cpp\r
-\r
-/*\r
-====================\r
-Extract file parts\r
-====================\r
-*/\r
-void ExtractFilePath (const char *path, char *dest)\r
-{\r
-  const char *src;\r
-\r
-  src = path + strlen(path) - 1;\r
-\r
-//\r
-// back up until a \ or the start\r
-//\r
-  while (src != path && *(src-1) != '/' && *(src-1) != '\\')\r
-    src--;\r
-\r
-  memcpy (dest, path, src-path);\r
-  dest[src-path] = 0;\r
-}\r
-\r
-void ExtractFileName (const char *path, char *dest)\r
-{\r
-  const char *src;\r
-\r
-  src = path + strlen(path) - 1;\r
-\r
-//\r
-// back up until a \ or the start\r
-//\r
-  while (src != path && *(src-1) != '/'\r
-         && *(src-1) != '\\' )\r
-    src--;\r
-\r
-  while (*src)\r
-  {\r
-    *dest++ = *src++;\r
-  }\r
-  *dest = 0;\r
-}\r
-\r
-void ConvertDOSToUnixName( char *dst, const char *src )\r
-{\r
-  while ( *src )\r
-  {\r
-    if ( *src == '\\' )\r
-      *dst = '/';\r
-    else\r
-      *dst = *src;\r
-    dst++; src++;\r
-  }\r
-  *dst = 0;\r
-}\r
-\r
-// End of rip from cmdlib.cpp\r
-\r
-// =============================================================================\r
-// Actual Plugin Code\r
-\r
-// get the wad name from the shader name (or an actual wadname) and add to a list of wad names making\r
-// sure we don't add duplicates.\r
-\r
-GSList *AddToWadList(GSList *wadlist, const char *shadername, const char *wad)\r
-{\r
-  char tmpstr[QER_MAX_NAMELEN];\r
-  char *wadname;\r
-  if (!shadername && !wad) return wadlist;\r
-\r
-  if (shadername)\r
-  {\r
-    if (strcmp(shadername,"color") == 0)\r
-      return wadlist;\r
-    ExtractFilePath(shadername,tmpstr);\r
-    // Sys_Printf("checking: %s\n",shadername);\r
-\r
-    int l = strlen(tmpstr) - 1;\r
-\r
-    if (tmpstr[l] == '/' || tmpstr[l] == '\\')\r
-      tmpstr[l] = 0;\r
-    else\r
-    {\r
-      Sys_Printf("HydraToolz: WARNING: Unknown wad file for shader %s\n",shadername);\r
-      return wadlist;\r
-    }\r
-\r
-    ExtractFileName(tmpstr,tmpstr);\r
-\r
-    wadname = (char *)malloc(strlen(tmpstr) + 5);\r
-    sprintf(wadname,"%s.wad",tmpstr);\r
-  }\r
-  else\r
-  {\r
-    wadname=strdup(wad);\r
-  }\r
-\r
-  for (GSList *l = wadlist; l != NULL ; l = l->next)\r
-  {\r
-    if (!stricmp((char *)l->data,wadname))\r
-    {\r
-      free( wadname );\r
-      return wadlist;\r
-    }\r
-  }\r
-\r
-  Sys_Printf("HydraToolz: Adding Wad File to WAD list: %s (reason: ",wadname);\r
-  if (shadername)\r
-    Sys_Printf("see shader \"%s\")\n", shadername);\r
-  else\r
-    Sys_Printf("already in WAD key. )\n");\r
-  return ( g_slist_append (wadlist, wadname ) );\r
-}\r
-\r
-void UpdateWadKeyPair( void )\r
-{\r
-  int i,nb;\r
-\r
-  char wads[2048]; // change to CString usage ?\r
-  *wads = 0;\r
-  char *p1,*p2;\r
-  entity_t *pEntity;\r
-  epair_t *pEpair;\r
-  GSList *wadlist = NULL;\r
-  face_t  *f;\r
-  brush_t *b;\r
-  char cleanwadname[QER_MAX_NAMELEN];\r
-  char *actualwad;\r
-\r
-\r
-  pEntity = (entity_t *)g_FuncTable.m_pfnGetEntityHandle(0); // get the worldspawn ent\r
-\r
-  Sys_Printf("HydraToolz: Searching for in-use wad files...\n");\r
-  for(pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next)\r
-  {\r
-    if (stricmp(pEpair->key,"wad") == 0)\r
-    {\r
-      strcpy(wads,pEpair->value);\r
-      ConvertDOSToUnixName(wads,wads);\r
-\r
-      Sys_Printf("HydraToolz: Current wad key is \"%s\"!\n",wads);\r
-\r
-      // ok, we got the list of ; delimited wads, now split it into a GSList that contains\r
-      // just the wad names themselves.\r
-\r
-      p1 = wads;\r
-\r
-      do\r
-      {\r
-        p2 = strchr(p1,';');\r
-        if (p2)\r
-          *p2 = 0; // swap the ; with a null terminator\r
-\r
-        if (strchr(p1,'/') || strchr(p1,'\\'))\r
-        {\r
-          ExtractFileName(p1,cleanwadname);\r
-          wadlist = AddToWadList (wadlist, NULL, cleanwadname);\r
-        }\r
-        else\r
-        {\r
-          wadlist = AddToWadList (wadlist, NULL, p1);\r
-        }\r
-        if (p2)\r
-          p1 = p2+1; // point back to the remainder of the string\r
-        else\r
-          p1 = NULL; // make it so we exit the loop.\r
-\r
-      } while (p1);\r
-\r
-      // ok, now we have a list of wads in GSList.\r
-      // now we need to add any new wadfiles (with their paths) to this list\r
-      // so scan all brushes and see what wads are in use\r
-      // FIXME: scan brushes only in the region ?\r
-\r
-      break; // we don't need to process any more key/pairs.\r
-    }\r
-  }\r
-\r
-  if (!*wads)\r
-    Sys_Printf("HydraToolz: No \"wad\" keypair wound in worldspawn\n");\r
-\r
-\r
-  nb = g_FuncTable.m_pfnAllocateActiveBrushHandles();\r
-  for( i = 0; i < nb; i++ )\r
-       {\r
-    b = (brush_t *)g_FuncTable.m_pfnGetActiveBrushHandle(i);\r
-    if (b->patchBrush) // patches in halflife ?\r
-    {\r
-      wadlist = AddToWadList(wadlist, b->pPatch->pShader->getName(),NULL);\r
-    } else\r
-    {\r
-      for (f=b->brush_faces ; f ; f=f->next)\r
-      {\r
-        wadlist = AddToWadList(wadlist, f->pShader->getName(),NULL);\r
-      }\r
-    }\r
-  }\r
-  g_FuncTable.m_pfnReleaseActiveBrushHandles();\r
-\r
-  nb = g_FuncTable.m_pfnAllocateSelectedBrushHandles();\r
-  for( i = 0; i < nb; i++ )\r
-       {\r
-    b = (brush_t *)g_FuncTable.m_pfnGetSelectedBrushHandle(i);\r
-    if (b->patchBrush) // patches in halflife ?\r
-    {\r
-      wadlist = AddToWadList(wadlist, b->pPatch->pShader->getName(),NULL);\r
-    } else\r
-    {\r
-      for (f=b->brush_faces ; f ; f=f->next)\r
-      {\r
-        wadlist = AddToWadList(wadlist, f->pShader->getName(),NULL);\r
-      }\r
-    }\r
-  }\r
-  g_FuncTable.m_pfnReleaseSelectedBrushHandles();\r
-\r
-  Sys_Printf("HydraToolz: Rebuilding worldspawn's \"wad\" key-pair...\n");\r
-  // Now we have a complete list of wadnames (without paths) so we just have to turn this\r
-  // back to a ; delimited list.\r
-\r
-  *wads = 0;\r
-  while (wadlist)\r
-  {\r
-    // skip wad files if they start with "common-"\r
-    if (strnicmp((char *)wadlist->data,"common-",7) == 0)\r
-    {\r
-      Sys_Printf("HydraToolz: Skipping radiant/user-supplied wad file %s\n",(char *)wadlist->data);\r
-    }\r
-    else\r
-    {\r
-      if (wads[0])\r
-        strcat(wads,";");\r
-\r
-      actualwad = vfsGetFullPath((char *)wadlist->data);\r
-\r
-      if (actualwad)\r
-      {\r
-        strcat(wads, actualwad);\r
-      }\r
-      else\r
-      {\r
-        Sys_Printf("HydraToolz: WARNING: could not locate wad file %s\n",(char *)wadlist->data);\r
-        strcat(wads, (char *)wadlist->data);\r
-      }\r
-    }\r
-\r
-    free (wadlist->data);\r
-    wadlist = g_slist_remove (wadlist, wadlist->data);\r
-  }\r
-\r
-  // store the wad list back in the worldspawn.\r
-  if (*wads)\r
-  {\r
-    //free(pEpair->value);\r
-    //pEpair->value = strdup(wads);\r
-    SetKeyValue(pEntity, "wad", wads);\r
-    Sys_Printf("HydraToolz: Setting worldspawn \"wad\" key value to \"%s\"\n",wads);\r
-\r
-  }\r
-\r
-  Sys_Printf("HydraToolz: Finished rebuilding wad keypair!\n");\r
-\r
-}\r
-\r
-// =============================================================================\r
-// PLUGIN INTERFACE STUFF\r
-\r
-// plugin name\r
-const char *PLUGIN_NAME = "HydraToolz";\r
-\r
-// commands in the menu\r
-const char *PLUGIN_COMMANDS = "About...;Create/Update WAD keypair";\r
-\r
-const char *PLUGIN_ABOUT = "HydraToolz v1.0 for GTKRadiant\n\n"\r
-                           "By Hydra!";\r
-\r
-extern "C" void* WINAPI QERPlug_GetFuncTable ()\r
-{\r
-  return &g_FuncTable;\r
-}\r
-\r
-const char* QERPlug_Init (void* hApp, void *pWidget)\r
-{\r
-  return "HydraToolz for GTKRadiant"; // do we need this ? hmmm\r
-}\r
-\r
-const char* QERPlug_GetName()\r
-{\r
-  return (char*)PLUGIN_NAME;\r
-}\r
-\r
-const char* QERPlug_GetCommandList()\r
-{\r
-  return PLUGIN_COMMANDS;\r
-}\r
-\r
-extern "C" void QERPlug_Dispatch(const char* p, vec3_t vMin, vec3_t vMax, bool bSingleBrush)\r
-{\r
-       if(!strcmp(p, "Create/Update WAD keypair"))\r
-               UpdateWadKeyPair();\r
-       else if(!strcmp(p, "About..."))\r
-               g_FuncTable.m_pfnMessageBox(NULL, PLUGIN_ABOUT, "About", MB_OK, NULL);\r
-}\r
-\r
-// =============================================================================\r
-// SYNAPSE\r
-\r
-CSynapseServer* g_pSynapseServer = NULL;\r
-CSynapseClientHydraToolz g_SynapseClient;\r
-\r
-extern "C" CSynapseClient* SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces (const char *version, CSynapseServer *pServer)\r
-{\r
-  if (strcmp(version, SYNAPSE_VERSION))\r
-  {\r
-    Syn_Printf("ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version);\r
-    return NULL;\r
-  }\r
-  g_pSynapseServer = pServer;\r
-  g_pSynapseServer->IncRef();\r
-  Set_Syn_Printf(g_pSynapseServer->Get_Syn_Printf());\r
-\r
-  g_SynapseClient.AddAPI(PLUGIN_MAJOR, "HydraToolz", sizeof(_QERPluginTable));\r
-  g_SynapseClient.AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable);\r
-  g_SynapseClient.AddAPI(VFS_MAJOR, "wad", sizeof(g_FileSystemTable), SYN_REQUIRE, &g_FileSystemTable);\r
-  g_SynapseClient.AddAPI(ENTITY_MAJOR, NULL, sizeof(g_EntityTable), SYN_REQUIRE, &g_EntityTable);\r
-  return &g_SynapseClient;\r
-}\r
-\r
-bool CSynapseClientHydraToolz::RequestAPI(APIDescriptor_t *pAPI)\r
-{\r
-  if (!strcmp(pAPI->major_name, PLUGIN_MAJOR))\r
-  {\r
-    _QERPluginTable *pTable = static_cast<_QERPluginTable*>(pAPI->mpTable);\r
-    pTable->m_pfnQERPlug_Init = QERPlug_Init;\r
-    pTable->m_pfnQERPlug_GetName = QERPlug_GetName;\r
-    pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;\r
-    pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch;\r
-    return true;\r
-  }\r
-\r
-  Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());\r
-  return false;\r
-}\r
-\r
-const char* CSynapseClientHydraToolz::GetInfo()\r
-{\r
-  return "HydraToolz plugin built " __DATE__ " " RADIANT_VERSION;\r
-}\r
+/*
+   Copyright (C) 1999-2006 Id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   GtkRadiant is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "plugin.h"
+#include "version.h"
+
+/*! \file plugin.cpp
+    \brief HydraToolz!
+
+    HydraToolz by Dominic Clifton - Hydra (Hydra@Hydras-World.com)
+
+    Overview
+    ========
+
+
+    Version History
+    ===============
+
+    v0.1 - 28/May/2002
+      - Initial version.
+
+
+    ToDo
+    ====
+
+ * Code it ? :)
+
+ */
+
+// =============================================================================
+// Globals
+
+_QERFuncTable_1 g_FuncTable;
+_QERFileSystemTable g_FileSystemTable;
+_QEREntityTable g_EntityTable;
+
+// cast to GtkWidget*
+void *g_pMainWnd;
+
+// =============================================================================
+// Ripped from TexTool.cpp
+
+static void dialog_button_callback( GtkWidget *widget, gpointer data ){
+       GtkWidget *parent;
+       int *loop, *ret;
+
+       parent = gtk_widget_get_toplevel( widget );
+       loop = (int*)gtk_object_get_data( GTK_OBJECT( parent ), "loop" );
+       ret = (int*)gtk_object_get_data( GTK_OBJECT( parent ), "ret" );
+
+       *loop = 0;
+       *ret = gpointer_to_int( data );
+}
+
+static gint dialog_delete_callback( GtkWidget *widget, GdkEvent* event, gpointer data ){
+       int *loop;
+
+       gtk_widget_hide( widget );
+       loop = (int*)gtk_object_get_data( GTK_OBJECT( widget ), "loop" );
+       *loop = 0;
+
+       return TRUE;
+}
+
+int DoMessageBox( const char* lpText, const char* lpCaption, guint32 uType ){
+       GtkWidget *w, *hbox;
+       int mode = ( uType & MB_TYPEMASK ), ret, loop = 1;
+
+       auto window = ui::Window( ui::window_type::TOP );
+       window.connect( "delete_event",
+                                               G_CALLBACK( dialog_delete_callback ), NULL );
+       window.connect( "destroy",
+                                               G_CALLBACK( gtk_widget_destroy ), NULL );
+       gtk_window_set_title( GTK_WINDOW( window ), lpCaption );
+       gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
+       gtk_object_set_data( GTK_OBJECT( window ), "loop", &loop );
+       gtk_object_set_data( GTK_OBJECT( window ), "ret", &ret );
+       gtk_widget_realize( window );
+
+       auto vbox = ui::VBox( FALSE, 10 );
+       window.add(vbox);
+       vbox.show();
+
+       w = ui::Label( lpText );
+       vbox.pack_start( w, FALSE, FALSE, 2 );
+       gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT );
+       gtk_widget_show( w );
+
+       w = gtk_hseparator_new();
+       vbox.pack_start( w, FALSE, FALSE, 2 );
+       gtk_widget_show( w );
+
+       hbox = ui::HBox( FALSE, 10 );
+       vbox.pack_start( hbox, FALSE, FALSE, 2 );
+       gtk_widget_show( hbox );
+
+       if ( mode == MB_OK ) {
+               w = ui::Button( "Ok" );
+               hbox.pack_start( w, TRUE, TRUE, 0 );
+               w.connect( "clicked",
+                                                       G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
+               gtk_widget_set_can_default( w, true );
+               gtk_widget_grab_default( w );
+               gtk_widget_show( w );
+               ret = IDOK;
+       }
+       else if ( mode ==  MB_OKCANCEL ) {
+               w = ui::Button( "Ok" );
+               hbox.pack_start( w, TRUE, TRUE, 0 );
+               w.connect( "clicked",
+                                                       G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
+               gtk_widget_set_can_default( w, true );
+               gtk_widget_grab_default( w );
+               gtk_widget_show( w );
+
+               w = ui::Button( "Cancel" );
+               hbox.pack_start( w, TRUE, TRUE, 0 );
+               w.connect( "clicked",
+                                                       G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
+               gtk_widget_show( w );
+               ret = IDCANCEL;
+       }
+       else if ( mode == MB_YESNOCANCEL ) {
+               w = ui::Button( "Yes" );
+               hbox.pack_start( w, TRUE, TRUE, 0 );
+               w.connect( "clicked",
+                                                       G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDYES ) );
+               gtk_widget_set_can_default( w, true );
+               gtk_widget_grab_default( w );
+               gtk_widget_show( w );
+
+               w = ui::Button( "No" );
+               hbox.pack_start( w, TRUE, TRUE, 0 );
+               w.connect( "clicked",
+                                                       G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDNO ) );
+               gtk_widget_show( w );
+
+               w = ui::Button( "Cancel" );
+               hbox.pack_start( w, TRUE, TRUE, 0 );
+               w.connect( "clicked",
+                                                       G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
+               gtk_widget_show( w );
+               ret = IDCANCEL;
+       }
+       else /* if (mode == MB_YESNO) */
+       {
+               w = ui::Button( "Yes" );
+               hbox.pack_start( w, TRUE, TRUE, 0 );
+               w.connect( "clicked",
+                                                       G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDYES ) );
+               gtk_widget_set_can_default( w, true );
+               gtk_widget_grab_default( w );
+               gtk_widget_show( w );
+
+               w = ui::Button( "No" );
+               hbox.pack_start( w, TRUE, TRUE, 0 );
+               w.connect( "clicked",
+                                                       G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDNO ) );
+               gtk_widget_show( w );
+               ret = IDNO;
+       }
+
+       gtk_widget_show( window );
+       gtk_grab_add( window );
+
+       while ( loop )
+               gtk_main_iteration();
+
+       gtk_grab_remove( window );
+       window.destroy();
+
+       return ret;
+}
+
+// End of rip from TexTool.cpp
+
+// =============================================================================
+// Ripped from cmdlib.cpp
+
+/*
+   ====================
+   Extract file parts
+   ====================
+ */
+void ExtractFilePath( const char *path, char *dest ){
+       const char *src;
+
+       src = path + strlen( path ) - 1;
+
+//
+// back up until a \ or the start
+//
+       while ( src != path && *( src - 1 ) != '/' && *( src - 1 ) != '\\' )
+               src--;
+
+       memcpy( dest, path, src - path );
+       dest[src - path] = 0;
+}
+
+void ExtractFileName( const char *path, char *dest ){
+       const char *src;
+
+       src = path + strlen( path ) - 1;
+
+//
+// back up until a \ or the start
+//
+       while ( src != path && *( src - 1 ) != '/'
+                       && *( src - 1 ) != '\\' )
+               src--;
+
+       while ( *src )
+       {
+               *dest++ = *src++;
+       }
+       *dest = 0;
+}
+
+void ConvertDOSToUnixName( char *dst, const char *src ){
+       while ( *src )
+       {
+               if ( *src == '\\' ) {
+                       *dst = '/';
+               }
+               else{
+                       *dst = *src;
+               }
+               dst++; src++;
+       }
+       *dst = 0;
+}
+
+// End of rip from cmdlib.cpp
+
+// =============================================================================
+// Actual Plugin Code
+
+// get the wad name from the shader name (or an actual wadname) and add to a list of wad names making
+// sure we don't add duplicates.
+
+GSList *AddToWadList( GSList *wadlist, const char *shadername, const char *wad ){
+       char tmpstr[QER_MAX_NAMELEN];
+       char *wadname;
+       if ( !shadername && !wad ) {
+               return wadlist;
+       }
+
+       if ( shadername ) {
+               if ( strcmp( shadername,"color" ) == 0 ) {
+                       return wadlist;
+               }
+               ExtractFilePath( shadername,tmpstr );
+               // Sys_Printf("checking: %s\n",shadername);
+
+               int l = strlen( tmpstr ) - 1;
+
+               if ( tmpstr[l] == '/' || tmpstr[l] == '\\' ) {
+                       tmpstr[l] = 0;
+               }
+               else
+               {
+                       Sys_Printf( "WARNING: Unknown wad file for shader %s\n",shadername );
+                       return wadlist;
+               }
+
+               ExtractFileName( tmpstr,tmpstr );
+
+               wadname = (char *)malloc( strlen( tmpstr ) + 5 );
+               sprintf( wadname,"%s.wad",tmpstr );
+       }
+       else
+       {
+               wadname = strdup( wad );
+       }
+
+       for ( GSList *l = wadlist; l != NULL ; l = l->next )
+       {
+               if ( string_equal_nocase( (char *)l->data,wadname ) ) {
+                       free( wadname );
+                       return wadlist;
+               }
+       }
+
+       Sys_Printf( "Adding Wad File to WAD list: %s (reason: ",wadname );
+       if ( shadername ) {
+               Sys_Printf( "see shader \"%s\")\n", shadername );
+       }
+       else{
+               Sys_Printf( "already in WAD key. )\n" );
+       }
+       return ( g_slist_append( wadlist, wadname ) );
+}
+
+void UpdateWadKeyPair( void ){
+       int i,nb;
+
+       char wads[2048]; // change to CString usage ?
+       wads[0] = 0;
+       char *p1,*p2;
+       entity_t *pEntity;
+       epair_t *pEpair;
+       GSList *wadlist = NULL;
+       face_t  *f;
+       brush_t *b;
+       char cleanwadname[QER_MAX_NAMELEN];
+       const char *actualwad;
+
+
+       pEntity = (entity_t *)g_FuncTable.m_pfnGetEntityHandle( 0 ); // get the worldspawn ent
+
+       Sys_Printf( "Searching for in-use wad files...\n" );
+       for ( pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next )
+       {
+               if ( string_equal_nocase( pEpair->key,"wad" ) ) {
+                       strcpy( wads,pEpair->value );
+                       ConvertDOSToUnixName( wads,wads );
+
+                       // ok, we got the list of ; delimited wads, now split it into a GSList that contains
+                       // just the wad names themselves.
+
+                       p1 = wads;
+
+                       do
+                       {
+                               p2 = strchr( p1,';' );
+                               if ( p2 ) {
+                                       *p2 = 0; // swap the ; with a null terminator
+
+                               }
+                               if ( strchr( p1,'/' ) || strchr( p1,'\\' ) ) {
+                                       ExtractFileName( p1,cleanwadname );
+                                       wadlist = AddToWadList( wadlist, NULL, cleanwadname );
+                               }
+                               else
+                               {
+                                       wadlist = AddToWadList( wadlist, NULL, p1 );
+                               }
+                               if ( p2 ) {
+                                       p1 = p2 + 1; // point back to the remainder of the string
+                               }
+                               else{
+                                       p1 = NULL; // make it so we exit the loop.
+
+                               }
+                       } while ( p1 );
+
+                       // ok, now we have a list of wads in GSList.
+                       // now we need to add any new wadfiles (with their paths) to this list
+                       // so scan all brushes and see what wads are in use
+                       // FIXME: scan brushes only in the region ?
+
+                       break; // we don't need to process any more key/pairs.
+               }
+       }
+
+       nb = g_FuncTable.m_pfnAllocateActiveBrushHandles();
+       for ( i = 0; i < nb; i++ )
+       {
+               b = (brush_t *)g_FuncTable.m_pfnGetActiveBrushHandle( i );
+               if ( b->patchBrush ) { // patches in halflife ?
+                       wadlist = AddToWadList( wadlist, b->pPatch->pShader->getName(),NULL );
+               }
+               else
+               {
+                       for ( f = b->brush_faces ; f ; f = f->next )
+                       {
+                               wadlist = AddToWadList( wadlist, f->pShader->getName(),NULL );
+                       }
+               }
+       }
+       g_FuncTable.m_pfnReleaseActiveBrushHandles();
+
+       nb = g_FuncTable.m_pfnAllocateSelectedBrushHandles();
+       for ( i = 0; i < nb; i++ )
+       {
+               b = (brush_t *)g_FuncTable.m_pfnGetSelectedBrushHandle( i );
+               if ( b->patchBrush ) { // patches in halflife ?
+                       wadlist = AddToWadList( wadlist, b->pPatch->pShader->getName(),NULL );
+               }
+               else
+               {
+                       for ( f = b->brush_faces ; f ; f = f->next )
+                       {
+                               wadlist = AddToWadList( wadlist, f->pShader->getName(),NULL );
+                       }
+               }
+       }
+       g_FuncTable.m_pfnReleaseSelectedBrushHandles();
+
+       // Now we have a complete list of wadnames (without paths) so we just have to turn this
+       // back to a ; delimited list.
+
+       wads[0] = 0;
+       while ( wadlist )
+       {
+               if ( string_equal_nocase( (char *)wadlist->data,"common-hydra.wad" ) ) {
+                       Sys_Printf( "Skipping radiant-supplied wad file %s\n",(char *)wadlist->data );
+               }
+               else
+               {
+                       if ( wads[0] ) {
+                               strcat( wads,";" );
+                       }
+
+                       actualwad = vfsGetFullPath( (char *)wadlist->data );
+
+                       if ( actualwad ) {
+                               strcat( wads, actualwad );
+                       }
+                       else
+                       {
+                               Sys_Printf( "WARNING: could not locate wad file %s\n",(char *)wadlist->data );
+                               strcat( wads, (char *)wadlist->data );
+                       }
+               }
+
+               free( wadlist->data );
+               wadlist = g_slist_remove( wadlist, wadlist->data );
+       }
+
+       // store the wad list back in the worldspawn.
+       if ( wads[0] ) {
+               //free(pEpair->value);
+               //pEpair->value = strdup(wads);
+               SetKeyValue( pEntity, "wad", wads );
+       }
+
+}
+
+// =============================================================================
+// PLUGIN INTERFACE STUFF
+
+// plugin name
+const char *PLUGIN_NAME = "Q3 Texture Tools";
+
+// commands in the menu
+const char *PLUGIN_COMMANDS = "About...;Create/Update WAD keypair";
+
+const char *PLUGIN_ABOUT = "HydraToolz for GTKRadiant\n\n"
+                                                  "By Hydra!";
+
+extern "C" void* WINAPI QERPlug_GetFuncTable(){
+       return &g_FuncTable;
+}
+
+const char* QERPlug_Init( void* hApp, void *pWidget ){
+       GtkWidget* pMainWidget = static_cast<GtkWidget*>( pWidget );
+
+       g_pMainWnd = pMainWidget;
+       memset( &g_FuncTable, 0, sizeof( _QERFuncTable_1 ) );
+       g_FuncTable.m_nSize = sizeof( _QERFuncTable_1 );
+       return "HydraToolz for GTKRadiant"; // do we need this ? hmmm
+}
+
+const char* QERPlug_GetName(){
+       return (char*)PLUGIN_NAME;
+}
+
+const char* QERPlug_GetCommandList(){
+       return PLUGIN_COMMANDS;
+}
+
+extern "C" void QERPlug_Dispatch( const char* p, vec3_t vMin, vec3_t vMax, bool bSingleBrush ){
+       if ( !strcmp( p, "Create/Update WAD keypair" ) ) {
+               UpdateWadKeyPair();
+       }
+       else if ( !strcmp( p, "About..." ) ) {
+               g_FuncTable.m_pfnMessageBox( (GtkWidget*)NULL, PLUGIN_ABOUT, "About", eMB_OK );
+       }
+}
+
+// =============================================================================
+// SYNAPSE
+
+CSynapseServer* g_pSynapseServer = NULL;
+CSynapseClientHydraToolz g_SynapseClient;
+
+extern "C" CSynapseClient * SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ){
+       if ( strcmp( version, SYNAPSE_VERSION ) ) {
+               Syn_Printf( "ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version );
+               return NULL;
+       }
+       g_pSynapseServer = pServer;
+       g_pSynapseServer->IncRef();
+       Set_Syn_Printf( g_pSynapseServer->Get_Syn_Printf() );
+
+       g_SynapseClient.AddAPI( PLUGIN_MAJOR, "HydraToolz", sizeof( _QERPluginTable ) );
+       g_SynapseClient.AddAPI( RADIANT_MAJOR, NULL, sizeof( g_FuncTable ), SYN_REQUIRE, &g_FuncTable );
+       g_SynapseClient.AddAPI( VFS_MAJOR, "wad", sizeof( g_FileSystemTable ), SYN_REQUIRE, &g_FileSystemTable );
+       g_SynapseClient.AddAPI( ENTITY_MAJOR, NULL, sizeof( g_EntityTable ), SYN_REQUIRE, &g_EntityTable );
+       return &g_SynapseClient;
+}
+
+bool CSynapseClientHydraToolz::RequestAPI( APIDescriptor_t *pAPI ){
+       if ( !strcmp( pAPI->major_name, PLUGIN_MAJOR ) ) {
+               _QERPluginTable *pTable = static_cast<_QERPluginTable*>( pAPI->mpTable );
+               pTable->m_pfnQERPlug_Init = QERPlug_Init;
+               pTable->m_pfnQERPlug_GetName = QERPlug_GetName;
+               pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;
+               pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch;
+               return true;
+       }
+
+       Syn_Printf( "ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo() );
+       return false;
+}
+
+const char* CSynapseClientHydraToolz::GetInfo(){
+       return "HydraToolz plugin built " __DATE__ " " RADIANT_VERSION;
+}