native file open/save dialogs

This commit is contained in:
berkeviktor@aol.com 2010-10-05 05:30:22 +02:00
parent b70d524749
commit dede76e56a
4 changed files with 335 additions and 3 deletions

33
src/common/thread.c Normal file
View File

@ -0,0 +1,33 @@
#include <fcntl.h>
#include "thread.h"
thread *
thread_new (void)
{
thread *th;
th = calloc (1, sizeof (*th));
if (!th)
{
return NULL;
}
if (_pipe (th->pipe_fd, 4096, _O_BINARY) == -1)
{
free (th);
return NULL;
}
return th;
}
int
thread_start (thread *th, void *(*start_routine)(void *), void *arg)
{
DWORD id;
CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, (DWORD *)&id));
th->threadid = id;
return 1;
}

10
src/common/thread.h Normal file
View File

@ -0,0 +1,10 @@
#include <windows.h>
typedef struct
{
DWORD threadid;
int pipe_fd[2];
} thread;
thread *thread_new (void);
int thread_start (thread *th, void *(*start_routine)(void *), void *arg);

View File

@ -5,7 +5,7 @@ CFLAGS = $(CFLAGS) /DWIN32 /DG_DISABLE_CAST_CHECKS /DG_DISABLE_DEPRECATED /DGDK_
CFLAGS = $(CFLAGS) -Ic:\mozilla-build\build\xchat-wdk\plugins
CPPFLAGS = /c /MD /W0 /nologo /DWIN32
LDFLAGS = /subsystem:windows /nologo
LIBS = $(LIBS) gdi32.lib shell32.lib user32.lib advapi32.lib imm32.lib ole32.lib winmm.lib ws2_32.lib wininet.lib
LIBS = $(LIBS) gdi32.lib shell32.lib user32.lib advapi32.lib imm32.lib ole32.lib winmm.lib ws2_32.lib wininet.lib comdlg32.lib
!ifdef X64
#############################################################
@ -77,6 +77,7 @@ server.obj \
servlist.obj \
ssl.obj \
text.obj \
thread.obj \
tree.obj \
url.obj \
userlist.obj \

View File

@ -882,7 +882,7 @@ diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-gtk/fkeys.c xchat-wdk/src/fe
#include <ctype.h>
diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-gtk/gtkutil.c xchat-wdk/src/fe-gtk/gtkutil.c
--- xchat-wdk.orig/src/fe-gtk/gtkutil.c 2009-07-18 14:38:10 +0200
+++ xchat-wdk/src/fe-gtk/gtkutil.c 2010-10-05 03:55:27 +0200
+++ xchat-wdk/src/fe-gtk/gtkutil.c 2010-10-05 05:22:28 +0200
@@ -22,7 +22,6 @@
#include <stdarg.h>
#include <sys/types.h>
@ -891,6 +891,283 @@ diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-gtk/gtkutil.c xchat-wdk/src/
#include <fcntl.h>
#include "fe-gtk.h"
@@ -51,6 +50,10 @@
#include "../common/util.h"
#include "gtkutil.h"
#include "pixmaps.h"
+#ifdef WIN32
+#include "../common/fe.h"
+#include "../common/thread.h"
+#endif
/* gtkutil.c, just some gtk wrappers */
@@ -63,6 +66,13 @@
void *userdata;
filereqcallback callback;
int flags; /* FRF_* flags */
+
+#ifdef WIN32
+ int multiple;
+ thread *th;
+ char *title; /* native locale */
+ char *filter;
+#endif
};
static char last_dir[256] = "";
@@ -164,6 +174,196 @@
}
}
+#ifdef WIN32
+static int
+win32_openfile (char *file_buf, int file_buf_len, char *title_text, char *filter,
+ int multiple)
+{
+ OPENFILENAME o;
+
+ memset (&o, 0, sizeof (o));
+
+ o.lStructSize = sizeof (o);
+ o.lpstrFilter = filter;
+ o.lpstrFile = file_buf;
+ o.nMaxFile = file_buf_len;
+ o.lpstrTitle = title_text;
+ o.Flags = 0x02000000 | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
+ OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_LONGNAMES | OFN_NONETWORKBUTTON;
+ if (multiple)
+ o.Flags |= OFN_ALLOWMULTISELECT;
+
+ return GetOpenFileName (&o);
+}
+
+static int
+win32_savefile (char *file_buf, int file_buf_len, char *title_text, char *filter,
+ int multiple)
+{
+ OPENFILENAME o;
+
+ memset (&o, 0, sizeof (o));
+
+ o.lStructSize = sizeof (o);
+ o.lpstrFilter = filter;
+ o.lpstrFile = file_buf;
+ o.nMaxFile = file_buf_len;
+ o.lpstrTitle = title_text;
+ o.Flags = 0x02000000 | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
+ OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_LONGNAMES | OFN_NONETWORKBUTTON;
+ if (multiple)
+ o.Flags |= OFN_ALLOWMULTISELECT;
+
+ return GetSaveFileName (&o);
+}
+
+static void *
+win32_thread (struct file_req *freq)
+{
+ char buf[1024 + 32];
+ char file[1024];
+
+ memset (file, 0, sizeof (file));
+ safe_strcpy (file, last_dir, sizeof (file));
+
+ if (win32_openfile (file, sizeof (file), freq->title, freq->filter, freq->multiple))
+ {
+ if (freq->multiple)
+ {
+ char *f = file;
+
+ if (f[strlen (f) + 1] == 0) /* only selected one file */
+ {
+ snprintf (buf, sizeof (buf), "1\n%s\n", file);
+ write (freq->th->pipe_fd[1], buf, strlen (buf));
+ } else
+ {
+ f += strlen (f) + 1; /* skip first, it's only the dir */
+ while (f[0])
+ {
+ snprintf (buf, sizeof (buf), "1\n%s\\%s\n", /*dir!*/file, f);
+ write (freq->th->pipe_fd[1], buf, strlen (buf));
+ f += strlen (f) + 1;
+ }
+ }
+
+ } else
+ {
+ snprintf (buf, sizeof (buf), "1\n%s\n", file);
+ write (freq->th->pipe_fd[1], buf, strlen (buf));
+ }
+ }
+
+ write (freq->th->pipe_fd[1], "0\n", 2);
+ Sleep (2000);
+
+ return NULL;
+}
+
+static void *
+win32_thread2 (struct file_req *freq)
+{
+ char buf[1024 + 32];
+ char file[1024];
+
+ memset (file, 0, sizeof (file));
+ safe_strcpy (file, last_dir, sizeof (file));
+
+ if (win32_savefile (file, sizeof (file), freq->title, freq->filter, freq->multiple))
+ {
+ if (freq->multiple)
+ {
+ char *f = file;
+
+ if (f[strlen (f) + 1] == 0) /* only selected one file */
+ {
+ snprintf (buf, sizeof (buf), "1\n%s\n", file);
+ write (freq->th->pipe_fd[1], buf, strlen (buf));
+ } else
+ {
+ f += strlen (f) + 1; /* skip first, it's only the dir */
+ while (f[0])
+ {
+ snprintf (buf, sizeof (buf), "1\n%s\\%s\n", /*dir!*/file, f);
+ write (freq->th->pipe_fd[1], buf, strlen (buf));
+ f += strlen (f) + 1;
+ }
+ }
+
+ } else
+ {
+ snprintf (buf, sizeof (buf), "1\n%s\n", file);
+ write (freq->th->pipe_fd[1], buf, strlen (buf));
+ }
+ }
+
+ write (freq->th->pipe_fd[1], "0\n", 2);
+ Sleep (2000);
+
+ return NULL;
+}
+
+static int
+waitline2 (GIOChannel *source, char *buf, int bufsize)
+{
+ int i = 0;
+ int len;
+
+ while (1)
+ {
+ if (g_io_channel_read (source, &buf[i], 1, &len) != G_IO_ERROR_NONE)
+ return -1;
+ if (buf[i] == '\n' || bufsize == i + 1)
+ {
+ buf[i] = 0;
+ return i;
+ }
+ i++;
+ }
+}
+
+static gboolean
+win32_close_pipe (int fd)
+{
+ close (fd);
+ return 0;
+}
+
+static gboolean
+win32_read_thread (GIOChannel *source, GIOCondition cond, struct file_req *freq)
+{
+ char buf[512];
+ char *file;
+
+ waitline2 (source, buf, sizeof buf);
+
+ switch (buf[0])
+ {
+ case '0': /* filedialog has closed */
+ freq->callback (freq->userdata, NULL);
+ break;
+
+ case '1': /* got a filename! */
+ waitline2 (source, buf, sizeof buf);
+ file = g_filename_to_utf8 (buf, -1, 0, 0, 0);
+ freq->callback (freq->userdata, file);
+ g_free (file);
+ return TRUE;
+ }
+
+ /* it doesn't work to close them here, because of the weird
+ way giowin32 works. We must _return_ before closing them */
+ g_timeout_add(3000, (GSourceFunc)win32_close_pipe, freq->th->pipe_fd[0]);
+ g_timeout_add(2000, (GSourceFunc)win32_close_pipe, freq->th->pipe_fd[1]);
+
+ g_free (freq->title);
+ free (freq->th);
+ free (freq);
+
+ return FALSE;
+}
+#endif
+
void
gtkutil_file_req (const char *title, void *callback, void *userdata, char *filter,
int flags)
@@ -172,6 +372,54 @@
GtkWidget *dialog;
extern char *get_xdir_fs (void);
+#ifdef WIN32
+ if (!(flags & FRF_WRITE))
+ {
+ freq = malloc (sizeof (struct file_req));
+ freq->th = thread_new ();
+ freq->flags = 0;
+ freq->multiple = (flags & FRF_MULTIPLE);
+ freq->callback = callback;
+ freq->userdata = userdata;
+ freq->title = g_locale_from_utf8 (title, -1, 0, 0, 0);
+ if (!filter)
+ freq->filter = "All files\000*.*\000"
+ "EXE files\000*.EXE\000"
+ "MP3 files\000*.MP3\000"
+ "MPEG files\000*.MPG;*.MPEG\000"
+ "RAR files\000*.RAR\000"
+ "ZIP files\000*.ZIP\000";
+ else
+ freq->filter = filter;
+
+ thread_start (freq->th, win32_thread, freq);
+ fe_input_add (freq->th->pipe_fd[0], FIA_FD|FIA_READ, win32_read_thread, freq);
+
+ return;
+
+ }
+
+ else {
+ freq = malloc (sizeof (struct file_req));
+ freq->th = thread_new ();
+ freq->flags = 0;
+ freq->multiple = (flags & FRF_MULTIPLE);
+ freq->callback = callback;
+ freq->userdata = userdata;
+ freq->title = g_locale_from_utf8 (title, -1, 0, 0, 0);
+ if (!filter)
+ freq->filter = "Text files\000*.TXT\000"
+ "All files\000*.*\000";
+ else
+ freq->filter = filter;
+
+ thread_start (freq->th, win32_thread2, freq);
+ fe_input_add (freq->th->pipe_fd[0], FIA_FD|FIA_READ, win32_read_thread, freq);
+
+ return;
+ }
+#endif
+
if (flags & FRF_WRITE)
{
dialog = gtk_file_chooser_dialog_new (title, NULL,
diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-gtk/joind.c xchat-wdk/src/fe-gtk/joind.c
--- xchat-wdk.orig/src/fe-gtk/joind.c 2006-12-26 05:56:55 +0100
+++ xchat-wdk/src/fe-gtk/joind.c 2010-10-05 03:55:27 +0200
@ -1195,7 +1472,7 @@ diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-gtk/plugin-tray.c xchat-wdk/
return 1; /* return 1 for success */
diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-gtk/plugingui.c xchat-wdk/src/fe-gtk/plugingui.c
--- xchat-wdk.orig/src/fe-gtk/plugingui.c 2010-05-16 05:20:22 +0200
+++ xchat-wdk/src/fe-gtk/plugingui.c 2010-10-05 03:55:28 +0200
+++ xchat-wdk/src/fe-gtk/plugingui.c 2010-10-05 02:53:43 +0200
@@ -35,7 +35,7 @@
#include "../common/xchat.h"
#define PLUGIN_C
@ -1205,6 +1482,17 @@ diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-gtk/plugingui.c xchat-wdk/sr
#include "../common/plugin.h"
#include "../common/util.h"
#include "../common/outbound.h"
@@ -147,7 +147,9 @@
plugingui_load (void)
{
gtkutil_file_req (_("Select a Plugin or Script to load"), plugingui_load_cb,
- current_sess, NULL, FRF_ADDFOLDER);
+ current_sess,
+ "Plugins and Scripts\000" "*.dll;*.pl;*.tcl;*.py;*.lua\000"
+ "All files\000" "*.*\000", 0);
}
static void
diff -ruN --strip-trailing-cr xchat-wdk.orig/src/fe-gtk/rawlog.c xchat-wdk/src/fe-gtk/rawlog.c
--- xchat-wdk.orig/src/fe-gtk/rawlog.c 2010-05-16 05:20:22 +0200
+++ xchat-wdk/src/fe-gtk/rawlog.c 2010-10-05 03:55:28 +0200