Jump to content
  • Advertisement
Sign in to follow this  
jeff8j

OpenGL NPAPI OpenGL Linux

This topic is 2644 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to get opengl going in a firefox plugin my problem is I dont know how to get a context from a XID and I cant find any help any where I have tried looking at several projects source code like gnash but cant figure out how everything works its got way more than I need.

Can someone help me get opengl drawing or point me to some clean source or a tutorial or something thank you.

here is my handle event code where I get the XID


int16_t NPP_HandleEvent(NPP instance, void* e) {
InstanceData *instanceData = (InstanceData*)(instance->pdata);
XEvent *nativeEvent = (XEvent*)e;

if (nativeEvent->type != GraphicsExpose){
return 0;
}

printf("graphics expose event\n");

XGraphicsExposeEvent *expose = &nativeEvent->xgraphicsexpose;
instanceData->window.window = (void*) (expose->drawable);


//(XID) (instanceData->window.window);


printf("done\n");

return 1;
}

Share this post


Link to post
Share on other sites
Advertisement
I havent made anything work but here is my code im working with it all compiles fine but nothing shows up in the plugin area its all black


static NPNetscapeFuncs* sBrowserFuncs = NULL;

typedef struct InstanceData {
NPP npp;
NPWindow window;
} InstanceData;

static void
drawWindow(InstanceData* instanceData, GdkDrawable* gdkWindow)
{
NPWindow window = instanceData->window;
int x = window.x;
int y = window.y;
int width = window.width;
int height = window.height;

NPP npp = instanceData->npp;
if (!npp)
return;

const char* uaString = sBrowserFuncs->uagent(npp);
if (!uaString)
return;

GdkGC* gdkContext = gdk_gc_new(gdkWindow);

// draw a grey background for the plugin frame
GdkColor grey;
grey.red = grey.blue = grey.green = 32767;
gdk_gc_set_rgb_fg_color(gdkContext, &grey);
gdk_draw_rectangle(gdkWindow, gdkContext, TRUE, x, y, width, height);

// draw a 3-pixel-thick black frame around the plugin
GdkColor black;
black.red = black.green = black.blue = 0;
gdk_gc_set_rgb_fg_color(gdkContext, &black);
gdk_gc_set_line_attributes(gdkContext, 3, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
gdk_draw_rectangle(gdkWindow, gdkContext, FALSE, x + 1, y + 1,
width - 3, height - 3);

// paint the UA string
PangoContext* pangoContext = gdk_pango_context_get();
PangoLayout* pangoTextLayout = pango_layout_new(pangoContext);
pango_layout_set_width(pangoTextLayout, (width - 10) * PANGO_SCALE);
pango_layout_set_text(pangoTextLayout, uaString, -1);
gdk_draw_layout(gdkWindow, gdkContext, x + 5, y + 5, pangoTextLayout);
g_object_unref(pangoTextLayout);

g_object_unref(gdkContext);
}

NP_EXPORT(NPError)
NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs)
{
sBrowserFuncs = bFuncs;

// Check the size of the provided structure based on the offset of the
// last member we need.
if (pFuncs->size < (offsetof(NPPluginFuncs, setvalue) + sizeof(void*)))
return NPERR_INVALID_FUNCTABLE_ERROR;

pFuncs->newp = NPP_New;
pFuncs->destroy = NPP_Destroy;
pFuncs->setwindow = NPP_SetWindow;
pFuncs->newstream = NPP_NewStream;
pFuncs->destroystream = NPP_DestroyStream;
pFuncs->asfile = NPP_StreamAsFile;
pFuncs->writeready = NPP_WriteReady;
pFuncs->write = NPP_Write;
pFuncs->print = NPP_Print;
pFuncs->event = NPP_HandleEvent;
pFuncs->urlnotify = NPP_URLNotify;
pFuncs->getvalue = NPP_GetValue;
pFuncs->setvalue = NPP_SetValue;

return NPERR_NO_ERROR;
}

NP_EXPORT(char*)
NP_GetPluginVersion()
{
return PLUGIN_VERSION;
}

NP_EXPORT(const char*)NP_GetMIMEDescription() {
return (const char*)PLUGIN_MIME;
}

NP_EXPORT(NPError)
NP_GetValue(void* future, NPPVariable aVariable, void* aValue) {
switch (aVariable) {
case NPPVpluginNameString:
*((char**)aValue) = PLUGIN_NAME;
break;
case NPPVpluginDescriptionString:
*((char**)aValue) = PLUGIN_DESCRIPTION;
break;
default:
return NPERR_INVALID_PARAM;
break;
}
return NPERR_NO_ERROR;
}

NP_EXPORT(NPError)
NP_Shutdown()
{
return NPERR_NO_ERROR;
}

NPError
NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved) {
// Make sure we can render this plugin
NPBool browserSupportsWindowless = false;
sBrowserFuncs->getvalue(instance, NPNVSupportsWindowless, &browserSupportsWindowless);
if (!browserSupportsWindowless) {
printf("Windowless mode not supported by the browser\n");
return NPERR_GENERIC_ERROR;
}

sBrowserFuncs->setvalue(instance, NPPVpluginWindowBool, (void*)false);

// set up our our instance data
InstanceData* instanceData = (InstanceData*)malloc(sizeof(InstanceData));
if (!instanceData)
return NPERR_OUT_OF_MEMORY_ERROR;
memset(instanceData, 0, sizeof(InstanceData));
instanceData->npp = instance;
instance->pdata = instanceData;

return NPERR_NO_ERROR;
}

NPError
NPP_Destroy(NPP instance, NPSavedData** save) {
InstanceData* instanceData = (InstanceData*)(instance->pdata);
free(instanceData);
return NPERR_NO_ERROR;
}

NPError
NPP_SetWindow(NPP instance, NPWindow* window) {
InstanceData* instanceData = (InstanceData*)(instance->pdata);
instanceData->window = *window;
return NPERR_NO_ERROR;
}

NPError
NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype) {
return NPERR_GENERIC_ERROR;
}

NPError
NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) {
return NPERR_GENERIC_ERROR;
}

int32_t
NPP_WriteReady(NPP instance, NPStream* stream) {
return 0;
}

int32_t
NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer) {
return 0;
}

void
NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) {

}

void
NPP_Print(NPP instance, NPPrint* platformPrint) {

}

inline GdkNativeWindow getGdkWindow(void *in){
// This is one of the ugliest hacks known to man; it was neccesary to make 64 bit work.
// Don't change it without testing on 32 and 64, and don't ask -- you don't want to know
return (char*)in - (char*)0;
}



static int attrListSgl[] = {
GLX_RGBA, GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None
};

static int attrListDbl[] = {
GLX_RGBA, GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None
};

typedef struct {
Display *dpy;
int screen;
Window win;
GLXContext ctx;
XSetWindowAttributes attr;
Bool fs;
Bool doubleBuffered;
XF86VidModeModeInfo deskMode;
int x, y;
unsigned int width, height;
unsigned int depth;
} GLWindow;

GLWindow GLWin;


static gboolean update(gpointer data) {
printf("Update\n");
//ins * o = (ins*)data;
//coSwitchTo(o->h.coaw);
//glXSwapBuffers(o->dpy, o->w);
glXSwapBuffers(GLWin.dpy, GLWin.win);
//return !o->h.awdone;
return false;
}


static gboolean event(GtkWidget * wid, GdkEvent * ev, gpointer data) {
//extern unsigned mapkeycode(unsigned);
//ins * o = (ins*)data;
//aw * w = &o->h.w;
int ret = TRUE;
/*
switch (ev->type) {
case GDK_KEY_PRESS: {
GdkEventKey * kev = (GdkEventKey*)ev;
got(w, AW_EVENT_DOWN, mapkeycode(kev->hardware_keycode), 0);
break;
}
case GDK_KEY_RELEASE: {
GdkEventKey * kev = (GdkEventKey*)ev;
got(w, AW_EVENT_UP, mapkeycode(kev->hardware_keycode), 0);
break;
}
case GDK_BUTTON_PRESS: {
GdkEventButton * bev = (GdkEventButton*)ev;
gtk_widget_grab_focus(o->plug);
got(w, AW_EVENT_DOWN, mapbutton(bev->button), 0);
break;
}
case GDK_BUTTON_RELEASE: {
GdkEventButton * bev = (GdkEventButton*)ev;
got(w, AW_EVENT_UP, mapbutton(bev->button), 0);
break;
}
case GDK_MOTION_NOTIFY: {
GdkEventMotion * mev = (GdkEventMotion*)ev;
got(w, AW_EVENT_MOTION, mev->x, mev->y);
break;
}
default: ret = FALSE; break;
}
*/
return ret;
}

static XVisualInfo * chooseVisual(Display * dpy, int screen) {
int att[64];
int * p = att;
*p++ = GLX_RGBA;
*p++ = GLX_DOUBLEBUFFER;
*p++ = GLX_RED_SIZE; *p++ = 1;
*p++ = GLX_GREEN_SIZE; *p++ = 1;
*p++ = GLX_BLUE_SIZE; *p++ = 1;
*p++ = GLX_DEPTH_SIZE; *p++ = 1;
*p++ = None;
return glXChooseVisual(dpy, screen, att);
}


int16_t NPP_HandleEvent(NPP instance, void* event) {
InstanceData *instanceData = (InstanceData*)(instance->pdata);
XEvent *nativeEvent = (XEvent*)event;

if (nativeEvent->type != GraphicsExpose)
return 0;

XGraphicsExposeEvent *expose = &nativeEvent->xgraphicsexpose;
if (expose != NULL){
printf("good expose\n");
} else {
printf("bad expose\n");
}



Bool doubleBuffered;
int glxMajor, glxMinor, vmMajor, vmMinor;
//GLWin.win = (XID)instanceData->window.window;
GLWin.win = expose->drawable;
GLWin.dpy = expose->display;
GLWin.screen = DefaultScreen(GLWin.dpy);




GtkWidget * plug = gtk_plug_new((GdkNativeWindow)(GLWin.win));
GTK_WIDGET_SET_FLAGS(GTK_WIDGET(plug), GTK_CAN_FOCUS);
gtk_widget_add_events(plug, 0 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_POINTER_MOTION_MASK );


//g_signal_connect(G_OBJECT(plug), "event", G_CALLBACK(event), o);
//g_signal_connect(G_OBJECT(plug), "event", G_CALLBACK(event), NULL);
gtk_widget_show_all(plug);
gtk_widget_grab_focus(plug);
//o->dpy = info->display;
//o->plug = plug;
GLWin.win = gtk_plug_get_id(GTK_PLUG(plug));
//Window w = gtk_plug_get_id(GTK_PLUG(plug));
//GLWin.win = gtk_plug_get_id( plug );
//guint to = g_timeout_add(10, update, o);
guint to = g_timeout_add(100, update, NULL);
XVisualInfo* vinfo = chooseVisual(GLWin.dpy, 0);
GLWin.ctx = glXCreateContext(GLWin.dpy, vinfo, 0, True);
XFree(vinfo);
glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
//glXMakeCurrent(GLWin.dpy, w, GLWin.ctx);



if (glXIsDirect(GLWin.dpy, GLWin.ctx)){
printf("DRI enabled\n");
} else {
printf("no DRI available\n");
}





/*
XF86VidModeQueryVersion(GLWin.dpy, &vmMajor, &vmMinor);
printf("XF86 VideoMode extension version %d.%d\n", vmMajor, vmMinor);
// get an appropriate visual
XVisualInfo* vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
if (vi == NULL){
vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
doubleBuffered = False;
printf("singlebuffered rendering will be used, no doublebuffering available\n");
} else {
doubleBuffered = True;
printf("doublebuffered rendering available\n");
}
glXQueryVersion(GLWin.dpy, &glxMajor, &glxMinor);
printf("GLX-Version %d.%d\n", glxMajor, glxMinor);
// create a GLX context
GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE);
// create a color map
//cmap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone);
//winAttr.colormap = cmap;
//winAttr.border_pixel = 0;


glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
*/




glShadeModel(GL_SMOOTH);
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
/* we use resizeGL once to set up our initial perspective */
//if (height == 0) /* Prevent A Divide By Zero If The Window Is Too Small */
// height = 1;
glViewport(0, 0, 200, 20); /* Reset The Current Viewport And Perspective Transformation */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)200 / (GLfloat)20, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);


glFlush();


//if (doubleBuffered){
printf("Swap\n");
glXSwapBuffers(GLWin.dpy, GLWin.win);
//}

return 1;












instanceData->window.window = (void*)(expose->drawable);

//GdkNativeWindow nativeWinId = (XID)(instanceData->window.window);
GdkNativeWindow nativeWinId = getGdkWindow( instanceData->window.window );
if (nativeWinId != NULL){
printf("good nativeWinId\n");
//printf( nativeWinId );
//printf("\n");
} else {
printf("bad nativeWinId\n");
}

//XSync (expose->display,False);

GdkDrawable* gdkWindow = GDK_DRAWABLE(gdk_window_foreign_new(nativeWinId));
if (gdkWindow != NULL){
printf("good gdkwindow\n");
} else {
printf("bad gdkwindow\n");
}
drawWindow(instanceData, gdkWindow);
g_object_unref(gdkWindow);

return 1;
}

void
NPP_URLNotify(NPP instance, const char* URL, NPReason reason, void* notifyData) {

}

NPError
NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
return NPERR_GENERIC_ERROR;
}

NPError
NPP_SetValue(NPP instance, NPNVariable variable, void *value) {
return NPERR_GENERIC_ERROR;
}


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!