/// @file LibraryKeyboardScript.lsl
/// Max Case's Free Keyboard Script 1.0 04/18/2005
///
/// Put it in a prim, attach it to yourself (or not) and watch as a
/// keyboard magically appears whenever you type. Feel free to reuse, etc.
/// Please don't just resell this script. That would be lame, since I am
/// giving it to you for free. Naturally, if you build something nice off
/// of it, sell that.
///
/// Or make a nice texture you would like to sell with keyboard script,
/// that's ok. Just leave script open to all to see.
///
/// Feedback/Rates/Donations/Hate Mail always welcome. Don't be shy.
/// leave in the comments; they don't affect performance.
/// – Max
///
/// Code comments assume that the keyboard is attached to a
/// cube primitive ('prim'), one of the simplest default objects to make. -VA
///
/// @author Max Case, 04/18/2005
/// @author Vershana Amarula, 05/26/2005
///
/// Change history
///
/// 05/26/2005-VA Tweaks, changed variable names, added comments
/// and constants
///
///
///
/// Declaration section - define and initialize all needed variables
///
/// Keeps track of who is holding the object.
key kOwner;
/// Keeps track of the last typing state detected.
integer iPrevState;
/// Opacity percentage that represents "completely transparent".
float TRANSPARENT = 0.0;
/// Time interval to wait between testing for typing activity.
float TYPING_CHECK_PERIOD = .2;
/// Value to represent the (initial) state of "not typing".
integer IS_NOT_TYPING = 0;
/// Value to represent the state of "not being held"
integer IS_NOT_HELD = -1;
/// Value to represent the state of "typing"
integer IS_TYPING = AGENT_TYPING;
// Do we have animation permissions?
integer gotPermission = FALSE;
// The key for the typing animation
key typingAnim = "c541c47f-e0c0-058b-ad1a-d6ae3a4584d9";
//typing anim name is type
// see
http://secondlife.com/badgeo/wakka.php?wakka=ClientAssetKeys and
http://secondlife.com/badgeo/wakka.php?wakka=animation string newTypingAnimation = "Dol-HoldingCards";
/// Perform all necessary operations to prepare script for use here.
initialize()
{
// During initialization, store the current owner to verify
// against later. If the owner changes, we'll reinitialize.
kOwner = llGetOwner();
// Announce startup of the script.
llOwnerSay("Sitter's keyboard responder initializing..."

;
// Make the entire box invisible (including the keyboard).
// llSetAlpha(TRANSPARENT, ALL_SIDES);
/// Set up a timer to periodically check for typing activity.
llSetTimerEvent(TYPING_CHECK_PERIOD);
// Assume that the owner is NOT typing at the time we're initialized.
iPrevState = IS_NOT_TYPING;
llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION);
}
/// All behaviors associated with the default state.
default
{
// Operations to perform when entering state "default"
state_entry()
{
// Checks to see if we have changed owner when the script starts
// and (re)initializes if so.
if(llGetOwner() != kOwner)
{
initialize();
}
}
// Operations to perform when "rezzing" (using) the object
on_rez(integer total_number)
{
// Checks for new owner when object is rezzed and (re)initializes
// if so.
if(llGetOwner() != kOwner)
{
initialize();
}
}
run_time_permissions(integer _parm) {
if( _parm == (PERMISSION_TRIGGER_ANIMATION) ) {
gotPermission = TRUE;
}
}
// Operations to perform when the amount of time set with llSetTimerEvent
// elapses
timer()
{
// Is someone holding me?
integer iAttached = llGetAttached();
if(iAttached == 0)
{
// Not attached, make myself visible so I can easily be found
// (if I haven't already)!
if(iPrevState != IS_NOT_HELD)
{
llMessageLinked(LINK_SET, -1, "SHOWKEYBOARD", NULL_KEY);
iPrevState = IS_NOT_HELD;
}
return;
}
// Are we typing? Thanks to Strife for rewrite here, though I find
// this sort of condensed logic can be confusing for non-programmer
// type, But this is definitely more efficient.
integer iTypingState = llGetAgentInfo(kOwner) & AGENT_TYPING;
// Has status changed since last checked?
if (iPrevState != iTypingState)
{
iPrevState = iTypingState;
if (iTypingState == 0) {
if (llListFindList(llGetAnimationList(kOwner), [newTypingAnimation])) {
llStopAnimation(newTypingAnimation);
}
} else {
if (llListFindList(llGetAnimationList(kOwner), [newTypingAnimation])) {
llStartAnimation(newTypingAnimation);
}
}
}
}
}