11/* Copyright (c) 2012 Research In Motion Limited.
2- *
3- * Licensed under the Apache License, Version 2.0 (the "License");
4- * you may not use this file except in compliance with the License.
5- * You may obtain a copy of the License at
6- *
7- * http://www.apache.org/licenses/LICENSE-2.0
8- *
9- * Unless required by applicable law or agreed to in writing, software
10- * distributed under the License is distributed on an "AS IS" BASIS,
11- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12- * See the License for the specific language governing permissions and
13- * limitations under the License.
14- */
2+ *
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
1515#include " helloforeignwindowapp.h"
1616
1717#include < bb/cascades/AbsoluteLayoutProperties>
2323
2424using namespace bb ::cascades;
2525
26+
27+ HelloForeignWindowApp::HelloForeignWindowApp ()
28+ {
29+ mTvOn = false ;
30+ mTvInitialized = false ;
31+
32+ // Here we create a QMLDocument and load the main UI QML file.
33+ QmlDocument *qml = QmlDocument::create ().load (" helloforeignwindow.qml" );
34+
35+ if (!qml->hasErrors ()) {
36+
37+ // Set a context property for the QML to the application object, so that we
38+ // can call invokable functions in the app from QML.
39+ qml->setContextProperty (" foreignWindowApp" , this );
40+
41+ // The application Page is created from QML.
42+ mAppPage = qml->createRootNode <Page>();
43+
44+ if (mAppPage ) {
45+
46+ Application::setScene (mAppPage );
47+
48+ // Start the thread in which we render to the custom window.
49+ start ();
50+ }
51+ }
52+ }
53+
54+ HelloForeignWindowApp::~HelloForeignWindowApp ()
55+ {
56+ // Cleanup screen context.
57+ screen_destroy_context (mScreenCtx );
58+
59+ // Stop the thread.
60+ terminate ();
61+ wait ();
62+ }
63+
64+ void HelloForeignWindowApp::run ()
65+ {
66+ while (true ) {
67+
68+ // A short sleep in between renders.
69+ usleep (25000 );
70+
71+ if (mTvOn && mTvInitialized ) {
72+ // If the TV is on render noise.
73+ doNoise (true );
74+ }
75+ }
76+ }
77+
2678void HelloForeignWindowApp::doNoise (bool noise)
2779{
2880 unsigned char *ptr = NULL ;
@@ -57,16 +109,7 @@ void HelloForeignWindowApp::doNoise(bool noise)
57109 screen_post_window (mScreenWindow , mScreenBuf [0 ], 1 , mRect , 0 );
58110}
59111
60- void HelloForeignWindowApp::onWindowAttached (unsigned long handle, const QString &group,
61- const QString &id)
62- {
63- // Application can verify that the attached window is the one expected.
64- qDebug () << " handle: " << handle;
65- qDebug () << " group: " << group;
66- qDebug () << " id: " << id;
67- }
68-
69- void HelloForeignWindowApp::createForeignWindow (const QString &group, const QString id, int x,
112+ bool HelloForeignWindowApp::createForeignWindow (const QString &group, const QString id, int x,
70113 int y, int width, int height)
71114{
72115 QByteArray groupArr = group.toAscii ();
@@ -78,130 +121,126 @@ void HelloForeignWindowApp::createForeignWindow(const QString &group, const QStr
78121 mRect [2 ] = width;
79122 mRect [3 ] = height;
80123
81- // You must create a context before you create a window.
82- screen_create_context (&mScreenCtx , SCREEN_APPLICATION_CONTEXT);
124+ // You must create a context before you create a window.
125+ if (screen_create_context (&mScreenCtx , SCREEN_APPLICATION_CONTEXT) != 0 ) {
126+ return false ;
127+ }
83128
84129 // Create a child window of the current window group, join the window group and set
85130 // a window id.
86- screen_create_window_type (&mScreenWindow , mScreenCtx , SCREEN_CHILD_WINDOW);
87- screen_join_window_group (mScreenWindow , groupArr.constData ());
88- screen_set_window_property_cv (mScreenWindow , SCREEN_PROPERTY_ID_STRING, idArr.length (),
89- idArr.constData ());
131+ if (screen_create_window_type (&mScreenWindow , mScreenCtx , SCREEN_CHILD_WINDOW) != 0 ) {
132+ return false ;
133+ }
134+ if (screen_join_window_group (mScreenWindow , groupArr.constData ()) != 0 ) {
135+ return false ;
136+ }
137+ if (screen_set_window_property_cv (mScreenWindow , SCREEN_PROPERTY_ID_STRING, idArr.length (),
138+ idArr.constData ()) != 0 ) {
139+ return false ;
140+ }
90141
91142 // In this application we will render to a pixmap buffer and then blit that to
92143 // the window, we set the usage to native (default is read and write but we do not need that here).
93144 int usage = SCREEN_USAGE_NATIVE;
94- screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_USAGE, &usage);
145+ if (screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_USAGE, &usage) != 0 ) {
146+ return false ;
147+ }
95148
96149 // The window size is specified in QML so we need to set up the buffer size to
97150 // correspond to that, the default size would be the full screen.
98- screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_BUFFER_SIZE, mRect + 2 );
99- screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_SOURCE_SIZE, mRect + 2 );
151+ if (screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_BUFFER_SIZE, mRect + 2 ) != 0 ) {
152+ return false ;
153+ }
154+ if (screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_SOURCE_SIZE, mRect + 2 ) != 0 ) {
155+ return false ;
156+ }
100157
101158 // Use negative Z order so that the window appears under the main window.
102159 // This is needed by the ForeignWindow functionality.
103160 int z = -5 ;
104- screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_ZORDER, &z);
161+ if (screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_ZORDER, &z) != 0 ) {
162+ return false ;
163+ }
105164
106165 // Set the window position on screen.
107166 int pos[2 ] = { x, y };
108- screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_POSITION, pos);
167+ if (screen_set_window_property_iv (mScreenWindow , SCREEN_PROPERTY_POSITION, pos) != 0 ) {
168+ return false ;
169+ }
109170
110171 // Finally create the window buffers, in this application we will only use one buffer.
111- screen_create_window_buffers (mScreenWindow , 1 );
172+ if (screen_create_window_buffers (mScreenWindow , 1 ) != 0 ) {
173+ return false ;
174+ }
112175
113176 // In this sample we use a pixmap to render to, a pixmap. This allows us to have
114177 // full control of exactly which pixels we choose to push to the screen.
115178 screen_pixmap_t screen_pix;
116- screen_create_pixmap (&screen_pix, mScreenCtx );
179+ if (screen_create_pixmap (&screen_pix, mScreenCtx ) != 0 ) {
180+ return false ;
181+ }
117182
118183 // A combination of write and native usage is necessary to blit the pixmap to screen.
119184 usage = SCREEN_USAGE_WRITE | SCREEN_USAGE_NATIVE;
120- screen_set_pixmap_property_iv (screen_pix, SCREEN_PROPERTY_USAGE, &usage);
185+ if (screen_set_pixmap_property_iv (screen_pix, SCREEN_PROPERTY_USAGE, &usage) != 0 ) {
186+ return false ;
187+ }
121188
122189 // Set the width and height of the buffer to correspond to the one we specified in QML.
123190 mSize [0 ] = width;
124191 mSize [1 ] = height;
125- screen_set_pixmap_property_iv (screen_pix, SCREEN_PROPERTY_BUFFER_SIZE, mSize );
192+ if (screen_set_pixmap_property_iv (screen_pix, SCREEN_PROPERTY_BUFFER_SIZE, mSize ) != 0 ) {
193+ return false ;
194+ }
126195
127196 // Create the pixmap buffer and get a reference to it for rendering in the doNoise function.
128- screen_create_pixmap_buffer (screen_pix);
129- screen_get_pixmap_property_pv (screen_pix, SCREEN_PROPERTY_RENDER_BUFFERS,
130- (void **) &mScreenPixelBuffer );
197+ if (screen_create_pixmap_buffer (screen_pix) != 0 ) {
198+ return false ;
199+ }
200+ if (screen_get_pixmap_property_pv (screen_pix, SCREEN_PROPERTY_RENDER_BUFFERS,
201+ (void **) &mScreenPixelBuffer ) != 0 ) {
202+ return false ;
203+ }
131204
132205 // We get the stride (the number of bytes between pixels on different rows), its used
133206 // later on when we perform the rendering to the pixmap buffer.
134- screen_get_buffer_property_iv (mScreenPixelBuffer , SCREEN_PROPERTY_STRIDE, &mStride );
135- }
136-
137- void HelloForeignWindowApp::run ()
138- {
139- while (true ) {
140-
141- // A short sleep in between renders.
142- usleep (25000 );
143-
144- if (mTvOn ) {
145- // If the TV is on render noise.
146- doNoise (true );
147- }
207+ if (screen_get_buffer_property_iv (mScreenPixelBuffer , SCREEN_PROPERTY_STRIDE, &mStride ) != 0 ) {
208+ return false ;
148209 }
149- }
150-
151- HelloForeignWindowApp::HelloForeignWindowApp ()
152- {
153-
154- // Here we create a QMLDocument and load the main UI QML file.
155- QmlDocument *qml = QmlDocument::create ().load (" helloforeignwindow.qml" );
156-
157- if (!qml->hasErrors ()) {
158-
159- // Set a context property for the QML to the application object, so that we
160- // can call invokable functions in the app from QML.
161- qml->setContextProperty (" foreignWindowApp" , this );
162-
163- // The application Page is created from QML.
164- Page *appPage = qml->createRootNode <Page>();
165-
166- if (appPage) {
167- mTvOn = false ;
168-
169- // Get the foreign window Control specified in QML and attach to the window attached signal.
170- ForeignWindow *foreignWindow = appPage->findChild <ForeignWindow*>(" myForeignWindow" );
171- QObject::connect (foreignWindow, SIGNAL (windowAttached (unsigned long ,QString,QString)),
172- this , SLOT (onWindowAttached (unsigned long , QString, QString)));
173-
174- AbsoluteLayoutProperties *layoutProperties =
175- dynamic_cast <AbsoluteLayoutProperties*>(foreignWindow->layoutProperties ());
176210
177- // Set up the foreign window at the position specified by its LayoutProperties and the dimensions
178- // given by its preferred width and height.
179- createForeignWindow (ForeignWindow::mainWindowGroupId (), " HelloForeignWindowAppID" ,
180- (int ) layoutProperties->positionX (), (int ) layoutProperties->positionY (),
181- (int ) foreignWindow->preferredWidth (), (int ) foreignWindow->preferredHeight ());
211+ return true ;
212+ }
182213
183- Application::setScene (appPage);
214+ void HelloForeignWindowApp::initForeignWindow () {
184215
185- // Start the thread in which we render to the custom window.
186- start ();
187- }
188- }
216+ // Get the foreign window Control specified in QML and attach to the window attached signal.
217+ ForeignWindow *foreignWindow = mAppPage ->findChild <ForeignWindow*>(" myForeignWindow" );
189218
190- }
219+ AbsoluteLayoutProperties *layoutProperties =
220+ dynamic_cast <AbsoluteLayoutProperties*>(foreignWindow->layoutProperties ());
191221
192- HelloForeignWindowApp::~HelloForeignWindowApp ()
193- {
194- // Cleanup screen context.
195- screen_destroy_context (mScreenCtx );
222+ // Set up the foreign window at the position specified by its LayoutProperties and the dimensions
223+ // given by its preferred width and height.
224+ if (createForeignWindow (ForeignWindow::mainWindowGroupId (), " HelloForeignWindowAppID" ,
225+ (int ) layoutProperties->positionX (), (int ) layoutProperties->positionY (),
226+ (int ) foreignWindow->preferredWidth (), (int ) foreignWindow->preferredHeight ()) == false ) {
227+ qWarning () << " The ForeginWindow was not properly initialized" ;
228+ }
196229
197- // Stop the thread .
198- terminate () ;
230+ // Initialization of the window has been performed .
231+ mTvInitialized = true ;
199232}
200233
201234void HelloForeignWindowApp::tvPower (bool on)
202235{
203236 mTvOn = on;
204237
238+ // Initialize the ForeignWindow if not already done, we can not do this when the application
239+ // starts since it is not possible to join the application window group at that stage.
240+ if (mTvInitialized == false ) {
241+ initForeignWindow ();
242+ }
243+
205244 // If the TV is off, render one frame of a black screen (noise false).
206245 if (mTvOn == false ) {
207246 doNoise (false );
0 commit comments