2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
25 * (c) Copyright 1993, 1994 International Business Machines Corp. *
26 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
27 * (c) Copyright 1993, 1994 Novell, Inc. *
30 *******************************************************************************
32 * File: ChkpntListen.c
33 * Description: CDE listener-side checkpoint protocol functions. Internal API
34 * functions for use by the CDE checkpoint listener.
35 * Created: Mon Sep 6 09:00:00 1993
38 * $XConsortium: ChkpntListen.c /main/6 1996/08/28 15:14:40 drk $
40 * (C) Copyright 1993, Hewlett-Packard, all rights reserved.
42 *******************************************************************************
45 #define INVALID_TIME ((Time) -1)
49 #include "Dt/ChkpntP.h"
50 #include "DtSvcLock.h"
53 Display *display; /* Display pointer */
54 Window window; /* Window id for the program */
55 Atom aSelection; /* Atom for root selection */
56 Boolean bListen; /* Should I do listening ? */
59 /* _DtPerfChkpntListenInit(): Start the Checkpoint listener */
61 _DtPerfChkpntListenInit(display, parentwin)
62 Display *display; /* Current display */
63 Window parentwin; /* Parent of window associated with listener */
65 _DtPerfChkpntListenInit(Display *display, Window parentwin)
68 Time timestamp = INVALID_TIME;
70 Bool bsuccess = False;
73 dtsvc_info.display = display;
74 dtsvc_info.window = XCreateSimpleWindow(display, parentwin,
76 BlackPixel(display,DefaultScreen(display)),
77 WhitePixel(display,DefaultScreen(display)));
78 dtsvc_info.bListen = True;
80 * Assert ownership over the appropriate root window selection
82 dtsvc_info.aSelection = XInternAtom(display, DT_PERF_CHKPNT_SEL, False);
83 if (XGetSelectionOwner(dtsvc_info.display, dtsvc_info.aSelection) == None) {
84 if (timestamp == INVALID_TIME) { /* Generate a valid timestamp */
87 char propname[80]; /* Temp buffer for property name */
89 sprintf(propname, "%s_%x", DT_PERF_CLIENT_CHKPNT_PROP, 0);
90 aProperty = XInternAtom(dtsvc_info.display, propname,False);
91 XSelectInput(dtsvc_info.display,
92 dtsvc_info.window, PropertyChangeMask);
94 XChangeProperty(dtsvc_info.display, dtsvc_info.window,
95 aProperty, XA_STRING, 8,
96 PropModeAppend, (unsigned char *) NULL, 0);
97 XFlush(dtsvc_info.display);
99 XWindowEvent(dtsvc_info.display, dtsvc_info.window,
100 PropertyChangeMask, &event);
101 if (event.type == PropertyNotify) {
102 timestamp = event.xproperty.time;
106 XSetSelectionOwner(dtsvc_info.display, dtsvc_info.aSelection,
107 dtsvc_info.window, timestamp);
108 tmpwin = XGetSelectionOwner(dtsvc_info.display, dtsvc_info.aSelection);
109 if ( tmpwin == dtsvc_info.window)
110 bsuccess = True;/* We are now the listener! */
113 if (bsuccess == False) {
115 "\t** Chkpnt listener: Cannot gain ownership of root selection **\n");
117 "\t** Chkpnt listener: Selection is owned by window: %lx **\n",
119 dtsvc_info.bListen = False;
120 _DtSvcProcessUnlock();
124 /* Express interests in Events on this window */
125 XSelectInput(dtsvc_info.display, dtsvc_info.window,
126 SelectionRequest | SelectionClear);
128 _DtSvcProcessUnlock();
132 /* Helper Boolean function to pass to XCheckIfEvent() */
133 static Bool myCheckSelectionEvent(Display *display, XEvent *event, char *args)
137 if (event->xany.window != dtsvc_info.window) { /* Only listener window events*/
138 _DtSvcProcessUnlock();
141 else switch(event->type) { /* Selection stuff ? */
143 case SelectionRequest:
144 _DtSvcProcessUnlock();
148 _DtSvcProcessUnlock();
155 * _DtPerfChkpntMsgReceive() Non blocking fetch from message queue
157 Bool _DtPerfChkpntMsgReceive(DtChkpntMsg *dtcp_msg, Bool bBlock)
163 static char **Stringlist;
164 static int numfields = 0;
167 if (dtsvc_info.bListen == False) {
168 _DtSvcProcessUnlock();
172 if (numfields) { /* Free the storage from last time around */
173 XFreeStringList(Stringlist);
178 XIfEvent(dtsvc_info.display, &event, myCheckSelectionEvent, NULL);
180 bool = XCheckIfEvent(dtsvc_info.display, &event,
181 myCheckSelectionEvent, NULL);
184 switch (event.type) {
185 case SelectionRequest: /* Message received from a client */
186 /* Is this a Checkpoint request ?*/
187 if (event.xselectionrequest.selection == dtsvc_info.aSelection){
188 /* Correct selection, now fetch the property */
190 * Note: Need to handle errors if the client is dead
191 * and the property no longer exists.
193 XGetTextProperty(dtsvc_info.display,
194 event.xselectionrequest.requestor,
196 event.xselectionrequest.property);
197 XDeleteProperty (dtsvc_info.display,
198 event.xselectionrequest.requestor,
199 event.xselectionrequest.property);
200 XTextPropertyToStringList(&tp, &Stringlist, &numfields);
202 for (i = 0; i < DT_PERF_CHKPNT_MSG_SIZE; i++)
203 dtcp_msg->array[i] = (Stringlist)[i];
205 /* End? Destroy the, RetainPermanent client window */
206 if (!strcmp(dtcp_msg->record.type, DT_PERF_CHKPNT_MSG_END))
207 XDestroyWindow(dtsvc_info.display,
208 event.xselectionrequest.requestor);
212 case SelectionClear: /* We no longer own the selection */
214 fprintf(stderr,"\t** Chkpnt listener: Warning - loss of Selection ownership **\n");
219 _DtSvcProcessUnlock();