diff -Nur /home/aho/CVS/skipstone/src/Makefile skipstone/src/Makefile --- /home/aho/CVS/skipstone/src/Makefile Mon Dec 3 16:46:26 2001 +++ skipstone/src/Makefile Sun Dec 16 04:04:03 2001 @@ -3,7 +3,7 @@ include ../config.mk SOURCES = main.c session.c go.c encoding.c callbacks.c moz_callbacks.c support.c ipc.c bookmarks.c interface.c interface-notebook.c history.c crash.c skipstone_config.c context.c skipstone-plugin.c skipstone-print.c debug.c mozilla.cpp SkipStonePrompter.cpp PromptService.cpp -OBJS = main.o go.o session.o callbacks.o encoding.o moz_callbacks.o support.o ipc.o bookmarks.o interface.o interface-notebook.o history.o crash.o skipstone-config.o context.o skipstone-plugin.o skipstone-print.o debug.o mozilla.o SkipStonePrompter.o PromptService.o +OBJS = main.o go.o session.o callbacks.o encoding.o moz_callbacks.o support.o ipc.o bookmarks.o interface.o interface-notebook.o history.o crash.o skipstone-config.o context.o skipstone-plugin.o skipstone-print.o debug.o mozilla.o SkipStonePrompter.o PromptService.o SkipDragListener.o DOWNLOADOBJS = skipdownload.o PROG = skipstone BINARY = skipstone-bin @@ -89,3 +89,4 @@ skipstone-plugin.o: skipstone-plugin.c skipstone.h skipstone-plugin.h SkipStonePrompter.o: SkipStonePrompter.cpp SkipStonePrompter.h PromptSerivce.o: PromptService.cpp PromptService.h +SkipDragListener.o: SkipDragListener.cpp SkipDragListener.h diff -Nur /home/aho/CVS/skipstone/src/SkipDragListener.cpp skipstone/src/SkipDragListener.cpp --- /home/aho/CVS/skipstone/src/SkipDragListener.cpp Thu Jan 1 09:00:00 1970 +++ skipstone/src/SkipDragListener.cpp Sun Dec 16 09:19:43 2001 @@ -0,0 +1,126 @@ +#include +#include "skipstone.h" +#include "SkipDragListener.h" + +/* type of drag and drop for links */ +static const GtkTargetEntry link_drag_types[] = +{ + { "_NETSCAPE_URL", 0, DND_TARGET_NETSCAPE_URL }, + { "STRING", 0, DND_TARGET_STRING }, +}; +static const gint link_drag_types_num_items = (sizeof (link_drag_types) / + sizeof (GtkTargetEntry)); +static GtkTargetList *link_drag_types_tl = NULL; + +SkipDragListener::SkipDragListener() +{ + NS_INIT_REFCNT(); + skipstone = NULL; +} + +SkipDragListener::~SkipDragListener(void) +{ + //g_print ("event listener destroyed!!\n"); +} + + +NS_IMPL_ADDREF(SkipDragListener) +NS_IMPL_RELEASE(SkipDragListener) +NS_INTERFACE_MAP_BEGIN(SkipDragListener) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDragListener) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMDragListener) + NS_INTERFACE_MAP_ENTRY(nsIDOMDragListener) +NS_INTERFACE_MAP_END + + +void +SkipDragListener::Init(SkipStone *sstone) +{ + skipstone = sstone; +} + + +// method of nsIDOMEventListener class +NS_IMETHODIMP +SkipDragListener::HandleEvent(nsIDOMEvent* aEvent) +{ + return NS_OK; +} + + +// methods of nsIDOMDragListener class +NS_IMETHODIMP SkipDragListener::DragEnter(nsIDOMEvent* aMouseEvent) +{ + return NS_OK; +} + +NS_IMETHODIMP SkipDragListener::DragOver(nsIDOMEvent* aMouseEvent) +{ + return NS_OK; +} + +NS_IMETHODIMP SkipDragListener::DragExit(nsIDOMEvent* aMouseEvent) +{ + return NS_OK; +} + +NS_IMETHODIMP SkipDragListener::DragDrop(nsIDOMEvent* aMouseEvent) +{ + return NS_OK; +} + +NS_IMETHODIMP SkipDragListener::DragGesture(nsIDOMEvent* aMouseEvent) +{ + gchar *old_dragging_link; + gchar *url = NULL; + gchar *dragging; + + if (skipstone->link && skipstone->link[0] != '\0') { + url = skipstone->link; + } + + if (url) + { + if (!link_drag_types_tl) + link_drag_types_tl = gtk_target_list_new + (link_drag_types, link_drag_types_num_items); + + old_dragging_link = (gchar*)gtk_object_get_data ( + GTK_OBJECT (skipstone->embed), + "dragging_link"); + if (old_dragging_link) g_free (old_dragging_link); + gtk_object_set_data (GTK_OBJECT(skipstone->embed), + "dragging_link", g_strdup (url)); + + dragging = (gchar *) gtk_object_get_data (GTK_OBJECT(skipstone->embed), "dragging_link"); + //g_print ("dragging link = %s\n", dragging); + + + GdkEvent gdk_event; + gdk_event.type = GDK_BUTTON_PRESS; + gdk_event.button.window = NULL; + gdk_event.button.send_event = 0; + gdk_event.button.time = time (NULL); + gdk_event.button.x = 0; + gdk_event.button.y = 0; + gdk_event.button.pressure = 0; + gdk_event.button.xtilt = 0; + gdk_event.button.ytilt = 0; + gdk_event.button.state = 0; + gdk_event.button.button = 0; + gdk_event.button.source = (GdkInputSource)0; + gdk_event.button.deviceid = 0; + gdk_event.button.x_root = 0; + gdk_event.button.y_root = 0; + + gtk_drag_begin (GTK_WIDGET(skipstone->embed), + link_drag_types_tl, + (GdkDragAction)(GDK_ACTION_COPY | + GDK_ACTION_LINK), + 1, &gdk_event); + } else { + //g_print ("drag fail!!\n"); + } + + return NS_OK; +} diff -Nur /home/aho/CVS/skipstone/src/SkipDragListener.h skipstone/src/SkipDragListener.h --- /home/aho/CVS/skipstone/src/SkipDragListener.h Thu Jan 1 09:00:00 1970 +++ skipstone/src/SkipDragListener.h Sun Dec 16 04:40:43 2001 @@ -0,0 +1,30 @@ +#ifndef SKIP_DRAG_LISTENER_H + +#include "nsIDOMDragListener.h" +#include "nsIDOMEvent.h" + +class SkipDragListener : public nsIDOMDragListener +{ +public: + SkipDragListener(); + virtual ~SkipDragListener(); + + void Init (SkipStone *sstone); + + NS_DECL_ISUPPORTS + + // method of nsIDOMEventListener class + NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent); + + // method of nsIDOMDragListener class + NS_IMETHOD DragEnter(nsIDOMEvent* aMouseEvent); + NS_IMETHOD DragOver(nsIDOMEvent* aMouseEvent); + NS_IMETHOD DragExit(nsIDOMEvent* aMouseEvent); + NS_IMETHOD DragDrop(nsIDOMEvent* aMouseEvent); + NS_IMETHOD DragGesture(nsIDOMEvent* aMouseEvent); + +private: + SkipStone *skipstone; +}; + +#endif /* SKIP_DRAG_LISTENER_H */ diff -Nur /home/aho/CVS/skipstone/src/callbacks.c skipstone/src/callbacks.c --- /home/aho/CVS/skipstone/src/callbacks.c Sat Dec 15 13:14:51 2001 +++ skipstone/src/callbacks.c Mon Dec 17 02:07:13 2001 @@ -797,3 +797,133 @@ D_RETURN; } +GList * +dnd_get_file_list(const gchar *string) +{ + gchar *file; + gchar *ptr, *uri; + GList *list = NULL; + gint len, pos = 0; + + uri = ptr = g_strdup (string); + len = strlen (uri); + + while (*ptr && (pos < len)) { + file = ptr; + + while (*ptr != '\r' && *ptr != '\n' && *ptr != '\0') { + ptr++; + pos++; + } + *ptr++ = '\0'; + pos++; + + while (*ptr == '\r' || *ptr == '\n' || *ptr == '\0') { + ptr++; + pos++; + } + + if (file && file[0] != '\r' && file[0] != '\n' && file[0] != '\0') + list = g_list_append (list, g_strdup(file)); + } + + g_free (uri); + + return list; +} + +void on_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, SkipStone *skipstone) +{ + gchar *data; + gchar **tmp; + GList *uri_list = NULL, *node; + + g_return_if_fail (selection_data); + data = selection_data->data; + + switch (info) { + case DND_TARGET_URI_LIST: + uri_list = dnd_get_file_list((gchar *)data); + if (!uri_list) return; + + node = uri_list; + while (node) { + gchar *uri = node->data; + + if (g_list_position (uri_list, node) == 0) + gtk_moz_embed_load_url(skipstone->embed, uri); + else + make_window(uri); + + node = g_list_next (node); + } + + g_list_foreach(uri_list, (GFunc)g_free, NULL); + g_list_free(uri_list); + break; + + case DND_TARGET_NETSCAPE_URL: + /* netscape format is: url \n title */ + tmp = g_strsplit(data, "\n", 2); + if (tmp) { + gtk_moz_embed_load_url(skipstone->embed,tmp[0]); + } else { + gtk_moz_embed_load_url(skipstone->embed,data); + } + g_strfreev (tmp); + break; + + case DND_TARGET_STRING: + gtk_moz_embed_load_url(skipstone->embed,data); + break; + + default: + g_warning ("unexpected drop type %ud\n", info); + break; + } +} + +void on_location_entry_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, SkipStone *skipstone) +{ + gchar *data; + gchar **tmp; + gchar *url; + GList *uri_list; + + g_return_if_fail (selection_data); + data = selection_data->data; + + switch (info) { + case DND_TARGET_URI_LIST: + uri_list = dnd_get_file_list((gchar *)data); + if (!uri_list) return; + + url = g_strdup (uri_list->data); + + g_list_foreach(uri_list, (GFunc)g_free, NULL); + g_list_free(uri_list); + break; + + case DND_TARGET_NETSCAPE_URL: + /* netscape format is: url \n title */ + tmp = g_strsplit(data, "\n", 2); + if (tmp) { + url = g_strdup(tmp[0]); + } else { + url = g_strdup(data); + } + g_strfreev(tmp); + break; + + case DND_TARGET_STRING: + url = g_strdup(data); + break; + + default: + g_warning ("unexpected drop type %ud\n", info); + return; + } + + if (url) gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(widget)->entry), url); + g_free (url); +} diff -Nur /home/aho/CVS/skipstone/src/interface-notebook.c skipstone/src/interface-notebook.c --- /home/aho/CVS/skipstone/src/interface-notebook.c Sat Dec 15 13:14:51 2001 +++ skipstone/src/interface-notebook.c Mon Dec 17 02:14:16 2001 @@ -21,6 +21,10 @@ GtkWidget *bmark_menu_item = NULL; GoMenu *notebook_go_menu = NULL; +/* for dnd */ +extern const GtkTargetEntry embed_drop_types[]; +extern const gint embed_drop_types_num_items; + /*static guint current_page = 0;*/ static SkipStone *skipstone = NULL; @@ -399,6 +403,13 @@ gtk_box_pack_start(GTK_BOX(hbox), skipstone->notebook_label, TRUE, TRUE, 2); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 2); gtk_widget_show_all(hbox); + + gtk_signal_connect(GTK_OBJECT(hbox), "drag_data_received", GTK_SIGNAL_FUNC(on_drag_data_received), skipstone); + gtk_drag_dest_set (GTK_WIDGET(hbox), GTK_DEST_DEFAULT_ALL, + embed_drop_types, embed_drop_types_num_items, + GDK_ACTION_COPY | GDK_ACTION_MOVE | + GDK_ACTION_LINK | GDK_ACTION_ASK ); + D_RETURN_(hbox); } @@ -457,6 +468,7 @@ /* skipstone->SkipNsHistory = mozilla_history_init(skipstone->embed);*/ + mozilla_dnd_init (skipstone); D_RETURN; } diff -Nur /home/aho/CVS/skipstone/src/interface.c skipstone/src/interface.c --- /home/aho/CVS/skipstone/src/interface.c Fri Dec 7 18:27:53 2001 +++ skipstone/src/interface.c Mon Dec 17 02:16:19 2001 @@ -12,6 +12,16 @@ gint reload_is_sensitive; }TbarSen; + +const GtkTargetEntry embed_drop_types[] = +{ + { "text/uri-list", 0, DND_TARGET_URI_LIST }, + { "_NETSCAPE_URL", 0, DND_TARGET_NETSCAPE_URL }, + { "STRING", 0, DND_TARGET_STRING }, +}; +const gint embed_drop_types_num_items = (sizeof (embed_drop_types) / + sizeof (GtkTargetEntry)); + static TbarSen *get_sensitive_buttons(SkipStone *skipstone); static void set_sensitive_buttons(SkipStone *skipstone, TbarSen *tbarsen); static void theme_menu_destroyed(GtkWidget *menu, gchar *theme); @@ -320,8 +330,9 @@ make_notebook_tab(url); D_RETURN; } - + make_real_window(url); + D_RETURN; } @@ -467,10 +478,11 @@ window_count = g_slist_append(window_count,skipstone); + mozilla_dnd_init (skipstone); + D_RETURN_(skipstone); } - void connect_embed_signals(SkipStone *skipstone) { D_ENTER; @@ -488,6 +500,13 @@ gtk_signal_connect(GTK_OBJECT(skipstone->embed), "size_to", GTK_SIGNAL_FUNC(size_to_cb), skipstone); gtk_signal_connect(GTK_OBJECT(skipstone->embed), "js_status", GTK_SIGNAL_FUNC(js_status_cb), skipstone); gtk_signal_connect(GTK_OBJECT(skipstone->embed), "progress_all", GTK_SIGNAL_FUNC(handle_progress), skipstone); + gtk_signal_connect(GTK_OBJECT(skipstone->embed), "drag_data_get", GTK_SIGNAL_FUNC(on_drag_data_get), skipstone); + gtk_signal_connect(GTK_OBJECT(skipstone->embed), "drag_data_received", GTK_SIGNAL_FUNC(on_drag_data_received), skipstone); + + gtk_drag_dest_set (GTK_WIDGET(skipstone->embed), GTK_DEST_DEFAULT_ALL, + embed_drop_types, embed_drop_types_num_items, + GDK_ACTION_COPY | GDK_ACTION_MOVE | + GDK_ACTION_LINK | GDK_ACTION_ASK ); D_RETURN; } @@ -560,6 +579,11 @@ } skipstone->combo = gtk_combo_new(); + gtk_signal_connect(GTK_OBJECT(skipstone->combo), "drag_data_received", GTK_SIGNAL_FUNC(on_location_entry_drag_data_received), skipstone); + gtk_drag_dest_set (GTK_WIDGET(skipstone->combo), GTK_DEST_DEFAULT_ALL, + embed_drop_types, embed_drop_types_num_items, + GDK_ACTION_COPY | GDK_ACTION_MOVE | + GDK_ACTION_LINK | GDK_ACTION_ASK ); if (combo_urls !=NULL) gtk_combo_set_popdown_strings(GTK_COMBO(skipstone->combo),combo_urls); diff -Nur /home/aho/CVS/skipstone/src/moz_callbacks.c skipstone/src/moz_callbacks.c --- /home/aho/CVS/skipstone/src/moz_callbacks.c Sat Dec 15 05:30:01 2001 +++ skipstone/src/moz_callbacks.c Sun Dec 16 09:38:17 2001 @@ -35,6 +35,15 @@ #define CONTEXT_XUL 256 +/* type of drag and drop for links */ +static const GtkTargetEntry link_drag_types[] = +{ + { "_NETSCAPE_URL", 0, DND_TARGET_NETSCAPE_URL }, + { "STRING", 0, DND_TARGET_STRING }, +}; +static const gint link_drag_types_num_items = (sizeof (link_drag_types) / + sizeof (GtkTargetEntry)); + extern GSList *window_count; extern ConfigData config; extern GList *combo_urls; @@ -93,6 +102,12 @@ } g_return_if_fail(skipstone->progressbar != NULL); + + if (skipstone->link) { + g_free (skipstone->link); + skipstone->link = NULL; + } + gtk_progress_set_activity_mode(GTK_PROGRESS(skipstone->progressbar), 1); gtk_progress_configure(GTK_PROGRESS(skipstone->progressbar), 0, 0, 100); skipstone->timer = gtk_timeout_add (100, (GSourceFunc)progress, skipstone); @@ -113,8 +128,8 @@ skipstone->link=NULL; } - skipstone->link = g_strdup(message); - if (message && (strlen(message) == 0)) D_RETURN; + if (message && (message[0] != '\0')) + skipstone->link = g_strdup(message); gtk_statusbar_push(GTK_STATUSBAR(skipstone->statusbar), 1, message); D_RETURN; @@ -331,6 +346,8 @@ hide_bmark_toolbar_nb(); } + mozilla_dnd_init (skipstone); + D_RETURN; } @@ -613,4 +630,23 @@ n / 1000000, (n % 1000000) / 100000); } D_RETURN_( buf ); +} + +void on_drag_data_get (GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint time, SkipStone *skipstone) +{ + gchar *link; + + link = gtk_object_get_data (GTK_OBJECT (widget), "dragging_link"); + + if (link) { + switch (info) { + case DND_TARGET_STRING: + case DND_TARGET_NETSCAPE_URL: + gtk_selection_data_set (selection_data, selection_data->target, 8, link, strlen (link)); + break; + default: + g_warning ("Unknown DND type"); + break; + } + } } diff -Nur /home/aho/CVS/skipstone/src/mozilla.cpp skipstone/src/mozilla.cpp --- /home/aho/CVS/skipstone/src/mozilla.cpp Sun Dec 9 00:16:09 2001 +++ skipstone/src/mozilla.cpp Sun Dec 16 04:36:03 2001 @@ -60,6 +60,11 @@ #include "nsIPlatformCharset.h" #include "nsICharsetConverterManager.h" +#include "nsPIDOMWindow.h" +#include "nsIDOMWindowInternal.h" +#include "nsIChromeEventHandler.h" +#include "nsIDOMEventReceiver.h" + #include "PromptService.h" #include "nsGfxCIID.h" #include "nsIContentViewer.h" @@ -67,6 +72,8 @@ #include "nsIPrintOptions.h" #include "nsIWebBrowserPrint.h" #include "skipstone-print.h" +#include "skipstone-types.h" +#include "SkipDragListener.h" #include "debug.h" #define ALT_KEY 1 @@ -93,6 +100,7 @@ static nsIPresShell *mozilla_get_presShell(nsIDocShell *docShell); static nsIDOMDocument *mozilla_get_dom_document(nsIPresShell *presShell); static gchar *mozilla_get_attribute (nsIDOMNode *node, gchar *attribute); +static nsresult GetPIDOMWindow(nsIWebBrowser *webBrowser, nsPIDOMWindow **aPIWin); extern "C" { @@ -844,4 +852,74 @@ uniStr = g_new0 (PRUnichar, 1); uniStr[0] = '\0'; D_RETURN_( uniStr ); +} + +static nsresult GetPIDOMWindow(nsIWebBrowser *webBrowser, nsPIDOMWindow **aPIWin) +{ + *aPIWin = nsnull; + + nsCOMPtr domWindow; + webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + if (!domWindow) + return NS_ERROR_FAILURE; + + nsCOMPtr domWindowPrivate = do_QueryInterface(domWindow); + nsCOMPtr rootWindow; + domWindowPrivate->GetPrivateRoot(getter_AddRefs(rootWindow)); + + nsCOMPtr chromeHandler; + nsCOMPtr piWin(do_QueryInterface(rootWindow)); + + *aPIWin = piWin.get(); + + if (*aPIWin) { + NS_ADDREF(*aPIWin); + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + +extern "C" gpointer +mozilla_dnd_init (SkipStone *skipstone) +{ + nsresult rv = NS_OK; + + //g_print ("DnD init ... "); + + nsCOMPtr webBrowser; + gtk_moz_embed_get_nsIWebBrowser (skipstone->embed, + getter_AddRefs(webBrowser)); + + nsCOMPtr piWin; + GetPIDOMWindow(webBrowser, getter_AddRefs(piWin)); + if (!piWin) return NULL; + + + /* get event handler */ + nsCOMPtr chromeHandler; + piWin->GetChromeEventHandler(getter_AddRefs(chromeHandler)); + if (!chromeHandler) return NULL; + + /* get event receiver */ + nsCOMPtr eventReceiver; + eventReceiver = do_QueryInterface(chromeHandler); + if (!eventReceiver) return NULL; + + /* create new drag event listener */ + nsCOMPtr dragListener; + dragListener = new SkipDragListener(); + dragListener->Init(skipstone); + if (!dragListener) return NULL; + + /* set drag event listener */ + nsCOMPtr eventListener = NS_STATIC_CAST(nsIDOMEventListener *, NS_STATIC_CAST(nsIDOMDragListener *, dragListener)); + rv = eventReceiver->AddEventListenerByIID(eventListener, NS_GET_IID(nsIDOMDragListener)); + if (NS_FAILED(rv)) { + return NULL; + } + + //g_print ("Complete!!\n"); + + return (gpointer) dragListener; } diff -Nur /home/aho/CVS/skipstone/src/skipstone-types.h skipstone/src/skipstone-types.h --- /home/aho/CVS/skipstone/src/skipstone-types.h Sat Dec 15 13:14:51 2001 +++ skipstone/src/skipstone-types.h Sun Dec 16 02:30:15 2001 @@ -289,5 +289,12 @@ }; +enum dnd_target_types { + DND_TARGET_URI_LIST, + DND_TARGET_NETSCAPE_URL, + DND_TARGET_STRING +}; + + #endif /* __SKIPSTONE_TYPE__H__ */ diff -Nur /home/aho/CVS/skipstone/src/skipstone.h skipstone/src/skipstone.h --- /home/aho/CVS/skipstone/src/skipstone.h Sat Dec 15 13:14:51 2001 +++ skipstone/src/skipstone.h Sun Dec 16 03:20:47 2001 @@ -84,6 +84,10 @@ void toggle_mime_handling(void); void create_dialog(gchar *title, gchar *labeltext, gint logo, gint lock); /* generic dialog */ void on_offline_toggle_cb(GtkCheckMenuItem *menuitem); +void on_location_entry_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, SkipStone *skipstone); + +void on_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint time, SkipStone *skipstone); +void on_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, SkipStone *skipstone); /* configure */ void open_config_dialog(GtkWidget *menuitem,gpointer data); @@ -175,6 +179,7 @@ extern void mozilla_save_image(GtkMozEmbed *b,gchar *location,gchar *FullPath); extern void mozilla_destroy_history(gpointer SkipNsHistory); extern gchar * mozilla_get_document_title (GtkMozEmbed *embed); +extern gpointer mozilla_dnd_init (SkipStone *skipstone); /* go */