guacd chapter 15
DESCRIPTION
freeTRANSCRIPT
-
12/6/2015 Chapter15.guacamolecommonjs
http://guacdev.org/doc/gug/guacamolecommonjs.html 1/6
Chapter15.guacamolecommonjsTheGuacamoleprojectprovidesaJavaScriptAPIforinterfacingwithothercomponentsthatconformtothedesignofGuacamole,suchasprojectsusinglibguacorguacamolecommon.ThisAPIiscalledguacamolecommonjs.
guacamolecommonjs provides a JavaScript implementation of a Guacamole client, as well as tunnelingmechanismsforgettingprotocoldataoutofJavaScriptandintoguacdortheserversideofawebapplication.
Forconvenience,italsoprovidesmouseandkeyboardabstractionobjectsthattranslateJavaScriptmouse,touch,andkeyboardeventsintoconsistentdatathatGuacamolecanmoreeasilydigest.TheextendableonscreenkeyboardthatwasdevelopedfortheGuacamolewebapplicationisalsoincluded.
GuacamoleclientThemainbenefittousingtheJavaScriptAPIisthefullGuacamoleclientimplementation,whichimplementsallGuacamole instructions,andmakesuseof the tunnel implementationsprovidedbyboth theJavaScriptandJavaAPIs.
UsingtheGuacamoleclient isstraightforward.Theclient, likeallotherobjectswithin theJavaScriptAPI, iswithintheGuacamolenamespace.Itisinstantiatedgivenanexisting,unconnectedtunnel:
varclient=newGuacamole.Client(tunnel);
Onceyouhavetheclient,itwon'timmediatelyappearwithintheDOM.Youneedtoadditsdisplayelementmanually:
document.body.appendChild(client.getDisplay().getElement());
Atthispoint,theclientwillbevisible,renderingallupdatesassoonastheyarereceivedthroughthetunnel.
client.connect();
Itispossibletopassarbitrarydatatothetunnelduringconnectionwhichcanbeusedforauthenticationorforchoosingaparticularconnection.Whentheconnect()functionof theGuacamoleclient iscalled, it in turncallstheconnect()functionofthetunneloriginallygiventotheclient,establishingaconnection.
Important
Whencreating theGuacamole.Client, the tunnelusedmustnotalreadybeconnected.TheGuacamole.Clientwillcalltheconnect()functionforyouwhenitsownconnect()functionisinvoked. 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 theGuacamole client, including instructions related to audio and video. The only instructionswhich youmusthandleyourselfare"name"(usedtonametheconnection),"clipboard"(usedtoupdateclipboarddataontheclient side), and "error" (usedwhen something goeswrong serverside). Each of these instructions has acorrespondingeventhandleryouneedonlysupply functions tohandle theseevents. Ifanyof theseevent
-
12/6/2015 Chapter15.guacamolecommonjs
http://guacdev.org/doc/gug/guacamolecommonjs.html 2/6
handlersareleftunset,thecorrespondinginstructionsaresimplyignored.
HTTPtunnelBoth the Java and JavaScript API implement corresponding ends of an HTTP tunnel, based onXMLHttpRequest.
Thetunnelisatruestreamthereisnopolling.AninitialrequestismadefromtheJavaScriptside,andthisrequestishandledontheJavaside.Whilethisrequestisopen,dataisstreamedalongtheconnection,andinstructionswithinthisstreamarehandledassoonastheyarereceivedbytheclient.
While data is being streamed along this existing connection, a second connection attempt ismade. Datacontinues to be streamed along the original connection until the server receives and handles the secondrequest,atwhichpointtheoriginalconnectionclosesandthestreamistransferredtothenewconnection.
This process repeats, alternating between active streams, thus creating an unbroken sequence ofinstructions,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,splittingeachelementintoelementsofanarraysothattheclientdoesn'thaveto.
InputabstractionBrowserscanbe rather finickywhen it comes tokeyboardandmouse input,not tomention touchevents.Thereislittleagreementonwhichkeyboardeventsgetfiredwhen,andwhatdetailabouttheeventismadeavailabletoJavaScript.Touchandmouseeventscanalsocauseconfusion,asmostbrowserswillgenerateboth events when the user touches the screen (for compatibility with JavaScript code that only handlesmouseevents),makingitmoredifficultforapplicationstosupportbothmouseandtouchindependently.
TheGuacamoleJavaScriptAPIabstractsmouse,keyboard,andtouch interaction,providingseveralhelperobjectswhichactasanabstractinterfacebetweenyouandthebrowserevents.
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 consistentacrossbrowsers.Thisobjectonlyresponse.totruemouseevents.Mouseeventswhichareactuallytheresultoftoucheventsareignored.
varelement=document.getElementById("somearbitraryid");varmouse=newGuacamole.Mouse(element);
mouse.onmousedown=mouse.onmousemove=mouse.onmouseup=function(state){
//Dosomethingwiththemousestatereceived...
};
ThehandlesofeacheventaregivenaninstanceofGuacamole.Mouse.Statewhichrepresentsthecurrentstateof themouse,containing thestateofeachbutton (including thescrollwheel)aswellas theXandY
-
12/6/2015 Chapter15.guacamolecommonjs
http://guacdev.org/doc/gug/guacamolecommonjs.html 3/6
coordinatesofthepointerinpixels.
Touch
Touch event abstraction is provided by either Guacamole.Touchpad (emulates a touchpad to generateartificial mouse events) or Guacamole.Touchscreen (emulates a touchscreen, again generating artificialmouseevents).Guacamoleusesthetouchpademulation,asthisprovidesthemostflexibilityandmouselikefeatures,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 providemouse events. The state objectgiventotheeventhandlersofeacheventisstillaninstanceofGuacamole.Mouse.State.
Ultimately, you could assign the same event handler to all the events of both an instance ofGuacamole.MouseaswellasGuacamole.TouchscreenorGuacamole.Touchpad,andyouwouldmagicallygain mouse and touch support. This support, being driven by the needs of remote desktop, is naturallygeared around themouse and providing a reasonablemeans of interactingwith it. For an actualmouse,eventsaretranslatedsimplyandliterally,whiletoucheventsgothroughadditionalemulationandheuristics.Fromtheperspectiveoftheuserandthecode,thisisalltransparent.
Keyboard
Keyboard events in Guacamole are abstracted with the Guacamole.Keyboard object as only keyup andkeydownevents there isnokeypress like there is inJavaScript.Further,all thecrazinessofkeycodesvs.scancodesvs.keyidentifiersnormallypresentacrossbrowsersisabstractedaway.AllyoureventhandlerswillseeisanX11keysym,whichrepresenteverykeyunambiguously.Conveniently,X11keysymsarealsowhattheGuacamoleprotocolrequires,soifyouwanttouseGuacamole.KeyboardtodrivekeyeventssentovertheGuacamoleprotocol,everythingcanbeconnecteddirectly.
Just like the other input abstraction objects, Guacamole.Keyboard requires a DOM element as an eventtarget.Onlykeyeventsdirectedatthiselementwillbehandled.
varkeyboard=newGuacamole.Keyboard(document);
keyboard.onkeydown=function(keysym){//Dosomething...};
keyboard.onkeyup=function(keysym){//Dosomething...};
In this case,we are usingdocument as the event target, thus receiving all key eventswhile the browserwindow(ortab)hasfocus.
OnscreenkeyboardThe Guacamole JavaScript API also provides an extendable onscreen keyboard,
-
12/6/2015 Chapter15.guacamolecommonjs
http://guacdev.org/doc/gug/guacamolecommonjs.html 4/6
Guacamole.OnScreenKeyboard,whichrequirestheURLofanXMLfiledescribingthekeyboardlayout.Theonscreen keyboard object provides no hardcoded layout information the keyboard layout is describedentirelywithintheXMLlayoutfile.
Keyboardlayouts
The keyboard layout XML included in the Guacamole web application would be a good place to startregardinghowtheselayoutfilesarewritten,butingeneral,thekeyboardissimplyasetofrowsorcolumns,denotedwithandtagsrespectively,whereeachcanbenestedwithintheotherasdesired.
Eachkey is representedwitha tag,but this isnotwhat theusersees,norwhatgenerates thekeyevent.Eachkeycontainsanynumberoftags,which represent the visiblepart of the key.ThecapdescribeswhichX11keysymwill besentwhen thekey ispressed.Each cap canbeassociatedwithanycombinationofarbitrarymodifierflagswhichdictatewhenthatcapisactive.
Forexample:
ShiftaA
Herewe have a very simple keyboardwhich defines only two keys: "shift" (amodifier) and the letter "a".When"shift"ispressed,itsetsthe"shift"modifier,affectingotherkeysinthekeyboard.The"a"keyhastwocaps:onelowercase(thedefault)andoneuppercase(whichrequirestheshiftmodifiertobeactive).
Noticethattheshiftkeyneededthekeysymexplicitlyspecified,whilethe"a"keydidnot.Thisisbecausetheonscreen keyboard will automatically derive the correct keysym from the text of the key cap if the textcontainsonlyasinglecharacter.
Displayingthekeyboard
Onceyouhaveakeyboardlayoutavailable,addinganonscreenkeyboardtoyourapplicationissimple:
//Addkeyboardtobodyvarkeyboard=newGuacamole.OnScreenKeyboard("path/to/layout.xml");document.body.appendChild(keyboard.getElement());
//Setsizeofkeyboardto100pixelskeyboard.resize(100);
Here,wehaveexplicitlyspecifiedthewidthofthekeyboardas100pixels.Normally,youwoulddeterminethisbyinspectingthewidthofthecontainingcomponent,orbydecidingonareasonablewidthbeforehand.Oncethewidthisgiven,theheightofthekeyboardisdeterminedbasedonthearrangementofeachrow.
Stylingthekeyboard
While theGuacamole.OnScreenKeyboard objectwill handlemost of the layout, youwill still need to styleeverything yourself with CSS to get the elements to render properly and the keys to change state whenclicked or activated. It defines several CSS classes, which you will need to manually style to get thingslookingasdesired:
-
12/6/2015 Chapter15.guacamolecommonjs
http://guacdev.org/doc/gug/guacamolecommonjs.html 5/6
guackeyboard
This class is assigned to the root element containing the entire keyboard, returned bygetElement(),
guackeyboardrow
Assignedtothedivelementswhichcontaineachrow.
guackeyboardcolumn
Assignedtothedivelementswhichcontaineachcolumn.
guackeyboardgap
Assignedtoanydivelementscreatedasaresultoftagsinthekeyboardlayout.tagsareintendedtobehaveaskeyswithnovisiblestylingorcaps.
guackeyboardkeycontainer
Assigned to the div element which contains a key, and provides that key with its requireddimensions.ItisthiselementthatwillbescaledrelativetothesizespecifiedinthelayoutXMLandthesizegiventotheresize()function.
guackeyboardkey
Assigned to thediv elementwhich represents the actual key, not the cap. This elementwill notdirectlycontaintext,butitwillcontainallcapsthatthiskeycanhave.WithcleverCSSrules,youcantakeadvantageofthisandcauseinactivecapstoappearonthekey inacorner(forexample), orhidethementirely.
guackeyboardcap
Assignedtothedivelementrepresentingakeycap.Eachcapisachildof itscorresponding key,anditisuptotheauthoroftheCSSrulestohideorshoworrepositioneachcapappropriately.EachcapwillcontainthedisplaytextdefinedwithintheelementinthelayoutXML.
guackeyboardrequires MODIFIER
Addedtothecapelementwhenthatcaprequiresaspecificmodifier.
guackeyboarduses MODIFIER
Addedtothekeyelementwhenanycapcontainedwithinitrequiresaspecificmodifier.
guackeyboardmodifier MODIFIER
Added to and removed from the root keyboard element when a modifier key is activated ordeactivatedrespectively.
guackeyboardpressed
Addedtoandremovedfromanykeyelementasitispressedandreleasedrespectively.
Important
TheCSSrulesrequiredfortheonscreenkeyboardtoworkasexpectedcanbequitecomplex.LookingovertheCSSrulesusedbytheonscreenkeyboardintheGuacamolewebapplicationwouldbeagoodplacetostarttoseehowtheappearanceofeachkeycanbedriventhroughthesimpleclasschangesdescribedabove.
InspectingtheelementsofanactiveonscreenkeyboardwithintheGuacamolewebapplicationwiththedevelopertoolsofyourfavoritebrowserisalsoagoodidea.
-
12/6/2015 Chapter15.guacamolecommonjs
http://guacdev.org/doc/gug/guacamolecommonjs.html 6/6
Handlingkeyevents
KeyeventsgeneratedbytheonscreenkeyboardareidenticaltothoseofGuacamole.KeyboardinthattheyconsistonlyofasingleX11keysym.Onlykeyupandkeydowneventsexist,asbeforethereisnokeypressevent.
//AssumingwehaveaninstanceofGuacamole.OnScreenKeyboardalready//called"keyboard"
keyboard.onkeydown=function(keysym){//Dosomething...};
keyboard.onkeyup=function(keysym){//Dosomething...};