From 81aa86ba66d935f06a476b37abb4f4e2c5aada72 Mon Sep 17 00:00:00 2001 From: koldo Date: Fri, 1 Apr 2016 20:38:25 +0000 Subject: [PATCH] SysInfo: Changing names git-svn-id: svn://ultimatepp.org/upp/trunk@9661 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- bazaar/SysInfo/Battery.cpp | 173 +++++++++ bazaar/SysInfo/CPUSpeed.cpp | 66 ++++ bazaar/SysInfo/MouseKey_.cpp | 535 --------------------------- bazaar/SysInfo/OS.cpp | 677 ++++++++++++++++++++++++++++++++++ bazaar/SysInfo/ScreenGrab.cpp | 618 +++++++++++++++++++++++++++++++ 5 files changed, 1534 insertions(+), 535 deletions(-) create mode 100644 bazaar/SysInfo/Battery.cpp create mode 100644 bazaar/SysInfo/CPUSpeed.cpp delete mode 100644 bazaar/SysInfo/MouseKey_.cpp create mode 100644 bazaar/SysInfo/OS.cpp create mode 100644 bazaar/SysInfo/ScreenGrab.cpp diff --git a/bazaar/SysInfo/Battery.cpp b/bazaar/SysInfo/Battery.cpp new file mode 100644 index 000000000..cf01b0449 --- /dev/null +++ b/bazaar/SysInfo/Battery.cpp @@ -0,0 +1,173 @@ +#include "SysInfo_in.h" + +NAMESPACE_UPP + +#ifdef PLATFORM_POSIX +bool GetBatteryStatus(bool &discharging, int &percentage, int &remainingMin) +{ +/* This is only if acpi package is present + StringParse data = Sys("acpi -V"); + + data.GoAfter("AC Adapter", ":"); + String sacStatus = data.GetText(); + discharging = sacStatus != "on-line"; + data.GoInit(); + data.GoAfter("Battery", ":"); + data.GoAfter(","); + percentage = data.GetInt("%"); + data.GoAfter(","); + String remaining; + if (discharging) { + remaining = data.GetText(" "); + int hour, min; + double secs; + StringToHMS(remaining, hour, min, secs); // It is really days:hour:min in this case + remainingMin = int(secs) + min*60 + hour*24*60; + } else + remainingMin = Null; +*/ + percentage = 100; + Vector files = SearchFile("/proc/acpi/battery", "state"); + if (files.GetCount() == 0) + return false; + StringParse state = LoadFile_Safe(files[0]); + if (state == "") + return false; + bool present; + if(!state.GoAfter_Init("present", ":")) + return false; + present = state.GetText() == "yes"; + if (!present) + return false; // No battery inserted + state.GoAfter_Init("charging state", ":"); discharging = state.GetText() == "discharging"; + int presentRate, remainingCapacity; + state.GoAfter_Init("present rate", ":"); presentRate = state.GetInt(); + state.GoAfter_Init("remaining capacity", ":"); remainingCapacity = state.GetInt(); + if (presentRate == 0 || !discharging) + remainingMin = Null; + else + remainingMin = (int)((60.*remainingCapacity)/presentRate); + + int designCapacity,lastFullCapacity; + String vendor, type, model, serial; + if (!GetBatteryInfo(present/*, designCapacity, lastFullCapacity, vendor, type, model, serial*/)) + percentage = (int)((100.*remainingCapacity)/lastFullCapacity); + + return true; +} + +bool GetBatteryInfo(bool &present/*, int &designCapacity, int &lastFullCapacity, String &vendor, String &type, String &model, String &serial*/) +{ + Vector files = SearchFile("/proc/acpi/battery", "info"); + if (files.GetCount() == 0) + return false; + StringParse info = LoadFile_Safe(files[0]); + if (info == "") + return false; + info.GoAfter_Init("present", ":"); present = info.GetText() == "yes"; + /* + info.GoAfter_Init("design capacity", ":"); designCapacity = info.GetInt(); + info.GoAfter_Init("last full capacity", ":");lastFullCapacity = info.GetInt(); + info.GoAfter_Init("OEM info", ":"); vendor = info.GetText(); + info.GoAfter_Init("battery type", ":"); type = info.GetText(); + info.GoAfter_Init("model number", ":"); model = info.GetText(); + info.GoAfter_Init("serial number", ":"); serial = info.GetText(); + */ + return true; +} + +bool OpenCDTray(String drive) +{ + String dummy; + return Sys("eject", dummy) > 0; +} +bool CloseCDTray(String drive) +{ + String dummy; + return Sys("eject -t", dummy) > 0; +} + +#endif +#if defined(PLATFORM_WIN32) || defined (PLATFORM_WIN64) +bool GetBatteryStatus(bool &discharging, int &percentage, int &remainingMin) +{ + SYSTEM_POWER_STATUS power; + + if(::GetSystemPowerStatus(&power) != 1) + return false; + + if (power.ACLineStatus == 1) + discharging = false; + else + discharging = true; + if (power.BatteryLifePercent <= 100) + percentage = power.BatteryLifePercent; + else + percentage = Null; + if (discharging && power.BatteryLifeTime != -1) + remainingMin = int(power.BatteryLifeTime/60); + else + remainingMin = Null; + return true; +} + +bool GetBatteryInfo(bool &present/*, int &designCapacity, int &lastFullCapacity, String &vendor, String &type, String &model, String &serial*/) +{ + SYSTEM_POWER_STATUS power; + + if(::GetSystemPowerStatus(&power) == 0) + return false; + if (power.BatteryFlag == 128) + return false; // No battery + + //designCapacity = (int)(power.BatteryFullLifeTime/60.); + + present = true; + //power.ACLineStatus == 0; + //lastFullCapacity = 0; + //vendor = type = model = serial = "UNKNOWN"; + + return true; +} + +bool DriveOpenClose(String drive, bool open) +{ + int operation; + if (open) + operation = IOCTL_STORAGE_EJECT_MEDIA; + else + operation = IOCTL_STORAGE_LOAD_MEDIA; + if (drive.IsEmpty()) + return false; + else if (drive.GetCount() == 1) + drive += ":"; + else { + drive = drive.Left(2); + if (drive[1] != ':') + return false; + } + HANDLE hDrive; + hDrive = CreateFile("\\\\.\\" + drive, GENERIC_READ || GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (hDrive == INVALID_HANDLE_VALUE) + return false; + bool ret = false; + DWORD dummyBytesReturned; + if (DeviceIoControl(hDrive, operation, 0, 0, 0, 0, &dummyBytesReturned, 0)) + ret = true; + CloseHandle(hDrive); + return ret; +} + +bool OpenCDTray(String drive) +{ + return DriveOpenClose(drive, true); +} + +bool CloseCDTray(String drive) +{ + return DriveOpenClose(drive, false); +} + +#endif + +END_UPP_NAMESPACE \ No newline at end of file diff --git a/bazaar/SysInfo/CPUSpeed.cpp b/bazaar/SysInfo/CPUSpeed.cpp new file mode 100644 index 000000000..d68ab2a21 --- /dev/null +++ b/bazaar/SysInfo/CPUSpeed.cpp @@ -0,0 +1,66 @@ +#include "SysInfo.h" + +NAMESPACE_UPP + +#if defined(PLATFORM_WIN32) || defined (PLATFORM_WIN64) +uint64 start, end; +unsigned long nCtr, nFreq, nCtrStop; + +#if defined(__MINGW32__) +uint64 __rdtsc() { + #if defined(__MINGW64__) // It does not work for now + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return uint64(lo) | (uint64(hi) << 32); + #else + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return uint64(lo) | (uint64(hi) << 32); + #endif +} +#endif + +int GetCpuSpeed() +{ + if(!QueryPerformanceFrequency((LARGE_INTEGER *) &nFreq)) + return 0; + QueryPerformanceCounter((LARGE_INTEGER *) &nCtrStop); + nCtrStop += nFreq; + + start = __rdtsc(); + do + QueryPerformanceCounter((LARGE_INTEGER *) &nCtr); + while (nCtr < nCtrStop); + end = __rdtsc(); + return int((end - start)/1000000); +} + +#endif + +#if defined(PLATFORM_POSIX) + +#define __rdtsc(tm) __asm__ __volatile__ (".byte 0x0f; .byte 0x31" :"=a" (tm)) +#define COUNT_SEC (double)tv.tv_sec + (1.e-6)*tv.tv_usec + +int GetCpuSpeed() +{ + struct timeval tv; + double cnt1, cnt2; + unsigned long start, end; + + __rdtsc(start); + gettimeofday(&tv, 0); + cnt1 = COUNT_SEC + 0.01; + + do { + gettimeofday(&tv, 0); + cnt2 = COUNT_SEC; + } while(cnt2 < cnt1); + + __rdtsc(end); + + return int((end-start)/10000); +} +#endif + +END_UPP_NAMESPACE \ No newline at end of file diff --git a/bazaar/SysInfo/MouseKey_.cpp b/bazaar/SysInfo/MouseKey_.cpp deleted file mode 100644 index 79f0e4a7a..000000000 --- a/bazaar/SysInfo/MouseKey_.cpp +++ /dev/null @@ -1,535 +0,0 @@ -#include "SysInfo_in.h" - -NAMESPACE_UPP - -struct KeyCodes { - String key; - int code; -}; - -#if defined(PLATFORM_WIN32) || defined (PLATFORM_WIN64) - -Array GetWinRegSubkeys(const String& key, HKEY base) { - HKEY hkey; - Array subkeys; - if(RegOpenKeyEx(base, key, 0, KEY_READ, &hkey) != ERROR_SUCCESS) - return subkeys; - char temp[_MAX_PATH]; - dword len; - for(dword dw = 0; len = sizeof(temp), RegEnumKeyEx(hkey, dw, temp, &len, 0, 0, 0, 0) == ERROR_SUCCESS; dw++) - subkeys.Add(temp); - RegCloseKey(hkey); - return subkeys; -} - -void Mouse_LeftDown() {mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);} -void Mouse_LeftUp() {mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);} -void Mouse_MiddleDown() {mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);} -void Mouse_MiddleUp() {mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);} -void Mouse_RightDown() {mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);} -void Mouse_RightUp() {mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);} - - -bool Mouse_SetPos(long xMove, long yMove, int64 windowId) { - long left, top, right, bottom; - - if (windowId != 0) { - Window_GetRect(windowId, left, top, right, bottom); - xMove = xMove + left; - yMove = yMove + top; - } - SetCursorPos(xMove, yMove); - - return true; -} - -bool Mouse_GetPos(long &x, long &y) { - POINT p; - - GetCursorPos (&p); - x = p.x; - y = p.y; - - return true; -} - -KeyCodes keyCodes[60] = { - "NUMPAD7", VK_NUMPAD7, "BACK", VK_BACK, - "NUMPAD8", VK_NUMPAD8, "TAB", VK_TAB, - "NUMPAD9", VK_NUMPAD9, "RETURN", VK_RETURN, - "MULTIPLY", VK_MULTIPLY, "SHIFT", VK_SHIFT, - "ADD", VK_ADD, "CONTROL", VK_CONTROL, - "SEPARATOR", VK_SEPARATOR, "MENU", VK_MENU, - "SUBTRACT", VK_SUBTRACT, "PAUSE", VK_PAUSE, - "DECIMAL", VK_DECIMAL, "CAPITAL", VK_CAPITAL, - "DIVIDE", VK_DIVIDE, "ESCAPE", VK_ESCAPE, - "F1", VK_F1, "SPACE", VK_SPACE, - "F2", VK_F2, "END", VK_END, - "F3", VK_F3, "HOME", VK_HOME, - "F4", VK_F4, "LEFT", VK_LEFT, - "F5", VK_F5, "UP", VK_UP, - "F6", VK_F6, "RIGHT", VK_RIGHT, - "F7", VK_F7, "DOWN", VK_DOWN, - "F8", VK_F8, "PRINT", VK_PRINT, - "F9", VK_F9, "SNAPSHOT", VK_SNAPSHOT, - "F10", VK_F10, "INSERT", VK_INSERT, - "F11", VK_F11, "DELETE", VK_DELETE, - "F12", VK_F12, "LWIN", VK_LWIN, - "NUMLOCK", VK_NUMLOCK, "RWIN", VK_RWIN, - "SCROLL", VK_SCROLL, "NUMPAD0", VK_NUMPAD0, - "LSHIFT", VK_LSHIFT, "NUMPAD1", VK_NUMPAD1, - "RSHIFT", VK_RSHIFT, "NUMPAD2", VK_NUMPAD2, - "LCONTROL", VK_LCONTROL, "NUMPAD3", VK_NUMPAD3, - "RCONTROL", VK_RCONTROL, "NUMPAD4", VK_NUMPAD4, - "LMENU", VK_LMENU, "NUMPAD5", VK_NUMPAD5, - "RMENU", VK_RMENU, "NUMPAD6", VK_NUMPAD6, - /*"PGUP", XK_Page_Up, "PGDOWN", XK_Page_Down - "CAPSLOCK", XK_Caps_Lock, "BACKSPACE",XK_BackSpace */ - "" -}; - -void PressKeyVK(int keyVK, bool hold = false, bool release = false, bool compatible = false) { - long nScan, nExtended; - - nScan = MapVirtualKey(keyVK, 2); - nExtended = 0; - if (nScan == 0) - nExtended = KEYEVENTF_EXTENDEDKEY; - nScan = MapVirtualKey(keyVK, 0); - - if (compatible) - nExtended = 0; - - if (!release) - keybd_event((BYTE)keyVK, (BYTE)nScan, nExtended, 0); - - if (!hold) - keybd_event((BYTE)keyVK, (BYTE)nScan, KEYEVENTF_KEYUP | nExtended, 0); -} - - -#if defined(__MINGW32__) -// #define MAPVK_VK_TO_VSC 0 -// #define MAPVK_VSC_TO_VK 1 - #ifndef MAPVK_VK_TO_CHAR - #define MAPVK_VK_TO_CHAR 2 - #endif -// #define MAPVK_VSC_TO_VK_EX 3 -#endif -//#define MAPVK_VK_TO_VSC_EX 4 - - -// This is less nice but more compatible for Notepad and MSWord for example -void PressKey(wchar key, bool hold = false, bool release = false) { - if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z') || (key >= '0' && key <= '9')) { - HKL hKeyboardLayout = ::GetKeyboardLayout(0); - SHORT nVK = VkKeyScanExW(key, hKeyboardLayout); - UINT nScan = MapVirtualKeyExW(nVK, MAPVK_VK_TO_CHAR, hKeyboardLayout); - if (!release) - keybd_event((BYTE)nVK, (BYTE)nScan, 0, 0); - if (!hold) - keybd_event((BYTE)nVK, (BYTE)nScan, KEYEVENTF_KEYUP, 0); - } else { - String numStr = FormatIntDec(key, 5, '0'); - PressKeyVK(VK_LMENU, true); - PressKeyVK(VK_NUMPAD0 + numStr[0] - '0'); - PressKeyVK(VK_NUMPAD0 + numStr[1] - '0'); - PressKeyVK(VK_NUMPAD0 + numStr[2] - '0'); - PressKeyVK(VK_NUMPAD0 + numStr[3] - '0'); - PressKeyVK(VK_NUMPAD0 + numStr[4] - '0'); - PressKeyVK(VK_LMENU, false, true); - } -} -/* -void PressKey(wchar key, bool hold = false, bool release = false) -{ - bool caps, num, scroll; - if (IsLetter(key)) { - GetKeyLockStatus(caps, num, scroll); - if (caps) - SetKeyLockStatus(false, num, scroll); - } - HKL hKeyboardLayout = ::GetKeyboardLayout(0); - if (hKeyboardLayout) { // Last resource !! - String numStr = FormatIntDec(key, 4, '0'); - PressKeyVK(VK_LMENU, true); - PressKeyVK(VK_NUMPAD0 + numStr[0] - '0'); - PressKeyVK(VK_NUMPAD0 + numStr[1] - '0'); - PressKeyVK(VK_NUMPAD0 + numStr[2] - '0'); - PressKeyVK(VK_NUMPAD0 + numStr[3] - '0'); - PressKeyVK(VK_LMENU, false, true); - return; - } - UINT nScan = MapVirtualKeyExW(nVK, MAPVK_VK_TO_CHAR, hKeyboardLayout); - long nExtended = 0; - if (nScan == 0) - nExtended = KEYEVENTF_EXTENDEDKEY; - - nScan = MapVirtualKeyExW(nVK, MAPVK_VK_TO_VSC, hKeyboardLayout); - - bool shift, ctrl, alt; - - shift = nVK & 0x100; - ctrl = nVK & 0x200; - alt = nVK & 0x400; - nVK = nVK & 0xFF; - - if (!release) { - if (shift) - keybd_event (VK_SHIFT, 0, 0, 0); - if (ctrl) - keybd_event (VK_CONTROL, 0, 0, 0); - if (alt) - keybd_event (VK_MENU, 0, 0, 0); - - keybd_event ((BYTE)nVK, (BYTE)nScan, nExtended, 0); - } - if (!hold) { - keybd_event ((BYTE)nVK, (BYTE)nScan, KEYEVENTF_KEYUP | nExtended, 0); - - if (shift) - keybd_event (VK_SHIFT, 0, KEYEVENTF_KEYUP, 0); - if (ctrl) - keybd_event (VK_CONTROL, 0, KEYEVENTF_KEYUP, 0); - if (alt) - keybd_event (VK_MENU, 0, KEYEVENTF_KEYUP, 0); - } - if (IsLetter(key) && caps) - SetKeyLockStatus(true, num, scroll); -} -*/ - -bool GetKeyLockStatus(bool &caps, bool &num, bool &scroll) { - caps = GetKeyState(VK_CAPITAL); - num = GetKeyState(VK_NUMLOCK); - scroll = GetKeyState(VK_SCROLL); - return true; -} - -bool SetKeyLockStatus(bool caps, bool num, bool scroll) { - bool capsnow, numnow, scrollnow; - - GetKeyLockStatus(capsnow, numnow, scrollnow); - if (capsnow != caps) - PressKeyVK(VK_CAPITAL); - if (numnow != num) - PressKeyVK(VK_NUMLOCK); - if (scrollnow != scroll) - PressKeyVK(VK_SCROLL); - return true; -} - -#endif - -#ifdef PLATFORM_POSIX - -bool Mouse_GetPos(long &x, long &y) { - SetSysInfoX11ErrorHandler(); - _XDisplay *dpy = XOpenDisplay (NULL); - if (!dpy) { - SetX11ErrorHandler(); - return false; - } - bool ret = false; - Window root, child; - Window r = DefaultRootWindow(dpy); - int retx, rety; - int wx, wy; - unsigned int keys_buttons; - if (XQueryPointer(dpy, r, &root, &child, &retx, &rety, &wx, &wy, &keys_buttons)) { - x = wx; - y = wy; - ret = true; - } else - x = y = -1; - - XCloseDisplay (dpy); - SetX11ErrorHandler(); - - return ret; -} - -bool Mouse_SetPos(long x, long y, int64 windowId) { - SetSysInfoX11ErrorHandler(); - _XDisplay *dpy = XOpenDisplay (NULL); - if (!dpy) { - SetX11ErrorHandler(); - return false; - } - long left, top, right, bottom; - Window r = DefaultRootWindow(dpy); - if (windowId != 0) { - Window_GetRect(windowId, left, top, right, bottom); - x = x + left; - y = y + top; - } - XWarpPointer(dpy, None, r, 0, 0, 0, 0, x, y); - XCloseDisplay (dpy); - SetX11ErrorHandler(); - - return true; -} - -// libxtst-dev -#if !defined(flagNO_XTEST) - -void Mouse_FakeClick(int button, int press) { - _XDisplay *dpy = XOpenDisplay(NULL); - XTestFakeButtonEvent(dpy, button, press, CurrentTime); - XFlush(dpy); - XCloseDisplay(dpy); -} - -void Mouse_LeftDown() {Mouse_FakeClick(1, True);} -void Mouse_LeftUp() {Mouse_FakeClick(1, False);} -void Mouse_MiddleDown() {Mouse_FakeClick(2, True);} -void Mouse_MiddleUp() {Mouse_FakeClick(2, False);} -void Mouse_RightDown() {Mouse_FakeClick(3, True);} -void Mouse_RightUp() {Mouse_FakeClick(3, False);} - -void PressKeyVK(int key, _XDisplay *dpy = NULL) { - bool local = false; - if (!dpy) { - if (!(dpy = XOpenDisplay(NULL))) - return; - local = true; - } - XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, key), True, CurrentTime); - XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, key), False, CurrentTime); - if (local) { - XFlush(dpy); - XCloseDisplay(dpy); - } -} - -void PressKey(wchar key, _XDisplay *dpy = NULL) { - bool local = false; - if (!dpy) { - if (!(dpy = XOpenDisplay(NULL))) - return; - local = true; - } - wchar k = key; - if (key > 0x00ff) - key = key | 0x01000000; - - bool shift = false; - KeyCode code = XKeysymToKeycode(dpy, key); - if (code != 0) { - if (XkbKeycodeToKeysym(dpy, code, 0, 0) != key) { - if (XkbKeycodeToKeysym(dpy, code, 1, 0) == key) - shift = true; - else - code = 0; - } - } else { - int firstKeycode, maxKeycode; - int keysymsPerKeycode; - - XDisplayKeycodes(dpy, &firstKeycode, &maxKeycode); - KeySym *keysyms = XGetKeyboardMapping(dpy, firstKeycode, maxKeycode - firstKeycode + 1, &keysymsPerKeycode); - int indx = (maxKeycode - firstKeycode - 1)*keysymsPerKeycode; - keysyms[indx] = key; - XChangeKeyboardMapping(dpy, firstKeycode, keysymsPerKeycode, keysyms, maxKeycode-firstKeycode); - XSync(dpy, False); - code = maxKeycode-1; - if (XkbKeycodeToKeysym(dpy, code, 0, 0) != key) { - if (XkbKeycodeToKeysym(dpy, code, 1, 0) == key) - shift = true; - } - } - if (code != 0) { - if (shift) - XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, XK_Shift_L), True, CurrentTime); - XTestFakeKeyEvent(dpy, code, True, CurrentTime); - XTestFakeKeyEvent(dpy, code, False, CurrentTime); - if (shift) - XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, XK_Shift_L), False, CurrentTime); - } - if (local) { - XFlush(dpy); - XCloseDisplay(dpy); - } -} - -#endif - -bool GetKeyLockStatus0(bool &caps, bool &num, bool &scroll, _XDisplay *dpy) { - int x, y, xx, yy; - Window dm1, dm2; - unsigned int sKbdState; - - if(!XQueryPointer(dpy, DefaultRootWindow(dpy), &dm1, &dm2, &x, &y, &xx, &yy, &sKbdState)) - return false; - - caps = sKbdState & LockMask; - num = sKbdState & Mod2Mask; - scroll = sKbdState & Mod5Mask; - - return true; -} - -bool GetKeyLockStatus(bool &caps, bool &num, bool &scroll) { - _XDisplay *dpy; - if (!(dpy = XOpenDisplay(NULL))) - return false; - - if (!GetKeyLockStatus0(caps, num, scroll, dpy)) { - XCloseDisplay(dpy); - return false; - } - XFlush(dpy); - XCloseDisplay(dpy); - return true; -} - -#if !defined(flagNO_XTEST) - -bool SetKeyLockStatus(bool caps, bool num, bool scroll) { - _XDisplay *dpy; - if (!(dpy = XOpenDisplay(NULL))) - return false; - - bool oldcaps, oldnum, oldscroll; - if (!GetKeyLockStatus0(oldcaps, oldnum, oldscroll, dpy)) { - XCloseDisplay(dpy); - return false; - } - if (caps != oldcaps) - PressKeyVK(XK_Caps_Lock, dpy); - if (num != oldnum) - PressKeyVK(XK_Num_Lock, dpy); - if (scroll != oldscroll) - PressKeyVK(XK_Scroll_Lock, dpy); - - XFlush(dpy); - XCloseDisplay(dpy); - return true; -} - -KeyCodes keyCodes[] = { - "NUMPAD7", XK_KP_7, "BACK", XK_BackSpace, - "NUMPAD8", XK_KP_8, "TAB", XK_Tab, - "NUMPAD9", XK_KP_9, "RETURN", XK_Return, - "MULTIPLY", XK_KP_Multiply, "SHIFT", XK_Shift_Lock, - "ADD", XK_KP_Add, "CONTROL", XK_Control_L, - "SEPARATOR", XK_KP_Separator,"MENU", XK_Super_L, - "SUBTRACT", XK_KP_Subtract, "PAUSE", XK_Pause, - "DECIMAL", XK_KP_Decimal, /*"CAPITAL", VK_CAPITAL,*/ - "DIVIDE", XK_KP_Divide, "ESCAPE", XK_Escape, - "F1", XK_F1, "SPACE", XK_KP_Space, - "F2", XK_F2, "END", XK_End, - "F3", XK_F3, "HOME", XK_Home, - "F4", XK_F4, "LEFT", XK_Left, - "F5", XK_F5, "UP", XK_Up, - "F6", XK_F6, "RIGHT", XK_Right, - "F7", XK_F7, "DOWN", XK_Down, - "F8", XK_F8, "PRINT", XK_Sys_Req, - "F9", XK_F9, /*"SNAPSHOT", VK_SNAPSHOT,*/ - "F10", XK_F10, "INSERT", XK_Insert, - "F11", XK_F11, "DELETE", XK_Delete, - "F12", XK_F12, "LWIN", XK_Meta_L, - "NUMLOCK", XK_Num_Lock, "RWIN", XK_Meta_R, - "SCROLL", XK_Scroll_Lock, "NUMPAD0", XK_KP_0, - "LSHIFT", XK_Shift_L, "NUMPAD1", XK_KP_1, - "RSHIFT", XK_Shift_R, "NUMPAD2", XK_KP_2, - "LCONTROL", XK_Control_L, "NUMPAD3", XK_KP_3, - "RCONTROL", XK_Control_R, "NUMPAD4", XK_KP_4, - "LMENU", XK_Super_L, "NUMPAD5", XK_KP_5, - "RMENU", XK_Super_R, "NUMPAD6", XK_KP_6, - "PGUP", XK_Page_Up, "PGDOWN", XK_Page_Down, - "CAPSLOCK", XK_Caps_Lock, "BACKSPACE",XK_BackSpace, - "" -}; -#endif - -#endif - -#if defined(PLATFORM_WIN32) || !defined(flagNO_XTEST) - -void Mouse_LeftClick() -{ - Mouse_LeftDown(); - Mouse_LeftUp(); -} -void Mouse_RightClick() -{ - Mouse_RightDown(); - Mouse_RightUp(); -} -void Mouse_MiddleClick() -{ - Mouse_MiddleDown(); - Mouse_MiddleUp(); -} -void Mouse_LeftDblClick() -{ - Mouse_LeftClick(); - Mouse_LeftClick(); -} -void Mouse_MiddleDblClick() -{ - Mouse_MiddleClick(); - Mouse_MiddleClick(); -} -void Mouse_RightDblClick() -{ - Mouse_RightClick(); - Mouse_RightClick(); -} - -int GetKeyCode(String key) { - for (int i = 0; keyCodes[i].code != 0; ++i) - if (keyCodes[i].key == key) - return keyCodes[i].code; - return 0; -} - -void Keyb_SendKeys(String text, long finalDelay, long delayBetweenKeys) -{ - Array virt; - bool inKey = false; - String key = ""; - WString wtext(text); - for (int i = 0; i < wtext.GetCount(); ++i) { - bool vk = false; - Sleep(delayBetweenKeys); - wchar c = wtext[i]; - if (c == '{') - inKey = true; - else if (c == '}') { - if (key == "{") - c = '{'; - else { - c = GetKeyCode(key); - vk = true; - } - inKey = false; - key = ""; - } else if (inKey == 1) - key.Cat(c); - else if (c == '\n') { - c = GetKeyCode("RETURN"); - vk = true; - } - if (inKey == false) { - if (!vk) - PressKey(c); -#if defined(PLATFORM_WIN32) || defined (PLATFORM_WIN64) - else { - PressKeyVK(c, true); - virt.Add(c); - } -#endif - } - } -#if defined(PLATFORM_WIN32) || defined (PLATFORM_WIN64) - for (int i = 0; i < virt.GetCount(); ++i) - PressKeyVK(virt[i], false, true); -#endif - Sleep(finalDelay); -} - -#endif - -END_UPP_NAMESPACE \ No newline at end of file diff --git a/bazaar/SysInfo/OS.cpp b/bazaar/SysInfo/OS.cpp new file mode 100644 index 000000000..68597b36a --- /dev/null +++ b/bazaar/SysInfo/OS.cpp @@ -0,0 +1,677 @@ +#include "SysInfo_in.h" + +NAMESPACE_UPP + +#if defined(PLATFORM_WIN32) || defined (PLATFORM_WIN64) + +#ifndef PRODUCT_UNLICENSED + #define PRODUCT_UNLICENSED 0xABCDABCD +#endif +#ifndef PRODUCT_BUSINESS + #define PRODUCT_BUSINESS 0x00000006 +#endif +#ifndef PRODUCT_BUSINESS_N + #define PRODUCT_BUSINESS_N 0x00000010 +#endif +#ifndef PRODUCT_CLUSTER_SERVER + #define PRODUCT_CLUSTER_SERVER 0x00000012 +#endif +#ifndef PRODUCT_CLUSTER_SERVER_V + #define PRODUCT_CLUSTER_SERVER_V 0x00000040 +#endif +#ifndef PRODUCT_CORE + #define PRODUCT_CORE 0x00000065 +#endif +#ifndef PRODUCT_CORE_N + #define PRODUCT_CORE_N 0x00000062 +#endif +#ifndef PRODUCT_CORE_COUNTRYSPECIFIC + #define PRODUCT_CORE_COUNTRYSPECIFIC 0x00000063 +#endif +#ifndef PRODUCT_CORE_SINGLELANGUAGE + #define PRODUCT_CORE_SINGLELANGUAGE 0x00000064 +#endif +#ifndef PRODUCT_DATACENTER_EVALUATION_SERVER + #define PRODUCT_DATACENTER_EVALUATION_SERVER 0x00000050 +#endif +#ifndef PRODUCT_DATACENTER_SERVER + #define PRODUCT_DATACENTER_SERVER 0x00000008 +#endif +#ifndef PRODUCT_DATACENTER_SERVER_CORE + #define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C +#endif +#ifndef PRODUCT_DATACENTER_SERVER_CORE_V + #define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027 +#endif +#ifndef PRODUCT_DATACENTER_SERVER_V + #define PRODUCT_DATACENTER_SERVER_V 0x00000025 +#endif +#ifndef PRODUCT_ENTERPRISE + #define PRODUCT_ENTERPRISE 0x00000004 +#endif +#ifndef PRODUCT_ENTERPRISE_E + #define PRODUCT_ENTERPRISE_E 0x00000046 +#endif +#ifndef PRODUCT_ENTERPRISE_N_EVALUATION + #define PRODUCT_ENTERPRISE_N_EVALUATION 0x00000054 +#endif +#ifndef PRODUCT_ENTERPRISE_N + #define PRODUCT_ENTERPRISE_N 0x0000001B +#endif +#ifndef PRODUCT_ENTERPRISE_EVALUATION + #define PRODUCT_ENTERPRISE_EVALUATION 0x00000048 +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER + #define PRODUCT_ENTERPRISE_SERVER 0x0000000A +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER_CORE + #define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER_CORE_V + #define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029 +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER_IA64 + #define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER_V + #define PRODUCT_ENTERPRISE_SERVER_V 0x00000026 +#endif +#ifndef PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT + #define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT 0x0000003B +#endif +#ifndef PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL + #define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL 0x0000003C +#endif +#ifndef PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC + #define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC 0x0000003D +#endif +#ifndef PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC + #define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC 0x0000003E +#endif +#ifndef PRODUCT_HOME_BASIC + #define PRODUCT_HOME_BASIC 0x00000002 +#endif +#ifndef PRODUCT_HOME_BASIC_E + #define PRODUCT_HOME_BASIC_E 0x00000043 +#endif +#ifndef PRODUCT_HOME_BASIC_N + #define PRODUCT_HOME_BASIC_N 0x00000005 +#endif +#ifndef PRODUCT_HOME_PREMIUM + #define PRODUCT_HOME_PREMIUM 0x00000003 +#endif +#ifndef PRODUCT_HOME_PREMIUM_E + #define PRODUCT_HOME_PREMIUM_E 0x00000044 +#endif +#ifndef PRODUCT_HOME_PREMIUM_N + #define PRODUCT_HOME_PREMIUM_N 0x0000001A +#endif +#ifndef PRODUCT_HOME_PREMIUM_SERVER + #define PRODUCT_HOME_PREMIUM_SERVER 0x00000022 +#endif +#ifndef PRODUCT_HOME_SERVER + #define PRODUCT_HOME_SERVER 0x00000013 +#endif +#ifndef PRODUCT_HYPERV + #define PRODUCT_HYPERV 0x0000002A +#endif +#ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT + #define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E +#endif +#ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING + #define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020 +#endif +#ifndef PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY + #define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F +#endif +#ifndef PRODUCT_MULTIPOINT_STANDARD_SERVER + #define PRODUCT_MULTIPOINT_STANDARD_SERVER 0x0000004C +#endif +#ifndef PRODUCT_MULTIPOINT_PREMIUM_SERVER + #define PRODUCT_MULTIPOINT_PREMIUM_SERVER 0x0000004D +#endif +#ifndef PRODUCT_PROFESSIONAL + #define PRODUCT_PROFESSIONAL 0x00000030 +#endif +#ifndef PRODUCT_PROFESSIONAL_E + #define PRODUCT_PROFESSIONAL_E 0x00000045 +#endif +#ifndef PRODUCT_PROFESSIONAL_N + #define PRODUCT_PROFESSIONAL_N 0x00000031 +#endif +#ifndef PRODUCT_PROFESSIONAL_WMC + #define PRODUCT_PROFESSIONAL_WMC 0x00000067 +#endif +#ifndef PRODUCT_SB_SOLUTION_SERVER_EM + #define PRODUCT_SB_SOLUTION_SERVER_EM 0x00000036 +#endif +#ifndef PRODUCT_SERVER_FOR_SB_SOLUTIONS + #define PRODUCT_SERVER_FOR_SB_SOLUTIONS 0x00000033 +#endif +#ifndef PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM + #define PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM 0x00000037 +#endif +#ifndef PRODUCT_SERVER_FOR_SMALLBUSINESS + #define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 +#endif +#ifndef PRODUCT_SERVER_FOR_SMALLBUSINESS_V + #define PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023 +#endif +#ifndef PRODUCT_SERVER_FOUNDATION + #define PRODUCT_SERVER_FOUNDATION 0x00000021 +#endif +#ifndef PRODUCT_SB_SOLUTION_SERVER + #define PRODUCT_SB_SOLUTION_SERVER 0x00000032 +#endif +#ifndef PRODUCT_SMALLBUSINESS_SERVER + #define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 +#endif +#ifndef PRODUCT_SMALLBUSINESS_SERVER_PREMIUM + #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019 +#endif +#ifndef PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE + #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE 0x0000003F +#endif +#ifndef PRODUCT_SOLUTION_EMBEDDEDSERVER + #define PRODUCT_SOLUTION_EMBEDDEDSERVER 0x00000038 +#endif +#ifndef PRODUCT_STANDARD_EVALUATION_SERVER + #define PRODUCT_STANDARD_EVALUATION_SERVER 0x0000004F +#endif +#ifndef PRODUCT_STANDARD_SERVER + #define PRODUCT_STANDARD_SERVER 0x00000007 +#endif +#ifndef PRODUCT_STANDARD_SERVER_CORE + #define PRODUCT_STANDARD_SERVER_CORE 0x0000000D +#endif +#ifndef PRODUCT_STANDARD_SERVER_V + #define PRODUCT_STANDARD_SERVER_V 0x00000024 +#endif +#ifndef PRODUCT_STANDARD_SERVER_CORE_V + #define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028 +#endif +#ifndef PRODUCT_STANDARD_SERVER_SOLUTIONS + #define PRODUCT_STANDARD_SERVER_SOLUTIONS 0x00000034 +#endif +#ifndef PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE + #define PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE 0x00000035 +#endif +#ifndef PRODUCT_STARTER + #define PRODUCT_STARTER 0x0000000B +#endif +#ifndef PRODUCT_STARTER_E + #define PRODUCT_STARTER_E 0x00000042 +#endif +#ifndef PRODUCT_STARTER_N + #define PRODUCT_STARTER_N 0x0000002F +#endif +#ifndef PRODUCT_STORAGE_ENTERPRISE_SERVER + #define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 +#endif +#ifndef PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE + #define PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE 0x0000002E +#endif +#ifndef PRODUCT_STORAGE_EXPRESS_SERVER + #define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 +#endif +#ifndef PRODUCT_STORAGE_EXPRESS_SERVER_CORE + #define PRODUCT_STORAGE_EXPRESS_SERVER_CORE 0x0000002B +#endif +#ifndef PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER + #define PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER 0x00000060 +#endif +#ifndef PRODUCT_STORAGE_STANDARD_SERVER + #define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 +#endif +#ifndef PRODUCT_STORAGE_STANDARD_SERVER_CORE + #define PRODUCT_STORAGE_STANDARD_SERVER_CORE 0x0000002C +#endif +#ifndef PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER + #define PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER 0x0000005F +#endif +#ifndef PRODUCT_STORAGE_WORKGROUP_SERVER + #define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 +#endif +#ifndef PRODUCT_STORAGE_WORKGROUP_SERVER_CORE + #define PRODUCT_STORAGE_WORKGROUP_SERVER_CORE 0x0000002D +#endif +#ifndef PRODUCT_UNDEFINED + #define PRODUCT_UNDEFINED 0x00000000 +#endif +#ifndef PRODUCT_ULTIMATE + #define PRODUCT_ULTIMATE 0x00000001 +#endif +#ifndef PRODUCT_ULTIMATE_E + #define PRODUCT_ULTIMATE_E 0x00000047 +#endif +#ifndef PRODUCT_ULTIMATE_N + #define PRODUCT_ULTIMATE_N 0x0000001C +#endif +#ifndef PRODUCT_WEB_SERVER + #define PRODUCT_WEB_SERVER 0x00000011 +#endif +#ifndef PRODUCT_WEB_SERVER_CORE + #define PRODUCT_WEB_SERVER_CORE 0x0000001D +#endif +#ifndef SM_SERVERR2 + #define SM_SERVERR2 89 +#endif +#ifndef VER_SUITE_WH_SERVER + #define VER_SUITE_WH_SERVER 0x00008000 +#endif + +typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); +typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); + + +bool GetOsInfo(String &kernel, String &kerVersion, String &kerArchitecture, String &distro, + String &distVersion, String &desktop, String &deskVersion) +{ + OSVERSIONINFOEX osvi; + SYSTEM_INFO si; + PGNSI pGNSI; + PGPI pGPI; + BOOL bOsVersionInfoEx; + + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&osvi))) + return false; + + // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. + pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); + if(NULL != pGNSI) + pGNSI(&si); + else + GetSystemInfo(&si); + + kerVersion = Format("%d.%d", (int)osvi.dwMajorVersion, (int)osvi.dwMinorVersion); + kernel = "Windows"; + switch(si.wProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_AMD64: kerArchitecture = "64 bits"; break; + case PROCESSOR_ARCHITECTURE_IA64: kerArchitecture = "Itanium 64 bits"; break; + case PROCESSOR_ARCHITECTURE_INTEL: kerArchitecture = "32 bits"; break; + default: kerArchitecture = "Unknown"; + } + if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4) { + if (osvi.dwMajorVersion == 6) { + if (osvi.dwMinorVersion == 3) { + if (osvi.wProductType == VER_NT_WORKSTATION) + kernel.Cat(" 8.1"); + else + kernel.Cat(" Server 2012 R2"); + } else if (osvi.dwMinorVersion == 2) { + if (osvi.wProductType == VER_NT_WORKSTATION) + kernel.Cat(" 8"); + else + kernel.Cat(" Server 2012"); + } else if (osvi.dwMinorVersion == 1) { + if (osvi.wProductType == VER_NT_WORKSTATION) + kernel.Cat(" 7"); + else + kernel.Cat(" Server 2008 R2"); + } else if (osvi.dwMinorVersion == 0) { + if (osvi.wProductType == VER_NT_WORKSTATION) + kernel.Cat(" Vista"); + else + kernel.Cat(" Server 2008"); + } + pGPI = (PGPI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); + DWORD dwType; + if (pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType)) { + switch(dwType) { + case PRODUCT_UNLICENSED: distro = "Unlicensed"; break; + case PRODUCT_BUSINESS: distro = "Business Edition"; break; + case PRODUCT_BUSINESS_N: distro = "Business Edition N"; break; + case PRODUCT_CLUSTER_SERVER: distro = "HPC Edition"; break; + case PRODUCT_CLUSTER_SERVER_V: distro = "Server Hyper Core V"; break; + case PRODUCT_CORE: distro = "Windows 8"; break; + case PRODUCT_CORE_N: distro = "Windows 8 N"; break; + case PRODUCT_CORE_COUNTRYSPECIFIC: distro = "Windows 8 China"; break; + case PRODUCT_CORE_SINGLELANGUAGE: distro = "Windows 8 Single Language"; break; + case PRODUCT_DATACENTER_EVALUATION_SERVER: distro = "Server Datacenter (evaluation installation)"; break; + case PRODUCT_DATACENTER_SERVER: distro = "Server Datacenter (full installation)"; break; + case PRODUCT_DATACENTER_SERVER_CORE: distro = "Server Datacenter (core installation)"; break; + case PRODUCT_DATACENTER_SERVER_CORE_V: distro = "Server Datacenter without Hyper-V (core installation)"; break; + case PRODUCT_DATACENTER_SERVER_V: distro = "Server Datacenter without Hyper-V (full installation)"; break; + case PRODUCT_ENTERPRISE: distro = "Enterprise"; break; + case PRODUCT_ENTERPRISE_E: distro = "Not supported"; break; + case PRODUCT_ENTERPRISE_N_EVALUATION: distro = "Enterprise N (evaluation installation)"; break; + case PRODUCT_ENTERPRISE_N: distro = "Enterprise N"; break; + case PRODUCT_ENTERPRISE_EVALUATION: distro = "Server Enterprise (evaluation installation)"; break; + case PRODUCT_ENTERPRISE_SERVER: distro = "Server Enterprise (full installation)"; break; + case PRODUCT_ENTERPRISE_SERVER_CORE: distro = "Server Enterprise (core installation)"; break; + case PRODUCT_ENTERPRISE_SERVER_CORE_V: distro = "Server Enterprise without Hyper-V (core installation)"; break; + case PRODUCT_ENTERPRISE_SERVER_IA64: distro = "Server Enterprise for Itanium-based Systems"; break; + case PRODUCT_ENTERPRISE_SERVER_V: distro = "Server Enterprise without Hyper-V (full installation)"; break; + case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT: distro = "Windows Essential Server Solution Management"; break; + case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL: distro = "Windows Essential Server Solution Additional"; break; + case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC: distro = "Windows Essential Server Solution Management SVC"; break; + case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC: distro = "Windows Essential Server Solution Additional SVC"; break; + case PRODUCT_HOME_BASIC: distro = "Home Basic"; break; + case PRODUCT_HOME_BASIC_E: distro = "Not supported"; break; + case PRODUCT_HOME_BASIC_N: distro = "Home Basic N"; break; + case PRODUCT_HOME_PREMIUM: distro = "Home Premium"; break; + case PRODUCT_HOME_PREMIUM_E: distro = "Not supported"; break; + case PRODUCT_HOME_PREMIUM_N: distro = "Home Premium N"; break; + case PRODUCT_HOME_PREMIUM_SERVER: distro = "Windows Home Server 2011"; break; + case PRODUCT_HOME_SERVER: distro = "Windows Storage Server 2008 R2 Essentials"; break; + case PRODUCT_HYPERV: distro = "Microsoft Hyper-V Server"; break; + case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT: distro = "Windows Essential Business Server Management Server"; break; + case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING: distro = "Windows Essential Business Server Messaging Server"; break; + case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY: distro = "Windows Essential Business Server Security Server"; break; + case PRODUCT_MULTIPOINT_STANDARD_SERVER: distro = "Windows MultiPoint Server Standard (full installation)"; break; + case PRODUCT_MULTIPOINT_PREMIUM_SERVER: distro = "Windows MultiPoint Server Premium (full installation)"; break; + case PRODUCT_PROFESSIONAL: distro = "Professional"; break; + case PRODUCT_PROFESSIONAL_E: distro = "Not supported"; break; + case PRODUCT_PROFESSIONAL_N: distro = "Professional N"; break; + case PRODUCT_PROFESSIONAL_WMC: distro = "Professional with Media Center"; break; + case PRODUCT_SB_SOLUTION_SERVER_EM: distro = "Server For SB Solutions EM"; break; + case PRODUCT_SERVER_FOR_SB_SOLUTIONS: distro = "Server For SB Solutions"; break; + case PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM: distro = "Server For SB Solutions EM"; break; + case PRODUCT_SERVER_FOR_SMALLBUSINESS: distro = "Windows Server 2008 for Windows Essential Server Solutions"; break; + case PRODUCT_SERVER_FOR_SMALLBUSINESS_V: distro = "Windows Server 2008 without Hyper-V for Windows Essential Server Solutions"; break; + case PRODUCT_SERVER_FOUNDATION: distro = "Server Foundation"; break; + case PRODUCT_SB_SOLUTION_SERVER: distro = "Windows Small Business Server 2011 Essentials"; break; + case PRODUCT_SMALLBUSINESS_SERVER: distro = "Windows Small Business Server"; break; + case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: distro = "Small Business Server Premium"; break; + case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE: distro = "Small Business Server Premium (core installation)"; break; + case PRODUCT_SOLUTION_EMBEDDEDSERVER: distro = "Windows MultiPoint Server"; break; + case PRODUCT_STANDARD_EVALUATION_SERVER: distro = "Server Standard (evaluation installation)"; break; + case PRODUCT_STANDARD_SERVER: distro = "Server Standard"; break; + case PRODUCT_STANDARD_SERVER_CORE: distro = "Server Standard (core installation)"; break; + case PRODUCT_STANDARD_SERVER_V: distro = "Server Standard without Hyper-V"; break; + case PRODUCT_STANDARD_SERVER_CORE_V: distro = "Server Standard without Hyper-V (core installation)"; break; + case PRODUCT_STANDARD_SERVER_SOLUTIONS: distro = "Server Solutions Premium"; break; + case PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE: distro = "Server Solutions Premium (core installation)"; break; + case PRODUCT_STARTER: distro = "Starter"; break; + case PRODUCT_STARTER_E: distro = "Not supported"; break; + case PRODUCT_STARTER_N: distro = "Starter N"; break; + case PRODUCT_STORAGE_ENTERPRISE_SERVER: distro = "Storage Server Enterprise"; break; + case PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE: distro = "Storage Server Enterprise (core installation)"; break; + case PRODUCT_STORAGE_EXPRESS_SERVER: distro = "Storage Server Express"; break; + case PRODUCT_STORAGE_EXPRESS_SERVER_CORE: distro = "Storage Server Express (core installation)"; break; + case PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER: distro = "Storage Server Standard (evaluation installation)"; break; + case PRODUCT_STORAGE_STANDARD_SERVER: distro = "Storage Server Standard"; break; + case PRODUCT_STORAGE_STANDARD_SERVER_CORE: distro = "Storage Server Standard (core installation)"; break; + case PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER: distro = "Storage Server Workgroup (evaluation installation)"; break; + case PRODUCT_STORAGE_WORKGROUP_SERVER: distro = "Storage Server Workgroup"; break; + case PRODUCT_STORAGE_WORKGROUP_SERVER_CORE: distro = "Storage Server Workgroup (core installation)"; break; + case PRODUCT_UNDEFINED: distro = "An unknown product"; break; + case PRODUCT_ULTIMATE: distro = "Ultimate"; break; + case PRODUCT_ULTIMATE_E: distro = "Not supported"; break; + case PRODUCT_ULTIMATE_N: distro = "Ultimate N"; break; + case PRODUCT_WEB_SERVER: distro = "Web Server (full installation)"; break; + case PRODUCT_WEB_SERVER_CORE: distro = "Web Server (core installation)"; break; + } + } + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { + if (GetSystemMetrics(SM_SERVERR2) ) + kernel.Cat(" Server 2003 R2"); + else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER) + kernel.Cat(" Storage Server 2003"); + else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER) + kernel.Cat(" Home Server"); + else if( osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + kernel.Cat(" XP Professional x64 Edition"); + else + kernel.Cat(" Server 2003"); + // Test for the server type. + if (osvi.wProductType != VER_NT_WORKSTATION ) { + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 ) { + if(osvi.wSuiteMask & VER_SUITE_DATACENTER ) + distro = "Datacenter Edition for Itanium-based Systems"; + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + distro = "Enterprise Edition for Itanium-based Systems"; + } + } else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ) { + if(osvi.wSuiteMask & VER_SUITE_DATACENTER ) + distro = "Datacenter x64 Edition"; + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + distro = "Enterprise x64 Edition"; + else + distro = "Standard x64 Edition"; + } else { + if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER ) + distro = "Compute Cluster Edition"; + else if(osvi.wSuiteMask & VER_SUITE_DATACENTER ) + distro = "Datacenter Edition"; + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + distro = "Enterprise Edition"; + else if (osvi.wSuiteMask & VER_SUITE_BLADE ) + distro = "Web Edition"; + else + distro = "Standard Edition"; + } + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) { + kernel.Cat(" XP"); + if(osvi.wSuiteMask & VER_SUITE_PERSONAL ) + distro = "Home Edition"; + else + distro = "Professional"; + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) { + kernel.Cat(" 2000"); + if (osvi.wProductType == VER_NT_WORKSTATION) + distro = "Professional"; + else { + if(osvi.wSuiteMask & VER_SUITE_DATACENTER) + distro = "Datacenter Server"; + else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + distro = "Advanced Server"; + else + distro = "Server"; + } + } + // Include service pack (if any) and build number. + if(osvi.wServicePackMajor > 0) + kerVersion.Cat(Format(" %s", osvi.szCSDVersion)); + + kerVersion.Cat(Format(" (Build %d)", (int)osvi.dwBuildNumber)); + } else if (osvi.dwPlatformId == 1) { + switch(osvi.dwMinorVersion) { + case 0: + kernel.Cat(" 95"); + break; + case 10: + kernel.Cat(" 98"); + break; + case 90: + kernel.Cat(" Millennium"); + break; + } + distro = ""; + } else if (osvi.dwPlatformId == 2) { + switch(osvi.dwMajorVersion) { + kernel.Cat(" NT"); + case 3: + kernel.Cat(" 3.51"); + break; + case 4: + kernel.Cat(" 4.0"); + break; + } + distro = ""; + } + desktop = kernel; + distVersion = deskVersion = ""; + return true; +} +#endif +#ifdef PLATFORM_POSIX + +static bool GetOsInfoCheckRelease(String &distro, String &distVersion) { + StringParse release; + for (FindFile ff("/etc/*-release"); ff; ff.Next()) + release += LoadFile_Safe(ff.GetPath()); + if (release.IsEmpty()) + return false; + if(!release.GoAfter("DISTRIB_ID=")) + if (!release.GoAfter("ID=")) + return false; + distro = ToLower(release.GetText()); + if (distro.IsEmpty()) + return false; + if (!release.GoAfter_Init("DISTRIB_RELEASE=")) + if (!release.GoAfter_Init("VERSION_ID=")) + return false; + distVersion = ToLower(release.GetText()); + + return true; +} + +bool GetOsInfo(String &kernel, String &kerVersion, String &kerArchitecture, String &distro, String &distVersion, String &desktop, String &deskVersion) +{ + struct utsname buf; + + if (0 == uname(&buf)) { + kernel = buf.sysname; + kerVersion = String(buf.release) + " " + String(buf.version); + kerArchitecture = buf.machine; + } + if (kernel.IsEmpty()) + kernel = LoadFile_Safe("/proc/sys/kernel/ostype"); + if (kernel.IsEmpty()) + kernel = LoadFile_Safe("/proc/version"); + if (kernel.IsEmpty()) { + if (Sys("sysctl_cmd -n kern.version").Find("FreeBSD") >= 0) + kernel = "freebsd"; + } + if (kernel.IsEmpty()) + kernel = ToLower(Sys("uname -s")); + + if (kerVersion.IsEmpty()) + kerVersion = LoadFile_Safe("/proc/sys/kernel/osrelease") + " " + LoadFile_Safe("/proc/sys/kernel/version"); + if (kerVersion.IsEmpty()) + kerArchitecture = ToLower(Sys("uname -v")); + + if (kerArchitecture.IsEmpty()) + kerArchitecture = ToLower(Sys("uname -m")); + + // printenv + if (GetEnv("GNOME_DESKTOP_SESSION_ID").GetCount() || GetEnv("GNOME_KEYRING_SOCKET").GetCount()) { + desktop = "gnome"; + StringParse gnomeVersion = Sys("gnome-about --version"); + gnomeVersion.GoAfter("gnome-about"); + deskVersion = gnomeVersion.GetText(); + } else if (GetEnv("KDE_FULL_SESSION").GetCount() || GetEnv("KDEDIR").GetCount() || GetEnv("KDE_MULTIHEAD").GetCount()) { + desktop = "kde"; + StringParse konsole = Sys("konsole --version"); + konsole.GoAfter("KDE", ":"); + deskVersion = konsole.GetText(); + if (deskVersion.IsEmpty()) + deskVersion = GetEnv("KDE_SESSION_VERSION"); + } else if (GetEnv("MATE_KEYRING_CONTROL").GetCount()) { + desktop = "mate"; + StringParse mateVersion = Sys("mate-about --version"); + while (true) { + String str = mateVersion.GetText(); + if (atof(str) > 0) { + deskVersion = str; + break; + } else if (str.IsEmpty()) + break; + } + } else { + String str = GetEnv("CINNAMON_VERSION"); + if (!str.IsEmpty()) { + desktop = "cinnamon"; + deskVersion = str; + } else { + StringParse desktopStr = ToLower(Sys("xprop -root")); + if (desktopStr.Find("lxde") >= 0 || ToLower(GetEnv("DESKTOP_SESSION")) == "lxde") { + desktop = "lxde"; + desktopStr.GoAfter("_ob_version", "="); + deskVersion = desktopStr.GetText(); + } else if (desktopStr.Find("xfce") >= 0) { + desktopStr.GoAfter("_dt_save_mode", "="); + desktop = desktopStr.GetText(); + StringParse xfceVersion = Sys(Format("%s-about --version", desktop)); + while (true) { + String str = xfceVersion.GetText(); + if (atof(str) > 0) { + deskVersion = str; + break; + } else if (str.IsEmpty()) + break; + } + } else if (desktopStr.Find("enlightenment") >= 0) { + desktop = "enlightenment"; + desktopStr.GoAfter("enlightenment_version", "="); + desktopStr = desktopStr.GetText(); + if (desktopStr.GetText() == "enlightenment") + deskVersion = desktopStr.GetText(); + } else + desktop = GetEnv("DESKTOP_SESSION"); + } + } + + if (GetOsInfoCheckRelease(distro, distVersion)) + ; + else if (FileExists("/usr/share/doc/ubuntu-minimal") || FileExists("/usr/share/ubuntu-docs")) + distro = "ubuntu"; + else if (FileExists("/etc/fedora-release")) { + distro = "fedora"; + StringParse strFile = LoadFile_Safe("/etc/fedora-release"); + strFile.GoAfter("release"); + distVersion = strFile.GetText(); + } else if (FileExists("/etc/redhat-release")) { + distro = "redhat"; + distVersion = LoadFile_Safe("/etc/redhat-release"); + } else if (FileExists("/etc/SuSE-release")) { + StringParse strFile = LoadFile_Safe("/etc/SuSE-release"); + distro = strFile.GetText(); + strFile.GoAfter_Init("VERSION", "="); + distVersion = strFile.GetText(); + } else if (FileExists("/etc/mandrake-release")) { + distro = "mandrake"; + distVersion = LoadFile_Safe("/etc/mandrake-release"); + } else if (FileExists("/etc/mandriva-release")) { + distro = "mandriva"; + distVersion = LoadFile_Safe("/etc/mandriva-release"); + } else if (FileExists("/etc/aurox-release")) { + distro = "aurox"; + distVersion = LoadFile_Safe("/etc/aurox-release"); + } else if (FileExists("/etc/altlinux-release")) { + distro = "altlinux"; + distVersion = LoadFile_Safe("/etc/altlinux-releas"); + } else if (FileExists("/etc/yellowdog-release")) { + distro = "yellowdog"; + distVersion = LoadFile_Safe("/etc/gentoo-yellowdog"); + } else if (FileExists("/etc/gentoo-release")) { + distro = "gentoo"; + distVersion = LoadFile_Safe("/etc/gentoo-release"); + } else if (FileExists("/usr/portage")) { + distro = "gentoo"; + distVersion = LoadFile_Safe("/usr/portage"); + } else if (FileExists("/etc/slackware-version")) { + distro = "slackware"; + StringParse strFile = LoadFile_Safe("/etc/slackware-version"); + strFile.GetText(); + distVersion = strFile.GetText(); + } else if (FileExists("/etc/debian_version")) { + distro = "debian"; + distVersion = LoadFile_Safe("/etc/debian_version"); + } else if (LoadFile_Safe("/etc/release").Find("Solaris") >= 0) + distro = "solaris"; + else if (ToLower(Sys("uname -r")).Find("freebsd") >= 0) + distro = "freebsd"; + else if (ToLower(Sys("uname -r")).Find("solaris") >= 0) + distro = "solaris"; + else { + distro = LoadFile_Safe("/etc/osname_version"); + distVersion = ""; + } + if (distro.IsEmpty()) + distro = LoadFile_Safe("/etc/issue"); + if (distro.IsEmpty()) + distro = distVersion = "UNKNOWN"; + + return true; +} + +#endif + +END_UPP_NAMESPACE \ No newline at end of file diff --git a/bazaar/SysInfo/ScreenGrab.cpp b/bazaar/SysInfo/ScreenGrab.cpp new file mode 100644 index 000000000..0165ead98 --- /dev/null +++ b/bazaar/SysInfo/ScreenGrab.cpp @@ -0,0 +1,618 @@ +#include "SysInfo_in.h" + +#include +#include +#include + +NAMESPACE_UPP + + +bool Window_SaveCapture(int64 windowId, String fileName, int left, int top, int width, int height) +{ + if ((width <= 0 && width != -1) || (height <= 0 && height != -1)) + return false; + + Image img = Window_SaveCapture(windowId, left, top, width, height); + if (IsNull(img)) + return false; + + if (GetFileExt(fileName) == ".png") { + PNGEncoder encoder; + return encoder.SaveFile(fileName, img); + } else if (GetFileExt(fileName) == ".jpg") { + JPGEncoder encoder(90); + return encoder.SaveFile(fileName, img); + } else if (GetFileExt(fileName) == ".bmp") { + BMPEncoder encoder; + return encoder.SaveFile(fileName, img); + } else + return false; +} + +#if defined(PLATFORM_WIN32) || defined (PLATFORM_WIN64) + +#if defined(__MINGW32__) + #define labs(x) labs((Upp::int64)(x)) +#elif defined(_MSC_VER) + #define labs(x) abs(x) +#endif + + +Rect GetDesktopRect() { + HWND wH = GetDesktopWindow(); + + RECT rc; + if (!GetWindowRect(wH, &rc)) + return Null; + + Rect ret(rc.left, rc.top, rc.right, rc.bottom); + return ret; +} + +Image Window_SaveCapture(int64 windowId, int left, int top, int width, int height) { + if ((width <= 0 && width != -1) || (height <= 0 && height != -1)) + return Null; + + HWND wH = reinterpret_cast(windowId); + if (wH == 0) + wH = GetDesktopWindow(); + + RECT rc; + if (!GetWindowRect(wH, &rc)) + return Null; + + if (left == -1) + left = rc.left; + if (top == -1) + top = rc.top; + if (width == -1) + width = rc.right - rc.left; + if (height == -1) + height = rc.bottom - rc.top; + + HDC hDC = NULL; + HDC memDC = NULL; + HBITMAP hb = NULL; + HBITMAP oldBM = NULL; + Image img = Null; + ImageBuffer b; + + if ((hDC = GetDC(0)) == NULL) + goto end; + if ((memDC = CreateCompatibleDC(hDC)) == NULL) + goto end; + if ((hb = CreateCompatibleBitmap(hDC, width, height)) == NULL) + goto end; + if ((oldBM = (HBITMAP)SelectObject(memDC, hb)) == NULL) + goto end; + if (!BitBlt(memDC, 0, 0, width, height , hDC, left, top, SRCCOPY)) + goto end; + + BITMAPINFO bmpInfo; + ZeroMemory(&bmpInfo, sizeof(BITMAPINFO)); + bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + if (!GetDIBits(hDC, hb, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS)) + goto end; + if(bmpInfo.bmiHeader.biSizeImage <= 0) + bmpInfo.bmiHeader.biSizeImage = bmpInfo.bmiHeader.biWidth*labs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; + bmpInfo.bmiHeader.biCompression = BI_RGB; + bmpInfo.bmiHeader.biHeight = -height; + + b.Create(width, height); + if (!GetDIBits(hDC, hb, 0, height, ~b, (BITMAPINFO *)&bmpInfo.bmiHeader, DIB_RGB_COLORS)) + goto end; + + img = b; + +end: + SelectObject(hDC, oldBM); + DeleteObject(hb); + DeleteDC(memDC); + ReleaseDC(0, hDC); + + return img; +} + +class ScreenGrab { +private: + enum {GRAB_MODE_DESKTOP, GRAB_MODE_WINDOW, GRAB_MODE_RECT}; + static HDC lDCDest; + static HGDIOBJ lDib; + static void *lDibPtr; + static HGDIOBJ lBmpOld; + static BITMAPINFO tBmpInfo; + static PAVIFILE lAVIPtrFile; + static PAVISTREAM lAVIPtrStrm; + static AVISTREAMINFO tAVIHdr; + static AVIFILEINFO tAVIFile; + long lAVICnt; + double frameRate; + long numFrames; // number of frames in video stream + long firstFrame; // position of the first video frame + String fileName; + bool viewMouse; + bool opened; + int grabMode; + uint64 hwnd; + int left; + int top; + int width; + int height; + + bool AVIOpen(bool create = true); + bool AVIWrite(); + void AVIClose(); + HICON GetCursorHandle(); + bool DIBCreate(HWND lHandleSource, long lWidth, long lHeight, long lPosX, long lPosY); + void DIBClean(); + bool ScreenshotMemory(); + +public: + ScreenGrab(String fileName, double secsFrame = 1, bool viewMouse = true); + ~ScreenGrab(); + + bool IniGrabDesktop(); + bool IniGrabWindow(uint64 handle); + bool IniGrabDesktopRectangle(int left, int top, int width, int height); + bool Grab(unsigned duration); + bool GrabSnapshot(); + void Close(); +}; + +bool Record_Desktop(String fileName, int duration, double secsFrame, bool viewMouse) +{ + ScreenGrab grab(fileName, secsFrame, viewMouse); + if (!grab.IniGrabDesktop()) + return false; + if (!grab.Grab(duration)) + return false; + grab.Close(); + return true; +} +bool Record_DesktopRectangle(String fileName, int duration, int left, int top, int width, int height, double secsFrame, bool viewMouse) +{ + ScreenGrab grab(fileName, secsFrame, viewMouse); + if (!grab.IniGrabDesktopRectangle(left, top, width, height)) + return false; + if (!grab.Grab(duration)) + return false; + grab.Close(); + return true; +} + +bool Record_Window(String fileName, int duration, int64 handle, double secsFrame, bool viewMouse) +{ + ScreenGrab grab(fileName, secsFrame, viewMouse); + if (!grab.IniGrabWindow(handle)) + return false; + if (!grab.Grab(duration)) + return false; + grab.Close(); + return true; +} + +bool ScreenGrab::AVIOpen(bool create) +{ + long lRet, mode, res; + + AVIFileInit(); + if (create) + mode = OF_CREATE | OF_WRITE; + else + mode = OF_SHARE_DENY_WRITE; + + lRet = AVIFileOpen(&lAVIPtrFile, fileName, mode, 0); + if (lRet == AVIERR_OK && create) { + tAVIHdr.fccType = streamtypeVIDEO; + tAVIHdr.fccHandler = 0; + tAVIHdr.dwScale = 100; + tAVIHdr.dwRate = (DWORD)(tAVIHdr.dwScale*frameRate); + //tAVIHdr.dwQuality = -1; + tAVIHdr.dwSuggestedBufferSize = tBmpInfo.bmiHeader.biSizeImage; + SetRect(&(tAVIHdr.rcFrame), 0, 0, tBmpInfo.bmiHeader.biWidth, tBmpInfo.bmiHeader.biHeight); + lRet = AVIFileCreateStream(lAVIPtrFile, &lAVIPtrStrm, &tAVIHdr); + if (lRet == AVIERR_OK) { + lRet = AVIStreamSetFormat(lAVIPtrStrm, 0, &(tBmpInfo.bmiHeader), sizeof(tBmpInfo.bmiHeader)); + if (lRet == AVIERR_OK) + lAVICnt = 0; + } + } else { + res = AVIFileGetStream(lAVIPtrFile, &lAVIPtrStrm, streamtypeVIDEO, 0); + if (res != AVIERR_OK) + return false; + firstFrame = AVIStreamStart(lAVIPtrStrm); + if (firstFrame != -1) + return false; + numFrames = AVIStreamLength(lAVIPtrStrm); + if (numFrames == -1) + return false; + res = AVIFileInfo(lAVIPtrFile, &tAVIFile, sizeof(tAVIFile)); + if (res != AVIERR_OK) + return false; + res = AVIStreamInfo(lAVIPtrStrm, &tAVIHdr, sizeof(tAVIHdr)); + if (res != AVIERR_OK) + return false; + } + return true; +} + +bool ScreenGrab::AVIWrite() +{ + HRESULT lRet; + + lRet = AVIStreamWrite(lAVIPtrStrm, lAVICnt, 1, lDibPtr, tBmpInfo.bmiHeader.biSizeImage, AVIIF_KEYFRAME, NULL, NULL); + if (lRet == AVIERR_OK) { + lAVICnt++; + return true; + } else + return false; +} + +void ScreenGrab::AVIClose() +{ + if (lAVIPtrStrm != 0) + AVIStreamClose(lAVIPtrStrm); + if (lAVIPtrFile != 0) + AVIFileClose(lAVIPtrFile); + AVIFileExit(); +} + +HICON ScreenGrab::GetCursorHandle() +{ + HWND lHandle; + POINT lpPos; + long lThreadID; + long lCurrentThreadID; + + GetCursorPos(&lpPos); + lHandle = WindowFromPoint(lpPos); + lThreadID = GetWindowThreadProcessId(lHandle, 0); + lCurrentThreadID = GetWindowThreadProcessId(reinterpret_cast(GetWindowIdFromProcessId(GetProcessId())), 0); + HICON ret; + if (lThreadID != lCurrentThreadID) { + if (AttachThreadInput(lCurrentThreadID, lThreadID, true)) { + ret = GetCursor(); + AttachThreadInput(lCurrentThreadID, lThreadID, false); + } + } else + ret = GetCursor(); + + return ret; +} + +bool ScreenGrab::DIBCreate(HWND lHandleSource, long lWidth, long lHeight, long lPosX, long lPosY) +{ + HDC lDCSource, lDCSourceDesktop; + POINT lpCursorPos; + + lDCSource = GetWindowDC(lHandleSource); + lDCSourceDesktop = GetWindowDC(0); + + bool ret = false; + if (lDCSource != 0 && lDCSourceDesktop != 0) { + lDCDest = CreateCompatibleDC(lDCSource); + if (lDCDest != 0) { + tBmpInfo.bmiHeader.biSize = sizeof(tBmpInfo.bmiHeader); + tBmpInfo.bmiHeader.biWidth = lWidth; + tBmpInfo.bmiHeader.biHeight = lHeight; + tBmpInfo.bmiHeader.biPlanes = 1; + tBmpInfo.bmiHeader.biBitCount = 24; + tBmpInfo.bmiHeader.biCompression = 0; + tBmpInfo.bmiHeader.biSizeImage = ((tBmpInfo.bmiHeader.biWidth * 3 + 3) & 0xFFFFFFFC) * tBmpInfo.bmiHeader.biHeight; + lDib = CreateDIBSection(lDCDest, &tBmpInfo, 0, &lDibPtr, 0, 0); + if (lDib != 0) { + lBmpOld = SelectObject(lDCDest, lDib); + BitBlt(lDCDest, 0, 0, lWidth, lHeight, lDCSourceDesktop, lPosX, lPosY, 0xCC0020); + if (viewMouse) { + GetCursorPos(&lpCursorPos); + DrawIcon(lDCDest, lpCursorPos.x - lPosX, lpCursorPos.y - lPosY, GetCursorHandle()); + } + ret = true; + } + } + } + ReleaseDC(lHandleSource, lDCSource); + ReleaseDC(0, lDCSourceDesktop); + return ret; +} + +void ScreenGrab::DIBClean() +{ + SelectObject(lDCDest, lBmpOld); + DeleteDC(lDCDest); + DeleteObject(lDib); +} + +bool ScreenGrab::ScreenshotMemory() +{ + HWND lHandle; + RECT lpRect; + long lWidth, lHeight; + long lPosX, lPosY; + + switch (grabMode) { + case GRAB_MODE_DESKTOP: + lHandle = GetDesktopWindow(); + GetWindowRect(lHandle, &lpRect); + lWidth = lpRect.right - lpRect.left; + lHeight = lpRect.bottom - lpRect.top; + lPosX = lpRect.left; + lPosY = lpRect.top; + break; + case GRAB_MODE_WINDOW: + lHandle = reinterpret_cast(hwnd); + GetWindowRect(lHandle, &lpRect); + lWidth = lpRect.right - lpRect.left; + lHeight = lpRect.bottom - lpRect.top; + lPosX = lpRect.left; + lPosY = lpRect.top; + break; + case GRAB_MODE_RECT: + lHandle = GetDesktopWindow(); + GetWindowRect(lHandle, &lpRect); + lWidth = width; + lHeight = height; + lPosX = left; + lPosY = top; + break; + default: + throw Exc(t_("Unknown grab mode")); + return false; + } + if (DIBCreate(lHandle, lWidth, lHeight, lPosX, lPosY)) + return true; + else + return false; +} + +HDC ScreenGrab::lDCDest; +HGDIOBJ ScreenGrab::lDib; +void *ScreenGrab::lDibPtr; +HGDIOBJ ScreenGrab::lBmpOld; +PAVIFILE ScreenGrab::lAVIPtrFile; +PAVISTREAM ScreenGrab::lAVIPtrStrm; +BITMAPINFO ScreenGrab::tBmpInfo; +AVISTREAMINFO ScreenGrab::tAVIHdr; +AVIFILEINFO ScreenGrab::tAVIFile; + +ScreenGrab::ScreenGrab(String _fileName, double secsFrame, bool _viewMouse) +{ + opened = false; + fileName = _fileName; + viewMouse = _viewMouse; + frameRate = 1./secsFrame; +} + +ScreenGrab::~ScreenGrab() +{ + Close(); +} + +void ScreenGrab::Close() +{ + if (!opened) + return; + AVIClose(); + DIBClean(); + opened = false; +} + +bool ScreenGrab::IniGrabDesktop() +{ + opened = true; + grabMode = GRAB_MODE_DESKTOP; + if (!ScreenshotMemory()) + return false; + if (!AVIOpen()) + return false; + return true; +} + +bool ScreenGrab::IniGrabWindow(uint64 handle) +{ + opened = true; + grabMode = GRAB_MODE_WINDOW; + hwnd = handle; + if (!ScreenshotMemory()) + return false; + if (!AVIOpen()) + return false; + return true; +} + +bool ScreenGrab::IniGrabDesktopRectangle(int _left, int _top, int _width, int _height) +{ + opened = true; + grabMode = GRAB_MODE_RECT; + left = _left; + top = _top; + width = _width; + height = _height; + if (!ScreenshotMemory()) + return false; + if (!AVIOpen()) + return false; + return true; +} + +bool ScreenGrab::Grab(unsigned duration) +{ + if (!opened) + return false; + TimeStop timer; + timer.Reset(); + while (timer.Elapsed() < duration*1000) { + if (!ScreenshotMemory()) + return false; + if (!AVIWrite()) + return false; + while (timer.Elapsed() < (lAVICnt*1000.)/frameRate) + Sleep(10);//DoEvents(); + } + return true; +} + +bool ScreenGrab::GrabSnapshot() +{ + if (!opened) + return false; + if (!ScreenshotMemory()) + return false; + if (!AVIWrite()) + return false; + return true; +} + +#endif + +#ifdef PLATFORM_POSIX + +Window GetToplevelParent(_XDisplay *display, Window window) { + Window parent; + Window root; + Window *children; + unsigned int numChildren; + + while (true) { + if (0 == XQueryTree(display, window, &root, &parent, &children, &numChildren)) + return -1; + if (children) + XFree(children); + + if (window == root || parent == root) + return window; + else + window = parent; + } +} + +Rect GetDesktopRect() { + SetSysInfoX11ErrorHandler(); + + _XDisplay *dpy = XOpenDisplay (NULL); + if (!dpy) { + SetX11ErrorHandler(); + return Null; + } + int screen = DefaultScreen(dpy); + int64 windowId = RootWindow(dpy, screen); + + XWindowAttributes rc; + if (!XGetWindowAttributes(dpy, windowId, &rc)) { + XCloseDisplay(dpy); + SetX11ErrorHandler(); + return Null; + } + Rect ret(rc.x, rc.y, rc.x + rc.width, rc.y + rc.height); + + XCloseDisplay(dpy); + SetX11ErrorHandler(); + + return ret; +} + +Image Window_SaveCapture(int64 windowId, int left, int top, int width, int height) +{ + if ((width <= 0 && width != -1) || (height <= 0 && height != -1)) + return Null + + SetSysInfoX11ErrorHandler(); + + _XDisplay *dpy = XOpenDisplay (NULL); + if (!dpy) { + SetX11ErrorHandler(); + return Null; + } + int screen = DefaultScreen(dpy); + if (windowId == 0) + windowId = RootWindow(dpy, screen); + else { + windowId = GetToplevelParent(dpy, windowId); + if (windowId < 0) { + SetX11ErrorHandler(); + return Null; + } + } + + XWindowAttributes rc; + if (!XGetWindowAttributes(dpy, windowId, &rc)) { + XCloseDisplay(dpy); + SetX11ErrorHandler(); + return Null; + } + + if (left == -1) + left = rc.x; + if (top == -1) + top = rc.y; + if (width == -1) + width = rc.width; + if (height == -1) + height = rc.height; + + XImage *image = XGetImage(dpy, windowId, left, top, width, height, XAllPlanes(), ZPixmap); + if (image == NULL) { + XCloseDisplay(dpy); + SetX11ErrorHandler(); + return Null; + } + + ImageBuffer ib(width, height); + + unsigned long red_mask = image->red_mask; + unsigned long green_mask = image->green_mask; + unsigned long blue_mask = image->blue_mask; + + for (int y = 0; y < height; y++) { + RGBA *row = ib[y]; + for (int x = 0; x < width ; x++) { + unsigned long pixel = XGetPixel(image, x, y); + unsigned char blue = pixel & blue_mask; + unsigned char green = (pixel & green_mask) >> 8; + unsigned char red = (pixel & red_mask) >> 16; + (row + x)->r = red; + (row + x)->g = green; + (row + x)->b = blue; + } + } + XCloseDisplay(dpy); + SetX11ErrorHandler(); + + Image img; + img = ib; + return img; +} + +#endif + +bool Snap_Desktop(String fileName) +{ + return Window_SaveCapture(0, fileName); +} + +bool Snap_DesktopRectangle(String fileName, int left, int top, int width, int height) +{ + return Window_SaveCapture(0, fileName, left, top, width, height); +} + +bool Snap_Window(String fileName, int64 handle) +{ + return Window_SaveCapture(handle, fileName); +} + +Image Snap_Desktop() +{ + return Window_SaveCapture(0); +} + +Image Snap_DesktopRectangle(int left, int top, int width, int height) +{ + return Window_SaveCapture(0, left, top, width, height); +} + +Image Snap_Window(int64 handle) +{ + return Window_SaveCapture(handle); +} + +END_UPP_NAMESPACE \ No newline at end of file