1
// Key.cpp: ActionScript "Key" class (keyboards), for Gnash.
3
// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 3 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include "smart_ptr.h" // GNASH_USE_GC
24
#include "movie_root.h"
25
#include "action.h" // for call_method
26
#include "VM.h" // for registerNative
27
#include "builtin_function.h"
28
#include "Object.h" // for getObjectInterface()
29
#include "AsBroadcaster.h" // for initializing self as a broadcaster
30
#include "namedStrings.h"
31
#include "GnashKey.h" // key::code
35
/************************************************************************
37
* This has been moved from action.cpp, when things are clean
38
* everything should have been moved up
40
************************************************************************/
42
key_as_object::key_as_object()
44
as_object(getObjectInterface()),
48
// Key is a broadcaster only in SWF6 and up (correct?)
49
int swfversion = _vm.getSWFVersion();
52
AsBroadcaster::initialize(*this);
57
key_as_object::is_key_down(int keycode)
59
if (keycode < 0 || keycode >= key::KEYCOUNT) return false;
60
if (_unreleasedKeys.test(keycode)) return true;
65
key_as_object::set_key_down(key::code code)
67
if (code >= key::KEYCOUNT) return;
69
// This is used for getAscii() of the last key event, so we store
70
// the unique gnash::key::code.
73
// Key.isDown() only cares about flash keycode, not character, so
74
// we lookup keycode to add to _unreleasedKeys.
75
size_t keycode = key::codeMap[code][key::KEY];
77
_unreleasedKeys.set(keycode, 1);
81
key_as_object::set_key_up(key::code code)
83
if (code >= key::KEYCOUNT) return;
85
// This is used for getAscii() of the last key event, so we store
86
// the unique gnash::key::code.
89
// Key.isDown() only cares about flash keycode, not character, so
90
// we lookup keycode to add to _unreleasedKeys.
91
size_t keycode = key::codeMap[code][key::KEY];
93
_unreleasedKeys.set(keycode, 0);
98
key_as_object::notify_listeners(const event_id& key_event)
100
// There is no user defined "onKeyPress" event handler
101
if( (key_event.m_id != event_id::KEY_DOWN) && (key_event.m_id != event_id::KEY_UP) ) return;
103
as_value ev(key_event.get_function_name());
105
//log_debug("notify_listeners calling broadcastMessage with arg %s", ev);
106
callMethod(NSV::PROP_BROADCAST_MESSAGE, ev);
110
key_as_object::get_last_key() const
112
return _lastKeyEvent;
116
key_is_accessible(const fn_call& fn)
119
boost::intrusive_ptr<key_as_object> ko =
120
ensureType<key_as_object>(fn.this_ptr);
122
log_unimpl("Key.isAccessible");
127
/// Return the ascii number of the last key pressed.
129
key_get_ascii(const fn_call& fn)
131
boost::intrusive_ptr<key_as_object> ko =
132
ensureType<key_as_object>(fn.this_ptr);
134
int code = ko->get_last_key();
136
return as_value(gnash::key::codeMap[code][key::ASCII]);
139
/// Returns the keycode of the last key pressed.
141
key_get_code(const fn_call& fn)
143
boost::intrusive_ptr<key_as_object> ko =
144
ensureType<key_as_object>(fn.this_ptr);
146
int code = ko->get_last_key();
148
return as_value(key::codeMap[code][key::KEY]);
151
/// Return true if the specified (first arg keycode) key is pressed.
153
key_is_down(const fn_call& fn)
155
boost::intrusive_ptr<key_as_object> ko =
156
ensureType<key_as_object>(fn.this_ptr);
160
IF_VERBOSE_ASCODING_ERRORS(
161
log_aserror(_("Key.isDown needs one argument (the key code)"));
166
int keycode = fn.arg(0).to_int();
168
return as_value(ko->is_key_down(keycode));
172
/// Given the keycode of NUM_LOCK or CAPSLOCK, returns true if
173
/// the associated state is on.
176
key_is_toggled(const fn_call& /* fn */)
178
log_unimpl("Key.isToggled");
180
return as_value(false);
183
void key_class_init(as_object& global)
186
// GNASH_REPORT_FUNCTION;
189
// Create built-in key object.
190
// NOTE: _global.Key *is* an object, not a constructor
191
as_object* key_obj = new key_as_object;
193
const int flags = as_prop_flags::readOnly |
194
as_prop_flags::dontDelete |
195
as_prop_flags::dontEnum;
198
#define KEY_CONST(k) key_obj->init_member(#k, key::codeMap[key::k][key::KEY], flags)
199
KEY_CONST(BACKSPACE);
202
KEY_CONST(DELETEKEY);
221
VM& vm = global.getVM();
223
vm.registerNative(key_get_ascii, 800, 0);
224
key_obj->init_member("getAscii", vm.getNative(800, 0), flags);
226
vm.registerNative(key_get_code, 800, 1);
227
key_obj->init_member("getCode", vm.getNative(800, 1), flags);
229
vm.registerNative(key_is_down, 800, 2);
230
key_obj->init_member("isDown", vm.getNative(800, 2), flags);
232
vm.registerNative(key_is_toggled, 800, 3);
233
key_obj->init_member("isToggled", vm.getNative(800, 3), flags);
235
key_obj->init_member("isAccessible",
236
new builtin_function(key_is_accessible), flags);
238
global.init_member("Key", key_obj);
243
key_as_object::markReachableResources() const
245
markAsObjectReachable();
246
for (Listeners::const_iterator i=_listeners.begin(), e=_listeners.end();
249
(*i)->setReachable();
252
#endif // def GNASH_USE_GC
254
} // end of gnash namespace