Bumping manifests a=b2g-bump
[gecko.git] / widget / gtk / nsAppShell.cpp
blobcf1359fd0f01e86c36fa4fa199b94923880fb62b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
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/. */
8 #include <sys/types.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <gdk/gdk.h>
13 #include "nsAppShell.h"
14 #include "nsWindow.h"
15 #include "prlog.h"
16 #include "prenv.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"
23 #endif
25 using mozilla::unused;
27 #define NOTIFY_TOKEN 0xFA
29 #ifdef PR_LOGGING
30 PRLogModuleInfo *gWidgetLog = nullptr;
31 PRLogModuleInfo *gWidgetFocusLog = nullptr;
32 PRLogModuleInfo *gWidgetDragLog = nullptr;
33 PRLogModuleInfo *gWidgetDrawLog = nullptr;
34 #endif
36 static GPollFunc sPollFunc;
38 // Wrapper function to disable hang monitoring while waiting in poll().
39 static gint
40 PollWrapper(GPollFD *ufds, guint nfsd, gint timeout_)
42 mozilla::HangMonitor::Suspend();
43 profiler_sleep_start();
44 gint result = (*sPollFunc)(ufds, nfsd, timeout_);
45 profiler_sleep_end();
46 mozilla::HangMonitor::NotifyActivity();
47 return result;
50 /*static*/ gboolean
51 nsAppShell::EventProcessorCallback(GIOChannel *source,
52 GIOCondition condition,
53 gpointer data)
55 nsAppShell *self = static_cast<nsAppShell *>(data);
57 unsigned char c;
58 unused << read(self->mPipeFDs[0], &c, 1);
59 NS_ASSERTION(c == (unsigned char) NOTIFY_TOKEN, "wrong token");
61 self->NativeEventCallback();
62 return TRUE;
65 nsAppShell::~nsAppShell()
67 if (mTag)
68 g_source_remove(mTag);
69 if (mPipeFDs[0])
70 close(mPipeFDs[0]);
71 if (mPipeFDs[1])
72 close(mPipeFDs[1]);
75 nsresult
76 nsAppShell::Init()
78 #ifdef PR_LOGGING
79 if (!gWidgetLog)
80 gWidgetLog = PR_NewLogModule("Widget");
81 if (!gWidgetFocusLog)
82 gWidgetFocusLog = PR_NewLogModule("WidgetFocus");
83 if (!gWidgetDragLog)
84 gWidgetDragLog = PR_NewLogModule("WidgetDrag");
85 if (!gWidgetDrawLog)
86 gWidgetDrawLog = PR_NewLogModule("WidgetDraw");
87 #endif
89 #ifdef MOZ_ENABLE_DBUS
90 nsCOMPtr<nsIPowerManagerService> powerManagerService =
91 do_GetService(POWERMANAGERSERVICE_CONTRACTID);
93 if (powerManagerService) {
94 powerManagerService->AddWakeLockListener(WakeLockListener::GetSingleton());
95 } else {
96 NS_WARNING("Failed to retrieve PowerManagerService, wakelocks will be broken!");
98 #endif
100 if (!sPollFunc) {
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);
109 if (err)
110 return NS_ERROR_OUT_OF_MEMORY;
112 GIOChannel *ioc;
113 GSource *source;
115 // make the pipe nonblocking
117 int flags = fcntl(mPipeFDs[0], F_GETFL, 0);
118 if (flags == -1)
119 goto failed;
120 err = fcntl(mPipeFDs[0], F_SETFL, flags | O_NONBLOCK);
121 if (err == -1)
122 goto failed;
123 flags = fcntl(mPipeFDs[1], F_GETFL, 0);
124 if (flags == -1)
125 goto failed;
126 err = fcntl(mPipeFDs[1], F_SETFL, flags | O_NONBLOCK);
127 if (err == -1)
128 goto failed;
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();
139 failed:
140 close(mPipeFDs[0]);
141 close(mPipeFDs[1]);
142 mPipeFDs[0] = mPipeFDs[1] = 0;
143 return NS_ERROR_FAILURE;
146 void
147 nsAppShell::ScheduleNativeEventCallback()
149 unsigned char buf[] = { NOTIFY_TOKEN };
150 unused << write(mPipeFDs[1], buf, 1);
153 bool
154 nsAppShell::ProcessNextNativeEvent(bool mayWait)
156 return g_main_context_iteration(nullptr, mayWait);