develop
Petr Mrázek 2009-12-12 23:56:28 +00:00
parent 337d42e15a
commit 1ea77b477e
2 changed files with 1353 additions and 1316 deletions

@ -65,6 +65,8 @@ using namespace std;
#include <X11/Xlib.h> //need for X11 functions #include <X11/Xlib.h> //need for X11 functions
#include <X11/extensions/XTest.h> //need for Xtest #include <X11/extensions/XTest.h> //need for Xtest
#include <X11/Xatom.h> //for the atom stuff #include <X11/Xatom.h> //for the atom stuff
#define XK_MISCELLANY
#include <X11/keysymdef.h>
#else #else
#define _WIN32_WINNT 0x0500 // needed for INPUT struct #define _WIN32_WINNT 0x0500 // needed for INPUT struct
#define WINVER 0x0500 // OpenThread(), PSAPI, Toolhelp32 #define WINVER 0x0500 // OpenThread(), PSAPI, Toolhelp32

@ -278,11 +278,13 @@ bool API::getCurrentCursorCreatures(vector<uint32_t> &addresses)
{ {
assert (d->cursorWindowInited); assert (d->cursorWindowInited);
DfVector creUnderCursor = d->dm->readVector (d->current_cursor_creature_offset, 4); DfVector creUnderCursor = d->dm->readVector (d->current_cursor_creature_offset, 4);
if(creUnderCursor.getSize() == 0){ if (creUnderCursor.getSize() == 0)
{
return false; return false;
} }
addresses.clear(); addresses.clear();
for(int i =0;i<creUnderCursor.getSize();i++){ for (int i = 0;i < creUnderCursor.getSize();i++)
{
uint32_t temp = * (uint32_t *) creUnderCursor.at (i); uint32_t temp = * (uint32_t *) creUnderCursor.at (i);
addresses.push_back (temp); addresses.push_back (temp);
} }
@ -305,7 +307,8 @@ Window EnumerateWindows (Display *display, Window rootWindow,const char *searchS
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;
} }
@ -325,7 +328,8 @@ Window EnumerateWindows (Display *display, Window rootWindow,const char *searchS
for (i = 0; i < noOfChildren; i++) for (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)
{
retWindow = tempWindow; retWindow = tempWindow;
break; break;
} }
@ -335,17 +339,21 @@ Window EnumerateWindows (Display *display, Window rootWindow,const char *searchS
return retWindow; return retWindow;
} }
// END ENUMERATE WINDOWS // END ENUMERATE WINDOWS
Window getDFWindow(Display *dpy){ bool getDFWindow (Display *dpy, Window& dfWindow, Window & rootWindow)
{
// int numScreeens = ScreenCount(dpy); // int numScreeens = ScreenCount(dpy);
for(int i = 0;i < ScreenCount(dpy);i++){ for (int i = 0;i < ScreenCount (dpy);i++)
Window currWin = RootWindow(dpy, i); {
Window retWindow = EnumerateWindows(dpy,currWin,"Dwarf Fortress"); rootWindow = RootWindow (dpy, i);
if(retWindow != BadWindow){ Window retWindow = EnumerateWindows (dpy, rootWindow, "Dwarf Fortress");
return (retWindow); if (retWindow != BadWindow)
{
dfWindow = retWindow;
return true;
} }
//I would ideally like to find the dfwindow using the PID, but X11 Windows only know their processes pid if the _NET_WM_PID attribute is set, which it is not for SDL 1.2. Supposedly SDL 1.3 will set this, but who knows when that will occur. //I would ideally like to find the dfwindow using the PID, but X11 Windows only know their processes pid if the _NET_WM_PID attribute is set, which it is not for SDL 1.2. Supposedly SDL 1.3 will set this, but who knows when that will occur.
} }
return(BadWindow); return false;
} }
bool setWMClientLeaderProperty (Display *dpy, Window &dfWin, Window &currentFocus) bool setWMClientLeaderProperty (Display *dpy, Window &dfWin, Window &currentFocus)
{ {
@ -373,7 +381,8 @@ bool setWMClientLeaderProperty(Display *dpy, Window &dfWin, Window &currentFocus
else else
{ {
Window curr = currentFocus; Window curr = currentFocus;
while(data == 0){ while (data == 0)
{
Window parent; Window parent;
Window root; Window root;
Window *children; Window *children;
@ -393,8 +402,9 @@ void API::TypeStr(const char *lpszString,int delay,bool useShift)
{ {
ForceResume(); ForceResume();
Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY
Window dfWin = getDFWindow(dpy); Window dfWin;
if(dfWin != BadWindow) Window rootWin;
if (getDFWindow (dpy, dfWin, rootWin))
{ {
XWindowAttributes currAttr; XWindowAttributes currAttr;
@ -403,10 +413,12 @@ void API::TypeStr(const char *lpszString,int delay,bool useShift)
XGetInputFocus (dpy, &currentFocus, &currentRevert); //get current focus XGetInputFocus (dpy, &currentFocus, &currentRevert); //get current focus
setWMClientLeaderProperty (dpy, dfWin, currentFocus); setWMClientLeaderProperty (dpy, dfWin, currentFocus);
XGetWindowAttributes (dpy, dfWin, &currAttr); XGetWindowAttributes (dpy, dfWin, &currAttr);
if(currAttr.map_state == IsUnmapped){ if (currAttr.map_state == IsUnmapped)
{
XMapRaised (dpy, dfWin); XMapRaised (dpy, dfWin);
} }
if(currAttr.map_state == IsUnviewable){ if (currAttr.map_state == IsUnviewable)
{
XRaiseWindow (dpy, dfWin); XRaiseWindow (dpy, dfWin);
} }
XSync (dpy, false); XSync (dpy, false);
@ -422,7 +434,8 @@ void API::TypeStr(const char *lpszString,int delay,bool useShift)
xkeycode = XKeysymToKeycode (dpy, cChar); xkeycode = XKeysymToKeycode (dpy, cChar);
//HACK add an extra shift up event, this fixes the problem of the same character twice in a row being displayed in df //HACK add an extra shift up event, this fixes the problem of the same character twice in a row being displayed in df
XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), false, CurrentTime); XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), false, CurrentTime);
if(useShift || cChar >= 'A' && cChar <= 'Z'){ if (useShift || cChar >= 'A' && cChar <= 'Z')
{
XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), true, CurrentTime); XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), true, CurrentTime);
XSync (dpy, false); XSync (dpy, false);
} }
@ -430,13 +443,15 @@ void API::TypeStr(const char *lpszString,int delay,bool useShift)
XSync (dpy, false); XSync (dpy, false);
XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime);
XSync (dpy, false); XSync (dpy, false);
if(useShift || cChar >= 'A' && cChar <= 'Z'){ if (useShift || cChar >= 'A' && cChar <= 'Z')
{
XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), false, CurrentTime); XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), false, CurrentTime);
XSync (dpy, false); XSync (dpy, false);
} }
} }
if(currAttr.map_state == IsUnmapped){ if (currAttr.map_state == IsUnmapped)
{
// XUnmapWindow(dpy,dfWin); if I unmap the window, it is no longer on the task bar, so just lower it instead // XUnmapWindow(dpy,dfWin); if I unmap the window, it is no longer on the task bar, so just lower it instead
XLowerWindow (dpy, dfWin); XLowerWindow (dpy, dfWin);
} }
@ -449,12 +464,14 @@ void API::TypeStr(const char *lpszString,int delay,bool useShift)
void API::TypeSpecial (t_special command, int count, int delay) void API::TypeSpecial (t_special command, int count, int delay)
{ {
ForceResume(); ForceResume();
if(command != WAIT){ if (command != WAIT)
{
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
Window dfWin = getDFWindow(dpy); Window dfWin;
if(dfWin != BadWindow) Window rootWin;
if (getDFWindow (dpy, dfWin, rootWin))
{ {
XWindowAttributes currAttr; XWindowAttributes currAttr;
Window currentFocus; Window currentFocus;
@ -462,10 +479,12 @@ void API::TypeSpecial(t_special command,int count,int delay)
XGetInputFocus (dpy, &currentFocus, &currentRevert); //get current focus XGetInputFocus (dpy, &currentFocus, &currentRevert); //get current focus
setWMClientLeaderProperty (dpy, dfWin, currentFocus); setWMClientLeaderProperty (dpy, dfWin, currentFocus);
XGetWindowAttributes (dpy, dfWin, &currAttr); XGetWindowAttributes (dpy, dfWin, &currAttr);
if(currAttr.map_state == IsUnmapped){ if (currAttr.map_state == IsUnmapped)
{
XMapRaised (dpy, dfWin); XMapRaised (dpy, dfWin);
} }
if(currAttr.map_state == IsUnviewable){ if (currAttr.map_state == IsUnviewable)
{
XRaiseWindow (dpy, dfWin); XRaiseWindow (dpy, dfWin);
} }
XSync (dpy, false); XSync (dpy, false);
@ -496,7 +515,8 @@ void API::TypeSpecial(t_special command,int count,int delay)
break; break;
case BACK_SPACE: case BACK_SPACE:
mykeysym = XStringToKeysym ("BackSpace"); mykeysym = XStringToKeysym ("BackSpace");
xkeycode = XKeysymToKeycode(dpy,mykeysym); xkeycode = XK_BackSpace;
xkeycode = XKeysymToKeycode (dpy, XK_BackSpace);
XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime);
XSync (dpy, true); XSync (dpy, true);
XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime);
@ -862,16 +882,15 @@ void API::TypeSpecial(t_special command,int count,int delay)
XSync (dpy, true); XSync (dpy, true);
break; break;
} }
usleep(20000);
} }
if(currAttr.map_state == IsUnmapped){ if (currAttr.map_state == IsUnmapped)
{
XLowerWindow (dpy, dfWin); // can't unmap, because you lose task bar XLowerWindow (dpy, dfWin); // can't unmap, because you lose task bar
} }
XSetInputFocus (dpy, currentFocus, currentRevert, CurrentTime); XSetInputFocus (dpy, currentFocus, currentRevert, CurrentTime);
XSync (dpy, false); XSync (dpy, false);
} }
if(command != WAIT){
usleep(delay*1000);
}
} }
else else
{ {
@ -880,15 +899,18 @@ void API::TypeSpecial(t_special command,int count,int delay)
} }
#else #else
//Windows key handlers //Windows key handlers
struct window{ struct window
{
HWND windowHandle; HWND windowHandle;
uint32_t pid; uint32_t pid;
}; };
BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam){ BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam)
{
uint32_t pid; uint32_t pid;
GetWindowThreadProcessId (hwnd, (LPDWORD) &pid); GetWindowThreadProcessId (hwnd, (LPDWORD) &pid);
if(pid == ((window *) lParam)->pid){ if (pid == ( (window *) lParam)->pid)
{
( (window *) lParam)->windowHandle = hwnd; ( (window *) lParam)->windowHandle = hwnd;
return FALSE; return FALSE;
} }
@ -915,7 +937,8 @@ void API::TypeStr(const char *lpszString,int delay, bool useShift)
while ( (cChar = *lpszString++)) // loops through chars while ( (cChar = *lpszString++)) // loops through chars
{ {
short vk = VkKeyScan (cChar); // keycode of char short vk = VkKeyScan (cChar); // keycode of char
if(useShift || (vk>>8)&1){ // char is capital, so need to hold down shift if (useShift || (vk >> 8) &1) // char is capital, so need to hold down shift
{
//shift down //shift down
INPUT input[4] = {0}; INPUT input[4] = {0};
input[0].type = INPUT_KEYBOARD; input[0].type = INPUT_KEYBOARD;
@ -935,7 +958,8 @@ void API::TypeStr(const char *lpszString,int delay, bool useShift)
SendInput (4, input, sizeof (input[0])); SendInput (4, input, sizeof (input[0]));
} }
else{ else
{
INPUT input[2] = {0}; INPUT input[2] = {0};
input[0].type = INPUT_KEYBOARD; input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = vk; input[0].ki.wVk = vk;
@ -1174,7 +1198,8 @@ void API::TypeSpecial(t_special command,int count,int delay)
input[1].ki.wVk = VK_SEPARATOR; input[1].ki.wVk = VK_SEPARATOR;
break; break;
} }
for(int i = 0; i<count;i++){ for (int i = 0; i < count;i++)
{
SendInput (2, input, sizeof (input[0])); SendInput (2, input, sizeof (input[0]));
} }
SetForegroundWindow (currentWindow); SetForegroundWindow (currentWindow);
@ -1182,7 +1207,8 @@ void API::TypeSpecial(t_special command,int count,int delay)
SetWindowPos (myWindow.windowHandle, nextWindow, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); SetWindowPos (myWindow.windowHandle, nextWindow, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
Sleep (delay); Sleep (delay);
} }
else{ else
{
Sleep (delay*count); Sleep (delay*count);
} }
} }
@ -1980,7 +2006,8 @@ void API::InitReadNameTables(map< string, vector<string> > & nameTable)
DfVector transVec (d->dm->readVector (transAddress, 4)); DfVector transVec (d->dm->readVector (transAddress, 4));
uint32_t dwarf_entry = 0; uint32_t dwarf_entry = 0;
for(int32_t i =0;i < genericVec.getSize();i++){ for (int32_t i = 0;i < genericVec.getSize();i++)
{
uint32_t genericNamePtr = * (uint32_t *) genericVec.at (i); uint32_t genericNamePtr = * (uint32_t *) genericVec.at (i);
string genericName = d->dm->readSTLString (genericNamePtr); string genericName = d->dm->readSTLString (genericNamePtr);
nameTable["GENERIC"].push_back (genericName); nameTable["GENERIC"].push_back (genericName);
@ -1991,7 +2018,8 @@ void API::InitReadNameTables(map< string, vector<string> > & nameTable)
uint32_t transPtr = * (uint32_t *) transVec.at (i); uint32_t transPtr = * (uint32_t *) transVec.at (i);
string transName = d->dm->readSTLString (transPtr); string transName = d->dm->readSTLString (transPtr);
DfVector trans_names_vec (d->dm->readVector (transPtr + word_table_offset, 4)); DfVector trans_names_vec (d->dm->readVector (transPtr + word_table_offset, 4));
for(uint32_t j =0;j<trans_names_vec.getSize();j++){ for (uint32_t j = 0;j < trans_names_vec.getSize();j++)
{
uint32_t transNamePtr = * (uint32_t *) trans_names_vec.at (j); uint32_t transNamePtr = * (uint32_t *) trans_names_vec.at (j);
string name = d->dm->readSTLString (transNamePtr); string name = d->dm->readSTLString (transNamePtr);
nameTable[transName].push_back (name); nameTable[transName].push_back (name);
@ -2006,9 +2034,12 @@ string API::TranslateName(const t_lastname & last, const map<string, vector<stri
assert (d->nameTablesInited); assert (d->nameTablesInited);
map<string, vector<string> >::const_iterator it; map<string, vector<string> >::const_iterator it;
it = nameTable.find (language); it = nameTable.find (language);
if(it != nameTable.end()){ if (it != nameTable.end())
for(int i =0;i<7;i++){ {
if(last.names[i] == -1){ for (int i = 0;i < 7;i++)
{
if (last.names[i] == -1)
{
break; break;
} }
trans_last.append (it->second[last.names[i]]); trans_last.append (it->second[last.names[i]]);
@ -2022,8 +2053,10 @@ string API::TranslateName(const t_squadname & squad, const map<string, vector<st
assert (d->nameTablesInited); assert (d->nameTablesInited);
map<string, vector<string> >::const_iterator it; map<string, vector<string> >::const_iterator it;
it = nameTable.find (language); it = nameTable.find (language);
if(it != nameTable.end()){ if (it != nameTable.end())
for(int i =0;i<7;i++){ {
for (int i = 0;i < 7;i++)
{
if (squad.names[i] == 0xFFFFFFFF) if (squad.names[i] == 0xFFFFFFFF)
{ {
continue; continue;
@ -2032,7 +2065,8 @@ string API::TranslateName(const t_squadname & squad, const map<string, vector<st
{ {
break; break;
} }
if(i ==4){ if (i == 4)
{
trans_squad.append (" "); trans_squad.append (" ");
} }
trans_squad.append (it->second[squad.names[i]]); trans_squad.append (it->second[squad.names[i]]);
@ -2294,7 +2328,8 @@ bool API::ReadViewScreen(t_viewscreen &screen)
uint32_t last = MreadDWord (d->view_screen_offset); uint32_t last = MreadDWord (d->view_screen_offset);
uint32_t screenAddr = MreadDWord (last); uint32_t screenAddr = MreadDWord (last);
uint32_t nextScreenPtr = MreadDWord (last + 4); uint32_t nextScreenPtr = MreadDWord (last + 4);
while(nextScreenPtr != 0){ while (nextScreenPtr != 0)
{
last = nextScreenPtr; last = nextScreenPtr;
screenAddr = MreadDWord (nextScreenPtr); screenAddr = MreadDWord (nextScreenPtr);
nextScreenPtr = MreadDWord (nextScreenPtr + 4); nextScreenPtr = MreadDWord (nextScreenPtr + 4);