move old gtk runtime code back to trunk

git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@361 8a3a26a2-13c4-0310-b231-cf6edde360e5
This commit is contained in:
TTimo 2010-12-26 04:13:09 +00:00
commit 82ef81821f
6 changed files with 303 additions and 204 deletions

View file

@ -273,7 +273,7 @@ class Config:
self.FetchGamePaks( self.install_directory ) self.FetchGamePaks( self.install_directory )
# NOTE: unrelated to self.setup_platforms - grab support files and binaries and install them # NOTE: unrelated to self.setup_platforms - grab support files and binaries and install them
if ( self.platform == 'Windows' ): if ( self.platform == 'Windows' ):
depsfile = 'GtkR-deps-1.6-6.zip' depsfile = 'GtkR-deps-1.6-3.zip'
if ( not os.path.exists( depsfile ) ): if ( not os.path.exists( depsfile ) ):
cmd = [ 'wget', '-N', 'http://zerowing.idsoftware.com/files/radiant/developer/1.6.1/%s' % depsfile ] cmd = [ 'wget', '-N', 'http://zerowing.idsoftware.com/files/radiant/developer/1.6.1/%s' % depsfile ]
print( repr( cmd ) ) print( repr( cmd ) )
@ -291,37 +291,28 @@ class Config:
# copy all the dependent runtime data to the install directory # copy all the dependent runtime data to the install directory
srcdir = os.path.dirname( backup_cwd ) srcdir = os.path.dirname( backup_cwd )
for f in [ for f in [
# USE THE DEPENDENCY WALKER
# tier 1: radiant.exe direct deps
# tier 2: deps of tier 1 DLLs
# etc.
# tier 1
'libxml2/bin/libxml2.dll', 'libxml2/bin/libxml2.dll',
'libxml2/bin/iconv.dll',
'gtk2/bin/libglib-2.0-0.dll', 'gtk2/bin/libglib-2.0-0.dll',
'gtk2/bin/libgobject-2.0-0.dll', 'gtk2/bin/libgobject-2.0-0.dll',
'gtk2/bin/libgdk-win32-2.0-0.dll', 'gtk2/bin/libgdk-win32-2.0-0.dll',
'gtk2/bin/libgtk-win32-2.0-0.dll', 'gtk2/bin/libgtk-win32-2.0-0.dll',
'gtk2/bin/intl.dll', 'gtk2/bin/intl.dll',
'gtk2/bin/libpango-1.0-0.dll', 'gtk2/bin/libatk-1.0-0.dll',
'gtk2/bin/libpangoft2-1.0-0.dll',
'gtk2/lib/gtkglext-1.2.0/lib/libgtkglext-win32-1.0-0.dll',
'gtk2/lib/gtkglext-1.2.0/lib/libgdkglext-win32-1.0-0.dll',
# tier 2
'gtk2/bin/libgthread-2.0-0.dll',
'gtk2/bin/libcairo-2.dll', 'gtk2/bin/libcairo-2.dll',
'gtk2/bin/libgdk_pixbuf-2.0-0.dll', 'gtk2/bin/libgdk_pixbuf-2.0-0.dll',
'gtk2/bin/libgmodule-2.0-0.dll',
'gtk2/bin/libpng13.dll',
'gtk2/bin/libpango-1.0-0.dll',
'gtk2/bin/libpangoft2-1.0-0.dll',
'gtk2/bin/libpangocairo-1.0-0.dll', 'gtk2/bin/libpangocairo-1.0-0.dll',
'gtk2/bin/libpangowin32-1.0-0.dll', 'gtk2/bin/libpangowin32-1.0-0.dll',
'gtk2/bin/libatk-1.0-0.dll', 'gtk2/lib/libgtkglext-win32-1.0-0.dll',
'gtk2/bin/libgmodule-2.0-0.dll', 'gtk2/lib/libgdkglext-win32-1.0-0.dll',
'gtk2/bin/libfontconfig-1.dll', 'gtk2/lib/iconv.dll',
'gtk2/bin/freetype6.dll', 'gtk2/zlib1.dll',
# tier 3 # 'freetype-dev_2.4.2-1_win32/bin/freetype6.dll',
'gtk2/bin/libexpat-1.dll', # 'fontconfig-dev_2.8.0-2_win32/bin/libfontconfig-1.dll',
'gtk2/bin/libpng14-14.dll', # 'expat_2.0.1-1_win32/bin/libexpat-1.dll',
'gtk2/bin/zlib1.dll',
'gtk2/bin/libgio-2.0-0.dll',
]: ]:
cmd = [ 'cp', '-v', os.path.join( srcdir, f ), 'install' ] cmd = [ 'cp', '-v', os.path.join( srcdir, f ), 'install' ]
print( repr( cmd ) ) print( repr( cmd ) )
@ -329,6 +320,9 @@ class Config:
for d in [ for d in [
'gtk2/etc', 'gtk2/etc',
'gtk2/share', 'gtk2/share',
# 'fontconfig-dev_2.8.0-2_win32/etc',
# 'fontconfig-dev_2.8.0-2_win32/share',
# 'freetype-dev_2.4.2-1_win32/share',
]: ]:
cmd = [ 'cp', '-r', '-v', os.path.join( srcdir, d ), 'install' ] cmd = [ 'cp', '-r', '-v', os.path.join( srcdir, d ), 'install' ]
print( repr( cmd ) ) print( repr( cmd ) )

View file

@ -137,7 +137,7 @@ void LoadImage (const char *filename, unsigned char **pic, int *width, int *heig
// http://www.libpng.org/pub/png/libpng-manual.html // http://www.libpng.org/pub/png/libpng-manual.html
png_structp png_ptr = png_create_read_struct png_structp png_ptr = png_create_read_struct
(PNG_LIBPNG_VER_STRING, NULL, (PNG_LIBPNG_VER_STRING, png_voidp_NULL,
user_error_fn, user_warning_fn); user_error_fn, user_warning_fn);
if (!png_ptr) if (!png_ptr)
{ {
@ -148,7 +148,7 @@ void LoadImage (const char *filename, unsigned char **pic, int *width, int *heig
png_infop info_ptr = png_create_info_struct(png_ptr); png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) { if (!info_ptr) {
png_destroy_read_struct(&png_ptr, png_destroy_read_struct(&png_ptr,
NULL, NULL); png_infopp_NULL, png_infopp_NULL);
g_FuncTable.m_pfnSysPrintf ("libpng error: png_create_info_struct (info_ptr)\n"); g_FuncTable.m_pfnSysPrintf ("libpng error: png_create_info_struct (info_ptr)\n");
return; return;
} }
@ -156,7 +156,7 @@ void LoadImage (const char *filename, unsigned char **pic, int *width, int *heig
png_infop end_info = png_create_info_struct(png_ptr); png_infop end_info = png_create_info_struct(png_ptr);
if (!end_info) { if (!end_info) {
png_destroy_read_struct(&png_ptr, &info_ptr, png_destroy_read_struct(&png_ptr, &info_ptr,
NULL); png_infopp_NULL);
g_FuncTable.m_pfnSysPrintf ("libpng error: png_create_info_struct (end_info)\n"); g_FuncTable.m_pfnSysPrintf ("libpng error: png_create_info_struct (end_info)\n");
return; return;
} }
@ -187,10 +187,8 @@ void LoadImage (const char *filename, unsigned char **pic, int *width, int *heig
if (color_type == PNG_COLOR_TYPE_PALETTE) if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr); png_set_palette_to_rgb(png_ptr);
if ( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 ) { if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
// png_set_gray_1_2_4_to_8 was renamed to png_set_expand_gray_1_2_4_to_8 png_set_gray_1_2_4_to_8(png_ptr);
png_set_expand_gray_1_2_4_to_8(png_ptr);
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png_ptr); png_set_tRNS_to_alpha(png_ptr);
@ -236,7 +234,7 @@ void LoadImage (const char *filename, unsigned char **pic, int *width, int *heig
png_read_end(png_ptr, info_ptr); png_read_end(png_ptr, info_ptr);
/* free up the memory structure */ /* free up the memory structure */
png_destroy_read_struct(&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
free(row_pointers); free(row_pointers);
g_FileSystemTable.m_pfnFreeFile (fbuffer); g_FileSystemTable.m_pfnFreeFile (fbuffer);

View file

@ -33,7 +33,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "stdafx.h" #include "stdafx.h"
#include <gtk/gtkgl.h> #include <gtk/gtkgl.h>
#ifndef _WIN32
#include <pango/pangoft2.h> #include <pango/pangoft2.h>
#endif
#include "glwidget.h" #include "glwidget.h"
#include "qgl.h" #include "qgl.h"
@ -208,6 +212,15 @@ gboolean WINAPI gtk_glwidget_make_current (GtkWidget *widget)
} }
#ifdef _WIN32
GLuint font_list_base;
static gchar font_string[] = "courier 8";
static gint font_height;
static int font_created = 0;
#else
// Think about rewriting this font stuff to use OpenGL display lists and glBitmap(). // Think about rewriting this font stuff to use OpenGL display lists and glBitmap().
// Bit maps together with display lists may offer a performance increase, but // Bit maps together with display lists may offer a performance increase, but
// they would not allow antialiased fonts. // they would not allow antialiased fonts.
@ -219,31 +232,88 @@ static int y_offset_bitmap_render_pango_units = -1;
static PangoContext *ft2_context = NULL; static PangoContext *ft2_context = NULL;
static int _debug_font_created = 0; static int _debug_font_created = 0;
#endif
// Units are pixels. Returns a positive value [most likely]. // Units are pixels. Returns a positive value [most likely].
int gtk_glwidget_font_ascent() int gtk_glwidget_font_ascent()
{ {
#ifdef _WIN32
return 6; // Approximation.
#else
if (!_debug_font_created) { if (!_debug_font_created) {
Error("Programming error: gtk_glwidget_font_ascent() called but font does not exist; " Error("Programming error: gtk_glwidget_font_ascent() called but font does not exist; "
"you should have called gtk_glwidget_create_font() first"); "you should have called gtk_glwidget_create_font() first");
} }
return font_ascent; return font_ascent;
#endif
} }
// Units are pixels. Returns a positive value [most likely]. // Units are pixels. Returns a positive value [most likely].
int gtk_glwidget_font_descent() int gtk_glwidget_font_descent()
{ {
#ifdef _WIN32
return 0; // Approximation.
#else
if (!_debug_font_created) { if (!_debug_font_created) {
Error("Programming error: gtk_glwidget_font_descent() called but font does not exist; " Error("Programming error: gtk_glwidget_font_descent() called but font does not exist; "
"you should have called gtk_glwidget_create_font() first"); "you should have called gtk_glwidget_create_font() first");
} }
return font_descent; return font_descent;
#endif
} }
#ifdef _WIN32
void gtk_glwidget_create_font_win_internal()
{
if (font_created) return;
font_created = 1;
PangoFontDescription *font_desc;
PangoFont *font;
PangoFontMetrics *font_metrics;
font_list_base = qglGenLists (256);
font_desc = pango_font_description_from_string (font_string);
font = gdk_gl_font_use_pango_font (font_desc, 0, 256, font_list_base);
if(font != NULL)
{
font_metrics = pango_font_get_metrics (font, NULL);
font_height = pango_font_metrics_get_ascent (font_metrics) +
pango_font_metrics_get_descent (font_metrics);
font_height = PANGO_PIXELS (font_height);
pango_font_metrics_unref (font_metrics);
}
pango_font_description_free (font_desc);
}
#endif
void gtk_glwidget_create_font() void gtk_glwidget_create_font()
{ {
#ifdef _WIN32
// Do nothing.
#else
PangoFontDescription *font_desc; PangoFontDescription *font_desc;
PangoLayout *layout; PangoLayout *layout;
PangoRectangle log_rect; PangoRectangle log_rect;
@ -294,10 +364,18 @@ void gtk_glwidget_create_font()
font_ascent = PANGO_PIXELS_CEIL(font_ascent_pango_units); font_ascent = PANGO_PIXELS_CEIL(font_ascent_pango_units);
font_descent = PANGO_PIXELS_CEIL(font_descent_pango_units); font_descent = PANGO_PIXELS_CEIL(font_descent_pango_units);
y_offset_bitmap_render_pango_units = (font_ascent * PANGO_SCALE) - font_ascent_pango_units; y_offset_bitmap_render_pango_units = (font_ascent * PANGO_SCALE) - font_ascent_pango_units;
#endif
} }
void gtk_glwidget_destroy_font() void gtk_glwidget_destroy_font()
{ {
#ifdef _WIN32
// Do nothing.
#else
if (!_debug_font_created) { if (!_debug_font_created) {
Error("Programming error: gtk_glwidget_destroy_font() called when font " Error("Programming error: gtk_glwidget_destroy_font() called when font "
"does not exist"); "does not exist");
@ -308,6 +386,8 @@ void gtk_glwidget_destroy_font()
y_offset_bitmap_render_pango_units = -1; y_offset_bitmap_render_pango_units = -1;
g_object_unref(G_OBJECT(ft2_context)); g_object_unref(G_OBJECT(ft2_context));
_debug_font_created = 0; _debug_font_created = 0;
#endif
} }
@ -323,6 +403,14 @@ void gtk_glwidget_destroy_font()
// Google for "glDrawPixels clipping". // Google for "glDrawPixels clipping".
void gtk_glwidget_print_string(const char *s) void gtk_glwidget_print_string(const char *s)
{ {
#ifdef _WIN32
gtk_glwidget_create_font_win_internal();
qglListBase(font_list_base);
qglCallLists(strlen(s), GL_UNSIGNED_BYTE, (unsigned char *)s);
#else
// The idea for this code initially came from the font-pangoft2.c example that comes with GtkGLExt. // The idea for this code initially came from the font-pangoft2.c example that comes with GtkGLExt.
PangoLayout *layout; PangoLayout *layout;
@ -396,12 +484,24 @@ void gtk_glwidget_print_string(const char *s)
} }
g_object_unref(G_OBJECT(layout)); g_object_unref(G_OBJECT(layout));
#endif
} }
void gtk_glwidget_print_char(char s) void gtk_glwidget_print_char(char s)
{ {
#ifdef _WIN32
gtk_glwidget_create_font_win_internal();
qglListBase(font_list_base);
qglCallLists(1, GL_UNSIGNED_BYTE, (unsigned char *) &s);
#else
char str[2]; char str[2];
str[0] = s; str[0] = s;
str[1] = '\0'; str[1] = '\0';
gtk_glwidget_print_string(str); gtk_glwidget_print_string(str);
#endif
} }

View file

@ -1025,8 +1025,6 @@ int WINAPI gtk_MessageBox (void *parent, const char* lpText, const char* lpCapti
// fenris #3078 WHENHELLISFROZENOVER // fenris #3078 WHENHELLISFROZENOVER
//#define FILEDLG_DBG
static void file_sel_callback (GtkWidget *widget, gpointer data) static void file_sel_callback (GtkWidget *widget, gpointer data)
{ {
GtkWidget *parent; GtkWidget *parent;
@ -1040,11 +1038,6 @@ static void file_sel_callback (GtkWidget *widget, gpointer data)
if (GPOINTER_TO_INT (data) == IDOK) if (GPOINTER_TO_INT (data) == IDOK)
*success = true; *success = true;
#ifdef FILEDLG_DBG
else
Sys_Printf("file_sel_callback != IDOK\n");
#endif
*loop = 0; *loop = 0;
} }
@ -1123,6 +1116,18 @@ public:
return filetype_t(); return filetype_t();
} }
int GetNumTypes()
{
return m_nTypes;
}
filetype_t GetTypeForIndex(int index) const // Zero-based index.
{
if (index >= 0 && index < m_nTypes)
return filetype_t(m_pTypes[index].m_name.c_str(), m_pTypes[index].m_pattern.c_str());
return filetype_t();
}
char *m_strWin32Filters; char *m_strWin32Filters;
char **m_pstrGTKMasks; char **m_pstrGTKMasks;
private: private:
@ -1185,10 +1190,10 @@ private:
for(r = m_pTypes[i].m_name.c_str(); *r!='\0'; r++, w++) for(r = m_pTypes[i].m_name.c_str(); *r!='\0'; r++, w++)
*w = *r; *w = *r;
*w++ = ' '; *w++ = ' ';
*w++ = '<'; *w++ = '(';
for(r = m_pTypes[i].m_pattern.c_str(); *r!='\0'; r++, w++) for(r = m_pTypes[i].m_pattern.c_str(); *r!='\0'; r++, w++)
*w = *r; *w = *r;
*w++ = '>'; *w++ = ')';
*w++ = '\0'; *w++ = '\0';
} }
m_pstrGTKMasks[m_nTypes] = NULL; m_pstrGTKMasks[m_nTypes] = NULL;
@ -1196,64 +1201,82 @@ private:
}; };
#ifdef _WIN32
typedef struct {
gboolean open;
OPENFILENAME *ofn;
BOOL dlgRtnVal;
bool done;
} win32_native_file_dialog_comms_t;
DWORD WINAPI win32_native_file_dialog_thread_func(LPVOID lpParam)
{
win32_native_file_dialog_comms_t *fileDialogComms;
fileDialogComms = (win32_native_file_dialog_comms_t *) lpParam;
if (fileDialogComms->open) {
fileDialogComms->dlgRtnVal = GetOpenFileName(fileDialogComms->ofn);
}
else {
fileDialogComms->dlgRtnVal = GetSaveFileName(fileDialogComms->ofn);
}
fileDialogComms->done = true; // No need to synchronize around lock, one-way gate.
return 0;
}
#endif
/** /**
* @param[in] baseSubDir should have a trailing slash if not @c NULL * @param[in] baseSubDir should have a trailing slash if not @c NULL
*/ */
const char* file_dialog (void *parent, gboolean open, const char* title, const char* path, const char* pattern, const char *baseSubDir) const char* file_dialog (void *parent, gboolean open, const char* title, const char* path, const char* pattern, const char *baseSubDir)
{ {
#ifdef _WIN32
static bool in_file_dialog = false;
HANDLE fileDialogThreadHandle;
win32_native_file_dialog_comms_t fileDialogComms;
bool dialogDone;
#endif
// Gtk dialog // Gtk dialog
GtkWidget* file_sel; GtkWidget* file_sel;
int loop = 1;
char *new_path = NULL; char *new_path = NULL;
const char* r; const char* r;
char* w; char *v, *w;
filetype_t type; filetype_t type;
CFileType typelist; CFileType typelist;
if(pattern != NULL) if(pattern != NULL)
GetFileTypeRegistry()->getTypeList(pattern, &typelist); GetFileTypeRegistry()->getTypeList(pattern, &typelist);
#ifdef FILEDLG_DBG
Sys_Printf("file_dialog: open = %d title = %s path = %s\n", open, title, path);
if (pattern)
{
Sys_Printf("Patterns:\n");
char** p = typelist.m_pstrGTKMasks;
while(*p!=NULL)
Sys_Printf("%s\n", *p++);
}
else
Sys_Printf("no patterns\n");
#endif
#ifdef _WIN32 #ifdef _WIN32
// win32 dialog stores the selected "save as type" extension in the second null-terminated string
char customfilter[FILEDLG_CUSTOM_FILTER_LENGTH];
if (g_PrefsDlg.m_bNativeGUI) if (g_PrefsDlg.m_bNativeGUI)
{ {
#ifdef FILEDLG_DBG
Sys_Printf("Doing win32 file dialog...");
#endif
// do that the native way // do that the native way
/* Place the terminating null character in the szFile. */
szFile[0] = '\0';
customfilter[0] = customfilter[1] = customfilter[2] = '\0';
if (in_file_dialog) return NULL; // Avoid recursive entry.
in_file_dialog = true;
/* Set the members of the OPENFILENAME structure. */ /* Set the members of the OPENFILENAME structure. */
ofn.lStructSize = sizeof(OPENFILENAME); // See http://msdn.microsoft.com/en-us/library/ms646839%28v=vs.85%29.aspx .
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = (HWND)GDK_WINDOW_HWND (g_pParentWnd->m_pWidget->window); ofn.hwndOwner = (HWND)GDK_WINDOW_HWND (g_pParentWnd->m_pWidget->window);
ofn.nFilterIndex = 1; // The index is 1-based, not 0-based. This basically says,
// "select the first filter as default".
if (pattern) if (pattern)
{ {
ofn.nFilterIndex = 0;
ofn.lpstrFilter = typelist.m_strWin32Filters; ofn.lpstrFilter = typelist.m_strWin32Filters;
} }
else ofn.nFilterIndex = 1; else
ofn.lpstrCustomFilter = customfilter; {
ofn.nMaxCustFilter = sizeof(customfilter); // TODO: Would be a bit cleaner if we could extract this string from
// GetFileTypeRegistry() instead of hardcoding it here.
ofn.lpstrFilter = "all files\0*.*\0"; // Second '\0' will be added to end of string.
}
szFile[0] = '\0';
ofn.lpstrFile = szFile; ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile); ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = NULL; // we don't need to get the name of the file
if(path) if(path)
{ {
// szDirName: Radiant uses unix convention for paths internally // szDirName: Radiant uses unix convention for paths internally
@ -1265,29 +1288,47 @@ const char* file_dialog (void *parent, gboolean open, const char* title, const c
*w = '\0'; *w = '\0';
ofn.lpstrInitialDir = szDirName; ofn.lpstrInitialDir = szDirName;
} }
else ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = title; ofn.lpstrTitle = title;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
/* Display the Open dialog box. */ memset(&fileDialogComms, 0, sizeof(fileDialogComms));
// it's open or close depending on 'open' parameter fileDialogComms.open = open;
if (open) fileDialogComms.ofn = &ofn;
{
if (!GetOpenFileName(&ofn)) fileDialogThreadHandle =
return NULL; // canceled CreateThread(NULL, // lpThreadAttributes
0, // dwStackSize, default stack size
win32_native_file_dialog_thread_func, // lpStartAddress, funcion to call
&fileDialogComms, // lpParameter, argument to pass to function
0, // dwCreationFlags
NULL); // lpThreadId
dialogDone = false;
while (1) {
// Avoid blocking indefinitely. Another thread will set fileDialogComms->done to true;
// we don't want to be in an indefinite blocked state when this happens. We want to break
// out of here eventually.
while (gtk_events_pending()) {
gtk_main_iteration();
}
if (dialogDone) break;
if (fileDialogComms.done) dialogDone = true; // One more loop of gtk_main_iteration() to get things in sync.
// Avoid tight infinte loop, add a small amount of sleep.
Sleep(10);
} }
else // Make absolutely sure that the thread is finished before we call CloseHandle().
{ WaitForSingleObject(fileDialogThreadHandle, INFINITE);
if (!GetSaveFileName(&ofn)) CloseHandle(fileDialogThreadHandle);
return NULL; // canceled
in_file_dialog = false;
if (!fileDialogComms.dlgRtnVal) {
return NULL; // Cancelled.
} }
if(pattern != NULL) if(pattern != NULL)
type = typelist.GetTypeForWin32Filter(customfilter+1); type = typelist.GetTypeForIndex(ofn.nFilterIndex - 1);
#ifdef FILEDLG_DBG
Sys_Printf("Done.\n");
#endif
} }
else else
{ {
@ -1297,9 +1338,6 @@ const char* file_dialog (void *parent, gboolean open, const char* title, const c
if (title == NULL) if (title == NULL)
title = open ? _("Open File") : _("Save File"); title = open ? _("Open File") : _("Save File");
#ifdef FILEDLG_DBG
Sys_Printf("Doing Gtk file dialog:\nBuilding new_path..");
#endif
// we expect an actual path below, if the path is NULL we might crash // we expect an actual path below, if the path is NULL we might crash
if (!path || path[0] == '\0') if (!path || path[0] == '\0')
{ {
@ -1321,101 +1359,51 @@ const char* file_dialog (void *parent, gboolean open, const char* title, const c
// terminate string // terminate string
*w = '\0'; *w = '\0';
#ifdef FILEDLG_DBG file_sel = gtk_file_chooser_dialog_new(title,
Sys_Printf("Done.\n"); GTK_WINDOW(parent),
Sys_Printf("Calling gtk_file_selection_new with title: %s...", title); open ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SAVE,
#endif GTK_STOCK_CANCEL,
file_sel = gtk_file_selection_new (title); GTK_RESPONSE_CANCEL,
#ifdef FILEDLG_DBG open ? GTK_STOCK_OPEN : GTK_STOCK_SAVE,
Sys_Printf("Done.\n"); GTK_RESPONSE_ACCEPT,
Sys_Printf("Set the masks..."); NULL);
#endif gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_sel), new_path);
delete[] new_path;
#if 0 //!\todo Add masks to GtkFileSelection in gtk-2.0 // Setting the file chooser dialog to modal and centering it on the parent is done automatically.
// set the masks
if (pattern)
{
gtk_file_selection_clear_masks (GTK_FILE_SELECTION (file_sel));
gtk_file_selection_set_masks (GTK_FILE_SELECTION (file_sel), const_cast<const char**>(typelist.m_pstrGTKMasks));
}
#endif
#ifdef FILEDLG_DBG if (pattern != NULL) {
Sys_Printf("Done.\n"); for (int i = 0; i < typelist.GetNumTypes(); i++) {
#endif GtkFileFilter *filter = gtk_file_filter_new();
type = typelist.GetTypeForIndex(i);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_sel)->ok_button), "clicked", // We can use type.name here, or m_pstrGTKMasks[i], which includes the actual pattern.
GTK_SIGNAL_FUNC (file_sel_callback), GINT_TO_POINTER (IDOK)); gtk_file_filter_set_name(filter, typelist.m_pstrGTKMasks[i]);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_sel)->cancel_button), "clicked", gtk_file_filter_add_pattern(filter, type.pattern);
GTK_SIGNAL_FUNC (file_sel_callback), GINT_TO_POINTER (IDCANCEL)); // "Note that the chooser takes ownership of the filter, so
gtk_signal_connect (GTK_OBJECT (file_sel), "delete_event", // you have to ref and sink it if you want to keep a reference."
GTK_SIGNAL_FUNC (dialog_delete_callback), NULL); // So I guess we won't need to garbage collect this.
gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (file_sel)); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_sel), filter);
}
if (parent != NULL)
gtk_window_set_transient_for (GTK_WINDOW (file_sel), GTK_WINDOW (parent));
#ifdef FILEDLG_DBG
Sys_Printf("set_data...");
#endif
bool success = false;
g_object_set_data (G_OBJECT (file_sel), "loop", &loop);
g_object_set_data (G_OBJECT (file_sel), "success", &success);
#ifdef FILEDLG_DBG
Sys_Printf("Done.\n");
#endif
if (!open)
{
#ifdef FILEDLG_DBG
Sys_Printf("set_data \"overwrite\" ...");
#endif
g_object_set_data (G_OBJECT (file_sel), "overwrite", GINT_TO_POINTER (1));
#ifdef FILEDLG_DBG
Sys_Printf("Done.\n");
#endif
} }
if (new_path != NULL) if (gtk_dialog_run(GTK_DIALOG(file_sel)) == GTK_RESPONSE_ACCEPT) {
{ strcpy(szFile, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_sel)));
#ifdef FILEDLG_DBG }
Sys_Printf("gtk_file_selection_set_filename... %p (%s)", file_sel, new_path); else {
#endif szFile[0] = '\0';
gtk_file_selection_set_filename (GTK_FILE_SELECTION (file_sel), new_path);
delete[] new_path;
#ifdef FILEDLG_DBG
Sys_Printf("Done.\n");
#endif
} }
gtk_grab_add (file_sel); if (pattern != NULL) {
#ifdef FILEDLG_DBG GtkFileFilter *filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(file_sel));
Sys_Printf("gtk_widget_show... %p", file_sel); if (filter == NULL) {
#endif type = filetype_t();
gtk_widget_show (file_sel); }
#ifdef FILEDLG_DBG else {
Sys_Printf("Done.\n"); type = typelist.GetTypeForGTKMask(gtk_file_filter_get_name(filter));
#endif }
#ifdef FILEDLG_DBG
Sys_Printf("gtk_main_iteration...");
#endif
while (loop)
gtk_main_iteration ();
if(success)
{
#if 0 //!\todo Add masks to GtkFileSelection in gtk2
if(pattern!=NULL)
type = typelist.GetTypeForGTKMask(GTK_FILE_SELECTION (file_sel)->mask);
#endif
strcpy(szFile, gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_sel)));
} }
#ifdef FILEDLG_DBG gtk_widget_destroy(file_sel);
Sys_Printf("Done.\n");
#endif
gtk_grab_remove (file_sel);
gtk_widget_destroy (file_sel);
#ifdef _WIN32 #ifdef _WIN32
} }
#endif #endif
@ -1428,21 +1416,42 @@ const char* file_dialog (void *parent, gboolean open, const char* title, const c
if(*w=='\\') if(*w=='\\')
*w = '/'; *w = '/';
#if defined(WIN32) /* \todo SPoG - file_dialog should return filetype information separately.. not force file extension.. */
if (g_PrefsDlg.m_bNativeGUI) // filetype mask not supported in gtk dialog yet if(!open && pattern != NULL) {
{ v = strrchr(szFile, '/');
// when saving, force an extension depending on filetype w = strrchr(szFile, '.');
/* \todo SPoG - file_dialog should return filetype information separately.. not force file extension.. */ if ((v && w && w < v) || // Last '.' is before the file.
if(!open && pattern != NULL) w == NULL) { // Extension missing.
{ if (type.pattern[0]) {
// last ext separator w = szFile + strlen(szFile);
w = strrchr(szFile, '.'); strcpy(w, type.pattern + 1); // Add extension of selected filter type.
// no extension }
w = (w!=NULL) ? w : szFile+strlen(szFile); else {
strcpy(w, type.pattern+1); // type will be empty if for example there were no filters for pattern,
// or if some other UI inconsistencies happen.
if (gtk_MessageBox(parent, "No file extension specified in file to be saved.\nAttempt to save anyways?",
"GtkRadiant", MB_YESNO) == IDNO) {
return NULL;
}
}
}
else { // An extension was explicitly in the filename.
bool knownExtension = false;
for (int i = typelist.GetNumTypes() - 1; i >= 0; i--) {
type = typelist.GetTypeForIndex(i);
if (type.pattern[0] && strcmp(w, type.pattern + 1) == 0) {
knownExtension = true;
break;
}
}
if (!knownExtension) {
if (gtk_MessageBox(parent, "Unknown file extension for this save operation.\nAttempt to save anyways?",
"GtkRadiant", MB_YESNO) == IDNO) {
return NULL;
}
}
} }
} }
#endif
// prompt to overwrite existing files // prompt to overwrite existing files
if (!open) if (!open)
@ -1450,11 +1459,6 @@ const char* file_dialog (void *parent, gboolean open, const char* title, const c
if (gtk_MessageBox (parent, "File already exists.\nOverwrite?", "GtkRadiant", MB_YESNO) == IDNO) if (gtk_MessageBox (parent, "File already exists.\nOverwrite?", "GtkRadiant", MB_YESNO) == IDNO)
return NULL; return NULL;
#ifdef FILEDLG_DBG
// ... let's use a static filename
Sys_Printf("filename: %p\n", szFile);
#endif
return szFile; return szFile;
} }

View file

@ -40,7 +40,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "gtkmisc.h" #include "gtkmisc.h"
#ifdef _WIN32 #ifdef _WIN32
#undef fprintf // sanity check - some gtk2 win32 runtimes replace sprintf
#if defined( sprintf )
#error sprintf is a macro. are you sure?
#endif
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
@ -2222,7 +2225,7 @@ void PrefsDlg::BuildDialog ()
#ifdef _WIN32 #ifdef _WIN32
// win32 file dialog // win32 file dialog
check = gtk_check_button_new_with_label (_("Use win32 file load dialog")); check = gtk_check_button_new_with_label (_("Use win32 file dialog (hacky)"));
gtk_widget_show (check); gtk_widget_show (check);
// gtk_container_add (GTK_CONTAINER (vbox), check); // gtk_container_add (GTK_CONTAINER (vbox), check);
gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);

View file

@ -40,7 +40,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="&quot;$(SolutionDir)\include&quot;;&quot;$(SolutionDir)\libs&quot;;&quot;$(SolutionDir)\..\STLPort\stlport&quot;;&quot;$(SolutionDir)\..\gtk2\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\glib-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\lib\glib-2.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtk-2.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtkglext-1.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\gtk-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\cairo&quot;;&quot;$(SolutionDir)\..\gtk2\include\pango-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\atk-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\gdk-pixbuf-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\freetype2&quot;;&quot;$(SolutionDir)\..\libxml2\include&quot;" AdditionalIncludeDirectories="&quot;$(SolutionDir)\include&quot;;&quot;$(SolutionDir)\libs&quot;;&quot;$(SolutionDir)\..\STLPort\stlport&quot;;&quot;$(SolutionDir)\..\gtk2\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\glib-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\lib\glib-2.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtk-2.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\gtkglext-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtkglext-1.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\gtk-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\cairo&quot;;&quot;$(SolutionDir)\..\gtk2\include\pango-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\atk-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\gdk-pixbuf-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\freetype2&quot;;&quot;$(SolutionDir)\..\libxml2\include&quot;"
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
@ -62,7 +62,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="intl.lib user32.lib shell32.lib gdi32.lib comdlg32.lib l_net.lib cmdlib.lib mathlib.lib Wsock32.lib libxml2.lib glib-2.0.lib gobject-2.0.lib gdk-win32-2.0.lib gtk-win32-2.0.lib pango-1.0.lib pangoft2-1.0.lib gtkglext-win32-1.0.lib gdkglext-win32-1.0.lib" AdditionalDependencies="intl.lib user32.lib shell32.lib gdi32.lib comdlg32.lib l_net.lib cmdlib.lib mathlib.lib Wsock32.lib libxml2.lib glib-2.0.lib gobject-2.0.lib gdk-win32-2.0.lib gtk-win32-2.0.lib pango-1.0.lib pangoft2-1.0.lib gtkglext-win32-1.0.lib gdkglext-win32-1.0.lib"
AdditionalLibraryDirectories="&quot;$(SolutionDir)\..\libxml2\lib&quot;;&quot;$(SolutionDir)\..\gtk2\lib&quot;;&quot;$(SolutionDir)\build\$(ConfigurationName)\libs&quot;;&quot;$(SolutionDir)..\gtk2\lib\gtkglext-1.0\lib&quot;" AdditionalLibraryDirectories="&quot;$(SolutionDir)\..\libxml2\lib&quot;;&quot;$(SolutionDir)\..\gtk2\lib&quot;;&quot;$(SolutionDir)\build\$(ConfigurationName)\libs&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtkglext-1.2.0\lib&quot;"
GenerateDebugInformation="true" GenerateDebugInformation="true"
RandomizedBaseAddress="1" RandomizedBaseAddress="1"
DataExecutionPrevention="0" DataExecutionPrevention="0"
@ -115,7 +115,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(SolutionDir)\include&quot;;&quot;$(SolutionDir)\libs&quot;;&quot;$(SolutionDir)\..\STLPort\stlport&quot;;&quot;$(SolutionDir)\..\gtk2\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\glib-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\lib\glib-2.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtk-2.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtkglext-1.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\gtk-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\cairo&quot;;&quot;$(SolutionDir)\..\gtk2\include\pango-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\atk-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\gdk-pixbuf-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\freetype2&quot;;&quot;$(SolutionDir)\..\libxml2\include&quot;" AdditionalIncludeDirectories="&quot;$(SolutionDir)\include&quot;;&quot;$(SolutionDir)\libs&quot;;&quot;$(SolutionDir)\..\STLPort\stlport&quot;;&quot;$(SolutionDir)\..\gtk2\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\glib-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\lib\glib-2.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtk-2.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\gtkglext-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtkglext-1.0\include&quot;;&quot;$(SolutionDir)\..\gtk2\include\gtk-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\cairo&quot;;&quot;$(SolutionDir)\..\gtk2\include\pango-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\atk-1.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\gdk-pixbuf-2.0&quot;;&quot;$(SolutionDir)\..\gtk2\include\freetype2&quot;;&quot;$(SolutionDir)\..\libxml2\include&quot;"
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="2" RuntimeLibrary="2"
WarningLevel="3" WarningLevel="3"
@ -135,7 +135,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="intl.lib user32.lib shell32.lib gdi32.lib comdlg32.lib l_net.lib cmdlib.lib mathlib.lib Wsock32.lib libxml2.lib glib-2.0.lib gobject-2.0.lib gdk-win32-2.0.lib gtk-win32-2.0.lib pango-1.0.lib pangoft2-1.0.lib gtkglext-win32-1.0.lib gdkglext-win32-1.0.lib" AdditionalDependencies="intl.lib user32.lib shell32.lib gdi32.lib comdlg32.lib l_net.lib cmdlib.lib mathlib.lib Wsock32.lib libxml2.lib glib-2.0.lib gobject-2.0.lib gdk-win32-2.0.lib gtk-win32-2.0.lib pango-1.0.lib pangoft2-1.0.lib gtkglext-win32-1.0.lib gdkglext-win32-1.0.lib"
AdditionalLibraryDirectories="&quot;$(SolutionDir)\..\libxml2\lib&quot;;&quot;$(SolutionDir)\..\gtk2\lib&quot;;&quot;$(SolutionDir)\build\$(ConfigurationName)\libs&quot;;&quot;$(SolutionDir)..\gtk2\lib\gtkglext-1.0\lib&quot;" AdditionalLibraryDirectories="&quot;$(SolutionDir)\..\libxml2\lib&quot;;&quot;$(SolutionDir)\..\gtk2\lib&quot;;&quot;$(SolutionDir)\build\$(ConfigurationName)\libs&quot;;&quot;$(SolutionDir)\..\gtk2\lib\gtkglext-1.2.0\lib&quot;"
GenerateDebugInformation="true" GenerateDebugInformation="true"
OptimizeReferences="2" OptimizeReferences="2"
EnableCOMDATFolding="2" EnableCOMDATFolding="2"
@ -996,11 +996,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\gtk+\gtk\gtkmisc.h" RelativePath=".\gtkmisc.h"
> >
</File> </File>
<File <File
RelativePath=".\gtkmisc.h" RelativePath="..\..\src\gtk+\gtk\gtkmisc.h"
> >
</File> </File>
<File <File
@ -2412,6 +2412,10 @@
<Filter <Filter
Name="Misc" Name="Misc"
> >
<File
RelativePath="..\..\src\glib\makefile.msc"
>
</File>
<File <File
RelativePath="..\..\src\gtk+\gdk\makefile.msc" RelativePath="..\..\src\gtk+\gdk\makefile.msc"
> >
@ -2424,10 +2428,6 @@
RelativePath="..\..\src\gtk+\gtk\makefile.msc" RelativePath="..\..\src\gtk+\gtk\makefile.msc"
> >
</File> </File>
<File
RelativePath="..\..\src\glib\makefile.msc"
>
</File>
</Filter> </Filter>
<File <File
RelativePath="..\setup\changelog.txt" RelativePath="..\setup\changelog.txt"