accessible/src/windows/msaa/nsWinUtils.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: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:expandtab:shiftwidth=2:tabstop=2:
     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 "nsWinUtils.h"
    10 #include "Compatibility.h"
    11 #include "DocAccessible.h"
    12 #include "nsCoreUtils.h"
    14 #include "mozilla/Preferences.h"
    15 #include "nsArrayUtils.h"
    16 #include "nsIArray.h"
    17 #include "nsIDocument.h"
    18 #include "nsIDocShellTreeItem.h"
    19 #include "nsXULAppAPI.h"
    21 using namespace mozilla;
    22 using namespace mozilla::a11y;
    24 // Window property used by ipc related code in identifying accessible
    25 // tab windows.
    26 const wchar_t* kPropNameTabContent = L"AccessibleTabWindow";
    28 /**
    29  * WindowProc to process WM_GETOBJECT messages, used in windows emulation mode.
    30  */
    31 static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg,
    32                                    WPARAM wParam, LPARAM lParam);
    34 nsRefPtrHashtable<nsPtrHashKey<void>, DocAccessible>* nsWinUtils::sHWNDCache = nullptr;
    36 already_AddRefed<nsIDOMCSSStyleDeclaration>
    37 nsWinUtils::GetComputedStyleDeclaration(nsIContent* aContent)
    38 {
    39   nsIContent* elm = nsCoreUtils::GetDOMElementFor(aContent);
    40   if (!elm)
    41     return nullptr;
    43   // Returns number of items in style declaration
    44   nsCOMPtr<nsIDOMWindow> window =
    45     do_QueryInterface(elm->OwnerDoc()->GetWindow());
    46   if (!window)
    47     return nullptr;
    49   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
    50   nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(elm));
    51   window->GetComputedStyle(domElement, EmptyString(), getter_AddRefs(cssDecl));
    52   return cssDecl.forget();
    53 }
    55 bool
    56 nsWinUtils::MaybeStartWindowEmulation()
    57 {
    58   // Register window class that'll be used for document accessibles associated
    59   // with tabs.
    60   if (Compatibility::IsJAWS() || Compatibility::IsWE() ||
    61       Compatibility::IsDolphin() ||
    62       XRE_GetProcessType() == GeckoProcessType_Content) {
    63     RegisterNativeWindow(kClassNameTabContent);
    64     sHWNDCache = new nsRefPtrHashtable<nsPtrHashKey<void>, DocAccessible>(4);
    65     return true;
    66   }
    68   return false;
    69 }
    71 void
    72 nsWinUtils::ShutdownWindowEmulation()
    73 {
    74   // Unregister window call that's used for document accessibles associated
    75   // with tabs.
    76   if (IsWindowEmulationStarted())
    77     ::UnregisterClassW(kClassNameTabContent, GetModuleHandle(nullptr));
    78 }
    80 bool
    81 nsWinUtils::IsWindowEmulationStarted()
    82 {
    83   return sHWNDCache != nullptr;
    84 }
    86 void
    87 nsWinUtils::RegisterNativeWindow(LPCWSTR aWindowClass)
    88 {
    89   WNDCLASSW wc;
    90   wc.style = CS_GLOBALCLASS;
    91   wc.lpfnWndProc = WindowProc;
    92   wc.cbClsExtra = 0;
    93   wc.cbWndExtra = 0;
    94   wc.hInstance = GetModuleHandle(nullptr);
    95   wc.hIcon = nullptr;
    96   wc.hCursor = nullptr;
    97   wc.hbrBackground = nullptr;
    98   wc.lpszMenuName = nullptr;
    99   wc.lpszClassName = aWindowClass;
   100   ::RegisterClassW(&wc);
   101 }
   103 HWND
   104 nsWinUtils::CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd,
   105                                int aX, int aY, int aWidth, int aHeight,
   106                                bool aIsActive)
   107 {
   108   HWND hwnd = ::CreateWindowExW(WS_EX_TRANSPARENT, aWindowClass,
   109                                 L"NetscapeDispatchWnd",
   110                                 WS_CHILD | (aIsActive ? WS_VISIBLE : 0),
   111                                 aX, aY, aWidth, aHeight,
   112                                 aParentWnd,
   113                                 nullptr,
   114                                 GetModuleHandle(nullptr),
   115                                 nullptr);
   116   if (hwnd) {
   117     // Mark this window so that ipc related code can identify it.
   118     ::SetPropW(hwnd, kPropNameTabContent, (HANDLE)1);
   119   }
   120   return hwnd;
   121 }
   123 void
   124 nsWinUtils::ShowNativeWindow(HWND aWnd)
   125 {
   126   ::ShowWindow(aWnd, SW_SHOW);
   127 }
   129 void
   130 nsWinUtils::HideNativeWindow(HWND aWnd)
   131 {
   132   ::SetWindowPos(aWnd, nullptr, 0, 0, 0, 0,
   133                  SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
   134                  SWP_NOZORDER | SWP_NOACTIVATE);
   135 }
   137 LRESULT CALLBACK
   138 WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
   139 {
   140   // Note, this window's message handling should not invoke any call that
   141   // may result in a cross-process ipc call. Doing so may violate RPC
   142   // message semantics.
   144   switch (msg) {
   145     case WM_GETOBJECT:
   146     {
   147       if (lParam == OBJID_CLIENT) {
   148         DocAccessible* document =
   149           nsWinUtils::sHWNDCache->GetWeak(static_cast<void*>(hWnd));
   150         if (document) {
   151           IAccessible* msaaAccessible = nullptr;
   152           document->GetNativeInterface((void**)&msaaAccessible); // does an addref
   153           if (msaaAccessible) {
   154             LRESULT result = ::LresultFromObject(IID_IAccessible, wParam,
   155                                                  msaaAccessible); // does an addref
   156             msaaAccessible->Release(); // release extra addref
   157             return result;
   158           }
   159         }
   160       }
   161       return 0;
   162     }
   163     case WM_NCHITTEST:
   164     {
   165       LRESULT lRet = ::DefWindowProc(hWnd, msg, wParam, lParam);
   166       if (HTCLIENT == lRet)
   167         lRet = HTTRANSPARENT;
   168       return lRet;
   169     }
   170   }
   172   return ::DefWindowProcW(hWnd, msg, wParam, lParam);
   173 }

mercurial