Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

NSOpenGLView : Calling openGLContext causes exception

7 views
Skip to first unread message

oren

unread,
Apr 1, 2009, 8:24:47 PM4/1/09
to
2009-04-01 23:36:59.184 MyGL[25376] XGGLContext.m:76 Assertion failed
in XGXSubWindow(instance), method initWithView:visualinfo:. request
of an X window attachment on a view that is not on a NSWindow

this wrong behavior happenned because the gl view doesn't move to any
window yet.
may be it should creates the xwindow right away and once the the view
of that context
did move to a window then tell its glcontext to reparent its window
onto a new one.


Omniscient

unread,
Apr 2, 2009, 1:42:32 AM4/2/09
to
When I cover part of glview with something it will turn black.
Is there a way to tell a glview to redraw itself whenever xexpose
event happen?
Or is there a way to cache the drawable some how?
What's better between caching drawable of a glview and then show it on
expose
or just let the glcontext convert xexpose event to glview
setNeedsDisplayInRect: ?

Thakns

Omniscient

unread,
Apr 2, 2009, 4:24:05 AM4/2/09
to


welll this is my current work-around, pretty hackish. just for a
further description of the problem.
(this didn't solve the context exception problem)

Index: Source/x11/XGGLContext.m
===================================================================
--- Source/x11/XGGLContext.m (revision 28164)
+++ Source/x11/XGGLContext.m (working copy)
@@ -129,6 +129,9 @@
xVisualInfo->depth, InputOutput,
xVisualInfo->visual,
mask, &window_attributes);

+ Atom atom_glview = XInternAtom(win_info->display,
"_GNUSTEP_OPENGLVIEW_POINTER", False);
+ XChangeProperty(win_info->display, xwindowid, atom_glview,
XA_CARDINAL, 32, PropModeReplace, &view, 1);
+
XMapWindow(win_info->display, xwindowid);

attached = view;
Index: Source/x11/XGServerEvent.m
===================================================================
--- Source/x11/XGServerEvent.m (revision 28164)
+++ Source/x11/XGServerEvent.m (working copy)
@@ -988,6 +988,26 @@
{
generic.cachedWindow
= [XGServer _windowForXWindow:xEvent.xexpose.window];
+ {
+ gswindow_device_t *device = [XGServer
_windowForXWindow:xEvent.xexpose.window];
+ if (device == NULL)
+ {
+ Atom actual_type;
+ int actual_format, num_items, bytes_left;
+ int *pointer_value = NULL;
+ NSView *aView;
+
+ Atom atom_glview = XInternAtom(dpy,
"_GNUSTEP_OPENGLVIEW_POINTER", True);
+ if (atom_glview && XGetWindowProperty(dpy,
xEvent.xexpose.window, atom_glview, 0, 1, False, XA_CARDINAL,
+ &actual_type, &actual_format, &num_items, &bytes_left,
+ (unsigned char **) &pointer_value) == Success)
+ {
+ aView = *pointer_value;
+ XFree(pointer_value);
+ [aView setNeedsDisplay:YES];
+ }
+ }
+ }
}
// sub-window ?
/*

Omniscient

unread,
Apr 3, 2009, 12:47:19 AM4/3/09
to

This is my second attempt, really a horrible kludge but fix both
issues
(the exposing and deferred/missing window glcontext), by breaking
encapsulation
here and there, passing pointer value over x and didn't get test well.
And I have no plan to clean them up as long as it did their jobs in my
tree.

Thanks

Index: Source/x11/XGGLContext.m
===================================================================
--- Source/x11/XGGLContext.m (revision 28164)
+++ Source/x11/XGGLContext.m (working copy)

@@ -47,6 +47,7 @@
@public
Window xwindowid;
NSView *attached;
+ BOOL hasParent;
}

+ subwindowOnView:(NSView *)view visualinfo:(XVisualInfo *)
xVisualInfo;
@@ -73,69 +74,136 @@
return nil;

window = [view window];
- NSAssert(window, @"request of an X window attachment on a view that
is not on a NSWindow");

- if ([view isRotatedOrScaledFromBase])
- {
- [NSException raise: NSInvalidArgumentException
- format: @"Cannot attach an Xwindow to a view that
is rotated or scaled"];
- }
-
- server = (XGServer *)GSServerForWindow(window);
- NSAssert(server != nil, NSInternalInconsistencyException);
+ if (window != nil)
+ {
+ server = (XGServer *)GSServerForWindow(window);
+ NSAssert(server != nil, NSInternalInconsistencyException);

- NSAssert([server isKindOfClass: [XGServer class]],
- NSInternalInconsistencyException);
+ NSAssert([server isKindOfClass: [XGServer class]],
+ NSInternalInconsistencyException);

- win_info = [XGServer _windowWithTag: [window windowNumber]];
- NSAssert(win_info, NSInternalInconsistencyException);

- if ([server handlesWindowDecorations] == YES)
- {
- /* The window manager handles window decorations, so the
- * the parent X window is equal to the content view and
- * we must therefore use content view coordinates.
- */
- rect = [view convertRect: [view bounds]
- toView: [window contentView]];
- }
- else
- {
- /* The GUI library handles window decorations, so the
- * the parent X window is equal to the NSWindow frame
- * and we can use window base coordinates.
- */
- rect = [view convertRect: [view bounds] toView: nil];
- }
+ win_info = [XGServer _windowWithTag: [window windowNumber]];
+ NSAssert(win_info, NSInternalInconsistencyException);

- x = NSMinX(rect);
- y = NSHeight(win_info->xframe) - NSMaxY(rect);
- width = NSWidth(rect);
- height = NSHeight(rect);
+ if ([server handlesWindowDecorations] == YES)
+ {
+ /* The window manager handles window decorations, so the
+ * the parent X window is equal to the content view and
+ * we must therefore use content view coordinates.
+ */
+ rect = [view convertRect: [view bounds]
+ toView: [window contentView]];
+ }
+ else
+ {
+ /* The GUI library handles window decorations, so the
+ * the parent X window is equal to the NSWindow frame
+ * and we can use window base coordinates.
+ */
+ rect = [view convertRect: [view bounds] toView: nil];
+ }

- window_attributes.border_pixel = 255;
- window_attributes.background_pixel = 0;
- window_attributes.colormap = XCreateColormap(win_info->display,
- win_info->ident,
- xVisualInfo->visual,
AllocNone);
- window_attributes.event_mask = StructureNotifyMask
- | VisibilityChangeMask
- | ExposureMask;
+ x = NSMinX(rect);
+ y = NSHeight(win_info->xframe) - NSMaxY(rect);
+ width = NSWidth(rect);
+ height = NSHeight(rect);

- mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+ window_attributes.border_pixel = 255;
+ window_attributes.background_pixel = 0;
+ window_attributes.colormap = XCreateColormap(win_info->display,
+ win_info->ident,
+ xVisualInfo->visual, AllocNone);
+ window_attributes.event_mask = StructureNotifyMask
+ | VisibilityChangeMask
+ | ExposureMask;

- xwindowid = XCreateWindow(win_info->display, win_info->ident,
- x, y, width, height, 0,
- xVisualInfo->depth, InputOutput,
xVisualInfo->visual,
- mask, &window_attributes);
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;

- XMapWindow(win_info->display, xwindowid);
+ xwindowid = XCreateWindow(win_info->display, win_info->ident,
+ x, y, width, height, 0,
+ xVisualInfo->depth, InputOutput, xVisualInfo->visual,
+ mask, &window_attributes);

+ Atom atom_glview = XInternAtom(win_info->display,
"_GNUSTEP_OPENGLVIEW_POINTER", False);
+ XChangeProperty(win_info->display, xwindowid, atom_glview,
XA_CARDINAL, 32, PropModeReplace, &view, 1);
+ XMapWindow(win_info->display, xwindowid);

+ hasParent = YES;
+ }
+ else /* prepare xwindow for deferred device */
+ {
+ server = GSCurrentServer();
+
+ NSAssert(server != nil, NSInternalInconsistencyException);
+
+ NSAssert([server isKindOfClass: [XGServer class]],
+ NSInternalInconsistencyException);
+
+
+ struct XGServerStruct
+ {
+ @defs(XGServer);
+ } *ss = server;
+
+ NSRect frame = [view frame];
+
+ window_attributes.border_pixel = 255;
+ window_attributes.background_pixel = 0;
+ window_attributes.colormap = XCreateColormap(ss->dpy,
+ RootWindow(ss->dpy, ss->defScreen),
+ xVisualInfo->visual, AllocNone);
+ window_attributes.event_mask = StructureNotifyMask
+ | VisibilityChangeMask
+ | ExposureMask;
+
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ xwindowid = XCreateWindow(ss->dpy, RootWindow(ss->dpy, ss-
>defScreen),
+ 0, 0, NSWidth(frame), NSHeight(frame), 0,
+ xVisualInfo->depth, InputOutput, xVisualInfo->visual,
+ mask, &window_attributes);
+
+ Atom atom_glview = XInternAtom(ss->dpy,
"_GNUSTEP_OPENGLVIEW_POINTER", False);
+ XChangeProperty(ss->dpy, xwindowid, atom_glview, XA_CARDINAL, 32,
PropModeReplace, &view, 1);
+ }
+
attached = view;

return self;
}

+- (void) tryReparent
+{
+ NSWindow *window = [attached window];
+ XGServer *server;
+
+ if (window == nil) return;
+
+ server = (XGServer *)GSServerForWindow(window);
+
+ gswindow_device_t *win_info = [XGServer _windowWithTag: [window
windowNumber]];
+
+ if (win_info == NULL) return;
+
+ NSRect rect;
+
+ if ([server handlesWindowDecorations] == YES)
+ {
+ rect = [attached convertRect: [attached bounds]
+ toView: [window contentView]];
+ }
+ else
+ {
+ rect = [attached convertRect: [attached bounds] toView: nil];
+ }
+ Display *dpy = [server xDisplay];
+
+ XReparentWindow(dpy, xwindowid, win_info->ident, NSMinX(rect),
NSMinY(rect));
+ XMapWindow(dpy, xwindowid);
+ hasParent = YES;
+}
+
- (void) map
{
MAKE_DISPLAY(dpy);
@@ -432,6 +500,9 @@
{
MAKE_DISPLAY(dpy);

+ if (xSubWindow->hasParent == NO)
+ [xSubWindow tryReparent];
+
if (xSubWindow == nil)
[NSException raise: NSGenericException
format: @"GL Context is not bind, cannot be made current"];


Index: Source/x11/XGServerEvent.m
===================================================================
--- Source/x11/XGServerEvent.m (revision 28164)
+++ Source/x11/XGServerEvent.m (working copy)
@@ -988,6 +988,26 @@
{
generic.cachedWindow
= [XGServer _windowForXWindow:xEvent.xexpose.window];
+ {

+ gswindow_device_t *device = generic.cachedWindow;

Fred Kiefer

unread,
Apr 3, 2009, 4:02:16 AM4/3/09
to Omniscient, discuss...@gnu.org
This really is horrible code, that cannot be commited in its current
form. I am willing to support this feature, but you or somebody else
will have to clean up the code first. You surely wouldn't like the whole
rest of GNUstep being written that way :-)
Passing a pointer through an X property is surely asking for trouble,
there has to be another solution.

Cheers
Fred

PS: Could you attach the patch the next time, inlining the code makes it
harder to apply a patch.

Omniscient

unread,
Apr 3, 2009, 4:28:48 AM4/3/09
to
On Apr 3, 3:02 pm, Fred Kiefer <fredkie...@gmx.de> wrote:
> This really is horrible code, that cannot be commited in its current
> form. I am willing to support this feature, but you or somebody else

Ha ha, yes, I hope someone will clean that up too, but i am too busy
already
with my projects (3VA and 3Σ) that can't get away w/o getting those 2
things fixed.

> will have to clean up the code first. You surely wouldn't like the whole
> rest of GNUstep being written that way :-)
> Passing a pointer through an X property is surely asking for trouble,
> there has to be another solution.

The cleaner solution should be creating a gs_device_t for a child
window.
then put it in map table which I am not very familiar with (I didn't
touch
back for a while)

>
> Cheers
> Fred
>
> PS: Could you attach the patch the next time, inlining the code makes it
> harder to apply a patch.

Oh sorry I didn't think about it, I am posting this over
groups.google.com and
there's no attach button. I'll try to post with gmail next time Thanks.

0 new messages