aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/dmx/dmxlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/dmx/dmxlog.c')
-rw-r--r--xorg-server/hw/dmx/dmxlog.c350
1 files changed, 350 insertions, 0 deletions
diff --git a/xorg-server/hw/dmx/dmxlog.c b/xorg-server/hw/dmx/dmxlog.c
new file mode 100644
index 000000000..31a74cdf1
--- /dev/null
+++ b/xorg-server/hw/dmx/dmxlog.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2001 Red Hat Inc., Durham, North Carolina.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ * This file encapsulated all of the logging functions that are used by
+ * DMX for informational, warning, and error messages. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxlog.h"
+#include "dmxinput.h"
+#ifdef XINPUT
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#endif
+
+static dmxLogLevel dmxCurrentLogLevel = dmxDebug;
+
+/** Set the default level for logging to #dmxLogLevel. Returns the
+ * previous log level. */
+dmxLogLevel dmxSetLogLevel(dmxLogLevel newLevel)
+{
+ dmxLogLevel oldLevel = dmxCurrentLogLevel;
+ if (newLevel > dmxFatal) newLevel = dmxFatal;
+ dmxCurrentLogLevel = newLevel;
+ return oldLevel;
+}
+
+/** Returns the log level set by #dmxLogLevel. */
+dmxLogLevel dmxGetLogLevel(void)
+{
+ return dmxCurrentLogLevel;
+}
+
+#ifdef DMX_LOG_STANDALONE
+/* When using this file as part of a stand-alone (i.e., non-X-Server
+ * program, then the ultimate output routines have to be defined. */
+
+/** Provide an ErrorF function when used stand-alone. */
+void ErrorF(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vfprintf(stderr, format, args); /* RATS: We assume the format string
+ * is trusted, since it is always
+ * from a log message in our code. */
+ va_end(args);
+}
+
+/** Provide an VFatalError function when used stand-alone. */
+static void VFatalError(const char *format, va_list args)
+{
+ vfprintf(stderr, format, args); /* RATS: We assume the format string
+ * is trusted, since it is always
+ * from a log message in our code. */
+ exit(1);
+}
+
+/** Provide an VErrorF function when used stand-alone. */
+void VErrorF(const char *format, va_list args)
+{
+ vfprintf(stderr, format, args); /* RATS: We assume the format string
+ * is trusted, since it is always
+ * from a log message in our code. */
+}
+#else
+/** This function was removed between XFree86 4.3.0 and XFree86 4.4.0. */
+extern void AbortServer(void);
+static void VFatalError(const char *format, va_list args)
+{
+ VErrorF(format, args);
+ ErrorF("\n");
+#ifdef DDXOSFATALERROR
+ OsVendorFatalError();
+#endif
+ AbortServer();
+ /*NOTREACHED*/
+}
+#endif
+
+/* Prints a consistent header for each line. */
+static void dmxHeader(dmxLogLevel logLevel, DMXInputInfo *dmxInput,
+ DMXScreenInfo *dmxScreen)
+{
+ const char *type = "??";
+
+ switch (logLevel) {
+ case dmxDebug: type = ".."; break;
+ case dmxInfo: type = "II"; break;
+ case dmxWarning: type = "**"; break;
+ case dmxError: type = "!!"; break;
+ case dmxFatal: type = "Fatal Error"; break;
+ }
+
+ if (dmxInput && dmxScreen) {
+ ErrorF("(%s) dmx[i%d/%s;o%d/%s]: ", type,
+ dmxInput->inputIdx, dmxInput->name,
+ dmxScreen->index, dmxScreen->name);
+ } else if (dmxScreen) {
+ ErrorF("(%s) dmx[o%d/%s]: ", type,
+ dmxScreen->index, dmxScreen->name);
+ } else if (dmxInput) {
+ const char *pt = strchr(dmxInput->name, ',');
+ int len = (pt
+ ? (size_t)(pt-dmxInput->name)
+ : strlen(dmxInput->name));
+
+ ErrorF("(%s) dmx[i%d/%*.*s]: ", type,
+ dmxInput->inputIdx, len, len, dmxInput->name);
+ } else {
+ ErrorF("(%s) dmx: ", type);
+ }
+}
+
+/* Prints the error message with the appropriate low-level X output
+ * routine. */
+static void dmxMessage(dmxLogLevel logLevel, const char *format, va_list args)
+{
+ if (logLevel == dmxFatal || logLevel >= dmxCurrentLogLevel) {
+ if (logLevel == dmxFatal) VFatalError(format, args);
+ else VErrorF(format, args);
+ }
+}
+
+/** Log the specified message at the specified \a logLevel. \a format
+ * can be a printf-like format expression. */
+void dmxLog(dmxLogLevel logLevel, const char *format, ...)
+{
+ va_list args;
+
+ dmxHeader(logLevel, NULL, NULL);
+ va_start(args, format);
+ dmxMessage(logLevel, format, args);
+ va_end(args);
+}
+
+/** Continue a log message without printing the message prefix. */
+void dmxLogCont(dmxLogLevel logLevel, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ dmxMessage(logLevel, format, args);
+ va_end(args);
+}
+
+#ifndef DMX_LOG_STANDALONE
+/** Log an informational message (at level #dmxInfo) related to ouput.
+ * The message prefix will contain backend information from \a
+ * dmxScreen. */
+void dmxLogOutput(DMXScreenInfo *dmxScreen, const char *format, ...)
+{
+ va_list args;
+
+ dmxHeader(dmxInfo, NULL, dmxScreen);
+ va_start(args, format);
+ dmxMessage(dmxInfo, format, args);
+ va_end(args);
+}
+
+/** Continue a message related to output without printing the message
+ * prefix. */
+void dmxLogOutputCont(DMXScreenInfo *dmxScreen, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ dmxMessage(dmxInfo, format, args);
+ va_end(args);
+}
+
+/** Log a warning message (at level #dmxWarning) related to output.
+ * The message prefix will contain backend information from \a
+ * dmxScreen. */
+void dmxLogOutputWarning(DMXScreenInfo *dmxScreen, const char *format, ...)
+{
+ va_list args;
+
+ dmxHeader(dmxWarning, NULL, dmxScreen);
+ va_start(args, format);
+ dmxMessage(dmxWarning, format, args);
+ va_end(args);
+}
+
+/** Log an informational message (at level #dmxInfo) related to input.
+ * The message prefix will contain information from \a dmxInput. */
+void dmxLogInput(DMXInputInfo *dmxInput, const char *format, ...)
+{
+ va_list args;
+
+ dmxHeader(dmxInfo, dmxInput, NULL);
+ va_start(args, format);
+ dmxMessage(dmxInfo, format, args);
+ va_end(args);
+}
+
+/** Continue a message related to input without printing the message
+ * prefix. */
+void dmxLogInputCont(DMXInputInfo *dmxInput, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ dmxMessage(dmxInfo, format, args);
+ va_end(args);
+}
+
+/** Print \a argc messages, each describing an element in \a argv. This
+ * is maingly for debugging purposes. */
+void dmxLogArgs(dmxLogLevel logLevel, int argc, char **argv)
+{
+ int i;
+ for (i = 0; i < argc; i++)
+ dmxLog(logLevel, " Arg[%d] = \"%s\"\n", i, argv[i]);
+}
+
+/** Print messages at level #dmxInfo describing the visuals in \a vi. */
+void dmxLogVisual(DMXScreenInfo *dmxScreen, XVisualInfo *vi, int defaultVisual)
+{
+ const char *class = "Unknown";
+
+ switch (vi->class) {
+ case StaticGray: class = "StaticGray "; break;
+ case GrayScale: class = "GrayScale "; break;
+ case StaticColor: class = "StaticColor"; break;
+ case PseudoColor: class = "PseudoColor"; break;
+ case TrueColor: class = "TrueColor "; break;
+ case DirectColor: class = "DirectColor"; break;
+ }
+
+ if (dmxScreen) {
+ dmxLogOutput(dmxScreen,
+ "0x%02x %s %2db %db/rgb %3d 0x%04x 0x%04x 0x%04x%s\n",
+ vi->visualid, class, vi->depth, vi->bits_per_rgb,
+ vi->colormap_size,
+ vi->red_mask, vi->green_mask, vi->blue_mask,
+ defaultVisual ? " *" : "");
+ } else {
+ dmxLog(dmxInfo,
+ " 0x%02x %s %2db %db/rgb %3d 0x%04x 0x%04x 0x%04x%s\n",
+ vi->visualid, class, vi->depth, vi->bits_per_rgb,
+ vi->colormap_size,
+ vi->red_mask, vi->green_mask, vi->blue_mask,
+ defaultVisual ? " *" : "");
+ }
+}
+
+#ifdef XINPUT
+/** Translate a (normalized) XInput event \a type into a human-readable
+ * string. */
+const char *dmxXInputEventName(int type)
+{
+ switch (type) {
+ case XI_DeviceValuator: return "XI_DeviceValuator";
+ case XI_DeviceKeyPress: return "XI_DeviceKeyPress";
+ case XI_DeviceKeyRelease: return "XI_DeviceKeyRelease";
+ case XI_DeviceButtonPress: return "XI_DeviceButtonPress";
+ case XI_DeviceButtonRelease: return "XI_DeviceButtonRelease";
+ case XI_DeviceMotionNotify: return "XI_DeviceMotionNotify";
+ case XI_DeviceFocusIn: return "XI_DeviceFocusIn";
+ case XI_DeviceFocusOut: return "XI_DeviceFocusOut";
+ case XI_ProximityIn: return "XI_ProximityIn";
+ case XI_ProximityOut: return "XI_ProximityOut";
+ case XI_DeviceStateNotify: return "XI_DeviceStateNotify";
+ case XI_DeviceMappingNotify: return "XI_DeviceMappingNotify";
+ case XI_ChangeDeviceNotify: return "XI_ChangeDeviceNotify";
+ case XI_DeviceKeystateNotify: return "XI_DeviceKeystateNotify";
+ case XI_DeviceButtonstateNotify: return "XI_DeviceButtonstateNotify";
+ default: return "unknown";
+ }
+}
+
+#endif
+#endif
+
+/** Translate an event \a type into a human-readable string. */
+const char *dmxEventName(int type)
+{
+ switch (type) {
+ case KeyPress: return "KeyPress";
+ case KeyRelease: return "KeyRelease";
+ case ButtonPress: return "ButtonPress";
+ case ButtonRelease: return "ButtonRelease";
+ case MotionNotify: return "MotionNotify";
+ case EnterNotify: return "EnterNotify";
+ case LeaveNotify: return "LeaveNotify";
+ case FocusIn: return "FocusIn";
+ case FocusOut: return "FocusOut";
+ case KeymapNotify: return "KeymapNotify";
+ case Expose: return "Expose";
+ case GraphicsExpose: return "GraphicsExpose";
+ case NoExpose: return "NoExpose";
+ case VisibilityNotify: return "VisibilityNotify";
+ case CreateNotify: return "CreateNotify";
+ case DestroyNotify: return "DestroyNotify";
+ case UnmapNotify: return "UnmapNotify";
+ case MapNotify: return "MapNotify";
+ case MapRequest: return "MapRequest";
+ case ReparentNotify: return "ReparentNotify";
+ case ConfigureNotify: return "ConfigureNotify";
+ case ConfigureRequest: return "ConfigureRequest";
+ case GravityNotify: return "GravityNotify";
+ case ResizeRequest: return "ResizeRequest";
+ case CirculateNotify: return "CirculateNotify";
+ case CirculateRequest: return "CirculateRequest";
+ case PropertyNotify: return "PropertyNotify";
+ case SelectionClear: return "SelectionClear";
+ case SelectionRequest: return "SelectionRequest";
+ case SelectionNotify: return "SelectionNotify";
+ case ColormapNotify: return "ColormapNotify";
+ case ClientMessage: return "ClientMessage";
+ case MappingNotify: return "MappingNotify";
+ default: return "<unknown>";
+ }
+}
+