前段时间把 gtk 的 plugin 搞定了, 下一步就得把 scintilla 集成进来了.
这里保存一个简单的 gtk plugin 例子以便以后查阅.
这个 plugin 实现的功能很简单, 就是把 gtk 的 tutorial 里的第二个例子给实现了.
单击 “Hello World” Button 调用 gprintf 在终端显示 Hello World.
这个例子里, widget 有了, event handle 也有了. 麻雀虽小, 五脏俱全地说.

plugin.h

?Download plugin.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#ifndef __PLUGIN_H__
#define __PLUGIN_H__
 
/* Xlib/Xt stuff */
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/cursorfont.h>
 
#include <gtk/gtk.h>
 
#include "pluginbase.h"
 
class nsPluginInstance : public nsPluginInstanceBase {
public:
    nsPluginInstance(NPP aInstance);
    virtual ~nsPluginInstance();
 
    NPBool init(NPWindow* aWindow);
    void shut();
    NPBool isInitialized() {
        return mInitialized;
    }
    NPError GetValue(NPPVariable variable, void *value);
    NPError SetWindow(NPWindow* aWindow);
 
    // locals
    const char * getVersion();
 
private:
    NPP mInstance;
    NPBool mInitialized;
 
    GtkWidget* m_GtkWidget;
    GtkWidget *button;
 
    Window mWindow;
 
    int mX, mY;
    int mWidth, mHeight;
 
};
 
#endif // __PLUGIN_H__

plugin.cpp:

?Download plugin.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "plugin.h"
 
#define MIME_TYPES_HANDLED  "application/basic-plugin"
#define PLUGIN_NAME         "Basic Gtk Example Plug-in for Mozilla"
#define MIME_TYPES_DESCRIPTION  MIME_TYPES_HANDLED":bsc:"PLUGIN_NAME
#define PLUGIN_DESCRIPTION  PLUGIN_NAME " (Plug-ins Gtk sample)"
 
 
char* NPP_GetMIMEDescription(void) {
    return(MIME_TYPES_DESCRIPTION);
}
 
/////////////////////////////////////
// general initialization and shutdown
//
NPError NS_PluginInitialize() {
    return NPERR_NO_ERROR;
}
 
void NS_PluginShutdown() {}
 
// get values per plugin
NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue) {
    NPError err = NPERR_NO_ERROR;
 
    switch (aVariable) {
    case NPPVpluginNameString:
        *((char **)aValue) = PLUGIN_NAME;
        break;
    case NPPVpluginDescriptionString:
        *((char **)aValue) = PLUGIN_DESCRIPTION;
        break;
    default:
        err = NPERR_INVALID_PARAM;
        break;
    }
 
    return err;
}
 
/////////////////////////////////////////////////////////////
//
// construction and destruction of our plugin instance object
//
nsPluginInstanceBase * NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct) {
    if(!aCreateDataStruct)
        return NULL;
 
    nsPluginInstance * plugin = new nsPluginInstance(aCreateDataStruct->instance);
    return plugin;
}
 
void NS_DestroyPluginInstance(nsPluginInstanceBase * aPlugin) {
    if(aPlugin)
        delete (nsPluginInstance *)aPlugin;
}
 
////////////////////////////////////////
//
// nsPluginInstance class implementation
//
nsPluginInstance::nsPluginInstance(NPP aInstance) : nsPluginInstanceBase(),
        mInstance(aInstance),
        mInitialized(FALSE),
        mWindow(0),
        m_GtkWidget(NULL) {}
 
nsPluginInstance::~nsPluginInstance() {}
 
static void hello(GtkWidget *widget, gpointer data) {
    g_print ("Hello World\n");
}
 
NPBool nsPluginInstance::init(NPWindow* aWindow) {
    if(aWindow == NULL)
        return FALSE;
 
    if (SetWindow(aWindow))
        mInitialized = TRUE;
 
    return mInitialized;
}
 
void nsPluginInstance::shut() {
    mInitialized = FALSE;
}
 
const char * nsPluginInstance::getVersion() {
    return NPN_UserAgent(mInstance);
}
 
NPError nsPluginInstance::GetValue(NPPVariable aVariable, void *aValue) {
    NPError err = NPERR_NO_ERROR;
 
    switch (aVariable) {
    case NPPVpluginNameString:
    case NPPVpluginDescriptionString:
        return NS_PluginGetValue(aVariable, aValue) ;
        break;
    default:
        err = NPERR_INVALID_PARAM;
        break;
    }
 
    return err;
}
 
NPError nsPluginInstance::SetWindow(NPWindow* aWindow) {
    if(aWindow == NULL)
        return FALSE;
 
    mX = aWindow->x;
    mY = aWindow->y;
    mWidth = aWindow->width;
    mHeight = aWindow->height;
 
    if (mWindow == (Window) aWindow->window) {
        // The page with the plugin is being resized.
        // Save any UI information because the next time
        // around expect a SetWindow with a new window id.
    } else {
 
        mWindow = (Window) aWindow->window;
 
        m_GtkWidget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_widget_realize(m_GtkWidget);
 
        gtk_widget_set_size_request(m_GtkWidget, aWindow->width, aWindow->height);
 
        button = gtk_button_new_with_label ("Hello World");
        g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (hello), NULL);
 
        gtk_container_add (GTK_CONTAINER (m_GtkWidget), button);
 
        gtk_widget_show (button);
 
        gtk_widget_show_all(m_GtkWidget);
 
    }
 
    return TRUE;
}

Makefile:

?Download Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
CXX   = g++
CPPFLAGS +=	-fno-rtti \
-fno-exceptions \
-shared  
 
# Change this to point at your Gecko SDK directory. 
GECKO_SDK_PATH = /home/duo/gecko-sdk
 
 
GECKO_DEFINES  = -DMOZ_X11 -DMOZILLA_STRICT_API
GECKO_INCLUDES = -I $(GECKO_SDK_PATH)/include
 
GTK_INCLUDES = -I /usr/include/gtk-2.0 -I /usr/lib/gtk-2.0/include 
GECKO_LDFLAGS =  -L $(GECKO_SDK_PATH)/lib -rdynamic  -lXi -lXext -lX11 -lm -lXt
 
PLUGIN_INCLUDES = -I include
 
GTK_CFLAGS = -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include  
GTK_LIBS = -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0
 
GUI_CFLAGS = -pthread -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/freetype2
GUI_LIBS =  -pthread -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 -lgobject-2.0 -lgmodule-2.0 -ldl -lgthread-2.0 -lglib-2.0 -lfreetype -lz -lXft -lXrender -lfontconfig -lfreetype -lz -lX11
 
FILES = plugin.cpp common/*.cpp
 
TARGET = libplugin.so
 
build: 
	$(CXX) -Wall -Os -o $(TARGET) $(GECKO_CONFIG_INCLUDE) $(GECKO_DEFINES) $(PLUGIN_INCLUDES) \
	$(GECKO_INCLUDES) $(GTK_CFLAGS) $(GUI_CFLAGS) $(GECKO_LDFLAGS) $(GTK_LIBS) $(GUI_LIBS) \
	$(CPPFLAGS) $(CXXFLAGS) $(FILES)
 
	cp $(TARGET) ~/.mozilla/plugins
 
clean: 
	rm $(TARGET)

附图:

gtk_sample.png

Related posts:

  1. 关于 Mozilla 的 Plugin 编译
  2. 目前的进展(Mozilla Plugin)
  3. Mozilla 的一个 hello world 的例子
  4. Creating a simple C++ component
  5. Get DOM CSS properties by using headless Mozilla

Tags: , ,



Reader's Comments

  1. nbjayme PHILIPPINES Linux Mozilla Firefox 3.5.1 | 2009-07-27 at 7.22 am

    thank you for the code.

    Reply to this comment

Leave a Comment