discuss-gnustep
[Top][All Lists]
Advanced

[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 ?
          /*


reply via email to

[Prev in Thread] Current Thread [Next in Thread]