7 #define WIN32_LEAN_AND_MEAN
14 #define property _property
17 #define Window X11Window
18 #define Cursor X11Cursor
20 #define Display X11Display
22 #define KeyCode X11KeyCode
26 #include <X11/Xatom.h>
28 #include <X11/Xresource.h>
29 #include <X11/Xutil.h>
52 static bool CALLBACK EnumWindowsBringToTop(HWND hwnd, LPARAM lParam)
55 GetWindowThreadProcessId(hwnd, &pid);
57 BringWindowToTop(hwnd);
61 static bool CALLBACK EnumWindowsSetForeground(HWND hwnd, LPARAM lParam)
64 GetWindowThreadProcessId(hwnd, &pid);
69 HWND parent = GetParent(hwnd);
70 if(parent) hwnd = parent; else break;
72 SetForegroundWindow(hwnd); //SetForegroundWindow( GetAncestor(hwnd, GA_ROOTOWNER));
78 class ShowProcessWindowsThread : Thread
85 EnumWindows(EnumWindowsSetForeground, processId);
86 EnumWindows(EnumWindowsBringToTop, processId);
93 extern void * IS_XGetDisplay();
94 static Atom xa_NET_WM_PID, xa_activeWindow;
96 static void WaitForViewableWindow(X11Display * xGlobalDisplay, X11Window window)
99 XFlush(xGlobalDisplay);
103 XWindowAttributes attributes = { 0 };
104 XGetWindowAttributes(xGlobalDisplay, window, &attributes);
105 if(attributes.map_state == IsViewable)
112 static void EnumWindowBringToTop(X11Display * xGlobalDisplay, X11Window window, int processId)
115 X11Window root = 0, parent = 0, * children = null;
118 unsigned long len, fill;
120 if(XQueryTree(xGlobalDisplay, window, &root, &parent, &children, &numWindows))
123 for(c = 0; c<numWindows; c++)
126 if(XGetWindowProperty(xGlobalDisplay, children[c], xa_NET_WM_PID, 0, 1, False,
127 XA_CARDINAL, &xa_type, &format, &len, &fill,
130 // printf("cant get _NET_WM_PID property\n");
136 int pid = *(int *)data;
137 //printf("pid: %d\n", pid);
140 // printf("Found one window with processID\n");
142 XRaiseWindow(xGlobalDisplay, children[c]);
143 WaitForViewableWindow(xGlobalDisplay, children[c]);
146 XClientMessageEvent event = { 0 };
147 event.type = ClientMessage;
148 event.message_type = xa_activeWindow;
149 event.display = xGlobalDisplay;
151 event.window = children[c];
152 event.send_event = 1;
156 XSendEvent(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), bool::false, SubstructureRedirectMask | SubstructureNotifyMask, (union _XEvent *)&event);
159 XSetInputFocus(xGlobalDisplay, children[c], RevertToPointerRoot, CurrentTime);
164 EnumWindowBringToTop(xGlobalDisplay, children[c], processId);
173 void Process_ShowWindows(int processId)
176 ShowProcessWindowsThread thread { processId = processId };
181 X11Display * xGlobalDisplay = IS_XGetDisplay();
182 xa_NET_WM_PID = XInternAtom(xGlobalDisplay, "_NET_WM_PID", True);
183 xa_activeWindow = XInternAtom(xGlobalDisplay, "_NET_ACTIVE_WINDOW", True);
184 EnumWindowBringToTop(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), processId);
189 bool Process_Break(int processId)
193 HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
196 DWORD remoteThreadId;
197 HANDLE hRemoteThread;
198 static void * debugBreakAddress;
199 if(!debugBreakAddress)
201 HINSTANCE hDll = LoadLibrary("kernel32");
202 debugBreakAddress = GetProcAddress(hDll, "DebugBreak");
205 hRemoteThread = CreateRemoteThread(handle, null, 0, debugBreakAddress, 0, 0, &remoteThreadId);
208 //DebugBreakProcess(handle); // this worked only in winxp, right?
209 //GenerateConsoleCtrlEvent(CTRL_C_EVENT, processId); // this had no effect, right?
211 CloseHandle(hRemoteThread);
216 kill(processId, SIGTRAP);
222 int Process_GetCurrentProcessId()
225 DWORD currentProcessId = GetCurrentProcessId();
226 return currentProcessId;
228 return (int)getpid();
232 int Process_GetChildExeProcessId(const int parentProcessId, const char * exeFile)
238 int childProcessId = 0;
240 hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
242 if(hProcessSnap != INVALID_HANDLE_VALUE)
244 pe32.dwSize = sizeof(PROCESSENTRY32);
246 if(Process32First(hProcessSnap, &pe32))
250 if(pe32.th32ParentProcessID == parentProcessId)
252 //if(strstr(exeFile, pe32.szExeFile) == exeFile)
253 if(SearchString(exeFile, 0, pe32.szExeFile, false, false) == exeFile)
255 childProcessId = pe32.th32ProcessID;
259 } while(Process32Next(hProcessSnap, &pe32));
261 CloseHandle(hProcessSnap);
263 return childProcessId;
264 #elif defined(__linux__)
265 char exeFileTruncated[16];
266 FileListing listing { "/proc/" };
267 // Names is limited to 15 characters in /proc/pid/status
268 strncpy(exeFileTruncated, exeFile, 15);
269 exeFileTruncated[15] = 0;
270 while(listing.Find())
272 if(listing.stats.attribs.isDirectory)
274 int process = atoi(listing.name);
281 strcpy(fileName, listing.path);
282 PathCat(fileName, "status");
283 if((f = FileOpen(fileName, read)))
286 while(f.GetLine(buffer, 256))
288 if(!strncmp(buffer, "Name:", 5))
290 char * string = strstr(buffer + 6, exeFileTruncated);
291 if(!string || strcmp(string, exeFileTruncated))
295 else if(!strncmp(buffer, "PPid:", 5))
297 ppid = atoi(buffer + 6);
303 if(found && ppid == parentProcessId)
313 // This is the current OS X implementation
315 File f = DualPipeOpen({ output = true }, "ps -ajx");
318 bool firstLine = true;
325 if(f.GetLine(line,sizeof(line)))
327 uint count = Tokenize(line, sizeof(tokens)/sizeof(tokens[0]), tokens,false);
331 for(i = 0; i < count; i++)
333 if(!strcmpi(tokens[i], "pid"))
335 else if(!strcmpi(tokens[i], "ppid"))
338 if(pidColumn > 0 && ppidColumn > 0)
345 if(count > pidColumn && count > ppidColumn && strtoul(tokens[ppidColumn], null, 0) == parentProcessId)
347 pid = (uint)strtoul(tokens[pidColumn], null, 0);
359 void setEcereLanguageInWinRegEnvironment(const char * languageCode)
363 uint16 wLanguage[256];
367 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
370 UTF8toUTF16Buffer(languageCode, wLanguage, sizeof(wLanguage) / sizeof(uint16));
371 RegSetValueExW(key, L"ECERE_LANGUAGE", 0, REG_EXPAND_SZ, (byte *)wLanguage, (uint)(wcslen(wLanguage)+1) * 2);