[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: NSOpenGLView : Calling openGLContext causes exception
From: |
Omniscient |
Subject: |
Re: NSOpenGLView : Calling openGLContext causes exception |
Date: |
Thu, 2 Apr 2009 21:47:19 -0700 (PDT) |
User-agent: |
G2/1.0 |
On Apr 2, 7:24 am, oren <obj...@gmail.com> wrote:
> 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.
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;
+ 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 ?
/*