#67879 eliminate crash unix defalt plugin; add puzzle pixmap to unix nullplugin; sr=blizzard, r=av

This commit is contained in:
serge%netscape.com 2001-04-14 21:14:23 +00:00
Родитель 7e92a0a0d1
Коммит a46fac61ea
4 изменённых файлов: 472 добавлений и 116 удалений

Просмотреть файл

@ -34,6 +34,13 @@
#include <stdio.h>
#include <gtk/gtk.h>
/* Xlib/Xt stuff */
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/cursorfont.h>
#include <X11/xpm.h>
#include "npapi.h"
#include "nullplugin.h"
@ -42,32 +49,14 @@
/* 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 +88,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 +109,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 +134,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 +161,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 +224,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 +271,145 @@ 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 Pixmap aPixmap = 0, aShapeMask = 0;
static XpmAttributes xpm_attr;
static Cursor cursor = 0;
static int
createPixmap(PluginInstance *This)
{
int err = 0;
if (aPixmap) return err;
xpm_attr.valuemask = 0;
err = XpmCreatePixmapFromData(This->display, This->window, npnul320_xpm, &aPixmap, &aShapeMask, &xpm_attr);
if (err) {
fprintf(stderr, "%s\n", XpmGetErrorString(err));
}
return err;
}
static void
drawPixmap(PluginInstance *This)
{
if (aPixmap)
{
int dest_x = This->width/2 - xpm_attr.width/2;
int dest_y = This->height/2 - xpm_attr.height/2;
if (dest_x >= 0 && dest_y >= 0)
{
GC gc;
gc = XCreateGC(This->display, This->window, 0, NULL);
XCopyArea(This->display, aPixmap, This->window, gc,
0, 0, xpm_attr.width, xpm_attr.height, dest_x, dest_y);
XFreeGC(This->display, gc);
}
}
}
static void
set_cursor (PluginInstance *This)
{
if (!cursor)
{
cursor = XCreateFontCursor(This->display, XC_hand2);
}
if (cursor)
{
XDefineCursor(This->display, This->window, cursor);
}
}
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);
addXtEventHandler(This);
set_cursor(This);
}

Просмотреть файл

@ -82,10 +82,13 @@ 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);

Просмотреть файл

@ -34,6 +34,13 @@
#include <stdio.h>
#include <gtk/gtk.h>
/* Xlib/Xt stuff */
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/cursorfont.h>
#include <X11/xpm.h>
#include "npapi.h"
#include "nullplugin.h"
@ -42,32 +49,14 @@
/* 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 +88,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 +109,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 +134,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 +161,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 +224,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 +271,145 @@ 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 Pixmap aPixmap = 0, aShapeMask = 0;
static XpmAttributes xpm_attr;
static Cursor cursor = 0;
static int
createPixmap(PluginInstance *This)
{
int err = 0;
if (aPixmap) return err;
xpm_attr.valuemask = 0;
err = XpmCreatePixmapFromData(This->display, This->window, npnul320_xpm, &aPixmap, &aShapeMask, &xpm_attr);
if (err) {
fprintf(stderr, "%s\n", XpmGetErrorString(err));
}
return err;
}
static void
drawPixmap(PluginInstance *This)
{
if (aPixmap)
{
int dest_x = This->width/2 - xpm_attr.width/2;
int dest_y = This->height/2 - xpm_attr.height/2;
if (dest_x >= 0 && dest_y >= 0)
{
GC gc;
gc = XCreateGC(This->display, This->window, 0, NULL);
XCopyArea(This->display, aPixmap, This->window, gc,
0, 0, xpm_attr.width, xpm_attr.height, dest_x, dest_y);
XFreeGC(This->display, gc);
}
}
}
static void
set_cursor (PluginInstance *This)
{
if (!cursor)
{
cursor = XCreateFontCursor(This->display, XC_hand2);
}
if (cursor)
{
XDefineCursor(This->display, This->window, cursor);
}
}
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);
addXtEventHandler(This);
set_cursor(This);
}

Просмотреть файл

@ -82,10 +82,13 @@ 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);