This is the mail archive of the
cygwin-xfree@cygwin.com
mailing list for the Cygwin XFree86 project.
Re: question about multiwindow mode and application icons
Howdy Harold,
At 11:45 PM 5/13/2003 -0400, you wrote:
...Wow! You have certainly done your homework here. This is way more
complicated than I thought it would have to be.
That's what happens when you put a square peg like X into a round hole like
Windoze! I'm really impressed at how well the 2 message loops are behaving
presently, it must have been some serious work to get things running! I'm
just trying to add the finishing touches, because I have found this server to
be more stable and compatible than a commercial one.
As for going from and HWND to a WindowPtr, it seems to me that you can
either use the existing WIN_WID_PROP property, which is set in
winmultiwindowwindow.c/winCreateWindowsWindow () and contains the XID of
the X window, or you could add another property that contains a pointer
either to the privates structure or the WindowPtr. Does that solve your
problem? I like the window properties because they eliminate searches
through linked lists and they eliminate the need to even have a linked
list structure in our code base.
That's what I was overlooking! I just added a custom property to each window
when mapped in the WM that has the HWND, and voila, no need for lists.
Another way of doing this would be to spawn a 3rd thread that makes a
notification
window and sleeps on a XNextEvent() loop. The WM would send a custom
message to
the hidden notification window each time a window is mapped, and that 3rd
thread would
Hmm... I would have to see the code in order to have some suggestions.
Trust me, you wouldn't want to see that code! I've settled on a timed wait
and have been running some jobs and it all seems to work at no noticeable
CPU load.
Kensuke Matsuzaki (the originaly author of the MultiWindow mode) might
have some ideas, but I have not seem him on the list in quite some
time. Even if the code doesn't work I would like to see it... I might be
able to help get it working. Shoot me any code that you would like me to
look over and I will see what I can do. [Feel free to post a `diff -U3
-N' to the list for all to see and I will pick it up there.]
I'll do one better than that, below is a diff -U3 OLD NEW of all the
changes against the text 84 release. It's got stubs for the WM_HINTS
already, so if Ralf Habacker wants to try his hand at updating the icons
Windows displays, he just needs to add a function call in the TBD
section.
In the default bash shell, when you "cd" it changes the window title to
the CWD, after this patch you'll see that reflected in the window title.
It's quite handy if you have multiple machines or multiple dirs you're
working on!
----------8<------------
diff -U3 ./winmultiwindowwm.c
/usr/src/xfree/release/programs/Xserver/hw/xwin/winmultiwindowwm.c
--- ./winmultiwindowwm.c 2003-03-12 06:28:12.000000000 -0800
+++
/usr/src/xfree/release/programs/Xserver/hw/xwin/winmultiwindowwm.c
2003-05-13 21:50:54.000000000 -0700
@@ -37,6 +37,7 @@
#include <fcntl.h>
#include <setjmp.h>
#include <pthread.h>
+#include <sys/timeb.h>
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
@@ -61,7 +62,6 @@
#define WIN_CONNECT_RETRIES 5
#define WIN_CONNECT_DELAY 5
#define WIN_MSG_QUEUE_FNAME "/dev/windows"
-#define WM_WM_X_EVENT 1
#define WIN_JMP_OKAY 0
#define WIN_JMP_ERROR_IO 2
@@ -87,6 +87,10 @@
WMMsgQueueRec wmMsgQueue;
Atom atmWmProtos;
Atom atmWmDelete;
+ Atom atmWmName;
+ Atom atmWmIconName;
+ Atom atmWmHints;
+ Atom atmPrivMap;
} WMInfoRec, *WMInfoPtr;
typedef struct _WMProcArgRec {
@@ -113,7 +117,7 @@
PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode);
static WMMsgNodePtr
-PopMessage (WMMsgQueuePtr pQueue);
+PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr);
static Bool
InitQueue (WMMsgQueuePtr pQueue);
@@ -148,7 +152,6 @@
static jmp_buf g_jmpEntry;
-
/*
* PushMessage - Push a message onto the queue
*/
@@ -237,9 +240,12 @@
*/
static WMMsgNodePtr
-PopMessage (WMMsgQueuePtr pQueue)
+PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo)
{
WMMsgNodePtr pNode;
+ struct timeb now;
+ struct timespec timeOut;
+ winWMMessageRec msg;
/* Lock the queue mutex */
pthread_mutex_lock (&pQueue->pmMutex);
@@ -247,7 +253,27 @@
/* Wait for --- */
while (pQueue->pHead == NULL)
{
- pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex);
+ /* Set a timeout for 50ms from now to see if any X events are
waiting... */
+ ftime(&now);
+ timeOut.tv_sec = now.time;
+ timeOut.tv_nsec = (now.millitm + 50)*1000*1000;
+ if (timeOut.tv_nsec>1000000000) {
+ timeOut.tv_nsec -= 1000000000;
+ timeOut.tv_sec += 1;
+ }
+ pthread_cond_timedwait (&pQueue->pcNotEmpty, &pQueue->pmMutex,
&timeOut);
+
+ if (XPending(pWMInfo->pDisplay)) {
+ pthread_mutex_unlock (&pQueue->pmMutex);
+
+ memset( &msg, 0, sizeof(msg) );
+ msg.msg = WM_WM_X_EVENT;
+ /* Other fields ignored */
+ winSendMessageToWM (pWMInfo, &msg);
+
+ pthread_mutex_lock (&pQueue->pmMutex);
+ }
+
}
pNode = pQueue->pHead;
@@ -447,7 +473,7 @@
WMMsgNodePtr pNode;
/* Pop a message off of our queue */
- pNode = PopMessage (&pWMInfo->wmMsgQueue);
+ pNode = PopMessage (&pWMInfo->wmMsgQueue, pWMInfo);
if (pNode == NULL)
{
/* Bail if PopMessage returns without a message */
@@ -515,6 +541,19 @@
free (pszName);
}
}
+ /* Put a note as to the HWND associated with this Window */
+ XChangeProperty( pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ pWMInfo->atmPrivMap,
+ pWMInfo->atmPrivMap,
+ 32,
+ PropModeReplace,
+ (unsigned char *)&(pNode->msg.hwndWindow),
+ 1 );
+ /* We need to know when it changes name or icon */
+ XSelectInput( pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ PropertyChangeMask );
break;
case WM_WM_UNMAP:
@@ -586,7 +625,7 @@
free (pNode);
/* Flush any pending events on our display */
- XFlush (pWMInfo->pDisplay);
+ // XFlush (pWMInfo->pDisplay);
}
/* Free the condition variable */
@@ -612,7 +651,9 @@
FlushXEvents (WMInfoPtr pWMInfo)
{
XEvent event;
-
+ HWND hWnd;
+ char *pszName;
+
#if CYGMULTIWINDOW_DEBUG
ErrorF ("FlushXEvents ()\n");
#endif
@@ -623,12 +664,56 @@
/* Get the next event - will not block because one is ready */
XNextEvent (pWMInfo->pDisplay, &event);
-#if 0
/* Branch on the event type */
switch (event.type)
{
- }
+ Atom atmType;
+ int fmtRet;
+ unsigned long items, remain;
+ HWND *retHwnd;
+
+ case PropertyNotify:
+ hWnd = 0;
+ /* See if we can get the cached HWND for this window... */
+ if (XGetWindowProperty(pWMInfo->pDisplay,
+ event.xproperty.window,
+ pWMInfo->atmPrivMap,
+ 0,
+ 1,
+ False,
+ pWMInfo->atmPrivMap,
+ &atmType,
+ &fmtRet,
+ &items,
+ &remain,
+ (unsigned char **)&retHwnd ) == Success) {
+ hWnd = *retHwnd;
+ XFree(retHwnd);
+ }
+
+ /* Some sanity checks */
+ if (!hWnd) break;
+ if (!IsWindow(hWnd)) break;
+
+ if (event.xproperty.atom==pWMInfo->atmWmName) {
+ /* Set the Windows window name */
+ GetWindowName(pWMInfo->pDisplay, event.xproperty.window, &pszName);
+ SetWindowText(hWnd, pszName);
+ free (pszName);
+ } else if (event.xproperty.atom==pWMInfo->atmWmIconName) {
+#if CYGMULTIWINDOW_DEBUG
+ /* TBD */
+ ErrorF("Changed WM_ICON_NAME\n");
+#endif
+ } else if (event.xproperty.atom==pWMInfo->atmWmHints) {
+#if CYGMULTIWINDOW_DEBUG
+ /* TBD */
+ ErrorF("Changed WM_HINTS -> Should update window icon\n");
#endif
+ }
+
+ break;
+ }
}
#if CYGMULTIWINDOW_DEBUG
@@ -862,12 +947,24 @@
XSetIOErrorHandler (winMutliWindowWMIOErrorHandler);
/* Create some atoms */
- pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay,
- "WM_PROTOCOLS",
- False);
- pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay,
- "WM_DELETE_WINDOW",
- False);
+ pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay,
+ "WM_PROTOCOLS",
+ False);
+ pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay,
+ "WM_DELETE_WINDOW",
+ False);
+ pWMInfo->atmWmName = XInternAtom (pWMInfo->pDisplay,
+ "WM_NAME",
+ False);
+ pWMInfo->atmWmIconName = XInternAtom (pWMInfo->pDisplay,
+ "WM_ICON_NAME",
+ False);
+ pWMInfo->atmWmHints = XInternAtom (pWMInfo->pDisplay,
+ "WM_HINTS",
+ False);
+ pWMInfo->atmPrivMap = XInternAtom (pWMInfo->pDisplay,
+ WIN_HWND_CACHE,
+ False);
}
diff -U3 ./winwindow.h
/usr/src/xfree/release/programs/Xserver/hw/xwin/winwindow.h
--- ./winwindow.h 2003-05-13 06:26:55.000000000 -0700
+++ /usr/src/xfree/release/programs/Xserver/hw/xwin/winwindow.h 2003-05-13
21:42:50.000000000 -0700
@@ -51,6 +51,7 @@
#define WIN_LOG_FNAME "/tmp/XWin.log"
#define WIN_WID_PROP "cyg_wid_prop_rl"
#define WIN_NEEDMANAGE_PROP "cyg_override_redirect_prop_rl"
+#define WIN_HWND_CACHE "cyg_privmap_rl"
#define CYGMULTIWINDOW_DEBUG NO
typedef struct _winPrivScreenRec *winPrivScreenPtr;
@@ -94,8 +95,7 @@
#define WM_WM_UNMAP (WM_USER + 6)
#define WM_WM_KILL (WM_USER + 7)
#define WM_WM_ACTIVATE (WM_USER + 8)
-
-#define WMMSG_MSG 10
+#define WM_WM_X_EVENT (WM_USER + 9)
/*
----------8<------------
-Earle F. Philhower, III
earle@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com