Exemple #1
0
static void kvi_ipcLoadAtoms()
{
	if(g_bIpcAtomsLoaded)
		return;
	g_bIpcAtomsLoaded = true;
	g_uLocalInstanceId = (kvi_u64_t)::getpid();
	kvi_sentinel_id.sprintf("pane tonno e mistero - %d", getuid());
	kvi_atom_ipc_sentinel_window = XInternAtom(kvi_ipc_get_xdisplay(), "XA_KVI4_IPC_SENTINEL_WINDOW", False);
	kvi_atom_ipc_remote_command = XInternAtom(kvi_ipc_get_xdisplay(), "XA_KVI4_IPC_REMOTE_COMMAND", False);
	kvi_atom_ipc_remote_message = XInternAtom(kvi_ipc_get_xdisplay(), "XA_KVI4_IPC_REMOTE_MESSAGE", False);
}
Exemple #2
0
	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;
	}
Exemple #3
0
bool KviIpcSentinel::x11GetRemoteMessage()
{
	Atom type;
	int format;
	unsigned long nItems, after;
	unsigned char * data = nullptr;
	KviCString szData;

	if(XGetWindowProperty(kvi_ipc_get_xdisplay(), winId(), kvi_atom_ipc_remote_command,
		   0, 1024, false, XA_STRING, &type, &format, &nItems, &after, &data) == Success)
	{
		if((type == XA_STRING) && (format == 8) && (nItems > 8) && data)
		{
			kvi_u32_t uSenderId = *((kvi_u32_t *)(data));
			if(uSenderId != g_uLocalInstanceId)
				szData = (char *)(data + 8);
			XFree((char *)data);
		}
	}

	if(szData.isEmpty())
		return false; // no command, or our own command

	kvi_ipcSetRemoteCommand(winId(), "");

	if(g_pApp)
		g_pApp->ipcMessage(szData.ptr());
	return true;
}
Exemple #4
0
	KviIpcSentinel::KviIpcSentinel()
	: QWidget(0)
	{
		setObjectName("kvirc4_ipc_sentinel");
#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
		setWindowTitle("kvirc4_ipc_sentinel");
		setWindowFlags(Qt::FramelessWindowHint);
#else
	#if defined(COMPILE_X11_SUPPORT) && defined(COMPILE_QX11INFO_SUPPORT)
		kvi_ipcLoadAtoms();

		XChangeProperty(kvi_ipc_get_xdisplay(),winId(),kvi_atom_ipc_sentinel_window,XA_STRING,8,
			PropModeReplace,(const unsigned char *)kvi_sentinel_id.ptr(),kvi_sentinel_id.len());

		kvi_ipcSetRemoteCommand(winId(),"");
	#endif //!COMPILE_NO_X
#endif

		move(-50,-50);
		resize(1,1);
#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
		// we need to show the window once otherwise it will never get "realized"
		// and we will not be able to find it via FindWindow()
		show();
#endif
		hide();

	}
Exemple #5
0
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;
}
Exemple #6
0
static void kvi_ipcSetRemoteCommand(Window w, const char * command)
{
	if(!command)
		return;

	int len = kvi_strLen(command) + 1;

	char * buffer = (char *)::malloc(len + 8);

	*((kvi_u64_t *)buffer) = g_uLocalInstanceId;

	::memcpy(buffer + 8, command, len);

	XChangeProperty(kvi_ipc_get_xdisplay(), w, kvi_atom_ipc_remote_command,
	    XA_STRING, 8, PropModeReplace, (const unsigned char *)buffer, len + 8);

	::free(buffer);
}