native file open/save dialogs
This commit is contained in:
parent
b70d524749
commit
dede76e56a
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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 \
|
||||
|
|
292
xchat-wdk.patch
292
xchat-wdk.patch
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue