diff --git a/mozilla/modules/plugin/default/unix/Makefile.in b/mozilla/modules/plugin/default/unix/Makefile.in index 470e6d86bfd..26829cd0d30 100644 --- a/mozilla/modules/plugin/default/unix/Makefile.in +++ b/mozilla/modules/plugin/default/unix/Makefile.in @@ -48,7 +48,7 @@ DEFINES += -D_IMPL_NS_PLUGIN include $(topsrcdir)/config/rules.mk -EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS) \ +EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS) -lXt \ $(NULL) ifndef MOZ_MONOLITHIC_TOOLKIT diff --git a/mozilla/modules/plugin/default/unix/npshell.c b/mozilla/modules/plugin/default/unix/npshell.c index 0be4e6bd3e8..032d9272b0a 100644 --- a/mozilla/modules/plugin/default/unix/npshell.c +++ b/mozilla/modules/plugin/default/unix/npshell.c @@ -44,6 +44,7 @@ #include "npapi.h" #include "nullplugin.h" #include "strings.h" +#include "plstr.h" /*********************************************************************** * @@ -91,6 +92,7 @@ NPP_GetJavaClass() void NPP_Shutdown(void) { + destroyPixmap(); } NPError @@ -135,16 +137,16 @@ NPP_New(NPMIMEType pluginType, argc --; if (argv[argc] != NULL) { - if (!strcasecmp(argn[argc], "PLUGINSPAGE")) + if (!PL_strcasecmp(argn[argc], "PLUGINSPAGE")) This->pluginsPageUrl = strdup(argv[argc]); - else if (!strcasecmp(argn[argc], "PLUGINURL")) + else if (!PL_strcasecmp(argn[argc], "PLUGINURL")) This->pluginsFileUrl = strdup(argv[argc]); - else if (!strcasecmp(argn[argc], "CODEBASE")) + else if (!PL_strcasecmp(argn[argc], "CODEBASE")) This->pluginsPageUrl = strdup(argv[argc]); - else if (!strcasecmp(argn[argc], "CLASSID")) + else if (!PL_strcasecmp(argn[argc], "CLASSID")) This->pluginsFileUrl = strdup(argv[argc]); - else if (!strcasecmp(argn[argc], "HIDDEN")) - This->pluginsHidden = (!strcasecmp(argv[argc], + else if (!PL_strcasecmp(argn[argc], "HIDDEN")) + This->pluginsHidden = (!PL_strcasecmp(argv[argc], "TRUE")); } } @@ -152,7 +154,6 @@ NPP_New(NPMIMEType pluginType, return NPERR_NO_ERROR; } - NPError NPP_Destroy(NPP instance, NPSavedData** save) { @@ -165,6 +166,8 @@ NPP_Destroy(NPP instance, NPSavedData** save) This = (PluginInstance*) instance->pdata; if (This != NULL) { + if (This->dialogBox) + destroyWidget(This); if (This->type) NPN_MemFree(This->type); if (This->pluginsPageUrl) @@ -221,10 +224,8 @@ NPP_SetWindow(NPP instance, NPWindow* window) This->visual = ws_info->visual; This->depth = ws_info->depth; This->colormap = ws_info->colormap; - if (This->exists != TRUE) { - This->exists = FALSE; - makeWidget(This); - } + makePixmap(This); + makeWidget(This); } return NPERR_NO_ERROR; } diff --git a/mozilla/modules/plugin/default/unix/nullplugin.c b/mozilla/modules/plugin/default/unix/nullplugin.c index 6fb2c2cd7d9..d237092ba6e 100644 --- a/mozilla/modules/plugin/default/unix/nullplugin.c +++ b/mozilla/modules/plugin/default/unix/nullplugin.c @@ -34,40 +34,30 @@ #include #include +#include + +/* Xlib/Xt stuff */ +#include +#include +#include + #include "npapi.h" #include "nullplugin.h" +#include "prprf.h" #define DIALOGID "dialog" /* Global data */ static MimeTypeElement *head = NULL; -/* this function is used to clear the mime type cache list - whenever the dialog box is closed. We need to clear the - list in order to have the dialog box pop up again when - the page is reload. (it's because there is no puzzle - icon in unix to let the people actively forward to netscape - page) */ -static void -clearList(MimeTypeElement **typelist) +/* destroy the dialog box */ +void +destroyWidget(PluginInstance *This) { - MimeTypeElement *ele; - MimeTypeElement *ele2; - - if (typelist == NULL) - return; - - /* follow the head to free the list */ - ele = *typelist; - while (ele != NULL) { - ele2 = ele->next; - if (ele->value != NULL) - NPN_MemFree(ele->value); - NPN_MemFree(ele); - ele = ele2; + if (This && This->dialogBox) + { + gtk_widget_destroy (GTK_WIDGET(This->dialogBox)); } - *typelist = ele; - return; } /* callback function for the OK button */ @@ -99,7 +89,7 @@ DialogOKClicked (GtkButton *button, gpointer data) { /* If necessary, get the default plug-ins page resource */ char* address = This->pluginsPageUrl; - if (address == NULL) + if (address == NULL || *address == 0) { address = PLUGINSPAGE_URL; } @@ -120,16 +110,14 @@ DialogOKClicked (GtkButton *button, gpointer data) NPN_MemFree(url); } } - gtk_widget_destroy (dialogWindow); - clearList(&head); + destroyWidget(This); } /* the call back function for cancel button */ static void DialogCancelClicked (GtkButton *button, gpointer data) { - gtk_widget_destroy (GTK_WIDGET(data)); - clearList(&head); + destroyWidget((PluginInstance*) data); } /* a handy procedure to add a widget and pack it as well */ @@ -147,23 +135,21 @@ AddWidget (GtkWidget *widget, GtkWidget *packingbox) static gboolean isEqual(NPMIMEType t1, NPMIMEType t2) { - return(strcmp(t1, t2) == 0); + return (t1 && t2) ? (strcmp(t1, t2) == 0) : FALSE; } -static gboolean +static MimeTypeElement * isExist(MimeTypeElement **typelist, NPMIMEType type) { MimeTypeElement *ele; - if (typelist == NULL) return FALSE; - ele = *typelist; while (ele != NULL) { - if (isEqual(ele->value, type)) - return TRUE; + if (isEqual(ele->pinst->type, type)) + return ele; ele = ele->next; } - return FALSE; + return NULL; } NPMIMEType @@ -176,19 +162,58 @@ dupMimeType(NPMIMEType type) } static gboolean -addToList(MimeTypeElement **typelist, NPMIMEType type) +addToList(MimeTypeElement **typelist, PluginInstance *This) { - MimeTypeElement *ele; + if (This && This->type && !isExist(typelist, This->type)) + { + MimeTypeElement *ele; + if ((ele = (MimeTypeElement *) NPN_MemAlloc(sizeof(MimeTypeElement)))) + { + ele->pinst = This; + ele->next = *typelist; + *typelist = ele; + return(TRUE); + } + } + return(FALSE); +} - if (!typelist) return(FALSE); +static gboolean +delFromList(MimeTypeElement **typelist, PluginInstance *This) +{ + if (typelist && This) + { + MimeTypeElement *ele_prev; + MimeTypeElement *ele = *typelist; + while (ele) + { + if (isEqual(ele->pinst->type, This->type)) + { + if (*typelist == ele) + { + *typelist = ele->next; + } else { + ele_prev->next = ele->next; + } + NPN_MemFree(ele); + return(TRUE); + } + ele_prev = ele; + ele = ele->next; + } + } + return(FALSE); +} - if (isExist(typelist, type)) return(FALSE); - - ele = (MimeTypeElement *) NPN_MemAlloc(sizeof(MimeTypeElement)); - ele->value = dupMimeType(type); - ele->next = *typelist; - *typelist = ele; - return(TRUE); +static void +onDestroyWidget(GtkWidget *w, gpointer data) +{ + PluginInstance* This = (PluginInstance*) data; + if (This && This->dialogBox && This->dialogBox == w) + { + This->dialogBox = 0; + delFromList(&head, This); + } } /* create and display the dialog box */ @@ -200,17 +225,37 @@ makeWidget(PluginInstance *This) GtkWidget *okButton; GtkWidget *cancelButton; char message[1024]; + MimeTypeElement *ele; if (!This) return; - if (This->exists == TRUE) return; + + /* need to check whether we already pop up a dialog box for previous + minetype in the same web page. It's require otherwise there will + be 2 dialog boxes pop if there are 2 plugin in the same web page + */ + if ((ele = isExist(&head, This->type))) + { + if (ele->pinst && ele->pinst->dialogBox) + { + GtkWidget *top_window = gtk_widget_get_toplevel(ele->pinst->dialogBox); + if (top_window && GTK_WIDGET_VISIBLE(top_window)) + { /* this will raise the toplevel window */ + gdk_window_show(top_window->window); + } + } + return; + } dialogWindow = gtk_dialog_new(); This->dialogBox = dialogWindow; This->exists = TRUE; + This->dialogBox = dialogWindow; + addToList(&head, This); gtk_window_set_title(GTK_WINDOW(dialogWindow), PLUGIN_NAME); - /* gtk_window_set_position(GTK_WINDOW(dialogWindow), GTK_WIN_POS_CENTER); */ - gtk_window_set_modal(GTK_WINDOW(dialogWindow), TRUE); - gtk_container_set_border_width(GTK_CONTAINER(dialogWindow), 0); + gtk_window_set_position(GTK_WINDOW(dialogWindow), GTK_WIN_POS_CENTER); + gtk_window_set_modal(GTK_WINDOW(dialogWindow), FALSE); + gtk_container_set_border_width(GTK_CONTAINER(dialogWindow), 20); + gtk_window_set_policy(GTK_WINDOW(dialogWindow), FALSE, FALSE, TRUE); PR_snprintf(message, sizeof(message) - 1, MESSAGE, This->type); dialogMessage = AddWidget(gtk_label_new (message), @@ -227,14 +272,175 @@ makeWidget(PluginInstance *This) GTK_SIGNAL_FUNC(DialogOKClicked), This); gtk_signal_connect (GTK_OBJECT(cancelButton), "clicked", - GTK_SIGNAL_FUNC(DialogCancelClicked), dialogWindow); + GTK_SIGNAL_FUNC(DialogCancelClicked), This); + /* hookup to when the dialog is destroyed */ + gtk_signal_connect(GTK_OBJECT(dialogWindow), "destroy", + GTK_SIGNAL_FUNC(onDestroyWidget), This); - /* need to check whether we already pop up a dialog box for previous - minetype in the same web page. It's require otherwise there will - be 2 dialog boxes pop if there are 2 plugin in the same web page */ - if (addToList(&head, This->type)) { - gtk_widget_show_all(dialogWindow); - } + gtk_widget_show_all(dialogWindow); } +/* XPM */ +static char * npnul320_xpm[] = { +"32 32 6 1", +" c None", +". c #808080", +"+ c #F8F8F8", +"@ c #C0C0C0", +"# c #000000", +"$ c #00F8F8", +"........................++++++++", +".++++++++++++++++++++++..+++++++", +".+++++++++++++++++++++@.@.++++++", +".++@@@@@@@@@@@@@@@@@@@@.+@.+++++", +".++@@@@@@@@@.....@@@@@@.++@.++++", +".++@@@@@@@@.+++++#@@@@@.+++@.+++", +".++@@@@@@@.++$$$$$#@@@@.++++@.++", +".++@@@@@@@.+$$$$$$#.@@@.+++++@.+", +".++@@@...@@.+$$$$#..###.#######+", +".++@@.+++$$++$$$$$##++$#......#+", +".++@@.+$$$++$$$$$$$+$$$#......#+", +".++@@.+$$$$$$$$$$$$$$$$#..@@++#+", +".++@@@$$$$$$$$$$$$$$$$#...@@++#+", +".++@@@$#$##.$$$$$$##$$#...@@++#+", +".++@@@@##...$$$$$#..##...@@@++#+", +".++@@@@@....+$$$$#.......@@@++#+", +".++@@@@@@...+$$$$#.@@@..@@@@++#+", +".++@@@@..@@.+$$$$#.@##@@@@@@++#+", +".++@@@.++$$++$$$$$##$$#@@@@@++#+", +".++@@@.+$$++$$$$$$$$$$#@@@@@++#+", +".++@@.++$$$$$$$$$$$$$$$#@@@@++#+", +".++@@.+$$$$$$$$$$$$$$$$#.@@@++#+", +".++@@.+$$##$$$$$$$##$$$#..@@++#+", +".++@@@###...$$$$$#.@###...@@++#+", +".++@@@@....$$$$$$$#.@.....@@++#+", +".++@@@@@...$$$$$$$#..@...@@@++#+", +".++@@@@@@@@#$$$$$#...@@@@@@@++#+", +".++@@@@@@@@@#####...@@@@@@@@++#+", +".++@@@@@@@@@@......@@@@@@@@@++#+", +".+++++++++++++....++++++++++++#+", +".+++++++++++++++++++++++++++++#+", +"###############################+"}; + + +static GdkPixmap *nullPluginGdkPixmap = 0; + +static GdkWindow *getGdkWindow(PluginInstance *This) +{ + GdkWindow *gdk_window; + Window xwin = (Window) This->window; + Widget xt_w = XtWindowToWidget(This->display, xwin); + + if (xt_w) { + xt_w = XtParent(xt_w); + if (xt_w) { + xwin = XtWindow(xt_w); + /* xwin = xt_w->core.window; */ + } + } + gdk_window = gdk_window_lookup(xwin); + return gdk_window; +} + +static void +createPixmap(PluginInstance *This) +{ + int err = 0; + + if (nullPluginGdkPixmap == 0) + { + GtkStyle *style; + GdkBitmap *mask; + GdkWindow *gdk_window = getGdkWindow(This); + if (gdk_window) + { + style = gtk_widget_get_style((GtkWidget *)gdk_window->user_data); + nullPluginGdkPixmap = gdk_pixmap_create_from_xpm_d(gdk_window , &mask, + &style->bg[GTK_STATE_NORMAL], npnul320_xpm); + } + } +} + +static void +drawPixmap(PluginInstance *This) +{ + if (nullPluginGdkPixmap) + { + int pixmap_with, pixmap_height, dest_x, dest_y; + gdk_window_get_size((GdkWindow *)nullPluginGdkPixmap, &pixmap_with, &pixmap_height); + dest_x = This->width/2 - pixmap_with/2; + dest_y = This->height/2 - pixmap_height/2; + if (dest_x >= 0 && dest_y >= 0) + { + GC gc; + gc = XCreateGC(This->display, This->window, 0, NULL); + XCopyArea(This->display, GDK_WINDOW_XWINDOW(nullPluginGdkPixmap) , This->window, gc, + 0, 0, pixmap_with, pixmap_height, dest_x, dest_y); + XFreeGC(This->display, gc); + } + } +} + +static void +setCursor (PluginInstance *This) +{ + static Cursor nullPluginCursor = 0; + if (!nullPluginCursor) + { + nullPluginCursor = XCreateFontCursor(This->display, XC_hand2); + } + if (nullPluginCursor) + { + XDefineCursor(This->display, This->window, nullPluginCursor); + } +} + +static void +xt_event_handler(Widget xt_w, PluginInstance *This, XEvent *xevent, Boolean *b) +{ + switch (xevent->type) + { + case Expose: + /* get rid of all other exposure events */ + while(XCheckTypedWindowEvent(This->display, This->window, Expose, xevent)); + drawPixmap(This); + break; + case ButtonRelease: + makeWidget(This); + break; + default: + break; + } +} + +static void +addXtEventHandler(PluginInstance *This) +{ + Display *dpy = (Display*) This->display; + Window xwin = (Window) This->window; + Widget xt_w = XtWindowToWidget(dpy, xwin); + if (xt_w) + { + long event_mask = ExposureMask | ButtonReleaseMask | ButtonPressMask; + XSelectInput(dpy, xwin, event_mask); + XtAddEventHandler(xt_w, event_mask, False, (XtEventHandler)xt_event_handler, This); + } +} + +void +makePixmap(PluginInstance *This) +{ + createPixmap(This); + drawPixmap(This); + setCursor(This); + addXtEventHandler(This); +} + +void destroyPixmap() +{ + if (nullPluginGdkPixmap) + { + gdk_pixmap_unref(nullPluginGdkPixmap); + } +} diff --git a/mozilla/modules/plugin/default/unix/nullplugin.h b/mozilla/modules/plugin/default/unix/nullplugin.h index 72b4f9b0420..c1a4707ef20 100644 --- a/mozilla/modules/plugin/default/unix/nullplugin.h +++ b/mozilla/modules/plugin/default/unix/nullplugin.h @@ -82,10 +82,15 @@ typedef struct _PluginInstance typedef struct _MimeTypeElement { - NPMIMEType value; + PluginInstance *pinst; struct _MimeTypeElement *next; } MimeTypeElement; /* Extern functions */ extern void makeWidget(PluginInstance *This); extern NPMIMEType dupMimeType(NPMIMEType type); +extern void destroyWidget(PluginInstance *This); +extern void makePixmap(PluginInstance *This); +extern void destroyPixmap(); + + diff --git a/mozilla/modules/plugin/samples/default/unix/Makefile.in b/mozilla/modules/plugin/samples/default/unix/Makefile.in index 470e6d86bfd..26829cd0d30 100644 --- a/mozilla/modules/plugin/samples/default/unix/Makefile.in +++ b/mozilla/modules/plugin/samples/default/unix/Makefile.in @@ -48,7 +48,7 @@ DEFINES += -D_IMPL_NS_PLUGIN include $(topsrcdir)/config/rules.mk -EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS) \ +EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS) -lXt \ $(NULL) ifndef MOZ_MONOLITHIC_TOOLKIT diff --git a/mozilla/modules/plugin/samples/default/unix/npshell.c b/mozilla/modules/plugin/samples/default/unix/npshell.c index 0be4e6bd3e8..032d9272b0a 100644 --- a/mozilla/modules/plugin/samples/default/unix/npshell.c +++ b/mozilla/modules/plugin/samples/default/unix/npshell.c @@ -44,6 +44,7 @@ #include "npapi.h" #include "nullplugin.h" #include "strings.h" +#include "plstr.h" /*********************************************************************** * @@ -91,6 +92,7 @@ NPP_GetJavaClass() void NPP_Shutdown(void) { + destroyPixmap(); } NPError @@ -135,16 +137,16 @@ NPP_New(NPMIMEType pluginType, argc --; if (argv[argc] != NULL) { - if (!strcasecmp(argn[argc], "PLUGINSPAGE")) + if (!PL_strcasecmp(argn[argc], "PLUGINSPAGE")) This->pluginsPageUrl = strdup(argv[argc]); - else if (!strcasecmp(argn[argc], "PLUGINURL")) + else if (!PL_strcasecmp(argn[argc], "PLUGINURL")) This->pluginsFileUrl = strdup(argv[argc]); - else if (!strcasecmp(argn[argc], "CODEBASE")) + else if (!PL_strcasecmp(argn[argc], "CODEBASE")) This->pluginsPageUrl = strdup(argv[argc]); - else if (!strcasecmp(argn[argc], "CLASSID")) + else if (!PL_strcasecmp(argn[argc], "CLASSID")) This->pluginsFileUrl = strdup(argv[argc]); - else if (!strcasecmp(argn[argc], "HIDDEN")) - This->pluginsHidden = (!strcasecmp(argv[argc], + else if (!PL_strcasecmp(argn[argc], "HIDDEN")) + This->pluginsHidden = (!PL_strcasecmp(argv[argc], "TRUE")); } } @@ -152,7 +154,6 @@ NPP_New(NPMIMEType pluginType, return NPERR_NO_ERROR; } - NPError NPP_Destroy(NPP instance, NPSavedData** save) { @@ -165,6 +166,8 @@ NPP_Destroy(NPP instance, NPSavedData** save) This = (PluginInstance*) instance->pdata; if (This != NULL) { + if (This->dialogBox) + destroyWidget(This); if (This->type) NPN_MemFree(This->type); if (This->pluginsPageUrl) @@ -221,10 +224,8 @@ NPP_SetWindow(NPP instance, NPWindow* window) This->visual = ws_info->visual; This->depth = ws_info->depth; This->colormap = ws_info->colormap; - if (This->exists != TRUE) { - This->exists = FALSE; - makeWidget(This); - } + makePixmap(This); + makeWidget(This); } return NPERR_NO_ERROR; } diff --git a/mozilla/modules/plugin/samples/default/unix/nullplugin.c b/mozilla/modules/plugin/samples/default/unix/nullplugin.c index 6fb2c2cd7d9..d237092ba6e 100644 --- a/mozilla/modules/plugin/samples/default/unix/nullplugin.c +++ b/mozilla/modules/plugin/samples/default/unix/nullplugin.c @@ -34,40 +34,30 @@ #include #include +#include + +/* Xlib/Xt stuff */ +#include +#include +#include + #include "npapi.h" #include "nullplugin.h" +#include "prprf.h" #define DIALOGID "dialog" /* Global data */ static MimeTypeElement *head = NULL; -/* this function is used to clear the mime type cache list - whenever the dialog box is closed. We need to clear the - list in order to have the dialog box pop up again when - the page is reload. (it's because there is no puzzle - icon in unix to let the people actively forward to netscape - page) */ -static void -clearList(MimeTypeElement **typelist) +/* destroy the dialog box */ +void +destroyWidget(PluginInstance *This) { - MimeTypeElement *ele; - MimeTypeElement *ele2; - - if (typelist == NULL) - return; - - /* follow the head to free the list */ - ele = *typelist; - while (ele != NULL) { - ele2 = ele->next; - if (ele->value != NULL) - NPN_MemFree(ele->value); - NPN_MemFree(ele); - ele = ele2; + if (This && This->dialogBox) + { + gtk_widget_destroy (GTK_WIDGET(This->dialogBox)); } - *typelist = ele; - return; } /* callback function for the OK button */ @@ -99,7 +89,7 @@ DialogOKClicked (GtkButton *button, gpointer data) { /* If necessary, get the default plug-ins page resource */ char* address = This->pluginsPageUrl; - if (address == NULL) + if (address == NULL || *address == 0) { address = PLUGINSPAGE_URL; } @@ -120,16 +110,14 @@ DialogOKClicked (GtkButton *button, gpointer data) NPN_MemFree(url); } } - gtk_widget_destroy (dialogWindow); - clearList(&head); + destroyWidget(This); } /* the call back function for cancel button */ static void DialogCancelClicked (GtkButton *button, gpointer data) { - gtk_widget_destroy (GTK_WIDGET(data)); - clearList(&head); + destroyWidget((PluginInstance*) data); } /* a handy procedure to add a widget and pack it as well */ @@ -147,23 +135,21 @@ AddWidget (GtkWidget *widget, GtkWidget *packingbox) static gboolean isEqual(NPMIMEType t1, NPMIMEType t2) { - return(strcmp(t1, t2) == 0); + return (t1 && t2) ? (strcmp(t1, t2) == 0) : FALSE; } -static gboolean +static MimeTypeElement * isExist(MimeTypeElement **typelist, NPMIMEType type) { MimeTypeElement *ele; - if (typelist == NULL) return FALSE; - ele = *typelist; while (ele != NULL) { - if (isEqual(ele->value, type)) - return TRUE; + if (isEqual(ele->pinst->type, type)) + return ele; ele = ele->next; } - return FALSE; + return NULL; } NPMIMEType @@ -176,19 +162,58 @@ dupMimeType(NPMIMEType type) } static gboolean -addToList(MimeTypeElement **typelist, NPMIMEType type) +addToList(MimeTypeElement **typelist, PluginInstance *This) { - MimeTypeElement *ele; + if (This && This->type && !isExist(typelist, This->type)) + { + MimeTypeElement *ele; + if ((ele = (MimeTypeElement *) NPN_MemAlloc(sizeof(MimeTypeElement)))) + { + ele->pinst = This; + ele->next = *typelist; + *typelist = ele; + return(TRUE); + } + } + return(FALSE); +} - if (!typelist) return(FALSE); +static gboolean +delFromList(MimeTypeElement **typelist, PluginInstance *This) +{ + if (typelist && This) + { + MimeTypeElement *ele_prev; + MimeTypeElement *ele = *typelist; + while (ele) + { + if (isEqual(ele->pinst->type, This->type)) + { + if (*typelist == ele) + { + *typelist = ele->next; + } else { + ele_prev->next = ele->next; + } + NPN_MemFree(ele); + return(TRUE); + } + ele_prev = ele; + ele = ele->next; + } + } + return(FALSE); +} - if (isExist(typelist, type)) return(FALSE); - - ele = (MimeTypeElement *) NPN_MemAlloc(sizeof(MimeTypeElement)); - ele->value = dupMimeType(type); - ele->next = *typelist; - *typelist = ele; - return(TRUE); +static void +onDestroyWidget(GtkWidget *w, gpointer data) +{ + PluginInstance* This = (PluginInstance*) data; + if (This && This->dialogBox && This->dialogBox == w) + { + This->dialogBox = 0; + delFromList(&head, This); + } } /* create and display the dialog box */ @@ -200,17 +225,37 @@ makeWidget(PluginInstance *This) GtkWidget *okButton; GtkWidget *cancelButton; char message[1024]; + MimeTypeElement *ele; if (!This) return; - if (This->exists == TRUE) return; + + /* need to check whether we already pop up a dialog box for previous + minetype in the same web page. It's require otherwise there will + be 2 dialog boxes pop if there are 2 plugin in the same web page + */ + if ((ele = isExist(&head, This->type))) + { + if (ele->pinst && ele->pinst->dialogBox) + { + GtkWidget *top_window = gtk_widget_get_toplevel(ele->pinst->dialogBox); + if (top_window && GTK_WIDGET_VISIBLE(top_window)) + { /* this will raise the toplevel window */ + gdk_window_show(top_window->window); + } + } + return; + } dialogWindow = gtk_dialog_new(); This->dialogBox = dialogWindow; This->exists = TRUE; + This->dialogBox = dialogWindow; + addToList(&head, This); gtk_window_set_title(GTK_WINDOW(dialogWindow), PLUGIN_NAME); - /* gtk_window_set_position(GTK_WINDOW(dialogWindow), GTK_WIN_POS_CENTER); */ - gtk_window_set_modal(GTK_WINDOW(dialogWindow), TRUE); - gtk_container_set_border_width(GTK_CONTAINER(dialogWindow), 0); + gtk_window_set_position(GTK_WINDOW(dialogWindow), GTK_WIN_POS_CENTER); + gtk_window_set_modal(GTK_WINDOW(dialogWindow), FALSE); + gtk_container_set_border_width(GTK_CONTAINER(dialogWindow), 20); + gtk_window_set_policy(GTK_WINDOW(dialogWindow), FALSE, FALSE, TRUE); PR_snprintf(message, sizeof(message) - 1, MESSAGE, This->type); dialogMessage = AddWidget(gtk_label_new (message), @@ -227,14 +272,175 @@ makeWidget(PluginInstance *This) GTK_SIGNAL_FUNC(DialogOKClicked), This); gtk_signal_connect (GTK_OBJECT(cancelButton), "clicked", - GTK_SIGNAL_FUNC(DialogCancelClicked), dialogWindow); + GTK_SIGNAL_FUNC(DialogCancelClicked), This); + /* hookup to when the dialog is destroyed */ + gtk_signal_connect(GTK_OBJECT(dialogWindow), "destroy", + GTK_SIGNAL_FUNC(onDestroyWidget), This); - /* need to check whether we already pop up a dialog box for previous - minetype in the same web page. It's require otherwise there will - be 2 dialog boxes pop if there are 2 plugin in the same web page */ - if (addToList(&head, This->type)) { - gtk_widget_show_all(dialogWindow); - } + gtk_widget_show_all(dialogWindow); } +/* XPM */ +static char * npnul320_xpm[] = { +"32 32 6 1", +" c None", +". c #808080", +"+ c #F8F8F8", +"@ c #C0C0C0", +"# c #000000", +"$ c #00F8F8", +"........................++++++++", +".++++++++++++++++++++++..+++++++", +".+++++++++++++++++++++@.@.++++++", +".++@@@@@@@@@@@@@@@@@@@@.+@.+++++", +".++@@@@@@@@@.....@@@@@@.++@.++++", +".++@@@@@@@@.+++++#@@@@@.+++@.+++", +".++@@@@@@@.++$$$$$#@@@@.++++@.++", +".++@@@@@@@.+$$$$$$#.@@@.+++++@.+", +".++@@@...@@.+$$$$#..###.#######+", +".++@@.+++$$++$$$$$##++$#......#+", +".++@@.+$$$++$$$$$$$+$$$#......#+", +".++@@.+$$$$$$$$$$$$$$$$#..@@++#+", +".++@@@$$$$$$$$$$$$$$$$#...@@++#+", +".++@@@$#$##.$$$$$$##$$#...@@++#+", +".++@@@@##...$$$$$#..##...@@@++#+", +".++@@@@@....+$$$$#.......@@@++#+", +".++@@@@@@...+$$$$#.@@@..@@@@++#+", +".++@@@@..@@.+$$$$#.@##@@@@@@++#+", +".++@@@.++$$++$$$$$##$$#@@@@@++#+", +".++@@@.+$$++$$$$$$$$$$#@@@@@++#+", +".++@@.++$$$$$$$$$$$$$$$#@@@@++#+", +".++@@.+$$$$$$$$$$$$$$$$#.@@@++#+", +".++@@.+$$##$$$$$$$##$$$#..@@++#+", +".++@@@###...$$$$$#.@###...@@++#+", +".++@@@@....$$$$$$$#.@.....@@++#+", +".++@@@@@...$$$$$$$#..@...@@@++#+", +".++@@@@@@@@#$$$$$#...@@@@@@@++#+", +".++@@@@@@@@@#####...@@@@@@@@++#+", +".++@@@@@@@@@@......@@@@@@@@@++#+", +".+++++++++++++....++++++++++++#+", +".+++++++++++++++++++++++++++++#+", +"###############################+"}; + + +static GdkPixmap *nullPluginGdkPixmap = 0; + +static GdkWindow *getGdkWindow(PluginInstance *This) +{ + GdkWindow *gdk_window; + Window xwin = (Window) This->window; + Widget xt_w = XtWindowToWidget(This->display, xwin); + + if (xt_w) { + xt_w = XtParent(xt_w); + if (xt_w) { + xwin = XtWindow(xt_w); + /* xwin = xt_w->core.window; */ + } + } + gdk_window = gdk_window_lookup(xwin); + return gdk_window; +} + +static void +createPixmap(PluginInstance *This) +{ + int err = 0; + + if (nullPluginGdkPixmap == 0) + { + GtkStyle *style; + GdkBitmap *mask; + GdkWindow *gdk_window = getGdkWindow(This); + if (gdk_window) + { + style = gtk_widget_get_style((GtkWidget *)gdk_window->user_data); + nullPluginGdkPixmap = gdk_pixmap_create_from_xpm_d(gdk_window , &mask, + &style->bg[GTK_STATE_NORMAL], npnul320_xpm); + } + } +} + +static void +drawPixmap(PluginInstance *This) +{ + if (nullPluginGdkPixmap) + { + int pixmap_with, pixmap_height, dest_x, dest_y; + gdk_window_get_size((GdkWindow *)nullPluginGdkPixmap, &pixmap_with, &pixmap_height); + dest_x = This->width/2 - pixmap_with/2; + dest_y = This->height/2 - pixmap_height/2; + if (dest_x >= 0 && dest_y >= 0) + { + GC gc; + gc = XCreateGC(This->display, This->window, 0, NULL); + XCopyArea(This->display, GDK_WINDOW_XWINDOW(nullPluginGdkPixmap) , This->window, gc, + 0, 0, pixmap_with, pixmap_height, dest_x, dest_y); + XFreeGC(This->display, gc); + } + } +} + +static void +setCursor (PluginInstance *This) +{ + static Cursor nullPluginCursor = 0; + if (!nullPluginCursor) + { + nullPluginCursor = XCreateFontCursor(This->display, XC_hand2); + } + if (nullPluginCursor) + { + XDefineCursor(This->display, This->window, nullPluginCursor); + } +} + +static void +xt_event_handler(Widget xt_w, PluginInstance *This, XEvent *xevent, Boolean *b) +{ + switch (xevent->type) + { + case Expose: + /* get rid of all other exposure events */ + while(XCheckTypedWindowEvent(This->display, This->window, Expose, xevent)); + drawPixmap(This); + break; + case ButtonRelease: + makeWidget(This); + break; + default: + break; + } +} + +static void +addXtEventHandler(PluginInstance *This) +{ + Display *dpy = (Display*) This->display; + Window xwin = (Window) This->window; + Widget xt_w = XtWindowToWidget(dpy, xwin); + if (xt_w) + { + long event_mask = ExposureMask | ButtonReleaseMask | ButtonPressMask; + XSelectInput(dpy, xwin, event_mask); + XtAddEventHandler(xt_w, event_mask, False, (XtEventHandler)xt_event_handler, This); + } +} + +void +makePixmap(PluginInstance *This) +{ + createPixmap(This); + drawPixmap(This); + setCursor(This); + addXtEventHandler(This); +} + +void destroyPixmap() +{ + if (nullPluginGdkPixmap) + { + gdk_pixmap_unref(nullPluginGdkPixmap); + } +} diff --git a/mozilla/modules/plugin/samples/default/unix/nullplugin.h b/mozilla/modules/plugin/samples/default/unix/nullplugin.h index 72b4f9b0420..c1a4707ef20 100644 --- a/mozilla/modules/plugin/samples/default/unix/nullplugin.h +++ b/mozilla/modules/plugin/samples/default/unix/nullplugin.h @@ -82,10 +82,15 @@ typedef struct _PluginInstance typedef struct _MimeTypeElement { - NPMIMEType value; + PluginInstance *pinst; struct _MimeTypeElement *next; } MimeTypeElement; /* Extern functions */ extern void makeWidget(PluginInstance *This); extern NPMIMEType dupMimeType(NPMIMEType type); +extern void destroyWidget(PluginInstance *This); +extern void makePixmap(PluginInstance *This); +extern void destroyPixmap(); + +