widget/gtk/nsAppShell.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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"
    21 using mozilla::unused;
    23 #define NOTIFY_TOKEN 0xFA
    25 #ifdef PR_LOGGING
    26 PRLogModuleInfo *gWidgetLog = nullptr;
    27 PRLogModuleInfo *gWidgetFocusLog = nullptr;
    28 PRLogModuleInfo *gWidgetDragLog = nullptr;
    29 PRLogModuleInfo *gWidgetDrawLog = nullptr;
    30 #endif
    32 static GPollFunc sPollFunc;
    34 // Wrapper function to disable hang monitoring while waiting in poll().
    35 static gint
    36 PollWrapper(GPollFD *ufds, guint nfsd, gint timeout_)
    37 {
    38     mozilla::HangMonitor::Suspend();
    39     profiler_sleep_start();
    40     gint result = (*sPollFunc)(ufds, nfsd, timeout_);
    41     profiler_sleep_end();
    42     mozilla::HangMonitor::NotifyActivity();
    43     return result;
    44 }
    46 /*static*/ gboolean
    47 nsAppShell::EventProcessorCallback(GIOChannel *source, 
    48                                    GIOCondition condition,
    49                                    gpointer data)
    50 {
    51     nsAppShell *self = static_cast<nsAppShell *>(data);
    53     unsigned char c;
    54     unused << read(self->mPipeFDs[0], &c, 1);
    55     NS_ASSERTION(c == (unsigned char) NOTIFY_TOKEN, "wrong token");
    57     self->NativeEventCallback();
    58     return TRUE;
    59 }
    61 nsAppShell::~nsAppShell()
    62 {
    63     if (mTag)
    64         g_source_remove(mTag);
    65     if (mPipeFDs[0])
    66         close(mPipeFDs[0]);
    67     if (mPipeFDs[1])
    68         close(mPipeFDs[1]);
    69 }
    71 nsresult
    72 nsAppShell::Init()
    73 {
    74 #ifdef PR_LOGGING
    75     if (!gWidgetLog)
    76         gWidgetLog = PR_NewLogModule("Widget");
    77     if (!gWidgetFocusLog)
    78         gWidgetFocusLog = PR_NewLogModule("WidgetFocus");
    79     if (!gWidgetDragLog)
    80         gWidgetDragLog = PR_NewLogModule("WidgetDrag");
    81     if (!gWidgetDrawLog)
    82         gWidgetDrawLog = PR_NewLogModule("WidgetDraw");
    83 #endif
    85     if (!sPollFunc) {
    86         sPollFunc = g_main_context_get_poll_func(nullptr);
    87         g_main_context_set_poll_func(nullptr, &PollWrapper);
    88     }
    90     if (PR_GetEnv("MOZ_DEBUG_PAINTS"))
    91         gdk_window_set_debug_updates(TRUE);
    93     int err = pipe(mPipeFDs);
    94     if (err)
    95         return NS_ERROR_OUT_OF_MEMORY;
    97     GIOChannel *ioc;
    98     GSource *source;
   100     // make the pipe nonblocking
   102     int flags = fcntl(mPipeFDs[0], F_GETFL, 0);
   103     if (flags == -1)
   104         goto failed;
   105     err = fcntl(mPipeFDs[0], F_SETFL, flags | O_NONBLOCK);
   106     if (err == -1)
   107         goto failed;
   108     flags = fcntl(mPipeFDs[1], F_GETFL, 0);
   109     if (flags == -1)
   110         goto failed;
   111     err = fcntl(mPipeFDs[1], F_SETFL, flags | O_NONBLOCK);
   112     if (err == -1)
   113         goto failed;
   115     ioc = g_io_channel_unix_new(mPipeFDs[0]);
   116     source = g_io_create_watch(ioc, G_IO_IN);
   117     g_io_channel_unref(ioc);
   118     g_source_set_callback(source, (GSourceFunc)EventProcessorCallback, this, nullptr);
   119     g_source_set_can_recurse(source, TRUE);
   120     mTag = g_source_attach(source, nullptr);
   121     g_source_unref(source);
   123     return nsBaseAppShell::Init();
   124 failed:
   125     close(mPipeFDs[0]);
   126     close(mPipeFDs[1]);
   127     mPipeFDs[0] = mPipeFDs[1] = 0;
   128     return NS_ERROR_FAILURE;
   129 }
   131 void
   132 nsAppShell::ScheduleNativeEventCallback()
   133 {
   134     unsigned char buf[] = { NOTIFY_TOKEN };
   135     unused << write(mPipeFDs[1], buf, 1);
   136 }
   138 bool
   139 nsAppShell::ProcessNextNativeEvent(bool mayWait)
   140 {
   141     return g_main_context_iteration(nullptr, mayWait);
   142 }

mercurial