Get GTK widget X display?

Archives Forums/Linux Discussion/Get GTK widget X display?

JoshK(Posted 2013) [#1]
I'm trying to figure out how to retrieve the X display of a GTK widget so I can initialize an OpenGL viewport on it:
https://mail.gnome.org/archives/gtk-list/1998-December/msg00658.html

I am using Brucey's GTKMaxGUI module. Any ideas how to do this?


JoshK(Posted 2013) [#2]
This is what I am trying:
#include "/usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0"

Display* GetGTKWindowXDisplay(GdkWindow* win)
{
	return GDK_WINDOW_XDISPLAY(win);
}


Unfortunately, this just causes BlitzMax to freeze, which is what it normally seems to do on Linux when it hits an error when compiling C code.


dawlane(Posted 2013) [#3]
It's been a very long time since I did any real C/C++ programing and even less with gtk. And I sure that #include directive was only meant for header files, not binary includes.
Instead of trying to include the shared library, use extern to include the functions you want from libgtk-x11 and then link in the normal way.
Or include the header files from libgtk2-dev (/usr/include/gtk2-0/gtk). You may still need to link in the normal way.


skidracer(Posted 2013) [#4]
Josh, the 143B release of maxide should fix that crash and is available here:

http://sourceforge.net/projects/maxgui/files/?source=navbar


dawlane(Posted 2013) [#5]
@Skidracer: Looks like that fix works. Deliberately added a syntax error in fltk and rebuit the module. +1. What other things are in the pipe line?.


JoshK(Posted 2013) [#6]
The problem is that the "function" I want is a Macro. Made up of other macros. :| So I have to include the GTK header from an imported C++ file.

When I try to include the GTK header from C++, it can't find other files it needs because there is no way to define a header search directory. :(

I might be able to add a little helper function in Leadwerks that only gets compiled into the Linux x86 build.


Yasha(Posted 2013) [#7]
If GCC can't find the headers, have they actually been installed to the correct place?

I think it's also possible to use the GCC_EXEC_PREFIX environment variable to get GCC to search custom locations without needing to add an -I parameter:

http://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
http://www.cpp-home.com/forum/viewtopic.php?f=5&t=8843


skidracer(Posted 2013) [#8]
Josh, is there an XDisplay per window in gtk? I would have thought gdk_x11_get_default_xdisplay is the handle you would be wanting.


dawlane(Posted 2013) [#9]
@Yasha: I don't think it's possible to GCC_EXEC_PREFIX from the MaxIDE directly. May adding it to .profile or issuing it in a terminal then start MaxIDE from the command line or rebuilding bmk with alterations for searching.

@Skidracer: I think the problem he is having is getting the gtk/gdk header files to work from within a BlitzMax.
From what I can see with mine is that the usual #include <gtk/gtk.h> isn't working, but #include <gtk-2.0/gtk/gtk.h> will find gtk.h but fails when that header tried to include <gdk/gdk.h>.
My guess is that <gtk/gtk.h> is being parsed as /usr/include/gtk/gtk.h instead of /usr/include/gtk-2.0/gtk/gtk.h.
I think that pkg-config gtk+-2.0 has to be called, but I can't remember is that was just for the libraries and compiler flags.


JoshK(Posted 2013) [#10]
Thanks, skid. BTW, if I hit the "back" button on the side of my mouse the IDE quits. (New and old ones do this.) ;)

This is the function I want to call:
http://www.cs.rit.edu/usr/local/pub/wrc/graphics/doc/opengl/books/blue/glXMakeCurrent.html

The paramater I need is this:
drawable: Specifies a GLX drawable. Must be either an X window ID or a GLX pixmap ID.


I believe the "handle" field in the GTKGadget class is a GtkWidget object.

So I need to get the X window ID of a GtkWidget object.

If you look at this page, there are a couple of macros that will return an X window id from a GtkWindow object, but I have a GtkWidget object:
https://developer.gnome.org/gdk/unstable/gdk-X-Window-System-Interaction.html

This macro looks like it might be what I want, but it takes a GtkDrawable object, not a GtkWidget object:
https://developer.gnome.org/gdk/unstable/gdk-X-Window-System-Interaction.html#GDK-DRAWABLE-XID:CAPS

So I created a GTKMaxGUI canvas, then passed TGTKGadget(canvas).handle to this C function:
void* GetGTKWidgetXDisplay(GdkDrawable* widget)
{
    return (void*)(GDK_DRAWABLE_XID(widget));
}

The program prints this message and the function returns 0:
(Leadwerks.debug:26289): Gdk-WARNING **: /build/buildd/gtk+2.0-2.24.10/gdk/x11/gdkdrawable-x11.c:952 drawable is not a pixmap or window



JoshK(Posted 2013) [#11]
:D

I poked around in the GTKMaxGUI source a bit and found the way. No special C functions are needed:
Import MaxGui.Drivers

Strict 

Global GAME_WIDTH=320
Global GAME_HEIGHT=240

' create a centered window with client size GAME_WIDTH,GAME_HEIGHT

Local wx=(ClientWidth(Desktop())-GAME_WIDTH)/2
Local wy=(ClientHeight(Desktop())-GAME_HEIGHT)/2

Local window:TGadget=CreateWindow("My Canvas",wx,wy,GAME_WIDTH,GAME_HEIGHT,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS)

' create a canvas for our game
Local canvas:TGadget=CreateCanvas(0,0,320,240,window)

'Get the X window handle of the canvas.  The window must not be hidden for the drawable to be valid
Local drawable:Int = gdk_x11_drawable_get_xid(Byte Ptr(Int Ptr(TGTKGadget(canvas).handle + _OFFSET_GTK_WINDOW)[0]))	
Print drawable

CreateTimer 60

While WaitEvent()
	Select EventID()
		Case EVENT_TIMERTICK
			RedrawGadget canvas

		Case EVENT_GADGETPAINT
			SetGraphics CanvasGraphics(canvas)
			SetOrigin 160,120
			SetLineWidth 5
			Cls
			Local t=MilliSecs()
			DrawLine 0,0,120*Cos(t),120*Sin(t)
			DrawLine 0,0,80*Cos(t/60),80*Sin(t/60)
			Flip

		Case EVENT_MOUSEMOVE
			Print "MOVE!"

		Case EVENT_WINDOWCLOSE
			FreeGadget canvas
			End

		Case EVENT_APPTERMINATE
			End
	End Select
Wend



skidracer(Posted 2013) [#12]
Cool.


Brucey(Posted 2014) [#13]
Funnily enough, CanvasGraphics appears to do all that already...