mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
finally committing that blooming snow leopard support
This commit is contained in:
parent
b2e2877d89
commit
dd007746b5
@ -33,6 +33,20 @@
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
|
||||||
|
// Lifted from NSEvent.h (which is Objective-C).
|
||||||
|
enum {
|
||||||
|
NSAlphaShiftKeyMask = 1 << 16,
|
||||||
|
NSShiftKeyMask = 1 << 17,
|
||||||
|
NSControlKeyMask = 1 << 18,
|
||||||
|
NSAlternateKeyMask = 1 << 19,
|
||||||
|
NSCommandKeyMask = 1 << 20,
|
||||||
|
NSNumericPadKeyMask = 1 << 21,
|
||||||
|
NSHelpKeyMask = 1 << 22,
|
||||||
|
NSFunctionKeyMask = 1 << 23,
|
||||||
|
NSDeviceIndependentModifierFlagsMask = 0xffff0000U
|
||||||
|
};
|
||||||
|
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -63,6 +77,15 @@ const char *P3DInstance::_image_type_names[P3DInstance::IT_num_image_types] = {
|
|||||||
"none", // Not really used.
|
"none", // Not really used.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_str(ostream &out, const wchar_t *str) {
|
||||||
|
const wchar_t *p = str;
|
||||||
|
while (*p != 0) {
|
||||||
|
out << (int)*p << ' ';
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::Constructor
|
// Function: P3DInstance::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -137,6 +160,7 @@ P3DInstance(P3D_request_ready_func *func,
|
|||||||
// We have to start with _mouse_active true; firefox doesn't send
|
// We have to start with _mouse_active true; firefox doesn't send
|
||||||
// activate events.
|
// activate events.
|
||||||
_mouse_active = true;
|
_mouse_active = true;
|
||||||
|
_modifiers = 0;
|
||||||
_frame_timer = NULL;
|
_frame_timer = NULL;
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
@ -833,88 +857,15 @@ handle_event(const P3D_event_data &event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
assert(event._event_type == P3D_ET_osx_event_record);
|
if (event._event_type == P3D_ET_osx_event_record) {
|
||||||
EventRecord *er = event._event._osx_event_record._event;
|
retval = handle_event_osx_event_record(event);
|
||||||
|
} else if (event._event_type == P3D_ET_osx_cocoa) {
|
||||||
// Need to ensure we have the correct port set, in order to
|
retval = handle_event_osx_cocoa(event);
|
||||||
// convert the mouse coordinates successfully via
|
} else {
|
||||||
// GlobalToLocal().
|
assert(false);
|
||||||
const P3D_window_handle &handle = _wparams.get_parent_window();
|
|
||||||
assert(handle._window_handle_type == P3D_WHT_osx_port);
|
|
||||||
GrafPtr out_port = handle._handle._osx_port._port;
|
|
||||||
GrafPtr port_save = NULL;
|
|
||||||
Boolean port_changed = QDSwapPort(out_port, &port_save);
|
|
||||||
|
|
||||||
Point pt = er->where;
|
|
||||||
GlobalToLocal(&pt);
|
|
||||||
|
|
||||||
if (port_changed) {
|
|
||||||
QDSwapPort(port_save, NULL);
|
|
||||||
}
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
SubprocessWindowBuffer::Event swb_event;
|
|
||||||
swb_event._source = SubprocessWindowBuffer::ES_none;
|
|
||||||
swb_event._type = SubprocessWindowBuffer::ET_none;
|
|
||||||
swb_event._code = 0;
|
|
||||||
swb_event._flags = 0;
|
|
||||||
add_modifier_flags(swb_event._flags, er->modifiers);
|
|
||||||
|
|
||||||
switch (er->what) {
|
|
||||||
case mouseDown:
|
|
||||||
case mouseUp:
|
|
||||||
{
|
|
||||||
P3D_window_handle window = _wparams.get_parent_window();
|
|
||||||
swb_event._source = SubprocessWindowBuffer::ES_mouse;
|
|
||||||
if (er->what == mouseUp) {
|
|
||||||
swb_event._type = SubprocessWindowBuffer::ET_button_up;
|
|
||||||
} else {
|
|
||||||
swb_event._type = SubprocessWindowBuffer::ET_button_down;
|
|
||||||
}
|
|
||||||
retval = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case keyDown:
|
|
||||||
case keyUp:
|
|
||||||
case autoKey:
|
|
||||||
if (_swbuffer != NULL) {
|
|
||||||
swb_event._source = SubprocessWindowBuffer::ES_keyboard;
|
|
||||||
swb_event._code = er->message;
|
|
||||||
if (er->what == keyUp) {
|
|
||||||
swb_event._type = SubprocessWindowBuffer::ET_button_up;
|
|
||||||
} else if (er->what == keyDown) {
|
|
||||||
swb_event._type = SubprocessWindowBuffer::ET_button_down;
|
|
||||||
} else {
|
|
||||||
swb_event._type = SubprocessWindowBuffer::ET_button_again;
|
|
||||||
}
|
|
||||||
retval = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case updateEvt:
|
|
||||||
paint_window();
|
|
||||||
retval = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case activateEvt:
|
|
||||||
_mouse_active = ((er->modifiers & 1) != 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_mouse_active) {
|
|
||||||
swb_event._x = pt.h;
|
|
||||||
swb_event._y = pt.v;
|
|
||||||
swb_event._flags |= SubprocessWindowBuffer::EF_mouse_position | SubprocessWindowBuffer::EF_has_mouse;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_swbuffer != NULL) {
|
|
||||||
_swbuffer->add_event(swb_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3018,28 +2969,47 @@ set_install_label(const string &install_label) {
|
|||||||
// Function: P3DInstance::paint_window
|
// Function: P3DInstance::paint_window
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: Actually paints the rendered image to the browser
|
// Description: Actually paints the rendered image to the browser
|
||||||
// window. This is only implemented (and needed) for
|
// window. This is only needed for OSX, where the child
|
||||||
// OSX, where the child process isn't allowed to do it
|
// process isn't allowed to do it directly.
|
||||||
// directly.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
paint_window() {
|
paint_window() {
|
||||||
|
const P3D_window_handle &handle = _wparams.get_parent_window();
|
||||||
|
if (handle._window_handle_type == P3D_WHT_osx_port) {
|
||||||
|
paint_window_osx_port();
|
||||||
|
|
||||||
|
} else if (handle._window_handle_type == P3D_WHT_osx_cgcontext) {
|
||||||
|
const P3D_window_handle &handle = _wparams.get_parent_window();
|
||||||
|
assert(handle._window_handle_type == P3D_WHT_osx_cgcontext);
|
||||||
|
CGContextRef context = handle._handle._osx_cgcontext._context;
|
||||||
|
|
||||||
|
paint_window_osx_cgcontext(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::get_framebuffer
|
||||||
|
// Access: Private
|
||||||
|
// Description: Fills _reversed_buffer with the pixels from the
|
||||||
|
// current frame. Returns true on success, or false if
|
||||||
|
// there is no Panda3D window visible. Only needed on
|
||||||
|
// OSX.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstance::
|
||||||
|
get_framebuffer() {
|
||||||
if (_swbuffer == NULL || !_instance_window_opened) {
|
if (_swbuffer == NULL || !_instance_window_opened) {
|
||||||
// We don't have a Panda3D window yet.
|
// We don't have a Panda3D window yet.
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (_splash_window != NULL && _splash_window->get_visible()) {
|
if (_splash_window != NULL && _splash_window->get_visible()) {
|
||||||
// If the splash window is up, don't draw the Panda3D window.
|
// If the splash window is up, don't draw the Panda3D window.
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDErr err;
|
|
||||||
|
|
||||||
// blit rendered framebuffer into window backing store
|
// blit rendered framebuffer into window backing store
|
||||||
int x_size = min(_wparams.get_win_width(), _swbuffer->get_x_size());
|
int x_size = min(_wparams.get_win_width(), _swbuffer->get_x_size());
|
||||||
int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
|
int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
|
||||||
|
|
||||||
size_t rowsize = _swbuffer->get_row_size();
|
size_t rowsize = _swbuffer->get_row_size();
|
||||||
|
|
||||||
if (_swbuffer->ready_for_read()) {
|
if (_swbuffer->ready_for_read()) {
|
||||||
@ -3089,61 +3059,34 @@ paint_window() {
|
|||||||
// time.
|
// time.
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
return true;
|
||||||
// This is an attempt to paint the frame using the less-deprecated
|
}
|
||||||
// Quartz interfaces. Sure does seem like a lot of layers to go
|
#endif // __APPLE__
|
||||||
// through just to paint a bitmap.
|
|
||||||
CFDataRef data =
|
|
||||||
CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)_reversed_buffer,
|
|
||||||
y_size * rowsize, kCFAllocatorNull);
|
|
||||||
|
|
||||||
CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);
|
#ifdef __APPLE__
|
||||||
CGColorSpaceRef color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::paint_window_osx_port
|
||||||
CGImageRef image =
|
// Access: Private
|
||||||
CGImageCreate(x_size, y_size, 8, 32, rowsize, color_space,
|
// Description: Actually paints the rendered image to the browser
|
||||||
kCGImageAlphaFirst | kCGBitmapByteOrder32Little, provider,
|
// window, using the OSX deprecated QuickDraw
|
||||||
NULL, false, kCGRenderingIntentDefault);
|
// interfaces.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
CGrafPtr port = _wparams.get_parent_window()._port;
|
void P3DInstance::
|
||||||
CGContextRef context;
|
paint_window_osx_port() {
|
||||||
err = QDBeginCGContext(port, &context);
|
if (!get_framebuffer()) {
|
||||||
if (err != noErr) {
|
// No Panda3D window is showing.
|
||||||
nout << "Error: QDBeginCGContext\n";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CGContextTranslateCTM(context, 0.0, win_height);
|
int x_size = min(_wparams.get_win_width(), _swbuffer->get_x_size());
|
||||||
// CGContextScaleCTM(context, 1.0, -1.0);
|
int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
|
||||||
|
size_t rowsize = _swbuffer->get_row_size();
|
||||||
|
|
||||||
// We have to rely on the clipping rectangle having been set up
|
|
||||||
// correctly in order to get the proper location to draw the image.
|
|
||||||
// This isn't completely right, because if the image is slightly
|
|
||||||
// offscreen, the top left of the clipping rectangle will no longer
|
|
||||||
// correspond to the top left of the original image.
|
|
||||||
CGRect rect = CGContextGetClipBoundingBox(context);
|
|
||||||
nout << "rect: " << rect.origin.x << " " << rect.origin.y
|
|
||||||
<< " " << rect.size.width << " " << rect.size.height << "\n";
|
|
||||||
rect.size.width = x_size;
|
|
||||||
rect.size.height = y_size;
|
|
||||||
|
|
||||||
CGContextDrawImage(context, rect, image);
|
|
||||||
|
|
||||||
//CGContextSynchronize(context);
|
|
||||||
CGContextFlush(context);
|
|
||||||
QDEndCGContext(port, &context);
|
|
||||||
|
|
||||||
CGImageRelease(image);
|
|
||||||
CGColorSpaceRelease(color_space);
|
|
||||||
CGDataProviderRelease(provider);
|
|
||||||
|
|
||||||
CFRelease(data);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Painting the frame using the deprecated QuickDraw interfaces.
|
|
||||||
Rect src_rect = {0, 0, y_size, x_size};
|
Rect src_rect = {0, 0, y_size, x_size};
|
||||||
Rect ddrc_rect = {0, 0, y_size, x_size};
|
Rect ddrc_rect = {0, 0, y_size, x_size};
|
||||||
|
|
||||||
|
QDErr err;
|
||||||
|
|
||||||
GWorldPtr pGWorld;
|
GWorldPtr pGWorld;
|
||||||
err = NewGWorldFromPtr(&pGWorld, k32BGRAPixelFormat, &src_rect, 0, 0, 0,
|
err = NewGWorldFromPtr(&pGWorld, k32BGRAPixelFormat, &src_rect, 0, 0, 0,
|
||||||
_reversed_buffer, rowsize);
|
_reversed_buffer, rowsize);
|
||||||
@ -3172,18 +3115,269 @@ paint_window() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DisposeGWorld(pGWorld);
|
DisposeGWorld(pGWorld);
|
||||||
|
}
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::paint_window_osx_cgcontext
|
||||||
|
// Access: Private
|
||||||
|
// Description: Actually paints the rendered image to the browser
|
||||||
|
// window. This is the newer CoreGraphics
|
||||||
|
// implementation on OSX.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DInstance::
|
||||||
|
paint_window_osx_cgcontext(CGContextRef context) {
|
||||||
|
if (!get_framebuffer()) {
|
||||||
|
// No Panda3D window is showing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x_size = min(_wparams.get_win_width(), _swbuffer->get_x_size());
|
||||||
|
int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
|
||||||
|
size_t rowsize = _swbuffer->get_row_size();
|
||||||
|
|
||||||
|
CGContextTranslateCTM(context, 0, y_size);
|
||||||
|
CGContextScaleCTM(context, 1.0, -1.0);
|
||||||
|
|
||||||
|
CFDataRef data =
|
||||||
|
CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)_reversed_buffer,
|
||||||
|
y_size * rowsize, kCFAllocatorNull);
|
||||||
|
|
||||||
|
CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);
|
||||||
|
//CGColorSpaceRef color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
||||||
|
CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
|
||||||
|
|
||||||
|
CGImageRef image =
|
||||||
|
CGImageCreate(x_size, y_size, 8, 32, rowsize, color_space,
|
||||||
|
kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
|
||||||
|
provider, NULL, false, kCGRenderingIntentDefault);
|
||||||
|
|
||||||
|
CGRect region = { { 0, 0 }, { x_size, y_size } };
|
||||||
|
CGContextDrawImage(context, region, image);
|
||||||
|
|
||||||
|
CGImageRelease(image);
|
||||||
|
CGColorSpaceRelease(color_space);
|
||||||
|
CGDataProviderRelease(provider);
|
||||||
|
|
||||||
|
CFRelease(data);
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::handle_event_osx_event_record
|
||||||
|
// Access: Private
|
||||||
|
// Description: Responds to the deprecated Carbon event types in Mac
|
||||||
|
// OSX.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstance::
|
||||||
|
handle_event_osx_event_record(const P3D_event_data &event) {
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
assert(event._event_type == P3D_ET_osx_event_record);
|
||||||
|
EventRecord *er = event._event._osx_event_record._event;
|
||||||
|
|
||||||
|
Point pt = er->where;
|
||||||
|
|
||||||
|
// Need to ensure we have the correct port set, in order to
|
||||||
|
// convert the mouse coordinates successfully via
|
||||||
|
// GlobalToLocal().
|
||||||
|
const P3D_window_handle &handle = _wparams.get_parent_window();
|
||||||
|
if (handle._window_handle_type == P3D_WHT_osx_port) {
|
||||||
|
GrafPtr out_port = handle._handle._osx_port._port;
|
||||||
|
GrafPtr port_save = NULL;
|
||||||
|
Boolean port_changed = QDSwapPort(out_port, &port_save);
|
||||||
|
|
||||||
|
GlobalToLocal(&pt);
|
||||||
|
|
||||||
|
if (port_changed) {
|
||||||
|
QDSwapPort(port_save, NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// First, convert the coordinates from screen coordinates to
|
||||||
|
// browser window coordinates.
|
||||||
|
WindowRef window = handle._handle._osx_cgcontext._window;
|
||||||
|
CGPoint cgpt = { pt.h, pt.v };
|
||||||
|
HIPointConvert(&cgpt, kHICoordSpaceScreenPixel, NULL,
|
||||||
|
kHICoordSpaceWindow, window);
|
||||||
|
|
||||||
|
// Then convert to plugin coordinates.
|
||||||
|
pt.h = cgpt.x - _wparams.get_win_x();
|
||||||
|
pt.v = cgpt.y - _wparams.get_win_y();
|
||||||
|
}
|
||||||
|
|
||||||
|
SubprocessWindowBuffer::Event swb_event;
|
||||||
|
swb_event._source = SubprocessWindowBuffer::ES_none;
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_none;
|
||||||
|
swb_event._code = 0;
|
||||||
|
swb_event._flags = 0;
|
||||||
|
add_carbon_modifier_flags(swb_event._flags, er->modifiers);
|
||||||
|
|
||||||
|
switch (er->what) {
|
||||||
|
case mouseDown:
|
||||||
|
swb_event._source = SubprocessWindowBuffer::ES_mouse;
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_down;
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mouseUp:
|
||||||
|
swb_event._source = SubprocessWindowBuffer::ES_mouse;
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_up;
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case keyDown:
|
||||||
|
case keyUp:
|
||||||
|
case autoKey:
|
||||||
|
if (_swbuffer != NULL) {
|
||||||
|
swb_event._source = SubprocessWindowBuffer::ES_keyboard;
|
||||||
|
swb_event._code = er->message;
|
||||||
|
if (er->what == keyUp) {
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_up;
|
||||||
|
} else if (er->what == keyDown) {
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_down;
|
||||||
|
} else {
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_again;
|
||||||
|
}
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case updateEvt:
|
||||||
|
paint_window();
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case activateEvt:
|
||||||
|
_mouse_active = ((er->modifiers & 1) != 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mouse_active) {
|
||||||
|
swb_event._x = pt.h;
|
||||||
|
swb_event._y = pt.v;
|
||||||
|
swb_event._flags |= SubprocessWindowBuffer::EF_mouse_position | SubprocessWindowBuffer::EF_has_mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_swbuffer != NULL) {
|
||||||
|
_swbuffer->add_event(swb_event);
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::add_modifier_flags
|
// Function: P3DInstance::handle_event_osx_cocoa
|
||||||
|
// Access: Private
|
||||||
|
// Description: Responds to the new Cocoa event types in Mac
|
||||||
|
// OSX.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstance::
|
||||||
|
handle_event_osx_cocoa(const P3D_event_data &event) {
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
assert(event._event_type == P3D_ET_osx_cocoa);
|
||||||
|
const P3DCocoaEvent &ce = event._event._osx_cocoa._event;
|
||||||
|
|
||||||
|
SubprocessWindowBuffer::Event swb_event;
|
||||||
|
swb_event._source = SubprocessWindowBuffer::ES_none;
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_none;
|
||||||
|
swb_event._code = 0;
|
||||||
|
swb_event._flags = 0;
|
||||||
|
|
||||||
|
switch (ce.type) {
|
||||||
|
case P3DCocoaEventDrawRect:
|
||||||
|
{
|
||||||
|
CGContextRef context = ce.data.draw.context;
|
||||||
|
paint_window_osx_cgcontext(context);
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventMouseDown:
|
||||||
|
swb_event._source = SubprocessWindowBuffer::ES_mouse;
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_down;
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventMouseUp:
|
||||||
|
swb_event._source = SubprocessWindowBuffer::ES_mouse;
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_up;
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventKeyDown:
|
||||||
|
swb_event._source = SubprocessWindowBuffer::ES_keyboard;
|
||||||
|
swb_event._code = ce.data.key.keyCode << 8;
|
||||||
|
if (ce.data.key.isARepeat) {
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_again;
|
||||||
|
} else {
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_down;
|
||||||
|
if (ce.data.key.characters[0] > 0 & ce.data.key.characters[0] < 0x100) {
|
||||||
|
swb_event._code |= ce.data.key.characters[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_modifiers = ce.data.key.modifierFlags;
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventKeyUp:
|
||||||
|
swb_event._source = SubprocessWindowBuffer::ES_keyboard;
|
||||||
|
swb_event._type = SubprocessWindowBuffer::ET_button_up;
|
||||||
|
swb_event._code = ce.data.key.keyCode << 8;
|
||||||
|
_modifiers = ce.data.key.modifierFlags;
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventFlagsChanged:
|
||||||
|
_modifiers = ce.data.key.modifierFlags;
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventFocusChanged:
|
||||||
|
_mouse_active = (ce.data.focus.hasFocus != 0);
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_cocoa_modifier_flags(swb_event._flags, _modifiers);
|
||||||
|
|
||||||
|
switch (ce.type) {
|
||||||
|
case P3DCocoaEventMouseDown:
|
||||||
|
case P3DCocoaEventMouseMoved:
|
||||||
|
case P3DCocoaEventMouseDragged:
|
||||||
|
swb_event._x = ce.data.mouse.pluginX;
|
||||||
|
swb_event._y = ce.data.mouse.pluginY;
|
||||||
|
swb_event._flags |= SubprocessWindowBuffer::EF_mouse_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mouse_active) {
|
||||||
|
swb_event._flags |= SubprocessWindowBuffer::EF_has_mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_swbuffer != NULL) {
|
||||||
|
_swbuffer->add_event(swb_event);
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::add_carbon_modifier_flags
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: OSX only: adds the appropriate bits to the Event flag
|
// Description: OSX only: adds the appropriate bits to the Event flag
|
||||||
// bitmask to correspond to the modifier buttons held in
|
// bitmask to correspond to the modifier buttons held in
|
||||||
// the MacOS-style EventRecord::modifiers mask.
|
// the MacOS-style EventRecord::modifiers mask.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
add_modifier_flags(unsigned int &swb_flags, int modifiers) {
|
add_carbon_modifier_flags(unsigned int &swb_flags, int modifiers) {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (modifiers & cmdKey) {
|
if (modifiers & cmdKey) {
|
||||||
swb_flags |= SubprocessWindowBuffer::EF_meta_held;
|
swb_flags |= SubprocessWindowBuffer::EF_meta_held;
|
||||||
@ -3200,6 +3394,31 @@ add_modifier_flags(unsigned int &swb_flags, int modifiers) {
|
|||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::add_cocoa_modifier_flags
|
||||||
|
// Access: Private
|
||||||
|
// Description: OSX only: adds the appropriate bits to the Event flag
|
||||||
|
// bitmask to correspond to the modifier buttons held in
|
||||||
|
// the P3DCocoaEvent modifierFlags mask.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DInstance::
|
||||||
|
add_cocoa_modifier_flags(unsigned int &swb_flags, int modifiers) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (modifiers & NSCommandKeyMask) {
|
||||||
|
swb_flags |= SubprocessWindowBuffer::EF_meta_held;
|
||||||
|
}
|
||||||
|
if (modifiers & NSShiftKeyMask) {
|
||||||
|
swb_flags |= SubprocessWindowBuffer::EF_shift_held;
|
||||||
|
}
|
||||||
|
if (modifiers & NSAlternateKeyMask) {
|
||||||
|
swb_flags |= SubprocessWindowBuffer::EF_alt_held;
|
||||||
|
}
|
||||||
|
if (modifiers & NSControlKeyMask) {
|
||||||
|
swb_flags |= SubprocessWindowBuffer::EF_control_held;
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::send_notify
|
// Function: P3DInstance::send_notify
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -3284,7 +3503,7 @@ parse_hexdigit(int &result, char digit) {
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::timer_callback
|
// Function: P3DInstance::timer_callback
|
||||||
// Access: Private
|
// Access: Private, Static
|
||||||
// Description: OSX only: this callback is associated with a
|
// Description: OSX only: this callback is associated with a
|
||||||
// CFRunLoopTimer, to be called periodically for
|
// CFRunLoopTimer, to be called periodically for
|
||||||
// updating the frame.
|
// updating the frame.
|
||||||
@ -3293,7 +3512,6 @@ void P3DInstance::
|
|||||||
timer_callback(CFRunLoopTimerRef timer, void *info) {
|
timer_callback(CFRunLoopTimerRef timer, void *info) {
|
||||||
P3DInstance *self = (P3DInstance *)info;
|
P3DInstance *self = (P3DInstance *)info;
|
||||||
self->request_refresh();
|
self->request_refresh();
|
||||||
//self->paint_window();
|
|
||||||
}
|
}
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
@ -200,7 +200,17 @@ private:
|
|||||||
void set_install_label(const string &install_label);
|
void set_install_label(const string &install_label);
|
||||||
|
|
||||||
void paint_window();
|
void paint_window();
|
||||||
void add_modifier_flags(unsigned int &swb_flags, int modifiers);
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
bool get_framebuffer();
|
||||||
|
void paint_window_osx_port();
|
||||||
|
void paint_window_osx_cgcontext(CGContextRef context);
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
bool handle_event_osx_event_record(const P3D_event_data &event);
|
||||||
|
bool handle_event_osx_cocoa(const P3D_event_data &event);
|
||||||
|
void add_carbon_modifier_flags(unsigned int &swb_flags, int modifiers);
|
||||||
|
void add_cocoa_modifier_flags(unsigned int &swb_flags, int modifiers);
|
||||||
|
|
||||||
void send_notify(const string &message);
|
void send_notify(const string &message);
|
||||||
|
|
||||||
@ -286,6 +296,7 @@ private:
|
|||||||
SubprocessWindowBuffer *_swbuffer;
|
SubprocessWindowBuffer *_swbuffer;
|
||||||
char *_reversed_buffer;
|
char *_reversed_buffer;
|
||||||
bool _mouse_active;
|
bool _mouse_active;
|
||||||
|
unsigned int _modifiers;
|
||||||
|
|
||||||
CFRunLoopTimerRef _frame_timer;
|
CFRunLoopTimerRef _frame_timer;
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
@ -220,51 +220,17 @@ set_install_progress(double install_progress,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool P3DOsxSplashWindow::
|
bool P3DOsxSplashWindow::
|
||||||
handle_event(const P3D_event_data &event) {
|
handle_event(const P3D_event_data &event) {
|
||||||
assert(event._event_type == P3D_ET_osx_event_record);
|
bool retval = false;
|
||||||
EventRecord *er = event._event._osx_event_record._event;
|
|
||||||
|
|
||||||
// Need to ensure we have the correct port set, in order to
|
if (event._event_type == P3D_ET_osx_event_record) {
|
||||||
// convert the mouse coordinates successfully via
|
retval = handle_event_osx_event_record(event);
|
||||||
// GlobalToLocal().
|
} else if (event._event_type == P3D_ET_osx_cocoa) {
|
||||||
const P3D_window_handle &handle = _wparams.get_parent_window();
|
retval = handle_event_osx_cocoa(event);
|
||||||
assert(handle._window_handle_type == P3D_WHT_osx_port);
|
} else {
|
||||||
GrafPtr out_port = handle._handle._osx_port._port;
|
assert(false);
|
||||||
GrafPtr port_save = NULL;
|
|
||||||
Boolean port_changed = QDSwapPort(out_port, &port_save);
|
|
||||||
|
|
||||||
Point pt = er->where;
|
|
||||||
GlobalToLocal(&pt);
|
|
||||||
|
|
||||||
if (port_changed) {
|
|
||||||
QDSwapPort(port_save, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (er->what) {
|
return retval;
|
||||||
case updateEvt:
|
|
||||||
paint_window();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case mouseDown:
|
|
||||||
set_mouse_data(_mouse_x, _mouse_y, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case mouseUp:
|
|
||||||
set_mouse_data(_mouse_x, _mouse_y, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case activateEvt:
|
|
||||||
_mouse_active = ((er->modifiers & 1) != 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_mouse_active) {
|
|
||||||
set_mouse_data(pt.h, pt.v, _mouse_down);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -297,34 +263,65 @@ paint_window() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrafPtr out_port = NULL;
|
if (_toplevel_window != NULL ||
|
||||||
if (_toplevel_window != NULL) {
|
_wparams.get_parent_window()._window_handle_type == P3D_WHT_osx_port) {
|
||||||
GetPort(&out_port);
|
|
||||||
|
// The old QuickDraw-style window handle. We use
|
||||||
|
// CreateCGContextForPort() to map this to the new
|
||||||
|
// CoreGraphics-style.
|
||||||
|
GrafPtr out_port = NULL;
|
||||||
|
if (_toplevel_window != NULL) {
|
||||||
|
GetPort(&out_port);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const P3D_window_handle &handle = _wparams.get_parent_window();
|
||||||
|
assert(handle._window_handle_type == P3D_WHT_osx_port);
|
||||||
|
out_port = handle._handle._osx_port._port;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGContextRef context;
|
||||||
|
OSStatus err = CreateCGContextForPort(out_port, &context);
|
||||||
|
if (err != noErr) {
|
||||||
|
nout << "Couldn't create CG context\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust for any SetOrigin calls on out_port
|
||||||
|
SyncCGContextOriginWithPort(context, out_port);
|
||||||
|
|
||||||
|
// Move the CG origin to the upper left of the port
|
||||||
|
Rect port_rect;
|
||||||
|
GetPortBounds(out_port, &port_rect);
|
||||||
|
CGContextTranslateCTM(context, 0, (float)(port_rect.bottom - port_rect.top));
|
||||||
|
|
||||||
|
// Flip the y axis so that positive Y points down
|
||||||
|
CGContextScaleCTM(context, 1.0, -1.0);
|
||||||
|
|
||||||
|
paint_window_osx_cgcontext(context);
|
||||||
|
|
||||||
|
// CGContextSynchronize(context);
|
||||||
|
CGContextRelease(context);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// The new CoreGraphics-style window handle. We can draw to this
|
||||||
|
// directly.
|
||||||
|
|
||||||
const P3D_window_handle &handle = _wparams.get_parent_window();
|
const P3D_window_handle &handle = _wparams.get_parent_window();
|
||||||
assert(handle._window_handle_type == P3D_WHT_osx_port);
|
assert(handle._window_handle_type == P3D_WHT_osx_cgcontext);
|
||||||
out_port = handle._handle._osx_port._port;
|
CGContextRef context = handle._handle._osx_cgcontext._context;
|
||||||
|
|
||||||
|
paint_window_osx_cgcontext(context);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CGContextRef context;
|
////////////////////////////////////////////////////////////////////
|
||||||
OSStatus err = CreateCGContextForPort(out_port, &context);
|
// Function: P3DOsxSplashWindow::paint_window_osx_cgcontext
|
||||||
if (err != noErr) {
|
// Access: Private
|
||||||
nout << "Couldn't create CG context\n";
|
// Description: Redraws the current splash window, using the new
|
||||||
return;
|
// CoreGraphics interface.
|
||||||
}
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DOsxSplashWindow::
|
||||||
// Adjust for any SetOrigin calls on out_port
|
paint_window_osx_cgcontext(CGContextRef context) {
|
||||||
SyncCGContextOriginWithPort(context, out_port);
|
|
||||||
|
|
||||||
// Move the CG origin to the upper left of the port
|
|
||||||
Rect port_rect;
|
|
||||||
GetPortBounds(out_port, &port_rect);
|
|
||||||
CGContextTranslateCTM(context, 0, (float)(port_rect.bottom - port_rect.top));
|
|
||||||
|
|
||||||
// Flip the y axis so that positive Y points down
|
|
||||||
CGContextScaleCTM(context, 1.0, -1.0);
|
|
||||||
|
|
||||||
// Clear the whole region to the background color before beginning.
|
// Clear the whole region to the background color before beginning.
|
||||||
CGFloat bg_components[] = { _bgcolor_r / 255.0f, _bgcolor_g / 255.0f, _bgcolor_b / 255.0f, 1 };
|
CGFloat bg_components[] = { _bgcolor_r / 255.0f, _bgcolor_g / 255.0f, _bgcolor_b / 255.0f, 1 };
|
||||||
CGColorSpaceRef rgb_space = CGColorSpaceCreateDeviceRGB();
|
CGColorSpaceRef rgb_space = CGColorSpaceCreateDeviceRGB();
|
||||||
@ -364,9 +361,122 @@ paint_window() {
|
|||||||
if (!_progress_known || _install_progress != 0.0) {
|
if (!_progress_known || _install_progress != 0.0) {
|
||||||
paint_progress_bar(context);
|
paint_progress_bar(context);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CGContextSynchronize(context);
|
////////////////////////////////////////////////////////////////////
|
||||||
CGContextRelease(context);
|
// Function: P3DOsxSplashWindow::handle_event_osx_event_record
|
||||||
|
// Access: Private
|
||||||
|
// Description: Responds to the deprecated Carbon event types in Mac
|
||||||
|
// OSX.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DOsxSplashWindow::
|
||||||
|
handle_event_osx_event_record(const P3D_event_data &event) {
|
||||||
|
assert(event._event_type == P3D_ET_osx_event_record);
|
||||||
|
EventRecord *er = event._event._osx_event_record._event;
|
||||||
|
|
||||||
|
Point pt = er->where;
|
||||||
|
|
||||||
|
// Need to ensure we have the correct port set, in order to
|
||||||
|
// convert the mouse coordinates successfully via
|
||||||
|
// GlobalToLocal().
|
||||||
|
const P3D_window_handle &handle = _wparams.get_parent_window();
|
||||||
|
if (handle._window_handle_type == P3D_WHT_osx_port) {
|
||||||
|
GrafPtr out_port = handle._handle._osx_port._port;
|
||||||
|
GrafPtr port_save = NULL;
|
||||||
|
Boolean port_changed = QDSwapPort(out_port, &port_save);
|
||||||
|
|
||||||
|
GlobalToLocal(&pt);
|
||||||
|
|
||||||
|
if (port_changed) {
|
||||||
|
QDSwapPort(port_save, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (handle._window_handle_type == P3D_WHT_osx_cgcontext) {
|
||||||
|
// First, convert the coordinates from screen coordinates to
|
||||||
|
// browser window coordinates.
|
||||||
|
WindowRef window = handle._handle._osx_cgcontext._window;
|
||||||
|
CGPoint cgpt = { pt.h, pt.v };
|
||||||
|
HIPointConvert(&cgpt, kHICoordSpaceScreenPixel, NULL,
|
||||||
|
kHICoordSpaceWindow, window);
|
||||||
|
|
||||||
|
// Then convert to plugin coordinates.
|
||||||
|
pt.h = cgpt.x - _wparams.get_win_x();
|
||||||
|
pt.v = cgpt.y - _wparams.get_win_y();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (er->what) {
|
||||||
|
case updateEvt:
|
||||||
|
paint_window();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mouseDown:
|
||||||
|
set_mouse_data(_mouse_x, _mouse_y, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mouseUp:
|
||||||
|
set_mouse_data(_mouse_x, _mouse_y, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case activateEvt:
|
||||||
|
_mouse_active = ((er->modifiers & 1) != 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mouse_active) {
|
||||||
|
set_mouse_data(pt.h, pt.v, _mouse_down);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DOsxSplashWindow::handle_event_osx_cocoa
|
||||||
|
// Access: Private
|
||||||
|
// Description: Responds to the new Cocoa event types in Mac
|
||||||
|
// OSX.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DOsxSplashWindow::
|
||||||
|
handle_event_osx_cocoa(const P3D_event_data &event) {
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
assert(event._event_type == P3D_ET_osx_cocoa);
|
||||||
|
const P3DCocoaEvent &ce = event._event._osx_cocoa._event;
|
||||||
|
|
||||||
|
switch (ce.type) {
|
||||||
|
case P3DCocoaEventDrawRect:
|
||||||
|
if (_visible) {
|
||||||
|
CGContextRef context = ce.data.draw.context;
|
||||||
|
paint_window_osx_cgcontext(context);
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventMouseDown:
|
||||||
|
set_mouse_data(ce.data.mouse.pluginX, ce.data.mouse.pluginY, true);
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventMouseUp:
|
||||||
|
set_mouse_data(ce.data.mouse.pluginX, ce.data.mouse.pluginY, false);
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventMouseMoved:
|
||||||
|
case P3DCocoaEventMouseDragged:
|
||||||
|
set_mouse_data(ce.data.mouse.pluginX, ce.data.mouse.pluginY, _mouse_down);
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3DCocoaEventFocusChanged:
|
||||||
|
_mouse_active = (ce.data.focus.hasFocus != 0);
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -681,13 +791,8 @@ event_callback(EventHandlerCallRef my_handler, EventRef event) {
|
|||||||
sizeof(Point), NULL, (void *)&point);
|
sizeof(Point), NULL, (void *)&point);
|
||||||
|
|
||||||
GrafPtr port;
|
GrafPtr port;
|
||||||
if (_toplevel_window != NULL) {
|
assert(_toplevel_window != NULL);
|
||||||
port = GetWindowPort(_toplevel_window);
|
port = GetWindowPort(_toplevel_window);
|
||||||
} else {
|
|
||||||
const P3D_window_handle &handle = _wparams.get_parent_window();
|
|
||||||
assert(handle._window_handle_type == P3D_WHT_osx_port);
|
|
||||||
port = handle._handle._osx_port._port;
|
|
||||||
}
|
|
||||||
GrafPtr port_save = NULL;
|
GrafPtr port_save = NULL;
|
||||||
Boolean port_changed = QDSwapPort(port, &port_save);
|
Boolean port_changed = QDSwapPort(port, &port_save);
|
||||||
GlobalToLocal(&point);
|
GlobalToLocal(&point);
|
||||||
|
@ -48,6 +48,9 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void paint_window();
|
void paint_window();
|
||||||
|
void paint_window_osx_cgcontext(CGContextRef context);
|
||||||
|
bool handle_event_osx_event_record(const P3D_event_data &event);
|
||||||
|
bool handle_event_osx_cocoa(const P3D_event_data &event);
|
||||||
class OsxImageData;
|
class OsxImageData;
|
||||||
|
|
||||||
void load_image(OsxImageData &image, const string &image_filename);
|
void load_image(OsxImageData &image, const string &image_filename);
|
||||||
|
@ -204,6 +204,7 @@ typedef enum {
|
|||||||
P3D_WHT_win_hwnd,
|
P3D_WHT_win_hwnd,
|
||||||
P3D_WHT_osx_port,
|
P3D_WHT_osx_port,
|
||||||
P3D_WHT_x11_window,
|
P3D_WHT_x11_window,
|
||||||
|
P3D_WHT_osx_cgcontext,
|
||||||
} P3D_window_handle_type;
|
} P3D_window_handle_type;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -220,6 +221,15 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
} P3D_window_handle_osx_port;
|
} P3D_window_handle_osx_port;
|
||||||
|
|
||||||
|
/* A CoreGraphics handle, as used by NPAPI with
|
||||||
|
NPDrawingModelCoreGraphics in effect. */
|
||||||
|
typedef struct {
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
CGContextRef _context;
|
||||||
|
WindowRef _window;
|
||||||
|
#endif
|
||||||
|
} P3D_window_handle_osx_cgcontext;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
#if defined(HAVE_X11)
|
#if defined(HAVE_X11)
|
||||||
unsigned long _xwindow;
|
unsigned long _xwindow;
|
||||||
@ -233,6 +243,7 @@ typedef struct {
|
|||||||
P3D_window_handle_win_hwnd _win_hwnd;
|
P3D_window_handle_win_hwnd _win_hwnd;
|
||||||
P3D_window_handle_osx_port _osx_port;
|
P3D_window_handle_osx_port _osx_port;
|
||||||
P3D_window_handle_x11_window _x11_window;
|
P3D_window_handle_x11_window _x11_window;
|
||||||
|
P3D_window_handle_osx_cgcontext _osx_cgcontext;
|
||||||
} _handle;
|
} _handle;
|
||||||
} P3D_window_handle;
|
} P3D_window_handle;
|
||||||
|
|
||||||
@ -913,6 +924,7 @@ P3D_instance_feed_url_stream_func(P3D_instance *instance, int unique_id,
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
P3D_ET_none = 0,
|
P3D_ET_none = 0,
|
||||||
P3D_ET_osx_event_record,
|
P3D_ET_osx_event_record,
|
||||||
|
P3D_ET_osx_cocoa,
|
||||||
} P3D_event_type;
|
} P3D_event_type;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -921,10 +933,72 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
} P3D_event_osx_event_record;
|
} P3D_event_osx_event_record;
|
||||||
|
|
||||||
|
// This enum reimplements NPCocoaEventTyped, used below.
|
||||||
|
typedef enum {
|
||||||
|
P3DCocoaEventDrawRect = 1,
|
||||||
|
P3DCocoaEventMouseDown,
|
||||||
|
P3DCocoaEventMouseUp,
|
||||||
|
P3DCocoaEventMouseMoved,
|
||||||
|
P3DCocoaEventMouseEntered,
|
||||||
|
P3DCocoaEventMouseExited,
|
||||||
|
P3DCocoaEventMouseDragged,
|
||||||
|
P3DCocoaEventKeyDown,
|
||||||
|
P3DCocoaEventKeyUp,
|
||||||
|
P3DCocoaEventFlagsChanged,
|
||||||
|
P3DCocoaEventFocusChanged,
|
||||||
|
P3DCocoaEventWindowFocusChanged,
|
||||||
|
P3DCocoaEventScrollWheel,
|
||||||
|
P3DCocoaEventTextInput
|
||||||
|
} P3DCocoaEventType;
|
||||||
|
|
||||||
|
// This structure reimplements NPCocoaEvent, to pass the complex
|
||||||
|
// cocoa event structures as generated by NPAPI.
|
||||||
|
typedef struct {
|
||||||
|
P3DCocoaEventType type;
|
||||||
|
unsigned int version;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned int modifierFlags;
|
||||||
|
double pluginX;
|
||||||
|
double pluginY;
|
||||||
|
int buttonNumber;
|
||||||
|
int clickCount;
|
||||||
|
double deltaX;
|
||||||
|
double deltaY;
|
||||||
|
double deltaZ;
|
||||||
|
} mouse;
|
||||||
|
struct {
|
||||||
|
unsigned int modifierFlags;
|
||||||
|
const wchar_t *characters;
|
||||||
|
const wchar_t *charactersIgnoringModifiers;
|
||||||
|
bool isARepeat;
|
||||||
|
unsigned short keyCode;
|
||||||
|
} key;
|
||||||
|
struct {
|
||||||
|
CGContextRef context;
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double width;
|
||||||
|
double height;
|
||||||
|
} draw;
|
||||||
|
struct {
|
||||||
|
bool hasFocus;
|
||||||
|
} focus;
|
||||||
|
struct {
|
||||||
|
const wchar_t *text;
|
||||||
|
} text;
|
||||||
|
} data;
|
||||||
|
} P3DCocoaEvent;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
P3DCocoaEvent _event;
|
||||||
|
} P3D_event_osx_cocoa;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
P3D_event_type _event_type;
|
P3D_event_type _event_type;
|
||||||
union {
|
union {
|
||||||
P3D_event_osx_event_record _osx_event_record;
|
P3D_event_osx_event_record _osx_event_record;
|
||||||
|
P3D_event_osx_cocoa _osx_cocoa;
|
||||||
} _event;
|
} _event;
|
||||||
} P3D_event_data;
|
} P3D_event_data;
|
||||||
|
|
||||||
|
@ -107,6 +107,18 @@ struct UC_NPString {
|
|||||||
#define HAS_PLUGIN_THREAD_ASYNC_CALL 1
|
#define HAS_PLUGIN_THREAD_ASYNC_CALL 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// We also need to know whether we have Apple's new Cocoa-based
|
||||||
|
// drawing and event callbacks.
|
||||||
|
#if defined(NPVERS_MACOSX_HAS_EVENT_MODELS) && NP_VERSION_MINOR >= NPVERS_MACOSX_HAS_EVENT_MODELS
|
||||||
|
#define MACOSX_HAS_EVENT_MODELS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// No one defined a symbol for the introduction of the Cocoa drawing,
|
||||||
|
// but it appears to have been version 19.
|
||||||
|
#if NP_VERSION_MINOR >= 19
|
||||||
|
#define MACOSX_HAS_COREGRAPHICS_DRAWING_MODEL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
// Appears in startup.cxx.
|
// Appears in startup.cxx.
|
||||||
extern NPNetscapeFuncs *browser;
|
extern NPNetscapeFuncs *browser;
|
||||||
|
|
||||||
|
@ -48,11 +48,15 @@ PPInstance::FileDatas PPInstance::_file_datas;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PPInstance::
|
PPInstance::
|
||||||
PPInstance(NPMIMEType pluginType, NPP instance, uint16_t mode,
|
PPInstance(NPMIMEType pluginType, NPP instance, uint16_t mode,
|
||||||
int16_t argc, char *argn[], char *argv[], NPSavedData *saved) {
|
int16_t argc, char *argn[], char *argv[], NPSavedData *saved,
|
||||||
|
P3D_window_handle_type window_handle_type,
|
||||||
|
P3D_event_type event_type) {
|
||||||
_p3d_inst = NULL;
|
_p3d_inst = NULL;
|
||||||
|
|
||||||
_npp_instance = instance;
|
_npp_instance = instance;
|
||||||
_npp_mode = mode;
|
_npp_mode = mode;
|
||||||
|
_window_handle_type = window_handle_type;
|
||||||
|
_event_type = event_type;
|
||||||
_script_object = NULL;
|
_script_object = NULL;
|
||||||
_failed = false;
|
_failed = false;
|
||||||
_started = false;
|
_started = false;
|
||||||
@ -79,6 +83,10 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16_t mode,
|
|||||||
_got_instance_url = false;
|
_got_instance_url = false;
|
||||||
_got_window = false;
|
_got_window = false;
|
||||||
_python_window_open = false;
|
_python_window_open = false;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
_request_timer = NULL;
|
||||||
|
#endif // __APPLE__
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -90,6 +98,14 @@ PPInstance::
|
|||||||
~PPInstance() {
|
~PPInstance() {
|
||||||
cleanup_window();
|
cleanup_window();
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (_request_timer != NULL) {
|
||||||
|
CFRunLoopTimerInvalidate(_request_timer);
|
||||||
|
CFRelease(_request_timer);
|
||||||
|
_request_timer = NULL;
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
if (_p3d_inst != NULL) {
|
if (_p3d_inst != NULL) {
|
||||||
P3D_instance_finish(_p3d_inst);
|
P3D_instance_finish(_p3d_inst);
|
||||||
_p3d_inst = NULL;
|
_p3d_inst = NULL;
|
||||||
@ -124,7 +140,8 @@ PPInstance::
|
|||||||
void PPInstance::
|
void PPInstance::
|
||||||
begin() {
|
begin() {
|
||||||
// On Windows and Linux, we must insist on having this call. OSX
|
// On Windows and Linux, we must insist on having this call. OSX
|
||||||
// doesn't necessarily require it.
|
// doesn't necessarily require it (which is lucky, since it appears
|
||||||
|
// that Safari doesn't necessarily provide it!)
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
if (!has_plugin_thread_async_call) {
|
if (!has_plugin_thread_async_call) {
|
||||||
nout << "Browser version insufficient: we require at least NPAPI version 0.19.\n";
|
nout << "Browser version insufficient: we require at least NPAPI version 0.19.\n";
|
||||||
@ -677,17 +694,30 @@ handle_event(void *event) {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
P3D_event_data edata;
|
P3D_event_data edata;
|
||||||
memset(&edata, 0, sizeof(edata));
|
memset(&edata, 0, sizeof(edata));
|
||||||
edata._event_type = P3D_ET_osx_event_record;
|
edata._event_type = _event_type;
|
||||||
edata._event._osx_event_record._event = (EventRecord *)event;
|
EventAuxData aux_data;
|
||||||
|
if (_event_type == P3D_ET_osx_event_record) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
edata._event._osx_event_record._event = (EventRecord *)event;
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
#ifdef MACOSX_HAS_EVENT_MODELS
|
||||||
|
} else if (_event_type == P3D_ET_osx_cocoa) {
|
||||||
|
// Copy the NPCocoaEvent structure componentwise into a
|
||||||
|
// P3DCocoaEvent structure.
|
||||||
|
NPCocoaEvent *np_event = (NPCocoaEvent *)event;
|
||||||
|
P3DCocoaEvent *p3d_event = &edata._event._osx_cocoa._event;
|
||||||
|
copy_cocoa_event(p3d_event, np_event, aux_data);
|
||||||
|
#endif // MACOSX_HAS_EVENT_MODELS
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (P3D_instance_handle_event(_p3d_inst, &edata)) {
|
if (P3D_instance_handle_event(_p3d_inst, &edata)) {
|
||||||
retval = true;
|
retval = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __APPLE__
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -962,14 +992,18 @@ request_ready(P3D_instance *instance) {
|
|||||||
PPInstance *inst = (PPInstance *)(instance->_user_data);
|
PPInstance *inst = (PPInstance *)(instance->_user_data);
|
||||||
assert(inst != NULL);
|
assert(inst != NULL);
|
||||||
|
|
||||||
|
{
|
||||||
|
static int n = 0;
|
||||||
|
nout << "request_ready " << ++n << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (has_plugin_thread_async_call) {
|
if (has_plugin_thread_async_call) {
|
||||||
#ifdef HAS_PLUGIN_THREAD_ASYNC_CALL
|
#ifdef HAS_PLUGIN_THREAD_ASYNC_CALL
|
||||||
// Since we are running at least Gecko 1.9, and we have this very
|
// Since we are running at least Gecko 1.9, and we have this very
|
||||||
// useful function, let's use it to ask the browser to call us back
|
// useful function, let's use it to ask the browser to call us back
|
||||||
// in the main thread.
|
// in the main thread.
|
||||||
if ((void *)browser->pluginthreadasynccall != (void *)NULL) {
|
assert((void *)browser->pluginthreadasynccall != (void *)NULL);
|
||||||
browser->pluginthreadasynccall(inst->_npp_instance, browser_sync_callback, NULL);
|
browser->pluginthreadasynccall(inst->_npp_instance, browser_sync_callback, NULL);
|
||||||
}
|
|
||||||
#endif // HAS_PLUGIN_THREAD_ASYNC_CALL
|
#endif // HAS_PLUGIN_THREAD_ASYNC_CALL
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -986,8 +1020,28 @@ request_ready(P3D_instance *instance) {
|
|||||||
PostMessage((HWND)(win->window), WM_USER, 0, 0);
|
PostMessage((HWND)(win->window), WM_USER, 0, 0);
|
||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
// On Mac and Linux, we ignore this asynchronous event, and rely on
|
|
||||||
// detecting it within HandleEvent() and similar callbacks.
|
#ifdef __APPLE__
|
||||||
|
// Use an OSX timer to forward this event to the main thread.
|
||||||
|
|
||||||
|
// Stop any previously-started timer--we don't need more than one.
|
||||||
|
if (inst->_request_timer != NULL) {
|
||||||
|
CFRunLoopTimerInvalidate(inst->_request_timer);
|
||||||
|
CFRelease(inst->_request_timer);
|
||||||
|
inst->_request_timer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// And start a new one.
|
||||||
|
CFRunLoopTimerContext timer_context;
|
||||||
|
memset(&timer_context, 0, sizeof(timer_context));
|
||||||
|
timer_context.info = inst;
|
||||||
|
inst->_request_timer = CFRunLoopTimerCreate
|
||||||
|
(NULL, 0, 0, 0, 0, timer_callback, &timer_context);
|
||||||
|
CFRunLoopRef run_loop = CFRunLoopGetMain();
|
||||||
|
CFRunLoopAddTimer(run_loop, inst->_request_timer, kCFRunLoopCommonModes);
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
// Doesn't appear to be a reliable way to simulate this in Linux.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1380,14 +1434,17 @@ send_window() {
|
|||||||
y = 0;
|
y = 0;
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
NP_Port *port = (NP_Port *)_window.window;
|
parent_window._window_handle_type = _window_handle_type;
|
||||||
parent_window._window_handle_type = P3D_WHT_osx_port;
|
if (_window_handle_type == P3D_WHT_osx_port) {
|
||||||
parent_window._handle._osx_port._port = port->port;
|
NP_Port *port = (NP_Port *)_window.window;
|
||||||
/*
|
parent_window._handle._osx_port._port = port->port;
|
||||||
NP_CGContext *context = (NP_CGContext *)_window.window;
|
} else if (_window_handle_type == P3D_WHT_osx_cgcontext) {
|
||||||
parent_window._context = context->context;
|
NP_CGContext *context = (NP_CGContext *)_window.window;
|
||||||
parent_window._window = (WindowRef)context->window;
|
if (context != NULL) {
|
||||||
*/
|
parent_window._handle._osx_cgcontext._context = context->context;
|
||||||
|
parent_window._handle._osx_cgcontext._window = (WindowRef)context->window;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(HAVE_X11)
|
#elif defined(HAVE_X11)
|
||||||
// We make it an 'unsigned long' instead of 'Window'
|
// We make it an 'unsigned long' instead of 'Window'
|
||||||
@ -1410,14 +1467,17 @@ send_window() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
NP_Port *port = (NP_Port *)_window.window;
|
parent_window._window_handle_type = _window_handle_type;
|
||||||
parent_window._window_handle_type = P3D_WHT_osx_port;
|
if (_window_handle_type == P3D_WHT_osx_port) {
|
||||||
parent_window._handle._osx_port._port = port->port;
|
NP_Port *port = (NP_Port *)_window.window;
|
||||||
/*
|
parent_window._handle._osx_port._port = port->port;
|
||||||
NP_CGContext *context = (NP_CGContext *)_window.window;
|
} else if (_window_handle_type == P3D_WHT_osx_cgcontext) {
|
||||||
parent_window._context = context->context;
|
NP_CGContext *context = (NP_CGContext *)_window.window;
|
||||||
parent_window._window = (WindowRef)context->window;
|
if (context != NULL) {
|
||||||
*/
|
parent_window._handle._osx_cgcontext._context = context->context;
|
||||||
|
parent_window._handle._osx_cgcontext._window = (WindowRef)context->window;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(HAVE_X11)
|
#elif defined(HAVE_X11)
|
||||||
unsigned long win;
|
unsigned long win;
|
||||||
@ -1440,7 +1500,7 @@ send_window() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
P3D_window_type window_type = P3D_WT_embedded;
|
P3D_window_type window_type = P3D_WT_embedded;
|
||||||
if (_window.window == NULL) {
|
if (_window.window == NULL && _event_type != P3D_ET_osx_cocoa) {
|
||||||
// No parent window: it must be a hidden window.
|
// No parent window: it must be a hidden window.
|
||||||
window_type = P3D_WT_hidden;
|
window_type = P3D_WT_hidden;
|
||||||
} else if (_window.width == 0 || _window.height == 0) {
|
} else if (_window.width == 0 || _window.height == 0) {
|
||||||
@ -1654,6 +1714,156 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#ifdef MACOSX_HAS_EVENT_MODELS
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::copy_cocoa_event
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: Copies the NPCocoaEvent structure componentwise into
|
||||||
|
// a P3DCocoaEvent structure, for passing into the core
|
||||||
|
// API.
|
||||||
|
//
|
||||||
|
// The aux_data object is used to manage temporary
|
||||||
|
// storage on the strings created for the event.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PPInstance::
|
||||||
|
copy_cocoa_event(P3DCocoaEvent *p3d_event, NPCocoaEvent *np_event,
|
||||||
|
EventAuxData &aux_data) {
|
||||||
|
p3d_event->version = np_event->version;
|
||||||
|
|
||||||
|
switch (np_event->type) {
|
||||||
|
case NPCocoaEventDrawRect:
|
||||||
|
p3d_event->type = P3DCocoaEventDrawRect;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventMouseDown:
|
||||||
|
p3d_event->type = P3DCocoaEventMouseDown;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventMouseUp:
|
||||||
|
p3d_event->type = P3DCocoaEventMouseUp;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventMouseMoved:
|
||||||
|
p3d_event->type = P3DCocoaEventMouseMoved;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventMouseEntered:
|
||||||
|
p3d_event->type = P3DCocoaEventMouseEntered;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventMouseExited:
|
||||||
|
p3d_event->type = P3DCocoaEventMouseExited;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventMouseDragged:
|
||||||
|
p3d_event->type = P3DCocoaEventMouseDragged;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventKeyDown:
|
||||||
|
p3d_event->type = P3DCocoaEventKeyDown;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventKeyUp:
|
||||||
|
p3d_event->type = P3DCocoaEventKeyUp;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventFlagsChanged:
|
||||||
|
p3d_event->type = P3DCocoaEventFlagsChanged;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventFocusChanged:
|
||||||
|
p3d_event->type = P3DCocoaEventFocusChanged;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventWindowFocusChanged:
|
||||||
|
p3d_event->type = P3DCocoaEventWindowFocusChanged;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventScrollWheel:
|
||||||
|
p3d_event->type = P3DCocoaEventScrollWheel;
|
||||||
|
break;
|
||||||
|
case NPCocoaEventTextInput:
|
||||||
|
p3d_event->type = P3DCocoaEventTextInput;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (np_event->type) {
|
||||||
|
case NPCocoaEventDrawRect:
|
||||||
|
p3d_event->data.draw.context = np_event->data.draw.context;
|
||||||
|
p3d_event->data.draw.x = np_event->data.draw.x;
|
||||||
|
p3d_event->data.draw.y = np_event->data.draw.y;
|
||||||
|
p3d_event->data.draw.width = np_event->data.draw.width;
|
||||||
|
p3d_event->data.draw.height = np_event->data.draw.height;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NPCocoaEventMouseDown:
|
||||||
|
case NPCocoaEventMouseUp:
|
||||||
|
case NPCocoaEventMouseMoved:
|
||||||
|
case NPCocoaEventMouseEntered:
|
||||||
|
case NPCocoaEventMouseExited:
|
||||||
|
case NPCocoaEventMouseDragged:
|
||||||
|
case NPCocoaEventScrollWheel:
|
||||||
|
p3d_event->data.mouse.modifierFlags = np_event->data.mouse.modifierFlags;
|
||||||
|
p3d_event->data.mouse.pluginX = np_event->data.mouse.pluginX;
|
||||||
|
p3d_event->data.mouse.pluginY = np_event->data.mouse.pluginY;
|
||||||
|
p3d_event->data.mouse.buttonNumber = np_event->data.mouse.buttonNumber;
|
||||||
|
p3d_event->data.mouse.clickCount = np_event->data.mouse.clickCount;
|
||||||
|
p3d_event->data.mouse.deltaX = np_event->data.mouse.deltaX;
|
||||||
|
p3d_event->data.mouse.deltaY = np_event->data.mouse.deltaY;
|
||||||
|
p3d_event->data.mouse.deltaZ = np_event->data.mouse.deltaZ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NPCocoaEventKeyDown:
|
||||||
|
case NPCocoaEventKeyUp:
|
||||||
|
case NPCocoaEventFlagsChanged:
|
||||||
|
p3d_event->data.key.modifierFlags = np_event->data.key.modifierFlags;
|
||||||
|
p3d_event->data.key.characters =
|
||||||
|
make_ansi_string(aux_data._characters, np_event->data.key.characters);
|
||||||
|
p3d_event->data.key.charactersIgnoringModifiers =
|
||||||
|
make_ansi_string(aux_data._characters_im, np_event->data.key.charactersIgnoringModifiers);
|
||||||
|
p3d_event->data.key.isARepeat = np_event->data.key.isARepeat;
|
||||||
|
p3d_event->data.key.keyCode = np_event->data.key.keyCode;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NPCocoaEventFocusChanged:
|
||||||
|
case NPCocoaEventWindowFocusChanged:
|
||||||
|
p3d_event->data.focus.hasFocus = np_event->data.focus.hasFocus;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NPCocoaEventTextInput:
|
||||||
|
p3d_event->data.text.text =
|
||||||
|
make_ansi_string(aux_data._text, np_event->data.text.text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // MACOSX_HAS_EVENT_MODELS
|
||||||
|
|
||||||
|
#ifdef MACOSX_HAS_EVENT_MODELS
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::make_ansi_string
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: OSX only: Fills result with the unicode characters in
|
||||||
|
// the NPNSString. Also returns result.c_str().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const wchar_t *PPInstance::
|
||||||
|
make_ansi_string(wstring &result, NPNSString *ns_string) {
|
||||||
|
// An NPNSString is really just an NSString, which is itself just a
|
||||||
|
// CFString.
|
||||||
|
CFStringRef cfstr = (CFStringRef)ns_string;
|
||||||
|
CFIndex length = CFStringGetLength(cfstr);
|
||||||
|
|
||||||
|
result.clear();
|
||||||
|
for (CFIndex i = 0; i < length; ++i) {
|
||||||
|
result += (wchar_t)CFStringGetCharacterAtIndex(cfstr, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.c_str();
|
||||||
|
}
|
||||||
|
#endif // MACOSX_HAS_EVENT_MODELS
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::timer_callback
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: OSX only: this callback is associated with a
|
||||||
|
// CFRunLoopTimer; it's used to forward request messages
|
||||||
|
// to the main thread.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PPInstance::
|
||||||
|
timer_callback(CFRunLoopTimerRef timer, void *info) {
|
||||||
|
PPInstance *self = (PPInstance *)info;
|
||||||
|
self->handle_request_loop();
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PPInstance::StreamingFileData::Constructor
|
// Function: PPInstance::StreamingFileData::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -35,7 +35,9 @@ class PPDownloadRequest;
|
|||||||
class PPInstance {
|
class PPInstance {
|
||||||
public:
|
public:
|
||||||
PPInstance(NPMIMEType pluginType, NPP instance, uint16_t mode,
|
PPInstance(NPMIMEType pluginType, NPP instance, uint16_t mode,
|
||||||
int16_t argc, char *argn[], char *argv[], NPSavedData *saved);
|
int16_t argc, char *argn[], char *argv[], NPSavedData *saved,
|
||||||
|
P3D_window_handle_type window_handle_type,
|
||||||
|
P3D_event_type event_type);
|
||||||
~PPInstance();
|
~PPInstance();
|
||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
@ -99,9 +101,28 @@ private:
|
|||||||
window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
class EventAuxData {
|
||||||
|
public:
|
||||||
|
wstring _characters;
|
||||||
|
wstring _characters_im;
|
||||||
|
wstring _text;
|
||||||
|
};
|
||||||
|
#ifdef MACOSX_HAS_EVENT_MODELS
|
||||||
|
static void copy_cocoa_event(P3DCocoaEvent *p3d_event,
|
||||||
|
NPCocoaEvent *np_event,
|
||||||
|
EventAuxData &aux_data);
|
||||||
|
static const wchar_t *make_ansi_string(wstring &result, NPNSString *ns_string);
|
||||||
|
#endif // MACOSX_HAS_EVENT_MODELS
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static void timer_callback(CFRunLoopTimerRef timer, void *info);
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NPP _npp_instance;
|
NPP _npp_instance;
|
||||||
unsigned int _npp_mode;
|
unsigned int _npp_mode;
|
||||||
|
P3D_window_handle_type _window_handle_type;
|
||||||
|
P3D_event_type _event_type;
|
||||||
typedef vector<P3D_token> Tokens;
|
typedef vector<P3D_token> Tokens;
|
||||||
Tokens _tokens;
|
Tokens _tokens;
|
||||||
|
|
||||||
@ -165,6 +186,10 @@ private:
|
|||||||
LONG_PTR _orig_window_proc;
|
LONG_PTR _orig_window_proc;
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
CFRunLoopTimerRef _request_timer;
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
bool _python_window_open;
|
bool _python_window_open;
|
||||||
|
|
||||||
PPToplevelObject *_script_object;
|
PPToplevelObject *_script_object;
|
||||||
|
@ -194,7 +194,12 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs,
|
|||||||
#ifdef HAS_PLUGIN_THREAD_ASYNC_CALL
|
#ifdef HAS_PLUGIN_THREAD_ASYNC_CALL
|
||||||
// Check if the browser offers this very useful call.
|
// Check if the browser offers this very useful call.
|
||||||
if (browser_major > 0 || browser_minor >= NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL) {
|
if (browser_major > 0 || browser_minor >= NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL) {
|
||||||
has_plugin_thread_async_call = true;
|
if ((void *)browser->pluginthreadasynccall == (void *)NULL) {
|
||||||
|
nout << "Browser should have PLUGIN_THREAD_ASYNC_CALL, but the pointer is NULL.\n";
|
||||||
|
has_plugin_thread_async_call = false;
|
||||||
|
} else {
|
||||||
|
has_plugin_thread_async_call = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -287,30 +292,65 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode,
|
|||||||
int16_t argc, char *argn[], char *argv[], NPSavedData *saved) {
|
int16_t argc, char *argn[], char *argv[], NPSavedData *saved) {
|
||||||
nout << "new instance " << instance << "\n";
|
nout << "new instance " << instance << "\n";
|
||||||
|
|
||||||
/*
|
P3D_window_handle_type window_handle_type = P3D_WHT_none;
|
||||||
|
P3D_event_type event_type = P3D_ET_none;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// We have to request the "core graphics" drawing model to be
|
// The default drawing model for Apple is via the deprecated
|
||||||
|
// QuickDraw GrafPtr, and the default event model is via the
|
||||||
|
// deprecated Carbon EventRecord.
|
||||||
|
window_handle_type = P3D_WHT_osx_port;
|
||||||
|
event_type = P3D_ET_osx_event_record;
|
||||||
|
|
||||||
|
// But we have to request the CoreGraphics drawing model to be
|
||||||
// compatible with Snow Leopard.
|
// compatible with Snow Leopard.
|
||||||
NPBool supportsCoreGraphics = false;
|
NPBool supports_core_graphics = false;
|
||||||
|
#ifdef MACOSX_HAS_COREGRAPHICS_DRAWING_MODEL
|
||||||
NPError err = browser->getvalue(instance,
|
NPError err = browser->getvalue(instance,
|
||||||
NPNVsupportsCoreGraphicsBool,
|
NPNVsupportsCoreGraphicsBool,
|
||||||
&supportsCoreGraphics);
|
&supports_core_graphics);
|
||||||
if (err != NPERR_NO_ERROR || !supportsCoreGraphics) {
|
if (err != NPERR_NO_ERROR) {
|
||||||
return NPERR_INCOMPATIBLE_VERSION_ERROR;
|
supports_core_graphics = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the drawing model
|
if (supports_core_graphics) {
|
||||||
err = browser->setvalue(instance,
|
// Set the drawing model
|
||||||
(NPPVariable)NPNVpluginDrawingModel,
|
err = browser->setvalue(instance,
|
||||||
(void *)NPDrawingModelCoreGraphics);
|
(NPPVariable)NPNVpluginDrawingModel,
|
||||||
if (err != NPERR_NO_ERROR) {
|
(void *)NPDrawingModelCoreGraphics);
|
||||||
return NPERR_INCOMPATIBLE_VERSION_ERROR;
|
if (err == NPERR_NO_ERROR) {
|
||||||
|
window_handle_type = P3D_WHT_osx_cgcontext;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif // MACOSX_HAS_COREGRAPHICS_DRAWING_MODEL
|
||||||
*/
|
nout << "supports_core_graphics = " << (bool)supports_core_graphics
|
||||||
|
<< " window_handle_type = " << window_handle_type << "\n";
|
||||||
|
|
||||||
|
// And Snow Leopard also wants the new Cocoa event model.
|
||||||
|
NPBool supports_cocoa = false;
|
||||||
|
#ifdef MACOSX_HAS_EVENT_MODELS
|
||||||
|
err = browser->getvalue(instance, NPNVsupportsCocoaBool, &supports_cocoa);
|
||||||
|
if (err != NPERR_NO_ERROR) {
|
||||||
|
supports_cocoa = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supports_cocoa) {
|
||||||
|
// Set the event model
|
||||||
|
err = browser->setvalue(instance,
|
||||||
|
(NPPVariable)NPPVpluginEventModel,
|
||||||
|
(void *)NPEventModelCocoa);
|
||||||
|
if (err == NPERR_NO_ERROR) {
|
||||||
|
event_type = P3D_ET_osx_cocoa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // MACOSX_HAS_EVENT_MODELS
|
||||||
|
nout << "supports_cocoa = " << (bool)supports_cocoa
|
||||||
|
<< " event_type = " << event_type << "\n";
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
PPInstance *inst = new PPInstance(pluginType, instance, mode,
|
PPInstance *inst = new PPInstance(pluginType, instance, mode,
|
||||||
argc, argn, argv, saved);
|
argc, argn, argv, saved,
|
||||||
|
window_handle_type, event_type);
|
||||||
instance->pdata = inst;
|
instance->pdata = inst;
|
||||||
nout << "new instance->pdata = " << inst << "\n";
|
nout << "new instance->pdata = " << inst << "\n";
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user