moz-bonobo-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[moz-bonobo-list] Calling javascript or changing the location from a bon


From: Jean Bréfort
Subject: [moz-bonobo-list] Calling javascript or changing the location from a bonobo control
Date: Tue, 30 Sep 2003 11:52:12 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.4) Gecko/20030702

Hi,

I join a patch to allow Bonobo Controls to interact to some extent with
mozilla.

How to use the new code?

In the Bonobo control initialization, add something like that:

and in an event handler:

>     BonoboEventSource* evs = bonobo_event_source_new();
> bonobo_object_add_interface((BonoboObject*)control, (BonoboObject*)evs);

and in the appropriate event handler:

>     BonoboArg* arg = bonobo_arg_new(BONOBO_ARG_STRING);
>     BONOBO_ARG_SET_STRING(arg, "some url");
>     bonobo_event_source_notify_listeners (evs, "URL", arg, NULL);
the "some url" string can be an URL in which case the page displayed in the browser will change or some javascript code such as the classical:
> "javascript:alert('hello world.')"

The string is passed to NPN_GetURL. See the documentation of this
function for more details.

Best regards,
Jean

diff -ru5 mozilla-bonobo.orig/src/mozilla-bonobo-plugin.c 
mozilla-bonobo/src/mozilla-bonobo-plugin.c
--- mozilla-bonobo.orig/src/mozilla-bonobo-plugin.c     Mon Sep 29 18:49:43 2003
+++ mozilla-bonobo/src/mozilla-bonobo-plugin.c  Mon Sep 29 18:50:13 2003
@@ -28,10 +28,11 @@
 
 #include <string.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <signal.h>
+#include <pthread.h>
 #include <sys/wait.h>
 #include <sys/types.h>
 #include "../config.h"
 
 /* Function for printing debugging messages */
@@ -63,10 +64,12 @@
        FILE *to_stream;        /* The stream connected to the viewers' 
standard in */
        FILE *from_stream;      /* The stream connected to the viewers' 
standard out */
 
        int argc;       
        char **args;
+       pthread_t thread;
+       NPP instance;
 } PluginInstance;
 
 /* Forward declaration of the spawning function */
 void spawn_viewer(PluginInstance* This);
 
@@ -230,10 +233,11 @@
        }
 
        instance->pdata = NPN_MemAlloc(sizeof(PluginInstance));
 
        This = (PluginInstance*) instance->pdata;
+       This->instance = instance;
 
        if (This == NULL) {
                return NPERR_OUT_OF_MEMORY_ERROR;
        }
 
@@ -276,25 +280,32 @@
        if (instance == NULL) {
                return NPERR_INVALID_INSTANCE_ERROR;
        }
 
        This = (PluginInstance*) instance->pdata;
-       
+
        if (This != NULL) {
-               
+
                if (This->to_pipe != 0) {
                        /* If the viewer has actually been spawned */
        
                        /* Send it the exit command */
                        fprintf(This->to_stream, "exit\n");
 
                        /* The flush is important */
                        fflush(This->to_stream);
+                       
+                       void *returned_value;
+                       pthread_join (This->thread, &returned_value);
 
                        /* Wait for the process to end so no zombie process is 
left */
                        waitpid(This->child_pid, NULL, 0);
                }
+
+               if (This->from_pipe != 0) {
+                       fclose (This->from_stream);
+               }
                
                /* Free some resources */
                if (This->url) free(This->url);
 
                if (This->args) {
@@ -310,10 +321,30 @@
        }
 
        return NPERR_NO_ERROR;
 }
 
+/* The listening thread*/
+void* listen_viewer (void* arg)
+{
+       char buf[256];
+       PluginInstance* This = (PluginInstance *) arg;
+       while (fgets (buf, sizeof (buf), This->from_stream)) {
+               buf [strlen (buf) -1] = 0;
+               if (!strcmp (buf, "URL"))
+               {
+                       fgets (buf, sizeof (buf), This->from_stream);
+                       buf [strlen (buf) -1] = 0;
+                       NPN_GetURL (This->instance, buf, "_self");
+               }
+               else if (!strcmp (buf, "exit"))
+                       break;
+       }
+       static int status = 0 ;
+       pthread_exit(&status) ;
+}
+
 /* This function actually spawns the viewer. It expects the "This->url"
  * field and the "This->moz_xid" field to be valid.
  */
 void spawn_viewer(PluginInstance* This) {
 
@@ -333,10 +364,13 @@
 
        spawn_program(argv, &This->to_pipe, &This->from_pipe, &This->child_pid);
        
        This->to_stream = (FILE*)fdopen(This->to_pipe, "w");
        This->from_stream = (FILE*)fdopen(This->from_pipe, "r");
+
+       /*Start a new thread to listen This->from_stream*/
+       pthread_create (&This->thread, NULL, listen_viewer, This);
 }
 
 /* This is tricky stuff. Mozilla calls it several times with different
  * parameters. Basically it tells us the window into which we should draw,
  * and tells us when the size changes or when the window is reparented.
diff -ru5 mozilla-bonobo.orig/src/mozilla-bonobo-viewer.c 
mozilla-bonobo/src/mozilla-bonobo-viewer.c
--- mozilla-bonobo.orig/src/mozilla-bonobo-viewer.c     Mon Sep 29 18:49:43 2003
+++ mozilla-bonobo/src/mozilla-bonobo-viewer.c  Mon Sep 29 18:50:13 2003
@@ -55,10 +55,13 @@
 char *mime_type;
 
 /* The io channel through which the viewer receives commands from the plugin */
 GIOChannel *in_channel;
 
+/* The io channel through which the viewer sends commands to the plugin */
+GIOChannel *out_channel;
+
 /* The GtkPlug that embeds the viewer into the browser window */
 GtkWidget *plug;       /* Main "window" */
 
 /* The GtkFixed that is used to get sane resizing */
 GtkWidget *fixed;
@@ -100,10 +103,25 @@
 const char* gnome_vfs_get_mime_type_from_file_data(GnomeVFSURI *uri);
 
 Bonobo_ServerInfo *server_info;
 Bonobo_ActivationID id;
 
+/*this callback is called when the BonoboEventSource associated to the control 
emits
+an event*/
+
+static void
+listener_callback (BonoboListener *l, char *event_name,
+                      BonoboArg* value, CORBA_Environment *ev,
+                      gpointer user_data)
+{
+       int nb;
+       gchar* buf;
+       buf = g_strdup_printf("%s\n%s\n", event_name, 
BONOBO_ARG_GET_STRING(value));
+       g_io_channel_write (out_channel, buf, strlen(buf), &nb);
+       g_free (buf);
+}
+
 /* This function creates a bonobo control that can display the given
  * URL. It sets the control to be non-editable, and returns NULL if
  * no control could be created.
  */
 CORBA_Object obj;
@@ -112,10 +130,12 @@
        GtkWidget *control;
        BonoboActivationInfo *activation_info;
        
        CORBA_Environment ev;
        Bonobo_Control bcontrol;
+       Bonobo_Unknown event_source;
+       BonoboListener *listener;
        
        server_info = gnome_vfs_mime_get_default_component(mime_type);
        
        activation_info = bonobo_activation_servinfo_to_actinfo(server_info);
        
@@ -211,11 +231,18 @@
                        /* Set editable property */
                        bonobo_pbclient_set_boolean(prop_bag, 
"bonobo:editable", FALSE, NULL);
                        DEBUGM("viewer: set editable to false\n");
                }
        }
-       
+
+       event_source = Bonobo_Unknown_queryInterface(bonobo_widget_get_objref 
(BONOBO_WIDGET(control)),
+                                                                               
                                                                                
        "IDL:Bonobo/EventSource:1.0", NULL);    
+       if (event_source) {
+               listener = bonobo_listener_new ((BonoboListenerCallbackFn) 
listener_callback, NULL);
+               Bonobo_EventSource_addListener (event_source, 
bonobo_object_corba_objref (BONOBO_OBJECT(listener)), NULL);
+       }
+
        return control;
 }
 
 GtkWidget *createPlug(unsigned long xid) {
        GtkWidget *res;
@@ -263,11 +290,13 @@
 }
 
 /* Callback called if the window is closed. Applicable only in standalone mode.
  */
 static void window_destroyed (GtkWindow *window, char * data) {
-    bonobo_main_quit();
+       int nb;
+       g_io_channel_write (out_channel, "exit\n", 5, &nb);
+   bonobo_main_quit();
 }
 
 #ifdef BLACKLIST_UNSUPPORTED_MIME_TYPES
 
 /* This function pops up a dialog that asks the user if he wants to
@@ -338,15 +367,14 @@
 
 /* This function is called as soon as data is available on the io channel
  * on which we receive commands from the plugin.
  */
 static gboolean io_func(GIOChannel *source, GIOCondition condition, gpointer 
data) {
-       
        GError *err = NULL;
        
        char *string;   /* The string we read from the io channel */
-       
+
        gsize length;   /* Its size */
        
        /* Read 1 line from the io channel, including newline character */
        int status = g_io_channel_read_line(source, &string, &length, NULL, 
&err);
 
@@ -451,14 +479,17 @@
                g_free(string);
                return TRUE;
        }
        
        if (g_str_equal("exit\n", string) == TRUE) {
+               int nb;
                /* The command was "exit", so that's what we do */
                
                g_free(string);
                
+               g_io_channel_write (out_channel, "exit\n", 5, &nb);
+               
                bonobo_main_quit();
                return TRUE;
        }
        
        if (g_str_equal("param\n", string) == TRUE) {
@@ -923,11 +954,12 @@
        gtk_widget_show_all(GTK_WIDGET(plug));          
 
        /* Connect the io channel through which we'll get commands */
        in_channel = g_io_channel_unix_new(fileno(stdin));      /* std in */
        g_io_add_watch(in_channel, G_IO_IN, io_func, &err);
-               
+       out_channel = g_io_channel_unix_new(fileno(stdout));    /* std in */
+       
        if (err != NULL) {
                g_error("Error: %s\n", err->message);
                g_error_free(err);
        }
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]