/*
 * KeySniffer.c
 * 
 * KeySniffer shows the use of key sniffers to intercept and process raw 
 * keystrokes.  This one creates a window where all data about the keystroke
 * is displayed.
 * 
 * Key strokes have two sets of character data.  The ASCII key code is a valid
 * ASCII value.  This value discriminates between the A key with and without shift
 * (e.g. 'A' and 'a') but does not discriminate between numbers on the main 
 * keyboard vs. numeric keypad.  Virtual key codes tell exactly what physical key
 * was pressed (e.g. top-row-0 vs. num-pad-0) but do not change by modifier keys.
 * Modifier keys are returned separately.
 * 
 * ASCII codes are good for handling text entry; virtual key codes are good for 
 * setting up key commands (since they allow for separate binding of the numeric
 * key pad).
 * 
 */

#include "XPLMDisplay.h"
#include "XPLMGraphics.h"
#include "XPLMUtilities.h"
#include <stdio.h>
#include <string.h>

/* We will store the information we got from our last key press globally 
 * so the window can show the most recent key press. */
static XPLMWindowID	gWindow = NULL;
static XPLMKeyFlags	gFlags = 0;
static char			gVirtualKey = 0;
static char			gChar = 0;

static void MyDrawWindowCallback(
                                   XPLMWindowID         inWindowID,    
                                   void *               inRefcon);    

static void MyHandleKeyCallback(
                                   XPLMWindowID         inWindowID,    
                                   char                 inKey,    
                                   XPLMKeyFlags         inFlags,    
                                   char                 inVirtualKey,    
                                   void *               inRefcon,    
                                   int                  losingFocus);    

static int MyHandleMouseClickCallback(
                                   XPLMWindowID         inWindowID,    
                                   int                  x,    
                                   int                  y,    
                                   XPLMMouseStatus      inMouse,    
                                   void *               inRefcon);    

static int MyKeySniffer(
                                   char                 inChar,    
                                   XPLMKeyFlags         inFlags,    
                                   char                 inVirtualKey,    
                                   void *               inRefcon);    



PLUGIN_API int XPluginStart(
						char *		outName,
						char *		outSig,
						char *		outDesc)
{
	/* First set up our plugin info. */
	strcpy(outName, "KeySniffer");
	strcpy(outSig, "xplanesdk.examples.keysniffer");
	strcpy(outDesc, "A plugin that makes a window.");

	/* Now create a new window.  Pass in our three callbacks. */
	gWindow = XPLMCreateWindow(
					50, 750, 350, 700,			/* Area of the window. */
					1,							/* Start visible. */
					MyDrawWindowCallback,		/* Callbacks */
					MyHandleKeyCallback,
					MyHandleMouseClickCallback,
					NULL);						/* Refcon - not used. */
					
	/* Finally register our key sniffer. */
	XPLMRegisterKeySniffer(
					MyKeySniffer, 				/* Our callback. */
					1, 							/* Receive input before plugin windows. */
					0);							/* Refcon - not used. */
	
	return 1;
}

PLUGIN_API void	XPluginStop(void)
{
	XPLMDestroyWindow(gWindow);
}

PLUGIN_API void XPluginDisable(void)
{
}

PLUGIN_API int XPluginEnable(void)
{
	return 1;
}

PLUGIN_API void XPluginReceiveMessage(
					XPLMPluginID	inFromWho,
					int				inMessage,
					void *			inParam)
{
}

/*
 * MyDrawWindowCallback
 * 
 * This routine draws the window, showing the last keyboard stroke to be 
 * recorded by our sniffer.
 * 
 */
void MyDrawWindowCallback(
                                   XPLMWindowID         inWindowID,
                                   void *               inRefcon)
{
		char	str[50];
		int		left, top, right, bottom;
		float	color[] = { 1.0, 1.0, 1.0 };

	/* First get our window's location. */
	XPLMGetWindowGeometry(inWindowID, &left, &top, &right, &bottom);

	/* Draw a translucent dark box as our window outline. */
	XPLMDrawTranslucentDarkBox(left, top, right, bottom);

	/* Take the last key stroke and form a descriptive string.
	 * Note that ASCII values may be printed directly.  Virtual key
	 * codes are not ASCII and cannot be, but the utility function
	 * XPLMGetVirtualKeyDescription provides a human-readable string
	 * for each key.  These strings may be multicharacter, e.g. 'ENTER'
	 * or 'NUMPAD-0'. */
	sprintf(str,"%d '%c' | %d '%s' (%c %c %c %c %c)",
		gChar,
		(gChar) ? gChar : '0',
		(int) (unsigned char) gVirtualKey,
		XPLMGetVirtualKeyDescription(gVirtualKey),
		(gFlags & xplm_ShiftFlag) ? 'S' : ' ',
		(gFlags & xplm_OptionAltFlag) ? 'A' : ' ',
		(gFlags & xplm_ControlFlag) ? 'C' : ' ',
		(gFlags & xplm_DownFlag) ? 'D' : ' ',
		(gFlags & xplm_UpFlag) ? 'U' : ' ');

	/* Draw the string into the window. */
	XPLMDrawString(color, left + 5, top - 20, str, NULL, xplmFont_Basic);
}

void MyHandleKeyCallback(
                                   XPLMWindowID         inWindowID,
                                   char                 inKey,
                                   XPLMKeyFlags         inFlags,
                                   char                 inVirtualKey,
                                   void *               inRefcon,
                                   int                  losingFocus)
{
}                                   

int MyHandleMouseClickCallback(
                                   XPLMWindowID         inWindowID,    
                                   int                  x,    
                                   int                  y,    
                                   XPLMMouseStatus      inMouse,    
                                   void *               inRefcon)
{
	return 0;
}                                      

/*
 * MyKeySniffer
 * 
 * This routnine receives keystrokes from the simulator as they are pressed.
 * A separate message is received for each key press and release as well as 
 * keys being held down.  
 * 
 */
int MyKeySniffer(
                                   char                 inChar,    
                                   XPLMKeyFlags         inFlags,    
                                   char                 inVirtualKey,    
                                   void *               inRefcon)
{
	/* First record the key data. */
	gVirtualKey = inVirtualKey;
	gFlags = inFlags;
	gChar = inChar;

	/* Return 1 to pass the keystroke to plugin windows and X-Plane.  
	 * Returning 0 would consume the keystroke. */
	return 1;
}

Leave a Reply

Your email address will not be published. Required fields are marked *

Please do not report bugs in the blog comments.
Only bugs reported via the X-Plane Bug Reporter are tracked.