MaxGUI Segmentation fault in CreateCanvas

BlitzMax Forums/MaxGUI Module/MaxGUI Segmentation fault in CreateCanvas

Scaremonger(Posted 2012) [#1]
Take this piece of code:
Strict
Import MaxGui.Drivers

Local window:TGadget = CreateWindow( "", 100, 100, 225, 400, Null, WINDOW_TITLEBAR | WINDOW_CENTER | WINDOW_CLIENTCOORDS | WINDOW_HIDDEN )
Local canvas:TGadget = CreateCanvas(1, 1, ClientWidth(window), ClientHeight(window), window)

It runs under Windows but not on Ubuntu.

The Segmentation fault occurs in file fltkgui.bmx, Type TFLCanvas, Method AttachGraphics() in the line that reads:

Method AttachGraphics:TGraphics( flags )
 canvasflags=flags
 ?MacOS
 canvas=brl.Graphics.AttachGraphics( NSContentView(flCanvasWindow(WidgetHandle())),flags )
 ?Not MacOS
 '### CODE BREAKS ON THIS NEXT LINE ###
 canvas=brl.Graphics.AttachGraphics( flCanvasWindow(WidgetHandle()),flags )
 ?
 End Method

Looking back at the source code, the problem is caused by the flag WINDOW_HIDDEN.

Any suggestions on how to resolve this, or should I report it as a Bug?

BLITZMAX 1.45
UBUNTU 11.10

EDIT: Have also tried BLITZMAX 1.48 with same results

Last edited 2012


shinkiro1(Posted 2012) [#2]
What does the code in the 2nd codebox do?
(If you want to create a normal canvas you wouldn't need the 2nd piece of code)


Scaremonger(Posted 2012) [#3]
@shinkiro1: The second box was a bit mis-leading so I edited it to show the whole MaxGUI function that is failing.


jsp(Posted 2012) [#4]
I don't have an Ubuntu installation at the moment, but it sounds like a bug.

To work around it, you could try to create a window with zero width and hight.
After creation you could use GadgetHide to hide the window and then set the size you need.
Only after doing that put other gadgets on top or they will may get resized as well.
Then use ShowGadget to display the window as normal.


Scaremonger(Posted 2012) [#5]
Cheers JSP, The easiest way to work around it is:
Strict
Import MaxGui.Drivers

Local window:TGadget = CreateWindow( "", 100, 100, 225, 400, Null, WINDOW_TITLEBAR | WINDOW_CENTER | WINDOW_CLIENTCOORDS )
Local canvas:TGadget = CreateCanvas(1, 1, ClientWidth(window), ClientHeight(window), window)
hidegadget( window )


It is important to remember that Hidegadget before creating the Canvas fails too; you have to do it afterwards.


jsp(Posted 2012) [#6]
Thought about that one, but supposed you would see a flicker before the window is hidden.

Good to have it working, may consider to report that bug...


Scaremonger(Posted 2012) [#7]
I think this bug goes deeper than this.

After fixing the example above I still couldn't get my app to work so I produced another cut down test program:
Strict
Import MaxGui.Drivers

Local window:TGadget = CreateWindow( "", 100, 100, 225, 200, Null, WINDOW_TITLEBAR | WINDOW_CENTER | WINDOW_CLIENTCOORDS )
Local canvas:TGadget = CreateCanvas(1, 1, ClientWidth(window), ClientHeight(window), window)

'HideGadget( window)
'ShowGadget( window)
Repeat
	WaitEvent()
	Select EventID()
		Case EVENT_WINDOWCLOSE
			End
		Case EVENT_GADGETPAINT
	  		SetGraphics CanvasGraphics (canvas)
    			DrawRect  20,20,50,80
        	Flip
	End Select
Forever
End

This runs fine, but now uncomment out the HIDEGADGET() and SHOWGADGET() and the application doesn't show anything, but when you close it the following message appears in the output:
X Error of failed request:  BadDrawable (invalid Pixmap or Window parameter)
  Major opcode of failed request:  14 (X_GetGeometry)
  Resource id in failed request:  0x2e00007
  Serial number of failed request:  110
  Current serial number in output stream:  110

Definitely a bug in the HIDE/SHOW code... :(


skidracer(Posted 2012) [#8]
Hmmm, FLTK can obviously not handle hidden GL contexts. I'm tempted to suggest managing all Canvas gadgets inside Panel containers which manage destroying and creating them when visible.


Scaremonger(Posted 2012) [#9]
I don't think it's just hidden contexts.

My app needs two windows, the second opens depending on the action in the first, so I've been trying to find a way around it but found the error again without any hidden context. For example:
Strict
Import MaxGui.Drivers
'DebugStop

Local window:TGadget 
Local canvas:TGadget
window = CreateWindow( "FIRST", 100, 100, 225, 400, Null, WINDOW_TITLEBAR | WINDOW_CENTER | WINDOW_CLIENTCOORDS )
canvas = CreateCanvas(0, 0, ClientWidth(window), ClientHeight(window), window)

FreeGadget( canvas )
FreeGadget( window )

window = CreateWindow( "SECOND", 100, 100, 225, 400, Null, WINDOW_TITLEBAR | WINDOW_CENTER | WINDOW_CLIENTCOORDS )
canvas = CreateCanvas(0, 0, ClientWidth(window), ClientHeight(window), window)

Repeat
	WaitEvent()
	Select EventID()
		Case EVENT_APPTERMINATE, EVENT_WINDOWCLOSE
			End
	End Select
forever

The odd thing about this is that running it gives:
Executing:untitled1.debug
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  4 (X_DestroyWindow)
  Resource id in failed request:  0x3a00007
  Serial number of failed request:  104
  Current serial number in output stream:  104

But stepping through it until after the second canvas is created, and then continuing execution bypasses the error.

Very bizarre!


Takis76(Posted 2012) [#10]
You are free the gadgets and might the window and canvas variables need to be re-initialized.

Use Global instead of local.

When I want 2 windows I have 2 different gadgets , I never free some gadget , might the variable is erased. But your code above worked to me.

Last edited 2012


Scaremonger(Posted 2012) [#11]
Using Global instead of local doesn't make any difference.

Did you try to code on Ubuntu or Windows?