previous next

Chapter 12: Sites (Windowing)

RealSystem consolidates windowing functions in the client core and provides these functions to rendering plug-ins as a platform-independent service. This means that rendering plug-ins do not need to implement window subclassing. Instead, the client core supplies a "site" and the rendering plug-in registers as a "site user." The rendering plug-in can then send data to the client core without providing platform-specific commands for displaying the data.

The RealSystem sites feature also supports "Wall of TVs," which allows a renderer to display data in more than one site simultaneously. In this case the renderer simply sends rendered data to a special default object instantiated by the client. That object then handles displaying the data in the multiple sites without placing any additional burden on the renderer.

Definitions

Site
An object that receives rendered data for display.

Site User
The object, typically the renderer, that "uses" a site by sending it display data.

Site User Supplier
An object, either the renderer or the "client core, that creates and destroys site user objects.

MISUS Object
The Multi-Instance Site User Supplier object, a default object instantiated by the client. When a renderer supports the "Wall of TVs" feature, it sends rendered data to this object as if it were the actual site. This object then passes the data to one or more sites.

Windowed Renderer
A renderer that writes data to an operating system-specific site window through RealSystem. It can pass operating system-specific commands to the site.

Windowless Renderer
A renderer that uses RealSystem to write operating system-generic data to a site. The site could be an operating system window or a "windowless" environment such as a browser. The renderer does not have specific knowledge of the display environment and does not pass operating system-specific commands to the site.

Interfaces

To use RealSystem sites, a rendering plug-in implements the following:

The RealSystem top-level client implements this interface:

The RealSystem client core implements these interfaces:

The client core implements these interfaces for site objects:

Coding a Rendering Plug-in for Sites

During rendering plug-in initialization, RealSystem queries the plug-in for its display type. If the rendering plug-in returns RMA_DISPLAY_WINDOW to indicate that it is a display renderer, the system queries for the plug-in's support of the site interfaces. The plug-in's response to these queries determines whether it supports a single site (one instance of rendered data) or multiple sites (one or more instances of rendered data).

Supporting a Single Site

To support a single site, the rendering plug-in implements IRMASiteUser but not IRMASiteUserSupplier. When the client calls IRMASiteUser::NeedsWindowedSites, the renderer responds with TRUE to render in an operating system-specific window (Windows or UNIX) through IRMASite and IRMASiteWindowed. It responds with FALSE to render operating system-generically through IRMASite and IRMASiteWindowless. The following figure illustrates the relationships between objects and main windowing interfaces in an operating system-generic single site.

Single, Operating System-generic Site

Supporting Multiple Sites

RealNetworks recommends that a rendering plug-in supports the multisite feature ("Wall of TVs"), which lets the plug-in render data to more than one site. To do this, the plug-in can implement IRMASiteUser and use its own methods of rendering to the various sites. However, RealSystem provides the Multi-Instance Site User Supplier (MISUS) object, a standard method of rendering to multiple sites with no extra overhead. To use this feature, however, the plug-in must render data in an OS-generic, "windowless" manner. The client's MISUS object then manages the multiple sites.

To support the multisite feature, the plug-in implements IRMASiteUser. When the system queries for IRMASiteUserSupplier, the plug-in responds by querying for that same interface through IRMAMultiInstanceSiteUserSupplier. This latter interface is for the MISUS object, the special window management object instantiated by the client. That object will become the "site" where the renderer sends its data. It will also be the site user supplier for the actual sites (one or more) where the display events occur.

The following extract from a RealSystem SDK sample file shows how the plug-in responds to the interface query. Here, m_pMISUS has been defined as a pointer to IRMAMultiInstanceSiteUserSupplier:


    else if (IsEqualIID(riid, IID_IRMASiteUserSupplier))
{
if (m_pMISUS)
{
return m_pMISUS-QueryInterface(IID_IRMASiteUserSupplier,ppvObj);
}
else
{
*ppvObj = NULL;
return PNR_UNEXPECTED;
}
}

Because multisite support requires that the renderer function in a "windowless" state, the plug-in returns FALSE when the system calls IRMASiteUser::NeedsWindowedSites. Before it begins to render data, the plug-in must create an instance of the MISUS object and call the object's IRMAMultiInstanceSiteUserSupplier::SetSingleSiteUser method to identify itself as the site user. This can happen during plug-in initialization in the IRMARenderer::StartStream method. The following extract from a RealSystem SDK sample file illustrates this.


m_pCommonClassFactory-CreateInstance(CLSID_IRMAMultiInstanceSiteUserSupplier, (void**)&m_pMISUS);

m_pMISUS-SetSingleSiteUser((IUnknown*)(IRMASiteUser*)this);

The plug-in then sends rendered data to the MISUS object through IRMASite and IRMASiteWindowless methods. The MISUS object handles displaying the data in the actual sites. The rendering plug-in does not need to have any knowledge of the number of sites being used.

Multiple Sites

Attaching a Site

The client calls the plug-in's IRMASiteUser::AttachSite method to pass it a pointer to the site object that receives the rendered data. When the multisite feature is used, the MISUS object becomes the site object. The following example illustrates this:


CExampleRenderer::AttachSite(IRMASite* /*IN*/ pSite)
{
if (m_pMISUSSite) return PNR_UNEXPECTED;
m_pMISUSSite = pSite;
m_pMISUSSite-AddRef();

Within the IRMASiteUser::AttachSite call, the renderer should use IRMASite::SetSize to set the site size from information received in the stream header.

Note
Typically, the system calls IRMARenderer::OnHeader before calling IRMASiteUser::AttachSite. Therefore, the renderer should not call the site object or the MISUS object in IRMARenderer::OnHeader.

Handling Events

To inform the renderer of an event, the client calls the renderer's IRMASiteUser::HandleEvent method, using the PNxEvent structure defined in header file pnwintyp.h. The following example illustrates this:


IRMASiteUser::HandleEvent(PNxEvent*)

The plug-in can then use the methods of IRMASite, as well as IRMASiteWindowless or IRMASiteWindowed to handle the site display.

The PNxEvent structure contains the following public input members:


ULONG32 event;
void* window;
void* param1;
void* param2;

The following table describes how to use these members for different platforms.

Cross-Platform Event Handling
Member Windows Unix (X Windows) Macintosh
event Represents a message passed to the window's WndProc. This message can be a standard message like WM_PAINT or an event defined in RealSystem. Corresponds to an event such as Expose, ButtonPress, or ButtonRelease. Corresponds to an event such as updateEvt, activateEvt, mouseDown, or mouseUp.
window Represents an HWND. Represents a widget object. For example:

HWND hWnd =
(HWND)pEvent->window
Represents a PNxWindow object. You can use this object to access the window for drawing and other window-related tasks. For example:

PNxWindow* pPNxWindow =
(PNxWindow*)PEvent->window
param1 &
param2
Represent message-specific parameters. Correspond to the WPARAM and LPARAM parameters passed to the window's WndProc. Represent message-specific parameters. Represent message-specific parameters.

Note
On the Macintosh, the origin, port and clipping region are set before the renderer's IRMASiteUser::HandleEvent method is called. This way the renderer can always assume that its "window" is located at 0,0 and that its port is set up correctly.

Watching a Site

The rendering plug-in implements IRMASiteWatcher if it needs to monitor and, if necessary, override a window's size and position changes. It attaches to the site as a watcher with IRMASite::AttachWatcher. It can later detach itself from the site as a watcher with IRMASite::DetachWatcher.

The client core then notifies the renderer about changes in window size and placement with IRMASiteWatcher::ChangingPosition or IRMASiteWatcher::ChangingSize, passing the renderer the old and new postion or size parameters, respectively.

Detaching a Site

When the presentation ends, the client calls the plug-in's IRMASiteUser::DetachSite method to release the site. If the renderer uses the MISUS object, it needs to call that object's IRMAMultiInstanceSiteUserSupplier::ReleaseSingleSiteUser method and then release the object.

Adding Site Support to a Client

If you are building a top-level client, you should add site support as described in this section. The top-level client implements IRMASiteSupplier, which the client core uses to inform the top-level of the need for sites. The top-level then uses IRMASiteManager to communicate with the client core.

Additional Information
See "Chapter 20: Top-Level Client".

When the client core needs a site, it calls IRMASiteSupplier::SitesNeeded to pass the top-level client a request ID and a pointer to an IRMAValues interface that contains the site properties. The top-level client then creates the window and calls IRMASiteManager::AddSite to pass the core a pointer to the IRMASite interface.

The client core calls IRMASiteSupplier::SitesNotNeeded when it is finished with a site. The top-level client then destroys the window and calls IRMASiteManager::RemoveSite to pass the core a pointer to the IRMASite interface.

If the presentation layout changes so that new windows are needed or existing windows are not, the client core calls IRMASiteSupplier::BeginChangeLayout to notify the top-level client. The top-level can then expect to receive IRMASiteSupplier::SitesNeeded and IRMASiteSupplier::SitesNotNeeded calls. The core calls IRMASiteSupplier::DoneChangeLayout when the new presentation layout is complete.

Modifying the Site Sample Code

The RealSystem SDK provides sample code that demonstrates how to write a top-level client that lets you capture or intercept video frames. Possible reasons to do this include applying some visual effects to the frames of video, displaying frames using a non-standard windowing API (for example, on Unix you might want to support GTK instead of Motif) , or grabbing "thumbnail" images (that is, the first frame of a clip).

Note
Although this sample appears to show how to implement a windowless site, it actually demonstrates how to implement IRMASiteWindowed, and is only called windowless because it does not actually display any windows.

The sample code is implemented in the following files:


Copyright © 2000 RealNetworks
For technical support, please contact supportsdk@real.com.
This file last updated on 05/17/00 at 12:50:21.
previous next