From 58986ef838fbb64e59f5f8aaccfb6506380e7f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 13 Dec 2009 00:20:25 +0000 Subject: [PATCH] cleanup #2 --- library/CMakeLists.txt | 2 + library/DFHackAPI.cpp | 923 ------------------------------------- library/DFKeys-linux.cpp | 632 +++++++++++++++++++++++++ library/DFKeys-windows.cpp | 341 ++++++++++++++ 4 files changed, 975 insertions(+), 923 deletions(-) create mode 100644 library/DFKeys-linux.cpp create mode 100644 library/DFKeys-windows.cpp diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 71f8f0d4a..feb157266 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -46,11 +46,13 @@ stdint_win.h SET(PROJECT_SRCS_LINUX DFProcess-linux.cpp +DFKeys-linux.cpp DFProcessEnumerator-linux.cpp ) SET(PROJECT_SRCS_WINDOWS DFProcess-windows.cpp +DFKeys-windows.cpp DFProcessEnumerator-windows.cpp ) diff --git a/library/DFHackAPI.cpp b/library/DFHackAPI.cpp index acef953b8..244262fae 100644 --- a/library/DFHackAPI.cpp +++ b/library/DFHackAPI.cpp @@ -291,929 +291,6 @@ bool API::getCurrentCursorCreatures (vector &addresses) return true; } -#ifdef LINUX_BUILD -// ENUMARATE THROUGH WINDOWS AND DISPLAY THEIR TITLES -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; - - char * win_name; - status = XFetchName (display, rootWindow, &win_name); - - if ( (status >= Success) && (win_name) && strcmp (win_name, searchString) == 0) - { - return rootWindow; - } - - level++; - - status = XQueryTree (display, rootWindow, &rootWindow, &parent, &children, &noOfChildren); - - if (status == 0) - { - return BadWindow; - } - - if (noOfChildren == 0) - { - return BadWindow; - } - for (i = 0; i < noOfChildren; i++) - { - Window tempWindow = EnumerateWindows (display, children[i], searchString); - if (tempWindow != BadWindow) - { - retWindow = tempWindow; - break; - } - } - - XFree ( (char*) children); - return retWindow; -} -// END ENUMERATE WINDOWS -bool getDFWindow (Display *dpy, Window& dfWindow, Window & rootWindow) -{ - // int numScreeens = ScreenCount(dpy); - for (int i = 0;i < ScreenCount (dpy);i++) - { - rootWindow = RootWindow (dpy, i); - Window retWindow = EnumerateWindows (dpy, rootWindow, "Dwarf Fortress"); - 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. - } - return false; -} -bool setWMClientLeaderProperty (Display *dpy, Window &dfWin, Window ¤tFocus) -{ - static bool propertySet; - if (propertySet) - { - return true; - } - Atom leaderAtom; - Atom type; - int format, status; - unsigned long nitems = 0; - unsigned long extra = 0; - unsigned char *data = 0; - Window result = 0; - leaderAtom = XInternAtom (dpy, "WM_CLIENT_LEADER", false); - status = XGetWindowProperty (dpy, currentFocus, leaderAtom, 0L, 1L, false, XA_WINDOW, &type, &format, &nitems, &extra, (unsigned char **) & data); - if (status == Success) - { - if (data != 0) - { - result = * ( (Window*) data); - XFree (data); - } - else - { - Window curr = currentFocus; - while (data == 0) - { - Window parent; - Window root; - Window *children; - uint numChildren; - XQueryTree (dpy, curr, &root, &parent, &children, &numChildren); - XGetWindowProperty (dpy, parent, leaderAtom, 0L, 1L, false, XA_WINDOW, &type, &format, &nitems, &extra, (unsigned char **) &data); - } - result = * ( (Window*) data); - XFree (data); - } - } - XChangeProperty (dpy, dfWin, leaderAtom, XA_WINDOW, 32, PropModeReplace, (const unsigned char *) &result, 1); - propertySet = true; - return true; -} -void API::TypeStr (const char *lpszString, int delay, bool useShift) -{ - ForceResume(); - Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY - Window dfWin; - Window rootWin; - if (getDFWindow (dpy, dfWin, rootWin)) - { - - XWindowAttributes currAttr; - Window currentFocus; - int currentRevert; - XGetInputFocus (dpy, ¤tFocus, ¤tRevert); //get current focus - setWMClientLeaderProperty (dpy, dfWin, currentFocus); - XGetWindowAttributes (dpy, dfWin, &currAttr); - if (currAttr.map_state == IsUnmapped) - { - XMapRaised (dpy, dfWin); - } - if (currAttr.map_state == IsUnviewable) - { - XRaiseWindow (dpy, dfWin); - } - XSync (dpy, false); - XSetInputFocus (dpy, dfWin, RevertToNone, CurrentTime); - XSync (dpy, false); - - char cChar; - KeyCode xkeycode; - char prevKey = 0; - int sleepAmnt = 0; - while ( (cChar = *lpszString++)) // loops through chars - { - 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 - XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), false, CurrentTime); - if (useShift || cChar >= 'A' && cChar <= 'Z') - { - XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), true, CurrentTime); - XSync (dpy, false); - } - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, false); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, false); - if (useShift || cChar >= 'A' && cChar <= 'Z') - { - XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), false, CurrentTime); - XSync (dpy, false); - } - - } - 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 - XLowerWindow (dpy, dfWin); - } - XSetInputFocus (dpy, currentFocus, currentRevert, CurrentTime); - XSync (dpy, true); - } - usleep (delay*1000); -} - -void API::TypeSpecial (t_special command, int count, int delay) -{ - ForceResume(); - if (command != WAIT) - { - KeySym mykeysym; - KeyCode xkeycode; - Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY - Window dfWin; - Window rootWin; - if (getDFWindow (dpy, dfWin, rootWin)) - { - XWindowAttributes currAttr; - Window currentFocus; - int currentRevert; - XGetInputFocus (dpy, ¤tFocus, ¤tRevert); //get current focus - setWMClientLeaderProperty (dpy, dfWin, currentFocus); - XGetWindowAttributes (dpy, dfWin, &currAttr); - if (currAttr.map_state == IsUnmapped) - { - XMapRaised (dpy, dfWin); - } - if (currAttr.map_state == IsUnviewable) - { - XRaiseWindow (dpy, dfWin); - } - XSync (dpy, false); - XSetInputFocus (dpy, dfWin, RevertToParent, CurrentTime); - - for (int i = 0;i < count; i++) - { - //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); - - switch (command) - { - case ENTER: - mykeysym = XStringToKeysym ("Return"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case SPACE: - mykeysym = XStringToKeysym ("space"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case BACK_SPACE: - mykeysym = XStringToKeysym ("BackSpace"); - xkeycode = XK_BackSpace; - xkeycode = XKeysymToKeycode (dpy, XK_BackSpace); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case TAB: - mykeysym = XStringToKeysym ("Tab"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case CAPS_LOCK: - mykeysym = XStringToKeysym ("Caps_Lock"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case LEFT_SHIFT: // I am not positive that this will work to distinguish the left and right.. - mykeysym = XStringToKeysym ("Shift_L"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case RIGHT_SHIFT: - mykeysym = XStringToKeysym ("Shift_R"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case LEFT_CONTROL: - mykeysym = XStringToKeysym ("Control_L"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - case RIGHT_CONTROL: - mykeysym = XStringToKeysym ("Control_R"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case ALT: - mykeysym = XStringToKeysym ("Alt_L"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case ESCAPE: - mykeysym = XStringToKeysym ("Escape"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case UP: - mykeysym = XStringToKeysym ("Up"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case DOWN: - mykeysym = XStringToKeysym ("Down"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case LEFT: - mykeysym = XStringToKeysym ("Left"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case RIGHT: - mykeysym = XStringToKeysym ("Right"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F1: - mykeysym = XStringToKeysym ("F1"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F2: - mykeysym = XStringToKeysym ("F2"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F3: - mykeysym = XStringToKeysym ("F3"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F4: - mykeysym = XStringToKeysym ("F4"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F5: - mykeysym = XStringToKeysym ("F5"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F6: - mykeysym = XStringToKeysym ("F6"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F7: - mykeysym = XStringToKeysym ("F7"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F8: - mykeysym = XStringToKeysym ("F8"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F9: - mykeysym = XStringToKeysym ("F9"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F11: - mykeysym = XStringToKeysym ("F11"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case F12: - mykeysym = XStringToKeysym ("F12"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case PAGE_UP: - mykeysym = XStringToKeysym ("Page_Up"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case PAGE_DOWN: - mykeysym = XStringToKeysym ("Page_Down"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case INSERT: - mykeysym = XStringToKeysym ("Insert"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEY_DELETE: - mykeysym = XStringToKeysym ("Delete"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case HOME: - mykeysym = XStringToKeysym ("Home"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case END: - mykeysym = XStringToKeysym ("End"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_DIVIDE: - mykeysym = XStringToKeysym ("KP_Divide"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_MULTIPLY: - mykeysym = XStringToKeysym ("KP_Multiply"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_SUBTRACT: - mykeysym = XStringToKeysym ("KP_Subtract"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_ADD: - mykeysym = XStringToKeysym ("KP_Add"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_ENTER: - mykeysym = XStringToKeysym ("KP_Enter"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_0: - mykeysym = XStringToKeysym ("KP_0"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_1: - mykeysym = XStringToKeysym ("KP_1"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_2: - mykeysym = XStringToKeysym ("KP_2"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_3: - mykeysym = XStringToKeysym ("KP_3"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_4: - mykeysym = XStringToKeysym ("KP_4"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_5: - mykeysym = XStringToKeysym ("KP_5"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_6: - mykeysym = XStringToKeysym ("KP_6"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_7: - mykeysym = XStringToKeysym ("KP_7"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_8: - mykeysym = XStringToKeysym ("KP_8"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_9: - mykeysym = XStringToKeysym ("KP_9"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - case KEYPAD_DECIMAL_POINT: - mykeysym = XStringToKeysym ("KP_Decimal"); - xkeycode = XKeysymToKeycode (dpy, mykeysym); - XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); - XSync (dpy, true); - XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); - XSync (dpy, true); - break; - } - usleep(20000); - } - if (currAttr.map_state == IsUnmapped) - { - XLowerWindow (dpy, dfWin); // can't unmap, because you lose task bar - } - XSetInputFocus (dpy, currentFocus, currentRevert, CurrentTime); - XSync (dpy, false); - } - } - else - { - usleep (delay*1000 * count); - } -} -#else -//Windows key handlers -struct window -{ - HWND windowHandle; - uint32_t pid; -}; -BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam) -{ - uint32_t pid; - - GetWindowThreadProcessId (hwnd, (LPDWORD) &pid); - if (pid == ( (window *) lParam)->pid) - { - ( (window *) lParam)->windowHandle = hwnd; - return FALSE; - } - return TRUE; -} -void API::TypeStr (const char *lpszString, int delay, bool useShift) -{ - //Resume(); - ForceResume(); - - //sendmessage needs a window handle HWND, so have to get that from the process HANDLE - HWND currentWindow = GetForegroundWindow(); - window myWindow; - myWindow.pid = GetProcessId (DFHack::g_ProcessHandle); - EnumWindows (EnumWindowsProc, (LPARAM) &myWindow); - - HWND nextWindow = GetWindow (myWindow.windowHandle, GW_HWNDNEXT); - - SetActiveWindow (myWindow.windowHandle); - SetForegroundWindow (myWindow.windowHandle); - - char cChar; - - while ( (cChar = *lpszString++)) // loops through chars - { - short vk = VkKeyScan (cChar); // keycode of char - if (useShift || (vk >> 8) &1) // char is capital, so need to hold down shift - { - //shift down - INPUT input[4] = {0}; - input[0].type = INPUT_KEYBOARD; - input[0].ki.wVk = VK_SHIFT; - - input[1].type = INPUT_KEYBOARD; - input[1].ki.wVk = vk; - - input[2].type = INPUT_KEYBOARD; - input[2].ki.wVk = vk; - input[2].ki.dwFlags = KEYEVENTF_KEYUP; - - // shift up - input[3].type = INPUT_KEYBOARD; - input[3].ki.wVk = VK_SHIFT; - input[3].ki.dwFlags = KEYEVENTF_KEYUP; - - SendInput (4, input, sizeof (input[0])); - } - else - { - INPUT input[2] = {0}; - input[0].type = INPUT_KEYBOARD; - input[0].ki.wVk = vk; - - input[1].type = INPUT_KEYBOARD; - input[1].ki.wVk = vk; - input[1].ki.dwFlags = KEYEVENTF_KEYUP; - SendInput (2, input, sizeof (input[0])); - } - } - SetForegroundWindow (currentWindow); - SetActiveWindow (currentWindow); - SetWindowPos (myWindow.windowHandle, nextWindow, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - Sleep (delay); - -} -void API::TypeSpecial (t_special command, int count, int delay) -{ - ForceResume(); - if (command != WAIT) - { - HWND currentWindow = GetForegroundWindow(); - window myWindow; - myWindow.pid = GetProcessId (DFHack::g_ProcessHandle); - EnumWindows (EnumWindowsProc, (LPARAM) &myWindow); - - HWND nextWindow = GetWindow (myWindow.windowHandle, GW_HWNDNEXT); - SetForegroundWindow (myWindow.windowHandle); - SetActiveWindow (myWindow.windowHandle); - INPUT shift; - shift.type = INPUT_KEYBOARD; - shift.ki.wVk = VK_SHIFT; - shift.ki.dwFlags = KEYEVENTF_KEYUP; - SendInput (1, &shift, sizeof (shift)); - INPUT input[2] = {0}; - input[0].type = INPUT_KEYBOARD; - input[1].type = INPUT_KEYBOARD; - input[1].ki.dwFlags = KEYEVENTF_KEYUP; - switch (command) - { - case ENTER: - input[0].ki.wVk = VK_RETURN; - input[1].ki.wVk = VK_RETURN; - break; - case SPACE: - input[0].ki.wVk = VK_SPACE; - input[1].ki.wVk = VK_SPACE; - break; - case BACK_SPACE: - input[0].ki.wVk = VK_BACK; - input[1].ki.wVk = VK_BACK; - break; - case TAB: - input[0].ki.wVk = VK_TAB; - input[1].ki.wVk = VK_TAB; - break; - case CAPS_LOCK: - input[0].ki.wVk = VK_CAPITAL; - input[1].ki.wVk = VK_CAPITAL; - break; - // These are only for pressing the modifier key itself, you can't do key combinations with them, like ctrl+C - case LEFT_SHIFT: // I am not positive that this will work to distinguish the left and right.. - input[0].ki.wVk = VK_LSHIFT; - input[1].ki.wVk = VK_LSHIFT; - break; - case RIGHT_SHIFT: - input[0].ki.wVk = VK_RSHIFT; - input[1].ki.wVk = VK_RSHIFT; - break; - case LEFT_CONTROL: - input[0].ki.wVk = VK_LCONTROL; - input[1].ki.wVk = VK_LCONTROL; - break; - case RIGHT_CONTROL: - input[0].ki.wVk = VK_RCONTROL; - input[1].ki.wVk = VK_RCONTROL; - break; - case ALT: - input[0].ki.wVk = VK_MENU; - input[1].ki.wVk = VK_MENU; - break; - case ESCAPE: - input[0].ki.wVk = VK_ESCAPE; - input[1].ki.wVk = VK_ESCAPE; - break; - case UP: - input[0].ki.wVk = VK_UP; - input[1].ki.wVk = VK_UP; - break; - case DOWN: - input[0].ki.wVk = VK_DOWN; - input[1].ki.wVk = VK_DOWN; - break; - case LEFT: - input[0].ki.wVk = VK_LEFT; - input[1].ki.wVk = VK_LEFT; - break; - case RIGHT: - input[0].ki.wVk = VK_RIGHT; - input[1].ki.wVk = VK_RIGHT; - break; - case F1: - input[0].ki.wVk = VK_F1; - input[1].ki.wVk = VK_F1; - break; - case F2: - input[0].ki.wVk = VK_F2; - input[1].ki.wVk = VK_F2; - break; - case F3: - input[0].ki.wVk = VK_F3; - input[1].ki.wVk = VK_F3; - break; - case F4: - input[0].ki.wVk = VK_F4; - input[1].ki.wVk = VK_F4; - break; - case F5: - input[0].ki.wVk = VK_F5; - input[1].ki.wVk = VK_F5; - break; - case F6: - input[0].ki.wVk = VK_F6; - input[1].ki.wVk = VK_F6; - break; - case F7: - input[0].ki.wVk = VK_F7; - input[1].ki.wVk = VK_F7; - break; - case F8: - input[0].ki.wVk = VK_F8; - input[1].ki.wVk = VK_F8; - break; - case F9: - input[0].ki.wVk = VK_F9; - input[1].ki.wVk = VK_F9; - break; - case F10: - input[0].ki.wVk = VK_F10; - input[1].ki.wVk = VK_F10; - break; - case F11: - input[0].ki.wVk = VK_F11; - input[1].ki.wVk = VK_F11; - break; - case F12: - input[0].ki.wVk = VK_F12; - input[1].ki.wVk = VK_F12; - break; - case PAGE_UP: - input[0].ki.wVk = VK_PRIOR; - input[1].ki.wVk = VK_PRIOR; - break; - case PAGE_DOWN: - input[0].ki.wVk = VK_NEXT; - input[1].ki.wVk = VK_NEXT; - break; - case INSERT: - input[0].ki.wVk = VK_INSERT; - input[1].ki.wVk = VK_INSERT; - break; - case KEY_DELETE: - input[0].ki.wVk = VK_DELETE; - input[1].ki.wVk = VK_DELETE; - break; - case HOME: - input[0].ki.wVk = VK_HOME; - input[1].ki.wVk = VK_HOME; - break; - case END: - input[0].ki.wVk = VK_END; - input[1].ki.wVk = VK_END; - break; - case KEYPAD_DIVIDE: - input[0].ki.wVk = VK_DIVIDE; - input[1].ki.wVk = VK_DIVIDE; - break; - case KEYPAD_MULTIPLY: - input[0].ki.wVk = VK_MULTIPLY; - input[1].ki.wVk = VK_MULTIPLY; - break; - case KEYPAD_SUBTRACT: - input[0].ki.wVk = VK_SUBTRACT; - input[1].ki.wVk = VK_SUBTRACT; - break; - case KEYPAD_ADD: - input[0].ki.wVk = VK_ADD; - input[1].ki.wVk = VK_ADD; - break; - case KEYPAD_ENTER: - input[0].ki.wVk = VK_RETURN; - input[1].ki.wVk = VK_RETURN; - break; - case KEYPAD_0: - input[0].ki.wVk = VK_NUMPAD0; - input[1].ki.wVk = VK_NUMPAD0; - break; - case KEYPAD_1: - input[0].ki.wVk = VK_NUMPAD1; - input[1].ki.wVk = VK_NUMPAD1; - break; - case KEYPAD_2: - input[0].ki.wVk = VK_NUMPAD2; - input[1].ki.wVk = VK_NUMPAD2; - break; - case KEYPAD_3: - input[0].ki.wVk = VK_NUMPAD3; - input[1].ki.wVk = VK_NUMPAD3; - break; - case KEYPAD_4: - input[0].ki.wVk = VK_NUMPAD4; - input[1].ki.wVk = VK_NUMPAD4; - break; - case KEYPAD_5: - input[0].ki.wVk = VK_NUMPAD5; - input[1].ki.wVk = VK_NUMPAD5; - break; - case KEYPAD_6: - input[0].ki.wVk = VK_NUMPAD6; - input[1].ki.wVk = VK_NUMPAD6; - break; - case KEYPAD_7: - input[0].ki.wVk = VK_NUMPAD7; - input[1].ki.wVk = VK_NUMPAD7; - break; - case KEYPAD_8: - input[0].ki.wVk = VK_NUMPAD8; - input[1].ki.wVk = VK_NUMPAD8; - break; - case KEYPAD_9: - input[0].ki.wVk = VK_NUMPAD9; - input[1].ki.wVk = VK_NUMPAD9; - break; - case KEYPAD_DECIMAL_POINT: - input[0].ki.wVk = VK_SEPARATOR; - input[1].ki.wVk = VK_SEPARATOR; - break; - } - for (int i = 0; i < count;i++) - { - SendInput (2, input, sizeof (input[0])); - } - SetForegroundWindow (currentWindow); - SetActiveWindow (currentWindow); - SetWindowPos (myWindow.windowHandle, nextWindow, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - Sleep (delay); - } - else - { - Sleep (delay*count); - } -} -#endif - // 256 * sizeof(uint32_t) bool API::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, uint32_t *buffer) { diff --git a/library/DFKeys-linux.cpp b/library/DFKeys-linux.cpp new file mode 100644 index 000000000..f1ce72c2d --- /dev/null +++ b/library/DFKeys-linux.cpp @@ -0,0 +1,632 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ +#define LINUX_BUILD +#include "DFCommonInternal.h" +using namespace DFHack; + +// ENUMARATE THROUGH WINDOWS AND DISPLAY THEIR TITLES +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; + + char * win_name; + status = XFetchName (display, rootWindow, &win_name); + + if ( (status >= Success) && (win_name) && strcmp (win_name, searchString) == 0) + { + return rootWindow; + } + + level++; + + status = XQueryTree (display, rootWindow, &rootWindow, &parent, &children, &noOfChildren); + + if (status == 0) + { + return BadWindow; + } + + if (noOfChildren == 0) + { + return BadWindow; + } + for (i = 0; i < noOfChildren; i++) + { + Window tempWindow = EnumerateWindows (display, children[i], searchString); + if (tempWindow != BadWindow) + { + retWindow = tempWindow; + break; + } + } + + XFree ( (char*) children); + return retWindow; +} +// END ENUMERATE WINDOWS +bool getDFWindow (Display *dpy, Window& dfWindow, Window & rootWindow) +{ + // int numScreeens = ScreenCount(dpy); + for (int i = 0;i < ScreenCount (dpy);i++) + { + rootWindow = RootWindow (dpy, i); + Window retWindow = EnumerateWindows (dpy, rootWindow, "Dwarf Fortress"); + 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. + } + return false; +} +bool setWMClientLeaderProperty (Display *dpy, Window &dfWin, Window ¤tFocus) +{ + static bool propertySet; + if (propertySet) + { + return true; + } + Atom leaderAtom; + Atom type; + int format, status; + unsigned long nitems = 0; + unsigned long extra = 0; + unsigned char *data = 0; + Window result = 0; + leaderAtom = XInternAtom (dpy, "WM_CLIENT_LEADER", false); + status = XGetWindowProperty (dpy, currentFocus, leaderAtom, 0L, 1L, false, XA_WINDOW, &type, &format, &nitems, &extra, (unsigned char **) & data); + if (status == Success) + { + if (data != 0) + { + result = * ( (Window*) data); + XFree (data); + } + else + { + Window curr = currentFocus; + while (data == 0) + { + Window parent; + Window root; + Window *children; + uint numChildren; + XQueryTree (dpy, curr, &root, &parent, &children, &numChildren); + XGetWindowProperty (dpy, parent, leaderAtom, 0L, 1L, false, XA_WINDOW, &type, &format, &nitems, &extra, (unsigned char **) &data); + } + result = * ( (Window*) data); + XFree (data); + } + } + XChangeProperty (dpy, dfWin, leaderAtom, XA_WINDOW, 32, PropModeReplace, (const unsigned char *) &result, 1); + propertySet = true; + return true; +} +void API::TypeStr (const char *lpszString, int delay, bool useShift) +{ + ForceResume(); + Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY + Window dfWin; + Window rootWin; + if (getDFWindow (dpy, dfWin, rootWin)) + { + + XWindowAttributes currAttr; + Window currentFocus; + int currentRevert; + XGetInputFocus (dpy, ¤tFocus, ¤tRevert); //get current focus + setWMClientLeaderProperty (dpy, dfWin, currentFocus); + XGetWindowAttributes (dpy, dfWin, &currAttr); + if (currAttr.map_state == IsUnmapped) + { + XMapRaised (dpy, dfWin); + } + if (currAttr.map_state == IsUnviewable) + { + XRaiseWindow (dpy, dfWin); + } + XSync (dpy, false); + XSetInputFocus (dpy, dfWin, RevertToNone, CurrentTime); + XSync (dpy, false); + + char cChar; + KeyCode xkeycode; + char prevKey = 0; + int sleepAmnt = 0; + while ( (cChar = *lpszString++)) // loops through chars + { + 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 + XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), false, CurrentTime); + if (useShift || cChar >= 'A' && cChar <= 'Z') + { + XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), true, CurrentTime); + XSync (dpy, false); + } + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, false); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, false); + if (useShift || cChar >= 'A' && cChar <= 'Z') + { + XTestFakeKeyEvent (dpy, XKeysymToKeycode (dpy, XStringToKeysym ("Shift_L")), false, CurrentTime); + XSync (dpy, false); + } + + } + 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 + XLowerWindow (dpy, dfWin); + } + XSetInputFocus (dpy, currentFocus, currentRevert, CurrentTime); + XSync (dpy, true); + } + usleep (delay*1000); +} + +void API::TypeSpecial (t_special command, int count, int delay) +{ + ForceResume(); + if (command != WAIT) + { + KeySym mykeysym; + KeyCode xkeycode; + Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY + Window dfWin; + Window rootWin; + if (getDFWindow (dpy, dfWin, rootWin)) + { + XWindowAttributes currAttr; + Window currentFocus; + int currentRevert; + XGetInputFocus (dpy, ¤tFocus, ¤tRevert); //get current focus + setWMClientLeaderProperty (dpy, dfWin, currentFocus); + XGetWindowAttributes (dpy, dfWin, &currAttr); + if (currAttr.map_state == IsUnmapped) + { + XMapRaised (dpy, dfWin); + } + if (currAttr.map_state == IsUnviewable) + { + XRaiseWindow (dpy, dfWin); + } + XSync (dpy, false); + XSetInputFocus (dpy, dfWin, RevertToParent, CurrentTime); + + for (int i = 0;i < count; i++) + { + //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); + + switch (command) + { + case ENTER: + mykeysym = XStringToKeysym ("Return"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case SPACE: + mykeysym = XStringToKeysym ("space"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case BACK_SPACE: + mykeysym = XStringToKeysym ("BackSpace"); + xkeycode = XK_BackSpace; + xkeycode = XKeysymToKeycode (dpy, XK_BackSpace); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case TAB: + mykeysym = XStringToKeysym ("Tab"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case CAPS_LOCK: + mykeysym = XStringToKeysym ("Caps_Lock"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case LEFT_SHIFT: // I am not positive that this will work to distinguish the left and right.. + mykeysym = XStringToKeysym ("Shift_L"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case RIGHT_SHIFT: + mykeysym = XStringToKeysym ("Shift_R"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case LEFT_CONTROL: + mykeysym = XStringToKeysym ("Control_L"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + case RIGHT_CONTROL: + mykeysym = XStringToKeysym ("Control_R"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case ALT: + mykeysym = XStringToKeysym ("Alt_L"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case ESCAPE: + mykeysym = XStringToKeysym ("Escape"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case UP: + mykeysym = XStringToKeysym ("Up"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case DOWN: + mykeysym = XStringToKeysym ("Down"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case LEFT: + mykeysym = XStringToKeysym ("Left"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case RIGHT: + mykeysym = XStringToKeysym ("Right"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F1: + mykeysym = XStringToKeysym ("F1"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F2: + mykeysym = XStringToKeysym ("F2"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F3: + mykeysym = XStringToKeysym ("F3"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F4: + mykeysym = XStringToKeysym ("F4"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F5: + mykeysym = XStringToKeysym ("F5"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F6: + mykeysym = XStringToKeysym ("F6"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F7: + mykeysym = XStringToKeysym ("F7"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F8: + mykeysym = XStringToKeysym ("F8"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F9: + mykeysym = XStringToKeysym ("F9"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F11: + mykeysym = XStringToKeysym ("F11"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case F12: + mykeysym = XStringToKeysym ("F12"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case PAGE_UP: + mykeysym = XStringToKeysym ("Page_Up"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case PAGE_DOWN: + mykeysym = XStringToKeysym ("Page_Down"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case INSERT: + mykeysym = XStringToKeysym ("Insert"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEY_DELETE: + mykeysym = XStringToKeysym ("Delete"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case HOME: + mykeysym = XStringToKeysym ("Home"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case END: + mykeysym = XStringToKeysym ("End"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_DIVIDE: + mykeysym = XStringToKeysym ("KP_Divide"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_MULTIPLY: + mykeysym = XStringToKeysym ("KP_Multiply"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_SUBTRACT: + mykeysym = XStringToKeysym ("KP_Subtract"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_ADD: + mykeysym = XStringToKeysym ("KP_Add"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_ENTER: + mykeysym = XStringToKeysym ("KP_Enter"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_0: + mykeysym = XStringToKeysym ("KP_0"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_1: + mykeysym = XStringToKeysym ("KP_1"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_2: + mykeysym = XStringToKeysym ("KP_2"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_3: + mykeysym = XStringToKeysym ("KP_3"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_4: + mykeysym = XStringToKeysym ("KP_4"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_5: + mykeysym = XStringToKeysym ("KP_5"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_6: + mykeysym = XStringToKeysym ("KP_6"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_7: + mykeysym = XStringToKeysym ("KP_7"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_8: + mykeysym = XStringToKeysym ("KP_8"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_9: + mykeysym = XStringToKeysym ("KP_9"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + case KEYPAD_DECIMAL_POINT: + mykeysym = XStringToKeysym ("KP_Decimal"); + xkeycode = XKeysymToKeycode (dpy, mykeysym); + XTestFakeKeyEvent (dpy, xkeycode, true, CurrentTime); + XSync (dpy, true); + XTestFakeKeyEvent (dpy, xkeycode, false, CurrentTime); + XSync (dpy, true); + break; + } + usleep(20000); + } + if (currAttr.map_state == IsUnmapped) + { + XLowerWindow (dpy, dfWin); // can't unmap, because you lose task bar + } + XSetInputFocus (dpy, currentFocus, currentRevert, CurrentTime); + XSync (dpy, false); + } + } + else + { + usleep (delay*1000 * count); + } +} diff --git a/library/DFKeys-windows.cpp b/library/DFKeys-windows.cpp new file mode 100644 index 000000000..690075ab8 --- /dev/null +++ b/library/DFKeys-windows.cpp @@ -0,0 +1,341 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "DFCommonInternal.h" +using namespace DFHack; + +//Windows key handlers +struct window +{ + HWND windowHandle; + uint32_t pid; +}; +BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam) +{ + uint32_t pid; + + GetWindowThreadProcessId (hwnd, (LPDWORD) &pid); + if (pid == ( (window *) lParam)->pid) + { + ( (window *) lParam)->windowHandle = hwnd; + return FALSE; + } + return TRUE; +} +void API::TypeStr (const char *lpszString, int delay, bool useShift) +{ + //Resume(); + ForceResume(); + + //sendmessage needs a window handle HWND, so have to get that from the process HANDLE + HWND currentWindow = GetForegroundWindow(); + window myWindow; + myWindow.pid = GetProcessId (DFHack::g_ProcessHandle); + EnumWindows (EnumWindowsProc, (LPARAM) &myWindow); + + HWND nextWindow = GetWindow (myWindow.windowHandle, GW_HWNDNEXT); + + SetActiveWindow (myWindow.windowHandle); + SetForegroundWindow (myWindow.windowHandle); + + char cChar; + + while ( (cChar = *lpszString++)) // loops through chars + { + short vk = VkKeyScan (cChar); // keycode of char + if (useShift || (vk >> 8) &1) // char is capital, so need to hold down shift + { + //shift down + INPUT input[4] = {0}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_SHIFT; + + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = vk; + + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = vk; + input[2].ki.dwFlags = KEYEVENTF_KEYUP; + + // shift up + input[3].type = INPUT_KEYBOARD; + input[3].ki.wVk = VK_SHIFT; + input[3].ki.dwFlags = KEYEVENTF_KEYUP; + + SendInput (4, input, sizeof (input[0])); + } + else + { + INPUT input[2] = {0}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = vk; + + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = vk; + input[1].ki.dwFlags = KEYEVENTF_KEYUP; + SendInput (2, input, sizeof (input[0])); + } + } + SetForegroundWindow (currentWindow); + SetActiveWindow (currentWindow); + SetWindowPos (myWindow.windowHandle, nextWindow, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + Sleep (delay); + +} +void API::TypeSpecial (t_special command, int count, int delay) +{ + ForceResume(); + if (command != WAIT) + { + HWND currentWindow = GetForegroundWindow(); + window myWindow; + myWindow.pid = GetProcessId (DFHack::g_ProcessHandle); + EnumWindows (EnumWindowsProc, (LPARAM) &myWindow); + + HWND nextWindow = GetWindow (myWindow.windowHandle, GW_HWNDNEXT); + SetForegroundWindow (myWindow.windowHandle); + SetActiveWindow (myWindow.windowHandle); + INPUT shift; + shift.type = INPUT_KEYBOARD; + shift.ki.wVk = VK_SHIFT; + shift.ki.dwFlags = KEYEVENTF_KEYUP; + SendInput (1, &shift, sizeof (shift)); + INPUT input[2] = {0}; + input[0].type = INPUT_KEYBOARD; + input[1].type = INPUT_KEYBOARD; + input[1].ki.dwFlags = KEYEVENTF_KEYUP; + switch (command) + { + case ENTER: + input[0].ki.wVk = VK_RETURN; + input[1].ki.wVk = VK_RETURN; + break; + case SPACE: + input[0].ki.wVk = VK_SPACE; + input[1].ki.wVk = VK_SPACE; + break; + case BACK_SPACE: + input[0].ki.wVk = VK_BACK; + input[1].ki.wVk = VK_BACK; + break; + case TAB: + input[0].ki.wVk = VK_TAB; + input[1].ki.wVk = VK_TAB; + break; + case CAPS_LOCK: + input[0].ki.wVk = VK_CAPITAL; + input[1].ki.wVk = VK_CAPITAL; + break; + // These are only for pressing the modifier key itself, you can't do key combinations with them, like ctrl+C + case LEFT_SHIFT: // I am not positive that this will work to distinguish the left and right.. + input[0].ki.wVk = VK_LSHIFT; + input[1].ki.wVk = VK_LSHIFT; + break; + case RIGHT_SHIFT: + input[0].ki.wVk = VK_RSHIFT; + input[1].ki.wVk = VK_RSHIFT; + break; + case LEFT_CONTROL: + input[0].ki.wVk = VK_LCONTROL; + input[1].ki.wVk = VK_LCONTROL; + break; + case RIGHT_CONTROL: + input[0].ki.wVk = VK_RCONTROL; + input[1].ki.wVk = VK_RCONTROL; + break; + case ALT: + input[0].ki.wVk = VK_MENU; + input[1].ki.wVk = VK_MENU; + break; + case ESCAPE: + input[0].ki.wVk = VK_ESCAPE; + input[1].ki.wVk = VK_ESCAPE; + break; + case UP: + input[0].ki.wVk = VK_UP; + input[1].ki.wVk = VK_UP; + break; + case DOWN: + input[0].ki.wVk = VK_DOWN; + input[1].ki.wVk = VK_DOWN; + break; + case LEFT: + input[0].ki.wVk = VK_LEFT; + input[1].ki.wVk = VK_LEFT; + break; + case RIGHT: + input[0].ki.wVk = VK_RIGHT; + input[1].ki.wVk = VK_RIGHT; + break; + case F1: + input[0].ki.wVk = VK_F1; + input[1].ki.wVk = VK_F1; + break; + case F2: + input[0].ki.wVk = VK_F2; + input[1].ki.wVk = VK_F2; + break; + case F3: + input[0].ki.wVk = VK_F3; + input[1].ki.wVk = VK_F3; + break; + case F4: + input[0].ki.wVk = VK_F4; + input[1].ki.wVk = VK_F4; + break; + case F5: + input[0].ki.wVk = VK_F5; + input[1].ki.wVk = VK_F5; + break; + case F6: + input[0].ki.wVk = VK_F6; + input[1].ki.wVk = VK_F6; + break; + case F7: + input[0].ki.wVk = VK_F7; + input[1].ki.wVk = VK_F7; + break; + case F8: + input[0].ki.wVk = VK_F8; + input[1].ki.wVk = VK_F8; + break; + case F9: + input[0].ki.wVk = VK_F9; + input[1].ki.wVk = VK_F9; + break; + case F10: + input[0].ki.wVk = VK_F10; + input[1].ki.wVk = VK_F10; + break; + case F11: + input[0].ki.wVk = VK_F11; + input[1].ki.wVk = VK_F11; + break; + case F12: + input[0].ki.wVk = VK_F12; + input[1].ki.wVk = VK_F12; + break; + case PAGE_UP: + input[0].ki.wVk = VK_PRIOR; + input[1].ki.wVk = VK_PRIOR; + break; + case PAGE_DOWN: + input[0].ki.wVk = VK_NEXT; + input[1].ki.wVk = VK_NEXT; + break; + case INSERT: + input[0].ki.wVk = VK_INSERT; + input[1].ki.wVk = VK_INSERT; + break; + case KEY_DELETE: + input[0].ki.wVk = VK_DELETE; + input[1].ki.wVk = VK_DELETE; + break; + case HOME: + input[0].ki.wVk = VK_HOME; + input[1].ki.wVk = VK_HOME; + break; + case END: + input[0].ki.wVk = VK_END; + input[1].ki.wVk = VK_END; + break; + case KEYPAD_DIVIDE: + input[0].ki.wVk = VK_DIVIDE; + input[1].ki.wVk = VK_DIVIDE; + break; + case KEYPAD_MULTIPLY: + input[0].ki.wVk = VK_MULTIPLY; + input[1].ki.wVk = VK_MULTIPLY; + break; + case KEYPAD_SUBTRACT: + input[0].ki.wVk = VK_SUBTRACT; + input[1].ki.wVk = VK_SUBTRACT; + break; + case KEYPAD_ADD: + input[0].ki.wVk = VK_ADD; + input[1].ki.wVk = VK_ADD; + break; + case KEYPAD_ENTER: + input[0].ki.wVk = VK_RETURN; + input[1].ki.wVk = VK_RETURN; + break; + case KEYPAD_0: + input[0].ki.wVk = VK_NUMPAD0; + input[1].ki.wVk = VK_NUMPAD0; + break; + case KEYPAD_1: + input[0].ki.wVk = VK_NUMPAD1; + input[1].ki.wVk = VK_NUMPAD1; + break; + case KEYPAD_2: + input[0].ki.wVk = VK_NUMPAD2; + input[1].ki.wVk = VK_NUMPAD2; + break; + case KEYPAD_3: + input[0].ki.wVk = VK_NUMPAD3; + input[1].ki.wVk = VK_NUMPAD3; + break; + case KEYPAD_4: + input[0].ki.wVk = VK_NUMPAD4; + input[1].ki.wVk = VK_NUMPAD4; + break; + case KEYPAD_5: + input[0].ki.wVk = VK_NUMPAD5; + input[1].ki.wVk = VK_NUMPAD5; + break; + case KEYPAD_6: + input[0].ki.wVk = VK_NUMPAD6; + input[1].ki.wVk = VK_NUMPAD6; + break; + case KEYPAD_7: + input[0].ki.wVk = VK_NUMPAD7; + input[1].ki.wVk = VK_NUMPAD7; + break; + case KEYPAD_8: + input[0].ki.wVk = VK_NUMPAD8; + input[1].ki.wVk = VK_NUMPAD8; + break; + case KEYPAD_9: + input[0].ki.wVk = VK_NUMPAD9; + input[1].ki.wVk = VK_NUMPAD9; + break; + case KEYPAD_DECIMAL_POINT: + input[0].ki.wVk = VK_SEPARATOR; + input[1].ki.wVk = VK_SEPARATOR; + break; + } + for (int i = 0; i < count;i++) + { + SendInput (2, input, sizeof (input[0])); + } + SetForegroundWindow (currentWindow); + SetActiveWindow (currentWindow); + SetWindowPos (myWindow.windowHandle, nextWindow, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + Sleep (delay); + } + else + { + Sleep (delay*count); + } +}