native file open/save dialogs
This commit is contained in:
		
							parent
							
								
									b70d524749
								
							
						
					
					
						commit
						dede76e56a
					
				
					 4 changed files with 335 additions and 3 deletions
				
			
		
							
								
								
									
										33
									
								
								src/common/thread.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/common/thread.c
									
										
									
									
									
										Normal 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
									
								
							
							
						
						
									
										10
									
								
								src/common/thread.h
									
										
									
									
									
										Normal 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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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…
	
	Add table
		
		Reference in a new issue