inter process NSView sharing

  • Hi

    I have 2 applications, one is written in java, the other in C. For reasons I
    wont go into to I need to have the C application perform hardware
    accelerated opengl rendering to a window created by the Java application.

    This is currently working on Windows. On this platform the java application
    sends the hwnd of the java canvas to the C application via a bridge. The C
    application then creates an opengl rendering context using this hwnd and all
    is fine.

    Now, on OSX the java app gets a NSView/cocoaviewref. Is there some member of
    NSView similar to the HWND on windows that I can pass to my C process? The C
    process can then create a hardware accelerated opengl rendering context from
    this 'handle' and render to the java apps NSView.

    I've looked at using Distributed Objects, however the C application would
    need quite a bit of rework to make it fit into the Cocoa application
    framework, so this is not an option. So, can a non cocoa application
    communicate with a distributed object ?

    If distributed objects are not the way to go, I presume there must be
    another way to do it as I've seen reference to NSWindowSharingReadWrite in
    the apple dev docs. If I use the setSharingType approach, what does my C
    application need to be able to create a rendering context on the java
    applications shared window. Perhaps there is some way to access this window
    using the OSX window server API ?

    many thanks

    Jonathan
  • On Fri, May 23, 2008 at 9:59 AM, Jonathan Cochrane
    <jonathancochrane...> wrote:
    > Now, on OSX the java app gets a NSView/cocoaviewref. Is there some member of
    > NSView similar to the HWND on windows that I can pass to my C process? The C
    > process can then create a hardware accelerated opengl rendering context from
    > this 'handle' and render to the java apps NSView.

    So you have taken a pointer that points to your Cocoa app's virtual
    memory and passed it to a different process?  Do you really expect
    this to work?

    A process is not allowed to draw in another process's window on OS X.
    You cannot do what you want to do the same way you have on Windows.
    You must refactor your application to compensate for the enhanced
    separation between processes on OS X.

    --Kyle Sluder
  • apologies if ive been misunderstood, but no, i havent taken a pointer from
    the java app and passed it to  the c app, i know that wont work.
    what i was asking if there something similar to the MS Windows HWND, or a
    window id, i could pass between processes, not a pointer

    ive just had a look at 'son of a grab' source and it seems there is the
    concept of a CGWindowID, maybe this is what i need ?

    below is an excerpt from the NSWindow Class Reference:

    These constants and data type represent the access levels other processes
    can have to a window's content.

    typedef enum {
      NSWindowSharingNone
    <http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Cla
    sses/NSWindow_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSWindow
    SharingNone
    >
    = 0,

      NSWindowSharingReadOnly
    <http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Cla
    sses/NSWindow_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSWindow
    SharingReadOnly
    >
    = 1,
      NSWindowSharingReadWrite
    <http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Cla
    sses/NSWindow_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSWindow
    SharingReadWrite
    >
    = 2

    };
    typedef NSUInteger NSWindowSharingType;

    NSWindowSharingReadWrite

    The window's contents can be read and modified by another process.

    Available in Mac OS X v10.5 and later.

    Declared in NSWindow.h

    If a process is not allowed to draw in another process's window on OS X,
    have i misunderstood the concept of NSWindowSharingType ?

    thanks again
    Jonathan- Show quoted text -

    On Fri, May 23, 2008 at 3:48 PM, Kyle Sluder <
    kyle.sluder+<cocoa-dev...> <kyle.sluder%<2Bcocoa-dev...>> wrote:

    > On Fri, May 23, 2008 at 9:59 AM, Jonathan Cochrane
    > <jonathancochrane...> wrote:
    >> Now, on OSX the java app gets a NSView/cocoaviewref. Is there some member
    > of
    >> NSView similar to the HWND on windows that I can pass to my C process?
    > The C
    >> process can then create a hardware accelerated opengl rendering context
    > from
    >> this 'handle' and render to the java apps NSView.
    >
    > So you have taken a pointer that points to your Cocoa app's virtual
    > memory and passed it to a different process?  Do you really expect
    > this to work?
    >
    > A process is not allowed to draw in another process's window on OS X.
    > You cannot do what you want to do the same way you have on Windows.
    > You must refactor your application to compensate for the enhanced
    > separation between processes on OS X.
    >
    > --Kyle Sluder
    >
  • On Fri, May 23, 2008 at 11:14 AM, Jonathan Cochrane
    <jonathancochrane...> wrote:
    > apologies if ive been misunderstood, but no, i havent taken a pointer from
    > the java app and passed it to  the c app, i know that wont work.

    Ok, good.  :)

    > what i was asking if there something similar to the MS Windows HWND, or a
    > window id, i could pass between processes, not a pointer

    Yep, Core Graphics has a window list that is one step lower than the
    abstraction NSWindow provides.

    > below is an excerpt from the NSWindow Class Reference:
    >
    > These constants and data type represent the access levels other processes
    > can have to a window's content.

    This (-[NSWindow sharingType]) is new in Leopard, which is why I
    didn't know about it.  I retract what I've said, though this question
    has come up in the recent past and people have made the same argument.

    --Kyle Sluder
  • On May 23, 2008, at 10:14 AM, Jonathan Cochrane wrote:

    > ive just had a look at 'son of a grab' source and it seems there is
    > the
    > concept of a CGWindowID, maybe this is what i need ?
    >
    > below is an excerpt from the NSWindow Class Reference:
    >
    > These constants and data type represent the access levels other
    > processes
    > can have to a window's content.
    >
    > typedef enum {
    > NSWindowSharingNone
    > <http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Cla
    sses/NSWindow_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSWindow
    SharingNone
    > >
    > >
    > >
    > = 2
    >
    > };
    > typedef NSUInteger NSWindowSharingType;
    >
    > NSWindowSharingReadWrite
    >
    > The window's contents can be read and modified by another process.
    >
    > Available in Mac OS X v10.5 and later.
    >
    > Declared in NSWindow.h
    >
    >
    > If a process is not allowed to draw in another process's window on
    > OS X,
    > have i misunderstood the concept of NSWindowSharingType ?

    Those declarations are indeed intriguing and tantalizing.  However, I
    don't know of any supported way to make use of them the way you want.
    Maybe it's planned for the future.  There's some additional stuff like
    that in /System/Library/Frameworks/ApplicationServices.framework/
    Frameworks/CoreGraphics.framework/Headers/CGWindow.h.  In particular,
    CGWindowSharingType seems like the Core Graphics equivalent of that
    Cocoa enum.

    A CGWindowID is documented there as being valid across the user
    session.  However, I don't know of any way to create a Carbon or Cocoa
    window from a CGWindowID.  The HIToolbox Release Notes for Mac OS X
    10.5 includes this, though:
    > The HIWindowGetCGWindowID API has been added to allow access to the
    > window server's global window identifier for a WindowRef. This
    > number is not usable with any other Carbon APIs, but may be passed
    > to other APIs that do take window numbers, such as OpenGL.
    >

    Oooh, that's quite close!  Unfortunately, I can't see where OpenGL
    could take a window number.

    Now, I am familiar with a completely different approach to this.
    Apple provides a special library for implementing X11 and allowing
    direct GL rendering by an X11 client into windows owned by the X11
    server, provided they're both running on the same machine.  That
    library is /usr/lib/libXplugin.dylib. It's only documentation is its
    header file /usr/lib/Xplugin.h.  It also provides windows which
    require a lot more manual handling than anything provided by Carbon,
    Cocoa, or Java.

    Truthfully, I recommend you avoid this whole hassle until Apple
    provides complete support for what you're trying to do.  Instead, I
    suggest that you refactor your app to avoid the need for one process
    to draw into a window created by another.  Can you host your C code
    inside your Java program?  Or, replace what is currently a Java front-
    end (I'm guessing) with a Cocoa front-end, and then have your C code
    be that program's back-end?

    Good luck,
    Ken