1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
13 #include "nsAppShell.h"
17 #include "mozilla/HangMonitor.h"
18 #include "mozilla/unused.h"
19 #include "GeckoProfiler.h"
20 #include "nsIPowerManagerService.h"
21 #ifdef MOZ_ENABLE_DBUS
22 #include "WakeLockListener.h"
25 using mozilla::unused
;
27 #define NOTIFY_TOKEN 0xFA
30 PRLogModuleInfo
*gWidgetLog
= nullptr;
31 PRLogModuleInfo
*gWidgetFocusLog
= nullptr;
32 PRLogModuleInfo
*gWidgetDragLog
= nullptr;
33 PRLogModuleInfo
*gWidgetDrawLog
= nullptr;
36 static GPollFunc sPollFunc
;
38 // Wrapper function to disable hang monitoring while waiting in poll().
40 PollWrapper(GPollFD
*ufds
, guint nfsd
, gint timeout_
)
42 mozilla::HangMonitor::Suspend();
43 profiler_sleep_start();
44 gint result
= (*sPollFunc
)(ufds
, nfsd
, timeout_
);
46 mozilla::HangMonitor::NotifyActivity();
51 nsAppShell::EventProcessorCallback(GIOChannel
*source
,
52 GIOCondition condition
,
55 nsAppShell
*self
= static_cast<nsAppShell
*>(data
);
58 unused
<< read(self
->mPipeFDs
[0], &c
, 1);
59 NS_ASSERTION(c
== (unsigned char) NOTIFY_TOKEN
, "wrong token");
61 self
->NativeEventCallback();
65 nsAppShell::~nsAppShell()
68 g_source_remove(mTag
);
80 gWidgetLog
= PR_NewLogModule("Widget");
82 gWidgetFocusLog
= PR_NewLogModule("WidgetFocus");
84 gWidgetDragLog
= PR_NewLogModule("WidgetDrag");
86 gWidgetDrawLog
= PR_NewLogModule("WidgetDraw");
89 #ifdef MOZ_ENABLE_DBUS
90 nsCOMPtr
<nsIPowerManagerService
> powerManagerService
=
91 do_GetService(POWERMANAGERSERVICE_CONTRACTID
);
93 if (powerManagerService
) {
94 powerManagerService
->AddWakeLockListener(WakeLockListener::GetSingleton());
96 NS_WARNING("Failed to retrieve PowerManagerService, wakelocks will be broken!");
101 sPollFunc
= g_main_context_get_poll_func(nullptr);
102 g_main_context_set_poll_func(nullptr, &PollWrapper
);
105 if (PR_GetEnv("MOZ_DEBUG_PAINTS"))
106 gdk_window_set_debug_updates(TRUE
);
108 int err
= pipe(mPipeFDs
);
110 return NS_ERROR_OUT_OF_MEMORY
;
115 // make the pipe nonblocking
117 int flags
= fcntl(mPipeFDs
[0], F_GETFL
, 0);
120 err
= fcntl(mPipeFDs
[0], F_SETFL
, flags
| O_NONBLOCK
);
123 flags
= fcntl(mPipeFDs
[1], F_GETFL
, 0);
126 err
= fcntl(mPipeFDs
[1], F_SETFL
, flags
| O_NONBLOCK
);
130 ioc
= g_io_channel_unix_new(mPipeFDs
[0]);
131 source
= g_io_create_watch(ioc
, G_IO_IN
);
132 g_io_channel_unref(ioc
);
133 g_source_set_callback(source
, (GSourceFunc
)EventProcessorCallback
, this, nullptr);
134 g_source_set_can_recurse(source
, TRUE
);
135 mTag
= g_source_attach(source
, nullptr);
136 g_source_unref(source
);
138 return nsBaseAppShell::Init();
142 mPipeFDs
[0] = mPipeFDs
[1] = 0;
143 return NS_ERROR_FAILURE
;
147 nsAppShell::ScheduleNativeEventCallback()
149 unsigned char buf
[] = { NOTIFY_TOKEN
};
150 unused
<< write(mPipeFDs
[1], buf
, 1);
154 nsAppShell::ProcessNextNativeEvent(bool mayWait
)
156 return g_main_context_iteration(nullptr, mayWait
);