2 * Copyright 2001 Red Hat Inc., Durham, North Carolina.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * Rickard E. (Rik) Faith <faith@redhat.com>
35 * This file encapsulated all of the logging functions that are used by
36 * DMX for informational, warning, and error messages. */
38 #ifdef HAVE_DMX_CONFIG_H
39 #include <dmx-config.h>
45 #include <X11/extensions/XI.h>
46 #include <X11/extensions/XIproto.h>
48 static dmxLogLevel dmxCurrentLogLevel
= dmxDebug
;
50 /** Set the default level for logging to #dmxLogLevel. Returns the
51 * previous log level. */
53 dmxSetLogLevel(dmxLogLevel newLevel
)
55 dmxLogLevel oldLevel
= dmxCurrentLogLevel
;
57 if (newLevel
> dmxFatal
)
59 dmxCurrentLogLevel
= newLevel
;
63 /** Returns the log level set by #dmxLogLevel. */
67 return dmxCurrentLogLevel
;
70 #ifdef DMX_LOG_STANDALONE
71 /* When using this file as part of a stand-alone (i.e., non-X-Server
72 * program, then the ultimate output routines have to be defined. */
74 /** Provide an ErrorF function when used stand-alone. */
76 ErrorF(const char *format
, ...)
80 va_start(args
, format
);
81 vfprintf(stderr
, format
, args
); /* RATS: We assume the format string
82 * is trusted, since it is always
83 * from a log message in our code. */
87 /** Provide an VFatalError function when used stand-alone. */
89 VFatalError(const char *format
, va_list args
) _X_ATTRIBUTE_PRINTF(1, 0) _X_NORETURN
;
91 VFatalError(const char *format
, va_list args
)
93 vfprintf(stderr
, format
, args
); /* RATS: We assume the format string
94 * is trusted, since it is always
95 * from a log message in our code. */
99 /** Provide an VErrorF function when used stand-alone. */
101 VErrorF(const char *format
, va_list args
)
103 vfprintf(stderr
, format
, args
); /* RATS: We assume the format string
104 * is trusted, since it is always
105 * from a log message in our code. */
108 /** This function was removed between XFree86 4.3.0 and XFree86 4.4.0. */
109 extern void AbortServer(void) _X_NORETURN
;
111 VFatalError(const char *format
, va_list args
) _X_ATTRIBUTE_PRINTF(1, 0) _X_NORETURN
;
113 VFatalError(const char *format
, va_list args
)
115 VErrorF(format
, args
);
121 /* Prints a consistent header for each line. */
123 dmxHeader(dmxLogLevel logLevel
, DMXInputInfo
* dmxInput
,
124 DMXScreenInfo
* dmxScreen
)
126 const char *type
= "??";
142 type
= "Fatal Error";
146 if (dmxInput
&& dmxScreen
) {
147 ErrorF("(%s) dmx[i%d/%s;o%d/%s]: ", type
,
148 dmxInput
->inputIdx
, dmxInput
->name
,
149 dmxScreen
->index
, dmxScreen
->name
);
151 else if (dmxScreen
) {
152 ErrorF("(%s) dmx[o%d/%s]: ", type
, dmxScreen
->index
, dmxScreen
->name
);
155 const char *pt
= strchr(dmxInput
->name
, ',');
156 int len
= (pt
? (size_t) (pt
- dmxInput
->name
)
157 : strlen(dmxInput
->name
));
159 ErrorF("(%s) dmx[i%d/%*.*s]: ", type
,
160 dmxInput
->inputIdx
, len
, len
, dmxInput
->name
);
163 ErrorF("(%s) dmx: ", type
);
167 /* Prints the error message with the appropriate low-level X output
170 dmxMessage(dmxLogLevel logLevel
, const char *format
, va_list args
) _X_ATTRIBUTE_PRINTF(2, 0);
172 dmxMessage(dmxLogLevel logLevel
, const char *format
, va_list args
)
174 if (logLevel
== dmxFatal
|| logLevel
>= dmxCurrentLogLevel
) {
175 if (logLevel
== dmxFatal
)
176 VFatalError(format
, args
);
178 VErrorF(format
, args
);
182 /** Log the specified message at the specified \a logLevel. \a format
183 * can be a printf-like format expression. */
185 dmxLog(dmxLogLevel logLevel
, const char *format
, ...)
189 dmxHeader(logLevel
, NULL
, NULL
);
190 va_start(args
, format
);
191 dmxMessage(logLevel
, format
, args
);
195 /** Continue a log message without printing the message prefix. */
197 dmxLogCont(dmxLogLevel logLevel
, const char *format
, ...)
201 va_start(args
, format
);
202 dmxMessage(logLevel
, format
, args
);
206 #ifndef DMX_LOG_STANDALONE
207 /** Log an informational message (at level #dmxInfo) related to ouput.
208 * The message prefix will contain backend information from \a
211 dmxLogOutput(DMXScreenInfo
* dmxScreen
, const char *format
, ...)
215 dmxHeader(dmxInfo
, NULL
, dmxScreen
);
216 va_start(args
, format
);
217 dmxMessage(dmxInfo
, format
, args
);
221 /** Continue a message related to output without printing the message
224 dmxLogOutputCont(DMXScreenInfo
* dmxScreen
, const char *format
, ...)
228 va_start(args
, format
);
229 dmxMessage(dmxInfo
, format
, args
);
233 /** Log a warning message (at level #dmxWarning) related to output.
234 * The message prefix will contain backend information from \a
237 dmxLogOutputWarning(DMXScreenInfo
* dmxScreen
, const char *format
, ...)
241 dmxHeader(dmxWarning
, NULL
, dmxScreen
);
242 va_start(args
, format
);
243 dmxMessage(dmxWarning
, format
, args
);
247 /** Log an informational message (at level #dmxInfo) related to input.
248 * The message prefix will contain information from \a dmxInput. */
250 dmxLogInput(DMXInputInfo
* dmxInput
, const char *format
, ...)
254 dmxHeader(dmxInfo
, dmxInput
, NULL
);
255 va_start(args
, format
);
256 dmxMessage(dmxInfo
, format
, args
);
260 /** Continue a message related to input without printing the message
263 dmxLogInputCont(DMXInputInfo
* dmxInput
, const char *format
, ...)
267 va_start(args
, format
);
268 dmxMessage(dmxInfo
, format
, args
);
272 /** Print \a argc messages, each describing an element in \a argv. This
273 * is maingly for debugging purposes. */
275 dmxLogArgs(dmxLogLevel logLevel
, int argc
, char **argv
)
279 for (i
= 0; i
< argc
; i
++)
280 dmxLog(logLevel
, " Arg[%d] = \"%s\"\n", i
, argv
[i
]);
283 /** Print messages at level #dmxInfo describing the visuals in \a vi. */
285 dmxLogVisual(DMXScreenInfo
* dmxScreen
, XVisualInfo
* vi
, int defaultVisual
)
287 const char *class = "Unknown";
291 class = "StaticGray ";
294 class = "GrayScale ";
297 class = "StaticColor";
300 class = "PseudoColor";
303 class = "TrueColor ";
306 class = "DirectColor";
309 #define VisualLogFormat "0x%02lx %s %2db %db/rgb %3d 0x%04lx 0x%04lx 0x%04lx%s\n"
312 dmxLogOutput(dmxScreen
,
314 vi
->visualid
, class, vi
->depth
, vi
->bits_per_rgb
,
316 vi
->red_mask
, vi
->green_mask
, vi
->blue_mask
,
317 defaultVisual
? " *" : "");
322 vi
->visualid
, class, vi
->depth
, vi
->bits_per_rgb
,
324 vi
->red_mask
, vi
->green_mask
, vi
->blue_mask
,
325 defaultVisual
? " *" : "");
329 /** Translate a (normalized) XInput event \a type into a human-readable
332 dmxXInputEventName(int type
)
335 case XI_DeviceValuator
:
336 return "XI_DeviceValuator";
337 case XI_DeviceKeyPress
:
338 return "XI_DeviceKeyPress";
339 case XI_DeviceKeyRelease
:
340 return "XI_DeviceKeyRelease";
341 case XI_DeviceButtonPress
:
342 return "XI_DeviceButtonPress";
343 case XI_DeviceButtonRelease
:
344 return "XI_DeviceButtonRelease";
345 case XI_DeviceMotionNotify
:
346 return "XI_DeviceMotionNotify";
347 case XI_DeviceFocusIn
:
348 return "XI_DeviceFocusIn";
349 case XI_DeviceFocusOut
:
350 return "XI_DeviceFocusOut";
352 return "XI_ProximityIn";
353 case XI_ProximityOut
:
354 return "XI_ProximityOut";
355 case XI_DeviceStateNotify
:
356 return "XI_DeviceStateNotify";
357 case XI_DeviceMappingNotify
:
358 return "XI_DeviceMappingNotify";
359 case XI_ChangeDeviceNotify
:
360 return "XI_ChangeDeviceNotify";
361 case XI_DeviceKeystateNotify
:
362 return "XI_DeviceKeystateNotify";
363 case XI_DeviceButtonstateNotify
:
364 return "XI_DeviceButtonstateNotify";
372 /** Translate an event \a type into a human-readable string. */
374 dmxEventName(int type
)
382 return "ButtonPress";
384 return "ButtonRelease";
386 return "MotionNotify";
388 return "EnterNotify";
390 return "LeaveNotify";
396 return "KeymapNotify";
400 return "GraphicsExpose";
403 case VisibilityNotify
:
404 return "VisibilityNotify";
406 return "CreateNotify";
408 return "DestroyNotify";
410 return "UnmapNotify";
416 return "ReparentNotify";
417 case ConfigureNotify
:
418 return "ConfigureNotify";
419 case ConfigureRequest
:
420 return "ConfigureRequest";
422 return "GravityNotify";
424 return "ResizeRequest";
425 case CirculateNotify
:
426 return "CirculateNotify";
427 case CirculateRequest
:
428 return "CirculateRequest";
430 return "PropertyNotify";
432 return "SelectionClear";
433 case SelectionRequest
:
434 return "SelectionRequest";
435 case SelectionNotify
:
436 return "SelectionNotify";
438 return "ColormapNotify";
440 return "ClientMessage";
442 return "MappingNotify";