mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
4dab17b9d9
--HG-- rename : modules/plugin/test/Makefile.in => dom/plugins/test/Makefile.in rename : modules/plugin/test/crashtests/110650-1.html => dom/plugins/test/crashtests/110650-1.html rename : modules/plugin/test/crashtests/41276-1.html => dom/plugins/test/crashtests/41276-1.html rename : modules/plugin/test/crashtests/48856-1.html => dom/plugins/test/crashtests/48856-1.html rename : modules/plugin/test/crashtests/539897-1.html => dom/plugins/test/crashtests/539897-1.html rename : modules/plugin/test/crashtests/540114-1.html => dom/plugins/test/crashtests/540114-1.html rename : modules/plugin/test/crashtests/570884.html => dom/plugins/test/crashtests/570884.html rename : modules/plugin/test/crashtests/598862.html => dom/plugins/test/crashtests/598862.html rename : modules/plugin/test/crashtests/626602-1.html => dom/plugins/test/crashtests/626602-1.html rename : modules/plugin/test/crashtests/crashtests.list => dom/plugins/test/crashtests/crashtests.list rename : modules/plugin/test/mochitest/307-xo-redirect.sjs => dom/plugins/test/mochitest/307-xo-redirect.sjs rename : modules/plugin/test/mochitest/Makefile.in => dom/plugins/test/mochitest/Makefile.in rename : modules/plugin/test/mochitest/cocoa_focus.html => dom/plugins/test/mochitest/cocoa_focus.html rename : modules/plugin/test/mochitest/cocoa_window_focus.html => dom/plugins/test/mochitest/cocoa_window_focus.html rename : modules/plugin/test/mochitest/crashing_subpage.html => dom/plugins/test/mochitest/crashing_subpage.html rename : modules/plugin/test/mochitest/large-pic.jpg => dom/plugins/test/mochitest/large-pic.jpg rename : modules/plugin/test/mochitest/loremipsum.txt => dom/plugins/test/mochitest/loremipsum.txt rename : modules/plugin/test/mochitest/loremipsum.xtest => dom/plugins/test/mochitest/loremipsum.xtest rename : modules/plugin/test/mochitest/loremipsum.xtest^headers^ => dom/plugins/test/mochitest/loremipsum.xtest^headers^ rename : modules/plugin/test/mochitest/loremipsum_file.txt => dom/plugins/test/mochitest/loremipsum_file.txt rename : modules/plugin/test/mochitest/loremipsum_nocache.txt => dom/plugins/test/mochitest/loremipsum_nocache.txt rename : modules/plugin/test/mochitest/loremipsum_nocache.txt^headers^ => dom/plugins/test/mochitest/loremipsum_nocache.txt^headers^ rename : modules/plugin/test/mochitest/neverending.sjs => dom/plugins/test/mochitest/neverending.sjs rename : modules/plugin/test/mochitest/plugin_visibility_loader.html => dom/plugins/test/mochitest/plugin_visibility_loader.html rename : modules/plugin/test/mochitest/plugin_window.html => dom/plugins/test/mochitest/plugin_window.html rename : modules/plugin/test/mochitest/pluginstream.js => dom/plugins/test/mochitest/pluginstream.js rename : modules/plugin/test/mochitest/post.sjs => dom/plugins/test/mochitest/post.sjs rename : modules/plugin/test/mochitest/test_GCrace.html => dom/plugins/test/mochitest/test_GCrace.html rename : modules/plugin/test/mochitest/test_bug479979.xul => dom/plugins/test/mochitest/test_bug479979.xul rename : modules/plugin/test/mochitest/test_bug532208.html => dom/plugins/test/mochitest/test_bug532208.html rename : modules/plugin/test/mochitest/test_bug539565-1.html => dom/plugins/test/mochitest/test_bug539565-1.html rename : modules/plugin/test/mochitest/test_bug539565-2.html => dom/plugins/test/mochitest/test_bug539565-2.html rename : modules/plugin/test/mochitest/test_clear_site_data.html => dom/plugins/test/mochitest/test_clear_site_data.html rename : modules/plugin/test/mochitest/test_cocoa_focus.html => dom/plugins/test/mochitest/test_cocoa_focus.html rename : modules/plugin/test/mochitest/test_cocoa_window_focus.html => dom/plugins/test/mochitest/test_cocoa_window_focus.html rename : modules/plugin/test/mochitest/test_convertpoint.xul => dom/plugins/test/mochitest/test_convertpoint.xul rename : modules/plugin/test/mochitest/test_cookies.html => dom/plugins/test/mochitest/test_cookies.html rename : modules/plugin/test/mochitest/test_copyText.html => dom/plugins/test/mochitest/test_copyText.html rename : modules/plugin/test/mochitest/test_crash_nested_loop.html => dom/plugins/test/mochitest/test_crash_nested_loop.html rename : modules/plugin/test/mochitest/test_crash_notify.xul => dom/plugins/test/mochitest/test_crash_notify.xul rename : modules/plugin/test/mochitest/test_crash_notify_no_report.xul => dom/plugins/test/mochitest/test_crash_notify_no_report.xul rename : modules/plugin/test/mochitest/test_crash_submit.xul => dom/plugins/test/mochitest/test_crash_submit.xul rename : modules/plugin/test/mochitest/test_crashing.html => dom/plugins/test/mochitest/test_crashing.html rename : modules/plugin/test/mochitest/test_crashing2.html => dom/plugins/test/mochitest/test_crashing2.html rename : modules/plugin/test/mochitest/test_enumerate.html => dom/plugins/test/mochitest/test_enumerate.html rename : modules/plugin/test/mochitest/test_fullpage.html => dom/plugins/test/mochitest/test_fullpage.html rename : modules/plugin/test/mochitest/test_getauthenticationinfo.html => dom/plugins/test/mochitest/test_getauthenticationinfo.html rename : modules/plugin/test/mochitest/test_hanging.html => dom/plugins/test/mochitest/test_hanging.html rename : modules/plugin/test/mochitest/test_instantiation.html => dom/plugins/test/mochitest/test_instantiation.html rename : modules/plugin/test/mochitest/test_multipleinstanceobjects.html => dom/plugins/test/mochitest/test_multipleinstanceobjects.html rename : modules/plugin/test/mochitest/test_newstreamondestroy.html => dom/plugins/test/mochitest/test_newstreamondestroy.html rename : modules/plugin/test/mochitest/test_npn_asynccall.html => dom/plugins/test/mochitest/test_npn_asynccall.html rename : modules/plugin/test/mochitest/test_npn_timers.html => dom/plugins/test/mochitest/test_npn_timers.html rename : modules/plugin/test/mochitest/test_npobject_getters.html => dom/plugins/test/mochitest/test_npobject_getters.html rename : modules/plugin/test/mochitest/test_npruntime.xul => dom/plugins/test/mochitest/test_npruntime.xul rename : modules/plugin/test/mochitest/test_npruntime_construct.html => dom/plugins/test/mochitest/test_npruntime_construct.html rename : modules/plugin/test/mochitest/test_npruntime_identifiers.html => dom/plugins/test/mochitest/test_npruntime_identifiers.html rename : modules/plugin/test/mochitest/test_npruntime_npnevaluate.html => dom/plugins/test/mochitest/test_npruntime_npnevaluate.html rename : modules/plugin/test/mochitest/test_npruntime_npninvoke.html => dom/plugins/test/mochitest/test_npruntime_npninvoke.html rename : modules/plugin/test/mochitest/test_npruntime_npninvokedefault.html => dom/plugins/test/mochitest/test_npruntime_npninvokedefault.html rename : modules/plugin/test/mochitest/test_npruntime_npnsetexception.html => dom/plugins/test/mochitest/test_npruntime_npnsetexception.html rename : modules/plugin/test/mochitest/test_painting.html => dom/plugins/test/mochitest/test_painting.html rename : modules/plugin/test/mochitest/test_plugin_scroll_painting.html => dom/plugins/test/mochitest/test_plugin_scroll_painting.html rename : modules/plugin/test/mochitest/test_pluginstream_asfile.html => dom/plugins/test/mochitest/test_pluginstream_asfile.html rename : modules/plugin/test/mochitest/test_pluginstream_asfileonly.html => dom/plugins/test/mochitest/test_pluginstream_asfileonly.html rename : modules/plugin/test/mochitest/test_pluginstream_err.html => dom/plugins/test/mochitest/test_pluginstream_err.html rename : modules/plugin/test/mochitest/test_pluginstream_geturl.html => dom/plugins/test/mochitest/test_pluginstream_geturl.html rename : modules/plugin/test/mochitest/test_pluginstream_geturlnotify.html => dom/plugins/test/mochitest/test_pluginstream_geturlnotify.html rename : modules/plugin/test/mochitest/test_pluginstream_newstream.html => dom/plugins/test/mochitest/test_pluginstream_newstream.html rename : modules/plugin/test/mochitest/test_pluginstream_post.html => dom/plugins/test/mochitest/test_pluginstream_post.html rename : modules/plugin/test/mochitest/test_pluginstream_poststream.html => dom/plugins/test/mochitest/test_pluginstream_poststream.html rename : modules/plugin/test/mochitest/test_pluginstream_seek.html => dom/plugins/test/mochitest/test_pluginstream_seek.html rename : modules/plugin/test/mochitest/test_pluginstream_seek_close.html => dom/plugins/test/mochitest/test_pluginstream_seek_close.html rename : modules/plugin/test/mochitest/test_pluginstream_src.html => dom/plugins/test/mochitest/test_pluginstream_src.html rename : modules/plugin/test/mochitest/test_positioning.html => dom/plugins/test/mochitest/test_positioning.html rename : modules/plugin/test/mochitest/test_privatemode.xul => dom/plugins/test/mochitest/test_privatemode.xul rename : modules/plugin/test/mochitest/test_propertyAndMethod.html => dom/plugins/test/mochitest/test_propertyAndMethod.html rename : modules/plugin/test/mochitest/test_redirect_handling.html => dom/plugins/test/mochitest/test_redirect_handling.html rename : modules/plugin/test/mochitest/test_streamNotify.html => dom/plugins/test/mochitest/test_streamNotify.html rename : modules/plugin/test/mochitest/test_streamatclose.html => dom/plugins/test/mochitest/test_streamatclose.html rename : modules/plugin/test/mochitest/test_twostreams.html => dom/plugins/test/mochitest/test_twostreams.html rename : modules/plugin/test/mochitest/test_visibility.html => dom/plugins/test/mochitest/test_visibility.html rename : modules/plugin/test/mochitest/test_windowed_invalidate.html => dom/plugins/test/mochitest/test_windowed_invalidate.html rename : modules/plugin/test/mochitest/test_wmode.xul => dom/plugins/test/mochitest/test_wmode.xul rename : modules/plugin/test/mochitest/test_xulbrowser_plugin_visibility.xul => dom/plugins/test/mochitest/test_xulbrowser_plugin_visibility.xul rename : modules/plugin/test/mochitest/test_zero_opacity.html => dom/plugins/test/mochitest/test_zero_opacity.html rename : modules/plugin/test/mochitest/utils.js => dom/plugins/test/mochitest/utils.js rename : modules/plugin/test/mochitest/xulbrowser_plugin_visibility.xul => dom/plugins/test/mochitest/xulbrowser_plugin_visibility.xul rename : modules/plugin/test/reftest/border-padding-1-ref.html => dom/plugins/test/reftest/border-padding-1-ref.html rename : modules/plugin/test/reftest/border-padding-1.html => dom/plugins/test/reftest/border-padding-1.html rename : modules/plugin/test/reftest/border-padding-2-ref.html => dom/plugins/test/reftest/border-padding-2-ref.html rename : modules/plugin/test/reftest/border-padding-2.html => dom/plugins/test/reftest/border-padding-2.html rename : modules/plugin/test/reftest/border-padding-3-ref.html => dom/plugins/test/reftest/border-padding-3-ref.html rename : modules/plugin/test/reftest/border-padding-3.html => dom/plugins/test/reftest/border-padding-3.html rename : modules/plugin/test/reftest/div-alpha-opacity.html => dom/plugins/test/reftest/div-alpha-opacity.html rename : modules/plugin/test/reftest/div-alpha-zindex.html => dom/plugins/test/reftest/div-alpha-zindex.html rename : modules/plugin/test/reftest/div-sanity.html => dom/plugins/test/reftest/div-sanity.html rename : modules/plugin/test/reftest/plugin-alpha-opacity.html => dom/plugins/test/reftest/plugin-alpha-opacity.html rename : modules/plugin/test/reftest/plugin-alpha-zindex.html => dom/plugins/test/reftest/plugin-alpha-zindex.html rename : modules/plugin/test/reftest/plugin-background-1-step.html => dom/plugins/test/reftest/plugin-background-1-step.html rename : modules/plugin/test/reftest/plugin-background-10-step.html => dom/plugins/test/reftest/plugin-background-10-step.html rename : modules/plugin/test/reftest/plugin-background-2-step.html => dom/plugins/test/reftest/plugin-background-2-step.html rename : modules/plugin/test/reftest/plugin-background-5-step.html => dom/plugins/test/reftest/plugin-background-5-step.html rename : modules/plugin/test/reftest/plugin-background-ref.html => dom/plugins/test/reftest/plugin-background-ref.html rename : modules/plugin/test/reftest/plugin-background.css => dom/plugins/test/reftest/plugin-background.css rename : modules/plugin/test/reftest/plugin-background.html => dom/plugins/test/reftest/plugin-background.html rename : modules/plugin/test/reftest/plugin-background.js => dom/plugins/test/reftest/plugin-background.js rename : modules/plugin/test/reftest/plugin-busy-alpha-zindex.html => dom/plugins/test/reftest/plugin-busy-alpha-zindex.html rename : modules/plugin/test/reftest/plugin-canvas-alpha-zindex.html => dom/plugins/test/reftest/plugin-canvas-alpha-zindex.html rename : modules/plugin/test/reftest/plugin-sanity.html => dom/plugins/test/reftest/plugin-sanity.html rename : modules/plugin/test/reftest/plugin-transform-1-ref.html => dom/plugins/test/reftest/plugin-transform-1-ref.html rename : modules/plugin/test/reftest/plugin-transform-1.html => dom/plugins/test/reftest/plugin-transform-1.html rename : modules/plugin/test/reftest/plugin-transform-2-ref.html => dom/plugins/test/reftest/plugin-transform-2-ref.html rename : modules/plugin/test/reftest/plugin-transform-2.html => dom/plugins/test/reftest/plugin-transform-2.html rename : modules/plugin/test/reftest/plugin-transform-alpha-zindex.html => dom/plugins/test/reftest/plugin-transform-alpha-zindex.html rename : modules/plugin/test/reftest/pluginproblemui-direction-1-ref.html => dom/plugins/test/reftest/pluginproblemui-direction-1-ref.html rename : modules/plugin/test/reftest/pluginproblemui-direction-1.html => dom/plugins/test/reftest/pluginproblemui-direction-1.html rename : modules/plugin/test/reftest/pluginproblemui-direction-2-ref.html => dom/plugins/test/reftest/pluginproblemui-direction-2-ref.html rename : modules/plugin/test/reftest/pluginproblemui-direction-2.html => dom/plugins/test/reftest/pluginproblemui-direction-2.html rename : modules/plugin/test/reftest/reftest.list => dom/plugins/test/reftest/reftest.list rename : modules/plugin/test/reftest/windowless-clipping-1-ref.html => dom/plugins/test/reftest/windowless-clipping-1-ref.html rename : modules/plugin/test/reftest/windowless-clipping-1.html => dom/plugins/test/reftest/windowless-clipping-1.html rename : modules/plugin/test/testplugin/Info.plist => dom/plugins/test/testplugin/Info.plist rename : modules/plugin/test/testplugin/Makefile.in => dom/plugins/test/testplugin/Makefile.in rename : modules/plugin/test/testplugin/README => dom/plugins/test/testplugin/README rename : modules/plugin/test/testplugin/nptest.cpp => dom/plugins/test/testplugin/nptest.cpp rename : modules/plugin/test/testplugin/nptest.def => dom/plugins/test/testplugin/nptest.def rename : modules/plugin/test/testplugin/nptest.h => dom/plugins/test/testplugin/nptest.h rename : modules/plugin/test/testplugin/nptest.rc => dom/plugins/test/testplugin/nptest.rc rename : modules/plugin/test/testplugin/nptest_droid.cpp => dom/plugins/test/testplugin/nptest_droid.cpp rename : modules/plugin/test/testplugin/nptest_gtk2.cpp => dom/plugins/test/testplugin/nptest_gtk2.cpp rename : modules/plugin/test/testplugin/nptest_macosx.mm => dom/plugins/test/testplugin/nptest_macosx.mm rename : modules/plugin/test/testplugin/nptest_os2.cpp => dom/plugins/test/testplugin/nptest_os2.cpp rename : modules/plugin/test/testplugin/nptest_platform.h => dom/plugins/test/testplugin/nptest_platform.h rename : modules/plugin/test/testplugin/nptest_qt.cpp => dom/plugins/test/testplugin/nptest_qt.cpp rename : modules/plugin/test/testplugin/nptest_utils.cpp => dom/plugins/test/testplugin/nptest_utils.cpp rename : modules/plugin/test/testplugin/nptest_utils.h => dom/plugins/test/testplugin/nptest_utils.h rename : modules/plugin/test/testplugin/nptest_windows.cpp => dom/plugins/test/testplugin/nptest_windows.cpp rename : modules/plugin/test/unit/head_plugins.js => dom/plugins/test/unit/head_plugins.js rename : modules/plugin/test/unit/test_bug455213.js => dom/plugins/test/unit/test_bug455213.js rename : modules/plugin/test/unit/test_bug471245.js => dom/plugins/test/unit/test_bug471245.js
569 lines
16 KiB
C++
569 lines
16 KiB
C++
/* ***** BEGIN LICENSE BLOCK *****
|
|
*
|
|
* Copyright (c) 2008, Mozilla Corporation
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* * Neither the name of the Mozilla Corporation nor the names of its
|
|
* contributors may be used to endorse or promote products derived from this
|
|
* software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* Contributor(s):
|
|
* Josh Aas <josh@mozilla.com>
|
|
* Jim Mathies <jmathies@mozilla.com>
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "nptest_platform.h"
|
|
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <stdio.h>
|
|
|
|
using namespace std;
|
|
|
|
void SetSubclass(HWND hWnd, InstanceData* instanceData);
|
|
void ClearSubclass(HWND hWnd);
|
|
LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
|
struct _PlatformData {
|
|
HWND childWindow;
|
|
};
|
|
|
|
bool
|
|
pluginSupportsWindowMode()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
pluginSupportsWindowlessMode()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
NPError
|
|
pluginInstanceInit(InstanceData* instanceData)
|
|
{
|
|
instanceData->platformData = static_cast<PlatformData*>
|
|
(NPN_MemAlloc(sizeof(PlatformData)));
|
|
if (!instanceData->platformData)
|
|
return NPERR_OUT_OF_MEMORY_ERROR;
|
|
|
|
instanceData->platformData->childWindow = NULL;
|
|
return NPERR_NO_ERROR;
|
|
}
|
|
|
|
void
|
|
pluginInstanceShutdown(InstanceData* instanceData)
|
|
{
|
|
NPN_MemFree(instanceData->platformData);
|
|
instanceData->platformData = 0;
|
|
}
|
|
|
|
void
|
|
pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow)
|
|
{
|
|
instanceData->window = *newWindow;
|
|
}
|
|
|
|
#define CHILD_WIDGET_SIZE 10
|
|
|
|
void
|
|
pluginWidgetInit(InstanceData* instanceData, void* oldWindow)
|
|
{
|
|
HWND hWnd = (HWND)instanceData->window.window;
|
|
if (oldWindow) {
|
|
// chrashtests/539897-1.html excercises this code
|
|
HWND hWndOld = (HWND)oldWindow;
|
|
ClearSubclass(hWndOld);
|
|
if (instanceData->platformData->childWindow) {
|
|
::DestroyWindow(instanceData->platformData->childWindow);
|
|
}
|
|
}
|
|
|
|
SetSubclass(hWnd, instanceData);
|
|
|
|
instanceData->platformData->childWindow =
|
|
::CreateWindowW(L"SCROLLBAR", L"Dummy child window",
|
|
WS_CHILD, 0, 0, CHILD_WIDGET_SIZE, CHILD_WIDGET_SIZE, hWnd, NULL,
|
|
NULL, NULL);
|
|
}
|
|
|
|
static void
|
|
drawToDC(InstanceData* instanceData, HDC dc,
|
|
int x, int y, int width, int height)
|
|
{
|
|
switch (instanceData->scriptableObject->drawMode) {
|
|
case DM_DEFAULT:
|
|
{
|
|
const RECT fill = { x, y, x + width, y + height };
|
|
|
|
int oldBkMode = ::SetBkMode(dc, TRANSPARENT);
|
|
HBRUSH brush = ::CreateSolidBrush(RGB(0, 0, 0));
|
|
if (brush) {
|
|
::FillRect(dc, &fill, brush);
|
|
::DeleteObject(brush);
|
|
}
|
|
if (width > 6 && height > 6) {
|
|
brush = ::CreateSolidBrush(RGB(192, 192, 192));
|
|
if (brush) {
|
|
RECT inset = { x + 3, y + 3, x + width - 3, y + height - 3 };
|
|
::FillRect(dc, &inset, brush);
|
|
::DeleteObject(brush);
|
|
}
|
|
}
|
|
|
|
const char* uaString = NPN_UserAgent(instanceData->npp);
|
|
if (uaString && width > 10 && height > 10) {
|
|
HFONT font =
|
|
::CreateFontA(20, 0, 0, 0, 400, FALSE, FALSE, FALSE,
|
|
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS, 5, // CLEARTYPE_QUALITY
|
|
DEFAULT_PITCH, "Arial");
|
|
if (font) {
|
|
HFONT oldFont = (HFONT)::SelectObject(dc, font);
|
|
RECT inset = { x + 5, y + 5, x + width - 5, y + height - 5 };
|
|
::DrawTextA(dc, uaString, -1, &inset,
|
|
DT_LEFT | DT_TOP | DT_NOPREFIX | DT_WORDBREAK);
|
|
::SelectObject(dc, oldFont);
|
|
::DeleteObject(font);
|
|
}
|
|
}
|
|
::SetBkMode(dc, oldBkMode);
|
|
}
|
|
break;
|
|
|
|
case DM_SOLID_COLOR:
|
|
{
|
|
HDC offscreenDC = ::CreateCompatibleDC(dc);
|
|
if (!offscreenDC)
|
|
return;
|
|
|
|
const BITMAPV4HEADER bitmapheader = {
|
|
sizeof(BITMAPV4HEADER),
|
|
width,
|
|
height,
|
|
1, // planes
|
|
32, // bits
|
|
BI_BITFIELDS,
|
|
0, // unused size
|
|
0, 0, // unused metrics
|
|
0, 0, // unused colors used/important
|
|
0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, // ARGB masks
|
|
};
|
|
PRUint32 *pixelData;
|
|
HBITMAP offscreenBitmap =
|
|
::CreateDIBSection(dc, reinterpret_cast<const BITMAPINFO*>(&bitmapheader),
|
|
0, reinterpret_cast<void**>(&pixelData), 0, 0);
|
|
if (!offscreenBitmap)
|
|
return;
|
|
|
|
PRUint32 rgba = instanceData->scriptableObject->drawColor;
|
|
unsigned int alpha = ((rgba & 0xFF000000) >> 24);
|
|
BYTE r = ((rgba & 0xFF0000) >> 16);
|
|
BYTE g = ((rgba & 0xFF00) >> 8);
|
|
BYTE b = (rgba & 0xFF);
|
|
|
|
// Windows expects premultiplied
|
|
r = BYTE(float(alpha * r) / 0xFF);
|
|
g = BYTE(float(alpha * g) / 0xFF);
|
|
b = BYTE(float(alpha * b) / 0xFF);
|
|
PRUint32 premultiplied =
|
|
(alpha << 24) + (r << 16) + (g << 8) + b;
|
|
|
|
for (PRUint32* lastPixel = pixelData + width * height;
|
|
pixelData < lastPixel;
|
|
++pixelData)
|
|
*pixelData = premultiplied;
|
|
|
|
::SelectObject(offscreenDC, offscreenBitmap);
|
|
BLENDFUNCTION blendFunc;
|
|
blendFunc.BlendOp = AC_SRC_OVER;
|
|
blendFunc.BlendFlags = 0;
|
|
blendFunc.SourceConstantAlpha = 255;
|
|
blendFunc.AlphaFormat = AC_SRC_ALPHA;
|
|
::AlphaBlend(dc, x, y, width, height, offscreenDC, 0, 0, width, height,
|
|
blendFunc);
|
|
|
|
::DeleteObject(offscreenDC);
|
|
::DeleteObject(offscreenBitmap);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
pluginDraw(InstanceData* instanceData)
|
|
{
|
|
NPP npp = instanceData->npp;
|
|
if (!npp)
|
|
return;
|
|
|
|
HDC hdc = NULL;
|
|
PAINTSTRUCT ps;
|
|
|
|
notifyDidPaint(instanceData);
|
|
|
|
if (instanceData->hasWidget)
|
|
hdc = ::BeginPaint((HWND)instanceData->window.window, &ps);
|
|
else
|
|
hdc = (HDC)instanceData->window.window;
|
|
|
|
if (hdc == NULL)
|
|
return;
|
|
|
|
// Push the browser's hdc on the resource stack. If this test plugin is windowless,
|
|
// we share the drawing surface with the rest of the browser.
|
|
int savedDCID = SaveDC(hdc);
|
|
|
|
// When we have a widget, window.x/y are meaningless since our widget
|
|
// is always positioned correctly and we just draw into it at 0,0.
|
|
int x = instanceData->hasWidget ? 0 : instanceData->window.x;
|
|
int y = instanceData->hasWidget ? 0 : instanceData->window.y;
|
|
int width = instanceData->window.width;
|
|
int height = instanceData->window.height;
|
|
drawToDC(instanceData, hdc, x, y, width, height);
|
|
|
|
// Pop our hdc changes off the resource stack
|
|
RestoreDC(hdc, savedDCID);
|
|
|
|
if (instanceData->hasWidget)
|
|
::EndPaint((HWND)instanceData->window.window, &ps);
|
|
}
|
|
|
|
/* script interface */
|
|
|
|
int32_t
|
|
pluginGetEdge(InstanceData* instanceData, RectEdge edge)
|
|
{
|
|
if (!instanceData || !instanceData->hasWidget)
|
|
return NPTEST_INT32_ERROR;
|
|
|
|
// Get the plugin client rect in screen coordinates
|
|
RECT rect = {0};
|
|
if (!::GetClientRect((HWND)instanceData->window.window, &rect))
|
|
return NPTEST_INT32_ERROR;
|
|
::MapWindowPoints((HWND)instanceData->window.window, NULL, (LPPOINT)&rect, 2);
|
|
|
|
// Get the toplevel window frame rect in screen coordinates
|
|
HWND rootWnd = ::GetAncestor((HWND)instanceData->window.window, GA_ROOT);
|
|
if (!rootWnd)
|
|
return NPTEST_INT32_ERROR;
|
|
RECT rootRect;
|
|
if (!::GetWindowRect(rootWnd, &rootRect))
|
|
return NPTEST_INT32_ERROR;
|
|
|
|
switch (edge) {
|
|
case EDGE_LEFT:
|
|
return rect.left - rootRect.left;
|
|
case EDGE_TOP:
|
|
return rect.top - rootRect.top;
|
|
case EDGE_RIGHT:
|
|
return rect.right - rootRect.left;
|
|
case EDGE_BOTTOM:
|
|
return rect.bottom - rootRect.top;
|
|
}
|
|
|
|
return NPTEST_INT32_ERROR;
|
|
}
|
|
|
|
static BOOL
|
|
getWindowRegion(HWND wnd, HRGN rgn)
|
|
{
|
|
if (::GetWindowRgn(wnd, rgn) != ERROR)
|
|
return TRUE;
|
|
|
|
RECT clientRect;
|
|
if (!::GetClientRect(wnd, &clientRect))
|
|
return FALSE;
|
|
return ::SetRectRgn(rgn, 0, 0, clientRect.right, clientRect.bottom);
|
|
}
|
|
|
|
static RGNDATA*
|
|
computeClipRegion(InstanceData* instanceData)
|
|
{
|
|
HWND wnd = (HWND)instanceData->window.window;
|
|
HRGN rgn = ::CreateRectRgn(0, 0, 0, 0);
|
|
if (!rgn)
|
|
return NULL;
|
|
HRGN ancestorRgn = ::CreateRectRgn(0, 0, 0, 0);
|
|
if (!ancestorRgn) {
|
|
::DeleteObject(rgn);
|
|
return NULL;
|
|
}
|
|
if (!getWindowRegion(wnd, rgn)) {
|
|
::DeleteObject(ancestorRgn);
|
|
::DeleteObject(rgn);
|
|
return NULL;
|
|
}
|
|
|
|
HWND ancestor = wnd;
|
|
for (;;) {
|
|
ancestor = ::GetAncestor(ancestor, GA_PARENT);
|
|
if (!ancestor || ancestor == ::GetDesktopWindow()) {
|
|
::DeleteObject(ancestorRgn);
|
|
|
|
DWORD size = ::GetRegionData(rgn, 0, NULL);
|
|
if (!size) {
|
|
::DeleteObject(rgn);
|
|
return NULL;
|
|
}
|
|
|
|
HANDLE heap = ::GetProcessHeap();
|
|
RGNDATA* data = static_cast<RGNDATA*>(::HeapAlloc(heap, 0, size));
|
|
if (!data) {
|
|
::DeleteObject(rgn);
|
|
return NULL;
|
|
}
|
|
DWORD result = ::GetRegionData(rgn, size, data);
|
|
::DeleteObject(rgn);
|
|
if (!result) {
|
|
::HeapFree(heap, 0, data);
|
|
return NULL;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
if (!getWindowRegion(ancestor, ancestorRgn)) {
|
|
::DeleteObject(ancestorRgn);
|
|
::DeleteObject(rgn);
|
|
return 0;
|
|
}
|
|
|
|
POINT pt = { 0, 0 };
|
|
::MapWindowPoints(ancestor, wnd, &pt, 1);
|
|
if (::OffsetRgn(ancestorRgn, pt.x, pt.y) == ERROR ||
|
|
::CombineRgn(rgn, rgn, ancestorRgn, RGN_AND) == ERROR) {
|
|
::DeleteObject(ancestorRgn);
|
|
::DeleteObject(rgn);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
int32_t
|
|
pluginGetClipRegionRectCount(InstanceData* instanceData)
|
|
{
|
|
RGNDATA* data = computeClipRegion(instanceData);
|
|
if (!data)
|
|
return NPTEST_INT32_ERROR;
|
|
|
|
int32_t result = data->rdh.nCount;
|
|
::HeapFree(::GetProcessHeap(), 0, data);
|
|
return result;
|
|
}
|
|
|
|
static int32_t
|
|
addOffset(LONG coord, int32_t offset)
|
|
{
|
|
if (offset == NPTEST_INT32_ERROR)
|
|
return NPTEST_INT32_ERROR;
|
|
return coord + offset;
|
|
}
|
|
|
|
int32_t
|
|
pluginGetClipRegionRectEdge(InstanceData* instanceData,
|
|
int32_t rectIndex, RectEdge edge)
|
|
{
|
|
RGNDATA* data = computeClipRegion(instanceData);
|
|
if (!data)
|
|
return NPTEST_INT32_ERROR;
|
|
|
|
HANDLE heap = ::GetProcessHeap();
|
|
if (rectIndex >= int32_t(data->rdh.nCount)) {
|
|
::HeapFree(heap, 0, data);
|
|
return NPTEST_INT32_ERROR;
|
|
}
|
|
|
|
RECT rect = reinterpret_cast<RECT*>(data->Buffer)[rectIndex];
|
|
::HeapFree(heap, 0, data);
|
|
|
|
switch (edge) {
|
|
case EDGE_LEFT:
|
|
return addOffset(rect.left, pluginGetEdge(instanceData, EDGE_LEFT));
|
|
case EDGE_TOP:
|
|
return addOffset(rect.top, pluginGetEdge(instanceData, EDGE_TOP));
|
|
case EDGE_RIGHT:
|
|
return addOffset(rect.right, pluginGetEdge(instanceData, EDGE_LEFT));
|
|
case EDGE_BOTTOM:
|
|
return addOffset(rect.bottom, pluginGetEdge(instanceData, EDGE_TOP));
|
|
}
|
|
|
|
return NPTEST_INT32_ERROR;
|
|
}
|
|
|
|
/* windowless plugin events */
|
|
|
|
static bool
|
|
handleEventInternal(InstanceData* instanceData, NPEvent* pe, LRESULT* result)
|
|
{
|
|
switch ((UINT)pe->event) {
|
|
case WM_PAINT:
|
|
pluginDraw(instanceData);
|
|
return true;
|
|
|
|
case WM_MOUSEACTIVATE:
|
|
if (instanceData->hasWidget) {
|
|
::SetFocus((HWND)instanceData->window.window);
|
|
*result = MA_ACTIVATEANDEAT;
|
|
return true;
|
|
}
|
|
return false;
|
|
|
|
case WM_MOUSEWHEEL:
|
|
return true;
|
|
|
|
case WM_WINDOWPOSCHANGED: {
|
|
WINDOWPOS* pPos = (WINDOWPOS*)pe->lParam;
|
|
instanceData->winX = instanceData->winY = 0;
|
|
if (pPos) {
|
|
instanceData->winX = pPos->x;
|
|
instanceData->winY = pPos->y;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
case WM_MOUSEMOVE:
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONUP:
|
|
case WM_MBUTTONDOWN:
|
|
case WM_MBUTTONUP:
|
|
case WM_RBUTTONDOWN:
|
|
case WM_RBUTTONUP: {
|
|
int x = instanceData->hasWidget ? 0 : instanceData->winX;
|
|
int y = instanceData->hasWidget ? 0 : instanceData->winY;
|
|
instanceData->lastMouseX = GET_X_LPARAM(pe->lParam) - x;
|
|
instanceData->lastMouseY = GET_Y_LPARAM(pe->lParam) - y;
|
|
return true;
|
|
}
|
|
|
|
case WM_KEYDOWN:
|
|
instanceData->lastKeyText.erase();
|
|
*result = 0;
|
|
return true;
|
|
|
|
case WM_CHAR: {
|
|
*result = 0;
|
|
wchar_t uniChar = static_cast<wchar_t>(pe->wParam);
|
|
if (!uniChar) {
|
|
return true;
|
|
}
|
|
char utf8Char[6];
|
|
int len =
|
|
::WideCharToMultiByte(CP_UTF8, 0, &uniChar, 1, utf8Char, 6, NULL, NULL);
|
|
if (len == 0 || len > 6) {
|
|
return true;
|
|
}
|
|
instanceData->lastKeyText.append(utf8Char, len);
|
|
return true;
|
|
}
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int16_t
|
|
pluginHandleEvent(InstanceData* instanceData, void* event)
|
|
{
|
|
NPEvent* pe = (NPEvent*)event;
|
|
|
|
if (pe == NULL || instanceData == NULL ||
|
|
instanceData->window.type != NPWindowTypeDrawable)
|
|
return 0;
|
|
|
|
LRESULT result = 0;
|
|
return handleEventInternal(instanceData, pe, &result);
|
|
}
|
|
|
|
/* windowed plugin events */
|
|
|
|
LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
WNDPROC wndProc = (WNDPROC)GetProp(hWnd, "MozillaWndProc");
|
|
if (!wndProc)
|
|
return 0;
|
|
InstanceData* pInstance = (InstanceData*)GetProp(hWnd, "InstanceData");
|
|
if (!pInstance)
|
|
return 0;
|
|
|
|
NPEvent event = { uMsg, wParam, lParam };
|
|
|
|
LRESULT result = 0;
|
|
if (handleEventInternal(pInstance, &event, &result))
|
|
return result;
|
|
|
|
if (uMsg == WM_CLOSE) {
|
|
ClearSubclass((HWND)pInstance->window.window);
|
|
}
|
|
|
|
return CallWindowProc(wndProc, hWnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
void
|
|
ClearSubclass(HWND hWnd)
|
|
{
|
|
if (GetProp(hWnd, "MozillaWndProc")) {
|
|
::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)GetProp(hWnd, "MozillaWndProc"));
|
|
RemoveProp(hWnd, "MozillaWndProc");
|
|
RemoveProp(hWnd, "InstanceData");
|
|
}
|
|
}
|
|
|
|
void
|
|
SetSubclass(HWND hWnd, InstanceData* instanceData)
|
|
{
|
|
// Subclass the plugin window so we can handle our own windows events.
|
|
SetProp(hWnd, "InstanceData", (HANDLE)instanceData);
|
|
WNDPROC origProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)PluginWndProc);
|
|
SetProp(hWnd, "MozillaWndProc", (HANDLE)origProc);
|
|
}
|
|
|
|
static void checkEquals(int a, int b, const char* msg, string& error)
|
|
{
|
|
if (a == b) {
|
|
return;
|
|
}
|
|
|
|
error.append(msg);
|
|
char buf[100];
|
|
sprintf(buf, " (got %d, expected %d)\n", a, b);
|
|
error.append(buf);
|
|
}
|
|
|
|
void pluginDoInternalConsistencyCheck(InstanceData* instanceData, string& error)
|
|
{
|
|
if (instanceData->platformData->childWindow) {
|
|
RECT childRect;
|
|
::GetWindowRect(instanceData->platformData->childWindow, &childRect);
|
|
RECT ourRect;
|
|
HWND hWnd = (HWND)instanceData->window.window;
|
|
::GetWindowRect(hWnd, &ourRect);
|
|
checkEquals(childRect.left, ourRect.left, "Child widget left", error);
|
|
checkEquals(childRect.top, ourRect.top, "Child widget top", error);
|
|
checkEquals(childRect.right, childRect.left + CHILD_WIDGET_SIZE, "Child widget width", error);
|
|
checkEquals(childRect.bottom, childRect.top + CHILD_WIDGET_SIZE, "Child widget height", error);
|
|
}
|
|
}
|