1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Unix Native App Support.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Mozilla Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 2007
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Michael Wu <flamingice@sourmilk.net> (original author)
24 : * Michael Ventnor <m.ventnor@gmail.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "nsNativeAppSupportBase.h"
41 : #include "nsCOMPtr.h"
42 : #include "nsXPCOM.h"
43 : #include "nsISupportsPrimitives.h"
44 : #include "nsIObserverService.h"
45 : #include "nsIAppStartup.h"
46 : #include "nsServiceManagerUtils.h"
47 : #include "prlink.h"
48 : #include "nsXREDirProvider.h"
49 : #include "nsReadableUtils.h"
50 :
51 : #include "nsIFile.h"
52 : #include "nsDirectoryServiceDefs.h"
53 : #include "nsICommandLineRunner.h"
54 : #include "nsIWindowMediator.h"
55 : #include "nsPIDOMWindow.h"
56 : #include "nsIDocShell.h"
57 : #include "nsIBaseWindow.h"
58 : #include "nsIWidget.h"
59 : #include "nsIWritablePropertyBag2.h"
60 : #include "nsIPrefService.h"
61 : #include "mozilla/Services.h"
62 :
63 : #include <stdlib.h>
64 : #include <glib.h>
65 : #include <glib-object.h>
66 : #include <gtk/gtk.h>
67 :
68 : #ifdef MOZ_X11
69 : #include <gdk/gdkx.h>
70 : #include <X11/Xatom.h>
71 : #endif
72 :
73 : #if (MOZ_PLATFORM_MAEMO == 5)
74 : struct DBusMessage; /* libosso.h references internals of dbus */
75 :
76 : #include <dbus/dbus.h>
77 : #include <dbus/dbus-protocol.h>
78 : #include <libosso.h>
79 :
80 : // These come from <mce/dbus-names.h> (maemo sdk 5+)
81 : #define MCE_SERVICE "com.nokia.mce"
82 : #define MCE_REQUEST_IF "com.nokia.mce.request"
83 : #define MCE_REQUEST_PATH "/com/nokia/mce/request"
84 : #define MCE_SIGNAL_IF "com.nokia.mce.signal"
85 : #define MCE_DEVICE_ORIENTATION_SIG "sig_device_orientation_ind"
86 : #define MCE_MATCH_RULE "type='signal',interface='" MCE_SIGNAL_IF "',member='" MCE_DEVICE_ORIENTATION_SIG "'"
87 : #endif
88 :
89 : #define MIN_GTK_MAJOR_VERSION 2
90 : #define MIN_GTK_MINOR_VERSION 10
91 : #define UNSUPPORTED_GTK_MSG "We're sorry, this application requires a version of the GTK+ library that is not installed on your computer.\n\n\
92 : You have GTK+ %d.%d.\nThis application requires GTK+ %d.%d or newer.\n\n\
93 : Please upgrade your GTK+ library if you wish to use this application."
94 :
95 : typedef struct _GnomeProgram GnomeProgram;
96 : typedef struct _GnomeModuleInfo GnomeModuleInfo;
97 : typedef struct _GnomeClient GnomeClient;
98 :
99 : typedef enum {
100 : GNOME_SAVE_GLOBAL,
101 : GNOME_SAVE_LOCAL,
102 : GNOME_SAVE_BOTH
103 : } GnomeSaveStyle;
104 :
105 : typedef enum {
106 : GNOME_INTERACT_NONE,
107 : GNOME_INTERACT_ERRORS,
108 : GNOME_INTERACT_ANY
109 : } GnomeInteractStyle;
110 :
111 : typedef enum {
112 : GNOME_DIALOG_ERROR,
113 : GNOME_DIALOG_NORMAL
114 : } GnomeDialogType;
115 :
116 : typedef GnomeProgram * (*_gnome_program_init_fn)(const char *, const char *,
117 : const GnomeModuleInfo *, int,
118 : char **, const char *, ...);
119 : typedef GnomeProgram * (*_gnome_program_get_fn)(void);
120 : typedef const GnomeModuleInfo * (*_libgnomeui_module_info_get_fn)();
121 : typedef GnomeClient * (*_gnome_master_client_fn)(void);
122 : typedef void (*_gnome_client_set_restart_command_fn)(GnomeClient*, gint, gchar*[]);
123 :
124 : static _gnome_client_set_restart_command_fn gnome_client_set_restart_command;
125 :
126 0 : gboolean save_yourself_cb(GnomeClient *client, gint phase,
127 : GnomeSaveStyle style, gboolean shutdown,
128 : GnomeInteractStyle interact, gboolean fast,
129 : gpointer user_data)
130 : {
131 : nsCOMPtr<nsIObserverService> obsServ =
132 0 : mozilla::services::GetObserverService();
133 :
134 : nsCOMPtr<nsISupportsPRBool> didSaveSession =
135 0 : do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
136 :
137 0 : if (!obsServ || !didSaveSession)
138 0 : return TRUE; // OOM
139 :
140 : // Notify observers to save the session state
141 0 : didSaveSession->SetData(false);
142 0 : obsServ->NotifyObservers(didSaveSession, "session-save", nsnull);
143 :
144 : bool status;
145 0 : didSaveSession->GetData(&status);
146 :
147 : // If there was no session saved and the save_yourself request is
148 : // caused by upcoming shutdown we like to prepare for it
149 0 : if (!status && shutdown) {
150 : nsCOMPtr<nsISupportsPRBool> cancelQuit =
151 0 : do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
152 :
153 0 : cancelQuit->SetData(false);
154 0 : obsServ->NotifyObservers(cancelQuit, "quit-application-requested", nsnull);
155 :
156 : bool abortQuit;
157 0 : cancelQuit->GetData(&abortQuit);
158 : }
159 :
160 0 : return TRUE;
161 : }
162 :
163 0 : void die_cb(GnomeClient *client, gpointer user_data)
164 : {
165 : nsCOMPtr<nsIAppStartup> appService =
166 0 : do_GetService("@mozilla.org/toolkit/app-startup;1");
167 :
168 0 : if (appService)
169 0 : appService->Quit(nsIAppStartup::eForceQuit);
170 0 : }
171 :
172 : class nsNativeAppSupportUnix : public nsNativeAppSupportBase
173 0 : {
174 : public:
175 : NS_IMETHOD Start(bool* aRetVal);
176 : NS_IMETHOD Stop(bool *aResult);
177 : NS_IMETHOD Enable();
178 :
179 : private:
180 : #if (MOZ_PLATFORM_MAEMO == 5)
181 : osso_context_t *m_osso_context;
182 : /* A note about why we need to have m_hw_state:
183 : the osso hardware callback does not tell us what changed, just
184 : that something has changed. We need to keep track of state so
185 : that we can determine what has changed.
186 : */
187 : osso_hw_state_t m_hw_state;
188 : #endif
189 : };
190 :
191 : #if (MOZ_PLATFORM_MAEMO == 5)
192 : static nsresult
193 : GetMostRecentWindow(const PRUnichar* aType, nsIDOMWindow** aWindow)
194 : {
195 : nsCOMPtr<nsIWindowMediator> wm = do_GetService("@mozilla.org/appshell/window-mediator;1");
196 : if (wm)
197 : return wm->GetMostRecentWindow(aType, aWindow);
198 : return NS_ERROR_FAILURE;
199 : }
200 :
201 : static GtkWidget*
202 : WidgetForDOMWindow(nsISupports *aWindow)
203 : {
204 : nsCOMPtr<nsPIDOMWindow> domWindow(do_QueryInterface(aWindow));
205 : if (!domWindow)
206 : return NULL;
207 :
208 : nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(domWindow->GetDocShell());
209 : if (!baseWindow)
210 : return NULL;
211 :
212 : nsCOMPtr<nsIWidget> widget;
213 : baseWindow->GetMainWidget(getter_AddRefs(widget));
214 : if (!widget)
215 : return NULL;
216 :
217 : return (GtkWidget*)(widget->GetNativeData(NS_NATIVE_SHELLWIDGET));
218 : }
219 :
220 : static void
221 : OssoSetWindowOrientation(bool aPortrait)
222 : {
223 : // If we locked the screen, ignore any orientation changes
224 : bool lockScreen = false;
225 : nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
226 : if (prefs)
227 : prefs->GetBoolPref("toolkit.screen.lock", &lockScreen);
228 :
229 : if (lockScreen)
230 : return;
231 :
232 : // Tell Hildon desktop to force our window to be either portrait or landscape,
233 : // depending on the current rotation
234 : // NOTE: We only update the most recent top-level window so this is only
235 : // suitable for apps with only one window.
236 : nsCOMPtr<nsIDOMWindow> window;
237 : GetMostRecentWindow(EmptyString().get(), getter_AddRefs(window));
238 : GtkWidget* widget = WidgetForDOMWindow(window);
239 : if (widget && widget->window) {
240 : GdkWindow *gdk = widget->window;
241 : GdkAtom request = gdk_atom_intern("_HILDON_PORTRAIT_MODE_REQUEST", FALSE);
242 :
243 : if (aPortrait) {
244 : gulong portrait_set = 1;
245 : gdk_property_change(gdk, request, gdk_x11_xatom_to_atom(XA_CARDINAL),
246 : 32, GDK_PROP_MODE_REPLACE, (const guchar *) &portrait_set, 1);
247 : }
248 : else {
249 : gdk_property_delete(gdk, request);
250 : }
251 : }
252 :
253 : // Update the system info property
254 : nsCOMPtr<nsIWritablePropertyBag2> info = do_GetService("@mozilla.org/system-info;1");
255 : if (info) {
256 : info->SetPropertyAsAString(NS_LITERAL_STRING("screen-orientation"),
257 : aPortrait ? NS_LITERAL_STRING("portrait") : NS_LITERAL_STRING("landscape"));
258 : }
259 : }
260 :
261 : static bool OssoIsScreenOn(osso_context_t* ctx)
262 : {
263 : osso_return_t rv;
264 : osso_rpc_t ret;
265 : bool result = false;
266 :
267 : rv = osso_rpc_run_system(ctx, MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF,
268 : "get_display_status", &ret, DBUS_TYPE_INVALID);
269 : if (rv == OSSO_OK) {
270 : if (strcmp(ret.value.s, "on") == 0)
271 : result = true;
272 :
273 : osso_rpc_free_val(&ret);
274 : }
275 : return result;
276 : }
277 :
278 : static void OssoRequestAccelerometer(osso_context_t *ctx, bool aEnabled)
279 : {
280 : osso_return_t rv;
281 : osso_rpc_t ret;
282 :
283 : rv = osso_rpc_run_system(ctx,
284 : MCE_SERVICE,
285 : MCE_REQUEST_PATH, MCE_REQUEST_IF,
286 : aEnabled ? "req_accelerometer_enable" : "req_accelerometer_disable",
287 : aEnabled ? &ret : NULL,
288 : DBUS_TYPE_INVALID);
289 :
290 : // Orientation might changed while the accelerometer was off, so let's update
291 : // the window's orientation
292 : if (rv == OSSO_OK && aEnabled) {
293 : OssoSetWindowOrientation(strcmp(ret.value.s, "portrait") == 0);
294 : osso_rpc_free_val(&ret);
295 : }
296 : }
297 :
298 : static void OssoDisplayCallback(osso_display_state_t state, gpointer data)
299 : {
300 : nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
301 : if (!os)
302 : return;
303 :
304 : osso_context_t* context = (osso_context_t*) data;
305 :
306 : if (state == OSSO_DISPLAY_ON) {
307 : os->NotifyObservers(nsnull, "system-display-on", nsnull);
308 : OssoRequestAccelerometer(context, true);
309 : } else {
310 : os->NotifyObservers(nsnull, "system-display-dimmed-or-off", nsnull);
311 : OssoRequestAccelerometer(context, false);
312 : }
313 : }
314 :
315 : static void OssoHardwareCallback(osso_hw_state_t *state, gpointer data)
316 : {
317 : NS_ASSERTION(state, "osso_hw_state_t must not be null.");
318 : NS_ASSERTION(data, "data must not be null.");
319 :
320 : osso_hw_state_t* ourState = (osso_hw_state_t*) data;
321 :
322 : if (state->shutdown_ind) {
323 : nsCOMPtr<nsIAppStartup> appService = do_GetService("@mozilla.org/toolkit/app-startup;1");
324 : if (appService)
325 : appService->Quit(nsIAppStartup::eForceQuit);
326 : return;
327 : }
328 :
329 : if (state->memory_low_ind && !ourState->memory_low_ind) {
330 : nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
331 : if (os)
332 : os->NotifyObservers(nsnull, "memory-pressure", NS_LITERAL_STRING("low-memory").get());
333 : }
334 :
335 : if (state->system_inactivity_ind != ourState->system_inactivity_ind) {
336 : nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
337 : if (!os)
338 : return;
339 :
340 : if (state->system_inactivity_ind)
341 : os->NotifyObservers(nsnull, "system-idle", nsnull);
342 : else
343 : os->NotifyObservers(nsnull, "system-active", nsnull);
344 : }
345 :
346 : memcpy(ourState, state, sizeof(osso_hw_state_t));
347 : }
348 :
349 : static gint
350 : OssoDbusCallback(const gchar *interface, const gchar *method,
351 : GArray *arguments, gpointer data, osso_rpc_t *retval)
352 : {
353 : retval->type = DBUS_TYPE_INVALID;
354 :
355 : // The "top_application" method just wants us to focus the top-most window.
356 : if (!strcmp("top_application", method)) {
357 : nsCOMPtr<nsIDOMWindow> window;
358 : GetMostRecentWindow(NS_LITERAL_STRING("").get(), getter_AddRefs(window));
359 : if (window)
360 : window->Focus();
361 :
362 : return OSSO_OK;
363 : }
364 :
365 : if (!strcmp("quit", method)) {
366 : nsCOMPtr<nsIAppStartup> appService = do_GetService("@mozilla.org/toolkit/app-startup;1");
367 : if (appService)
368 : appService->Quit(nsIAppStartup::eForceQuit);
369 :
370 : return OSSO_OK;
371 : }
372 :
373 : // Other methods can have arguments, which we convert and send to commandline
374 : // handlers.
375 : nsCOMPtr<nsICommandLineRunner> cmdLine
376 : (do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
377 :
378 : nsCOMPtr<nsIFile> workingDir;
379 : NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
380 : getter_AddRefs(workingDir));
381 :
382 : char** argv = 0;
383 : int argc = 0;
384 :
385 : // Not all DBus methods pass arguments
386 : if (arguments && arguments->len > 0) {
387 : // Create argument list with a dummy argv[0]
388 : argc = arguments->len + 1;
389 : argv = (char**)calloc(1, argc * sizeof(*argv));
390 :
391 : // Start at 1 to skip the dummy argv[0]
392 : for (int i = 1; i < argc; i++) {
393 : osso_rpc_t* entry = (osso_rpc_t*)&g_array_index(arguments, osso_rpc_t, i - 1);
394 : if (entry->type != DBUS_TYPE_STRING)
395 : continue;
396 :
397 : argv[i] = strdup(entry->value.s);
398 : }
399 : }
400 :
401 : cmdLine->Init(argc, argv, workingDir, nsICommandLine::STATE_REMOTE_AUTO);
402 :
403 : // Cleanup argument list
404 : while (argc) {
405 : free(argv[--argc]);
406 : }
407 : free(argv);
408 :
409 : cmdLine->Run();
410 :
411 : return OSSO_OK;
412 : }
413 :
414 : static DBusHandlerResult
415 : OssoModeControlCallback(DBusConnection *con, DBusMessage *msg, gpointer data)
416 : {
417 : if (dbus_message_is_signal(msg, MCE_SIGNAL_IF, MCE_DEVICE_ORIENTATION_SIG)) {
418 : DBusMessageIter iter;
419 : if (dbus_message_iter_init(msg, &iter)) {
420 : const gchar *mode = NULL;
421 : dbus_message_iter_get_basic(&iter, &mode);
422 :
423 : OssoSetWindowOrientation(strcmp(mode, "portrait") == 0);
424 : }
425 : }
426 : return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
427 : }
428 :
429 : #endif
430 :
431 : NS_IMETHODIMP
432 0 : nsNativeAppSupportUnix::Start(bool *aRetVal)
433 : {
434 0 : NS_ASSERTION(gAppData, "gAppData must not be null.");
435 :
436 0 : if (gtk_major_version < MIN_GTK_MAJOR_VERSION ||
437 : (gtk_major_version == MIN_GTK_MAJOR_VERSION && gtk_minor_version < MIN_GTK_MINOR_VERSION)) {
438 : GtkWidget* versionErrDialog = gtk_message_dialog_new(NULL,
439 : GtkDialogFlags(GTK_DIALOG_MODAL |
440 : GTK_DIALOG_DESTROY_WITH_PARENT),
441 : GTK_MESSAGE_ERROR,
442 : GTK_BUTTONS_OK,
443 : UNSUPPORTED_GTK_MSG,
444 : gtk_major_version,
445 : gtk_minor_version,
446 : MIN_GTK_MAJOR_VERSION,
447 0 : MIN_GTK_MINOR_VERSION);
448 0 : gtk_dialog_run(GTK_DIALOG(versionErrDialog));
449 0 : gtk_widget_destroy(versionErrDialog);
450 0 : exit(0);
451 : }
452 :
453 : #if (MOZ_PLATFORM_MAEMO == 5)
454 : /* zero state out. */
455 : memset(&m_hw_state, 0, sizeof(osso_hw_state_t));
456 :
457 : /* Initialize maemo application
458 :
459 : The initalization name will be of the form "Vendor.Name".
460 : If a Vendor isn't given, then we will just use "Name".
461 :
462 : Note that this value must match your X-Osso-Service name
463 : defined in your desktop file. If it doesn't, the OSSO
464 : system will happily kill your process.
465 : */
466 : nsCAutoString applicationName;
467 : if (gAppData->vendor) {
468 : applicationName.Append(gAppData->vendor);
469 : applicationName.Append(".");
470 : }
471 : applicationName.Append(gAppData->name);
472 : ToLowerCase(applicationName);
473 :
474 : m_osso_context = osso_initialize(applicationName.get(),
475 : gAppData->version ? gAppData->version : "1.0",
476 : true,
477 : nsnull);
478 :
479 : /* Check that initilialization was ok */
480 : if (m_osso_context == nsnull) {
481 : return NS_ERROR_FAILURE;
482 : }
483 :
484 : osso_hw_set_event_cb(m_osso_context, nsnull, OssoHardwareCallback, &m_hw_state);
485 : osso_hw_set_display_event_cb(m_osso_context, OssoDisplayCallback, m_osso_context);
486 : osso_rpc_set_default_cb_f(m_osso_context, OssoDbusCallback, nsnull);
487 :
488 : // Setup an MCE callback to monitor orientation
489 : DBusConnection *connnection = (DBusConnection*)osso_get_sys_dbus_connection(m_osso_context);
490 : dbus_bus_add_match(connnection, MCE_MATCH_RULE, nsnull);
491 : dbus_connection_add_filter(connnection, OssoModeControlCallback, nsnull, nsnull);
492 : #endif
493 :
494 0 : *aRetVal = true;
495 :
496 : #ifdef MOZ_X11
497 :
498 0 : PRLibrary *gnomeuiLib = PR_LoadLibrary("libgnomeui-2.so.0");
499 0 : if (!gnomeuiLib)
500 0 : return NS_OK;
501 :
502 0 : PRLibrary *gnomeLib = PR_LoadLibrary("libgnome-2.so.0");
503 0 : if (!gnomeLib) {
504 0 : PR_UnloadLibrary(gnomeuiLib);
505 0 : return NS_OK;
506 : }
507 :
508 : _gnome_program_init_fn gnome_program_init =
509 0 : (_gnome_program_init_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_init");
510 : _gnome_program_get_fn gnome_program_get =
511 0 : (_gnome_program_get_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_get");
512 0 : _libgnomeui_module_info_get_fn libgnomeui_module_info_get = (_libgnomeui_module_info_get_fn)PR_FindFunctionSymbol(gnomeuiLib, "libgnomeui_module_info_get");
513 0 : if (!gnome_program_init || !gnome_program_get || !libgnomeui_module_info_get) {
514 0 : PR_UnloadLibrary(gnomeuiLib);
515 0 : PR_UnloadLibrary(gnomeLib);
516 0 : return NS_OK;
517 : }
518 :
519 : #endif /* MOZ_X11 */
520 :
521 : #ifdef ACCESSIBILITY
522 : // We will load gail, atk-bridge by ourself later
523 : // We can't run atk-bridge init here, because gail get the control
524 : // Set GNOME_ACCESSIBILITY to 0 can avoid this
525 : static const char *accEnv = "GNOME_ACCESSIBILITY";
526 0 : const char *accOldValue = getenv(accEnv);
527 0 : setenv(accEnv, "0", 1);
528 : #endif
529 :
530 : #ifdef MOZ_X11
531 0 : if (!gnome_program_get()) {
532 0 : gnome_program_init("Gecko", "1.0", libgnomeui_module_info_get(), gArgc, gArgv, NULL);
533 : }
534 : #endif /* MOZ_X11 */
535 :
536 : #ifdef ACCESSIBILITY
537 0 : if (accOldValue) {
538 0 : setenv(accEnv, accOldValue, 1);
539 : } else {
540 0 : unsetenv(accEnv);
541 : }
542 : #endif
543 :
544 : // Careful! These libraries cannot be unloaded after this point because
545 : // gnome_program_init causes atexit handlers to be registered. Strange
546 : // crashes will occur if these libraries are unloaded.
547 :
548 : #ifdef MOZ_X11
549 : gnome_client_set_restart_command = (_gnome_client_set_restart_command_fn)
550 0 : PR_FindFunctionSymbol(gnomeuiLib, "gnome_client_set_restart_command");
551 :
552 : _gnome_master_client_fn gnome_master_client = (_gnome_master_client_fn)
553 0 : PR_FindFunctionSymbol(gnomeuiLib, "gnome_master_client");
554 :
555 0 : GnomeClient *client = gnome_master_client();
556 0 : g_signal_connect(client, "save-yourself", G_CALLBACK(save_yourself_cb), NULL);
557 0 : g_signal_connect(client, "die", G_CALLBACK(die_cb), NULL);
558 :
559 : // Set the correct/requested restart command in any case.
560 :
561 : // Is there a request to suppress default binary launcher?
562 0 : nsCAutoString path;
563 0 : char* argv1 = getenv("MOZ_APP_LAUNCHER");
564 :
565 0 : if(!argv1) {
566 : // Tell the desktop the command for restarting us so that we can be part of XSMP session restore
567 0 : NS_ASSERTION(gDirServiceProvider, "gDirServiceProvider is NULL! This shouldn't happen!");
568 0 : nsCOMPtr<nsIFile> executablePath;
569 : nsresult rv;
570 :
571 : bool dummy;
572 0 : rv = gDirServiceProvider->GetFile(XRE_EXECUTABLE_FILE, &dummy, getter_AddRefs(executablePath));
573 :
574 0 : if (NS_SUCCEEDED(rv)) {
575 : // Strip off the -bin suffix to get the shell script we should run; this is what Breakpad does
576 0 : nsCAutoString leafName;
577 0 : rv = executablePath->GetNativeLeafName(leafName);
578 0 : if (NS_SUCCEEDED(rv) && StringEndsWith(leafName, NS_LITERAL_CSTRING("-bin"))) {
579 0 : leafName.SetLength(leafName.Length() - strlen("-bin"));
580 0 : executablePath->SetNativeLeafName(leafName);
581 : }
582 :
583 0 : executablePath->GetNativePath(path);
584 0 : argv1 = (char*)(path.get());
585 : }
586 : }
587 :
588 0 : if (argv1) {
589 0 : gnome_client_set_restart_command(client, 1, &argv1);
590 : }
591 : #endif /* MOZ_X11 */
592 :
593 0 : return NS_OK;
594 : }
595 :
596 : NS_IMETHODIMP
597 0 : nsNativeAppSupportUnix::Stop(bool *aResult)
598 : {
599 0 : NS_ENSURE_ARG(aResult);
600 0 : *aResult = true;
601 :
602 : #if (MOZ_PLATFORM_MAEMO == 5)
603 : if (m_osso_context) {
604 : // Disable the accelerometer when closing
605 : OssoRequestAccelerometer(m_osso_context, false);
606 :
607 : // Remove the MCE callback filter
608 : DBusConnection *connnection = (DBusConnection*)osso_get_sys_dbus_connection(m_osso_context);
609 : dbus_connection_remove_filter(connnection, OssoModeControlCallback, nsnull);
610 :
611 : osso_hw_unset_event_cb(m_osso_context, nsnull);
612 : osso_rpc_unset_default_cb_f(m_osso_context, OssoDbusCallback, nsnull);
613 : osso_deinitialize(m_osso_context);
614 : m_osso_context = nsnull;
615 : }
616 : #endif
617 0 : return NS_OK;
618 : }
619 :
620 : NS_IMETHODIMP
621 0 : nsNativeAppSupportUnix::Enable()
622 : {
623 : #if (MOZ_PLATFORM_MAEMO == 5)
624 : // Enable the accelerometer for orientation support
625 : if (OssoIsScreenOn(m_osso_context))
626 : OssoRequestAccelerometer(m_osso_context, true);
627 : #endif
628 0 : return NS_OK;
629 : }
630 :
631 : nsresult
632 0 : NS_CreateNativeAppSupport(nsINativeAppSupport **aResult)
633 : {
634 0 : nsNativeAppSupportBase* native = new nsNativeAppSupportUnix();
635 0 : if (!native)
636 0 : return NS_ERROR_OUT_OF_MEMORY;
637 :
638 0 : *aResult = native;
639 0 : NS_ADDREF(*aResult);
640 :
641 0 : return NS_OK;
642 : }
|