OSDN Git Service

LinGui: merge gtk mingw cross compiling support
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Thu, 16 Apr 2009 01:46:08 +0000 (01:46 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Thu, 16 Apr 2009 01:46:08 +0000 (01:46 +0000)
git-svn-id: svn://localhost/HandBrake/trunk@2332 b64f7644-9d1e-0410-96f1-a4d463321fa5

16 files changed:
gtk/configure.ac
gtk/module.defs
gtk/module.rules
gtk/src/Makefile.am
gtk/src/audiohandler.c
gtk/src/callbacks.c
gtk/src/callbacks.h
gtk/src/ghb-dvd.c
gtk/src/hb-backend.c
gtk/src/main.c
gtk/src/presets.c
gtk/src/preview.c
gtk/src/queuehandler.c
gtk/src/values.c
gtk/src/widgetdeps.c [moved from gtk/src/makedeps.c with 100% similarity]
gtk/src/x264handler.c

index c7e0ad6..7f3ca5f 100644 (file)
@@ -45,6 +45,10 @@ else
        AC_SUBST(HB_DIR, '$(top_srcdir)/'"..")
 fi
 
+AC_ARG_ENABLE(gst,
+       AS_HELP_STRING([--enable-gst], [enable gstreamer on Win32]),
+       w32_gst=yes, w32_gst=no)
+
 # overwrite global variable (used for Makefile generation)
 AC_SUBST(GLOBALCXXFLAGS, $CXXFLAGS )
 AC_SUBST(GLOBALLDFLAGS, $LDFLAGS )
@@ -60,23 +64,35 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name])
 AM_GLIB_GNU_GETTEXT
 IT_PROG_INTLTOOL([0.35.0])
 
-
-
 AM_PROG_LIBTOOL
 
+case $host in
+  *-*-mingw*)
+    if test "x$w32_gst" = "xyes" ; then
+               GHB_PACKAGES="gtk+-2.0 >= 2.8 gthread-2.0 gstreamer-0.10 gstreamer-interfaces-0.10 gstreamer-video-0.10 gstreamer-pbutils-0.10 gio-2.0 hal hal-storage libgtkhtml-3.14"
+       else
+        GHB_PACKAGES="gtk+-2.0 >= 2.8 gthread-2.0 gio-2.0"
+       fi
+       mingw_flag=yes
+    ;;
+  *)
+       GHB_PACKAGES="gtk+-2.0 >= 2.8 gthread-2.0 gstreamer-0.10 gstreamer-interfaces-0.10 gstreamer-video-0.10 gstreamer-pbutils-0.10 gio-2.0 hal hal-storage libgtkhtml-3.14 libnotify"
+       mingw_flag=no
+    ;;
+esac
+
+if test "x$w32_gst" = "xyes" -o  "x$mingw_flag" != "xyes" ; then
+       CXXFLAGS="$CXXFLAGS -D_ENABLE_GST"
+       CFLAGS="$CFLAGS -D_ENABLE_GST"
+fi
 
+AM_CONDITIONAL([MINGW], [test "x$mingw_flag" = "xyes"])
 
-PKG_CHECK_MODULES(GHBTOOLS, [glib-2.0 gobject-2.0 gdk-pixbuf-2.0])
-AC_SUBST(GHBTOOLS_CFLAGS)
-AC_SUBST(GHBTOOLS_LIBS)
+PKG_CHECK_MODULES(GHB, [$GHB_PACKAGES])
 
-PKG_CHECK_MODULES(GHB, [gtk+-2.0 >= 2.8 gthread-2.0 gstreamer-0.10 gstreamer-interfaces-0.10 gstreamer-video-0.10 gstreamer-pbutils-0.10 gio-2.0 hal hal-storage libgtkhtml-3.14 libnotify ])
 AC_SUBST(GHB_CFLAGS)
 AC_SUBST(GHB_LIBS)
 
-
-
-
 AC_OUTPUT([
 Makefile
 src/Makefile
index 7550a82..8c1648d 100644 (file)
@@ -11,3 +11,59 @@ GTK.CONFIGURE.stamp = $(GTK.build/).stamp.configure
 GTK.out += $(GTK.CONFIGURE.stamp)
 
 BUILD.out += $(GTK.out)
+
+###############################################################################
+
+ifeq (1-mingw,$(BUILD.cross)-$(BUILD.system))
+    GTK.GCC.D += PTW32_STATIC_LIB
+endif
+
+
+###############################################################################
+###############################################################################
+$(eval $(call import.MODULE.defs,HGTK,hgtk))
+$(eval $(call import.GCC,HGTK))
+
+HGTK.GCC.gcc = gcc
+HGTK.GCC.args.extra = $(shell pkg-config --cflags glib-2.0)
+HGTK.GCC.args.extra += $(shell pkg-config --cflags gdk-pixbuf-2.0)
+HGTK.GCC.args.extra += $(shell pkg-config --libs glib-2.0)
+HGTK.GCC.args.extra += $(shell pkg-config --libs gdk-pixbuf-2.0)
+
+HGTK.src/ = $(SRC/)gtk/src/
+HGTK.build/ = $(BUILD/)gtk/src/
+
+HGTKCOMMON.c = \
+       $(HGTK.src/)plist.c \
+       $(HGTK.src/)values.c
+
+HGTKCOMMON.c.o = $(patsubst $(SRC/)%.c,$(BUILD/)%-native.o,$(HGTKCOMMON.c))
+
+CREATE_RES.c = \
+       $(HGTK.src/)create_resources.c \
+       $(HGTK.src/)icon_tools.c
+
+CREATE_RES.c.o = $(patsubst $(SRC/)%.c,$(BUILD/)%-native.o,$(CREATE_RES.c))
+CREATE_RES.exe = $(HGTK.build/)create_resources
+
+WIDGETDEPS.c = \
+       $(HGTK.src/)widgetdeps.c
+
+WIDGETDEPS.c.o = $(patsubst $(SRC/)%.c,$(BUILD/)%-native.o,$(WIDGETDEPS.c))
+WIDGETDEPS.exe = $(HGTK.build/)widgetdeps
+
+QUOTESTRING.c = \
+       $(HGTK.src/)quotestring.c
+
+QUOTESTRING.c.o = $(patsubst $(SRC/)%.c,$(BUILD/)%-native.o,$(QUOTESTRING.c))
+QUOTESTRING.exe = $(HGTK.build/)quotestring
+
+HGTK.out += $(HGTKCOMMON.c.o)
+HGTK.out += $(CREATE_RES.exe)
+HGTK.out += $(CREATE_RES.c.o)
+HGTK.out += $(WIDGETDEPS.exe)
+HGTK.out += $(WIDGETDEPS.c.o)
+HGTK.out += $(QUOTESTRING.exe)
+HGTK.out += $(QUOTESTRING.c.o)
+
+BUILD.out += $(HGTK.out)
index 3fd03e1..ddf9bcc 100644 (file)
@@ -1,10 +1,10 @@
 $(eval $(call import.MODULE.rules,GTK))
 
-build: gtk.build
+build: hgtk.build gtk.build
 install: gtk.install
 uninstall: gtk.uninstall
-clean: gtk.clean
-xclean: gtk.xclean
+clean: hgtk.clean gtk.clean
+xclean: hgtk.clean gtk.xclean
 
 gtk.configure: $(GTK.CONFIGURE.stamp)
 
@@ -12,12 +12,22 @@ $(GTK.CONFIGURE.stamp): | $(dir $(GTK.CONFIGURE.stamp))
 $(GTK.CONFIGURE.stamp): $(GTK.src/)Makefile.am
 $(GTK.CONFIGURE.stamp): $(GTK.src/)configure.ac $(GTK.src/)src/Makefile.am
        set -e; cd $(GTK.src/); NOCONFIGURE=1 ./autogen.sh
+ifeq (1-mingw,$(BUILD.cross)-$(BUILD.system))
        set -e; cd $(GTK.build/); $(call fn.ABSOLUTE,$(GTK.src/))configure \
-               PKG_CONFIG_DIR=$(BUILD/)contrib/lib/pkgconfig \
-           CFLAGS="$(call fn.ARGS,GTK.GCC,.g .O)" \
+               --host=$(BUILD.spec) \
+               PKG_CONFIG_PATH=$(BUILD/)contrib/lib/pkgconfig \
+           CFLAGS="$(call fn.ARGS,GTK.GCC,.g .O *D ?extra)" \
+           LDFLAGS="$(call fn.ARGS,GTK.GCC,?strip .g .O) " \
+           --prefix=$(PREFIX) \
+           --with-hb=$(call fn.ABSOLUTE,$(BUILD/))
+else
+       set -e; cd $(GTK.build/); $(call fn.ABSOLUTE,$(GTK.src/))configure \
+               PKG_CONFIG_PATH=$(BUILD/)contrib/lib/pkgconfig \
+           CFLAGS="$(call fn.ARGS,GTK.GCC,.g .O ?extra)" \
            LDFLAGS="$(call fn.ARGS,GTK.GCC,?strip .g .O)" \
            --prefix=$(PREFIX) \
            --with-hb=$(call fn.ABSOLUTE,$(BUILD/))
+endif
        $(TOUCH.exe) $@
 
 gtk.build: | $(GTK.build/)
@@ -37,3 +47,40 @@ gtk.xclean:
        $(MAKE) -C $(GTK.build/) distclean
        $(RM.exe) -f $(GTK.out)
        $(RM.exe) -fr $(GTK.build/)
+
+###############################################################################
+###############################################################################
+$(eval $(call import.MODULE.rules,HGTK))
+
+hgtk.build: $(CREATE_RES.exe) $(WIDGETDEPS.exe) $(QUOTESTRING.exe)
+
+$(CREATE_RES.exe): | $(dir $(CREATE_RES.exe))
+$(CREATE_RES.exe): $(CREATE_RES.c.o) $(HGTKCOMMON.c.o)
+       $(call HGTK.GCC.EXE,$@,$^)
+
+$(HGTKCOMMON.c.o): | $(dir $(HGTKCOMMON.c.o))
+$(HGTKCOMMON.c.o): $(BUILD/)%-native.o: $(SRC/)%.c
+       $(call HGTK.GCC.C_O,$@,$<)
+
+$(CREATE_RES.c.o): | $(dir $(CREATE_RES.c.o))
+$(CREATE_RES.c.o): $(BUILD/)%-native.o: $(SRC/)%.c
+       $(call HGTK.GCC.C_O,$@,$<)
+
+$(WIDGETDEPS.exe): | $(dir $(WIDGETDEPS.exe))
+$(WIDGETDEPS.exe): $(WIDGETDEPS.c.o) $(HGTKCOMMON.c.o)
+       $(call HGTK.GCC.EXE,$@,$^)
+
+$(WIDGETDEPS.c.o): | $(dir $(WIDGETDEPS.c.o))
+$(WIDGETDEPS.c.o): $(BUILD/)%-native.o: $(SRC/)%.c
+       $(call HGTK.GCC.C_O,$@,$<)
+
+$(QUOTESTRING.c.o): | $(dir $(QUOTESTRING.c.o))
+$(QUOTESTRING.c.o): $(BUILD/)%-native.o: $(SRC/)%.c
+       $(call HGTK.GCC.C_O,$@,$<)
+
+$(QUOTESTRING.exe): | $(dir $(QUOTESTRING.exe))
+$(QUOTESTRING.exe): $(QUOTESTRING.c.o)
+       $(call HGTK.GCC.EXE,$@,$^)
+
+hgtk.clean:
+       $(RM.exe) -f $(HGTK.out)
index 8abcc6f..b6e6f52 100644 (file)
@@ -1,30 +1,18 @@
 ## Process this file with automake to produce Makefile.in
 
-HB_LIBS=\
-       -lhb \
-       -la52 \
-       -lmkv \
-       -lavformat \
-       -lavcodec \
-       -lavutil \
-       -ldca \
-       -ldvdread \
-       -lfaac \
-       -lmp3lame \
-       -lmpeg2 \
-       -lvorbis \
-       -lvorbisenc \
-       -logg \
-       -lsamplerate \
-       -lx264 \
-       -lxvidcore \
-       -lmp4v2 \
-       -lswscale \
-       -ltheora \
-       -lfaad \
-       -lz \
-       -lbz2 \
-       -lpthread
+if MINGW
+HB_LIBS= \
+       -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -ldca -ldvdread \
+       -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate \
+       -lx264 -lxvidcore -lmp4v2 -lswscale -ltheora -lfaad -lz \
+       -lbz2 -liberty -lpthreadGC2
+else
+HB_LIBS= \
+       -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -ldca -ldvdread \
+       -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate \
+       -lx264 -lxvidcore -lmp4v2 -lswscale -ltheora -lfaad -lz \
+       -lbz2 -liberty -lpthread
+endif
 
 icons =        \
        hb-icon.128.png 
@@ -66,13 +54,9 @@ AM_CPPFLAGS = \
        -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
        $(GHB_CFLAGS)
 
-AM_CFLAGS =\
-        -Wall\
-        -g
+AM_CFLAGS = -Wall -g
 
 bin_PROGRAMS = ghb 
-noinst_PROGRAMS = makewidgetdeps quotestring create_resources preset_xlat \
-       resource_data.h resources.plist widget.deps widget_reverse.deps
 
 # Dummy file, not built.  Forces g++ linking
 nodist_EXTRA_ghb_SOURCES = dummy.cpp
@@ -117,54 +101,26 @@ ghb_SOURCES = \
        marshalers.c \
        marshalers.h
 
+if MINGW
+ghb_LDFLAGS = \
+       -mwindows -Wl,--export-dynamic -Wl,--exclude-libs,ALL
+else
 ghb_LDFLAGS = \
        -Wl,--export-dynamic -Wl,--exclude-libs,ALL
+endif
 
 ghb_LDADD = $(HB_LIBS) $(GHB_LIBS)
 
 ghb_DEPENDENCIES = $(HB_DIR)/libhb/libhb.a
 
-makewidgetdeps_SOURCES = \
-       plist.c \
-       plist.h \
-       values.c \
-       values.h \
-       makedeps.c 
-
-makewidgetdeps_LDADD = $(GHBTOOLS_LIBS)
-
-create_resources_SOURCES = \
-       create_resources.c \
-       plist.c \
-       plist.h \
-       values.c \
-       values.h \
-       icon_tools.c \
-       icon_tools.h
-
-create_resources_LDADD = $(GHBTOOLS_LIBS)
-
-preset_xlat_SOURCES = \
-       preset_xlat.c \
-       plist.c \
-       plist.h \
-       values.c \
-       values.h
-
-preset_xlat_LDADD = $(GHBTOOLS_LIBS)
-
-quotestring_SOURCES = quotestring.c
-
-dumbell: preset_xlat
-
 resources.o: resource_data.h
 
 resource_data.h: quotestring resources.plist
        ./quotestring resources.plist resource_data.h
 
-widget_reverse.deps: makewidgetdeps
-widget.deps: makewidgetdeps
-       ./makewidgetdeps
+widget_reverse.deps: widgetdeps
+widget.deps: widgetdeps
+       ./widgetdeps
 
 resources.plist: create_resources resources.list $(icons_dep) internal_defaults.xml standard_presets.xml ghb.ui widget.deps widget_reverse.deps
        ./create_resources -I$(srcdir) $(srcdir)/resources.list resources.plist
index 1ffbf8d..adfc79b 100644 (file)
@@ -281,7 +281,7 @@ audio_list_refresh_selected(signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        static gint prev_acodec = 0;
@@ -337,7 +337,7 @@ audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_live_reset(ud);
 }
 
-void
+G_MODULE_EXPORT void
 audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        GValue *asettings;
@@ -359,7 +359,7 @@ audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_live_reset(ud);
 }
 
-void
+G_MODULE_EXPORT void
 audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        GValue *asettings;
@@ -376,7 +376,7 @@ audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_live_reset(ud);
 }
 
-void
+G_MODULE_EXPORT void
 audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        GValue *asettings;
@@ -392,7 +392,7 @@ audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_live_reset(ud);
 }
 
-void
+G_MODULE_EXPORT void
 drc_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        GValue *asettings;
@@ -418,7 +418,7 @@ drc_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 // the selection is updated automaitcally when the title
 // changes.  I don't want the preset selection changed as
 // would happen for regular settings.
-void
+G_MODULE_EXPORT void
 subtitle_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        const gchar *name = gtk_widget_get_name(widget);
@@ -508,7 +508,7 @@ add_to_audio_list(signal_user_data_t *ud, GValue *settings)
        g_free(s_mix);
 }
 
-void
+G_MODULE_EXPORT void
 audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
 {
        GtkTreeModel *store;
@@ -545,7 +545,7 @@ audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t
        }
 }
 
-void
+G_MODULE_EXPORT void
 audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        // Add the current audio settings to the list.
@@ -588,7 +588,7 @@ audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        GtkTreeView *treeview;
index 166b8c6..42f7b6a 100644 (file)
 #endif
 
 #include <string.h>
-#include <poll.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+
+#if !defined(_WIN32)
+#include <poll.h>
+#include <libhal-storage.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
 #include <netinet/in.h>
 #include <netdb.h>
-#include <libhal-storage.h>
-#include <gtk/gtk.h>
 #include <gtkhtml/gtkhtml.h>
+#include <libnotify/notify.h>
+#else
+#define WINVER 0x0500
+#include <winsock2.h>
+#include <dbt.h>
+#endif
+
+#include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 #include <glib/gstdio.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
 #include <gio/gio.h>
-#include <libnotify/notify.h>
 
 #include "hb.h"
 #include "callbacks.h"
@@ -260,7 +269,7 @@ ghb_check_all_depencencies(signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 on_quit1_activate(GtkMenuItem *quit, signal_user_data_t *ud)
 {
        gint state = ghb_get_queue_state();
@@ -412,29 +421,110 @@ get_file_label(const gchar *filename)
        return base;
 }
 
+static gchar*
+get_drive_name(const gchar *drive)
+{
+       gchar *result;
+#if defined(_WIN32)
+       gchar vname[51], fsname[51];
+       if (GetVolumeInformation(drive, vname, 50, NULL, NULL, NULL, fsname, 51))
+       {
+               result = g_strdup_printf("%s (%s)", vname, drive);
+       }
+       else
+       {
+               result = g_strdup_printf("%s", drive);
+       }
+#else
+       result = g_strdup_printf("%s", drive);
+#endif
+       return result;
+}
+
+static gchar*
+resolve_drive_name(gchar *filename)
+{
+#if defined(_WIN32)
+       if (filename[1] == ':')
+       {
+               gchar drive[4];
+               gchar *name;
+               gint dtype;
+
+               g_strlcpy(drive, filename, 4);
+               dtype = GetDriveType(drive);
+               if (dtype == DRIVE_CDROM)
+               {
+                       gchar vname[51], fsname[51];
+                       GetVolumeInformation(drive, vname, 50, NULL, 
+                                                               NULL, NULL, fsname, 50);
+                       name = g_strdup(vname);
+                       return name;
+               }
+       }
+       return NULL;
+#else
+       return NULL;
+#endif
+}
+
 static gboolean
 update_source_label(signal_user_data_t *ud, const gchar *source)
 {
        gchar *label = NULL;
        gint len;
        gchar **path;
+       gchar *start;
        gchar *filename = g_strdup(source);
        
        len = strlen(filename);
-       if (filename[len-1] == '/') filename[len-1] = 0;
+       if (filename[len-1] == G_DIR_SEPARATOR) filename[len-1] = 0;
        if (g_file_test(filename, G_FILE_TEST_IS_DIR))
        {
-               path = g_strsplit(filename, "/", -1);
-               len = g_strv_length (path);
-               if ((len > 1) && (strcmp("VIDEO_TS", path[len-1]) == 0))
+               // Skip dos drive letters
+               start = strchr(filename, ':');
+               label = resolve_drive_name(filename);
+               if (label != NULL)
                {
-                       label = g_strdup(path[len-2]);
+                       if (uppers_and_unders(label))
+                       {
+                               camel_convert(label);
+                       }
                }
                else
                {
-                       label = g_strdup(path[len-1]);
+                       if (start != NULL)
+                               start++;
+                       else
+                               start = filename;
+                       
+                       path = g_strsplit(start, G_DIR_SEPARATOR_S, -1);
+                       len = g_strv_length (path);
+                       if ((len > 1) && (strcmp("VIDEO_TS", path[len-1]) == 0))
+                       {
+                               label = g_strdup(path[len-2]);
+                               if (uppers_and_unders(label))
+                               {
+                                       camel_convert(label);
+                               }
+                       }
+                       else if (len > 0)
+                       {
+                               if (path[len-1][0] != 0)
+                               {
+                                       label = g_strdup(path[len-1]);
+                                       if (uppers_and_unders(label))
+                                       {
+                                               camel_convert(label);
+                                       }
+                               }
+                               else
+                                       label = g_strdup("new_video");
+                       }
+                       else
+                               label = g_strdup("new_video");
+                       g_strfreev (path);
                }
-               g_strfreev (path);
        }
        else
        {
@@ -472,7 +562,7 @@ update_source_label(signal_user_data_t *ud, const gchar *source)
        return TRUE;
 }
 
-void
+G_MODULE_EXPORT void
 chooser_file_selected_cb(GtkFileChooser *dialog, signal_user_data_t *ud)
 {
        const gchar *name = gtk_file_chooser_get_filename (dialog);
@@ -503,7 +593,7 @@ chooser_file_selected_cb(GtkFileChooser *dialog, signal_user_data_t *ud)
                gtk_combo_box_set_active (combo, 0);
 }
 
-void
+G_MODULE_EXPORT void
 dvd_device_changed_cb(GtkComboBox *combo, signal_user_data_t *ud)
 {
        GtkWidget *dialog;
@@ -522,7 +612,7 @@ dvd_device_changed_cb(GtkComboBox *combo, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 source_type_changed_cb(GtkToggleButton *toggle, signal_user_data_t *ud)
 {
        gchar *folder;
@@ -715,19 +805,19 @@ do_source_dialog(GtkButton *button, gboolean single, signal_user_data_t *ud)
        g_free(sourcename);
 }
 
-void
+G_MODULE_EXPORT void
 source_button_clicked_cb(GtkButton *button, signal_user_data_t *ud)
 {
        do_source_dialog(button, FALSE, ud);
 }
 
-void
+G_MODULE_EXPORT void
 single_title_source_cb(GtkButton *button, signal_user_data_t *ud)
 {
        do_source_dialog(button, TRUE, ud);
 }
 
-void
+G_MODULE_EXPORT void
 dvd_source_activate_cb(GtkAction *action, signal_user_data_t *ud)
 {
        const gchar *filename;
@@ -803,7 +893,7 @@ destination_select_title(GtkEntry *entry)
        }
        for (start = end; start >= 0; start--)
        {
-               if (dest[start] == '/')
+               if (dest[start] == G_DIR_SEPARATOR)
                {
                        start++;
                        break;
@@ -816,7 +906,7 @@ destination_select_title(GtkEntry *entry)
        }
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 destination_grab_cb(
        GtkEntry *entry, 
        signal_user_data_t *ud)
@@ -827,7 +917,7 @@ destination_grab_cb(
 
 static gboolean update_default_destination = FALSE;
 
-void
+G_MODULE_EXPORT void
 dest_dir_set_cb(GtkFileChooserButton *dest_chooser, signal_user_data_t *ud)
 {
        gchar *dest_file, *dest_dir, *dest;
@@ -836,7 +926,7 @@ dest_dir_set_cb(GtkFileChooserButton *dest_chooser, signal_user_data_t *ud)
        ghb_widget_to_setting(ud->settings, (GtkWidget*)dest_chooser);
        dest_file = ghb_settings_get_string(ud->settings, "dest_file");
        dest_dir = ghb_settings_get_string(ud->settings, "dest_dir");
-       dest = g_strdup_printf("%s/%s", dest_dir, dest_file);
+       dest = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dest_dir, dest_file);
        ghb_settings_set_string(ud->settings, "destination", dest);
        g_free(dest_file);
        g_free(dest_dir);
@@ -844,7 +934,7 @@ dest_dir_set_cb(GtkFileChooserButton *dest_chooser, signal_user_data_t *ud)
        update_default_destination = TRUE;
 }
 
-void
+G_MODULE_EXPORT void
 dest_file_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
 {
        gchar *dest_file, *dest_dir, *dest;
@@ -856,7 +946,7 @@ dest_file_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
        // update on the timer.
        dest_file = ghb_settings_get_string(ud->settings, "dest_file");
        dest_dir = ghb_settings_get_string(ud->settings, "dest_dir");
-       dest = g_strdup_printf("%s/%s", dest_dir, dest_file);
+       dest = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dest_dir, dest_file);
        ghb_settings_set_string(ud->settings, "destination", dest);
        g_free(dest_file);
        g_free(dest_dir);
@@ -864,7 +954,7 @@ dest_file_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
        update_default_destination = TRUE;
 }
 
-void
+G_MODULE_EXPORT void
 destination_browse_clicked_cb(GtkButton *button, signal_user_data_t *ud)
 {
        GtkWidget *dialog;
@@ -904,7 +994,7 @@ destination_browse_clicked_cb(GtkButton *button, signal_user_data_t *ud)
        gtk_widget_destroy(dialog);
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 window_destroy_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *ud)
 {
        g_debug("window_destroy_event_cb ()");
@@ -914,7 +1004,7 @@ window_destroy_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *
        return FALSE;
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 window_delete_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *ud)
 {
        gint state = ghb_get_queue_state();
@@ -942,7 +1032,7 @@ update_acodec_combo(signal_user_data_t *ud)
        ghb_grey_combo_options (ud->builder);
 }
 
-void
+G_MODULE_EXPORT void
 container_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        const GValue *audio_list;
@@ -1087,7 +1177,7 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
 
 static gboolean update_preview = FALSE;
 
-void
+G_MODULE_EXPORT void
 title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_title_info_t tinfo;
@@ -1133,7 +1223,7 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 setting_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
@@ -1142,7 +1232,7 @@ setting_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_live_reset(ud);
 }
 
-void
+G_MODULE_EXPORT void
 vquality_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
@@ -1166,7 +1256,7 @@ vquality_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        gtk_range_set_value(GTK_RANGE(widget), val);
 }
 
-void
+G_MODULE_EXPORT void
 http_opt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
@@ -1177,7 +1267,7 @@ http_opt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_grey_combo_options (ud->builder);
 }
 
-void
+G_MODULE_EXPORT void
 vcodec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        gdouble vqmin, vqmax, step, page;
@@ -1196,7 +1286,7 @@ vcodec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        gtk_range_set_inverted (GTK_RANGE(qp), inverted);
 }
 
-void
+G_MODULE_EXPORT void
 target_size_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        const gchar *name = gtk_widget_get_name(widget);
@@ -1214,7 +1304,7 @@ target_size_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 start_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        gint start, end;
@@ -1233,7 +1323,7 @@ start_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 end_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        gint start, end;
@@ -1252,7 +1342,7 @@ end_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 scale_width_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("scale_width_changed_cb ()");
@@ -1272,7 +1362,7 @@ scale_width_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_live_reset(ud);
 }
 
-void
+G_MODULE_EXPORT void
 scale_height_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("scale_height_changed_cb ()");
@@ -1292,7 +1382,7 @@ scale_height_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_live_reset(ud);
 }
 
-void
+G_MODULE_EXPORT void
 crop_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        gint titleindex, crop[4];
@@ -1331,7 +1421,7 @@ crop_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_live_reset(ud);
 }
 
-void
+G_MODULE_EXPORT void
 display_width_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("scale_changed_cb ()");
@@ -1425,7 +1515,7 @@ scale_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        gtk_label_set_text (GTK_LABEL(widget), text);
 }
 
-void
+G_MODULE_EXPORT void
 generic_entry_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
 {
        // Normally (due to user input) I only want to process the entry
@@ -1442,7 +1532,7 @@ generic_entry_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 prefs_dialog_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkWidget *dialog;
@@ -2007,7 +2097,7 @@ ghb_backend_events(signal_user_data_t *ud)
        }
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 ghb_timer_cb(gpointer data)
 {
        signal_user_data_t *ud = (signal_user_data_t*)data;
@@ -2038,7 +2128,7 @@ ghb_timer_cb(gpointer data)
        return TRUE;
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 ghb_log_cb(GIOChannel *source, GIOCondition cond, gpointer data)
 {
        gchar *text = NULL;
@@ -2092,13 +2182,25 @@ ghb_log_cb(GIOChannel *source, GIOCondition cond, gpointer data)
                        gtk_text_view_scroll_mark_onscreen(textview, mark);
                        gtk_text_buffer_delete_mark(buffer, mark);
                }
+#if defined(_WIN32)
+               gsize one = 1;
+               text[length-1] = '\r';
+#endif
                g_io_channel_write_chars (ud->activity_log, text, 
                                                                length, &length, NULL);
+#if defined(_WIN32)
+               g_io_channel_write_chars (ud->activity_log, "\n", 
+                                                               one, &one, NULL);
+#endif
                g_io_channel_flush(ud->activity_log, NULL);
                if (ud->job_activity_log)
                {
                        g_io_channel_write_chars (ud->job_activity_log, text, 
                                                                        length, &length, NULL);
+#if defined(_WIN32)
+                       g_io_channel_write_chars (ud->activity_log, "\n", 
+                                                                       one, &one, NULL);
+#endif
                        g_io_channel_flush(ud->job_activity_log, NULL);
                }
                g_free(text);
@@ -2133,7 +2235,7 @@ set_visible(GtkWidget *widget, gboolean visible)
        }
 }
 
-void
+G_MODULE_EXPORT void
 show_activity_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkWidget *widget = GHB_WIDGET (ud->builder, "activity_window");
@@ -2141,7 +2243,7 @@ show_activity_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
                                                GTK_TOGGLE_TOOL_BUTTON(xwidget)));
 }
 
-void
+G_MODULE_EXPORT void
 show_activity_menu_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkWidget *widget = GHB_WIDGET (ud->builder, "activity_window");
@@ -2150,7 +2252,7 @@ show_activity_menu_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
        gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), TRUE);
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 activity_window_delete_cb(GtkWidget *xwidget, GdkEvent *event, signal_user_data_t *ud)
 {
        set_visible(xwidget, FALSE);
@@ -2212,7 +2314,7 @@ about_web_hook(GtkAboutDialog *about, const gchar *link, gpointer data)
        browse_url(link);
 }
 
-void
+G_MODULE_EXPORT void
 about_activate_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkWidget *widget = GHB_WIDGET (ud->builder, "hb_about");
@@ -2229,19 +2331,19 @@ about_activate_cb(GtkWidget *xwidget, signal_user_data_t *ud)
        gtk_widget_show (widget);
 }
 
-void
+G_MODULE_EXPORT void
 guide_activate_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        browse_url("http://trac.handbrake.fr/wiki/HandBrakeGuide");
 }
 
-void
+G_MODULE_EXPORT void
 hb_about_response_cb(GtkWidget *widget, gint response, signal_user_data_t *ud)
 {
        gtk_widget_hide (widget);
 }
 
-void
+G_MODULE_EXPORT void
 show_queue_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkWidget *widget = GHB_WIDGET (ud->builder, "queue_window");
@@ -2249,7 +2351,7 @@ show_queue_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
                                                GTK_TOGGLE_TOOL_BUTTON(xwidget)));
 }
 
-void
+G_MODULE_EXPORT void
 show_queue_menu_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkWidget *widget = GHB_WIDGET (ud->builder, "queue_window");
@@ -2258,7 +2360,7 @@ show_queue_menu_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
        gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), TRUE);
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 queue_window_delete_cb(GtkWidget *xwidget, GdkEvent *event, signal_user_data_t *ud)
 {
        set_visible(xwidget, FALSE);
@@ -2267,7 +2369,7 @@ queue_window_delete_cb(GtkWidget *xwidget, GdkEvent *event, signal_user_data_t *
        return TRUE;
 }
 
-void
+G_MODULE_EXPORT void
 show_presets_toggled_cb(GtkWidget *action, signal_user_data_t *ud)
 {
        GtkWidget *widget;
@@ -2369,7 +2471,7 @@ update_chapter_list(signal_user_data_t *ud)
 
 static gint chapter_edit_key = 0;
 
-gboolean
+G_MODULE_EXPORT gboolean
 chapter_keypress_cb(
        GhbCellRendererText *cell,
        GdkEventKey *event,
@@ -2379,7 +2481,7 @@ chapter_keypress_cb(
        return FALSE;
 }
 
-void
+G_MODULE_EXPORT void
 chapter_edited_cb(
        GhbCellRendererText *cell, 
        gchar *path, 
@@ -2458,7 +2560,7 @@ chapter_edited_cb(
        gtk_tree_path_free (treepath);
 }
 
-void
+G_MODULE_EXPORT void
 chapter_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
 {
        g_debug("chapter_list_selection_changed_cb ()");
@@ -2479,7 +2581,6 @@ debug_log_handler(const gchar *domain, GLogLevelFlags flags, const gchar *msg, g
 void
 warn_log_handler(const gchar *domain, GLogLevelFlags flags, const gchar *msg, gpointer data)
 {
-       printf("mywarning\n");
        printf("%s: %s\n", domain, msg);
 }
 
@@ -2512,7 +2613,7 @@ ghb_hbfd(signal_user_data_t *ud, gboolean hbfd)
 
 }
 
-void
+G_MODULE_EXPORT void
 hbfd_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("hbfd_toggled_cb");
@@ -2522,7 +2623,7 @@ hbfd_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_pref_save(ud->settings, "hbfd");
 }
 
-void
+G_MODULE_EXPORT void
 pref_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("pref_changed_cb");
@@ -2532,7 +2633,7 @@ pref_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_pref_save(ud->settings, name);
 }
 
-void
+G_MODULE_EXPORT void
 vqual_granularity_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("vqual_granularity_changed_cb");
@@ -2551,7 +2652,7 @@ vqual_granularity_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        gtk_range_set_increments (GTK_RANGE(qp), step, page);
 }
 
-void
+G_MODULE_EXPORT void
 tweaks_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("tweaks_changed_cb");
@@ -2560,7 +2661,7 @@ tweaks_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_pref_save(ud->settings, name);
 }
 
-void
+G_MODULE_EXPORT void
 hbfd_feature_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("hbfd_feature_changed_cb");
@@ -2594,20 +2695,30 @@ ghb_file_menu_add_dvd(signal_user_data_t *ud)
        link = drives = dvd_device_list();
        while (link != NULL)
        {
-               gchar *name = (gchar*)link->data;
+               GtkAction *action;
+               gchar *drive = (gchar*)link->data;
+               gchar *name = get_drive_name(drive);
+               
+               action = gtk_action_group_get_action(agroup, drive);
+               if (action != NULL)
+               {
+                       gtk_action_group_remove_action(agroup, action);
+                       g_object_unref(G_OBJECT(action));
+               }
                // Create action for this drive
-               GtkAction *action = gtk_action_new(name, name,
+               action = gtk_action_new(drive, name,
                        "Scan this DVD source", "gtk-cdrom");
                // Add action to action group
-               gtk_action_group_add_action_with_accel(agroup, action, "");
+               gtk_action_group_add_action_with_accel(agroup, action, NULL);
                // Add to ui manager
                gtk_ui_manager_add_ui(ui, merge_id, 
-                       "ui/menubar1/menuitem1/quit1", name, name,
+                       "ui/menubar1/menuitem1/quit1", drive, drive,
                        GTK_UI_MANAGER_AUTO, TRUE);
                // Connect signal to action (menu item)
                g_signal_connect(action, "activate", 
                        (GCallback)dvd_source_activate_cb, ud);
                g_free(name);
+               g_free(drive);
                link = link->next;
        }
        g_list_free(drives);
@@ -2623,9 +2734,33 @@ gboolean ghb_is_cd(GDrive *gd);
 static GList*
 dvd_device_list()
 {
+       GList *dvd_devices = NULL;
+
+#if defined(_WIN32)
+       gint ii, drives;
+       gchar drive[5];
+
+       strcpy(drive, "A:" G_DIR_SEPARATOR_S);
+       drives = GetLogicalDrives();
+       for (ii = 0; ii < 26; ii++)
+       {
+               if (drives & 0x01)
+               {
+                       guint dtype;
+
+                       drive[0] = 'A' + ii;
+                       dtype = GetDriveType(drive);
+                       if (dtype == DRIVE_CDROM)
+                       {
+                               dvd_devices = g_list_append(dvd_devices, 
+                                               (gpointer)g_strdup(drive));
+                       }
+               }
+               drives >>= 1;
+       }
+#else
        GVolumeMonitor *gvm;
        GList *drives, *link;
-       GList *dvd_devices = NULL;
        
        gvm = g_volume_monitor_get ();
        drives = g_volume_monitor_get_connected_drives (gvm);
@@ -2645,14 +2780,19 @@ dvd_device_list()
                link = link->next;
        }
        g_list_free(drives);
+#endif
+
        return dvd_devices;
 }
 
+#if !defined(_WIN32)
 static LibHalContext *hal_ctx;
+#endif
 
 gboolean
 ghb_is_cd(GDrive *gd)
 {
+#if !defined(_WIN32)
        gchar *device;
        LibHalDrive *halDrive;
        LibHalDriveType dtype;
@@ -2663,9 +2803,120 @@ ghb_is_cd(GDrive *gd)
        libhal_drive_free(halDrive);
        g_free(device);
        return (dtype == LIBHAL_DRIVE_TYPE_CDROM);
+#else
+       return FALSE;
+#endif
+}
+
+#if defined(_WIN32)
+static void
+handle_media_change(const gchar *device, gboolean insert, signal_user_data_t *ud)
+{
+       guint dtype;
+       static gint ins_count = 0;
+       static gint rem_count = 0;
+
+       // DVD insertion detected.  Scan it.
+       dtype = GetDriveType(device);
+       if (dtype != DRIVE_CDROM)
+               return;
+       if (insert)
+       {
+               rem_count = 0;
+               ins_count++;
+               if (ins_count == 2)
+               {
+                       ghb_file_menu_add_dvd(ud);
+                       if (ud->current_dvd_device != NULL &&
+                               strcmp(device, ud->current_dvd_device) == 0)
+                       {
+                               GtkProgressBar *progress;
+                               progress = GTK_PROGRESS_BAR(GHB_WIDGET (ud->builder, "progressbar"));
+                               gtk_progress_bar_set_text (progress, "Scanning ...");
+                               gtk_progress_bar_set_fraction (progress, 0);
+                               update_source_label(ud, device);
+                               ghb_hb_cleanup(TRUE);
+                               prune_logs(ud);
+                               gint preview_count;
+                               preview_count = ghb_settings_get_int(ud->settings, "preview_count");
+                               ghb_backend_scan(device, 0, preview_count);
+                       }
+               }
+       }
+       else
+       {
+               ins_count = 0;
+               rem_count++;
+               if (rem_count == 2)
+               {
+                       ghb_file_menu_add_dvd(ud);
+                       if (ud->current_dvd_device != NULL &&
+                               strcmp(device, ud->current_dvd_device) == 0)
+                       {
+                               ghb_hb_cleanup(TRUE);
+                               prune_logs(ud);
+                               ghb_backend_scan("/dev/null", 0, 1);
+                       }
+               }
+       }
+}
+
+static gchar
+FindDriveFromMask(ULONG unitmask)
+{
+       gchar cc;
+       for (cc = 0; cc < 26; cc++)
+       {
+               if (unitmask & 0x01)
+                       return 'A' + cc;
+               unitmask >>= 1;
+       }
+       return 0;
 }
 
 void
+wm_drive_changed(MSG *msg, signal_user_data_t *ud)
+{
+       PDEV_BROADCAST_HDR bch = (PDEV_BROADCAST_HDR)msg->lParam;
+       gchar drive[4];
+
+       g_strlcpy(drive, "A:" G_DIR_SEPARATOR_S, 4);
+       switch (msg->wParam)
+       {
+               case DBT_DEVICEARRIVAL:
+               {
+                       if (bch->dbch_devicetype == DBT_DEVTYP_VOLUME)
+                       {
+                               PDEV_BROADCAST_VOLUME bcv = (PDEV_BROADCAST_VOLUME)bch;
+
+                               if (bcv->dbcv_flags & DBTF_MEDIA)
+                               {
+                                       drive[0] = FindDriveFromMask(bcv->dbcv_unitmask);
+                                       handle_media_change(drive, TRUE, ud);
+                               }
+                       }
+               } break;
+
+               case DBT_DEVICEREMOVECOMPLETE:
+               {
+                       if (bch->dbch_devicetype == DBT_DEVTYP_VOLUME)
+                       {
+                               PDEV_BROADCAST_VOLUME bcv = (PDEV_BROADCAST_VOLUME)bch;
+
+                               if (bcv->dbcv_flags & DBTF_MEDIA)
+                               {
+                                       drive[0] = FindDriveFromMask(bcv->dbcv_unitmask);
+                                       handle_media_change(drive, FALSE, ud);
+                               }
+                       }
+               } break;
+               default: ;
+       }
+}
+
+#else
+
+G_MODULE_EXPORT void
 drive_changed_cb(GVolumeMonitor *gvm, GDrive *gd, signal_user_data_t *ud)
 {
        gchar *device;
@@ -2706,8 +2957,9 @@ drive_changed_cb(GVolumeMonitor *gvm, GDrive *gd, signal_user_data_t *ud)
        }
        g_free(device);
 }
+#endif
 
-
+#if !defined(_WIN32)
 static void
 dbus_init (void)
 {
@@ -2719,10 +2971,12 @@ dbus_init (void)
 #define GPM_DBUS_INHIBIT_INTERFACE     "org.freedesktop.PowerManagement.Inhibit" 
 static gboolean gpm_inhibited = FALSE;
 static guint gpm_cookie = -1;
+#endif
 
 void
 ghb_inhibit_gpm()
 {
+#if !defined(_WIN32)
        DBusGConnection *conn;
        DBusGProxy      *proxy;
        GError *error = NULL;
@@ -2770,11 +3024,13 @@ ghb_inhibit_gpm()
        gpm_inhibited = TRUE;
        g_object_unref(G_OBJECT(proxy));
        dbus_g_connection_unref(conn);
+#endif
 }
 
 void
 ghb_uninhibit_gpm()
 {
+#if !defined(_WIN32)
        DBusGConnection *conn;
        DBusGProxy      *proxy;
        GError *error = NULL;
@@ -2818,11 +3074,13 @@ ghb_uninhibit_gpm()
        gpm_inhibited = FALSE;
        dbus_g_connection_unref(conn);
        g_object_unref(G_OBJECT(proxy));
+#endif
 }
 
 void
 ghb_hal_init()
 {
+#if !defined(_WIN32)
        DBusGConnection *gconn;
        DBusConnection *conn;
        GError *gerror = NULL;
@@ -2873,9 +3131,10 @@ ghb_hal_init()
 
        libhal_free_string_array (devices);
        dbus_g_connection_unref(gconn);
+#endif
 }
 
-gboolean 
+G_MODULE_EXPORT gboolean 
 tweak_setting_cb(
        GtkWidget *widget, 
        GdkEventButton *event, 
@@ -2937,7 +3196,7 @@ tweak_setting_cb(
        return ret;
 }
 
-gboolean 
+G_MODULE_EXPORT gboolean 
 easter_egg_cb(
        GtkWidget *widget, 
        GdkEventButton *event, 
@@ -2963,7 +3222,7 @@ easter_egg_cb(
        return FALSE;
 }
 
-gchar*
+G_MODULE_EXPORT gchar*
 format_deblock_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
 {
        if (val < 5.0)
@@ -2976,7 +3235,7 @@ format_deblock_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
        }
 }
 
-gchar*
+G_MODULE_EXPORT gchar*
 format_drc_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
 {
        if (val <= 0.0)
@@ -2989,7 +3248,7 @@ format_drc_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
        }
 }
 
-gchar*
+G_MODULE_EXPORT gchar*
 format_vquality_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
 {
        gdouble percent;
@@ -3029,11 +3288,13 @@ format_vquality_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
        return g_strdup_printf("QP: %.1f / %.1f%%", val, percent);
 }
 
-static void
+#if !defined(_WIN32)
+G_MODULE_EXPORT void
 html_link_cb(GtkHTML *html, const gchar *url, signal_user_data_t *ud)
 {
        browse_url(url);
 }
+#endif
 
 static gpointer check_stable_update(signal_user_data_t *ud);
 static gboolean stable_update_lock = FALSE;
@@ -3042,7 +3303,10 @@ static void
 process_appcast(signal_user_data_t *ud)
 {
        gchar *description = NULL, *build = NULL, *version = NULL, *msg;
-       GtkWidget *html, *window, *dialog, *label;
+#if !defined(_WIN32)
+       GtkWidget *html, *window;
+#endif
+       GtkWidget *dialog, *label;
        gint    response, ibuild = 0, skip;
 
        if (ud->appcast == NULL || ud->appcast_len < 15 || 
@@ -3067,17 +3331,21 @@ process_appcast(signal_user_data_t *ud)
                        version, build, hb_get_version(NULL), hb_get_build(NULL));
        label = GHB_WIDGET(ud->builder, "update_message");
        gtk_label_set_text(GTK_LABEL(label), msg);
+#if !defined(_WIN32)
        html = gtk_html_new_from_string(description, -1);
        g_signal_connect(html, "link_clicked", G_CALLBACK(html_link_cb), ud);
        window = GHB_WIDGET(ud->builder, "update_scroll");
        gtk_container_add(GTK_CONTAINER(window), html);
        // Show it
-       dialog = GHB_WIDGET(ud->builder, "update_dialog");
        gtk_widget_set_size_request(html, 420, 240);
        gtk_widget_show(html);
+#endif
+       dialog = GHB_WIDGET(ud->builder, "update_dialog");
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_hide(dialog);
+#if !defined(_WIN32)
        gtk_widget_destroy(html);
+#endif
        if (response == GTK_RESPONSE_OK)
        {
                // Skip
@@ -3107,7 +3375,7 @@ ghb_net_close(GIOChannel *ioc)
        g_io_channel_unref(ioc);
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 ghb_net_recv_cb(GIOChannel *ioc, GIOCondition cond, gpointer data)
 {
        gchar buf[2048];
@@ -3230,7 +3498,7 @@ check_stable_update(signal_user_data_t *ud)
        return NULL;
 }
 
-void
+G_MODULE_EXPORT void
 status_activate_cb(GtkStatusIcon *si, signal_user_data_t *ud)
 {
        GtkWindow *window;
@@ -3239,20 +3507,24 @@ status_activate_cb(GtkStatusIcon *si, signal_user_data_t *ud)
        gtk_window_present(window);
 }
 
-static void
+#if !defined(_WIN32)
+G_MODULE_EXPORT void
 notify_closed_cb(NotifyNotification *notification, signal_user_data_t *ud)
 {
        g_object_unref(G_OBJECT(notification));
 }
+#endif
 
 void
 ghb_notify_done(signal_user_data_t *ud)
 {
-       NotifyNotification *notification;
        GtkStatusIcon *si;
 
        si = GTK_STATUS_ICON(GHB_OBJECT(ud->builder, "hb_status"));
        gtk_status_icon_set_from_icon_name(si, "hb-status-empty");
+
+#if !defined(_WIN32)
+       NotifyNotification *notification;
        notification = notify_notification_new(
                "Encode Complete",
                "Put down that cocktail, Your HandBrake queue is done!",
@@ -3261,4 +3533,5 @@ ghb_notify_done(signal_user_data_t *ud)
        notify_notification_attach_to_status_icon(notification, si);
        g_signal_connect(notification, "closed", (GCallback)notify_closed_cb, ud);
        notify_notification_show(notification, NULL);
+#endif
 }
index 2c17e50..f438ba5 100644 (file)
 #if !defined(_CALLBACKS_H_)
 #define _CALLBACKS_H_
 
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
 #include <gtk/gtk.h>
 #include "settings.h"
 
@@ -52,6 +56,9 @@ void ghb_log(gchar *log, ...);
 gpointer ghb_check_update(signal_user_data_t *ud);
 void ghb_uninhibit_gpm(void);
 void ghb_inhibit_gpm(void);
+#if defined(_WIN32)
+void wm_drive_changed(MSG *msg, signal_user_data_t *ud);
+#endif
 
 #endif // _CALLBACKS_H_
 
index c20b8fa..1d3422c 100644 (file)
  *     Free Software Foundation version 2 of the License.
  */
 
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
 #include <glib.h>
 #include <gio/gio.h>
 
@@ -315,7 +319,6 @@ ghb_dvd_volname(const gchar *device)
 }
 #endif
 
-#if defined(__linux__)
 gchar*
 ghb_resolve_symlink(const gchar *name)
 {
@@ -359,12 +362,11 @@ ghb_resolve_symlink(const gchar *name)
        g_object_unref(gfile);
        return file;
 }
-#endif
 
 void
 ghb_dvd_set_current(const gchar *name, signal_user_data_t *ud)
 {
-#if defined(__linux__)
+#if !defined(_WIN32)
        GFile *gfile;
        GFileInfo *info;
        gchar *resolved = ghb_resolve_symlink(name);
@@ -395,11 +397,19 @@ ghb_dvd_set_current(const gchar *name, signal_user_data_t *ud)
        }
        g_object_unref(gfile);
 #else
+       gchar drive[4];
+       guint dtype;
+
        if (ud->current_dvd_device != NULL)
        {
                g_free(ud->current_dvd_device);
                ud->current_dvd_device = NULL;
        }
-       ud->current_dvd_device = g_strdup(name);;
+       g_strlcpy(drive, name, 4);
+       dtype = GetDriveType(drive);
+       if (dtype == DRIVE_CDROM)
+       {
+               ud->current_dvd_device = g_strdup(name);
+       }
 #endif
 }
index 5012576..eae2f1f 100644 (file)
@@ -1977,9 +1977,9 @@ ghb_update_ui_combo_box(GtkBuilder *builder, const gchar *name, gint user_data,
        gint signal_id;
        gint handler_id = 0;
 
-       g_debug("ghb_update_ui_combo_box() %s\n", name);
        if (name != NULL)
        {               
+               g_debug("ghb_update_ui_combo_box() %s\n", name);
                // Clearing a combo box causes a rash of "changed" events, even when
                // the active item is -1 (inactive).  To control things, I'm disabling
                // the event till things are settled down.
@@ -3457,7 +3457,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
                job->deinterlace = 0;
     job->grayscale   = ghb_settings_get_boolean(js, "VideoGrayScale");
 
-       job->anamorphic.mode = ghb_settings_get_boolean(js, "PicturePAR");
+       job->anamorphic.mode = ghb_settings_combo_int(js, "PicturePAR");
        job->anamorphic.modulus = ghb_settings_combo_int(js, "PictureAlignment");
 
        /* Add selected filters */
index 76097cb..e67b3db 100644 (file)
 #include <config.h>
 
 #include <gtk/gtk.h>
+
+#if !defined(_WIN32)
 #include <gst/gst.h>
+#include <libnotify/notify.h>
+#else
+#include <windows.h>
+#include <io.h>
+//#include <pthread/pthread.h>
+#define pipe(phandles) _pipe (phandles, 4096, _O_BINARY)
+#endif
+
 #include <glib/gstdio.h>
 #include <gio/gio.h>
-#include <libnotify/notify.h>
 #include "hb.h"
 #include "renderer_button.h"
 #include "hb-backend.h"
@@ -76,7 +85,6 @@
 #endif
 
 
-
 #define BUILDER_NAME "ghb"
 
 GtkBuilder*
@@ -193,9 +201,9 @@ change_font(GtkWidget *widget, gpointer data)
     //gtk_container_foreach((GtkContainer*)window, change_font, "sans 20");
 #endif
 
-extern void chapter_list_selection_changed_cb(void);
-extern void chapter_edited_cb(void);
-extern void chapter_keypress_cb(void);
+extern G_MODULE_EXPORT void chapter_list_selection_changed_cb(void);
+extern G_MODULE_EXPORT void chapter_edited_cb(void);
+extern G_MODULE_EXPORT void chapter_keypress_cb(void);
 
 // Create and bind the tree model to the tree view for the chapter list
 // Also, connect up the signal that lets us know the selection has changed
@@ -236,11 +244,11 @@ bind_chapter_tree_model (signal_user_data_t *ud)
 }
 
 
-extern void queue_list_selection_changed_cb(void);
-extern void queue_remove_clicked_cb(void);
-extern void queue_list_size_allocate_cb(void);
-extern void queue_drag_cb(void);
-extern void queue_drag_motion_cb(void);
+extern G_MODULE_EXPORT void queue_list_selection_changed_cb(void);
+extern G_MODULE_EXPORT void queue_remove_clicked_cb(void);
+extern G_MODULE_EXPORT void queue_list_size_allocate_cb(void);
+extern G_MODULE_EXPORT void queue_drag_cb(void);
+extern G_MODULE_EXPORT void queue_drag_motion_cb(void);
 
 // Create and bind the tree model to the tree view for the queue list
 // Also, connect up the signal that lets us know the selection has changed
@@ -304,7 +312,7 @@ bind_queue_tree_model (signal_user_data_t *ud)
        gtk_widget_hide (widget);
 }
 
-extern void audio_list_selection_changed_cb(void);
+extern G_MODULE_EXPORT void audio_list_selection_changed_cb(void);
 
 // Create and bind the tree model to the tree view for the audio track list
 // Also, connect up the signal that lets us know the selection has changed
@@ -369,9 +377,9 @@ bind_audio_tree_model (signal_user_data_t *ud)
        g_debug("Done\n");
 }
 
-extern void presets_list_selection_changed_cb(void);
-extern void presets_drag_cb(void);
-extern void presets_drag_motion_cb(void);
+extern G_MODULE_EXPORT void presets_list_selection_changed_cb(void);
+extern G_MODULE_EXPORT void presets_drag_cb(void);
+extern G_MODULE_EXPORT void presets_drag_motion_cb(void);
 extern void presets_row_expanded_cb(void);
 
 // Create and bind the tree model to the tree view for the preset list
@@ -444,8 +452,12 @@ IoRedirect(signal_user_data_t *ud)
        g_free(config);
        // Set encoding to raw.
        g_io_channel_set_encoding (ud->activity_log, NULL, NULL);
+#if !defined(_WIN32)
        stderr->_fileno = pfd[1];
-       stdin->_fileno = pfd[0];
+#else
+       stderr->_file = pfd[1];
+#endif
+       setvbuf(stderr, NULL, _IONBF, 0);
        channel = g_io_channel_unix_new (pfd[0]);
        // I was getting an this error:
        // "Invalid byte sequence in conversion input"
@@ -472,31 +484,47 @@ static GOptionEntry entries[] =
        { NULL }
 };
 
-#if defined(__linux__)
-void drive_changed_cb(GVolumeMonitor *gvm, GDrive *gd, signal_user_data_t *ud);
+G_MODULE_EXPORT void drive_changed_cb(GVolumeMonitor *gvm, GDrive *gd, signal_user_data_t *ud);
 //void drive_disconnected_cb(GnomeVFSVolumeMonitor *gvm, GnomeVFSDrive *gd, signal_user_data_t *ud);
 
+#if defined(_WIN32)
+G_MODULE_EXPORT GdkFilterReturn
+win_message_cb(GdkXEvent *wmevent, GdkEvent *event, gpointer data)
+{
+       signal_user_data_t *ud = (signal_user_data_t*)data;
+       MSG *msg = (MSG*)wmevent;
+
+       if (msg->message == WM_DEVICECHANGE)
+       {
+               wm_drive_changed(wmevent, ud);
+       }
+       return GDK_FILTER_CONTINUE;
+}
+#endif
+
 void
 watch_volumes(signal_user_data_t *ud)
 {
+#if !defined(_WIN32)
        GVolumeMonitor *gvm;
        gvm = g_volume_monitor_get ();
 
        g_signal_connect(gvm, "drive-changed", (GCallback)drive_changed_cb, ud);
-       //g_signal_connect(gvm, "drive-connected", (GCallback)drive_connected_cb, ud);
-}
 #else
-void
-watch_volumes(signal_user_data_t *ud)
-{
-}
+       GdkWindow *window;
+       GtkWidget *widget;
+
+       widget = GHB_WIDGET (ud->builder, "hb_window");
+       window = gtk_widget_get_parent_window(widget);
+       gdk_window_add_filter(window, win_message_cb, ud);
 #endif
+}
 
 // Hack to avoid a segfault in libavcodec
 extern int mm_flags;
 int mm_support();
 
-void x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud);
+G_MODULE_EXPORT void x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud);
 void preview_window_expose_cb(void);
 
 // Some style definitions for the preview window and hud
@@ -543,24 +571,33 @@ main (int argc, char *argv[])
        textdomain (GETTEXT_PACKAGE);
 #endif
 
+#ifdef PTW32_STATIC_LIB
+       pthread_win32_process_attach_np();
+       pthread_win32_thread_attach_np();
+#endif
+
        if (!g_thread_supported())
                g_thread_init(NULL);
        context = g_option_context_new ("- Rip and encode DVD or MPEG file");
        g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
        g_option_context_add_group (context, gtk_get_option_group (TRUE));
+#if !defined(_WIN32)
        g_option_context_add_group (context, gst_init_get_option_group ());
+#endif
        g_option_context_parse (context, &argc, &argv, &error);
        g_option_context_free(context);
        
        gtk_set_locale ();
        gtk_init (&argc, &argv);
        gtk_rc_parse_string(hud_rcstyle);
+#if !defined(_WIN32)
        notify_init("HandBrake");
+#endif
        ghb_register_transforms();
        ghb_resource_init();
        ghb_load_icons();
 
-#if defined(__linux__)
+#if !defined(_WIN32)
        ghb_hal_init();
 #endif
 
@@ -570,9 +607,9 @@ main (int argc, char *argv[])
        g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, warn_log_handler, ud);
        //g_log_set_handler ("Gtk", G_LOG_LEVEL_CRITICAL, warn_log_handler, ud);
        ud->settings = ghb_settings_new();
+       ud->builder = create_builder_or_die (BUILDER_NAME);
        // Enable events that alert us to media change events
        watch_volumes (ud);
-       ud->builder = create_builder_or_die (BUILDER_NAME);
 
        //GtkWidget *widget = GHB_WIDGET(ud->builder, "PictureDetelecineCustom");
        //gtk_entry_set_inner_border(widget, 2);
@@ -687,8 +724,13 @@ main (int argc, char *argv[])
        ghb_value_free(ud->settings);
        g_io_channel_unref(ud->activity_log);
        ghb_settings_close();
+#if !defined(_WIN32)
        notify_uninit();
+#endif
        g_free(ud);
+#ifdef PTW32_STATIC_LIB
+       pthread_win32_thread_detach_np();
+       pthread_win32_process_detach_np();
+#endif
        return 0;
 }
-
index 2a07291..1c5869d 100644 (file)
@@ -1033,7 +1033,7 @@ ghb_get_user_config_dir(gchar *subdir)
                gchar **split;
                gint ii;
 
-               split = g_strsplit(subdir, "/", -1);
+               split = g_strsplit(subdir, G_DIR_SEPARATOR_S, -1);
                for (ii = 0; split[ii] != NULL; ii++)
                {
                        gchar *tmp;
@@ -1328,6 +1328,34 @@ ghb_settings_close()
                ghb_value_free(prefsPlist);
 }
 
+#if defined(_WIN32)
+gchar*
+FindFirstCDROM(void)
+{
+       gint ii, drives;
+       gchar drive[5];
+
+       strcpy(drive, "A:" G_DIR_SEPARATOR_S);
+       drives = GetLogicalDrives();
+       for (ii = 0; ii < 26; ii++)
+       {
+               if (drives & 0x01)
+               {
+                       guint dtype;
+
+                       drive[0] = 'A' + ii;
+                       dtype = GetDriveType(drive);
+                       if (dtype == DRIVE_CDROM)
+                       {
+                               return g_strdup(drive);
+                       }
+               }
+               drives >>= 1;
+       }
+       return NULL;
+}
+#endif
+
 void
 ghb_prefs_load(signal_user_data_t *ud)
 {
@@ -1363,6 +1391,18 @@ ghb_prefs_load(signal_user_data_t *ud)
                }
                ghb_dict_insert(dict, 
                        g_strdup("destination_dir"), ghb_value_dup(ghb_string_value(dir)));
+#if defined(_WIN32)
+               gchar *source;
+
+               source = FindFirstCDROM();
+               if (source == NULL)
+               {
+                       source = g_strdup("C:" G_DIR_SEPARATOR_S);
+               }
+               ghb_dict_insert(dict, g_strdup("default_source"), 
+                                               ghb_value_dup(ghb_string_value(source)));
+               g_free(source);
+#endif
                store_prefs();
     }
        // Read legacy default_preset preference and update accordingly
@@ -2837,7 +2877,7 @@ enforce_preset_type(signal_user_data_t *ud, const GValue *path)
        }
 }
 
-void
+G_MODULE_EXPORT void
 presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkWidget *dialog;
@@ -2906,13 +2946,13 @@ presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 preset_type_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
 }
 
-void
+G_MODULE_EXPORT void
 preset_name_changed_cb(GtkWidget *entry, signal_user_data_t *ud)
 {
        gchar *name;
@@ -2928,7 +2968,7 @@ preset_name_changed_cb(GtkWidget *entry, signal_user_data_t *ud)
        ghb_value_free(dest);
 }
 
-void
+G_MODULE_EXPORT void
 presets_restore_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GValue *preset;
@@ -2942,7 +2982,7 @@ presets_restore_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
        ghb_select_preset(ud->builder, preset);
 }
 
-void
+G_MODULE_EXPORT void
 presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkTreeView *treeview;
@@ -3011,7 +3051,7 @@ presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 }
 
 // controls where valid drop locations are
-gboolean
+G_MODULE_EXPORT gboolean
 presets_drag_motion_cb(
        GtkTreeView *tv,
        GdkDragContext *ctx,
@@ -3102,7 +3142,7 @@ presets_drag_motion_cb(
        return TRUE;
 }
 
-void 
+G_MODULE_EXPORT void 
 presets_drag_cb(
        GtkTreeView *dstwidget, 
        GdkDragContext *dc, 
@@ -3347,7 +3387,7 @@ preset_update_title_deps(signal_user_data_t *ud, ghb_title_info_t *tinfo)
        }
 }
 
-void
+G_MODULE_EXPORT void
 presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
 {
        GtkTreeModel *store;
@@ -3445,7 +3485,7 @@ ghb_clear_presets_selection(signal_user_data_t *ud)
        ghb_settings_set_boolean(ud->settings, "preset_modified", TRUE);
 }
 
-void
+G_MODULE_EXPORT void
 presets_frame_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, signal_user_data_t *ud)
 {
        GtkTreeView *treeview;
@@ -3465,7 +3505,7 @@ presets_frame_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, sig
        }
 }
 
-void
+G_MODULE_EXPORT void
 presets_default_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GValue *preset;
index 6164270..ef5f8c7 100644 (file)
 #include <glib/gstdio.h>
 #include <glib-object.h>
 #include <gtk/gtk.h>
+
+#if !defined(_WIN32)
 #include <gdk/gdkx.h>
+#endif
+
+#if defined(_ENABLE_GST)
 #include <gst/gst.h>
 #include <gst/interfaces/xoverlay.h>
 #include <gst/video/video.h>
 #include <gst/pbutils/missing-plugins.h>
+#endif
+
 #include "settings.h"
 #include "presets.h"
 #include "callbacks.h"
 
 struct preview_s
 {
+#if defined(_ENABLE_GST)
        GstElement *play;
+       gulong xid;
+#endif
        gint64 len;
        gint64 pos;
        gboolean seek_lock;
@@ -42,7 +52,6 @@ struct preview_s
        gint width;
        gint height;
        GtkWidget *view;
-       gulong xid;
        GdkPixbuf *pix;
        gint button_width;
        gint button_height;
@@ -55,15 +64,19 @@ struct preview_s
        gchar *current;
 };
 
-static gboolean live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data);
+#if defined(_ENABLE_GST)
+G_MODULE_EXPORT gboolean live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data);
 static GstBusSyncReply create_window(GstBus *bus, GstMessage *msg, 
                                gpointer data);
-gboolean preview_expose_cb(GtkWidget *widget, GdkEventExpose *event, 
+#endif
+
+G_MODULE_EXPORT gboolean preview_expose_cb(GtkWidget *widget, GdkEventExpose *event, 
                                signal_user_data_t *ud);
 
 void
 ghb_screen_par(signal_user_data_t *ud, gint *par_n, gint *par_d)
 {
+#if defined(_ENABLE_GST)
        GValue disp_par = {0,};
        GstElement *xover;
        GObjectClass *klass;
@@ -91,6 +104,10 @@ ghb_screen_par(signal_user_data_t *ud, gint *par_n, gint *par_d)
        *par_n = gst_value_get_fraction_numerator(&disp_par);
        *par_d = gst_value_get_fraction_denominator(&disp_par);
        g_value_unset(&disp_par);
+#else
+       *par_n = 1;
+       *par_d = 1;
+#endif
 }
 
 void
@@ -111,20 +128,22 @@ ghb_par_scale(signal_user_data_t *ud, gint *width, gint *height, gint par_n, gin
 void
 ghb_preview_init(signal_user_data_t *ud)
 {
-       GstBus *bus;
-       GstElement *xover;
-
        ud->preview = g_malloc0(sizeof(preview_t));
        ud->preview->view = GHB_WIDGET(ud->builder, "preview_image");
        gtk_widget_realize(ud->preview->view);
        g_signal_connect(G_OBJECT(ud->preview->view), "expose_event",
                                        G_CALLBACK(preview_expose_cb), ud);
-       ud->preview->xid = GDK_DRAWABLE_XID(ud->preview->view->window);
 
-       ud->preview->play = gst_element_factory_make("playbin", "play");
        ud->preview->pause = TRUE;
        ud->preview->encode_frame = -1;
        ud->preview->live_id = -1;
+
+#if defined(_ENABLE_GST)
+       GstBus *bus;
+       GstElement *xover;
+
+       ud->preview->xid = GDK_DRAWABLE_XID(ud->preview->view->window);
+       ud->preview->play = gst_element_factory_make("playbin", "play");
        //xover = gst_element_factory_make("xvimagesink", "xover");
        //xover = gst_element_factory_make("ximagesink", "xover");
        xover = gst_element_factory_make("gconfvideosink", "xover");
@@ -135,6 +154,12 @@ ghb_preview_init(signal_user_data_t *ud)
        gst_bus_add_watch(bus, live_preview_cb, ud);
        gst_bus_set_sync_handler(bus, create_window, ud->preview);
        gst_object_unref(bus);
+#else
+       GtkWidget *widget = GHB_WIDGET(ud->builder, "live_preview_box");
+       gtk_widget_hide (widget);
+       widget = GHB_WIDGET(ud->builder, "live_preview_duration_box");
+       gtk_widget_hide (widget);
+#endif
 }
 
 void
@@ -147,6 +172,7 @@ ghb_preview_cleanup(signal_user_data_t *ud)
        }
 }
 
+#if defined(_ENABLE_GST)
 static GstBusSyncReply
 create_window(GstBus *bus, GstMessage *msg, gpointer data)
 {
@@ -307,7 +333,7 @@ update_stream_info(signal_user_data_t *ud)
        g_list_free(vstreams);
 }
 
-static gboolean
+G_MODULE_EXPORT gboolean
 live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data)
 {
        signal_user_data_t *ud = (signal_user_data_t*)data;
@@ -409,6 +435,7 @@ live_preview_pause(signal_user_data_t *ud)
        gst_element_set_state(ud->preview->play, GST_STATE_PAUSED);
        ud->preview->pause = TRUE;
 }
+#endif
 
 void
 live_preview_stop(signal_user_data_t *ud)
@@ -418,7 +445,9 @@ live_preview_stop(signal_user_data_t *ud)
 
        img = GTK_IMAGE(GHB_WIDGET(ud->builder, "live_preview_play_image"));
        gtk_image_set_from_stock(img, "gtk-media-play", GTK_ICON_SIZE_BUTTON);
+#if defined(_ENABLE_GST)
        gst_element_set_state(ud->preview->play, GST_STATE_NULL);
+#endif
        ud->preview->pause = TRUE;
        ud->preview->state = PREVIEW_STATE_IMAGE;
 
@@ -452,7 +481,7 @@ ghb_live_reset(signal_user_data_t *ud)
 
 extern void hb_get_tempory_directory(hb_handle_t *h, char path[512]);
 
-void
+G_MODULE_EXPORT void
 live_preview_start_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        gchar *tmp_dir;
@@ -468,10 +497,12 @@ live_preview_start_cb(GtkWidget *xwidget, signal_user_data_t *ud)
        if (ud->preview->encoded[frame] &&
                g_file_test(name, G_FILE_TEST_IS_REGULAR))
        {
+#if defined(_ENABLE_GST)
                if (ud->preview->pause)
                        live_preview_start(ud);
                else
                        live_preview_pause(ud);
+#endif
        }
        else
        {
@@ -502,7 +533,9 @@ ghb_live_encode_done(signal_user_data_t *ud, gboolean success)
                gtk_progress_bar_set_text(GTK_PROGRESS_BAR(prog), "Done");
                gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(prog), 1);
                ud->preview->encoded[ud->preview->encode_frame] = TRUE;
+#if defined(_ENABLE_GST)
                live_preview_start(ud);
+#endif
                widget = GHB_WIDGET(ud->builder, "live_progress_box");
                gtk_widget_hide (widget);
                widget = GHB_WIDGET(ud->builder, "live_preview_progress");
@@ -516,7 +549,8 @@ ghb_live_encode_done(signal_user_data_t *ud, gboolean success)
        }
 }
 
-static gboolean
+#if defined(_ENABLE_GST)
+G_MODULE_EXPORT gboolean
 unlock_progress_cb(signal_user_data_t *ud)
 {
        ud->preview->progress_lock = FALSE;
@@ -524,10 +558,12 @@ unlock_progress_cb(signal_user_data_t *ud)
        // so that it is not called again
        return FALSE;
 }
+#endif
 
 void
 ghb_live_preview_progress(signal_user_data_t *ud)
 {
+#if defined(_ENABLE_GST)
        GstFormat fmt = GST_FORMAT_TIME;
        gint64 len = -1, pos = -1;
 
@@ -559,9 +595,11 @@ ghb_live_preview_progress(signal_user_data_t *ud)
                gtk_range_set_value(progress, percent);
        }
        g_idle_add((GSourceFunc)unlock_progress_cb, ud);
+#endif
 }
 
-static gboolean
+#if defined(_ENABLE_GST)
+G_MODULE_EXPORT gboolean
 unlock_seek_cb(signal_user_data_t *ud)
 {
        ud->preview->seek_lock = FALSE;
@@ -569,10 +607,12 @@ unlock_seek_cb(signal_user_data_t *ud)
        // so that it is not called again
        return FALSE;
 }
+#endif
 
-void
+G_MODULE_EXPORT void
 live_preview_seek_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
+#if defined(_ENABLE_GST)
        gdouble dval;
        gint64 pos;
 
@@ -587,6 +627,7 @@ live_preview_seek_cb(GtkWidget *widget, signal_user_data_t *ud)
                GST_SEEK_TYPE_SET, pos,
                GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
        g_idle_add((GSourceFunc)unlock_seek_cb, ud);
+#endif
 }
 
 void
@@ -666,7 +707,8 @@ ghb_set_preview_image(signal_user_data_t *ud)
        }
 }
 
-static gboolean
+#if defined(_ENABLE_GST)
+G_MODULE_EXPORT gboolean
 delayed_expose_cb(signal_user_data_t *ud)
 {
        GstElement *vsink;
@@ -683,13 +725,15 @@ delayed_expose_cb(signal_user_data_t *ud)
        // so that it is not called again
        return FALSE;
 }
+#endif
 
-gboolean
+G_MODULE_EXPORT gboolean
 preview_expose_cb(
        GtkWidget *widget, 
        GdkEventExpose *event, 
        signal_user_data_t *ud)
 {
+#if defined(_ENABLE_GST)
        if (ud->preview->state == PREVIEW_STATE_LIVE)
        {
                if (GST_STATE(ud->preview->play) >= GST_STATE_PAUSED)
@@ -712,6 +756,7 @@ preview_expose_cb(
                }
                return TRUE;
        }
+#endif
 
        if (ud->preview->pix != NULL)
        {
@@ -722,7 +767,7 @@ preview_expose_cb(
        return TRUE;
 }
 
-void
+G_MODULE_EXPORT void
 preview_button_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, signal_user_data_t *ud)
 {
        g_debug("allocate %d x %d", allocation->width, allocation->height);
@@ -919,7 +964,7 @@ preview_frame_value_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_set_preview_image(ud);
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 preview_window_delete_cb(
        GtkWidget *widget, 
        GdkEvent *event, 
@@ -967,7 +1012,7 @@ settings_window_delete_cb(
        return TRUE;
 }
 
-void
+G_MODULE_EXPORT void
 preview_duration_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("preview_duration_changed_cb ()");
index f01f543..aed2b07 100644 (file)
@@ -23,7 +23,7 @@
 #include "presets.h"
 #include "ghb-dvd.h"
 
-void
+G_MODULE_EXPORT void
 queue_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
 {
        GtkTreeModel *store;
@@ -674,14 +674,14 @@ queue_add(signal_user_data_t *ud)
        return TRUE;
 }
 
-void
+G_MODULE_EXPORT void
 queue_add_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("queue_add_clicked_cb ()");
        queue_add(ud);
 }
 
-void
+G_MODULE_EXPORT void
 queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
 {
        GtkTreeView *treeview;
@@ -761,7 +761,7 @@ find_last_finished(GValue *queue)
 // handler from expanding rows if you hover over them while
 // dragging.
 // Also controls where valid drop locations are
-gboolean
+G_MODULE_EXPORT gboolean
 queue_drag_motion_cb(
        GtkTreeView *tv,
        GdkDragContext *ctx,
@@ -839,7 +839,7 @@ queue_drag_motion_cb(
        return TRUE;
 }
 
-void 
+G_MODULE_EXPORT void 
 queue_drag_cb(
        GtkTreeView *dstwidget, 
        GdkDragContext *dc, 
@@ -973,7 +973,7 @@ ghb_queue_buttons_grey(signal_user_data_t *ud, gboolean working)
        gtk_action_set_sensitive (action, working);
 }
 
-void
+G_MODULE_EXPORT void
 queue_list_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, GtkCellRenderer *cell)
 {
        GtkTreeViewColumn *column;
@@ -988,7 +988,7 @@ queue_list_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, GtkCel
                g_object_set(cell, "wrap-width", width-70, NULL);
 }
 
-void
+G_MODULE_EXPORT void
 queue_start_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GValue *js;
@@ -1024,14 +1024,14 @@ queue_start_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 queue_stop_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        ud->cancel_encode = TRUE;
        ghb_cancel_encode(NULL);
 }
 
-void
+G_MODULE_EXPORT void
 queue_pause_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        ghb_pause_queue();
@@ -1107,7 +1107,7 @@ ghb_reload_queue(signal_user_data_t *ud)
        return FALSE;
 }
 
-gboolean 
+G_MODULE_EXPORT gboolean 
 queue_key_press_cb(
        GtkWidget *widget, 
        GdkEventKey *event,
@@ -1170,7 +1170,7 @@ queue_key_press_cb(
 
 GValue *ghb_queue_edit_settings = NULL;
 
-void
+G_MODULE_EXPORT void
 queue_edit_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkTreeView *treeview;
index a2096e0..17319a5 100644 (file)
@@ -15,6 +15,7 @@
 #include <glib.h>
 #include <glib-object.h>
 #include <string.h>
+#include <inttypes.h>
 #include "values.h"
 
 static void dict_delete_key(gpointer data);
@@ -96,7 +97,7 @@ debug_show_value(GValue *gval)
        }
        else if (tp == G_TYPE_INT64)
        {
-               g_message("Type %s value %ld", "int64", g_value_get_int64(gval));
+               g_message("Type %s value %" PRId64, "int64", g_value_get_int64(gval));
        }
        else if (tp == G_TYPE_DOUBLE)
        {
similarity index 100%
rename from gtk/src/makedeps.c
rename to gtk/src/widgetdeps.c
index 20ec56e..ff2338f 100644 (file)
@@ -26,7 +26,7 @@ static gchar* sanitize_x264opts(signal_user_data_t *ud, const gchar *options);
 // Flag needed to prevent x264 options processing from chasing its tail
 static gboolean ignore_options_update = FALSE;
 
-void
+G_MODULE_EXPORT void
 x264_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
@@ -40,7 +40,7 @@ x264_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_clear_presets_selection(ud);
 }
 
-void
+G_MODULE_EXPORT void
 x264_me_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        gint me;
@@ -68,7 +68,7 @@ x264_me_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        }
 }
 
-void
+G_MODULE_EXPORT void
 x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("x264_entry_changed_cb ()");
@@ -96,7 +96,7 @@ x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        }
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 x264_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, 
        signal_user_data_t *ud)
 {