Bug 932076 - Add check for MediaExtractor creation failure. r=doublec
[gecko.git] / widget / gtk / nsAppShell.cpp
blob2520e375a99b0fd52a5836848ae5a6e19d2b1377
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"
20 using mozilla::unused;
22 #define NOTIFY_TOKEN 0xFA
24 #ifdef PR_LOGGING
25 PRLogModuleInfo *gWidgetLog = nullptr;
26 PRLogModuleInfo *gWidgetFocusLog = nullptr;
27 PRLogModuleInfo *gWidgetDragLog = nullptr;
28 PRLogModuleInfo *gWidgetDrawLog = nullptr;
29 #endif
31 static GPollFunc sPollFunc;
33 // Wrapper function to disable hang monitoring while waiting in poll().
34 static gint
35 PollWrapper(GPollFD *ufds, guint nfsd, gint timeout_)
37 mozilla::HangMonitor::Suspend();
38 gint result = (*sPollFunc)(ufds, nfsd, timeout_);
39 mozilla::HangMonitor::NotifyActivity();
40 return result;
43 /*static*/ gboolean
44 nsAppShell::EventProcessorCallback(GIOChannel *source,
45 GIOCondition condition,
46 gpointer data)
48 nsAppShell *self = static_cast<nsAppShell *>(data);
50 unsigned char c;
51 unused << read(self->mPipeFDs[0], &c, 1);
52 NS_ASSERTION(c == (unsigned char) NOTIFY_TOKEN, "wrong token");
54 self->NativeEventCallback();
55 return TRUE;
58 nsAppShell::~nsAppShell()
60 if (mTag)
61 g_source_remove(mTag);
62 if (mPipeFDs[0])
63 close(mPipeFDs[0]);
64 if (mPipeFDs[1])
65 close(mPipeFDs[1]);
68 nsresult
69 nsAppShell::Init()
71 #ifdef PR_LOGGING
72 if (!gWidgetLog)
73 gWidgetLog = PR_NewLogModule("Widget");
74 if (!gWidgetFocusLog)
75 gWidgetFocusLog = PR_NewLogModule("WidgetFocus");
76 if (!gWidgetDragLog)
77 gWidgetDragLog = PR_NewLogModule("WidgetDrag");
78 if (!gWidgetDrawLog)
79 gWidgetDrawLog = PR_NewLogModule("WidgetDraw");
80 #endif
82 if (!sPollFunc) {
83 sPollFunc = g_main_context_get_poll_func(nullptr);
84 g_main_context_set_poll_func(nullptr, &PollWrapper);
87 if (PR_GetEnv("MOZ_DEBUG_PAINTS"))
88 gdk_window_set_debug_updates(TRUE);
90 int err = pipe(mPipeFDs);
91 if (err)
92 return NS_ERROR_OUT_OF_MEMORY;
94 GIOChannel *ioc;
95 GSource *source;
97 // make the pipe nonblocking
99 int flags = fcntl(mPipeFDs[0], F_GETFL, 0);
100 if (flags == -1)
101 goto failed;
102 err = fcntl(mPipeFDs[0], F_SETFL, flags | O_NONBLOCK);
103 if (err == -1)
104 goto failed;
105 flags = fcntl(mPipeFDs[1], F_GETFL, 0);
106 if (flags == -1)
107 goto failed;
108 err = fcntl(mPipeFDs[1], F_SETFL, flags | O_NONBLOCK);
109 if (err == -1)
110 goto failed;
112 ioc = g_io_channel_unix_new(mPipeFDs[0]);
113 source = g_io_create_watch(ioc, G_IO_IN);
114 g_io_channel_unref(ioc);
115 g_source_set_callback(source, (GSourceFunc)EventProcessorCallback, this, nullptr);
116 g_source_set_can_recurse(source, TRUE);
117 mTag = g_source_attach(source, nullptr);
118 g_source_unref(source);
120 return nsBaseAppShell::Init();
121 failed:
122 close(mPipeFDs[0]);
123 close(mPipeFDs[1]);
124 mPipeFDs[0] = mPipeFDs[1] = 0;
125 return NS_ERROR_FAILURE;
128 void
129 nsAppShell::ScheduleNativeEventCallback()
131 unsigned char buf[] = { NOTIFY_TOKEN };
132 unused << write(mPipeFDs[1], buf, 1);
135 bool
136 nsAppShell::ProcessNextNativeEvent(bool mayWait)
138 return g_main_context_iteration(nullptr, mayWait);