Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

12/6/2015

Chapter15.guacamolecommonjs

Chapter15.guacamolecommonjs
TheGuacamoleprojectprovidesaJavaScriptAPIforinterfacingwithothercomponentsthatconformtothe
designofGuacamole,suchasprojectsusinglibguacorguacamolecommon.ThisAPIiscalledguacamole
commonjs.
guacamolecommonjs provides a JavaScript implementation of a Guacamole client, as well as tunneling
mechanismsforgettingprotocoldataoutofJavaScriptandintoguacdortheserversideofawebapplication.
Forconvenience,italsoprovidesmouseandkeyboardabstractionobjectsthattranslateJavaScriptmouse,
touch,andkeyboardeventsintoconsistentdatathatGuacamolecanmoreeasilydigest.Theextendableon
screenkeyboardthatwasdevelopedfortheGuacamolewebapplicationisalsoincluded.

Guacamoleclient
ThemainbenefittousingtheJavaScriptAPIisthefullGuacamoleclientimplementation,whichimplements
all Guacamole instructions, and makes use of the tunnel implementations provided by both the JavaScript
andJavaAPIs.
UsingtheGuacamoleclientisstraightforward.Theclient,likeallotherobjectswithintheJavaScriptAPI,is
withintheGuacamolenamespace.Itisinstantiatedgivenanexisting,unconnectedtunnel:
varclient=newGuacamole.Client(tunnel);
Onceyouhavetheclient,itwon'timmediatelyappearwithintheDOM.Youneedtoadditsdisplayelement
manually:
document.body.appendChild(client.getDisplay().getElement());
Atthispoint,theclientwillbevisible,renderingallupdatesassoonastheyarereceivedthroughthetunnel.
client.connect();
Itispossibletopassarbitrarydatatothetunnelduringconnectionwhichcanbeusedforauthenticationorfor
choosingaparticularconnection.Whentheconnect()function of the Guacamole client is called, it in turn
callstheconnect()functionofthetunneloriginallygiventotheclient,establishingaconnection.

Important
When creating the Guacamole.Client, the tunnel used must not already be connected. The
Guacamole.Clientwillcalltheconnect()functionforyouwhenitsownconnect()functionis
invoked. If the tunnel is already connected when it is given to the Guacamole.Client,
connectionmaynotworkatall.

In general, all instructions available within the Guacamole protocol are automatically handled by the
Guacamole client, including instructions related to audio and video. The only instructions which you must
handleyourselfare"name"(usedtonametheconnection),"clipboard"(usedtoupdateclipboarddataonthe
client side), and "error" (used when something goes wrong serverside). Each of these instructions has a
correspondingeventhandler you need only supply functions to handle these events. If any of these event
http://guacdev.org/doc/gug/guacamolecommonjs.html

1/6

12/6/2015

Chapter15.guacamolecommonjs

handlersareleftunset,thecorrespondinginstructionsaresimplyignored.

HTTPtunnel
Both the Java and JavaScript API implement corresponding ends of an HTTP tunnel, based on
XMLHttpRequest.
Thetunnelisatruestreamthereisnopolling.AninitialrequestismadefromtheJavaScriptside,andthis
requestishandledontheJavaside.Whilethisrequestisopen,dataisstreamedalongtheconnection,and
instructionswithinthisstreamarehandledassoonastheyarereceivedbytheclient.
While data is being streamed along this existing connection, a second connection attempt is made. Data
continues to be streamed along the original connection until the server receives and handles the second
request,atwhichpointtheoriginalconnectionclosesandthestreamistransferredtothenewconnection.
This process repeats, alternating between active streams, thus creating an unbroken sequence of
instructions,whilealsoallowingJavaScripttofreeanymemoryusedbythepreviouslyactiveconnection.
ThetunneliscreatedbysupplyingtherelativeURLtotheserversidetunnelservlet:
vartunnel=newGuacamole.Tunnel("tunnel");
Oncecreated,thetunnelcanbepassedtoaGuacamole.ClientforuseinaGuacamoleconnection.
The tunnel actually takes care of the Guacamole protocol parsing on behalf of the client, triggering
"oninstruction"eventsforeveryinstructionreceived,splittingeachelementintoelementsofanarraysothat
theclientdoesn'thaveto.

Inputabstraction
Browsers can be rather finicky when it comes to keyboard and mouse input, not to mention touch events.
Thereislittleagreementonwhichkeyboardeventsgetfiredwhen,andwhatdetailabouttheeventismade
availabletoJavaScript.Touchandmouseeventscanalsocauseconfusion,asmostbrowserswillgenerate
both events when the user touches the screen (for compatibility with JavaScript code that only handles
mouseevents),makingitmoredifficultforapplicationstosupportbothmouseandtouchindependently.
The Guacamole JavaScript API abstracts mouse, keyboard, and touch interaction, providing several helper
objectswhichactasanabstractinterfacebetweenyouandthebrowserevents.

Mouse
Mouse event abstraction is provided by the Guacamole.Mouse object. Given an arbitrary DOM element,
Guacamole.Mouse triggers onmousedown, onmousemove, and onmouseup events which are consistent
acrossbrowsers.Thisobjectonlyresponse.totruemouseevents.Mouseeventswhichareactuallytheresult
oftoucheventsareignored.
varelement=document.getElementById("somearbitraryid");
varmouse=newGuacamole.Mouse(element);
mouse.onmousedown=
mouse.onmousemove=
mouse.onmouseup=function(state){
//Dosomethingwiththemousestatereceived...
};
ThehandlesofeacheventaregivenaninstanceofGuacamole.Mouse.Statewhichrepresentsthecurrent
state of the mouse, containing the state of each button (including the scroll wheel) as well as the X and Y
http://guacdev.org/doc/gug/guacamolecommonjs.html

2/6

12/6/2015

Chapter15.guacamolecommonjs

coordinatesofthepointerinpixels.

Touch
Touch event abstraction is provided by either Guacamole.Touchpad (emulates a touchpad to generate
artificial mouse events) or Guacamole.Touchscreen (emulates a touchscreen, again generating artificial
mouseevents).Guacamoleusesthetouchpademulation,asthisprovidesthemostflexibilityandmouselike
features,includingscrollwheelandclickingwithdifferentbuttons,butyourpreferencesmaydiffer.
varelement=document.getElementById("somearbitraryid");
vartouch=newGuacamole.Touchpad(element);//orGuacamole.Touchscreen
touch.onmousedown=
touch.onmousemove=
touch.onmouseup=function(state){
//Dosomethingwiththemousestatereceived...
};
Note that even though these objects are touchspecific, they still provide mouse events. The state object
giventotheeventhandlersofeacheventisstillaninstanceofGuacamole.Mouse.State.
Ultimately, you could assign the same event handler to all the events of both an instance of
Guacamole.MouseaswellasGuacamole.TouchscreenorGuacamole.Touchpad,andyouwouldmagically
gain mouse and touch support. This support, being driven by the needs of remote desktop, is naturally
geared around the mouse and providing a reasonable means of interacting with it. For an actual mouse,
eventsaretranslatedsimplyandliterally,whiletoucheventsgothroughadditionalemulationandheuristics.
Fromtheperspectiveoftheuserandthecode,thisisalltransparent.

Keyboard
Keyboard events in Guacamole are abstracted with the Guacamole.Keyboard object as only keyup and
keydown events there is no keypress like there is in JavaScript. Further, all the craziness of keycodes vs.
scancodesvs.keyidentifiersnormallypresentacrossbrowsersisabstractedaway.Allyoureventhandlers
willseeisanX11keysym,whichrepresenteverykeyunambiguously.Conveniently,X11keysymsarealso
whattheGuacamoleprotocolrequires,soifyouwanttouseGuacamole.Keyboardtodrivekeyeventssent
overtheGuacamoleprotocol,everythingcanbeconnecteddirectly.
Just like the other input abstraction objects, Guacamole.Keyboard requires a DOM element as an event
target.Onlykeyeventsdirectedatthiselementwillbehandled.
varkeyboard=newGuacamole.Keyboard(document);
keyboard.onkeydown=function(keysym){
//Dosomething...
};
keyboard.onkeyup=function(keysym){
//Dosomething...
};
In this case, we are using document as the event target, thus receiving all key events while the browser
window(ortab)hasfocus.

Onscreenkeyboard
The

Guacamole

JavaScript

http://guacdev.org/doc/gug/guacamolecommonjs.html

API

also

provides

an

extendable

onscreen

keyboard,
3/6

12/6/2015

Chapter15.guacamolecommonjs

Guacamole.OnScreenKeyboard,whichrequirestheURLofanXMLfiledescribingthekeyboardlayout.The
onscreen keyboard object provides no hardcoded layout information the keyboard layout is described
entirelywithintheXMLlayoutfile.

Keyboardlayouts
The keyboard layout XML included in the Guacamole web application would be a good place to start
regardinghowtheselayoutfilesarewritten,butingeneral,thekeyboardissimplyasetofrowsorcolumns,
denotedwith<row>and<column>tagsrespectively,whereeachcanbenestedwithintheotherasdesired.
Each key is represented with a <key> tag, but this is not what the user sees, nor what generates the key
event. Each key contains any number of <cap>tags, which represent the visible part of the key. The cap
describes which X11 keysym will be sent when the key is pressed. Each cap can be associated with any
combinationofarbitrarymodifierflagswhichdictatewhenthatcapisactive.
Forexample:
<keyboardlang="en_US"layout="example"size="5">
<row>
<keysize="4">
<capmodifier="shift"keysym="0xFFE1">Shift</cap>
</key>
<key>
<cap>a</cap>
<capif="shift">A</cap>
</key>
</row>
</keyboard>
Here we have a very simple keyboard which defines only two keys: "shift" (a modifier) and the letter "a".
When"shift"ispressed,itsetsthe"shift"modifier,affectingotherkeysinthekeyboard.The"a"keyhastwo
caps:onelowercase(thedefault)andoneuppercase(whichrequirestheshiftmodifiertobeactive).
Noticethattheshiftkeyneededthekeysymexplicitlyspecified,whilethe"a"keydidnot.Thisisbecausethe
onscreen keyboard will automatically derive the correct keysym from the text of the key cap if the text
containsonlyasinglecharacter.

Displayingthekeyboard
Onceyouhaveakeyboardlayoutavailable,addinganonscreenkeyboardtoyourapplicationissimple:
//Addkeyboardtobody
varkeyboard=newGuacamole.OnScreenKeyboard("path/to/layout.xml");
document.body.appendChild(keyboard.getElement());
//Setsizeofkeyboardto100pixels
keyboard.resize(100);
Here,wehaveexplicitlyspecifiedthewidthofthekeyboardas100pixels.Normally,youwoulddeterminethis
byinspectingthewidthofthecontainingcomponent,orbydecidingonareasonablewidthbeforehand.Once
thewidthisgiven,theheightofthekeyboardisdeterminedbasedonthearrangementofeachrow.

Stylingthekeyboard
While the Guacamole.OnScreenKeyboard object will handle most of the layout, you will still need to style
everything yourself with CSS to get the elements to render properly and the keys to change state when
clicked or activated. It defines several CSS classes, which you will need to manually style to get things
lookingasdesired:
http://guacdev.org/doc/gug/guacamolecommonjs.html

4/6

12/6/2015

Chapter15.guacamolecommonjs

guackeyboard
This class is assigned to the root element containing the entire keyboard, returned by
getElement(),
guackeyboardrow
Assignedtothedivelementswhichcontaineachrow.
guackeyboardcolumn
Assignedtothedivelementswhichcontaineachcolumn.
guackeyboardgap
Assignedtoanydivelementscreatedasaresultof<gap>tagsinthekeyboardlayout.<gap>tags
areintendedtobehaveaskeyswithnovisiblestylingorcaps.
guackeyboardkeycontainer
Assigned to the div element which contains a key, and provides that key with its required
dimensions.ItisthiselementthatwillbescaledrelativetothesizespecifiedinthelayoutXMLand
thesizegiventotheresize()function.
guackeyboardkey
Assigned to the div element which represents the actual key, not the cap. This element will not
directlycontaintext,butitwillcontainallcapsthatthiskeycanhave.WithcleverCSSrules,youcan
takeadvantageofthisandcauseinactivecapstoappearonthekeyinacorner(forexample), or
hidethementirely.
guackeyboardcap
Assignedtothedivelementrepresentingakeycap.Eachcapisachildofitscorresponding key,
anditisuptotheauthoroftheCSSrulestohideorshoworrepositioneachcapappropriately.Each
capwillcontainthedisplaytextdefinedwithinthe<cap>elementinthelayoutXML.
guackeyboardrequires MODIFIER
Addedtothecapelementwhenthatcaprequiresaspecificmodifier.
guackeyboarduses MODIFIER
Addedtothekeyelementwhenanycapcontainedwithinitrequiresaspecificmodifier.
guackeyboardmodifier MODIFIER
Added to and removed from the root keyboard element when a modifier key is activated or
deactivatedrespectively.
guackeyboardpressed
Addedtoandremovedfromanykeyelementasitispressedandreleasedrespectively.

Important
TheCSSrulesrequiredfortheonscreenkeyboardtoworkasexpectedcanbequitecomplex.
LookingovertheCSSrulesusedbytheonscreenkeyboardintheGuacamolewebapplication
wouldbeagoodplacetostarttoseehowtheappearanceofeachkeycanbedriventhrough
thesimpleclasschangesdescribedabove.
InspectingtheelementsofanactiveonscreenkeyboardwithintheGuacamolewebapplication
withthedevelopertoolsofyourfavoritebrowserisalsoagoodidea.
http://guacdev.org/doc/gug/guacamolecommonjs.html

5/6

12/6/2015

Chapter15.guacamolecommonjs

Handlingkeyevents
KeyeventsgeneratedbytheonscreenkeyboardareidenticaltothoseofGuacamole.Keyboardinthatthey
consistonlyofasingleX11keysym.Onlykeyupandkeydowneventsexist,asbeforethereisnokeypress
event.
//AssumingwehaveaninstanceofGuacamole.OnScreenKeyboardalready
//called"keyboard"
keyboard.onkeydown=function(keysym){
//Dosomething...
};
keyboard.onkeyup=function(keysym){
//Dosomething...
};

http://guacdev.org/doc/gug/guacamolecommonjs.html

6/6

You might also like