bool kvi_sendIpcMessage(const char * message) { #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) HWND hSentinel = kvi_win_findIpcSentinel(); if(hSentinel != NULL) { COPYDATASTRUCT cpd; cpd.cbData = strlen(message)+1; cpd.dwData = KVI_WINDOWS_IPC_MESSAGE; cpd.lpData = (void *)message; DWORD_PTR dwResult; if(!::SendMessageTimeout(hSentinel,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cpd,SMTO_BLOCK,1000,&dwResult)) { qDebug("Failed to send IPC message: error code 0x%x",::GetLastError()); } return true; } #else #if defined(COMPILE_X11_SUPPORT) && defined(COMPILE_QX11INFO_SUPPORT) kvi_ipcLoadAtoms(); Window sentinel = kvi_x11_findIpcSentinel(kvi_ipc_get_xrootwin()); if(sentinel != 0) { // XChangeProperty(kvi_ipc_get_xdisplay(),sentinel,kvi_atom_ipc_remote_command,XA_STRING,8, // PropModeReplace,(const unsigned char *)message,kvi_strLen(message)); kvi_ipcSetRemoteCommand(sentinel,message); #if (QT_VERSION < 0x050000) XEvent e; KviMemory::set(&e,0,sizeof(XEvent)); e.type = ClientMessage; e.xclient.display = kvi_ipc_get_xdisplay(); e.xclient.window = sentinel; e.xclient.message_type = kvi_atom_ipc_remote_message; e.xclient.format = 8; Status ret = XSendEvent(kvi_ipc_get_xdisplay(),sentinel,False,0,&e); #else // On Qt5 the ClientMessage events aren't propagated at all.. we have to rely on the property change only #endif return true; } #endif //!COMPILE_NO_X #endif return false; }
bool kvi_sendIpcMessage(const char * message) { #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) HWND hSentinel = ::FindWindow(TEXT("Qt5QWindowIcon"), TEXT("kvirc4_ipc_sentinel")); if(hSentinel != nullptr) { COPYDATASTRUCT cpd; cpd.cbData = strlen(message) + 1; cpd.dwData = KVI_WINDOWS_IPC_MESSAGE; cpd.lpData = (void *)message; DWORD_PTR dwResult; if(!::SendMessageTimeout(hSentinel, WM_COPYDATA, (WPARAM)nullptr, (LPARAM)&cpd, SMTO_BLOCK, 1000, &dwResult)) { DWORD errorMessageID = ::GetLastError(); if (errorMessageID) { LPSTR messageBuffer = nullptr; size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, nullptr); std::string winMessage(messageBuffer, size); //Free the buffer. LocalFree(messageBuffer); qDebug("Failed to send IPC message: %s", winMessage.c_str()); } else { qDebug("Failed to send IPC message."); } } return true; } #elif defined(COMPILE_X11_SUPPORT) && defined(COMPILE_QX11INFO_SUPPORT) kvi_ipcLoadAtoms(); Window sentinel = kvi_x11_findIpcSentinel(kvi_ipc_get_xrootwin()); if(sentinel != 0) { kvi_ipcSetRemoteCommand(sentinel, message); return true; } #endif //!COMPILE_NO_X && COMPILE_ON_WINDOWS return false; }
static Window kvi_x11_findIpcSentinel(Window win) { Atom type; int format; unsigned long nItems, after; unsigned char * data = nullptr; if(XGetWindowProperty(kvi_ipc_get_xdisplay(), win, kvi_atom_ipc_sentinel_window, 0, 32, false, XA_STRING, &type, &format, &nItems, &after, &data) == Success) { if((type == XA_STRING) && (format == 8)) { if((nItems == ((unsigned long)(kvi_sentinel_id.len()))) && data) { if(kvi_strEqualCSN((const char *)data, kvi_sentinel_id.ptr(), kvi_sentinel_id.len())) { XFree((char *)data); return win; } } } } Window root, parent; Window * children; unsigned int nChildren; if(!XQueryTree(kvi_ipc_get_xdisplay(), win, &root, &parent, &children, &nChildren)) { if(children) XFree((char *)children); return 0; } Window found = 0; for(size_t i = 0; !found && i < nChildren; ++i) found = kvi_x11_findIpcSentinel(children[i]); if(children) XFree((char *)children); return found; }