123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905 |
- // Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
- // file at the top-level directory of this distribution and at
- // https://github.com/go-vgo/robotgo/blob/master/LICENSE
- //
- // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
- // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
- // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
- // option. This file may not be copied, modified, or distributed
- // except according to those terms.
- // #include "../base/os.h"
- // #include <stdlib.h>
- #include "process.h"
- struct _MData{
- #if defined(IS_MACOSX)
- CGWindowID CgID; // Handle to a CGWindowID
- AXUIElementRef AxID; // Handle to a AXUIElementRef
- #elif defined(USE_X11)
- Window XWin; // Handle to an X11 window
- #elif defined(IS_WINDOWS)
- HWND HWnd; // Handle to a window HWND
- #endif
- };
- typedef struct _MData MData;
- MData mData;
- bool setHandle(uintptr handle);
- bool IsValid();
- bool IsAxEnabled(bool options);
- MData GetActive (void);
- void aWindow();
- #if defined(IS_MACOSX)
- static Boolean (*gAXIsProcessTrustedWithOptions) (CFDictionaryRef);
- static CFStringRef* gkAXTrustedCheckOptionPrompt;
- AXError _AXUIElementGetWindow (AXUIElementRef, CGWindowID* out);
- static AXUIElementRef GetUIElement (CGWindowID win){
- intptr pid = 0;
- // double_t pid=0;
- // Create array storing window
- CGWindowID window[1] = { win };
- CFArrayRef wlist = CFArrayCreate (NULL,
- (const void**) window, 1, NULL);
- // Get window info
- CFArrayRef info =CGWindowListCreateDescriptionFromArray (wlist);
- CFRelease (wlist);
- // Check whether the resulting array is populated
- if (info != NULL && CFArrayGetCount (info) > 0){
- // Retrieve description from info array
- CFDictionaryRef desc = (CFDictionaryRef) CFArrayGetValueAtIndex (info, 0);
- // Get window PID
- CFNumberRef data =(CFNumberRef)
- CFDictionaryGetValue (desc, kCGWindowOwnerPID);
- if (data != NULL)
- CFNumberGetValue (data, kCFNumberIntType, &pid);
- // Return result
- CFRelease (info);
- }
- // Check if PID was retrieved
- if (pid <= 0) return NULL;
- // Create an accessibility object using retrieved PID
- AXUIElementRef application = AXUIElementCreateApplication (pid);
-
- if (application == 0) return NULL;
- CFArrayRef windows = NULL;
- // Get all windows associated with the app
- AXUIElementCopyAttributeValues (application,
- kAXWindowsAttribute, 0, 1024, &windows);
- // Reference to resulting value
- AXUIElementRef result = NULL;
- if (windows != NULL){
- int count = CFArrayGetCount (windows);
- // Loop all windows in the process
- for (CFIndex i = 0; i < count; ++i){
- // Get the element at the index
- AXUIElementRef element = (AXUIElementRef)
- CFArrayGetValueAtIndex (windows, i);
- CGWindowID temp = 0;
- // Use undocumented API to get WindowID
- _AXUIElementGetWindow (element, &temp);
- // Check results
- if (temp == win){
- // Retain element
- CFRetain (element);
- result = element;
- break;
- }
- }
- CFRelease (windows);
- }
- CFRelease (application);
- return result;
- }
- #elif defined(USE_X11)
- // Error Handling
- typedef int (*XErrorHandler) (Display*, XErrorEvent*);
- static int XHandleError (Display* dp, XErrorEvent* e) { return 0; }
- XErrorHandler mOld;
- void XDismissErrors (void){
- Display *rDisplay = XOpenDisplay(NULL);
- // Save old handler and dismiss errors
- mOld = XSetErrorHandler (XHandleError);
- // Flush output buffer
- XSync (rDisplay, False);
- // Reinstate old handler
- XSetErrorHandler (mOld);
- }
- // Definitions
- struct Hints
- {
- unsigned long Flags;
- unsigned long Funcs;
- unsigned long Decorations;
- signed long Mode;
- unsigned long Stat;
- };
- static Atom WM_STATE = None;
- static Atom WM_ABOVE = None;
- static Atom WM_HIDDEN = None;
- static Atom WM_HMAX = None;
- static Atom WM_VMAX = None;
- static Atom WM_DESKTOP = None;
- static Atom WM_CURDESK = None;
- static Atom WM_NAME = None;
- static Atom WM_UTF8 = None;
- static Atom WM_PID = None;
- static Atom WM_ACTIVE = None;
- static Atom WM_HINTS = None;
- static Atom WM_EXTENTS = None;
- ////////////////////////////////////////////////////////////////////////////////
- static void LoadAtoms (void)
- {
- Display *rDisplay = XOpenDisplay(NULL);
- WM_STATE = XInternAtom (rDisplay, "_NET_WM_STATE", True);
- WM_ABOVE = XInternAtom (rDisplay, "_NET_WM_STATE_ABOVE", True);
- WM_HIDDEN = XInternAtom (rDisplay, "_NET_WM_STATE_HIDDEN", True);
- WM_HMAX = XInternAtom (rDisplay, "_NET_WM_STATE_MAXIMIZED_HORZ", True);
- WM_VMAX = XInternAtom (rDisplay, "_NET_WM_STATE_MAXIMIZED_VERT", True);
- WM_DESKTOP = XInternAtom (rDisplay, "_NET_WM_DESKTOP", True);
- WM_CURDESK = XInternAtom (rDisplay, "_NET_CURRENT_DESKTOP", True);
- WM_NAME = XInternAtom (rDisplay, "_NET_WM_NAME", True);
- WM_UTF8 = XInternAtom (rDisplay, "UTF8_STRING", True);
- WM_PID = XInternAtom (rDisplay, "_NET_WM_PID", True);
- WM_ACTIVE = XInternAtom (rDisplay, "_NET_ACTIVE_WINDOW", True);
- WM_HINTS = XInternAtom (rDisplay, "_MOTIF_WM_HINTS", True);
- WM_EXTENTS = XInternAtom (rDisplay, "_NET_FRAME_EXTENTS", True);
- }
- // Functions
- static void* GetWindowProperty (MData win, Atom atom, uint32* items)
- {
- // Property variables
- Atom type; int format;
- unsigned long nItems;
- unsigned long bAfter;
- unsigned char* result = NULL;
- Display *rDisplay = XOpenDisplay(NULL);
- // Check the atom
- if (atom != None)
- {
- // Retrieve and validate the specified property
- if (!XGetWindowProperty (rDisplay, win.XWin, atom, 0,
- BUFSIZ, False, AnyPropertyType, &type, &format,
- &nItems, &bAfter, &result) && result && nItems)
- {
- // Copy items result
- if (items != NULL)
- *items = (uint32) nItems;
- return result;
- }
- }
- // Reset the items result if valid
- if (items != NULL) *items = 0;
- // Free the result if it got allocated
- if (result != NULL) XFree (result);
- return NULL;
- }
- //////
- #define STATE_TOPMOST 0
- #define STATE_MINIMIZE 1
- #define STATE_MAXIMIZE 2
- //////
- static void SetDesktopForWindow (MData win){
- Display *rDisplay = XOpenDisplay(NULL);
- // Validate every atom that we want to use
- if (WM_DESKTOP != None && WM_CURDESK != None){
- // Get desktop property
- long* desktop = (long*)
- GetWindowProperty (win, WM_DESKTOP,NULL);
- // Check result value
- if (desktop != NULL){
- // Retrieve the screen number
- XWindowAttributes attr = { 0 };
- XGetWindowAttributes (rDisplay, win.XWin, &attr);
- int s = XScreenNumberOfScreen (attr.screen);
- Window root = XRootWindow(rDisplay, s);
- // Prepare an event
- XClientMessageEvent e = { 0 };
- e.window = root; e.format = 32;
- e.message_type = WM_CURDESK;
- e.display = rDisplay;
- e.type = ClientMessage;
- e.data.l[0] = *desktop;
- e.data.l[1] = CurrentTime;
- // Send the message
- XSendEvent(rDisplay,
- root, False, SubstructureNotifyMask |
- SubstructureRedirectMask, (XEvent*) &e);
- XFree(desktop);
- }
- }
- }
- #elif defined(IS_WINDOWS)
- //
- #endif
- //int findwindow()
- uintptr ahandle = 0;
- void aWindow(uintptr handle){
- #if defined(IS_MACOSX)
- mData.CgID = 0;
- mData.AxID = 0;
- #elif defined(USE_X11)
- Display *rDisplay = XOpenDisplay(NULL);
- // If atoms loaded
- if (WM_PID == None){
- // Load all necessary atom properties
- if (rDisplay != NULL) LoadAtoms();
- }
- mData.XWin = 0;
- #elif defined(IS_WINDOWS)
- mData.HWnd = 0;
- #endif
- setHandle(handle);
- }
- bool IsValid (){
- aWindow(ahandle);
- if(!IsAxEnabled(true))printf("%s\n", "Window:Accessibility API is disabled!\nFailed to enable access for assistive devices.");
- MData actdata=GetActive();
- #if defined(IS_MACOSX)
- mData.CgID=actdata.CgID;
- mData.AxID=actdata.AxID;
- if (mData.CgID == 0 || mData.AxID == 0)return false;
- CFTypeRef r = NULL;
- // Attempt to get the window role
- if (AXUIElementCopyAttributeValue(mData.AxID,
- kAXRoleAttribute,&r) == kAXErrorSuccess && r){
- CFRelease (r);
- return true;
- }
- return false;
- #elif defined(USE_X11)
- mData.XWin=actdata.XWin;
- if (mData.XWin == 0)return false;
- Display *rDisplay = XOpenDisplay(NULL);
- // Check for a valid X-Window display
- if (rDisplay == NULL) return false;
- // Ignore X errors
- XDismissErrors();
- // Get the window PID property
- void* result = GetWindowProperty(mData, WM_PID,NULL);
- if (result == NULL) return false;
- // Free result and return true
- XFree (result); return true;
- #elif defined(IS_WINDOWS)
- mData.HWnd=actdata.HWnd;
- if (mData.HWnd == 0)
- return false;
- return IsWindow (mData.HWnd) != 0;
- #endif
- }
- bool IsAxEnabled (bool options){
- #if defined(IS_MACOSX)
- // Statically load all required functions one time
- static dispatch_once_t once; dispatch_once (&once,
- ^{
- // Open the framework
- void* handle = dlopen
- ("/System/Library/Frameworks/Application"
- "Services.framework/ApplicationServices", RTLD_LAZY);
- // Validate the handle
- if (handle != NULL){
- *(void**) (&gAXIsProcessTrustedWithOptions) =
- dlsym (handle, "AXIsProcessTrustedWithOptions");
- gkAXTrustedCheckOptionPrompt = (CFStringRef*)
- dlsym (handle, "kAXTrustedCheckOptionPrompt");
- }
- });
- // Check for new OSX 10.9 function
- if (gAXIsProcessTrustedWithOptions){
- // Check whether to show prompt
- CFBooleanRef displayPrompt = options ?
- kCFBooleanTrue : kCFBooleanFalse;
- // Convert display prompt value into a dictionary
- const void* k[] = { *gkAXTrustedCheckOptionPrompt };
- const void* v[] = { displayPrompt };
- CFDictionaryRef o = CFDictionaryCreate
- (NULL, k, v, 1, NULL, NULL);
- // Determine whether the process is actually trusted
- bool result = (*gAXIsProcessTrustedWithOptions) (o);
- // Free memory
- CFRelease (o);
- return result;
- }else{
- // Ignore deprecated warnings
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- // Check whether we have accessibility access
- return AXAPIEnabled() || AXIsProcessTrusted();
- #pragma clang diagnostic pop
- }
- #elif defined(USE_X11)
- return true;
- #elif defined(IS_WINDOWS)
- return true;
- #endif
- }
- // int
- bool setHandle (uintptr handle){
- #if defined(IS_MACOSX)
- // Release the AX element
- if (mData.AxID != NULL)CFRelease (mData.AxID);
- // Reset both values
- mData.CgID = 0;
- mData.AxID = 0;
- if (handle == 0)return 0;
- // return true;
- // Retrieve the window element
- CGWindowID cgID = (CGWindowID) handle;
- AXUIElementRef axID = GetUIElement (cgID);
- if (axID != NULL){
- mData.CgID = cgID;
- mData.AxID = axID;
- // return 0;
- return true;
- }
- // return 1;
- return false;
- #elif defined(USE_X11)
- mData.XWin = (Window) handle;
- if (handle == 0)
- return true;
- if (IsValid())
- return true;
- mData.XWin = 0;
- return false;
- #elif defined(IS_WINDOWS)
- mData.HWnd = (HWND) handle;
- if (handle == 0)
- return true;
- if (IsValid())
- return true;
- mData.HWnd = 0;
- return false;
- #endif
- }
- //uint32 uintptr
- uintptr getHandle(){
- #if defined(IS_MACOSX)
- return (uintptr) mData.CgID;
- #elif defined(USE_X11)
- return (uintptr) mData.XWin;
- #elif defined(IS_WINDOWS)
- return (uintptr) mData.HWnd;
- #endif
- }
- bool IsTopMost (void){
- // Check the window validity
- if (!IsValid()) return false;
- #if defined(IS_MACOSX)
- return false; // WARNING: Unavailable
- #elif defined(USE_X11)
- // Ignore X errors
- // XDismissErrors ();
- // return GetState (mData.XWin, STATE_TOPMOST);
- #elif defined(IS_WINDOWS)
- return (GetWindowLongPtr (mData.HWnd,
- GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
- #endif
- }
- bool IsMinimized(void){
- // Check the window validity
- if (!IsValid()) return false;
- #if defined(IS_MACOSX)
- CFBooleanRef data = NULL;
- // Determine whether the window is minimized
- if (AXUIElementCopyAttributeValue (mData.AxID,
- kAXMinimizedAttribute, (CFTypeRef*) &data)
- == kAXErrorSuccess && data != NULL)
- {
- // Convert resulting data into a bool
- bool result = CFBooleanGetValue(data);
- CFRelease (data); return result;
- }
- return false;
- #elif defined(USE_X11)
- // Ignore X errors
- // XDismissErrors();
- // return GetState (mData.XWin, STATE_MINIMIZE);
- #elif defined(IS_WINDOWS)
- return (GetWindowLongPtr (mData.HWnd,
- GWL_STYLE) & WS_MINIMIZE) != 0;
- #endif
- }
- //////
- bool IsMaximized(void){
- // Check the window validity
- if (!IsValid()) return false;
- #if defined(IS_MACOSX)
- return false; // WARNING: Unavailable
- #elif defined(USE_X11)
- // Ignore X errors
- // XDismissErrors();
- // return GetState (mData.XWin, STATE_MAXIMIZE);
- #elif defined(IS_WINDOWS)
- return (GetWindowLongPtr (mData.HWnd,
- GWL_STYLE) & WS_MAXIMIZE) != 0;
- #endif
- }
- void SetActive(const MData win){
- // Check if the window is valid
- if (!IsValid()) return;
- #if defined(IS_MACOSX)
- // Attempt to raise the specified window object
- if (AXUIElementPerformAction (win.AxID,
- kAXRaiseAction) == kAXErrorSuccess)
- {
- pid_t pid = 0;
- // Attempt to retrieve the PID of the window
- if (AXUIElementGetPid (win.AxID, &pid)
- != kAXErrorSuccess || !pid) return;
- // Ignore deprecated warnings
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- // NOTE: Until Apple actually removes
- // these functions, there's no real
- // reason to switch to the NS* flavor
- ProcessSerialNumber psn;
- // Attempt to retrieve the process psn
- if (GetProcessForPID (pid, &psn) == 0){
- // Gracefully activate process
- SetFrontProcessWithOptions (&psn,
- kSetFrontProcessFrontWindowOnly);
- }
- #pragma clang diagnostic pop
- }
- #elif defined(USE_X11)
- // Ignore X errors
- XDismissErrors();
- // Go to the specified window's desktop
- SetDesktopForWindow(win);
- Display *rDisplay = XOpenDisplay(NULL);
- // Check the atom value
- if (WM_ACTIVE != None){
- // Retrieve the screen number
- XWindowAttributes attr = { 0 };
- XGetWindowAttributes (rDisplay,
- win.XWin, &attr);
- int s = XScreenNumberOfScreen(attr.screen);
- // Prepare an event
- XClientMessageEvent e = { 0 };
- e.window = win.XWin;
- e.format = 32;
- e.message_type = WM_ACTIVE;
- e.display = rDisplay;
- e.type = ClientMessage;
- e.data.l[0] = 2;
- e.data.l[1] = CurrentTime;
- // Send the message
- XSendEvent(rDisplay, XRootWindow (rDisplay, s), False,
- SubstructureNotifyMask | SubstructureRedirectMask,
- (XEvent*) &e);
- }else{
- // Attempt to raise the specified window
- XRaiseWindow(rDisplay, win.XWin);
- // Set the specified window's input focus
- XSetInputFocus(rDisplay, win.XWin,
- RevertToParent, CurrentTime);
- }
- #elif defined(IS_WINDOWS)
- if (IsMinimized())
- ShowWindow(win.HWnd, SW_RESTORE);
- SetForegroundWindow (win.HWnd);
- #endif
- }
- MData GetActive (void){
- #if defined(IS_MACOSX)
- MData result;
- // Ignore deprecated warnings
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- ProcessSerialNumber psn; pid_t pid;
- // Attempt to retrieve the front process
- if (GetFrontProcess (&psn ) != 0 ||
- GetProcessPID (&psn, &pid) != 0)
- return result;
- #pragma clang diagnostic pop
- // Create accessibility object using focused PID
- AXUIElementRef focused = AXUIElementCreateApplication (pid);
- if (focused == NULL) return result; // Verify
- AXUIElementRef element;
- // Retrieve the currently focused window
- if (AXUIElementCopyAttributeValue (focused,
- kAXFocusedWindowAttribute, (CFTypeRef*)
- &element) == kAXErrorSuccess && element)
- {
- CGWindowID win = 0;
- // Use undocumented API to get WID
- if (_AXUIElementGetWindow (element,
- &win) == kAXErrorSuccess && win)
- {
- // Manually set internals
- result.CgID = win;
- result.AxID = element;
- }
- // Something went wrong
- else CFRelease (element);
- }
- CFRelease (focused);
-
- return result;
- #elif defined(USE_X11)
- MData result;
- Display *rDisplay = XOpenDisplay(NULL);
- // Check X-Window display
- if (WM_ACTIVE == None ||
- rDisplay == NULL)
- return result;
- // Ignore X errors
- XDismissErrors();
- // Get the current active window
- result.XWin=XDefaultRootWindow (rDisplay);
- void* active = GetWindowProperty(result,WM_ACTIVE,NULL);
- // Check result value
- if (active != NULL)
- {
- // Extract window from the result
- long window = *((long*) active);
- XFree (active); if (window != 0)
- {
- // Set and return the foreground window
- result.XWin = (Window) window;
- return result;
- }
- }
- // Use input focus instead
- Window window = None;
- int revert = RevertToNone;
- XGetInputFocus (rDisplay,
- &window, &revert);
- // Return foreground window
- result.XWin = window;
- return result;
- #elif defined(IS_WINDOWS)
- // Attempt to get the foreground window multiple times in case
- MData result;
- uint8 times = 0;
- while (++times < 20)
- {
- HWND handle;
- handle = GetForegroundWindow();
- if (handle != NULL){
- // mData.HWnd=(uintptr) handle;
- result.HWnd= (HWND)handle;
- return result;
- }
- Sleep (20);
- }
- return result;
- #endif
- }
- void SetTopMost (bool state){
- // Check window validity
- if (!IsValid()) return;
- #if defined(IS_MACOSX)
- // WARNING: Unavailable
- #elif defined(USE_X11)
- // Ignore X errors
- // XDismissErrors ();
- // SetState (mData.XWin, STATE_TOPMOST, state);
- #elif defined(IS_WINDOWS)
- SetWindowPos (mData.HWnd, state ?
- HWND_TOPMOST : HWND_NOTOPMOST, 0,
- 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- #endif
- }
- //CloseWindow
- void CloseWin(void){
- // Check window validity
- if (!IsValid()) return;
- #if defined(IS_MACOSX)
- AXUIElementRef b = NULL;
- // Retrieve the close button of this window
- if (AXUIElementCopyAttributeValue (mData.AxID,
- kAXCloseButtonAttribute, (CFTypeRef*) &b)
- == kAXErrorSuccess && b != NULL)
- {
- // Simulate button press on the close button
- AXUIElementPerformAction (b, kAXPressAction);
- CFRelease (b);
- }
- #elif defined(USE_X11)
- Display *rDisplay = XOpenDisplay(NULL);
- // Ignore X errors
- XDismissErrors();
- // Close the window
- XDestroyWindow (rDisplay, mData.XWin);
- #elif defined(IS_WINDOWS)
- PostMessage (mData.HWnd, WM_CLOSE, 0, 0);
- #endif
- }
- char *GetTitle(){
- // Check if the window is valid
- if (!IsValid()) return "IsValid failed.";
- #if defined(IS_MACOSX)
- CFStringRef data = NULL;
-
- // Determine the current title of the window
- if (AXUIElementCopyAttributeValue (mData.AxID,
- kAXTitleAttribute, (CFTypeRef*) &data)
- == kAXErrorSuccess && data != NULL)
- {
- char conv[512];
- // Convert result to a C-String
- CFStringGetCString (data, conv,
- 512, kCFStringEncodingUTF8);
- CFRelease (data);
- char* s=(char*)calloc(100,sizeof(char*));
- if(s)strcpy(s,conv);
- // return (char *)&conv;
- return s;
- }
- return "null";
- #elif defined(USE_X11)
- void* result;
- // Ignore X errors
- XDismissErrors();
- // Get window title (UTF-8)
- result = GetWindowProperty(mData, WM_NAME,NULL);
- // Check result value
- if (result != NULL){
- // Convert result to a string
- char *name=(char*) result;
- XFree (result);
- if (name!=NULL)return name;
- }
- // Get window title (ASCII)
- result = GetWindowProperty(mData, XA_WM_NAME,NULL);
- // Check result value
- if (result != NULL){
- // Convert result to a string
- char *name =(char*) result;
- XFree (result); return name;
- }
- return "null";
- #elif defined(IS_WINDOWS)
- TCHAR name[512];
- return GetWindowText
- (mData.HWnd, name, 512) > 0 ? name : "null";
- // return GetWindowText
- // (mData.HWnd, name, 512) > 0 ?
- // _UTF8Encode (name) : "null";
- #endif
- }
- int32 WGetPID(void){
- // Check window validity
- if (!IsValid()) return 0;
- #if defined(IS_MACOSX)
- pid_t pid = 0;
- // Attempt to retrieve the window pid
- if (AXUIElementGetPid(mData.AxID, &pid)
- == kAXErrorSuccess) return pid;
- return 0;
- #elif defined(USE_X11)
- // Ignore X errors
- XDismissErrors();
- // Get the window PID
- long* result = (long*)
- GetWindowProperty(mData, WM_PID,NULL);
- // Check result and convert it
- if (result == NULL) return 0;
- int32 pid = (int32) *result;
- XFree (result); return pid;
- #elif defined(IS_WINDOWS)
- DWORD id = 0;
- GetWindowThreadProcessId (mData.HWnd, &id);
- return id;
- #endif
- }
|