#67879 fix the crash, getting rid of xpm.h to show up a puzzle pixmap; sr=blizzard, r=av

This commit is contained in:
serge%netscape.com 2001-04-17 23:57:26 +00:00
Родитель 093eb06477
Коммит a9d6f87537
8 изменённых файлов: 564 добавлений и 140 удалений

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

@ -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

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

@ -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;
}

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

@ -34,40 +34,30 @@
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
/* Xlib/Xt stuff */
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/cursorfont.h>
#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);
}
}

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

@ -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();

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

@ -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

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

@ -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;
}

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

@ -34,40 +34,30 @@
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
/* Xlib/Xt stuff */
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/cursorfont.h>
#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);
}
}

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

@ -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();