From 1d25a995b8a7cafdea91cb7a1d75dde6f59c1199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 13 Dec 2009 04:43:06 +0000 Subject: [PATCH] comments, leftovers, fixed repeated character input on linux --- library/DFHackAPI.h | 20 ++++++++++----- library/DFKeys-linux.cpp | 51 ++++++++++++++++++++------------------ library/DFKeys-windows.cpp | 1 + 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/library/DFHackAPI.h b/library/DFHackAPI.h index a21d51206..32e2a0b57 100644 --- a/library/DFHackAPI.h +++ b/library/DFHackAPI.h @@ -47,12 +47,18 @@ namespace DFHack bool Attach(); bool Detach(); 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); - 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 &); @@ -61,6 +67,7 @@ namespace DFHack // resume DF bool Resume(); /** + * Force resume * be careful with this one */ bool ForceResume(); @@ -155,7 +162,7 @@ namespace DFHack void FinishReadVegetation(); 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, const uint16_t &x1, const uint16_t &y1,const uint16_t &z1, 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 setCursorCoords (const int32_t &x, const int32_t &y, const int32_t &z); - bool getCurrentCursorCreatures(vector &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 &addresses); bool InitViewSize(); bool getWindowSize(int32_t & width, int32_t & height); diff --git a/library/DFKeys-linux.cpp b/library/DFKeys-linux.cpp index 7ed69ea5f..7b2463da1 100644 --- a/library/DFKeys-linux.cpp +++ b/library/DFKeys-linux.cpp @@ -30,6 +30,8 @@ distribution. #define XK_LATIN1 #include +//FIXME: + using namespace DFHack; // should always reflect the enum in DFkeys.h @@ -87,41 +89,33 @@ const static KeySym ksTable[NUM_SPECIALS]= 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) { - static int level = 0; Window parent; Window *children; - Window *child; Window retWindow = BadWindow; unsigned int noOfChildren; int status; - int i; - + + // get name of current window, compare to control, return if found char * win_name; status = XFetchName (display, rootWindow, &win_name); - if ( (status >= Success) && (win_name) && strcmp (win_name, searchString) == 0) { return rootWindow; } - level++; - + // look at surrounding window tree nodes, bailout on error or no children status = XQueryTree (display, rootWindow, &rootWindow, &parent, &children, &noOfChildren); - - if (status == 0) - { - return BadWindow; - } - - if (noOfChildren == 0) + if (!status || !noOfChildren) { 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); if (tempWindow != BadWindow) @@ -130,7 +124,8 @@ Window EnumerateWindows (Display *display, Window rootWindow, const char *search break; } } - + + // free resources XFree ( (char*) children); return retWindow; } @@ -153,6 +148,8 @@ bool getDFWindow (Display *dpy, Window& dfWindow, Window & rootWindow) } // 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) { XKeyEvent event; @@ -184,22 +181,25 @@ void API::TypeStr (const char *lpszString, int delay, bool useShift) if (getDFWindow (dpy, dfWin, rootWin)) { char cChar; + int realDelay = delay * 1000; KeyCode xkeycode; char prevKey = 0; int sleepAmnt = 0; while ( (cChar = *lpszString++)) // loops through chars { + // HACK: the timing here is a strange beast xkeycode = XKeysymToKeycode (dpy, cChar); + send_xkeyevent(dpy,dfWin,rootWin,ksTable[DFHack::LEFT_SHIFT],0,false, realDelay); if (useShift || cChar >= 'A' && cChar <= 'Z') { - send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,true, delay * 1000); - send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,false, delay * 1000); + send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,true, realDelay); + send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,false, realDelay); XSync (dpy, false); } else { - send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, delay * 1000); - send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, delay * 1000); + send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, realDelay); + send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, realDelay); XSync (dpy, false); } } @@ -209,6 +209,7 @@ void API::TypeStr (const char *lpszString, int delay, bool useShift) cout << "FAIL!" << endl; } } + void API::TypeSpecial (t_special command, int count, int delay) { ForceResume(); @@ -217,17 +218,19 @@ void API::TypeSpecial (t_special command, int count, int delay) KeySym mykeysym; KeyCode xkeycode; Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY + int realDelay = delay * 1000; Window dfWin; Window rootWin; if (getDFWindow (dpy, dfWin, rootWin)) { for (int i = 0;i < count; i++) { + // HACK: the timing here is a strange beast mykeysym = ksTable[command]; xkeycode = XKeysymToKeycode (dpy, mykeysym); - send_xkeyevent(dpy,dfWin,rootWin,ksTable[DFHack::LEFT_SHIFT],0,false, delay * 1000); - send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, delay * 1000); - send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, delay * 1000); + send_xkeyevent(dpy,dfWin,rootWin,ksTable[DFHack::LEFT_SHIFT],0,false, realDelay); + send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, realDelay); + send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, realDelay); XSync (dpy, false); } } diff --git a/library/DFKeys-windows.cpp b/library/DFKeys-windows.cpp index c3bf11632..e9afeefc2 100644 --- a/library/DFKeys-windows.cpp +++ b/library/DFKeys-windows.cpp @@ -102,6 +102,7 @@ BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam) } // 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) { //Resume();