2002-04-27 20:26:10 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
|
|
|
*/
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2001-10-14 23:02:05 +04:00
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
2009-01-03 10:37:52 +03:00
|
|
|
#include <gdk/gdk.h>
|
2001-10-14 23:02:05 +04:00
|
|
|
#include "nsAppShell.h"
|
2008-10-19 05:34:18 +04:00
|
|
|
#include "nsWindow.h"
|
2006-05-10 21:30:15 +04:00
|
|
|
#include "prlog.h"
|
2001-12-13 01:51:19 +03:00
|
|
|
#include "prenv.h"
|
2011-11-14 20:07:42 +04:00
|
|
|
#include "mozilla/HangMonitor.h"
|
2001-10-14 23:02:05 +04:00
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
#define NOTIFY_TOKEN 0xFA
|
2001-12-07 08:23:56 +03:00
|
|
|
|
2002-04-26 21:52:08 +04:00
|
|
|
#ifdef PR_LOGGING
|
2012-07-30 18:20:58 +04:00
|
|
|
PRLogModuleInfo *gWidgetLog = nullptr;
|
|
|
|
PRLogModuleInfo *gWidgetFocusLog = nullptr;
|
|
|
|
PRLogModuleInfo *gWidgetDragLog = nullptr;
|
|
|
|
PRLogModuleInfo *gWidgetDrawLog = nullptr;
|
2002-04-26 21:52:08 +04:00
|
|
|
#endif
|
|
|
|
|
2011-11-14 20:07:42 +04:00
|
|
|
static GPollFunc sPollFunc;
|
|
|
|
|
|
|
|
// Wrapper function to disable hang monitoring while waiting in poll().
|
|
|
|
static gint
|
|
|
|
PollWrapper(GPollFD *ufds, guint nfsd, gint timeout_)
|
|
|
|
{
|
|
|
|
mozilla::HangMonitor::Suspend();
|
|
|
|
gint result = (*sPollFunc)(ufds, nfsd, timeout_);
|
|
|
|
mozilla::HangMonitor::NotifyActivity();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
/*static*/ gboolean
|
|
|
|
nsAppShell::EventProcessorCallback(GIOChannel *source,
|
|
|
|
GIOCondition condition,
|
|
|
|
gpointer data)
|
2001-12-07 08:23:56 +03:00
|
|
|
{
|
2007-07-08 11:08:04 +04:00
|
|
|
nsAppShell *self = static_cast<nsAppShell *>(data);
|
2001-12-07 08:23:56 +03:00
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
unsigned char c;
|
2012-05-12 00:23:49 +04:00
|
|
|
read(self->mPipeFDs[0], &c, 1);
|
2006-05-10 21:30:15 +04:00
|
|
|
NS_ASSERTION(c == (unsigned char) NOTIFY_TOKEN, "wrong token");
|
|
|
|
|
|
|
|
self->NativeEventCallback();
|
2002-04-27 20:26:10 +04:00
|
|
|
return TRUE;
|
2001-12-07 08:23:56 +03:00
|
|
|
}
|
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
nsAppShell::~nsAppShell()
|
2001-12-07 08:23:56 +03:00
|
|
|
{
|
2006-05-10 21:30:15 +04:00
|
|
|
if (mTag)
|
|
|
|
g_source_remove(mTag);
|
|
|
|
if (mPipeFDs[0])
|
|
|
|
close(mPipeFDs[0]);
|
|
|
|
if (mPipeFDs[1])
|
|
|
|
close(mPipeFDs[1]);
|
2001-12-07 08:23:56 +03:00
|
|
|
}
|
2001-10-14 23:02:05 +04:00
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
nsresult
|
|
|
|
nsAppShell::Init()
|
2001-10-14 23:02:05 +04:00
|
|
|
{
|
2002-04-26 21:52:08 +04:00
|
|
|
#ifdef PR_LOGGING
|
2002-04-27 20:26:10 +04:00
|
|
|
if (!gWidgetLog)
|
|
|
|
gWidgetLog = PR_NewLogModule("Widget");
|
2002-11-06 06:29:02 +03:00
|
|
|
if (!gWidgetFocusLog)
|
|
|
|
gWidgetFocusLog = PR_NewLogModule("WidgetFocus");
|
2009-06-15 04:48:52 +04:00
|
|
|
if (!gWidgetDragLog)
|
|
|
|
gWidgetDragLog = PR_NewLogModule("WidgetDrag");
|
2002-11-13 15:41:49 +03:00
|
|
|
if (!gWidgetDrawLog)
|
|
|
|
gWidgetDrawLog = PR_NewLogModule("WidgetDraw");
|
2002-04-26 21:52:08 +04:00
|
|
|
#endif
|
2003-07-02 23:27:38 +04:00
|
|
|
|
2011-11-14 20:07:42 +04:00
|
|
|
if (!sPollFunc) {
|
|
|
|
sPollFunc = g_main_context_get_poll_func(NULL);
|
|
|
|
g_main_context_set_poll_func(NULL, &PollWrapper);
|
|
|
|
}
|
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
if (PR_GetEnv("MOZ_DEBUG_PAINTS"))
|
2002-04-27 20:26:10 +04:00
|
|
|
gdk_window_set_debug_updates(TRUE);
|
2001-12-07 08:23:56 +03:00
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
int err = pipe(mPipeFDs);
|
|
|
|
if (err)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2012-11-02 03:29:20 +04:00
|
|
|
GIOChannel *ioc;
|
|
|
|
GSource *source;
|
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
// make the pipe nonblocking
|
|
|
|
|
|
|
|
int flags = fcntl(mPipeFDs[0], F_GETFL, 0);
|
|
|
|
if (flags == -1)
|
|
|
|
goto failed;
|
|
|
|
err = fcntl(mPipeFDs[0], F_SETFL, flags | O_NONBLOCK);
|
|
|
|
if (err == -1)
|
|
|
|
goto failed;
|
|
|
|
flags = fcntl(mPipeFDs[1], F_GETFL, 0);
|
|
|
|
if (flags == -1)
|
|
|
|
goto failed;
|
|
|
|
err = fcntl(mPipeFDs[1], F_SETFL, flags | O_NONBLOCK);
|
|
|
|
if (err == -1)
|
|
|
|
goto failed;
|
|
|
|
|
|
|
|
ioc = g_io_channel_unix_new(mPipeFDs[0]);
|
2012-11-02 03:29:20 +04:00
|
|
|
source = g_io_create_watch(ioc, G_IO_IN);
|
2006-05-10 21:30:15 +04:00
|
|
|
g_io_channel_unref(ioc);
|
2012-11-02 03:29:20 +04:00
|
|
|
g_source_set_callback(source, (GSourceFunc)EventProcessorCallback, this, nullptr);
|
|
|
|
g_source_set_can_recurse(source, TRUE);
|
|
|
|
mTag = g_source_attach(source, nullptr);
|
|
|
|
g_source_unref(source);
|
2006-05-10 21:30:15 +04:00
|
|
|
|
|
|
|
return nsBaseAppShell::Init();
|
|
|
|
failed:
|
|
|
|
close(mPipeFDs[0]);
|
|
|
|
close(mPipeFDs[1]);
|
|
|
|
mPipeFDs[0] = mPipeFDs[1] = 0;
|
|
|
|
return NS_ERROR_FAILURE;
|
2001-10-14 23:02:05 +04:00
|
|
|
}
|
|
|
|
|
2006-05-10 21:30:15 +04:00
|
|
|
void
|
|
|
|
nsAppShell::ScheduleNativeEventCallback()
|
2001-10-14 23:02:05 +04:00
|
|
|
{
|
2006-05-10 21:30:15 +04:00
|
|
|
unsigned char buf[] = { NOTIFY_TOKEN };
|
2012-05-12 00:23:49 +04:00
|
|
|
write(mPipeFDs[1], buf, 1);
|
2001-10-14 23:02:05 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
|
|
|
nsAppShell::ProcessNextNativeEvent(bool mayWait)
|
2001-10-14 23:02:05 +04:00
|
|
|
{
|
2006-05-10 21:30:15 +04:00
|
|
|
return g_main_context_iteration(NULL, mayWait);
|
2001-10-14 23:02:05 +04:00
|
|
|
}
|