1/*
2 * tkUnix.c --
3 *
4 *	This file contains procedures that are UNIX/X-specific, and will
5 *	probably have to be written differently for Windows or Macintosh
6 *	platforms.
7 *
8 * Copyright (c) 1995 Sun Microsystems, Inc.
9 *
10 * See the file "license.terms" for information on usage and redistribution of
11 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 *
13 * RCS: @(#) $Id$
14 */
15
16#include "tkInt.h"
17#ifdef HAVE_XSS
18#include <X11/extensions/scrnsaver.h>
19#endif
20
21/*
22 *----------------------------------------------------------------------
23 *
24 * TkGetServerInfo --
25 *
26 *	Given a window, this procedure returns information about the window
27 *	server for that window. This procedure provides the guts of the "winfo
28 *	server" command.
29 *
30 * Results:
31 *	None.
32 *
33 * Side effects:
34 *	None.
35 *
36 *----------------------------------------------------------------------
37 */
38
39void
40TkGetServerInfo(
41    Tcl_Interp *interp,		/* The server information is returned in this
42				 * interpreter's result. */
43    Tk_Window tkwin)		/* Token for window; this selects a particular
44				 * display and server. */
45{
46    char buffer[8 + TCL_INTEGER_SPACE * 2];
47    char buffer2[TCL_INTEGER_SPACE];
48
49    sprintf(buffer, "X%dR%d ", ProtocolVersion(Tk_Display(tkwin)),
50	    ProtocolRevision(Tk_Display(tkwin)));
51    sprintf(buffer2, " %d", VendorRelease(Tk_Display(tkwin)));
52    Tcl_AppendResult(interp, buffer, ServerVendor(Tk_Display(tkwin)),
53	    buffer2, (char *) NULL);
54}
55
56/*
57 *----------------------------------------------------------------------
58 *
59 * TkGetDefaultScreenName --
60 *
61 *	Returns the name of the screen that Tk should use during
62 *	initialization.
63 *
64 * Results:
65 *	Returns the argument or a string that should not be freed by the
66 *	caller.
67 *
68 * Side effects:
69 *	None.
70 *
71 *----------------------------------------------------------------------
72 */
73
74CONST char *
75TkGetDefaultScreenName(
76    Tcl_Interp *interp,		/* Interp used to find environment
77				 * variables. */
78    CONST char *screenName)	/* Screen name from command line, or NULL. */
79{
80    if ((screenName == NULL) || (screenName[0] == '\0')) {
81	screenName = Tcl_GetVar2(interp, "env", "DISPLAY", TCL_GLOBAL_ONLY);
82    }
83    return screenName;
84}
85
86/*
87 *----------------------------------------------------------------------
88 *
89 * Tk_UpdatePointer --
90 *
91 *	Unused function in UNIX
92 *
93 * Results:
94 *	None.
95 *
96 * Side effects:
97 *	None.
98 *
99 *----------------------------------------------------------------------
100 */
101
102void
103Tk_UpdatePointer(
104    Tk_Window tkwin,		/* Window to which pointer event is reported.
105				 * May be NULL. */
106    int x, int y,		/* Pointer location in root coords. */
107    int state)			/* Modifier state mask. */
108{
109  /*
110   * This function intentionally left blank
111   */
112}
113
114/*
115 *----------------------------------------------------------------------
116 *
117 * TkpBuildRegionFromAlphaData --
118 *
119 *	Set up a rectangle of the given region based on the supplied alpha
120 *	data.
121 *
122 * Results:
123 *	None
124 *
125 * Side effects:
126 *	The region is updated, with extra pixels added to it.
127 *
128 *----------------------------------------------------------------------
129 */
130
131void
132TkpBuildRegionFromAlphaData(
133    TkRegion region,		/* Region to be updated. */
134    unsigned x, unsigned y,	/* Where in region to update. */
135    unsigned width, unsigned height,
136				/* Size of rectangle to update. */
137    unsigned char *dataPtr,	/* Data to read from. */
138    unsigned pixelStride,	/* Num bytes from one piece of alpha data to
139				 * the next in the line. */
140    unsigned lineStride)	/* Num bytes from one line of alpha data to
141				 * the next line. */
142{
143    unsigned char *lineDataPtr;
144    unsigned int x1, y1, end;
145    XRectangle rect;
146
147    for (y1 = 0; y1 < height; y1++) {
148	lineDataPtr = dataPtr;
149	for (x1 = 0; x1 < width; x1 = end) {
150	    /*
151	     * Search for first non-transparent pixel.
152	     */
153
154	    while ((x1 < width) && !*lineDataPtr) {
155		x1++;
156		lineDataPtr += pixelStride;
157	    }
158	    end = x1;
159
160	    /*
161	     * Search for first transparent pixel.
162	     */
163
164	    while ((end < width) && *lineDataPtr) {
165		end++;
166		lineDataPtr += pixelStride;
167	    }
168	    if (end > x1) {
169		rect.x = x + x1;
170		rect.y = y + y1;
171		rect.width = end - x1;
172		rect.height = 1;
173		TkUnionRectWithRegion(&rect, region, region);
174	    }
175	}
176	dataPtr += lineStride;
177    }
178}
179
180/*
181 *----------------------------------------------------------------------
182 *
183 * Tk_GetUserInactiveTime --
184 *
185 *	Return the number of milliseconds the user was inactive.
186 *
187 * Results:
188 *	The number of milliseconds since the user's latest interaction with
189 *	the system on the given display, or -1 if the XScreenSaver extension
190 *	is not supported by the client libraries or the X server
191 *	implementation.
192 *
193 * Side effects:
194 *	None.
195 *----------------------------------------------------------------------
196 */
197
198long
199Tk_GetUserInactiveTime(
200    Display *dpy)		/* The display for which to query the inactive
201				 * time. */
202{
203    long inactiveTime = -1;
204#ifdef HAVE_XSS
205    int eventBase, errorBase, major, minor;
206
207    /*
208     * Calling XScreenSaverQueryVersion seems to be needed to prevent a crash
209     * on some buggy versions of XFree86.
210     */
211
212    if (
213#ifdef __APPLE__
214 	XScreenSaverQueryInfo != NULL && /* Support for weak-linked libXss. */
215#endif
216	XScreenSaverQueryExtension(dpy, &eventBase, &errorBase) &&
217	XScreenSaverQueryVersion(dpy, &major, &minor)) {
218
219	XScreenSaverInfo *info = XScreenSaverAllocInfo();
220
221	if (info == NULL) {
222	    /*
223	     * We are out of memory.
224	     */
225
226	    Tcl_Panic("Out of memory: XScreenSaverAllocInfo failed in Tk_GetUserInactiveTime");
227	}
228	if (XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), info)) {
229	    inactiveTime = info->idle;
230	}
231	XFree(info);
232    }
233#endif /* HAVE_XSS */
234    return inactiveTime;
235}
236
237/*
238 *----------------------------------------------------------------------
239 *
240 * Tk_ResetUserInactiveTime --
241 *
242 *	Reset the user inactivity timer
243 *
244 * Results:
245 *	none
246 *
247 * Side effects:
248 *	The user inactivity timer of the underlaying windowing system is reset
249 *	to zero.
250 *
251 *----------------------------------------------------------------------
252 */
253
254void
255Tk_ResetUserInactiveTime(
256    Display *dpy)
257{
258    XResetScreenSaver(dpy);
259}
260
261/*
262 * Local Variables:
263 * mode: c
264 * c-basic-offset: 4
265 * fill-column: 78
266 * End:
267 */
268