Using the TV Out for extra information

With the new iOS devices, plug in the VGA or HDMI cable and you have an external screen in the form of the TV or the monitor that is connected. If you were developing with XCode, then you can easily access or add this to your app. Enumerate the displays, create a window for the external display and add a view - Voila. Is that available to developers that are using a Lua based framework? Up until now the answer was NO.

First a couple of things,
1. When you connect a display cable, the iOS device mirrors the display. Whatever you see on the screen is seen on the external display too.
2. Obviously, the external display is not a touch screen
3. You can have the device display something while the external screen can display something entirely different

First let us whet out appetite and see what we are going to create as seen in below.

How does it work?
This has been run on the XCode simulator, so the TV out is always connected, unlike real world scenario where the display can be connected or disconnected. Here is an image of the phone connected to an external display

First we set up an observer to the Notifications that are send to the app when an external display is connected or disconnected. The notifications passed are

We set up a listener for these using the following code
NSNotificationCenter:defaultCenter():addObserver_selector_name_object(self, "connect", "UIScreenDidConnectNotification", nil)
    NSNotificationCenter:defaultCenter():addObserver_selector_name_object(self, "connect", "UIScreenDidDisconnectNotification", nil)

Each time either of the two notifications are found, the function connect is called. We can in this function enumerate the number of screens present in the UIScreen object. If we have more than 1 screen then we create a new window and a new view to display otherwise, we simply nil the variables.

and also declare the function connect as
function connect()
    screens = UIScreen:screen()
    if #screen > 1 then 
      extScreen = screens[2] -- The second screen
      if extWindow == nil then 
        extWindow = UIWindow:initWithFrame(extScreen:bounds())

        view = UIView:initWithFrame(extWindow:frame())

        label = UILabel:initWithFrame(CGRect(10,10,600,20))


      extScreen = nil
      extWindow = nil


That is all that is there to displaying data on an external display. However, it is also important to note that there is only one OpenGL surface with Lua based frameworks and that can either be displayed on the device or the external display. In other words, the native objects, images, rectangles, etc are only displayed on the OpenGL surface where as the new window we create is an iOS UIWindow with an UIView and this cannot display the native objects, so we almost have to create two sets of displays, one using the normal framework objects and and external one with UIKit. If the framework can support creating another OpenGL surface context, then we could use the external display with native framework objects.

Swapping the displays
This is quite easy. The displays can be swapped to output the OpenGL context to the external display while adding the UIKit display context onto the device. This can be achieved by

if extWindow ~= nil then

The iOS programming guide warns that this swapping is an expensive operation and should be avoided if possible. The two new variables, mainView and mainWindow are intialised as

mainWindow = UIApplication:sharedApplication():keyWindow()
  mainView = toobjc(mainWindow:subviews()):objectAtIndex(0)

The above code is written in Lua using Gideros Studio and to include the functionality of using iOS API, the HotWax plug-in from Andy Bower is used, which is an adapted custom version for Gideros Studio of WAX from Corey Johnson.

Hope you enjoyed this...


Popular Posts