comments, leftovers, fixed repeated character input on linux

develop
Petr Mrázek 2009-12-13 04:43:06 +00:00
parent cb4197f4fc
commit 1d25a995b8
3 changed files with 42 additions and 30 deletions

@ -47,12 +47,18 @@ namespace DFHack
bool Attach(); bool Attach();
bool Detach(); bool Detach();
bool isAttached(); bool isAttached();
void TypeStr(const char *lpszString,int delay = 0,bool useShift = false); //Capitals are shifted automatically, other keys !@# ect need to have useShift set for them // type a string into the DF window
//Capitals are shifted automatically, other keys !@# ect need to have useShift set for them
void TypeStr(const char *lpszString,int delay = 0,bool useShift = false);
// type a special key into DF window $count times
void TypeSpecial(t_special command,int count=1,int delay = 0); void TypeSpecial(t_special command,int count=1,int delay = 0);
bool ReadPauseState(); //true if paused, false if not //true if paused, false if not
bool ReadPauseState();
// read the DF menu view state
bool ReadViewScreen(t_viewscreen &); bool ReadViewScreen(t_viewscreen &);
@ -61,6 +67,7 @@ namespace DFHack
// resume DF // resume DF
bool Resume(); bool Resume();
/** /**
* Force resume
* be careful with this one * be careful with this one
*/ */
bool ForceResume(); bool ForceResume();
@ -155,7 +162,7 @@ namespace DFHack
void FinishReadVegetation(); void FinishReadVegetation();
uint32_t InitReadCreatures(); uint32_t InitReadCreatures();
// returns index of creature actually read or -1 if no creature can be found /// returns index of creature actually read or -1 if no creature can be found
int32_t ReadCreatureInBox(int32_t index, t_creature & furball, int32_t ReadCreatureInBox(int32_t index, t_creature & furball,
const uint16_t &x1, const uint16_t &y1,const uint16_t &z1, const uint16_t &x1, const uint16_t &y1,const uint16_t &z1,
const uint16_t &x2, const uint16_t &y2,const uint16_t &z2); const uint16_t &x2, const uint16_t &y2,const uint16_t &z2);
@ -173,7 +180,8 @@ namespace DFHack
bool getCursorCoords (int32_t &x, int32_t &y, int32_t &z); bool getCursorCoords (int32_t &x, int32_t &y, int32_t &z);
bool setCursorCoords (const int32_t &x, const int32_t &y, const int32_t &z); bool setCursorCoords (const int32_t &x, const int32_t &y, const int32_t &z);
bool getCurrentCursorCreatures(vector<uint32_t> &addresses); // This returns false if there is nothing under the cursor, it puts the addresses in a the vector if there is /// This returns false if there is nothing under the cursor, it puts the addresses in a vector if there is
bool getCurrentCursorCreatures(vector<uint32_t> &addresses);
bool InitViewSize(); bool InitViewSize();
bool getWindowSize(int32_t & width, int32_t & height); bool getWindowSize(int32_t & width, int32_t & height);

@ -30,6 +30,8 @@ distribution.
#define XK_LATIN1 #define XK_LATIN1
#include <X11/keysymdef.h> #include <X11/keysymdef.h>
//FIXME:
using namespace DFHack; using namespace DFHack;
// should always reflect the enum in DFkeys.h // should always reflect the enum in DFkeys.h
@ -87,41 +89,33 @@ const static KeySym ksTable[NUM_SPECIALS]=
XK_KP_Decimal XK_KP_Decimal
}; };
// ENUMARATE THROUGH WINDOWS AND DISPLAY THEIR TITLES // Source: http://www.experts-exchange.com/OS/Unix/X_Windows/Q_21341279.html
// find named window recursively
Window EnumerateWindows (Display *display, Window rootWindow, const char *searchString) Window EnumerateWindows (Display *display, Window rootWindow, const char *searchString)
{ {
static int level = 0;
Window parent; Window parent;
Window *children; Window *children;
Window *child;
Window retWindow = BadWindow; Window retWindow = BadWindow;
unsigned int noOfChildren; unsigned int noOfChildren;
int status; int status;
int i;
// get name of current window, compare to control, return if found
char * win_name; char * win_name;
status = XFetchName (display, rootWindow, &win_name); status = XFetchName (display, rootWindow, &win_name);
if ( (status >= Success) && (win_name) && strcmp (win_name, searchString) == 0) if ( (status >= Success) && (win_name) && strcmp (win_name, searchString) == 0)
{ {
return rootWindow; return rootWindow;
} }
level++; // look at surrounding window tree nodes, bailout on error or no children
status = XQueryTree (display, rootWindow, &rootWindow, &parent, &children, &noOfChildren); status = XQueryTree (display, rootWindow, &rootWindow, &parent, &children, &noOfChildren);
if (!status || !noOfChildren)
if (status == 0)
{
return BadWindow;
}
if (noOfChildren == 0)
{ {
return BadWindow; return BadWindow;
} }
for (i = 0; i < noOfChildren; i++) // recurse into children
for (int i = 0; i < noOfChildren; i++)
{ {
Window tempWindow = EnumerateWindows (display, children[i], searchString); Window tempWindow = EnumerateWindows (display, children[i], searchString);
if (tempWindow != BadWindow) if (tempWindow != BadWindow)
@ -130,7 +124,8 @@ Window EnumerateWindows (Display *display, Window rootWindow, const char *search
break; break;
} }
} }
// free resources
XFree ( (char*) children); XFree ( (char*) children);
return retWindow; return retWindow;
} }
@ -153,6 +148,8 @@ bool getDFWindow (Display *dpy, Window& dfWindow, Window & rootWindow)
} }
// let's hope it works // let's hope it works
// Source: http://homepage3.nifty.com/tsato/xvkbd/events.html
// TODO: is permission from original author needed here?
void send_xkeyevent(Display *display, Window dfW,Window rootW, int keycode, int modstate, int is_press, useconds_t delay) void send_xkeyevent(Display *display, Window dfW,Window rootW, int keycode, int modstate, int is_press, useconds_t delay)
{ {
XKeyEvent event; XKeyEvent event;
@ -184,22 +181,25 @@ void API::TypeStr (const char *lpszString, int delay, bool useShift)
if (getDFWindow (dpy, dfWin, rootWin)) if (getDFWindow (dpy, dfWin, rootWin))
{ {
char cChar; char cChar;
int realDelay = delay * 1000;
KeyCode xkeycode; KeyCode xkeycode;
char prevKey = 0; char prevKey = 0;
int sleepAmnt = 0; int sleepAmnt = 0;
while ( (cChar = *lpszString++)) // loops through chars while ( (cChar = *lpszString++)) // loops through chars
{ {
// HACK: the timing here is a strange beast
xkeycode = XKeysymToKeycode (dpy, cChar); xkeycode = XKeysymToKeycode (dpy, cChar);
send_xkeyevent(dpy,dfWin,rootWin,ksTable[DFHack::LEFT_SHIFT],0,false, realDelay);
if (useShift || cChar >= 'A' && cChar <= 'Z') if (useShift || cChar >= 'A' && cChar <= 'Z')
{ {
send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,true, delay * 1000); send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,true, realDelay);
send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,false, delay * 1000); send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,false, realDelay);
XSync (dpy, false); XSync (dpy, false);
} }
else else
{ {
send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, delay * 1000); send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, realDelay);
send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, delay * 1000); send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, realDelay);
XSync (dpy, false); XSync (dpy, false);
} }
} }
@ -209,6 +209,7 @@ void API::TypeStr (const char *lpszString, int delay, bool useShift)
cout << "FAIL!" << endl; cout << "FAIL!" << endl;
} }
} }
void API::TypeSpecial (t_special command, int count, int delay) void API::TypeSpecial (t_special command, int count, int delay)
{ {
ForceResume(); ForceResume();
@ -217,17 +218,19 @@ void API::TypeSpecial (t_special command, int count, int delay)
KeySym mykeysym; KeySym mykeysym;
KeyCode xkeycode; KeyCode xkeycode;
Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY
int realDelay = delay * 1000;
Window dfWin; Window dfWin;
Window rootWin; Window rootWin;
if (getDFWindow (dpy, dfWin, rootWin)) if (getDFWindow (dpy, dfWin, rootWin))
{ {
for (int i = 0;i < count; i++) for (int i = 0;i < count; i++)
{ {
// HACK: the timing here is a strange beast
mykeysym = ksTable[command]; mykeysym = ksTable[command];
xkeycode = XKeysymToKeycode (dpy, mykeysym); xkeycode = XKeysymToKeycode (dpy, mykeysym);
send_xkeyevent(dpy,dfWin,rootWin,ksTable[DFHack::LEFT_SHIFT],0,false, delay * 1000); send_xkeyevent(dpy,dfWin,rootWin,ksTable[DFHack::LEFT_SHIFT],0,false, realDelay);
send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, delay * 1000); send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, realDelay);
send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, delay * 1000); send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, realDelay);
XSync (dpy, false); XSync (dpy, false);
} }
} }

@ -102,6 +102,7 @@ BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam)
} }
// TODO: investigate use of PostMessage() for input sending to background windows // TODO: investigate use of PostMessage() for input sending to background windows
// TODO: also investigate possible problems with UIPI on Vista and 7
void API::TypeStr (const char *lpszString, int delay, bool useShift) void API::TypeStr (const char *lpszString, int delay, bool useShift)
{ {
//Resume(); //Resume();