Add Distributed Multihead X (DMX) support
This commit is contained in:
105
Xext/panoramiX.c
105
Xext/panoramiX.c
@@ -53,6 +53,12 @@ Equipment Corporation.
|
||||
#include "modinit.h"
|
||||
|
||||
|
||||
#ifdef GLXPROXY
|
||||
extern VisualPtr glxMatchVisual(ScreenPtr pScreen,
|
||||
VisualPtr pVisual,
|
||||
ScreenPtr pMatchScreen);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static unsigned char PanoramiXReqCode = 0;
|
||||
#endif
|
||||
@@ -416,6 +422,56 @@ XineramaRegisterConnectionBlockCallback(void (*func)(void))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void XineramaInitData(ScreenPtr pScreen)
|
||||
{
|
||||
int i, w, h;
|
||||
|
||||
REGION_NULL(pScreen, &PanoramiXScreenRegion)
|
||||
for (i = 0; i < PanoramiXNumScreens; i++) {
|
||||
BoxRec TheBox;
|
||||
|
||||
pScreen = screenInfo.screens[i];
|
||||
|
||||
panoramiXdataPtr[i].x = dixScreenOrigins[i].x;
|
||||
panoramiXdataPtr[i].y = dixScreenOrigins[i].y;
|
||||
panoramiXdataPtr[i].width = pScreen->width;
|
||||
panoramiXdataPtr[i].height = pScreen->height;
|
||||
|
||||
TheBox.x1 = panoramiXdataPtr[i].x;
|
||||
TheBox.x2 = TheBox.x1 + panoramiXdataPtr[i].width;
|
||||
TheBox.y1 = panoramiXdataPtr[i].y;
|
||||
TheBox.y2 = TheBox.y1 + panoramiXdataPtr[i].height;
|
||||
|
||||
REGION_INIT(pScreen, &XineramaScreenRegions[i], &TheBox, 1);
|
||||
REGION_UNION(pScreen, &PanoramiXScreenRegion, &PanoramiXScreenRegion,
|
||||
&XineramaScreenRegions[i]);
|
||||
}
|
||||
|
||||
PanoramiXPixWidth = panoramiXdataPtr[0].x + panoramiXdataPtr[0].width;
|
||||
PanoramiXPixHeight = panoramiXdataPtr[0].y + panoramiXdataPtr[0].height;
|
||||
|
||||
for (i = 1; i < PanoramiXNumScreens; i++) {
|
||||
w = panoramiXdataPtr[i].x + panoramiXdataPtr[i].width;
|
||||
h = panoramiXdataPtr[i].y + panoramiXdataPtr[i].height;
|
||||
|
||||
if (PanoramiXPixWidth < w)
|
||||
PanoramiXPixWidth = w;
|
||||
if (PanoramiXPixHeight < h)
|
||||
PanoramiXPixHeight = h;
|
||||
}
|
||||
}
|
||||
|
||||
void XineramaReinitData(ScreenPtr pScreen)
|
||||
{
|
||||
int i;
|
||||
|
||||
REGION_UNINIT(pScreen, &PanoramiXScreenRegion);
|
||||
for (i = 0; i < PanoramiXNumScreens; i++)
|
||||
REGION_UNINIT(pScreen, &XineramaScreenRegions[i]);
|
||||
|
||||
XineramaInitData(pScreen);
|
||||
}
|
||||
|
||||
/*
|
||||
* PanoramiXExtensionInit():
|
||||
* Called from InitExtensions in main().
|
||||
@@ -430,7 +486,6 @@ void PanoramiXExtensionInit(int argc, char *argv[])
|
||||
ExtensionEntry *extEntry;
|
||||
ScreenPtr pScreen = screenInfo.screens[0];
|
||||
PanoramiXScreenPtr pScreenPriv;
|
||||
int w, h;
|
||||
|
||||
if (noPanoramiXExtension)
|
||||
return;
|
||||
@@ -509,41 +564,7 @@ void PanoramiXExtensionInit(int argc, char *argv[])
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
REGION_NULL(pScreen, &PanoramiXScreenRegion);
|
||||
for (i = 0; i < PanoramiXNumScreens; i++) {
|
||||
BoxRec TheBox;
|
||||
|
||||
pScreen = screenInfo.screens[i];
|
||||
|
||||
panoramiXdataPtr[i].x = dixScreenOrigins[i].x;
|
||||
panoramiXdataPtr[i].y = dixScreenOrigins[i].y;
|
||||
panoramiXdataPtr[i].width = pScreen->width;
|
||||
panoramiXdataPtr[i].height = pScreen->height;
|
||||
|
||||
TheBox.x1 = panoramiXdataPtr[i].x;
|
||||
TheBox.x2 = TheBox.x1 + panoramiXdataPtr[i].width;
|
||||
TheBox.y1 = panoramiXdataPtr[i].y;
|
||||
TheBox.y2 = TheBox.y1 + panoramiXdataPtr[i].height;
|
||||
|
||||
REGION_INIT(pScreen, &XineramaScreenRegions[i], &TheBox, 1);
|
||||
REGION_UNION(pScreen, &PanoramiXScreenRegion, &PanoramiXScreenRegion,
|
||||
&XineramaScreenRegions[i]);
|
||||
}
|
||||
|
||||
|
||||
PanoramiXPixWidth = panoramiXdataPtr[0].x + panoramiXdataPtr[0].width;
|
||||
PanoramiXPixHeight = panoramiXdataPtr[0].y + panoramiXdataPtr[0].height;
|
||||
|
||||
for (i = 1; i < PanoramiXNumScreens; i++) {
|
||||
w = panoramiXdataPtr[i].x + panoramiXdataPtr[i].width;
|
||||
h = panoramiXdataPtr[i].y + panoramiXdataPtr[i].height;
|
||||
|
||||
if(PanoramiXPixWidth < w)
|
||||
PanoramiXPixWidth = w;
|
||||
if(PanoramiXPixHeight < h)
|
||||
PanoramiXPixHeight = h;
|
||||
}
|
||||
XineramaInitData(pScreen);
|
||||
|
||||
/*
|
||||
* Put our processes into the ProcVector
|
||||
@@ -789,6 +810,18 @@ void PanoramiXConsolidate(void)
|
||||
/* check if the visual exists on all screens */
|
||||
for (j = 1; j < PanoramiXNumScreens; j++) {
|
||||
pScreen2 = screenInfo.screens[j];
|
||||
|
||||
#ifdef GLXPROXY
|
||||
pVisual2 = glxMatchVisual(pScreen, pVisual, pScreen2);
|
||||
if (pVisual2) {
|
||||
PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j] =
|
||||
pVisual2->vid;
|
||||
continue;
|
||||
} else if (glxMatchVisual(pScreen, pVisual, pScreen)) {
|
||||
PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j] = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
pVisual2 = pScreen2->visuals;
|
||||
|
||||
for (k = 0; k < pScreen2->numVisuals; k++, pVisual2++) {
|
||||
|
||||
@@ -20,6 +20,8 @@ extern WindowPtr PanoramiXChangeWindow(int, WindowPtr);
|
||||
extern Bool XineramaRegisterConnectionBlockCallback(void (*func)(void));
|
||||
extern int XineramaDeleteResource(pointer, XID);
|
||||
|
||||
extern void XineramaReinitData(ScreenPtr);
|
||||
|
||||
extern RegionRec XineramaScreenRegions[MAXSCREENS];
|
||||
|
||||
extern unsigned long XRC_DRAWABLE;
|
||||
|
||||
42
dix/events.c
42
dix/events.c
@@ -1,4 +1,4 @@
|
||||
/* $XdotOrg$ */
|
||||
/* $XdotOrg: xc/programs/Xserver/dix/events.c,v 1.2 2004/04/23 19:04:44 eich Exp $ */
|
||||
/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.51 2004/01/12 17:04:52 tsi Exp $ */
|
||||
/************************************************************
|
||||
|
||||
@@ -2036,6 +2036,46 @@ WindowsRestructured()
|
||||
(void) CheckMotion((xEvent *)NULL);
|
||||
}
|
||||
|
||||
#ifdef PANORAMIX
|
||||
/* This was added to support reconfiguration under Xdmx. The problem is
|
||||
* that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
|
||||
* other than 0,0, the information in the private sprite structure must
|
||||
* be updated accordingly, or XYToWindow (and other routines) will not
|
||||
* compute correctly. */
|
||||
void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
|
||||
{
|
||||
ScreenPtr pScreen = win->drawable.pScreen;
|
||||
GrabPtr grab;
|
||||
|
||||
if (noPanoramiXExtension) return;
|
||||
|
||||
sprite.hot.x -= xoff;
|
||||
sprite.hot.y -= yoff;
|
||||
|
||||
sprite.hotPhys.x -= xoff;
|
||||
sprite.hotPhys.y -= yoff;
|
||||
|
||||
sprite.hotLimits.x1 -= xoff;
|
||||
sprite.hotLimits.y1 -= yoff;
|
||||
sprite.hotLimits.x2 -= xoff;
|
||||
sprite.hotLimits.y2 -= yoff;
|
||||
|
||||
if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg1))
|
||||
REGION_TRANSLATE(sprite.screen, &sprite.Reg1, xoff, yoff);
|
||||
if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg2))
|
||||
REGION_TRANSLATE(sprite.screen, &sprite.Reg2, xoff, yoff);
|
||||
|
||||
/* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
|
||||
if ((grab = inputInfo.pointer->grab) && grab->confineTo) {
|
||||
if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
|
||||
sprite.hotPhys.x = sprite.hotPhys.y = 0;
|
||||
ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
|
||||
} else
|
||||
ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
|
||||
TRUE, FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
DefineInitialRootWindow(win)
|
||||
register WindowPtr win;
|
||||
|
||||
23
dix/main.c
23
dix/main.c
@@ -1,4 +1,4 @@
|
||||
/* $XdotOrg: xc/programs/Xserver/dix/main.c,v 1.1.4.5.2.4.6.1 2004/04/20 03:27:08 gisburn Exp $ */
|
||||
/* $XdotOrg: xc/programs/Xserver/dix/main.c,v 1.2 2004/04/23 19:04:44 eich Exp $ */
|
||||
/* $XFree86: xc/programs/Xserver/dix/main.c,v 3.43 2003/10/30 21:21:02 herrb Exp $ */
|
||||
/***********************************************************
|
||||
|
||||
@@ -500,6 +500,21 @@ main(int argc, char *argv[], char *envp[])
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int VendorRelease = VENDOR_RELEASE;
|
||||
static char *VendorString = VENDOR_STRING;
|
||||
|
||||
void
|
||||
SetVendorRelease(int release)
|
||||
{
|
||||
VendorRelease = release;
|
||||
}
|
||||
|
||||
void
|
||||
SetVendorString(char *string)
|
||||
{
|
||||
VendorString = string;
|
||||
}
|
||||
|
||||
static int padlength[4] = {0, 3, 2, 1};
|
||||
|
||||
#ifndef PANORAMIX
|
||||
@@ -523,7 +538,7 @@ CreateConnectionBlock()
|
||||
/* Leave off the ridBase and ridMask, these must be sent with
|
||||
connection */
|
||||
|
||||
setup.release = VENDOR_RELEASE;
|
||||
setup.release = VendorRelease;
|
||||
/*
|
||||
* per-server image and bitmap parameters are defined in Xmd.h
|
||||
*/
|
||||
@@ -535,7 +550,7 @@ CreateConnectionBlock()
|
||||
setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
|
||||
setup.motionBufferSize = NumMotionEvents();
|
||||
setup.numRoots = screenInfo.numScreens;
|
||||
setup.nbytesVendor = strlen(VENDOR_STRING);
|
||||
setup.nbytesVendor = strlen(VendorString);
|
||||
setup.numFormats = screenInfo.numPixmapFormats;
|
||||
setup.maxRequestSize = MAX_REQUEST_SIZE;
|
||||
QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
|
||||
@@ -552,7 +567,7 @@ CreateConnectionBlock()
|
||||
sizesofar = sizeof(xConnSetup);
|
||||
pBuf = ConnectionInfo + sizeof(xConnSetup);
|
||||
|
||||
memmove(pBuf, VENDOR_STRING, (int)setup.nbytesVendor);
|
||||
memmove(pBuf, VendorString, (int)setup.nbytesVendor);
|
||||
sizesofar += setup.nbytesVendor;
|
||||
pBuf += setup.nbytesVendor;
|
||||
i = padlength[setup.nbytesVendor & 3];
|
||||
|
||||
741
hw/dmx/Xdmx.man
Normal file
741
hw/dmx/Xdmx.man
Normal file
@@ -0,0 +1,741 @@
|
||||
.\" $XFree86$
|
||||
.\"
|
||||
.\" Copyright 2001-2004 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:
|
||||
.\"
|
||||
.\" he 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.
|
||||
.TH Xdmx 1 __vendorversion__
|
||||
.SH NAME
|
||||
Xdmx - Distributed Multi-head X server
|
||||
.SH SYNOPSIS
|
||||
.B Xdmx
|
||||
[:display] [option ...]
|
||||
.SH DESCRIPTION
|
||||
.I Xdmx
|
||||
is a proxy X server that uses one or more other X servers as its display
|
||||
devices. It provides multi-head X functionality for displays that might
|
||||
be located on different machines.
|
||||
.I Xdmx
|
||||
functions as a front-end X server that acts as a proxy to a set of
|
||||
back-end X servers. All of the visible rendering is passed to the
|
||||
back-end X servers. Clients connect to the
|
||||
.I Xdmx
|
||||
front-end, and everything appears as it would in a regular multi-head
|
||||
configuration. If Xinerama is enabled (e.g., with
|
||||
.B +xinerama
|
||||
on the command line), the clients see a single large screen.
|
||||
.PP
|
||||
.I Xdmx
|
||||
communicates to the back-end X servers using the standard X11 protocol,
|
||||
and standard and/or commonly available X server extensions.
|
||||
.SH OPTIONS
|
||||
In addition to the normal X server options described in the
|
||||
.I Xserver(1)
|
||||
manual page,
|
||||
.I Xdmx
|
||||
accepts the following command line switches:
|
||||
.TP 8
|
||||
.BI "\-display " display-name
|
||||
This specifies the name(s) of the back-end X server display(s) to connect
|
||||
to. This option may be specified multiple times to connect to more than
|
||||
one back-end display. The first is used as screen 0, the second as screen 1,
|
||||
etc. If this option is omitted, the
|
||||
.B $DISPLAY
|
||||
environment variable is used as the single back-end X server display.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "\-xinput " input-source
|
||||
This specifies the source to use for XInput extension devices. The
|
||||
choices are the same as for
|
||||
.BR "\-input " ,
|
||||
described below, except that core devices on backend servers cannot be
|
||||
treated as XInput extension devices. (Although extension devices on
|
||||
backend and console servers are supported as extension devices under
|
||||
.IR Xdmx ).
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "\-input " input-source
|
||||
This specifies the source to use for the core input devices. The choices are:
|
||||
.RS
|
||||
.TP 4
|
||||
.B dummy
|
||||
A set of dummy core input drivers are used. These never generate any
|
||||
input events.
|
||||
.sp
|
||||
.TP 4
|
||||
.B local
|
||||
The raw keyboard and pointer from the local computer are used. A
|
||||
comma-separated list of driver names can be appended. For example, to
|
||||
select the example Linux keyboard and PS/2 mouse driver use:
|
||||
.BR "-input local,kbd,ps2" .
|
||||
The following drivers have been implemented for Linux: kbd, ms (a
|
||||
two-button Microsoft mouse driver), ps2 (a PS/2 mouse driver), usb-mou
|
||||
(a USB mouse driver), usb-kbd (a USB keyboard driver), and usb-oth (a
|
||||
USB non-keyboard, non-mouse driver). Additional drivers may be
|
||||
implemented in the future. Appropriate defaults will be used if no
|
||||
comma-separated list is provided.
|
||||
.sp
|
||||
.TP 4
|
||||
.I display-name
|
||||
If the display-name is a back-end server, then core input events are
|
||||
taken from the server specified. Otherwise, a console window will be
|
||||
opened on the specified display.
|
||||
.sp
|
||||
If the
|
||||
.I display-name
|
||||
is followed by ",xi" then XInput extension devices on the display will
|
||||
be used as
|
||||
.I Xdmx
|
||||
XInput extension devices. If the
|
||||
.I display-name
|
||||
is followed by ",noxi" then XInput extension devices on the display will
|
||||
.B not
|
||||
be used as
|
||||
.I Xdmx
|
||||
XInput extension devices. Currently, the default is ",xi".
|
||||
.sp
|
||||
If the
|
||||
.I display-name
|
||||
is followed by ",console" and the
|
||||
.I display-name
|
||||
refers to a display that is used as a backend display, then a console
|
||||
window will be opened on that display
|
||||
.B and
|
||||
that display will be treated as a backend display. Otherwise (or if
|
||||
",noconsole" is used), the display will be treated purely as a backend
|
||||
or a console display, as described above.
|
||||
.sp
|
||||
If the
|
||||
.I display-name
|
||||
is followed by ",windows", then outlines of the windows on the backend
|
||||
will be displayed inside the console window. Otherwise (or if
|
||||
",nowindows" is used), the console window will not display the outlines
|
||||
of backend windows. (This option only applies to console input.)
|
||||
.sp
|
||||
If the
|
||||
.I display-name
|
||||
is followed by ",xkb", then the next 1 to 3 comma-separated parameters
|
||||
will specify the keycodes, symbols, and geometry of the keyboard for
|
||||
this input device. For example, ",xkb,xfree86,pc104" will specify that
|
||||
the "xfree86" keycodes and the "pc104" symbols should be used to
|
||||
initialize the keyboard. For an SGI keyboard, ",xkb,sgi/indy(pc102)"
|
||||
might be useful. A list of keycodes, symbols, and geometries can be
|
||||
found in
|
||||
.IR /usr/X11R6/lib/X11/xkb .
|
||||
If this option is not specified, the input device will be queried,
|
||||
perhaps using the XKEYBOARD extension.
|
||||
.RE
|
||||
.sp
|
||||
.RS
|
||||
If this option isn't specified, the default input source is the first
|
||||
back-end server (the one used for screen 0). The console window shows
|
||||
the layout of the back-end display(s) and pointer movements and key
|
||||
presses within the console window will be used as core input devices.
|
||||
.sp
|
||||
Several special function keys are active, depending on the input
|
||||
source:
|
||||
.sp
|
||||
.RS
|
||||
.B Ctrl-Alt-q
|
||||
will terminate the
|
||||
.I Xdmx
|
||||
server in all modes.
|
||||
.sp
|
||||
.B Ctrl-Alt-g
|
||||
will toggle a
|
||||
server grab in console mode (a special cursor, currently a spider, is
|
||||
used to indicate an active server grab).
|
||||
.sp
|
||||
.B Ctrl-Alt-f
|
||||
will toggle fine-grain motion in console mode (a special cursor,
|
||||
currently a cross hair, is used to indicate this mode). If this mode is
|
||||
combined with a server grab, then the cursor will have 4 lines instead
|
||||
of only 2.
|
||||
.sp
|
||||
.BR Ctrl-Alt-F1 " through " Ctrl-Alt-F12
|
||||
will switch to another VC in local (raw) mode.
|
||||
.RE
|
||||
.RE
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-shadowfb"
|
||||
This option turns on (legacy) support for the shadow frame buffer.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-noshadowfb"
|
||||
This option turns off (legacy) support for the shadow frame buffer.
|
||||
Note that this option has been deprecated and will be removed in the
|
||||
next release.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-nomulticursor"
|
||||
This option turns off support for displaying multiple cursors on
|
||||
overlapped back-end displays. This option is available for testing and
|
||||
benchmarking purposes.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-fontpath"
|
||||
This option sets the
|
||||
.I Xdmx
|
||||
server's default font path. This option can be specified multiple times
|
||||
to accommodate multiple font paths. See the
|
||||
.B "FONT PATHS"
|
||||
section below for very important information regarding setting the
|
||||
default font path.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-configfile " filename
|
||||
Specify the configuration file that should be read. Note that if the
|
||||
.B \-display
|
||||
command-line option is used, then the configuration file will be
|
||||
ignored.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-config " name
|
||||
Specify a configuration to use. The
|
||||
.I name
|
||||
will be the name following the
|
||||
.B virtual
|
||||
keyword in the configuration file.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-stat " "interval screens"
|
||||
This option enables the display of performance statistics. The interval
|
||||
is in seconds. The screens is a count of the number of back-end screens
|
||||
for which data is printed each interval. Specifying 0 for screens will
|
||||
display data for all screens.
|
||||
.sp
|
||||
For each screen, the following information is printed: the screen
|
||||
number, an absolute count of the number of XSync() calls made
|
||||
(SyncCount), the rate of these calls during the previous interval
|
||||
(Sync/s), the average round-trip time (in microseconds) of the last 10
|
||||
XSync() calls (avSync), the maximum round-trip time (in microseconds) of
|
||||
the last 10 XSync calls (mxSync), the average number of XSync() requests
|
||||
that were pending but not yet processed for each of the last 10
|
||||
processed XSync() calls, the maximum number of XSync() requests that
|
||||
were pending but not yet processed for each of the last 10 processed
|
||||
XSync() calls, and a histogram showing the distribution of the times of
|
||||
all of the XSync() calls that were made during the previous interval.
|
||||
.sp
|
||||
(The length of the moving average and the number and value of histogram
|
||||
bins are configurable at compile time in the
|
||||
.B dmxstat.h
|
||||
header file.)
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-syncbatch " interval
|
||||
This option sets the
|
||||
.I interval
|
||||
in milliseconds for XSync() batching. An
|
||||
.I interval
|
||||
less than or equal to 0 will disable XSync() batching. The default
|
||||
.I interval
|
||||
is 100 ms.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-nooffscreenopt"
|
||||
This option disables the offscreen optimization. Since the lazy window
|
||||
creation optimization requires the offscreen optimization to be enabled,
|
||||
this option will also disable the lazy window creation optimization.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-nowindowopt"
|
||||
This option disables the lazy window creation optimization.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-nosubdivprims"
|
||||
This option disables the primitive subdivision optimization.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-noxkb"
|
||||
Disable use of the XKB extension for communication with the back end
|
||||
displays. (Combine with
|
||||
.B "-kb"
|
||||
to disable all use of XKB.)
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-depth " int
|
||||
This option sets the root window's default depth. When choosing a
|
||||
default visual from those available on the back-end X server, the first
|
||||
visual with that matches the depth specified is used.
|
||||
.sp
|
||||
This option can be combined with the
|
||||
.BI "-cc"
|
||||
option, which specifies the default color visual class, to force the use
|
||||
of a specific depth and color class for the root window.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-norender"
|
||||
This option disables the RENDER extension.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-noglxproxy"
|
||||
This option disables GLX proxy -- the build-in GLX extension
|
||||
implementation that is DMX aware.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-noglxswapgroup"
|
||||
This option disables the swap group and swap barrier extensions in GLX
|
||||
proxy.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-glxsyncswap"
|
||||
This option enables synchronization after a swap buffers call by waiting
|
||||
until all X protocol has been processed. When a client issues a
|
||||
glXSwapBuffers request, Xdmx relays that request to each back-end X
|
||||
server, and those requests are buffered along with all other protocol
|
||||
requests. However, in systems that have large network buffers, this
|
||||
buffering can lead to the set of back-end X servers handling the swap
|
||||
buffers request asynchronously. With this option, an XSync() request is
|
||||
issued to each back-end X server after sending the swap buffers request.
|
||||
The XSync() requests will flush all buffered protocol (including the
|
||||
swap buffers requests) and wait until the back-end X servers have
|
||||
processed those requests before continuing. This option does not wait
|
||||
until all GL commands have been processed so there might be previously
|
||||
issued commands that are still being processed in the GL pipe when the
|
||||
XSync() request returns. See the
|
||||
.BI "-glxfinishswap"
|
||||
option below if Xdmx should wait until the GL commands have been
|
||||
processed.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-glxfinishswap"
|
||||
This option enables synchronization after a swap buffers call by waiting
|
||||
until all GL commands have been completed. It is similar to the
|
||||
.BI "-glxsyncswap"
|
||||
option above; however, instead of issuing an XSync(), it issues a
|
||||
glFinish() request to each back-end X server after sending the swap
|
||||
buffers requests. The glFinish() request will flush all buffered
|
||||
protocol requests, process both X and GL requests, and wait until all
|
||||
previously called GL commands are complete before returning.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-ignorebadfontpaths"
|
||||
This option ignores font paths that are not available on all back-end
|
||||
servers by removing the bad font path(s) from the default font path
|
||||
list. If no valid font paths are left after removing the bad paths, an
|
||||
error to that effect is printed in the log.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-addremovescreens"
|
||||
This option enables the dynamic addition and removal of screens, which
|
||||
is disabled by default. Note that GLXProxy and Render do not yet
|
||||
support dynamic addition and removal of screens, and must be disabled
|
||||
via the
|
||||
.BI "-noglxproxy"
|
||||
and
|
||||
.BI "-norender"
|
||||
command line options described above.
|
||||
.sp
|
||||
.TP 8
|
||||
.BI "-param"
|
||||
This option specifies parameters on the command line. Currently, only
|
||||
parameters dealing with XKEYBOARD configuration are supported. These
|
||||
parameters apply only to the core keyboard. Parameter values are
|
||||
installation-dependent. Please see
|
||||
.I /usr/X11R6/lib/X11/xkb
|
||||
or a similar directory for complete information.
|
||||
.RS
|
||||
.TP 8
|
||||
.B XkbRules
|
||||
Defaults to "xfree86". Other values may include "sgi" and "sun".
|
||||
.sp
|
||||
.TP 8
|
||||
.B XkbModel
|
||||
Defaults to "pc101". When used with "xfree86" rules, other values may
|
||||
include "pc102", "pc104", "pc105", "microsoft", and many others. When
|
||||
used with "sun" rules, other values may include "type4" and "type5".
|
||||
.sp
|
||||
.TP 8
|
||||
.B XkbLayout
|
||||
Defaults to "us". Other country codes and "dvorak" are usually
|
||||
available.
|
||||
.sp
|
||||
.TP 8
|
||||
.B XkbVariant
|
||||
Defaults to "".
|
||||
.sp
|
||||
.TP 8
|
||||
.B XkbOptions
|
||||
Defaults to "".
|
||||
.RE
|
||||
.SH "CONFIGURATION FILE GRAMMAR"
|
||||
The following words and tokens are reserved:
|
||||
.RS
|
||||
.B virtual
|
||||
.B display
|
||||
.B wall
|
||||
.B option
|
||||
.B param
|
||||
.B {
|
||||
.B }
|
||||
.B ;
|
||||
.B #
|
||||
.RE
|
||||
.PP
|
||||
Comments start with a
|
||||
.B #
|
||||
mark and extend to the end of the line. They may appear anywhere. If a
|
||||
configuration file is read into
|
||||
.BR xdmxconfig ,
|
||||
the comments in that file will be preserved, but will not be editable.
|
||||
.PP
|
||||
The grammar is as follows:
|
||||
.RS
|
||||
virtual-list ::= [ virtual-list ] | virtual
|
||||
|
||||
virtual ::=
|
||||
.B virtual
|
||||
[ name ] [ dim ]
|
||||
.B {
|
||||
dw-list
|
||||
.B }
|
||||
|
||||
dw-list ::= [ dw-list ] | dw
|
||||
|
||||
dw ::= display | wall | option
|
||||
|
||||
display ::=
|
||||
.B display
|
||||
name [ geometry ] [ / geometry ] [ origin ]
|
||||
.B ;
|
||||
|
||||
wall ::=
|
||||
.B wall
|
||||
[ dim ] [ dim ] name-list
|
||||
.B ;
|
||||
|
||||
option ::=
|
||||
.B option
|
||||
name-list
|
||||
.B ;
|
||||
|
||||
param ::=
|
||||
.B param
|
||||
name-list
|
||||
.B ;
|
||||
|
||||
param ::=
|
||||
.B param {
|
||||
param-list
|
||||
.B }
|
||||
|
||||
param-list ::= [ param-list ] | name-list
|
||||
.B ;
|
||||
|
||||
name-list ::= [ name-list ] | name
|
||||
|
||||
name ::= string | double-quoted-string
|
||||
|
||||
dim ::= integer
|
||||
.B x
|
||||
integer
|
||||
|
||||
geometry ::= [ integer
|
||||
.B x
|
||||
integer ] [ signed-integer signed-integer ]
|
||||
|
||||
origin ::=
|
||||
.B @
|
||||
integer
|
||||
.B x
|
||||
integer
|
||||
.RE
|
||||
.PP
|
||||
The name following
|
||||
.B virtual
|
||||
is used as an identifier for the configuration, and may be passed to
|
||||
.B Xdmx
|
||||
using the
|
||||
.B \-config
|
||||
command line option. The name of a display should be standard X display
|
||||
name, although no checking is performed (e.g., "machine:0").
|
||||
.PP
|
||||
For names, double quotes are optional unless the name is reserved or
|
||||
contains spaces.
|
||||
.PP
|
||||
The first dimension following
|
||||
.B wall
|
||||
is the dimension for tiling (e.g., 2x4 or 4x4). The second dimension
|
||||
following
|
||||
.B wall
|
||||
is the dimension of each display in the wall (e.g., 1280x1024).
|
||||
.PP
|
||||
The first geometry following
|
||||
.B display
|
||||
is the geometry of the screen window on the backend server. The second
|
||||
geometry, which is always preceeded by a slash, is the geometry of the
|
||||
root window. By default, the root window has the same geometry as the
|
||||
screen window.
|
||||
.PP
|
||||
The
|
||||
.B option
|
||||
line can be used to specify any command-line options (e.g.,
|
||||
.BR \-input ).
|
||||
(It cannot be used to specify the name of the front-end display.) The
|
||||
option line is processed once at server startup, just line command line
|
||||
options. This behavior may be unexpected.
|
||||
.SH "CONFIGURATION FILE EXAMPLES"
|
||||
Two displays being used for a desktop may be specified in any of the
|
||||
following formats:
|
||||
.RS
|
||||
.nf
|
||||
virtual example0 {
|
||||
display d0:0 1280x1024 @0x0;
|
||||
display d1:0 1280x1024 @1280x0;
|
||||
}
|
||||
.sp
|
||||
virtual example1 {
|
||||
display d0:0 1280x1024;
|
||||
display d1:0 @1280x0;
|
||||
}
|
||||
.sp
|
||||
virtual example2 {
|
||||
display "d0:0";
|
||||
display "d1:0" @1280x0;
|
||||
}
|
||||
.sp
|
||||
virtual example3 { wall 2x1 d0:0 d1:0; }
|
||||
.fi
|
||||
.RE
|
||||
A 4x4 wall of 16 total displays could be specified as follows (if no
|
||||
tiling dimension is specified, an approximate square is used):
|
||||
.RS
|
||||
.nf
|
||||
virtual example4 {
|
||||
wall d0:0 d1:0 d2:0 d3:0
|
||||
d4:0 d5:0 d6:0 d7:0
|
||||
d8:0 d9:0 da:0 db:0
|
||||
dc:0 dd:0 de:0 df:0;
|
||||
}
|
||||
.fi
|
||||
.RE
|
||||
.SH "FONT PATHS"
|
||||
The font path used by the
|
||||
.I Xdmx
|
||||
front-end server will be propagated to each back-end server,which
|
||||
requires that each back-end server have access to the exact same font
|
||||
paths as the front-end server. This can be most easily handled by
|
||||
either using a font server (e.g., xfs) or by remotely mounting the font
|
||||
paths on each back-end server, and then setting the
|
||||
.I Xdmx
|
||||
server's default font path with the
|
||||
-I "-fontpath"
|
||||
command line option described above.
|
||||
.PP
|
||||
For example, if you specify a font path with the following command line:
|
||||
.RS
|
||||
Xdmx :1 -display d0:0 -fontpath /usr/fonts/75dpi/ -fontpath /usr/fonts/Type1/ +xinerama
|
||||
.RE
|
||||
Then, /usr/fonts/75dpi/ and /usr/fonts/Type1/ must be valid font paths
|
||||
on the
|
||||
.I Xdmx
|
||||
server and all back-end server, which is d0 in this example.
|
||||
.PP
|
||||
Font servers can also be specified with the
|
||||
.I "-fontpath"
|
||||
option. For example, let's assume that a properly configured font
|
||||
server is running on host d0. Then, the following command line
|
||||
.RS
|
||||
Xdmx :1 -display d0:0 -display d1:0 -fontpath tcp/d0:7100 +xinerama
|
||||
.RE
|
||||
will initialize the front-end
|
||||
.I Xdmx
|
||||
server and each of the back-end servers to use the font server on d0.
|
||||
.PP
|
||||
Some fonts might not be supported by either the front-end or the
|
||||
back-end servers. For example, let's assume the front-end
|
||||
.I Xdmx
|
||||
server includes support Type1 fonts, but one of the back-end servers
|
||||
does not. Let's also assume that the default font path for
|
||||
.I Xdmx
|
||||
includes Type1 fonts in its font path. Then, when
|
||||
.I Xdmx
|
||||
initializes the default font path to load the default font, the font
|
||||
path that includes Type1 fonts (along with the other default font paths
|
||||
that are used by the
|
||||
.I Xdmx
|
||||
server) is sent to the back-end server that cannot handle Type1 fonts.
|
||||
That back-end server then rejects the font path and sends an error back
|
||||
to the
|
||||
.I Xdmx
|
||||
server.
|
||||
.I Xdmx
|
||||
then prints an error message and exits because it failed to set the
|
||||
default font path and was unable load the default font.
|
||||
.PP
|
||||
To fix this error, the offending font path must be removed from the
|
||||
default font path by using a different
|
||||
.I "-fontpath"
|
||||
command line option.
|
||||
.PP
|
||||
The
|
||||
.I "-fontpath"
|
||||
option can also be added to the configuration file as described above.
|
||||
.SH "COMMAND-LINE EXAMPLES"
|
||||
The back-end machines are d0 and d1, core input is from the pointer and
|
||||
keyboard attached to d0, clients will refer to :1 when opening windows:
|
||||
.RS
|
||||
Xdmx :1 -display d0:0 -display d1:0 +xinerama
|
||||
.RE
|
||||
.PP
|
||||
As above, except with core input from d1:
|
||||
.RS
|
||||
Xdmx :1 -display d0:0 -display d1:0 -input d1:0 +xinerama
|
||||
.RE
|
||||
.PP
|
||||
As above, except with core input from a console window on the local
|
||||
display:
|
||||
.RS
|
||||
Xdmx :1 -display d0:0 -display d1:0 -input :0 +xinerama
|
||||
.RE
|
||||
.PP
|
||||
As above, except with core input from the local keyboard and mouse:
|
||||
.RS
|
||||
Xdmx :1 -display d0:0 -display d1:0 -input local,kbd,ps2 +xinerama
|
||||
.RE
|
||||
Note that local input can be used under Linux while another X session is
|
||||
running on :0 (assuming the user can access the Linux console tty and
|
||||
mouse devices): a new (blank) VC will be used for keyboard input on the
|
||||
local machine and the Ctrl-Alt-F* sequence will be available to change
|
||||
to another VC (possibly back to another X session running on the local
|
||||
machine). Using Ctrl-Alt-Backspace on the blank VC will terminate the
|
||||
Xdmx session and return to the original VC.
|
||||
.PP
|
||||
This example uses the configuration file shown in the previous section:
|
||||
.RS
|
||||
Xdmx :1 -input :0 +xinerama -configfile filename -config example2
|
||||
.RE
|
||||
With this configuration file line:
|
||||
.RS
|
||||
option -input :0 +xinerama;
|
||||
.RE
|
||||
the command line can be shortened to:
|
||||
.RS
|
||||
Xdmx :1 -configfile filename -config example2
|
||||
.RE
|
||||
.SH "USING THE USB DEVICE DRIVERS"
|
||||
.P
|
||||
The USB device drivers use the devices called
|
||||
.IR /dev/input/event0 ", " /dev/input/event1 ", etc."
|
||||
under Linux. These devices are driven using the
|
||||
.I evdev
|
||||
Linux kernel module, which is part of the hid suite. Please note that
|
||||
if you load the
|
||||
.I mousedev
|
||||
or
|
||||
.I kbddev
|
||||
Linux kernel modules, then USB devices will appear as core Linux input
|
||||
devices and you will not be able to select between using the device only
|
||||
as an
|
||||
.I Xdmx
|
||||
core device or an
|
||||
.I Xdmx
|
||||
XInput extension device. Further, you may be unable to unload the
|
||||
.I mousedev
|
||||
Linux kernel module if
|
||||
.I XFree86
|
||||
is configured to use
|
||||
.I /dev/input/mice
|
||||
as an input device (this is quite helpful for laptop users and is set up
|
||||
by default under some Linux distributions, but should be changed if USB
|
||||
devices are to be used with
|
||||
.IR Xdmx ).
|
||||
.PP
|
||||
The USB device drivers search through the Linux devices for the first
|
||||
mouse, keyboard, or non-mouse-non-keyboard Linux device and use that
|
||||
device.
|
||||
.SH "KEYBOARD INITIALIZATION"
|
||||
.PP
|
||||
If
|
||||
.I Xdmx
|
||||
was invoked with
|
||||
.I \-xkb
|
||||
or was
|
||||
.B not
|
||||
compiled to use the XKEYBOARD extension, then a keyboard on a backend or
|
||||
console will be initialized using the map that the host X server
|
||||
provides.
|
||||
.PP
|
||||
If the XKEYBOARD extension is used for both
|
||||
.I Xdmx
|
||||
and the host X server for the keyboard (i.e., the backend or console X
|
||||
server), then the type of the keyboard will
|
||||
be obtained from the host X server and the keyboard under
|
||||
.I Xdmx
|
||||
will be initialized with that information. Otherwise, the default type
|
||||
of keyboard will be initialized. In both cases, the map from the host X
|
||||
server will
|
||||
.B not
|
||||
be used. This means that different initial behavior may be noted with
|
||||
and without XKEYBOARD. Consistent and expected results will be obtained
|
||||
by running XKEYBOARD on all servers and by avoiding the use of
|
||||
.I xmodmap
|
||||
on the backend or console X servers prior to starting
|
||||
.IR Xdmx .
|
||||
.PP
|
||||
If
|
||||
.I \-xkbmap
|
||||
is specified on the
|
||||
.I Xdmx
|
||||
command line, then that map will currently be used for all keyboards.
|
||||
.SH "MULTIPLE CORE KEYBOARDS"
|
||||
X was not designed to support multiple core keyboards. However,
|
||||
.I Xdmx
|
||||
provides some support for multiple core keyboards. Best results will be
|
||||
obtained if all of the keyboards are of the same type and are using the
|
||||
same keyboard map. Because the X server passes raw key code information
|
||||
to the X client, key symbols for keyboards with different key maps would
|
||||
be different if the key code for each keyboard was sent without
|
||||
translation to the client. Therefore,
|
||||
.I Xdmx
|
||||
will attempt to translate the key code from a core keyboard to the key
|
||||
code for the key with the same key symbol of the
|
||||
.B first
|
||||
core keyboard that was loaded. If the key symbol appears in both maps,
|
||||
the results will be expected. Otherwise, the second core keyboard will
|
||||
return a NoSymbol key symbol for some keys that would have been
|
||||
translated if it was the first core keyboard.
|
||||
.ig
|
||||
.SH ENVIRONMENT
|
||||
..
|
||||
.ig
|
||||
.SH FILES
|
||||
..
|
||||
.SH "SEE ALSO"
|
||||
.BR DMX "(3X), " X "(__miscmansuffix__), " Xserver "(1), " xdmxconfig "(1), "
|
||||
.BR vdltodmx "(1), " xfs "(1), " xkbcomp (1)
|
||||
.SH AUTHORS
|
||||
Kevin E. Martin
|
||||
.I <kem@redhat.com>,
|
||||
David H. Dawes
|
||||
.I <dawes@xfree86.org>,
|
||||
and
|
||||
Rickard E. (Rik) Faith
|
||||
.IR <faith@redhat.com> .
|
||||
.PP
|
||||
Portions of
|
||||
.I Xdmx
|
||||
are based on code from The XFree86 Project
|
||||
.RI ( http://www.xfree86.org )
|
||||
and X.Org
|
||||
.RI ( http://www.x.org ).
|
||||
160
hw/dmx/config/Canvas.c
Normal file
160
hw/dmx/config/Canvas.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 1987, 1998 The Open Group
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation.
|
||||
*
|
||||
* The above copyright notice and this permission notice 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* OPEN GROUP 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.
|
||||
*
|
||||
* Except as contained in this notice, the name of The Open Group shall not be
|
||||
* used in advertising or otherwise to promote the sale, use or other dealings
|
||||
* in this Software without prior written authorization from The Open Group.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2002 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>
|
||||
*
|
||||
* This file was originally taken from xc/lib/Xaw/Template.c
|
||||
*/
|
||||
|
||||
#include <X11/IntrinsicP.h>
|
||||
#include <X11/StringDefs.h>
|
||||
#include "CanvasP.h"
|
||||
|
||||
static void CanvasInitialize(Widget request, Widget w,
|
||||
ArgList args, Cardinal *num_args)
|
||||
{
|
||||
}
|
||||
|
||||
static void CanvasExpose(Widget w, XEvent *event, Region region)
|
||||
{
|
||||
CanvasExposeDataRec data;
|
||||
|
||||
data.w = w;
|
||||
data.event = event;
|
||||
data.region = region;
|
||||
|
||||
if (!XtIsRealized(w)) return;
|
||||
XtCallCallbacks(w, XtNcanvasExposeCallback, (XtPointer)&data);
|
||||
}
|
||||
|
||||
static void CanvasResize(Widget w)
|
||||
{
|
||||
if (!XtIsRealized(w)) return;
|
||||
XtCallCallbacks(w, XtNcanvasResizeCallback, (XtPointer)w);
|
||||
}
|
||||
|
||||
static void CanvasAction(Widget w, XEvent *event,
|
||||
String *params, Cardinal *num_params)
|
||||
{
|
||||
XtCallCallbacks(w, XtNcallback, (XtPointer)event);
|
||||
}
|
||||
|
||||
#define offset(field) XtOffsetOf(CanvasRec, canvas.field)
|
||||
static XtResource resources[] = {
|
||||
{ XtNcallback, XtCCallback, XtRCallback,
|
||||
sizeof(XtCallbackList), offset(input_callback), XtRCallback, NULL },
|
||||
{ XtNcanvasExposeCallback, XtCcanvasExposeCallback, XtRCallback,
|
||||
sizeof(XtCallbackList), offset(expose_callback), XtRCallback, NULL },
|
||||
{ XtNcanvasResizeCallback, XtCcanvasResizeCallback, XtRCallback,
|
||||
sizeof(XtCallbackList), offset(resize_callback), XtRCallback, NULL },
|
||||
};
|
||||
#undef offset
|
||||
|
||||
static XtActionsRec actions[] =
|
||||
{
|
||||
{"canvas", CanvasAction},
|
||||
};
|
||||
|
||||
static char translations[] =
|
||||
"<Key>: canvas()\n\
|
||||
<Motion>: canvas()\n\
|
||||
<BtnDown>: canvas()\n\
|
||||
<BtnUp>: canvas()\n\
|
||||
"
|
||||
;
|
||||
|
||||
#define Superclass (&widgetClassRec)
|
||||
CanvasClassRec canvasClassRec = {
|
||||
/* core */
|
||||
{
|
||||
(WidgetClass)Superclass, /* superclass */
|
||||
"Canvas", /* class_name */
|
||||
sizeof(CanvasRec), /* widget_size */
|
||||
NULL, /* class_initialize */
|
||||
NULL, /* class_part_initialize */
|
||||
False, /* class_inited */
|
||||
CanvasInitialize, /* initialize */
|
||||
NULL, /* initialize_hook */
|
||||
XtInheritRealize, /* realize */
|
||||
actions, /* actions */
|
||||
XtNumber(actions), /* num_actions */
|
||||
resources, /* resources */
|
||||
XtNumber(resources), /* num_resources */
|
||||
NULLQUARK, /* xrm_class */
|
||||
True, /* compress_motion */
|
||||
True, /* compress_exposure */
|
||||
True, /* compress_enterleave */
|
||||
False, /* visible_interest */
|
||||
NULL, /* destroy */
|
||||
CanvasResize, /* resize */
|
||||
CanvasExpose, /* expose */
|
||||
NULL, /* set_values */
|
||||
NULL, /* set_values_hook */
|
||||
XtInheritSetValuesAlmost, /* set_values_almost */
|
||||
NULL, /* get_values_hook */
|
||||
NULL, /* accept_focus */
|
||||
XtVersion, /* version */
|
||||
NULL, /* callback_private */
|
||||
translations, /* tm_table */
|
||||
XtInheritQueryGeometry, /* query_geometry */
|
||||
XtInheritDisplayAccelerator, /* display_accelerator */
|
||||
NULL, /* extension */
|
||||
},
|
||||
/* canvas */
|
||||
{
|
||||
NULL, /* extension */
|
||||
}
|
||||
};
|
||||
|
||||
WidgetClass canvasWidgetClass = (WidgetClass)&canvasClassRec;
|
||||
56
hw/dmx/config/Canvas.h
Normal file
56
hw/dmx/config/Canvas.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
Copyright 2002 Red Hat Inc., Durham, North Carolina.
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
* This file was originally taken from xc/lib/Xaw/Template.h
|
||||
*/
|
||||
|
||||
#ifndef _Canvas_h
|
||||
#define _Canvas_h
|
||||
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
#define XtNcanvasExposeCallback "canvasExposeCallback"
|
||||
#define XtCcanvasExposeCallback "CanvasExposeCallback"
|
||||
#define XtNcanvasResizeCallback "canvasResizeCallback"
|
||||
#define XtCcanvasResizeCallback "CanvasResizeCallback"
|
||||
|
||||
typedef struct _CanvasClassRec *CanvasWidgetClass;
|
||||
typedef struct _CanvasRec *CanvasWidget;
|
||||
extern WidgetClass canvasWidgetClass;
|
||||
|
||||
typedef struct _CanvasExposeDataRec {
|
||||
Widget w;
|
||||
XEvent *event;
|
||||
Region region;
|
||||
} CanvasExposeDataRec, *CanvasExposeDataPtr;
|
||||
|
||||
#endif /* _Canvas_h */
|
||||
66
hw/dmx/config/CanvasP.h
Normal file
66
hw/dmx/config/CanvasP.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
Copyright 2002 Red Hat Inc., Durham, North Carolina.
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
* This file was originally taken from xc/lib/Xaw/TemplateP.h
|
||||
*/
|
||||
|
||||
#ifndef _CanvasP_h
|
||||
#define _CanvasP_h
|
||||
|
||||
#include "Canvas.h"
|
||||
|
||||
/* include superclass private header file */
|
||||
#include <X11/CoreP.h>
|
||||
|
||||
typedef struct {
|
||||
XtPointer extension;
|
||||
} CanvasClassPart;
|
||||
|
||||
typedef struct _CanvasClassRec {
|
||||
CoreClassPart core_class;
|
||||
CanvasClassPart canvas_class;
|
||||
} CanvasClassRec;
|
||||
|
||||
extern CanvasClassRec canvasClassRec;
|
||||
|
||||
typedef struct {
|
||||
XtCallbackList input_callback;
|
||||
XtCallbackList expose_callback;
|
||||
XtCallbackList resize_callback;
|
||||
} CanvasPart;
|
||||
|
||||
typedef struct _CanvasRec {
|
||||
CorePart core;
|
||||
CanvasPart canvas;
|
||||
} CanvasRec;
|
||||
|
||||
#endif /* _CanvasP_h */
|
||||
7
hw/dmx/config/TODO
Normal file
7
hw/dmx/config/TODO
Normal file
@@ -0,0 +1,7 @@
|
||||
Fri May 31 13:20:17 2002
|
||||
|
||||
1) Sanitize values from input boxes.
|
||||
|
||||
2) Add canvas colors to cavas widget resources or to command-line options.
|
||||
|
||||
3) Add ability to edit option line(s) and wall.
|
||||
233
hw/dmx/config/dmxcompat.c
Normal file
233
hw/dmx/config/dmxcompat.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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 provides some compatibility support for reading VDL files
|
||||
* that are used by xmovie
|
||||
* (http://www.llnl.gov/icc/sdd/img/xmovie/xmovie.shtml).
|
||||
*
|
||||
* This file is not used by the DMX server.
|
||||
*/
|
||||
|
||||
#include "dmxconfig.h"
|
||||
#include "dmxparse.h"
|
||||
#include "dmxcompat.h"
|
||||
#include "parser.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static int dmxVDLReadLine(FILE *str, char *buf, int len)
|
||||
{
|
||||
if (fgets(buf, len, str)) return strlen(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dmxVDLCount(const char *buf)
|
||||
{
|
||||
return strtol(buf, NULL, 10);
|
||||
}
|
||||
|
||||
static void dmxVDLVirtualEntry(const char *buf,
|
||||
char *name, int *len,
|
||||
int *x, int *y)
|
||||
{
|
||||
char *end;
|
||||
const char *s;
|
||||
char *d;
|
||||
int start;
|
||||
|
||||
*x = strtol(buf, &end, 10);
|
||||
*y = strtol(end, &end, 10);
|
||||
|
||||
for (s = end, d = name, start = 1; *s && *s != '['; ++s) {
|
||||
if (start && isspace(*s)) continue;
|
||||
*d++ = *s;
|
||||
start = 0;
|
||||
}
|
||||
*d = '\0';
|
||||
while (d > name && isspace(d[-1])) *--d = '\0'; /* remove trailing space */
|
||||
*len = strlen(name);
|
||||
}
|
||||
|
||||
static void dmxVDLDisplayEntry(const char *buf,
|
||||
char *name, int *len,
|
||||
int *x, int *y,
|
||||
int *xoff, int *yoff,
|
||||
int *xorig, int *yorig)
|
||||
{
|
||||
const char *pt;
|
||||
char *end;
|
||||
|
||||
pt = strchr(buf, ' ');
|
||||
strncpy(name, buf, pt-buf);
|
||||
name[pt-buf] = '\0';
|
||||
*len = strlen(name);
|
||||
|
||||
*x = strtol(pt, &end, 10);
|
||||
*y = strtol(end, &end, 10);
|
||||
*xorig = strtol(end, &end, 10);
|
||||
*yorig = strtol(end, &end, 10);
|
||||
*xoff = strtol(end, &end, 10);
|
||||
*yoff = strtol(end, NULL, 10);
|
||||
}
|
||||
|
||||
/** Read from the VDL format \a filename and return a newly allocated \a
|
||||
* DMXConfigEntryPtr */
|
||||
DMXConfigEntryPtr dmxVDLRead(const char *filename)
|
||||
{
|
||||
FILE *str;
|
||||
char buf[2048]; /* RATS: Use ok */
|
||||
char *pt;
|
||||
int lineno = 0;
|
||||
DMXConfigEntryPtr entry = NULL;
|
||||
DMXConfigVirtualPtr virtual = NULL;
|
||||
DMXConfigSubPtr sub = NULL;
|
||||
DMXConfigDisplayPtr display = NULL;
|
||||
DMXConfigFullDimPtr fdim = NULL;
|
||||
int vcount = 0;
|
||||
int dcount = 0;
|
||||
int icount = 0;
|
||||
int x, y, xoff, yoff, xorig, yorig;
|
||||
char name[2048]; /* RATS: Use ok */
|
||||
const char *tmp;
|
||||
int len;
|
||||
enum {
|
||||
simulateFlag,
|
||||
virtualCount,
|
||||
virtualEntry,
|
||||
displayCount,
|
||||
displayEntry,
|
||||
ignoreCount,
|
||||
ignoreEntry
|
||||
} state = simulateFlag;
|
||||
|
||||
if (!filename) str = stdin;
|
||||
else str = fopen(filename, "r");
|
||||
if (!str) return NULL;
|
||||
|
||||
while (dmxVDLReadLine(str, buf, sizeof(buf))) {
|
||||
DMXConfigCommentPtr comment = NULL;
|
||||
|
||||
++lineno;
|
||||
for (pt = buf; *pt; pt++)
|
||||
if (*pt == '\r' || *pt == '\n') {
|
||||
*pt = '\0';
|
||||
break;
|
||||
}
|
||||
if (buf[0] == '#') {
|
||||
tmp = dmxConfigCopyString(buf + 1, strlen(buf + 1));
|
||||
comment = dmxConfigCreateComment(T_COMMENT, lineno, tmp);
|
||||
entry = dmxConfigAddEntry(entry, dmxConfigComment, comment, NULL);
|
||||
continue;
|
||||
}
|
||||
switch (state) {
|
||||
case simulateFlag:
|
||||
state = virtualCount;
|
||||
break;
|
||||
case virtualCount:
|
||||
vcount = dmxVDLCount(buf);
|
||||
state = virtualEntry;
|
||||
break;
|
||||
case virtualEntry:
|
||||
len = sizeof(name);
|
||||
dmxVDLVirtualEntry(buf, name, &len, &x, &y);
|
||||
tmp = dmxConfigCopyString(name, len);
|
||||
virtual = dmxConfigCreateVirtual(NULL,
|
||||
dmxConfigCreateString(T_STRING,
|
||||
lineno,
|
||||
NULL,
|
||||
tmp),
|
||||
dmxConfigCreatePair(T_DIMENSION,
|
||||
lineno,
|
||||
NULL,
|
||||
x, y, 0, 0),
|
||||
NULL, NULL, NULL);
|
||||
state = displayCount;
|
||||
break;
|
||||
case displayCount:
|
||||
dcount = dmxVDLCount(buf);
|
||||
state = displayEntry;
|
||||
break;
|
||||
case displayEntry:
|
||||
dmxVDLDisplayEntry(buf, name, &len, &x, &y, &xoff, &yoff,
|
||||
&xorig, &yorig);
|
||||
tmp = dmxConfigCopyString(name, len);
|
||||
fdim = dmxConfigCreateFullDim(
|
||||
dmxConfigCreatePartDim(
|
||||
dmxConfigCreatePair(T_DIMENSION,
|
||||
lineno,
|
||||
NULL,
|
||||
x, y, 0, 0),
|
||||
dmxConfigCreatePair(T_OFFSET,
|
||||
lineno,
|
||||
NULL,
|
||||
xoff, yoff,
|
||||
xoff, yoff)),
|
||||
NULL);
|
||||
display = dmxConfigCreateDisplay(NULL,
|
||||
dmxConfigCreateString(T_STRING,
|
||||
lineno,
|
||||
NULL,
|
||||
tmp),
|
||||
fdim,
|
||||
dmxConfigCreatePair(T_ORIGIN,
|
||||
lineno,
|
||||
NULL,
|
||||
xorig, yorig,
|
||||
0, 0),
|
||||
NULL);
|
||||
sub = dmxConfigAddSub(sub, dmxConfigSubDisplay(display));
|
||||
if (!--dcount) {
|
||||
state = ignoreCount;
|
||||
virtual->subentry = sub;
|
||||
entry = dmxConfigAddEntry(entry,
|
||||
dmxConfigVirtual,
|
||||
NULL,
|
||||
virtual);
|
||||
virtual = NULL;
|
||||
sub = NULL;
|
||||
}
|
||||
break;
|
||||
case ignoreCount:
|
||||
icount = dmxVDLCount(buf);
|
||||
state = ignoreEntry;
|
||||
break;
|
||||
case ignoreEntry:
|
||||
if (!--icount) state = virtualEntry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
45
hw/dmx/config/dmxcompat.h
Normal file
45
hw/dmx/config/dmxcompat.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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
|
||||
* Interface to VDL compatibility support. \see dmxcompat.c
|
||||
*
|
||||
* This file is not used by the DMX server.
|
||||
*/
|
||||
|
||||
#ifndef _DMXCOMPAT_H_
|
||||
#define _DMXCOMPAT_H_
|
||||
|
||||
extern DMXConfigEntryPtr dmxVDLRead(const char *filename);
|
||||
#endif
|
||||
495
hw/dmx/config/dmxconfig.c
Normal file
495
hw/dmx/config/dmxconfig.c
Normal file
@@ -0,0 +1,495 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002-2003 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
|
||||
* Provides interface for reading DMX configuration files and for
|
||||
* combining that information with command-line configuration parameters. */
|
||||
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxinput.h"
|
||||
#include "dmxconfig.h"
|
||||
#include "dmxparse.h"
|
||||
#include "dmxlog.h"
|
||||
#include "dmxcb.h"
|
||||
#include "dmxstat.h"
|
||||
#include "parser.h"
|
||||
|
||||
extern int yyparse(void);
|
||||
extern FILE *yyin;
|
||||
|
||||
static char *dmxXkbRules;
|
||||
static char *dmxXkbModel;
|
||||
static char *dmxXkbLayout;
|
||||
static char *dmxXkbVariant;
|
||||
static char *dmxXkbOptions;
|
||||
|
||||
/** Stores lists of configuration information. */
|
||||
typedef struct DMXConfigListStruct {
|
||||
const char *name;
|
||||
struct DMXConfigListStruct *next;
|
||||
} DMXConfigList, *DMXConfigListPtr;
|
||||
|
||||
/** This stucture stores the parsed configuration information. */
|
||||
typedef struct DMXConfigCmdStruct {
|
||||
const char *filename;
|
||||
const char *config;
|
||||
DMXConfigList *displays;
|
||||
DMXConfigList *inputs;
|
||||
DMXConfigList *xinputs;
|
||||
} DMXConfigCmd, *DMXConfigCmdPtr;
|
||||
|
||||
DMXConfigEntryPtr dmxConfigEntry;
|
||||
static DMXConfigCmd dmxConfigCmd;
|
||||
|
||||
static int dmxDisplaysFromCommandLine;
|
||||
|
||||
/** Make a note that \a display is the name of an X11 display that
|
||||
* should be initialized as a backend (output) display. Called from
|
||||
* #ddxProcessArgument. */
|
||||
void dmxConfigStoreDisplay(const char *display)
|
||||
{
|
||||
DMXConfigListPtr entry = malloc(sizeof(*entry));
|
||||
entry->name = strdup(display);
|
||||
entry->next = NULL;
|
||||
if (!dmxConfigCmd.displays) dmxConfigCmd.displays = entry;
|
||||
else {
|
||||
DMXConfigList *pt;
|
||||
for (pt = dmxConfigCmd.displays; pt->next; pt = pt->next);
|
||||
if (!pt)
|
||||
dmxLog(dmxFatal, "dmxConfigStoreDisplay: end of list non-NULL\n");
|
||||
pt->next = entry;
|
||||
}
|
||||
++dmxDisplaysFromCommandLine;
|
||||
}
|
||||
|
||||
/** Make a note that \a input is the name of an X11 display that should
|
||||
* be used for input (either a backend or a console input device). */
|
||||
void dmxConfigStoreInput(const char *input)
|
||||
{
|
||||
DMXConfigListPtr entry = malloc(sizeof(*entry));
|
||||
entry->name = strdup(input);
|
||||
entry->next = NULL;
|
||||
if (!dmxConfigCmd.inputs) dmxConfigCmd.inputs = entry;
|
||||
else {
|
||||
DMXConfigList *pt;
|
||||
for (pt = dmxConfigCmd.inputs; pt->next; pt = pt->next);
|
||||
if (!pt)
|
||||
dmxLog(dmxFatal, "dmxConfigStoreInput: end of list non-NULL\n");
|
||||
pt->next = entry;
|
||||
}
|
||||
}
|
||||
|
||||
/** Make a note that \a input is the name of an X11 display that should
|
||||
* be used for input from XInput extension devices. */
|
||||
void dmxConfigStoreXInput(const char *input)
|
||||
{
|
||||
DMXConfigListPtr entry = malloc(sizeof(*entry));
|
||||
entry->name = strdup(input);
|
||||
entry->next = NULL;
|
||||
if (!dmxConfigCmd.xinputs) dmxConfigCmd.xinputs = entry;
|
||||
else {
|
||||
DMXConfigList *pt;
|
||||
for (pt = dmxConfigCmd.xinputs; pt->next; pt = pt->next);
|
||||
if (!pt)
|
||||
dmxLog(dmxFatal, "dmxConfigStoreXInput: end of list non-NULL\n");
|
||||
pt->next = entry;
|
||||
}
|
||||
}
|
||||
|
||||
/** Make a note that \a file is the configuration file. */
|
||||
void dmxConfigStoreFile(const char *file)
|
||||
{
|
||||
if (dmxConfigCmd.filename)
|
||||
dmxLog(dmxFatal, "Only one -configfile allowed\n");
|
||||
dmxConfigCmd.filename = strdup(file);
|
||||
}
|
||||
|
||||
/** Make a note that \a config should be used as the configuration for
|
||||
* current instantiation of the DMX server. */
|
||||
void dmxConfigStoreConfig(const char *config)
|
||||
{
|
||||
if (dmxConfigCmd.config) dmxLog(dmxFatal, "Only one -config allowed\n");
|
||||
dmxConfigCmd.config = strdup(config);
|
||||
}
|
||||
|
||||
static int dmxConfigReadFile(const char *filename, int debug)
|
||||
{
|
||||
FILE *str;
|
||||
|
||||
if (!(str = fopen(filename, "r"))) return -1;
|
||||
dmxLog(dmxInfo, "Reading configuration file \"%s\"\n", filename);
|
||||
yyin = str;
|
||||
yydebug = debug;
|
||||
yyparse();
|
||||
fclose(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *dmxConfigMatch(const char *target, DMXConfigEntryPtr entry)
|
||||
{
|
||||
DMXConfigVirtualPtr v = entry->virtual;
|
||||
const char *name = NULL;
|
||||
|
||||
if (v && v->name) name = v->name;
|
||||
|
||||
if (v && !dmxConfigCmd.config) return v->name ? v->name : "<noname>";
|
||||
if (!name) return NULL;
|
||||
if (!strcmp(name, target)) return name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DMXScreenInfo *dmxConfigAddDisplay(const char *name,
|
||||
int scrnWidth, int scrnHeight,
|
||||
int scrnX, int scrnY,
|
||||
int scrnXSign, int scrnYSign,
|
||||
int rootWidth, int rootHeight,
|
||||
int rootX, int rootY,
|
||||
int rootXSign, int rootYSign)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen;
|
||||
|
||||
if (!(dmxScreens = realloc(dmxScreens,
|
||||
(dmxNumScreens+1) * sizeof(*dmxScreens))))
|
||||
dmxLog(dmxFatal,
|
||||
"dmxConfigAddDisplay: realloc failed for screen %d (%s)\n",
|
||||
dmxNumScreens, name);
|
||||
|
||||
dmxScreen = &dmxScreens[dmxNumScreens];
|
||||
memset(dmxScreen, 0, sizeof(*dmxScreen));
|
||||
dmxScreen->name = name;
|
||||
dmxScreen->index = dmxNumScreens;
|
||||
dmxScreen->scrnWidth = scrnWidth;
|
||||
dmxScreen->scrnHeight = scrnHeight;
|
||||
dmxScreen->scrnX = scrnX;
|
||||
dmxScreen->scrnY = scrnY;
|
||||
dmxScreen->scrnXSign = scrnXSign;
|
||||
dmxScreen->scrnYSign = scrnYSign;
|
||||
dmxScreen->rootWidth = rootWidth;
|
||||
dmxScreen->rootHeight = rootHeight;
|
||||
dmxScreen->rootX = rootX;
|
||||
dmxScreen->rootY = rootY;
|
||||
dmxScreen->stat = dmxStatAlloc();
|
||||
++dmxNumScreens;
|
||||
return dmxScreen;
|
||||
}
|
||||
|
||||
DMXInputInfo *dmxConfigAddInput(const char *name, int core)
|
||||
{
|
||||
DMXInputInfo *dmxInput;
|
||||
|
||||
if (!(dmxInputs = realloc(dmxInputs,
|
||||
(dmxNumInputs+1) * sizeof(*dmxInputs))))
|
||||
dmxLog(dmxFatal,
|
||||
"dmxConfigAddInput: realloc failed for input %d (%s)\n",
|
||||
dmxNumInputs, name);
|
||||
|
||||
dmxInput = &dmxInputs[dmxNumInputs];
|
||||
|
||||
memset(dmxInput, 0, sizeof(*dmxInput));
|
||||
dmxInput->name = name;
|
||||
dmxInput->inputIdx = dmxNumInputs;
|
||||
dmxInput->scrnIdx = -1;
|
||||
dmxInput->core = core;
|
||||
++dmxNumInputs;
|
||||
return dmxInput;
|
||||
}
|
||||
|
||||
static void dmxConfigCopyFromDisplay(DMXConfigDisplayPtr d)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen;
|
||||
|
||||
dmxScreen = dmxConfigAddDisplay(d->name,
|
||||
d->scrnWidth, d->scrnHeight,
|
||||
d->scrnX, d->scrnY,
|
||||
d->scrnXSign, d->scrnYSign,
|
||||
d->rootWidth, d->rootHeight,
|
||||
d->rootX, d->rootY,
|
||||
d->rootXSign, d->rootXSign);
|
||||
dmxScreen->where = PosAbsolute;
|
||||
dmxScreen->whereX = d->rootXOrigin;
|
||||
dmxScreen->whereY = d->rootYOrigin;
|
||||
}
|
||||
|
||||
static void dmxConfigCopyFromWall(DMXConfigWallPtr w)
|
||||
{
|
||||
DMXConfigStringPtr pt;
|
||||
DMXScreenInfo *dmxScreen;
|
||||
int edge = dmxNumScreens;
|
||||
int last = dmxNumScreens;
|
||||
|
||||
if (!w->xwall && !w->ywall) { /* Try to make it square */
|
||||
int count;
|
||||
for (pt = w->nameList, count = 0; pt; pt = pt->next) ++count;
|
||||
w->xwall = sqrt(count) + .5;
|
||||
}
|
||||
|
||||
for (pt = w->nameList; pt; pt = pt->next) {
|
||||
dmxScreen = dmxConfigAddDisplay(pt->string, w->width, w->height,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
if (pt == w->nameList) { /* Upper left */
|
||||
dmxScreen->where = PosAbsolute;
|
||||
dmxScreen->whereX = 0;
|
||||
dmxScreen->whereY = 0;
|
||||
} else if (w->xwall) { /* Tile left to right, then top to bottom */
|
||||
if (!((dmxNumScreens-1) % w->xwall)) {
|
||||
dmxScreen->where = PosBelow;
|
||||
dmxScreen->whereRefScreen = edge;
|
||||
edge = dmxNumScreens-1;
|
||||
} else {
|
||||
dmxScreen->where = PosRightOf;
|
||||
dmxScreen->whereRefScreen = last;
|
||||
}
|
||||
} else { /* Tile top to bottom, then left to right */
|
||||
if (!((dmxNumScreens-1) % w->ywall)) {
|
||||
dmxScreen->where = PosRightOf;
|
||||
dmxScreen->whereRefScreen = edge;
|
||||
edge = dmxNumScreens-1;
|
||||
} else {
|
||||
dmxScreen->where = PosBelow;
|
||||
dmxScreen->whereRefScreen = last;
|
||||
}
|
||||
|
||||
}
|
||||
last = dmxNumScreens-1;
|
||||
if (dmxScreen->where == PosAbsolute)
|
||||
dmxLog(dmxInfo, "Added %s at %d %d\n",
|
||||
pt->string, dmxScreen->whereX, dmxScreen->whereY);
|
||||
else
|
||||
dmxLog(dmxInfo, "Added %s %s %s\n",
|
||||
pt->string,
|
||||
dmxScreen->where == PosBelow ? "below" : "right of",
|
||||
dmxScreens[dmxScreen->whereRefScreen].name);
|
||||
}
|
||||
}
|
||||
|
||||
static void dmxConfigCopyFromOption(DMXConfigOptionPtr o)
|
||||
{
|
||||
DMXConfigStringPtr pt;
|
||||
int argc = 0;
|
||||
char **argv = NULL;
|
||||
|
||||
if (serverGeneration != 1) return; /* FIXME: only do once, for now */
|
||||
if (!o || !o->string) return;
|
||||
for (pt = o->option; pt; pt = pt->next) {
|
||||
if (pt->string) {
|
||||
++argc;
|
||||
argv = realloc(argv, (argc+1) * sizeof(*argv));
|
||||
argv[argc] = (char *)pt->string;
|
||||
}
|
||||
}
|
||||
argv[0] = NULL;
|
||||
ProcessCommandLine(argc+1, argv);
|
||||
free(argv);
|
||||
}
|
||||
|
||||
static void dmxConfigCopyFromParam(DMXConfigParamPtr p)
|
||||
{
|
||||
const char **argv;
|
||||
int argc;
|
||||
|
||||
if ((argv = dmxConfigLookupParam(p, "xkbrules", &argc)) && argc == 2) {
|
||||
dmxConfigSetXkbRules(argv[1]);
|
||||
} else if ((argv = dmxConfigLookupParam(p, "xkbmodel", &argc))
|
||||
&& argc == 2) {
|
||||
dmxConfigSetXkbModel(argv[1]);
|
||||
} else if ((argv = dmxConfigLookupParam(p, "xkblayout", &argc))
|
||||
&& argc == 2) {
|
||||
dmxConfigSetXkbLayout(argv[1]);
|
||||
} else if ((argv = dmxConfigLookupParam(p, "xkbvariant", &argc))
|
||||
&& argc == 2) {
|
||||
dmxConfigSetXkbVariant(argv[1]);
|
||||
} else if ((argv = dmxConfigLookupParam(p, "xkboptions", &argc))
|
||||
&& argc == 2) {
|
||||
dmxConfigSetXkbOptions(argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void dmxConfigCopyData(DMXConfigVirtualPtr v)
|
||||
{
|
||||
DMXConfigSubPtr sub;
|
||||
|
||||
if (v->dim) dmxSetWidthHeight(v->dim->x, v->dim->y);
|
||||
else dmxSetWidthHeight(0, 0);
|
||||
for (sub = v->subentry; sub; sub = sub->next) {
|
||||
switch (sub->type) {
|
||||
case dmxConfigDisplay: dmxConfigCopyFromDisplay(sub->display); break;
|
||||
case dmxConfigWall: dmxConfigCopyFromWall(sub->wall); break;
|
||||
case dmxConfigOption: dmxConfigCopyFromOption(sub->option); break;
|
||||
case dmxConfigParam: dmxConfigCopyFromParam(sub->param); break;
|
||||
default:
|
||||
dmxLog(dmxFatal,
|
||||
"dmxConfigCopyData: not a display, wall, or value\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dmxConfigFromCommandLine(void)
|
||||
{
|
||||
DMXConfigListPtr pt;
|
||||
|
||||
dmxLog(dmxInfo, "Using configuration from command line\n");
|
||||
for (pt = dmxConfigCmd.displays; pt; pt = pt->next) {
|
||||
DMXScreenInfo *dmxScreen = dmxConfigAddDisplay(pt->name,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0);
|
||||
if (dmxNumScreens == 1) {
|
||||
dmxScreen->where = PosAbsolute;
|
||||
dmxScreen->whereX = 0;
|
||||
dmxScreen->whereY = 0;
|
||||
dmxLog(dmxInfo, "Added %s at %d %d\n",
|
||||
dmxScreen->name, dmxScreen->whereX, dmxScreen->whereY);
|
||||
} else {
|
||||
dmxScreen->where = PosRightOf;
|
||||
dmxScreen->whereRefScreen = dmxNumScreens - 2;
|
||||
if (dmxScreen->whereRefScreen < 0) dmxScreen->whereRefScreen = 0;
|
||||
dmxLog(dmxInfo, "Added %s %s %s\n",
|
||||
dmxScreen->name,
|
||||
dmxScreen->where == PosBelow ? "below" : "right of",
|
||||
dmxScreens[dmxScreen->whereRefScreen].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dmxConfigFromConfigFile(void)
|
||||
{
|
||||
DMXConfigEntryPtr pt;
|
||||
const char *name;
|
||||
|
||||
for (pt = dmxConfigEntry; pt; pt = pt->next) {
|
||||
/* FIXME -- if an input is specified, use it */
|
||||
if (pt->type != dmxConfigVirtual) continue;
|
||||
if ((name = dmxConfigMatch(dmxConfigCmd.config, pt))) {
|
||||
dmxLog(dmxInfo, "Using configuration \"%s\"\n", name);
|
||||
dmxConfigCopyData(pt->virtual);
|
||||
return;
|
||||
}
|
||||
}
|
||||
dmxLog(dmxFatal, "Could not find configuration \"%s\" in \"%s\"\n",
|
||||
dmxConfigCmd.config, dmxConfigCmd.filename);
|
||||
}
|
||||
|
||||
static void dmxConfigConfigInputs(void)
|
||||
{
|
||||
DMXConfigListPtr pt;
|
||||
|
||||
if (dmxNumInputs) return;
|
||||
|
||||
if (dmxConfigCmd.inputs) { /* Use command line */
|
||||
for (pt = dmxConfigCmd.inputs; pt; pt = pt->next)
|
||||
dmxConfigAddInput(pt->name, TRUE);
|
||||
} else if (dmxNumScreens) { /* Use first display */
|
||||
dmxConfigAddInput(dmxScreens[0].name, TRUE);
|
||||
} else { /* Use dummy */
|
||||
dmxConfigAddInput("dummy", TRUE);
|
||||
}
|
||||
|
||||
if (dmxConfigCmd.xinputs) { /* Non-core devices from command line */
|
||||
for (pt = dmxConfigCmd.xinputs; pt; pt = pt->next)
|
||||
dmxConfigAddInput(pt->name, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/** Set up the appropriate global variables so that the DMX server will
|
||||
* be initialized using the configuration specified in the config file
|
||||
* and on the command line. */
|
||||
void dmxConfigConfigure(void)
|
||||
{
|
||||
if (dmxConfigEntry) {
|
||||
dmxConfigFreeEntry(dmxConfigEntry);
|
||||
dmxConfigEntry = NULL;
|
||||
}
|
||||
if (dmxConfigCmd.filename) {
|
||||
if (dmxConfigCmd.displays)
|
||||
dmxLog(dmxWarning,
|
||||
"Using configuration file \"%s\" instead of command line\n",
|
||||
dmxConfigCmd.filename);
|
||||
dmxConfigReadFile(dmxConfigCmd.filename, 0);
|
||||
dmxConfigFromConfigFile();
|
||||
} else {
|
||||
if (dmxConfigCmd.config)
|
||||
dmxLog(dmxWarning,
|
||||
"Configuration name (%s) without configuration file\n",
|
||||
dmxConfigCmd.config);
|
||||
dmxConfigFromCommandLine();
|
||||
}
|
||||
dmxConfigConfigInputs();
|
||||
}
|
||||
|
||||
/** This function determines the number of displays we WILL have and
|
||||
* sets MAXSCREENS to that value. This is difficult since the number
|
||||
* depends on the command line (which is easy to count) or on the config
|
||||
* file, which has to be parsed. */
|
||||
void dmxConfigSetMaxScreens(void)
|
||||
{
|
||||
static int processing = 0;
|
||||
|
||||
if (processing) return; /* Prevent reentry via ProcessCommandLine */
|
||||
processing = 1;
|
||||
if (dmxConfigCmd.filename) {
|
||||
if (!dmxNumScreens)
|
||||
dmxConfigConfigure();
|
||||
#ifndef MAXSCREENS
|
||||
SetMaxScreens(dmxNumScreens);
|
||||
#endif
|
||||
} else
|
||||
#ifndef MAXSCREENS
|
||||
SetMaxScreens(dmxDisplaysFromCommandLine);
|
||||
#endif
|
||||
processing = 0;
|
||||
}
|
||||
|
||||
/** This macro is used to generate the following access methods:
|
||||
* - dmxConfig{Set,Get}rules
|
||||
* - dmxConfig{Set,Get}model
|
||||
* - dmxConfig{Set,Get}layout
|
||||
* - dmxConfig{Set,Get}variant
|
||||
* - dmxConfig{Set,Get}options
|
||||
* These methods are used to read and write information about the keyboard. */
|
||||
|
||||
#define GEN(param,glob,def) \
|
||||
void dmxConfigSet##glob(const char *param) { \
|
||||
if (dmx##glob) free((void *)dmx##glob); \
|
||||
dmx##glob = strdup(param); \
|
||||
} \
|
||||
char *dmxConfigGet##glob(void) { \
|
||||
return (char *)(dmx##glob ? dmx##glob : def); \
|
||||
}
|
||||
|
||||
GEN(rules, XkbRules, DMX_DEFAULT_XKB_RULES)
|
||||
GEN(model, XkbModel, DMX_DEFAULT_XKB_MODEL)
|
||||
GEN(layout, XkbLayout, DMX_DEFAULT_XKB_LAYOUT)
|
||||
GEN(variant, XkbVariant, DMX_DEFAULT_XKB_VARIANT)
|
||||
GEN(options, XkbOptions, DMX_DEFAULT_XKB_OPTIONS)
|
||||
|
||||
65
hw/dmx/config/dmxconfig.h
Normal file
65
hw/dmx/config/dmxconfig.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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
|
||||
* Interface for DMX configuration file support. \see dmxconfig.c */
|
||||
|
||||
#ifndef _DMXCONFIG_H_
|
||||
#define _DMXCONFIG_H_
|
||||
#define DMX_DEFAULT_XKB_RULES "xfree86"
|
||||
#define DMX_DEFAULT_XKB_MODEL "pc101"
|
||||
#define DMX_DEFAULT_XKB_LAYOUT "us"
|
||||
#define DMX_DEFAULT_XKB_VARIANT NULL
|
||||
#define DMX_DEFAULT_XKB_OPTIONS NULL
|
||||
|
||||
extern void dmxConfigStoreDisplay(const char *display);
|
||||
extern void dmxConfigStoreInput(const char *input); /* Core devices */
|
||||
extern void dmxConfigStoreXInput(const char *input); /* Non-core devices */
|
||||
extern void dmxConfigStoreFile(const char *file);
|
||||
extern void dmxConfigStoreConfig(const char *config);
|
||||
extern void dmxConfigConfigure(void);
|
||||
extern void dmxConfigSetMaxScreens(void);
|
||||
|
||||
extern void dmxConfigSetXkbRules(const char *rules);
|
||||
extern void dmxConfigSetXkbModel(const char *model);
|
||||
extern void dmxConfigSetXkbLayout(const char *layout);
|
||||
extern void dmxConfigSetXkbVariant(const char *variant);
|
||||
extern void dmxConfigSetXkbOptions(const char *options);
|
||||
|
||||
extern char *dmxConfigGetXkbRules(void);
|
||||
extern char *dmxConfigGetXkbModel(void);
|
||||
extern char *dmxConfigGetXkbLayout(void);
|
||||
extern char *dmxConfigGetXkbVariant(void);
|
||||
extern char *dmxConfigGetXkbOptions(void);
|
||||
#endif
|
||||
607
hw/dmx/config/dmxparse.c
Normal file
607
hw/dmx/config/dmxparse.c
Normal file
@@ -0,0 +1,607 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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 provides support routines and helper functions to be used
|
||||
* by the DMX configuration file parser.
|
||||
*
|
||||
* Because the DMX configuration file parsing should be capable of being
|
||||
* used in a stand-alone fashion (i.e., independent from the DMX server
|
||||
* source tree), no dependencies on other DMX routines are made. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "dmxparse.h"
|
||||
|
||||
/** A general error logging routine that does not depend on the dmxLog
|
||||
* functions. */
|
||||
void dmxConfigLog(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vprintf(format, args); /* RATS: All calls to dmxConfigLog from
|
||||
* dmxparse.c and dmxprint.c use a
|
||||
* trusted format. */
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void *dmxConfigAlloc(unsigned long bytes)
|
||||
{
|
||||
void *area = malloc(bytes);
|
||||
if (!area) {
|
||||
dmxConfigLog("dmxConfigAlloc: out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
memset(area, 0, bytes);
|
||||
return area;
|
||||
}
|
||||
|
||||
void *dmxConfigRealloc(void *orig, unsigned long orig_bytes,
|
||||
unsigned long bytes)
|
||||
{
|
||||
unsigned char *area = realloc(orig, bytes);
|
||||
if (!area) {
|
||||
dmxConfigLog("dmxConfigRealloc: out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
memset(area + orig_bytes, 0, bytes - orig_bytes);
|
||||
return area;
|
||||
}
|
||||
|
||||
const char *dmxConfigCopyString(const char *string, int length)
|
||||
{
|
||||
char *copy;
|
||||
|
||||
if (!length) length = strlen(string);
|
||||
copy = dmxConfigAlloc(length + 1);
|
||||
if (length) strncpy(copy, string, length);
|
||||
copy[length] = '\0';
|
||||
return copy;
|
||||
}
|
||||
|
||||
void dmxConfigFree(void *area)
|
||||
{
|
||||
if (area) free(area);
|
||||
}
|
||||
|
||||
DMXConfigTokenPtr dmxConfigCreateToken(int token, int line,
|
||||
const char *comment)
|
||||
{
|
||||
DMXConfigTokenPtr pToken = dmxConfigAlloc(sizeof(*pToken));
|
||||
pToken->token = token;
|
||||
pToken->line = line;
|
||||
pToken->comment = comment;
|
||||
return pToken;
|
||||
}
|
||||
|
||||
void dmxConfigFreeToken(DMXConfigTokenPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
dmxConfigFree((void *)p->comment);
|
||||
dmxConfigFree(p);
|
||||
}
|
||||
|
||||
DMXConfigStringPtr dmxConfigCreateString(int token, int line,
|
||||
const char *comment,
|
||||
const char *string)
|
||||
{
|
||||
DMXConfigStringPtr pString = dmxConfigAlloc(sizeof(*pString));
|
||||
|
||||
pString->token = token;
|
||||
pString->line = line;
|
||||
pString->comment = comment;
|
||||
pString->string = string;
|
||||
return pString;
|
||||
}
|
||||
|
||||
void dmxConfigFreeString(DMXConfigStringPtr p)
|
||||
{
|
||||
DMXConfigStringPtr next;
|
||||
|
||||
if (!p) return;
|
||||
do {
|
||||
next = p->next;
|
||||
dmxConfigFree((void *)p->comment);
|
||||
dmxConfigFree((void *)p->string);
|
||||
dmxConfigFree(p);
|
||||
} while ((p = next));
|
||||
}
|
||||
|
||||
DMXConfigNumberPtr dmxConfigCreateNumber(int token, int line,
|
||||
const char *comment,
|
||||
int number)
|
||||
{
|
||||
DMXConfigNumberPtr pNumber = dmxConfigAlloc(sizeof(*pNumber));
|
||||
|
||||
pNumber->token = token;
|
||||
pNumber->line = line;
|
||||
pNumber->comment = comment;
|
||||
pNumber->number = number;
|
||||
return pNumber;
|
||||
}
|
||||
|
||||
void dmxConfigFreeNumber(DMXConfigNumberPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
dmxConfigFree((void *)p->comment);
|
||||
dmxConfigFree(p);
|
||||
}
|
||||
|
||||
DMXConfigPairPtr dmxConfigCreatePair(int token, int line,
|
||||
const char *comment,
|
||||
int x, int y,
|
||||
int xsign, int ysign)
|
||||
{
|
||||
DMXConfigPairPtr pPair = dmxConfigAlloc(sizeof(*pPair));
|
||||
|
||||
pPair->token = token;
|
||||
pPair->line = line;
|
||||
pPair->comment = comment;
|
||||
pPair->x = x;
|
||||
pPair->y = y;
|
||||
pPair->xsign = (xsign < 0) ? -1 : 1;
|
||||
pPair->ysign = (ysign < 0) ? -1 : 1;
|
||||
return pPair;
|
||||
}
|
||||
|
||||
void dmxConfigFreePair(DMXConfigPairPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
dmxConfigFree((void *)p->comment);
|
||||
dmxConfigFree(p);
|
||||
}
|
||||
|
||||
DMXConfigCommentPtr dmxConfigCreateComment(int token, int line,
|
||||
const char *comment)
|
||||
{
|
||||
DMXConfigCommentPtr pComment = dmxConfigAlloc(sizeof(*pComment));
|
||||
|
||||
pComment->token = token;
|
||||
pComment->line = line;
|
||||
pComment->comment = comment;
|
||||
return pComment;
|
||||
}
|
||||
|
||||
void dmxConfigFreeComment(DMXConfigCommentPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
dmxConfigFree((void *)p->comment);
|
||||
dmxConfigFree(p);
|
||||
}
|
||||
|
||||
DMXConfigPartDimPtr dmxConfigCreatePartDim(DMXConfigPairPtr pDim,
|
||||
DMXConfigPairPtr pOffset)
|
||||
{
|
||||
DMXConfigPartDimPtr pPart = dmxConfigAlloc(sizeof(*pPart));
|
||||
pPart->dim = pDim;
|
||||
pPart->offset = pOffset;
|
||||
return pPart;
|
||||
}
|
||||
|
||||
void dmxConfigFreePartDim(DMXConfigPartDimPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
dmxConfigFreePair(p->dim);
|
||||
dmxConfigFreePair(p->offset);
|
||||
dmxConfigFree(p);
|
||||
}
|
||||
|
||||
DMXConfigFullDimPtr dmxConfigCreateFullDim(DMXConfigPartDimPtr pScrn,
|
||||
DMXConfigPartDimPtr pRoot)
|
||||
{
|
||||
DMXConfigFullDimPtr pFull = dmxConfigAlloc(sizeof(*pFull));
|
||||
pFull->scrn = pScrn;
|
||||
pFull->root = pRoot;
|
||||
return pFull;
|
||||
}
|
||||
|
||||
void dmxConfigFreeFullDim(DMXConfigFullDimPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
dmxConfigFreePartDim(p->scrn);
|
||||
dmxConfigFreePartDim(p->root);
|
||||
dmxConfigFree(p);
|
||||
}
|
||||
|
||||
DMXConfigDisplayPtr dmxConfigCreateDisplay(DMXConfigTokenPtr pStart,
|
||||
DMXConfigStringPtr pName,
|
||||
DMXConfigFullDimPtr pDim,
|
||||
DMXConfigPairPtr pOrigin,
|
||||
DMXConfigTokenPtr pEnd)
|
||||
{
|
||||
DMXConfigDisplayPtr pDisplay = dmxConfigAlloc(sizeof(*pDisplay));
|
||||
|
||||
memset(pDisplay, 0, sizeof(*pDisplay));
|
||||
|
||||
pDisplay->start = pStart;
|
||||
pDisplay->dname = pName;
|
||||
pDisplay->dim = pDim;
|
||||
pDisplay->origin = pOrigin;
|
||||
pDisplay->end = pEnd;
|
||||
|
||||
pDisplay->name = pName ? pName->string : NULL;
|
||||
pDisplay->rootXOrigin = pOrigin ? pOrigin->x : 0;
|
||||
pDisplay->rootYOrigin = pOrigin ? pOrigin->y : 0;
|
||||
|
||||
if (pDim && pDim->scrn && pDim->scrn->dim) {
|
||||
pDisplay->scrnWidth = pDim->scrn->dim->x;
|
||||
pDisplay->scrnHeight = pDim->scrn->dim->y;
|
||||
}
|
||||
if (pDim && pDim->scrn && pDim->scrn->offset) {
|
||||
pDisplay->scrnX = pDim->scrn->offset->x;
|
||||
pDisplay->scrnY = pDim->scrn->offset->y;
|
||||
pDisplay->scrnXSign = pDim->scrn->offset->xsign;
|
||||
pDisplay->scrnYSign = pDim->scrn->offset->ysign;
|
||||
}
|
||||
|
||||
if (pDim && pDim->root) {
|
||||
if (pDim->root->dim) {
|
||||
pDisplay->rootWidth = pDim->root->dim->x;
|
||||
pDisplay->rootHeight = pDim->root->dim->y;
|
||||
}
|
||||
if (pDim->root->offset) {
|
||||
pDisplay->rootX = pDim->root->offset->x;
|
||||
pDisplay->rootY = pDim->root->offset->y;
|
||||
pDisplay->rootXSign = pDim->root->offset->xsign;
|
||||
pDisplay->rootYSign = pDim->root->offset->ysign;
|
||||
}
|
||||
} else { /* If no root specification, copy width
|
||||
* and height from scrn -- leave offset
|
||||
* as zero, since it is relative to
|
||||
* scrn. */
|
||||
pDisplay->rootWidth = pDisplay->scrnWidth;
|
||||
pDisplay->rootHeight = pDisplay->scrnHeight;
|
||||
}
|
||||
|
||||
|
||||
return pDisplay;
|
||||
}
|
||||
|
||||
void dmxConfigFreeDisplay(DMXConfigDisplayPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
dmxConfigFreeToken(p->start);
|
||||
dmxConfigFreeString(p->dname);
|
||||
dmxConfigFreeFullDim(p->dim);
|
||||
dmxConfigFreeToken(p->end);
|
||||
dmxConfigFree(p);
|
||||
}
|
||||
|
||||
DMXConfigWallPtr dmxConfigCreateWall(DMXConfigTokenPtr pStart,
|
||||
DMXConfigPairPtr pWallDim,
|
||||
DMXConfigPairPtr pDisplayDim,
|
||||
DMXConfigStringPtr pNameList,
|
||||
DMXConfigTokenPtr pEnd)
|
||||
{
|
||||
DMXConfigWallPtr pWall = dmxConfigAlloc(sizeof(*pWall));
|
||||
|
||||
pWall->start = pStart;
|
||||
pWall->wallDim = pWallDim;
|
||||
pWall->displayDim = pDisplayDim;
|
||||
pWall->nameList = pNameList;
|
||||
pWall->end = pEnd;
|
||||
|
||||
pWall->width = pDisplayDim ? pDisplayDim->x : 0;
|
||||
pWall->height = pDisplayDim ? pDisplayDim->y : 0;
|
||||
pWall->xwall = pWallDim ? pWallDim->x : 0;
|
||||
pWall->ywall = pWallDim ? pWallDim->y : 0;
|
||||
|
||||
return pWall;
|
||||
}
|
||||
|
||||
void dmxConfigFreeWall(DMXConfigWallPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
dmxConfigFreeToken(p->start);
|
||||
dmxConfigFreePair(p->wallDim);
|
||||
dmxConfigFreePair(p->displayDim);
|
||||
dmxConfigFreeString(p->nameList);
|
||||
dmxConfigFreeToken(p->end);
|
||||
dmxConfigFree(p);
|
||||
}
|
||||
|
||||
DMXConfigOptionPtr dmxConfigCreateOption(DMXConfigTokenPtr pStart,
|
||||
DMXConfigStringPtr pOption,
|
||||
DMXConfigTokenPtr pEnd)
|
||||
{
|
||||
int length = 0;
|
||||
int offset = 0;
|
||||
DMXConfigStringPtr p;
|
||||
DMXConfigOptionPtr option = dmxConfigAlloc(sizeof(*option));
|
||||
|
||||
for (p = pOption; p; p = p->next) {
|
||||
if (p->string) length += strlen(p->string) + 1;
|
||||
}
|
||||
|
||||
option->string = dmxConfigAlloc(length + 1);
|
||||
|
||||
for (p = pOption; p; p = p->next) {
|
||||
if (p->string) {
|
||||
int len = strlen(p->string);
|
||||
strncpy(option->string + offset, p->string, len);
|
||||
offset += len;
|
||||
if (p->next) option->string[offset++] = ' ';
|
||||
}
|
||||
}
|
||||
option->string[offset] = '\0';
|
||||
|
||||
option->start = pStart;
|
||||
option->option = pOption;
|
||||
option->end = pEnd;
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
void dmxConfigFreeOption(DMXConfigOptionPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
if (p->string) free(p->string);
|
||||
dmxConfigFreeToken(p->start);
|
||||
dmxConfigFreeString(p->option);
|
||||
dmxConfigFreeToken(p->end);
|
||||
dmxConfigFree(p);
|
||||
}
|
||||
|
||||
const char **dmxConfigLookupParam(DMXConfigParamPtr p, const char *key,
|
||||
int *argc)
|
||||
{
|
||||
DMXConfigParamPtr pt;
|
||||
|
||||
for (pt = p; pt; pt = pt->next) {
|
||||
if (pt->argv && !strcasecmp(pt->argv[0], key)) {
|
||||
*argc = pt->argc;
|
||||
return pt->argv;
|
||||
}
|
||||
}
|
||||
*argc = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DMXConfigParamPtr dmxConfigCreateParam(DMXConfigTokenPtr pStart,
|
||||
DMXConfigTokenPtr pOpen,
|
||||
DMXConfigStringPtr pParam,
|
||||
DMXConfigTokenPtr pClose,
|
||||
DMXConfigTokenPtr pEnd)
|
||||
{
|
||||
DMXConfigParamPtr param = dmxConfigAlloc(sizeof(*param));
|
||||
DMXConfigStringPtr pt;
|
||||
|
||||
param->argc = 0;
|
||||
param->argv = NULL;
|
||||
for (pt = pParam; pt; pt = pt->next) {
|
||||
if (pt->string) {
|
||||
param->argv = realloc(param->argv,
|
||||
(param->argc+2) * sizeof(*param->argv));
|
||||
param->argv[param->argc] = pt->string;
|
||||
++param->argc;
|
||||
}
|
||||
}
|
||||
if (param->argv) param->argv[param->argc] = NULL;
|
||||
|
||||
param->start = pStart;
|
||||
param->open = pOpen;
|
||||
param->param = pParam;
|
||||
param->close = pClose;
|
||||
param->end = pEnd;
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
void dmxConfigFreeParam(DMXConfigParamPtr p)
|
||||
{
|
||||
DMXConfigParamPtr next;
|
||||
|
||||
if (!p) return;
|
||||
do {
|
||||
next = p->next;
|
||||
dmxConfigFreeToken(p->start);
|
||||
dmxConfigFreeToken(p->open);
|
||||
dmxConfigFreeString(p->param);
|
||||
dmxConfigFreeToken(p->close);
|
||||
dmxConfigFreeToken(p->end);
|
||||
dmxConfigFree(p->argv);
|
||||
dmxConfigFree(p);
|
||||
} while ((p = next));
|
||||
}
|
||||
|
||||
DMXConfigSubPtr dmxConfigCreateSub(DMXConfigType type,
|
||||
DMXConfigCommentPtr comment,
|
||||
DMXConfigDisplayPtr display,
|
||||
DMXConfigWallPtr wall,
|
||||
DMXConfigOptionPtr option,
|
||||
DMXConfigParamPtr param)
|
||||
{
|
||||
DMXConfigSubPtr pSub = dmxConfigAlloc(sizeof(*pSub));
|
||||
pSub->type = type;
|
||||
switch (type) {
|
||||
case dmxConfigComment: pSub->comment = comment; break;
|
||||
case dmxConfigDisplay: pSub->display = display; break;
|
||||
case dmxConfigWall: pSub->wall = wall; break;
|
||||
case dmxConfigOption: pSub->option = option; break;
|
||||
case dmxConfigParam: pSub->param = param; break;
|
||||
default: dmxConfigLog("Type %d not supported in subentry\n", type); break;
|
||||
}
|
||||
return pSub;
|
||||
}
|
||||
|
||||
void dmxConfigFreeSub(DMXConfigSubPtr sub)
|
||||
{
|
||||
DMXConfigSubPtr pt;
|
||||
|
||||
for (pt = sub; pt; pt = pt->next) {
|
||||
switch (pt->type) {
|
||||
case dmxConfigComment: dmxConfigFreeComment(pt->comment); break;
|
||||
case dmxConfigDisplay: dmxConfigFreeDisplay(pt->display); break;
|
||||
case dmxConfigWall: dmxConfigFreeWall(pt->wall); break;
|
||||
case dmxConfigOption: dmxConfigFreeOption(pt->option); break;
|
||||
case dmxConfigParam: dmxConfigFreeParam(pt->param); break;
|
||||
default:
|
||||
dmxConfigLog("Type %d not supported in subentry\n", pt->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dmxConfigFree(sub);
|
||||
}
|
||||
|
||||
DMXConfigSubPtr dmxConfigSubComment(DMXConfigCommentPtr comment)
|
||||
{
|
||||
return dmxConfigCreateSub(dmxConfigComment, comment, NULL, NULL, NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
DMXConfigSubPtr dmxConfigSubDisplay(DMXConfigDisplayPtr display)
|
||||
{
|
||||
return dmxConfigCreateSub(dmxConfigDisplay, NULL, display, NULL, NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
DMXConfigSubPtr dmxConfigSubWall(DMXConfigWallPtr wall)
|
||||
{
|
||||
return dmxConfigCreateSub(dmxConfigWall, NULL, NULL, wall, NULL, NULL);
|
||||
}
|
||||
|
||||
DMXConfigSubPtr dmxConfigSubOption(DMXConfigOptionPtr option)
|
||||
{
|
||||
return dmxConfigCreateSub(dmxConfigOption, NULL, NULL, NULL, option, NULL);
|
||||
}
|
||||
|
||||
DMXConfigSubPtr dmxConfigSubParam(DMXConfigParamPtr param)
|
||||
{
|
||||
return dmxConfigCreateSub(dmxConfigParam, NULL, NULL, NULL, NULL, param);
|
||||
}
|
||||
|
||||
extern DMXConfigSubPtr dmxConfigAddSub(DMXConfigSubPtr head,
|
||||
DMXConfigSubPtr sub)
|
||||
{
|
||||
DMXConfigSubPtr pt;
|
||||
|
||||
if (!head) return sub;
|
||||
for (pt = head; pt->next; pt = pt->next);
|
||||
pt->next = sub;
|
||||
return head;
|
||||
}
|
||||
|
||||
DMXConfigVirtualPtr dmxConfigCreateVirtual(DMXConfigTokenPtr pStart,
|
||||
DMXConfigStringPtr pName,
|
||||
DMXConfigPairPtr pDim,
|
||||
DMXConfigTokenPtr pOpen,
|
||||
DMXConfigSubPtr pSubentry,
|
||||
DMXConfigTokenPtr pClose)
|
||||
{
|
||||
DMXConfigVirtualPtr pVirtual = dmxConfigAlloc(sizeof(*pVirtual));
|
||||
|
||||
pVirtual->start = pStart;
|
||||
pVirtual->vname = pName;
|
||||
pVirtual->dim = pDim;
|
||||
pVirtual->open = pOpen;
|
||||
pVirtual->subentry = pSubentry;
|
||||
pVirtual->close = pClose;
|
||||
|
||||
pVirtual->name = pName ? pName->string : NULL;
|
||||
pVirtual->width = pDim ? pDim->x : 0;
|
||||
pVirtual->height = pDim ? pDim->y : 0;
|
||||
|
||||
return pVirtual;
|
||||
}
|
||||
|
||||
void dmxConfigFreeVirtual(DMXConfigVirtualPtr virtual)
|
||||
{
|
||||
dmxConfigFreeToken(virtual->start);
|
||||
dmxConfigFreeString(virtual->vname);
|
||||
dmxConfigFreePair(virtual->dim);
|
||||
dmxConfigFreeToken(virtual->open);
|
||||
dmxConfigFreeSub(virtual->subentry);
|
||||
dmxConfigFreeToken(virtual->close);
|
||||
dmxConfigFree(virtual);
|
||||
}
|
||||
|
||||
DMXConfigEntryPtr dmxConfigCreateEntry(DMXConfigType type,
|
||||
DMXConfigCommentPtr comment,
|
||||
DMXConfigVirtualPtr virtual)
|
||||
{
|
||||
DMXConfigEntryPtr pEntry = dmxConfigAlloc(sizeof(*pEntry));
|
||||
pEntry->type = type;
|
||||
switch (type) {
|
||||
case dmxConfigComment: pEntry->comment = comment; break;
|
||||
case dmxConfigVirtual: pEntry->virtual = virtual; break;
|
||||
default: dmxConfigLog("Type %d not supported in entry\n", type); break;
|
||||
}
|
||||
return pEntry;
|
||||
}
|
||||
|
||||
void dmxConfigFreeEntry(DMXConfigEntryPtr entry)
|
||||
{
|
||||
DMXConfigEntryPtr pt;
|
||||
|
||||
for (pt = entry; pt; pt = pt->next) {
|
||||
switch (pt->type) {
|
||||
case dmxConfigComment: dmxConfigFreeComment(pt->comment); break;
|
||||
case dmxConfigVirtual: dmxConfigFreeVirtual(pt->virtual); break;
|
||||
default:
|
||||
dmxConfigLog("Type %d not supported in entry\n", pt->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dmxConfigFree(entry);
|
||||
}
|
||||
|
||||
DMXConfigEntryPtr dmxConfigAddEntry(DMXConfigEntryPtr head,
|
||||
DMXConfigType type,
|
||||
DMXConfigCommentPtr comment,
|
||||
DMXConfigVirtualPtr virtual)
|
||||
{
|
||||
DMXConfigEntryPtr child = dmxConfigCreateEntry(type, comment, virtual);
|
||||
DMXConfigEntryPtr pt;
|
||||
|
||||
if (!head) return child;
|
||||
|
||||
for (pt = head; pt->next; pt = pt->next);
|
||||
pt->next = child;
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
DMXConfigEntryPtr dmxConfigEntryComment(DMXConfigCommentPtr comment)
|
||||
{
|
||||
return dmxConfigCreateEntry(dmxConfigComment, comment, NULL);
|
||||
}
|
||||
|
||||
DMXConfigEntryPtr dmxConfigEntryVirtual(DMXConfigVirtualPtr virtual)
|
||||
{
|
||||
return dmxConfigCreateEntry(dmxConfigVirtual, NULL, virtual);
|
||||
}
|
||||
298
hw/dmx/config/dmxparse.h
Normal file
298
hw/dmx/config/dmxparse.h
Normal file
@@ -0,0 +1,298 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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
|
||||
* Interface to DMX configuration file parser. \see dmxparse.c */
|
||||
|
||||
#ifndef _DMXPARSE_H_
|
||||
#define _DMXPARSE_H_
|
||||
|
||||
#include <stdio.h> /* For FILE */
|
||||
|
||||
/** Stores tokens not stored in other structures (e.g., keywords and ;) */
|
||||
typedef struct _DMXConfigToken {
|
||||
int token;
|
||||
int line;
|
||||
const char *comment;
|
||||
} DMXConfigToken, *DMXConfigTokenPtr;
|
||||
|
||||
/** Stores parsed strings. */
|
||||
typedef struct _DMXConfigString {
|
||||
int token;
|
||||
int line;
|
||||
const char *comment;
|
||||
const char *string;
|
||||
struct _DMXConfigString *next;
|
||||
} DMXConfigString, *DMXConfigStringPtr;
|
||||
|
||||
/** Stores parsed numbers. */
|
||||
typedef struct _DMXConfigNumber {
|
||||
int token;
|
||||
int line;
|
||||
const char *comment;
|
||||
int number;
|
||||
} DMXConfigNumber, *DMXConfigNumberPtr;
|
||||
|
||||
/** Stores parsed pairs (e.g., x y) */
|
||||
typedef struct _DMXConfigPair {
|
||||
int token;
|
||||
int line;
|
||||
const char *comment;
|
||||
int x;
|
||||
int y;
|
||||
int xsign;
|
||||
int ysign;
|
||||
} DMXConfigPair, *DMXConfigPairPtr;
|
||||
|
||||
/** Stores parsed comments not stored with a token. */
|
||||
typedef struct _DMXConfigComment {
|
||||
int token;
|
||||
int line;
|
||||
const char *comment;
|
||||
} DMXConfigComment, *DMXConfigCommentPtr;
|
||||
|
||||
typedef enum {
|
||||
dmxConfigComment,
|
||||
dmxConfigVirtual,
|
||||
dmxConfigDisplay,
|
||||
dmxConfigWall,
|
||||
dmxConfigOption,
|
||||
dmxConfigParam
|
||||
} DMXConfigType;
|
||||
|
||||
/** Stores a geometry specification. */
|
||||
typedef struct _DMXConfigPartDim {
|
||||
DMXConfigPairPtr dim;
|
||||
DMXConfigPairPtr offset;
|
||||
} DMXConfigPartDim, *DMXConfigPartDimPtr;
|
||||
|
||||
/** Stores a pair of geometry specifications. */
|
||||
typedef struct _DMXConfigFullDim {
|
||||
DMXConfigPartDimPtr scrn;
|
||||
DMXConfigPartDimPtr root;
|
||||
} DMXConfigFullDim, *DMXConfigFullDimPtr;
|
||||
|
||||
/** Stores parsed display information. */
|
||||
typedef struct _DMXConfigDisplay {
|
||||
/* Summary information */
|
||||
const char *name;
|
||||
/* Screen Window Geometry */
|
||||
int scrnWidth, scrnHeight;
|
||||
int scrnX, scrnY;
|
||||
int scrnXSign, scrnYSign;
|
||||
/* Root Window Geometry */
|
||||
int rootWidth, rootHeight;
|
||||
int rootX, rootY;
|
||||
int rootXSign, rootYSign;
|
||||
/* Origin in global space */
|
||||
int rootXOrigin, rootYOrigin;
|
||||
|
||||
/* Raw configuration information */
|
||||
DMXConfigTokenPtr start;
|
||||
DMXConfigStringPtr dname;
|
||||
DMXConfigFullDimPtr dim;
|
||||
DMXConfigPairPtr origin;
|
||||
DMXConfigTokenPtr end;
|
||||
} DMXConfigDisplay, *DMXConfigDisplayPtr;
|
||||
|
||||
/** Stores parsed wall information. */
|
||||
typedef struct _DMXConfigWall {
|
||||
/* Summary information */
|
||||
int width, height; /* dimensions of displays */
|
||||
int xwall, ywall; /* dimensions of wall, in tiles */
|
||||
|
||||
|
||||
/* Raw configuration informaiton */
|
||||
DMXConfigTokenPtr start;
|
||||
DMXConfigPairPtr wallDim;
|
||||
DMXConfigPairPtr displayDim;
|
||||
DMXConfigStringPtr nameList;
|
||||
DMXConfigTokenPtr end;
|
||||
} DMXConfigWall, *DMXConfigWallPtr;
|
||||
|
||||
/** Stores parsed option information. */
|
||||
typedef struct _DMXConfigOption {
|
||||
/* Summary information */
|
||||
char *string;
|
||||
|
||||
/* Raw configuration informaiton */
|
||||
DMXConfigTokenPtr start;
|
||||
DMXConfigStringPtr option;
|
||||
DMXConfigTokenPtr end;
|
||||
} DMXConfigOption, *DMXConfigOptionPtr;
|
||||
|
||||
/** Stores parsed param information. */
|
||||
typedef struct _DMXConfigParam {
|
||||
int argc;
|
||||
const char **argv;
|
||||
|
||||
DMXConfigTokenPtr start;
|
||||
DMXConfigTokenPtr open;
|
||||
DMXConfigStringPtr param;
|
||||
DMXConfigTokenPtr close;
|
||||
DMXConfigTokenPtr end; /* Either open/close OR end */
|
||||
struct _DMXConfigParam *next;
|
||||
} DMXConfigParam, *DMXConfigParamPtr;
|
||||
|
||||
/** Stores options under an entry (subentry). */
|
||||
typedef struct _DMXConfigSub {
|
||||
DMXConfigType type;
|
||||
DMXConfigCommentPtr comment;
|
||||
DMXConfigDisplayPtr display;
|
||||
DMXConfigWallPtr wall;
|
||||
DMXConfigOptionPtr option;
|
||||
DMXConfigParamPtr param;
|
||||
struct _DMXConfigSub *next;
|
||||
} DMXConfigSub, *DMXConfigSubPtr;
|
||||
|
||||
/** Stores parsed virtual information. */
|
||||
typedef struct _DMXConfigVirtual {
|
||||
/* Summary information */
|
||||
const char *name;
|
||||
int width, height;
|
||||
|
||||
/* Raw configuration information */
|
||||
DMXConfigTokenPtr start;
|
||||
DMXConfigStringPtr vname;
|
||||
DMXConfigPairPtr dim;
|
||||
DMXConfigTokenPtr open;
|
||||
DMXConfigSubPtr subentry;
|
||||
DMXConfigTokenPtr close;
|
||||
} DMXConfigVirtual, *DMXConfigVirtualPtr;
|
||||
|
||||
/** Heads entry storage. */
|
||||
typedef struct _DMXConfigEntry {
|
||||
DMXConfigType type;
|
||||
DMXConfigCommentPtr comment;
|
||||
DMXConfigVirtualPtr virtual;
|
||||
struct _DMXConfigEntry *next;
|
||||
} DMXConfigEntry, *DMXConfigEntryPtr;
|
||||
|
||||
extern DMXConfigEntryPtr dmxConfigEntry;
|
||||
|
||||
extern int yylex(void);
|
||||
extern int yydebug;
|
||||
extern void yyerror(const char *message);
|
||||
|
||||
extern void dmxConfigLog(const char *format, ...);
|
||||
extern void *dmxConfigAlloc(unsigned long bytes);
|
||||
extern void *dmxConfigRealloc(void *orig,
|
||||
unsigned long orig_bytes,
|
||||
unsigned long bytes);
|
||||
extern const char *dmxConfigCopyString(const char *string,
|
||||
int length);
|
||||
extern void dmxConfigFree(void *area);
|
||||
extern DMXConfigTokenPtr dmxConfigCreateToken(int token, int line,
|
||||
const char *comment);
|
||||
extern void dmxConfigFreeToken(DMXConfigTokenPtr p);
|
||||
extern DMXConfigStringPtr dmxConfigCreateString(int token, int line,
|
||||
const char *comment,
|
||||
const char *string);
|
||||
extern void dmxConfigFreeString(DMXConfigStringPtr p);
|
||||
extern DMXConfigNumberPtr dmxConfigCreateNumber(int token, int line,
|
||||
const char *comment,
|
||||
int number);
|
||||
extern void dmxConfigFreeNumber(DMXConfigNumberPtr p);
|
||||
extern DMXConfigPairPtr dmxConfigCreatePair(int token, int line,
|
||||
const char *comment,
|
||||
int x, int y,
|
||||
int xsign, int ysign);
|
||||
extern void dmxConfigFreePair(DMXConfigPairPtr p);
|
||||
extern DMXConfigCommentPtr dmxConfigCreateComment(int token, int line,
|
||||
const char *comment);
|
||||
extern void dmxConfigFreeComment(DMXConfigCommentPtr p);
|
||||
extern DMXConfigPartDimPtr dmxConfigCreatePartDim(DMXConfigPairPtr pDim,
|
||||
DMXConfigPairPtr pOffset);
|
||||
extern void dmxConfigFreePartDim(DMXConfigPartDimPtr p);
|
||||
extern DMXConfigFullDimPtr dmxConfigCreateFullDim(DMXConfigPartDimPtr pScrn,
|
||||
DMXConfigPartDimPtr pRoot);
|
||||
extern void dmxConfigFreeFullDim(DMXConfigFullDimPtr p);
|
||||
extern DMXConfigDisplayPtr dmxConfigCreateDisplay(DMXConfigTokenPtr pStart,
|
||||
DMXConfigStringPtr pName,
|
||||
DMXConfigFullDimPtr pDim,
|
||||
DMXConfigPairPtr pOrigin,
|
||||
DMXConfigTokenPtr pEnd);
|
||||
extern void dmxConfigFreeDisplay(DMXConfigDisplayPtr p);
|
||||
extern DMXConfigWallPtr dmxConfigCreateWall(DMXConfigTokenPtr pStart,
|
||||
DMXConfigPairPtr pWallDim,
|
||||
DMXConfigPairPtr pDisplayDim,
|
||||
DMXConfigStringPtr pNameList,
|
||||
DMXConfigTokenPtr pEnd);
|
||||
extern void dmxConfigFreeWall(DMXConfigWallPtr p);
|
||||
extern DMXConfigOptionPtr dmxConfigCreateOption(DMXConfigTokenPtr pStart,
|
||||
DMXConfigStringPtr pOption,
|
||||
DMXConfigTokenPtr pEnd);
|
||||
extern void dmxConfigFreeOption(DMXConfigOptionPtr p);
|
||||
extern DMXConfigParamPtr dmxConfigCreateParam(DMXConfigTokenPtr pStart,
|
||||
DMXConfigTokenPtr pOpen,
|
||||
DMXConfigStringPtr pParam,
|
||||
DMXConfigTokenPtr pClose,
|
||||
DMXConfigTokenPtr pEnd);
|
||||
extern void dmxConfigFreeParam(DMXConfigParamPtr p);
|
||||
extern const char **dmxConfigLookupParam(DMXConfigParamPtr p,
|
||||
const char *key,
|
||||
int *argc);
|
||||
extern DMXConfigSubPtr dmxConfigCreateSub(DMXConfigType type,
|
||||
DMXConfigCommentPtr comment,
|
||||
DMXConfigDisplayPtr display,
|
||||
DMXConfigWallPtr wall,
|
||||
DMXConfigOptionPtr option,
|
||||
DMXConfigParamPtr param);
|
||||
extern void dmxConfigFreeSub(DMXConfigSubPtr sub);
|
||||
extern DMXConfigSubPtr dmxConfigSubComment(DMXConfigCommentPtr comment);
|
||||
extern DMXConfigSubPtr dmxConfigSubDisplay(DMXConfigDisplayPtr display);
|
||||
extern DMXConfigSubPtr dmxConfigSubWall(DMXConfigWallPtr wall);
|
||||
extern DMXConfigSubPtr dmxConfigSubOption(DMXConfigOptionPtr option);
|
||||
extern DMXConfigSubPtr dmxConfigSubParam(DMXConfigParamPtr param);
|
||||
extern DMXConfigSubPtr dmxConfigAddSub(DMXConfigSubPtr head,
|
||||
DMXConfigSubPtr sub);
|
||||
extern DMXConfigVirtualPtr dmxConfigCreateVirtual(DMXConfigTokenPtr pStart,
|
||||
DMXConfigStringPtr pName,
|
||||
DMXConfigPairPtr pDim,
|
||||
DMXConfigTokenPtr pOpen,
|
||||
DMXConfigSubPtr pSubentry,
|
||||
DMXConfigTokenPtr pClose);
|
||||
extern void dmxConfigFreeVirtual(DMXConfigVirtualPtr virtual);
|
||||
extern DMXConfigEntryPtr dmxConfigCreateEntry(DMXConfigType type,
|
||||
DMXConfigCommentPtr comment,
|
||||
DMXConfigVirtualPtr virtual);
|
||||
extern void dmxConfigFreeEntry(DMXConfigEntryPtr entry);
|
||||
extern DMXConfigEntryPtr dmxConfigAddEntry(DMXConfigEntryPtr head,
|
||||
DMXConfigType type,
|
||||
DMXConfigCommentPtr comment,
|
||||
DMXConfigVirtualPtr virtual);
|
||||
extern DMXConfigEntryPtr dmxConfigEntryComment(DMXConfigCommentPtr comment);
|
||||
extern DMXConfigEntryPtr dmxConfigEntryVirtual(DMXConfigVirtualPtr virtual);
|
||||
|
||||
#endif
|
||||
452
hw/dmx/config/dmxprint.c
Normal file
452
hw/dmx/config/dmxprint.c
Normal file
@@ -0,0 +1,452 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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 provides support routines and helper functions to be used
|
||||
* to pretty-print DMX configurations.
|
||||
*
|
||||
* Because the DMX configuration file parsing should be capable of being
|
||||
* used in a stand-alone fashion (i.e., independent from the DMX server
|
||||
* source tree), no dependencies on other DMX routines are made. */
|
||||
|
||||
#include "dmxconfig.h"
|
||||
#include "dmxparse.h"
|
||||
#include "dmxprint.h"
|
||||
#include "parser.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static FILE *str = NULL;
|
||||
static int indent = 0;
|
||||
static int pos = 0;
|
||||
|
||||
/** Stack of indentation information used for pretty-printing
|
||||
* configuration information. */
|
||||
static struct stack {
|
||||
int base;
|
||||
int comment;
|
||||
int step;
|
||||
struct stack *next;
|
||||
} *stack, initialStack = { 0, 0, 4, NULL };
|
||||
|
||||
static void dmxConfigIndent(void)
|
||||
{
|
||||
int i;
|
||||
if (indent < 0) indent = 0;
|
||||
if (indent > 40) indent = 40;
|
||||
for (i = 0; i < indent; i++) fprintf(str, " ");
|
||||
}
|
||||
|
||||
static void dmxConfigNewline(void)
|
||||
{
|
||||
if (pos) fprintf(str, "\n");
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
static void dmxConfigPushState(int base, int comment, int step)
|
||||
{
|
||||
struct stack *new = dmxConfigAlloc(sizeof(*new));
|
||||
new->base = base;
|
||||
new->comment = comment;
|
||||
new->step = step;
|
||||
new->next = stack;
|
||||
stack = new;
|
||||
indent = base;
|
||||
dmxConfigNewline();
|
||||
}
|
||||
|
||||
static void dmxConfigPushComment(void)
|
||||
{
|
||||
if (stack) indent = stack->comment;
|
||||
}
|
||||
|
||||
static void dmxConfigPushStep(void)
|
||||
{
|
||||
if (stack) indent = stack->step;
|
||||
}
|
||||
|
||||
static void dmxConfigPopState(void)
|
||||
{
|
||||
struct stack *old = stack;
|
||||
|
||||
if (!stack) return;
|
||||
indent = old->base;
|
||||
stack = old->next;
|
||||
if (!stack) dmxConfigLog("Stack underflow\n");
|
||||
dmxConfigFree(old);
|
||||
dmxConfigNewline();
|
||||
}
|
||||
|
||||
static void dmxConfigOutput(int addSpace, int doNewline, const char *comment,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!pos) dmxConfigIndent();
|
||||
else if (addSpace) fprintf(str, " ");
|
||||
|
||||
if (format) {
|
||||
va_start(args, format);
|
||||
/* RATS: This hasn't been audited -- it
|
||||
* could probably result in a buffer
|
||||
* overflow. */
|
||||
pos += vfprintf(str, format, args); /* assumes no newlines! */
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
if (comment) {
|
||||
if (pos) fprintf(str, " ");
|
||||
pos += fprintf(str, "#%s", comment);
|
||||
dmxConfigNewline();
|
||||
dmxConfigPushComment();
|
||||
} else if (doNewline) dmxConfigNewline();
|
||||
}
|
||||
|
||||
static void dmxConfigPrintComment(DMXConfigCommentPtr p)
|
||||
{
|
||||
dmxConfigOutput(1, 1, p->comment, NULL);
|
||||
}
|
||||
|
||||
static void dmxConfigPrintTokenFlag(DMXConfigTokenPtr p, int flag)
|
||||
{
|
||||
if (!p) return;
|
||||
switch (p->token) {
|
||||
case T_VIRTUAL:
|
||||
dmxConfigPushState(0, 4, 4);
|
||||
dmxConfigOutput(0, 0, p->comment, "virtual");
|
||||
break;
|
||||
case T_DISPLAY:
|
||||
dmxConfigPushState(4, 12, 16);
|
||||
dmxConfigOutput(0, 0, p->comment, "display");
|
||||
break;
|
||||
case T_WALL:
|
||||
dmxConfigPushState(4, 12, 16);
|
||||
dmxConfigOutput(0, 0, p->comment, "wall");
|
||||
break;
|
||||
case T_OPTION:
|
||||
dmxConfigPushState(4, 12, 16);
|
||||
dmxConfigOutput(0, 0, p->comment, "option");
|
||||
break;
|
||||
case T_PARAM:
|
||||
dmxConfigPushState(4, 8, 12);
|
||||
dmxConfigOutput(0, 0, p->comment, "param");
|
||||
break;
|
||||
case ';':
|
||||
dmxConfigOutput(0, 1, p->comment, ";");
|
||||
if (flag) dmxConfigPopState();
|
||||
break;
|
||||
case '{':
|
||||
dmxConfigOutput(1, 1, p->comment, "{");
|
||||
dmxConfigPushStep();
|
||||
break;
|
||||
case '}':
|
||||
if (flag) dmxConfigPopState();
|
||||
dmxConfigOutput(0, 1, p->comment, "}");
|
||||
break;
|
||||
case '/':
|
||||
dmxConfigOutput(1, 0, NULL, "/");
|
||||
break;
|
||||
default:
|
||||
dmxConfigLog("unknown token %d on line %d\n", p->token, p->line);
|
||||
}
|
||||
}
|
||||
|
||||
static void dmxConfigPrintToken(DMXConfigTokenPtr p)
|
||||
{
|
||||
dmxConfigPrintTokenFlag(p, 1);
|
||||
}
|
||||
|
||||
static void dmxConfigPrintTokenNopop(DMXConfigTokenPtr p)
|
||||
{
|
||||
dmxConfigPrintTokenFlag(p, 0);
|
||||
}
|
||||
|
||||
static int dmxConfigPrintQuotedString(const char *s)
|
||||
{
|
||||
const char *pt;
|
||||
|
||||
if (!s || !s[0]) return 1; /* Quote empty string */
|
||||
for (pt = s; *pt; ++pt) if (isspace(*pt)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dmxConfigPrintString(DMXConfigStringPtr p, int quote)
|
||||
{
|
||||
DMXConfigStringPtr pt;
|
||||
|
||||
if (!p) return;
|
||||
for (pt = p; pt; pt = pt->next) {
|
||||
if (quote && dmxConfigPrintQuotedString(pt->string)) {
|
||||
dmxConfigOutput(1, 0, pt->comment, "\"%s\"",
|
||||
pt->string ? pt->string : "");
|
||||
} else
|
||||
dmxConfigOutput(1, 0, pt->comment, "%s",
|
||||
pt->string ? pt->string : "");
|
||||
}
|
||||
}
|
||||
|
||||
static int dmxConfigPrintPair(DMXConfigPairPtr p, int addSpace)
|
||||
{
|
||||
const char *format = NULL;
|
||||
|
||||
if (!p) return 0;
|
||||
switch (p->token) {
|
||||
case T_ORIGIN: format = "@%dx%d"; break;
|
||||
case T_DIMENSION: format = "%dx%d"; break;
|
||||
case T_OFFSET: format = "%c%d%c%d"; break;
|
||||
}
|
||||
if (p->token == T_OFFSET) {
|
||||
if (!p->comment && !p->x && !p->y && p->xsign >= 0 && p->ysign >= 0)
|
||||
return 0;
|
||||
dmxConfigOutput(addSpace, 0, p->comment, format,
|
||||
p->xsign < 0 ? '-' : '+', p->x,
|
||||
p->ysign < 0 ? '-' : '+', p->y);
|
||||
} else {
|
||||
if (!p->comment && !p->x && !p->y) return 0;
|
||||
dmxConfigOutput(addSpace, 0, p->comment, format, p->x, p->y);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void dmxConfigPrintDisplay(DMXConfigDisplayPtr p)
|
||||
{
|
||||
DMXConfigToken dummyStart = { T_DISPLAY, 0, NULL };
|
||||
DMXConfigToken dummyEnd = { ';', 0, NULL };
|
||||
DMXConfigToken dummySep = { '/', 0, NULL };
|
||||
DMXConfigString dummyName = { T_STRING, 0, NULL, NULL, NULL };
|
||||
DMXConfigPair dummySDim = { T_DIMENSION, 0, NULL, 0, 0, 0, 0 };
|
||||
DMXConfigPair dummySOffset = { T_OFFSET, 0, NULL, 0, 0, 0, 0 };
|
||||
DMXConfigPair dummyRDim = { T_DIMENSION, 0, NULL, 0, 0, 0, 0 };
|
||||
DMXConfigPair dummyROffset = { T_OFFSET, 0, NULL, 0, 0, 0, 0 };
|
||||
DMXConfigPair dummyOrigin = { T_ORIGIN, 0, NULL, 0, 0, 0, 0 };
|
||||
int output;
|
||||
|
||||
if (p->dname) p->dname->string = p->name;
|
||||
else dummyName.string = p->name;
|
||||
|
||||
if (p->dim && p->dim->scrn && p->dim->scrn->dim) {
|
||||
p->dim->scrn->dim->x = p->scrnWidth;
|
||||
p->dim->scrn->dim->y = p->scrnHeight;
|
||||
} else {
|
||||
dummySDim.x = p->scrnWidth;
|
||||
dummySDim.y = p->scrnHeight;
|
||||
}
|
||||
|
||||
if (p->dim && p->dim->scrn && p->dim->scrn->offset) {
|
||||
p->dim->scrn->offset->x = p->scrnX;
|
||||
p->dim->scrn->offset->y = p->scrnY;
|
||||
} else {
|
||||
dummySOffset.x = p->scrnX;
|
||||
dummySOffset.y = p->scrnY;
|
||||
}
|
||||
|
||||
if (p->dim && p->dim->root && p->dim->root->dim) {
|
||||
p->dim->root->dim->x = p->rootWidth;
|
||||
p->dim->root->dim->y = p->rootHeight;
|
||||
} else {
|
||||
dummyRDim.x = p->rootWidth;
|
||||
dummyRDim.y = p->rootHeight;
|
||||
}
|
||||
|
||||
if (p->dim && p->dim->root && p->dim->root->offset) {
|
||||
p->dim->root->offset->x = p->rootX;
|
||||
p->dim->root->offset->y = p->rootY;
|
||||
} else {
|
||||
dummyROffset.x = p->rootX;
|
||||
dummyROffset.y = p->rootY;
|
||||
}
|
||||
|
||||
if (p->origin) {
|
||||
p->origin->x = p->rootXOrigin, p->origin->y = p->rootYOrigin;
|
||||
p->origin->xsign = p->rootXSign, p->origin->ysign = p->rootYSign;
|
||||
} else {
|
||||
dummyOrigin.x = p->rootXOrigin, dummyOrigin.y = p->rootYOrigin;
|
||||
dummyOrigin.xsign = p->rootXSign, dummyOrigin.ysign = p->rootYSign;
|
||||
}
|
||||
|
||||
dmxConfigPrintToken(p->start ? p->start : &dummyStart);
|
||||
dmxConfigPrintString(p->dname ? p->dname : &dummyName, 1);
|
||||
|
||||
if (p->dim && p->dim->scrn && p->dim->scrn->dim)
|
||||
output = dmxConfigPrintPair(p->dim->scrn->dim, 1);
|
||||
else
|
||||
output = dmxConfigPrintPair(&dummySDim, 1);
|
||||
if (p->dim && p->dim->scrn && p->dim->scrn->offset)
|
||||
dmxConfigPrintPair(p->dim->scrn->offset, !output);
|
||||
else
|
||||
dmxConfigPrintPair(&dummySOffset, !output);
|
||||
|
||||
if (p->scrnWidth != p->rootWidth
|
||||
|| p->scrnHeight != p->rootHeight
|
||||
|| p->rootX
|
||||
|| p->rootY) {
|
||||
dmxConfigPrintToken(&dummySep);
|
||||
if (p->dim && p->dim->root && p->dim->root->dim)
|
||||
output = dmxConfigPrintPair(p->dim->root->dim, 1);
|
||||
else
|
||||
output = dmxConfigPrintPair(&dummyRDim, 1);
|
||||
if (p->dim && p->dim->root && p->dim->root->offset)
|
||||
dmxConfigPrintPair(p->dim->root->offset, !output);
|
||||
else
|
||||
dmxConfigPrintPair(&dummyROffset, !output);
|
||||
}
|
||||
|
||||
dmxConfigPrintPair(p->origin ? p->origin : &dummyOrigin, 1);
|
||||
dmxConfigPrintToken(p->end ? p->end : &dummyEnd);
|
||||
}
|
||||
|
||||
static void dmxConfigPrintWall(DMXConfigWallPtr p)
|
||||
{
|
||||
dmxConfigPrintToken(p->start);
|
||||
dmxConfigPrintPair(p->wallDim, 1);
|
||||
dmxConfigPrintPair(p->displayDim, 1);
|
||||
dmxConfigPrintString(p->nameList, 1);
|
||||
dmxConfigPrintToken(p->end);
|
||||
}
|
||||
|
||||
static void dmxConfigPrintOption(DMXConfigOptionPtr p)
|
||||
{
|
||||
DMXConfigToken dummyStart = { T_OPTION, 0, NULL };
|
||||
DMXConfigString dummyOption = { T_STRING, 0, NULL, NULL, NULL };
|
||||
DMXConfigToken dummyEnd = { ';', 0, NULL };
|
||||
|
||||
dummyOption.string = p->string;
|
||||
|
||||
dmxConfigPrintToken(p->start ? p->start : &dummyStart);
|
||||
dmxConfigPrintString(&dummyOption, 0);
|
||||
dmxConfigPrintToken(p->end ? p->end : &dummyEnd);
|
||||
}
|
||||
|
||||
static void dmxConfigPrintParam(DMXConfigParamPtr p)
|
||||
{
|
||||
if (!p) return;
|
||||
if (p->start) {
|
||||
if (p->open && p->close) {
|
||||
dmxConfigPrintToken(p->start);
|
||||
dmxConfigPrintToken(p->open);
|
||||
dmxConfigPrintParam(p->next);
|
||||
dmxConfigPrintToken(p->close);
|
||||
} else if (p->end && p->param) {
|
||||
dmxConfigPrintToken(p->start);
|
||||
dmxConfigPrintString(p->param, 1);
|
||||
dmxConfigPrintToken(p->end);
|
||||
} else
|
||||
dmxConfigLog("dmxConfigPrintParam: cannot handle format (a)\n");
|
||||
} else if (p->end && p->param) {
|
||||
dmxConfigPrintString(p->param, 1);
|
||||
dmxConfigPrintTokenNopop(p->end);
|
||||
dmxConfigPrintParam(p->next);
|
||||
} else
|
||||
dmxConfigLog("dmxConfigPrintParam: cannot handle format (b)\n");
|
||||
}
|
||||
|
||||
static void dmxConfigPrintSub(DMXConfigSubPtr p)
|
||||
{
|
||||
DMXConfigSubPtr pt;
|
||||
|
||||
if (!p) return;
|
||||
for (pt = p; pt; pt = pt->next) {
|
||||
switch (pt->type) {
|
||||
case dmxConfigComment: dmxConfigPrintComment(pt->comment); break;
|
||||
case dmxConfigDisplay: dmxConfigPrintDisplay(pt->display); break;
|
||||
case dmxConfigWall: dmxConfigPrintWall(pt->wall); break;
|
||||
case dmxConfigOption: dmxConfigPrintOption(pt->option); break;
|
||||
case dmxConfigParam: dmxConfigPrintParam(pt->param); break;
|
||||
default:
|
||||
dmxConfigLog("dmxConfigPrintSub:"
|
||||
" cannot handle type %d in subentry\n", pt->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dmxConfigPrintVirtual(DMXConfigVirtualPtr p)
|
||||
{
|
||||
DMXConfigToken dummyStart = { T_VIRTUAL, 0, NULL };
|
||||
DMXConfigToken dummyOpen = { '{', 0, NULL };
|
||||
DMXConfigToken dummyClose = { '}', 0, NULL };
|
||||
DMXConfigString dummyName = { T_STRING, 0, NULL, NULL, NULL };
|
||||
DMXConfigPair dummyDim = { T_DIMENSION, 0, NULL, 0, 0 };
|
||||
|
||||
if (p->vname) p->vname->string = p->name;
|
||||
else dummyName.string = p->name;
|
||||
|
||||
if (p->dim) p->dim->x = p->width, p->dim->y = p->height;
|
||||
else dummyDim.x = p->width, dummyDim.y = p->height;
|
||||
|
||||
|
||||
dmxConfigPrintToken(p->start ? p->start : &dummyStart);
|
||||
dmxConfigPrintString(p->vname ? p->vname : &dummyName, 1);
|
||||
dmxConfigPrintPair(p->dim ? p->dim : &dummyDim, 1);
|
||||
dmxConfigPrintToken(p->open ? p->open : &dummyOpen);
|
||||
dmxConfigPrintSub(p->subentry);
|
||||
dmxConfigPrintToken(p->close ? p->close : &dummyClose);
|
||||
}
|
||||
|
||||
/** The configuration information in \a entry will be pretty-printed to
|
||||
* the \a stream. If \a stream is NULL, then stdout will be used. */
|
||||
void dmxConfigPrint(FILE *stream, DMXConfigEntryPtr entry)
|
||||
{
|
||||
DMXConfigEntryPtr pt;
|
||||
|
||||
if (!stream) str = stdout;
|
||||
else str = stream;
|
||||
|
||||
stack = &initialStack;
|
||||
|
||||
for (pt = entry; pt; pt = pt->next) {
|
||||
switch (pt->type) {
|
||||
case dmxConfigComment: dmxConfigPrintComment(pt->comment); break;
|
||||
case dmxConfigVirtual: dmxConfigPrintVirtual(pt->virtual); break;
|
||||
default:
|
||||
dmxConfigLog("dmxConfigPrint: cannot handle type %d in entry\n",
|
||||
pt->type);
|
||||
}
|
||||
}
|
||||
if (pos) dmxConfigNewline();
|
||||
}
|
||||
|
||||
/** The configuration information in \a p will be pretty-printed to the
|
||||
* \a stream. If \a stream is NULL, then stdout will be used. */
|
||||
void dmxConfigVirtualPrint(FILE *stream, DMXConfigVirtualPtr p)
|
||||
{
|
||||
if (!stream) str = stdout;
|
||||
else str = stream;
|
||||
|
||||
stack = &initialStack;
|
||||
|
||||
dmxConfigPrintVirtual(p);
|
||||
if (pos) dmxConfigNewline();
|
||||
}
|
||||
44
hw/dmx/config/dmxprint.h
Normal file
44
hw/dmx/config/dmxprint.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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
|
||||
* Interface to DMX configuration file pretty-printer. \see dmxprint.c */
|
||||
|
||||
#ifndef _DMXPRINT_H_
|
||||
#define _DMXPRINT_H_
|
||||
|
||||
void dmxConfigPrint(FILE *str, DMXConfigEntryPtr entry);
|
||||
void dmxConfigVirtualPrint(FILE *str, DMXConfigVirtualPtr p);
|
||||
|
||||
#endif
|
||||
50
hw/dmx/config/dmxtodmx.c
Normal file
50
hw/dmx/config/dmxtodmx.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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>
|
||||
*
|
||||
* This is a simple filter for testing.
|
||||
*/
|
||||
|
||||
#include "dmxconfig.h"
|
||||
#include "dmxparse.h"
|
||||
#include "dmxprint.h"
|
||||
#include "dmxcompat.h"
|
||||
|
||||
extern int yyparse(void);
|
||||
extern FILE *yyin;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
yydebug = 0;
|
||||
yyparse();
|
||||
dmxConfigPrint(stdout, dmxConfigEntry);
|
||||
return 0;
|
||||
}
|
||||
41
hw/dmx/config/dmxtodmx.man
Normal file
41
hw/dmx/config/dmxtodmx.man
Normal file
@@ -0,0 +1,41 @@
|
||||
.\" $XFree86$
|
||||
.\" Copyright 2002 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>
|
||||
.\"
|
||||
.TH dmxtodmx 1 __vendorversion__
|
||||
.SH NAME
|
||||
dmxtodmx - dmx configuration file parser and printer
|
||||
.SH SYNOPSIS
|
||||
.B dmxtodmx
|
||||
.SH DESCRIPTION
|
||||
.I dmxtodmx
|
||||
reads the standard input, parsing a configuration file for the
|
||||
.I Xdmx
|
||||
distributed multi-head X server. After a successful parse, the file is
|
||||
pretty-printed to standard output.
|
||||
.SH "SEE ALSO"
|
||||
Xdmx(1), vdltodmx(1), xdmxconfig(1)
|
||||
222
hw/dmx/config/parser.y
Normal file
222
hw/dmx/config/parser.y
Normal file
@@ -0,0 +1,222 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002-2003 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>
|
||||
*
|
||||
*/
|
||||
|
||||
%{
|
||||
#include "dmxparse.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#define YYDEBUG 1
|
||||
#define YYERROR_VERBOSE
|
||||
#define YY_USE_PROTOS
|
||||
|
||||
DMXConfigEntryPtr dmxConfigEntry = NULL;
|
||||
#define APPEND(type, h, t) \
|
||||
{ \
|
||||
type pt; \
|
||||
for (pt = h; pt->next; pt = pt->next); \
|
||||
pt->next = t; \
|
||||
}
|
||||
%}
|
||||
|
||||
%union {
|
||||
DMXConfigTokenPtr token;
|
||||
DMXConfigStringPtr string;
|
||||
DMXConfigNumberPtr number;
|
||||
DMXConfigPairPtr pair;
|
||||
DMXConfigFullDimPtr fdim;
|
||||
DMXConfigPartDimPtr pdim;
|
||||
DMXConfigDisplayPtr display;
|
||||
DMXConfigWallPtr wall;
|
||||
DMXConfigOptionPtr option;
|
||||
DMXConfigParamPtr param;
|
||||
DMXConfigCommentPtr comment;
|
||||
DMXConfigSubPtr subentry;
|
||||
DMXConfigVirtualPtr virtual;
|
||||
DMXConfigEntryPtr entry;
|
||||
}
|
||||
|
||||
/* Terminals */
|
||||
%token <token> '{' '}' ';' '/' T_VIRTUAL T_DISPLAY T_WALL T_OPTION T_PARAM
|
||||
%token <string> T_STRING
|
||||
%token <pair> T_DIMENSION T_OFFSET T_ORIGIN
|
||||
%token <comment> T_COMMENT T_LINE_COMMENT
|
||||
|
||||
/* Non-termials */
|
||||
%type <token> Display Wall Terminal Open Close
|
||||
%type <string> NameList Name
|
||||
%type <pair> Dimension Offset Origin
|
||||
%type <pdim> PartialDim
|
||||
%type <fdim> FullDim
|
||||
%type <display> DisplayEntry
|
||||
%type <option> OptionEntry
|
||||
%type <param> ParamEntry ParamList Param
|
||||
%type <subentry> SubList Sub
|
||||
%type <wall> WallEntry
|
||||
%type <virtual> Virtual
|
||||
%type <entry> Program EntryList Entry
|
||||
|
||||
%%
|
||||
|
||||
Program : EntryList { dmxConfigEntry = $1; }
|
||||
;
|
||||
|
||||
EntryList : Entry
|
||||
| EntryList Entry { APPEND(DMXConfigEntryPtr,$1,$2); $$ = $1; }
|
||||
;
|
||||
|
||||
Entry : Virtual { $$ = dmxConfigEntryVirtual($1); }
|
||||
| T_LINE_COMMENT { $$ = dmxConfigEntryComment($1); }
|
||||
;
|
||||
|
||||
Virtual : T_VIRTUAL Open SubList Close
|
||||
{ $$ = dmxConfigCreateVirtual($1, NULL, NULL, $2, $3, $4); }
|
||||
| T_VIRTUAL Dimension Open SubList Close
|
||||
{ $$ = dmxConfigCreateVirtual($1, NULL, $2, $3, $4, $5); }
|
||||
| T_VIRTUAL Name Open SubList Close
|
||||
{ $$ = dmxConfigCreateVirtual($1, $2, NULL, $3, $4, $5); }
|
||||
| T_VIRTUAL Name Dimension Open SubList Close
|
||||
{ $$ = dmxConfigCreateVirtual($1, $2, $3, $4, $5, $6 ); }
|
||||
;
|
||||
|
||||
SubList : Sub
|
||||
| SubList Sub { APPEND(DMXConfigSubPtr,$1,$2); $$ = $1; }
|
||||
;
|
||||
|
||||
Sub : T_LINE_COMMENT { $$ = dmxConfigSubComment($1); }
|
||||
| DisplayEntry { $$ = dmxConfigSubDisplay($1); }
|
||||
| WallEntry { $$ = dmxConfigSubWall($1); }
|
||||
| OptionEntry { $$ = dmxConfigSubOption($1); }
|
||||
| ParamEntry { $$ = dmxConfigSubParam($1); }
|
||||
;
|
||||
|
||||
OptionEntry : T_OPTION NameList Terminal
|
||||
{ $$ = dmxConfigCreateOption($1, $2, $3); }
|
||||
;
|
||||
|
||||
ParamEntry : T_PARAM NameList Terminal
|
||||
{ $$ = dmxConfigCreateParam($1, NULL, $2, NULL, $3); }
|
||||
| T_PARAM Open ParamList Close
|
||||
{ $$ = dmxConfigCreateParam($1, $2, NULL, $4, NULL);
|
||||
$$->next = $3;
|
||||
}
|
||||
;
|
||||
|
||||
ParamList : Param
|
||||
| ParamList Param { APPEND(DMXConfigParamPtr,$1,$2); $$ = $1; }
|
||||
;
|
||||
|
||||
Param : NameList Terminal
|
||||
{ $$ = dmxConfigCreateParam(NULL, NULL, $1, NULL, $2); }
|
||||
;
|
||||
|
||||
PartialDim : Dimension Offset
|
||||
{ $$ = dmxConfigCreatePartDim($1, $2); }
|
||||
| Dimension
|
||||
{ $$ = dmxConfigCreatePartDim($1, NULL); }
|
||||
| Offset
|
||||
{ $$ = dmxConfigCreatePartDim(NULL, $1); }
|
||||
;
|
||||
|
||||
FullDim : PartialDim '/' PartialDim
|
||||
{ $$ = dmxConfigCreateFullDim($1, $3); }
|
||||
| '/' PartialDim
|
||||
{ $$ = dmxConfigCreateFullDim(NULL, $2); }
|
||||
| PartialDim
|
||||
{ $$ = dmxConfigCreateFullDim($1, NULL); }
|
||||
;
|
||||
|
||||
DisplayEntry : Display Name FullDim Origin Terminal
|
||||
{ $$ = dmxConfigCreateDisplay($1, $2, $3, $4, $5); }
|
||||
| Display FullDim Origin Terminal
|
||||
{ $$ = dmxConfigCreateDisplay($1, NULL, $2, $3, $4); }
|
||||
| Display Name Origin Terminal
|
||||
{ $$ = dmxConfigCreateDisplay($1, $2, NULL, $3, $4); }
|
||||
|
||||
| Display Name FullDim Terminal
|
||||
{ $$ = dmxConfigCreateDisplay($1, $2, $3, NULL, $4); }
|
||||
| Display FullDim Terminal
|
||||
{ $$ = dmxConfigCreateDisplay($1, NULL, $2, NULL, $3); }
|
||||
| Display Name Terminal
|
||||
{ $$ = dmxConfigCreateDisplay($1, $2, NULL, NULL, $3); }
|
||||
| Display Terminal
|
||||
{ $$ = dmxConfigCreateDisplay($1, NULL, NULL, NULL, $2); }
|
||||
;
|
||||
|
||||
WallEntry : Wall Dimension Dimension NameList Terminal
|
||||
{ $$ = dmxConfigCreateWall($1, $2, $3, $4, $5); }
|
||||
| Wall Dimension NameList Terminal
|
||||
{ $$ = dmxConfigCreateWall($1, $2, NULL, $3, $4); }
|
||||
| Wall NameList Terminal
|
||||
{ $$ = dmxConfigCreateWall($1, NULL, NULL, $2, $3); }
|
||||
;
|
||||
|
||||
Display : T_DISPLAY
|
||||
| T_DISPLAY T_COMMENT { $$ = $1; $$->comment = $2->comment; }
|
||||
;
|
||||
|
||||
Name : T_STRING
|
||||
| T_STRING T_COMMENT { $$ = $1; $$->comment = $2->comment; }
|
||||
;
|
||||
|
||||
Dimension : T_DIMENSION
|
||||
| T_DIMENSION T_COMMENT { $$ = $1; $$->comment = $2->comment; }
|
||||
;
|
||||
|
||||
Offset : T_OFFSET
|
||||
| T_OFFSET T_COMMENT { $$ = $1; $$->comment = $2->comment; }
|
||||
;
|
||||
|
||||
Origin : T_ORIGIN
|
||||
| T_ORIGIN T_COMMENT { $$ = $1; $$->comment = $2->comment; }
|
||||
;
|
||||
|
||||
Terminal : ';'
|
||||
| ';' T_COMMENT { $$ = $1; $$->comment = $2->comment; }
|
||||
;
|
||||
|
||||
Open : '{'
|
||||
| '{' T_COMMENT { $$ = $1; $$->comment = $2->comment; }
|
||||
;
|
||||
|
||||
Close : '}'
|
||||
| '}' T_COMMENT { $$ = $1; $$->comment = $2->comment; }
|
||||
;
|
||||
|
||||
Wall : T_WALL
|
||||
| T_WALL T_COMMENT { $$ = $1; $$->comment = $2->comment; }
|
||||
;
|
||||
|
||||
NameList : Name
|
||||
| NameList Name { APPEND(DMXConfigStringPtr, $1, $2); $$ = $1; }
|
||||
;
|
||||
179
hw/dmx/config/scanner.l
Normal file
179
hw/dmx/config/scanner.l
Normal file
@@ -0,0 +1,179 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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>
|
||||
*
|
||||
*/
|
||||
|
||||
%{
|
||||
#include "dmxparse.h"
|
||||
#include "parser.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
static int getdimension(int token, const char *text, int leng);
|
||||
static int getstring(int token, const char *text, int leng);
|
||||
static int gettoken(int token, const char *text, int leng);
|
||||
static int getcomment(int token, const char *text, int leng);
|
||||
static int lineno = 1;
|
||||
%}
|
||||
%s OTHER
|
||||
comment #.*
|
||||
word ([[:alpha:]_/:\-\+\.\*][[:alnum:]_/:\-\+\.\*]+)
|
||||
string \"(([^\"\n])|\"\")*\"
|
||||
badstring \"(([^\"\n])|\"\")*
|
||||
number [[:digit:]x]+
|
||||
dimension [[:digit:]]+[[:blank:]]*x[[:blank:]]*[[:digit:]]+
|
||||
offset [+-][[:digit:]]+[[:blank:]]*[+-][[:blank:]]*[[:digit:]]+
|
||||
origin @[[:blank:]]*[[:digit:]]+[[:blank:]]*[[:blank:]]*x[[:digit:]]+
|
||||
NL \n
|
||||
WS [[:blank:]]+
|
||||
%%
|
||||
virtual return gettoken(T_VIRTUAL, yytext, yyleng);
|
||||
display return gettoken(T_DISPLAY, yytext, yyleng);
|
||||
wall return gettoken(T_WALL, yytext, yyleng);
|
||||
option return gettoken(T_OPTION, yytext, yyleng);
|
||||
param return gettoken(T_PARAM, yytext, yyleng);
|
||||
{dimension} return getdimension(T_DIMENSION, yytext, yyleng);
|
||||
{offset} return getdimension(T_OFFSET, yytext+1, yyleng-1);
|
||||
{origin} return getdimension(T_ORIGIN, yytext+1, yyleng-1);
|
||||
{word} return getstring(T_STRING, yytext, yyleng);
|
||||
{string} return getstring(T_STRING, yytext+1, yyleng-2);
|
||||
{NL} ++lineno;
|
||||
{WS}
|
||||
\{ return gettoken(yytext[0], yytext, yyleng);
|
||||
\} return gettoken(yytext[0], yytext, yyleng);
|
||||
\; return gettoken(yytext[0], yytext, yyleng);
|
||||
\/ return gettoken(yytext[0], yytext, yyleng);
|
||||
^{comment} return getcomment(T_LINE_COMMENT, yytext, yyleng);
|
||||
{comment} return getcomment(T_COMMENT, yytext, yyleng);
|
||||
. return getstring(T_STRING, yytext, yyleng);
|
||||
<<EOF>> return 0;
|
||||
%%
|
||||
int yywrap(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void yyerror(const char *message)
|
||||
{
|
||||
const char *pt, *end;
|
||||
struct _entry {
|
||||
const char *from;
|
||||
const char *to;
|
||||
} *entry, list[] = {
|
||||
{ "T_VIRTUAL", "\"virtual\"" },
|
||||
{ "T_DISPLAY", "\"display\"" },
|
||||
{ "T_WALL", "\"wall\"" },
|
||||
{ "T_OPTION", "\"option\"" },
|
||||
{ "T_PARAM", "\"param\"" },
|
||||
{ "T_DIMENSION", "dimension (e.g., 2x2 or 1024x768)" },
|
||||
{ "T_OFFSET", "display offset (e.g., +10-10)" },
|
||||
{ "T_ORIGIN", "tile origin (e.g., @1280x1024)" },
|
||||
{ "T_STRING", "string" },
|
||||
{ "T_COMMENT", "comment (e.g., #...)" },
|
||||
{ "T_LINE_COMMENT", "comment (e.g., #...)" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
fprintf(stderr, "parse error on line %d at token \"%*.*s\"\n",
|
||||
lineno, yyleng, yyleng, yytext);
|
||||
end = message + strlen(message);
|
||||
for (pt = message; *pt; pt++) {
|
||||
if (pt[0] == 'T' && pt[1] == '_') {
|
||||
const char *next = strchr(pt, ' ');
|
||||
if (!next || !*next) next = strchr(pt, '\0');
|
||||
if (!next) goto bail;
|
||||
--next;
|
||||
if (next-pt == 1 && next[1]
|
||||
&& next[2] == '\'' && next[3] == '\'') {
|
||||
fprintf(stderr, "\"%c\"", next[1]);
|
||||
pt += 4;
|
||||
goto cnt;
|
||||
}
|
||||
for (entry = list; entry->from; ++entry) {
|
||||
if (!strncmp(entry->from, pt, strlen(entry->from))) {
|
||||
fprintf(stderr, "%s", entry->to);
|
||||
pt = next;
|
||||
goto cnt;
|
||||
}
|
||||
}
|
||||
} else if (end-pt >= 5 && pt[0] == '\'' && pt[1] == '\'' && pt[3]
|
||||
&& pt[4] == '\'' && pt[5] == '\'') {
|
||||
fprintf(stderr, "\"%c\"", pt[3]);
|
||||
pt += 5;
|
||||
} else if (end-pt >= 3 && pt[0] == '\'' && pt[1] && pt[2] == '\'') {
|
||||
fprintf(stderr, "\"%c\"", pt[1]);
|
||||
pt += 3;
|
||||
}
|
||||
bail:
|
||||
putc(*pt, stderr);
|
||||
cnt:
|
||||
;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
static int getdimension(int token, const char *text, int leng)
|
||||
{
|
||||
char *endptr;
|
||||
char *tmp = dmxConfigAlloc(leng+1);
|
||||
int x, y;
|
||||
|
||||
strncpy(tmp, text, leng);
|
||||
x = strtol(tmp, &endptr, 10);
|
||||
while (*endptr && !isdigit(*endptr)) ++endptr;
|
||||
y = strtol(endptr, NULL, 10);
|
||||
dmxConfigFree(tmp);
|
||||
yylval.pair = dmxConfigCreatePair(token, lineno, NULL, x, y, 1, 1);
|
||||
return token;
|
||||
}
|
||||
|
||||
static int getstring(int token, const char *text, int leng)
|
||||
{
|
||||
yylval.string = dmxConfigCreateString(token, lineno, NULL,
|
||||
dmxConfigCopyString(leng ? text : "",
|
||||
leng));
|
||||
return token;
|
||||
}
|
||||
|
||||
static int gettoken(int token, const char *text, int leng)
|
||||
{
|
||||
yylval.token = dmxConfigCreateToken(token, lineno, NULL);
|
||||
return token;
|
||||
}
|
||||
|
||||
static int getcomment(int token, const char *text, int leng)
|
||||
{
|
||||
yylval.comment = dmxConfigCreateComment(token, lineno,
|
||||
dmxConfigCopyString(text + 1,
|
||||
leng - 1));
|
||||
return token;
|
||||
}
|
||||
1
hw/dmx/config/test-a.in
Normal file
1
hw/dmx/config/test-a.in
Normal file
@@ -0,0 +1 @@
|
||||
error
|
||||
2
hw/dmx/config/test-a.out
Normal file
2
hw/dmx/config/test-a.out
Normal file
@@ -0,0 +1,2 @@
|
||||
parse error on line 1 at token "error"
|
||||
syntax error, unexpected string expecting "virtual" or comment (e.g., #...)
|
||||
1
hw/dmx/config/test-b.in
Normal file
1
hw/dmx/config/test-b.in
Normal file
@@ -0,0 +1 @@
|
||||
# comment
|
||||
1
hw/dmx/config/test-b.out
Normal file
1
hw/dmx/config/test-b.out
Normal file
@@ -0,0 +1 @@
|
||||
# comment
|
||||
1
hw/dmx/config/test-c.in
Normal file
1
hw/dmx/config/test-c.in
Normal file
@@ -0,0 +1 @@
|
||||
virtual
|
||||
2
hw/dmx/config/test-c.out
Normal file
2
hw/dmx/config/test-c.out
Normal file
@@ -0,0 +1,2 @@
|
||||
parse error on line 2 at token " "
|
||||
syntax error, unexpected $end, expecting "{" or string or dimension (e.g., 2x2 or 1024x768)
|
||||
1
hw/dmx/config/test-d.in
Normal file
1
hw/dmx/config/test-d.in
Normal file
@@ -0,0 +1 @@
|
||||
display
|
||||
2
hw/dmx/config/test-d.out
Normal file
2
hw/dmx/config/test-d.out
Normal file
@@ -0,0 +1,2 @@
|
||||
parse error on line 1 at token "display"
|
||||
syntax error, unexpected "display" expecting "virtual" or comment (e.g., #...)
|
||||
1
hw/dmx/config/test-e.in
Normal file
1
hw/dmx/config/test-e.in
Normal file
@@ -0,0 +1 @@
|
||||
display;
|
||||
2
hw/dmx/config/test-e.out
Normal file
2
hw/dmx/config/test-e.out
Normal file
@@ -0,0 +1,2 @@
|
||||
parse error on line 1 at token "display"
|
||||
syntax error, unexpected "display" expecting "virtual" or comment (e.g., #...)
|
||||
2
hw/dmx/config/test-f.in
Normal file
2
hw/dmx/config/test-f.in
Normal file
@@ -0,0 +1,2 @@
|
||||
virtual {
|
||||
}
|
||||
BIN
hw/dmx/config/test-f.out
Normal file
BIN
hw/dmx/config/test-f.out
Normal file
Binary file not shown.
4
hw/dmx/config/test-g.in
Normal file
4
hw/dmx/config/test-g.in
Normal file
@@ -0,0 +1,4 @@
|
||||
virtual a {
|
||||
display d0:0 1280x1024;
|
||||
display d1:0 1280x1024;
|
||||
}
|
||||
4
hw/dmx/config/test-g.out
Normal file
4
hw/dmx/config/test-g.out
Normal file
@@ -0,0 +1,4 @@
|
||||
virtual a {
|
||||
display d0:0 1280x1024;
|
||||
display d1:0 1280x1024;
|
||||
}
|
||||
7
hw/dmx/config/test-h.in
Normal file
7
hw/dmx/config/test-h.in
Normal file
@@ -0,0 +1,7 @@
|
||||
# comment a
|
||||
# comment b
|
||||
## comment c
|
||||
# <-- tab
|
||||
# Next comment is empty
|
||||
#
|
||||
# Non empty
|
||||
7
hw/dmx/config/test-h.out
Normal file
7
hw/dmx/config/test-h.out
Normal file
@@ -0,0 +1,7 @@
|
||||
# comment a
|
||||
# comment b
|
||||
## comment c
|
||||
# <-- tab
|
||||
# Next comment is empty
|
||||
#
|
||||
# Non empty
|
||||
3
hw/dmx/config/test-i.in
Normal file
3
hw/dmx/config/test-i.in
Normal file
@@ -0,0 +1,3 @@
|
||||
virtual a {
|
||||
param a b; # comment
|
||||
}
|
||||
3
hw/dmx/config/test-i.out
Normal file
3
hw/dmx/config/test-i.out
Normal file
@@ -0,0 +1,3 @@
|
||||
virtual a {
|
||||
param a b; # comment
|
||||
}
|
||||
13
hw/dmx/config/test-j.in
Normal file
13
hw/dmx/config/test-j.in
Normal file
@@ -0,0 +1,13 @@
|
||||
virtual a {
|
||||
option aaa # bbb
|
||||
aa cc;
|
||||
param { # comment 1
|
||||
a b;
|
||||
c d;
|
||||
x y z; # comment 2
|
||||
}
|
||||
param e f g h; # comment 3
|
||||
param e f g hlskdjflskdfjsd #comment 4
|
||||
flksdjf sldkfjsldkfjsdlf
|
||||
"lsdkfjsldkfjlsdkjflskdjflsdkjfl" "lkjsdlfjsdlfkjsdlfj";
|
||||
}
|
||||
11
hw/dmx/config/test-j.out
Normal file
11
hw/dmx/config/test-j.out
Normal file
@@ -0,0 +1,11 @@
|
||||
virtual a {
|
||||
option "aaa aa cc";
|
||||
param { # comment 1
|
||||
a b;
|
||||
c d;
|
||||
x y z; # comment 2
|
||||
}
|
||||
param e f g h; # comment 3
|
||||
param e f g hlskdjflskdfjsd #comment 4
|
||||
flksdjf sldkfjsldkfjsdlf lsdkfjsldkfjlsdkjflskdjflsdkjfl lkjsdlfjsdlfkjsdlfj;
|
||||
}
|
||||
3
hw/dmx/config/test-k.in
Normal file
3
hw/dmx/config/test-k.in
Normal file
@@ -0,0 +1,3 @@
|
||||
virtual a {
|
||||
option +xinerama -syncbatch 0;
|
||||
}
|
||||
3
hw/dmx/config/test-k.out
Normal file
3
hw/dmx/config/test-k.out
Normal file
@@ -0,0 +1,3 @@
|
||||
virtual a {
|
||||
option "+xinerama -syncbatch 0";
|
||||
}
|
||||
12
hw/dmx/config/test-l.in
Normal file
12
hw/dmx/config/test-l.in
Normal file
@@ -0,0 +1,12 @@
|
||||
virtual a {
|
||||
display d0:0 1x2;
|
||||
display d1:0 +3+4;
|
||||
display d2:0 100x200 @1x1;
|
||||
display d3:0 +3+4 @2x2;
|
||||
display d4:0 100x200+3+4 @3x3;
|
||||
display d5:0 / 1x2+3+4;
|
||||
display d6:0 / 1x2;
|
||||
display d7:0 / +3+4;
|
||||
display d8:0 / 1x2+3+4 @4x4;
|
||||
display d9:0 11x22+33+44 / 111x222+333+444 @1000x1100;
|
||||
}
|
||||
12
hw/dmx/config/test-l.out
Normal file
12
hw/dmx/config/test-l.out
Normal file
@@ -0,0 +1,12 @@
|
||||
virtual a {
|
||||
display d0:0 1x2;
|
||||
display d1:0 +3+4;
|
||||
display d2:0 100x200 @1x1;
|
||||
display d3:0 +3+4 @2x2;
|
||||
display d4:0 100x200+3+4 @3x3;
|
||||
display d5:0 / 1x2+3+4;
|
||||
display d6:0 / 1x2;
|
||||
display d7:0 / +3+4;
|
||||
display d8:0 / 1x2+3+4 @4x4;
|
||||
display d9:0 11x22+33+44 / 111x222+333+444 @1000x1100;
|
||||
}
|
||||
58
hw/dmx/config/vdltodmx.c
Normal file
58
hw/dmx/config/vdltodmx.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dmxconfig.h"
|
||||
#include "dmxparse.h"
|
||||
#include "dmxprint.h"
|
||||
#include "dmxcompat.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
DMXConfigEntryPtr entry;
|
||||
FILE *str;
|
||||
|
||||
if (argc != 2 && argc !=3) {
|
||||
fprintf(stderr, "Usage: vdltodmx inFile [outFile]\n");
|
||||
return 1;
|
||||
}
|
||||
if (argc == 2) {
|
||||
str = stdout;
|
||||
} else if (!(str = fopen(argv[2], "w"))) {
|
||||
fprintf(stderr, "Cannot open %s for write\n", argv[2]);
|
||||
return 2;
|
||||
}
|
||||
entry = dmxVDLRead(argv[1]);
|
||||
dmxConfigPrint(str, entry);
|
||||
return 0;
|
||||
}
|
||||
95
hw/dmx/config/vdltodmx.man
Normal file
95
hw/dmx/config/vdltodmx.man
Normal file
@@ -0,0 +1,95 @@
|
||||
.\" $XFree86$
|
||||
.\" Copyright 2002 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>
|
||||
.\"
|
||||
.TH vdltodmx 1 __vendorversion__
|
||||
.SH NAME
|
||||
vdltodmx - dmx configuration file parser and printer
|
||||
.SH SYNOPSIS
|
||||
.B vdltodmx
|
||||
.I infile
|
||||
.I outfile
|
||||
.SH DESCRIPTION
|
||||
.I vdltodmx
|
||||
reads the input file, which should be in VDL configuration file format.
|
||||
After a successful parse, a file in Xdmx configuration file format is
|
||||
written to the output file.
|
||||
.P
|
||||
The VDL file format is used with
|
||||
.IR xmovie ,
|
||||
which is available from
|
||||
http://www.llnl.gov/icc/lc/img/xmovie/xmovie.html
|
||||
.SH EXAMPLE
|
||||
Given the following VDL-format file:
|
||||
.RS
|
||||
.nf
|
||||
0
|
||||
2
|
||||
#
|
||||
#
|
||||
2560 2048 Left two-thirds [restrict=*:2]
|
||||
2
|
||||
:2.1 1280 2048 0 0 0 0
|
||||
:2.2 1280 2048 1280 0 0 0
|
||||
4
|
||||
1280 1024 0 0
|
||||
1280 1024 0 1024
|
||||
1280 1024 1280 0
|
||||
1280 1024 1280 1024
|
||||
#
|
||||
2560 2048 Right two-thirds [restrict=*:2]
|
||||
2
|
||||
:2.2 1280 2048 0 0 0 0
|
||||
:2.3 1280 2048 1280 0 0 0
|
||||
4
|
||||
1280 1024 1280 0
|
||||
1280 1024 1280 1024
|
||||
1280 1024 2560 0
|
||||
1280 1024 2560 1024
|
||||
.fi
|
||||
.RE
|
||||
the following DMX-format file will be produced:
|
||||
.RS
|
||||
.nf
|
||||
#
|
||||
#
|
||||
virtual "Left two-thirds" 2560x2048 {
|
||||
display :2.1 1280x2048;
|
||||
display :2.2 1280x2048 @1280x0;
|
||||
}
|
||||
#
|
||||
virtual "Right two-thirds" 2560x2048 {
|
||||
display :2.2 1280x2048;
|
||||
display :2.3 1280x2048 @1280x0;
|
||||
}
|
||||
.fi
|
||||
.RE
|
||||
.SH BUGS
|
||||
If the VDL file is not in the expected format, the program will probably
|
||||
dump core.
|
||||
.SH "SEE ALSO"
|
||||
Xdmx(1), xdmxconfig(1), vdl(3), xmovie(1)
|
||||
1188
hw/dmx/config/xdmxconfig.c
Normal file
1188
hw/dmx/config/xdmxconfig.c
Normal file
File diff suppressed because it is too large
Load Diff
63
hw/dmx/config/xdmxconfig.man
Normal file
63
hw/dmx/config/xdmxconfig.man
Normal file
@@ -0,0 +1,63 @@
|
||||
.\" $XFree86$
|
||||
.\" Copyright 2002 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>
|
||||
.\"
|
||||
.TH xdmxconfig 1 __vendorversion__
|
||||
.SH NAME
|
||||
xdmxconfig - a graphical configuration tool for Xdmx configuration files
|
||||
.SH SYNOPSIS
|
||||
.B xdmxconfig
|
||||
[filename]
|
||||
.SH DESCRIPTION
|
||||
.I xdmxconfig
|
||||
reads, edits, and writes configuration files for the Xdmx server. The
|
||||
grammar for the configuration file is specified in the Xdmx(1) manual
|
||||
page.
|
||||
.PP
|
||||
To start from scratch, create a "New Global" and specify the name and
|
||||
overall dimensions for the configuration. Then use "New Display" to
|
||||
enter more displays.
|
||||
.PP
|
||||
If there is more than one configuration, the configuration name button
|
||||
will bring up a selection menu.
|
||||
.PP
|
||||
In the right-hand pannel, the left mouse button will move the
|
||||
highlighted display at "tool resolution"; the middle mouse button will
|
||||
move the highlighted display by a single pixel (at "wall resolution");
|
||||
and the right mouse button will bring up a menu allowing the highlighted
|
||||
display to be edited or deleted. The arrow keys will also move the
|
||||
highlighted display by a single pixel.
|
||||
.SH BUGS
|
||||
Currently, entries with the
|
||||
.B wall
|
||||
keyword are not editable, but will be preserved in the new output file.
|
||||
The tool will quit when requested by the user, even if a configuration
|
||||
file has not been written out (i.e., without warning). The menu
|
||||
interaction should be improved (menu entries that don't currently work
|
||||
should be greyed-out, for example). The Help button does not work.
|
||||
.SH "SEE ALSO"
|
||||
Xdmx(1), vdltodmx(1)
|
||||
1124
hw/dmx/dmx.c
Normal file
1124
hw/dmx/dmx.c
Normal file
File diff suppressed because it is too large
Load Diff
377
hw/dmx/dmx.h
Normal file
377
hw/dmx/dmx.h
Normal file
@@ -0,0 +1,377 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2003 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
* David H. Dawes <dawes@xfree86.org>
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Main header file included by all other DMX-related files.
|
||||
*/
|
||||
|
||||
/** \mainpage
|
||||
* - <a href="http://dmx.sourceforge.net">DMX Home Page</a>
|
||||
* - <a href="http://sourceforge.net/projects/dmx">DMX Project Page (on
|
||||
* Source Forge)</a>
|
||||
* - <a href="http://dmx.sourceforge.net/dmx.html">Distributed Multihead
|
||||
* X design</a>, the design document for DMX
|
||||
* - <a href="http://dmx.sourceforge.net/DMXSpec.txt">Client-to-Server
|
||||
* DMX Extension to the X Protocol</a>
|
||||
*/
|
||||
|
||||
#ifndef DMX_H
|
||||
#define DMX_H
|
||||
|
||||
#include "gcstruct.h"
|
||||
|
||||
/* Handle client-side include files in one place. */
|
||||
#include "dmxclient.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "scrnintstr.h"
|
||||
|
||||
#ifdef RENDER
|
||||
#include "picturestr.h"
|
||||
#endif
|
||||
|
||||
#ifdef GLXEXT
|
||||
#include <GL/glx.h>
|
||||
#include <GL/glxint.h>
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PosNone = -1,
|
||||
PosAbsolute = 0,
|
||||
PosRightOf,
|
||||
PosLeftOf,
|
||||
PosAbove,
|
||||
PosBelow,
|
||||
PosRelative
|
||||
} PositionType;
|
||||
|
||||
/** Provide the typedef globally, but keep the contents opaque outside
|
||||
* of the input routines. \see dmxinput.h */
|
||||
typedef struct _DMXInputInfo DMXInputInfo;
|
||||
|
||||
/** Provide the typedef globally, but keep the contents opaque outside
|
||||
* of the XSync statistic routines. \see dmxstat.c */
|
||||
typedef struct _DMXStatInfo DMXStatInfo;
|
||||
|
||||
/** Global structure containing information about each backend screen. */
|
||||
typedef struct _DMXScreenInfo {
|
||||
const char *name; /**< Name from command line or config file */
|
||||
int index; /**< Index into dmxScreens global */
|
||||
|
||||
/*---------- Back-end X server information ----------*/
|
||||
|
||||
Display *beDisplay; /**< Back-end X server's display */
|
||||
int beWidth; /**< Width of BE display */
|
||||
int beHeight; /**< Height of BE display */
|
||||
int beDepth; /**< Depth of BE display */
|
||||
int beBPP; /**< Bits per pixel of BE display */
|
||||
int beXDPI; /**< Horizontal dots per inch of BE */
|
||||
int beYDPI; /**< Vertical dots per inch of BE */
|
||||
|
||||
int beNumDepths; /**< Number of depths on BE server */
|
||||
int *beDepths; /**< Depths from BE server */
|
||||
|
||||
int beNumPixmapFormats; /**< Number of pixmap formats on BE */
|
||||
XPixmapFormatValues *bePixmapFormats; /**< Pixmap formats on BE */
|
||||
|
||||
int beNumVisuals; /**< Number of visuals on BE */
|
||||
XVisualInfo *beVisuals; /**< Visuals from BE server */
|
||||
int beDefVisualIndex; /**< Default visual index of BE */
|
||||
|
||||
int beNumDefColormaps; /**< Number of default colormaps */
|
||||
Colormap *beDefColormaps; /**< Default colormaps for DMX server */
|
||||
|
||||
Pixel beBlackPixel; /**< Default black pixel for BE */
|
||||
Pixel beWhitePixel; /**< Default white pixel for BE */
|
||||
|
||||
/*---------- Screen window information ----------*/
|
||||
|
||||
Window scrnWin; /**< "Screen" window on backend display */
|
||||
int scrnX; /**< X offset of "screen" WRT BE display */
|
||||
int scrnY; /**< Y offset of "screen" WRT BE display */
|
||||
int scrnWidth; /**< Width of "screen" */
|
||||
int scrnHeight; /**< Height of "screen" */
|
||||
int scrnXSign; /**< X offset sign of "screen" */
|
||||
int scrnYSign; /**< Y offset sign of "screen" */
|
||||
|
||||
/** Default drawables for "screen" */
|
||||
Drawable scrnDefDrawables[MAXFORMATS];
|
||||
|
||||
struct _DMXScreenInfo *next; /**< List of "screens" on same display */
|
||||
struct _DMXScreenInfo *over; /**< List of "screens" that overlap */
|
||||
|
||||
/*---------- Root window information ----------*/
|
||||
|
||||
Window rootWin; /**< "Root" window on backend display */
|
||||
int rootX; /**< X offset of "root" window WRT "screen"*/
|
||||
int rootY; /**< Y offset of "root" window WRT "screen"*/
|
||||
int rootWidth; /**< Width of "root" window */
|
||||
int rootHeight; /**< Height of "root" window */
|
||||
|
||||
int rootXOrigin; /**< Global X origin of "root" window */
|
||||
int rootYOrigin; /**< Global Y origin of "root" window */
|
||||
|
||||
/*---------- Shadow framebuffer information ----------*/
|
||||
|
||||
void *shadow; /**< Shadow framebuffer data (if enabled) */
|
||||
XlibGC shadowGC; /**< Default GC used by shadow FB code */
|
||||
XImage *shadowFBImage; /**< Screen image used by shadow FB code */
|
||||
|
||||
/*---------- Other related information ----------*/
|
||||
|
||||
int shared; /**< Non-zero if another Xdmx is running */
|
||||
|
||||
Bool WMRunningOnBE;
|
||||
|
||||
Cursor noCursor;
|
||||
Cursor curCursor;
|
||||
/* Support for cursors on overlapped
|
||||
* backend displays. */
|
||||
CursorPtr cursor;
|
||||
int cursorVisible;
|
||||
int cursorNotShared; /* for overlapping screens on a backend */
|
||||
|
||||
PositionType where; /**< Relative layout information */
|
||||
int whereX; /**< Relative layout information */
|
||||
int whereY; /**< Relative layout information */
|
||||
int whereRefScreen; /**< Relative layout information */
|
||||
|
||||
int savedTimeout; /**< Original screen saver timeout */
|
||||
int dpmsCapable; /**< Non-zero if backend is DPMS capable */
|
||||
int dpmsEnabled; /**< Non-zero if DPMS enabled */
|
||||
int dpmsStandby; /**< Original DPMS standby value */
|
||||
int dpmsSuspend; /**< Original DPMS suspend value */
|
||||
int dpmsOff; /**< Original DPMS off value */
|
||||
|
||||
DMXStatInfo *stat; /**< Statistics about XSync */
|
||||
Bool needsSync; /**< True if an XSync is pending */
|
||||
|
||||
#ifdef GLXEXT
|
||||
/** Visual information for glxProxy */
|
||||
int numGlxVisuals;
|
||||
__GLXvisualConfig *glxVisuals;
|
||||
int glxMajorOpcode;
|
||||
int glxErrorBase;
|
||||
|
||||
/** FB config information for glxProxy */
|
||||
__GLXFBConfig *fbconfigs;
|
||||
int numFBConfigs;
|
||||
#endif
|
||||
|
||||
/** Function pointers to wrapped screen
|
||||
* functions */
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
SaveScreenProcPtr SaveScreen;
|
||||
|
||||
CreateGCProcPtr CreateGC;
|
||||
|
||||
CreateWindowProcPtr CreateWindow;
|
||||
DestroyWindowProcPtr DestroyWindow;
|
||||
PositionWindowProcPtr PositionWindow;
|
||||
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
|
||||
RealizeWindowProcPtr RealizeWindow;
|
||||
UnrealizeWindowProcPtr UnrealizeWindow;
|
||||
RestackWindowProcPtr RestackWindow;
|
||||
WindowExposuresProcPtr WindowExposures;
|
||||
PaintWindowBackgroundProcPtr PaintWindowBackground;
|
||||
PaintWindowBorderProcPtr PaintWindowBorder;
|
||||
CopyWindowProcPtr CopyWindow;
|
||||
|
||||
ResizeWindowProcPtr ResizeWindow;
|
||||
ReparentWindowProcPtr ReparentWindow;
|
||||
|
||||
ChangeBorderWidthProcPtr ChangeBorderWidth;
|
||||
|
||||
GetImageProcPtr GetImage;
|
||||
GetSpansProcPtr GetSpans;
|
||||
|
||||
CreatePixmapProcPtr CreatePixmap;
|
||||
DestroyPixmapProcPtr DestroyPixmap;
|
||||
BitmapToRegionProcPtr BitmapToRegion;
|
||||
|
||||
RealizeFontProcPtr RealizeFont;
|
||||
UnrealizeFontProcPtr UnrealizeFont;
|
||||
|
||||
CreateColormapProcPtr CreateColormap;
|
||||
DestroyColormapProcPtr DestroyColormap;
|
||||
InstallColormapProcPtr InstallColormap;
|
||||
StoreColorsProcPtr StoreColors;
|
||||
|
||||
#ifdef SHAPE
|
||||
SetShapeProcPtr SetShape;
|
||||
#endif
|
||||
|
||||
#ifdef RENDER
|
||||
CreatePictureProcPtr CreatePicture;
|
||||
DestroyPictureProcPtr DestroyPicture;
|
||||
ChangePictureClipProcPtr ChangePictureClip;
|
||||
DestroyPictureClipProcPtr DestroyPictureClip;
|
||||
|
||||
ChangePictureProcPtr ChangePicture;
|
||||
ValidatePictureProcPtr ValidatePicture;
|
||||
|
||||
CompositeProcPtr Composite;
|
||||
GlyphsProcPtr Glyphs;
|
||||
CompositeRectsProcPtr CompositeRects;
|
||||
|
||||
InitIndexedProcPtr InitIndexed;
|
||||
CloseIndexedProcPtr CloseIndexed;
|
||||
UpdateIndexedProcPtr UpdateIndexed;
|
||||
|
||||
TrapezoidsProcPtr Trapezoids;
|
||||
TrianglesProcPtr Triangles;
|
||||
TriStripProcPtr TriStrip;
|
||||
TriFanProcPtr TriFan;
|
||||
#endif
|
||||
} DMXScreenInfo;
|
||||
|
||||
/* Global variables available to all Xserver/hw/dmx routines. */
|
||||
extern int dmxNumScreens; /**< Number of dmxScreens */
|
||||
extern DMXScreenInfo *dmxScreens; /**< List of outputs */
|
||||
extern int dmxShadowFB; /**< Non-zero if using
|
||||
* shadow frame-buffer
|
||||
* (deprecated) */
|
||||
extern XErrorEvent dmxLastErrorEvent; /**< Last error that
|
||||
* occurred */
|
||||
extern Bool dmxErrorOccurred; /**< True if an error
|
||||
* occurred */
|
||||
extern Bool dmxOffScreenOpt; /**< True if using off
|
||||
* screen
|
||||
* optimizations */
|
||||
extern Bool dmxSubdividePrimitives; /**< True if using the
|
||||
* primitive subdivision
|
||||
* optimization */
|
||||
extern Bool dmxLazyWindowCreation; /**< True if using the
|
||||
* lazy window creation
|
||||
* optimization */
|
||||
extern Bool dmxUseXKB; /**< True if the XKB
|
||||
* extension should be
|
||||
* used with the backend
|
||||
* servers */
|
||||
extern int dmxDepth; /**< Requested depth if
|
||||
* non-zero */
|
||||
extern Bool dmxNoRender; /**< True if the RENDER
|
||||
* extension should be
|
||||
* disabled */
|
||||
#ifdef GLXEXT
|
||||
extern Bool dmxGLXProxy; /**< True if glxProxy
|
||||
* support is enabled */
|
||||
extern Bool dmxGLXSwapGroupSupport; /**< True if glxProxy
|
||||
* support for swap
|
||||
* groups and barriers
|
||||
* is enabled */
|
||||
extern Bool dmxGLXSyncSwap; /**< True if glxProxy
|
||||
* should force an XSync
|
||||
* request after each
|
||||
* swap buffers call */
|
||||
extern Bool dmxGLXFinishSwap; /**< True if glxProxy
|
||||
* should force a
|
||||
* glFinish request
|
||||
* after each swap
|
||||
* buffers call */
|
||||
#endif
|
||||
extern char *dmxFontPath; /**< NULL if no font
|
||||
* path is set on the
|
||||
* command line;
|
||||
* otherwise, a string
|
||||
* of comma separated
|
||||
* paths built from the
|
||||
* command line
|
||||
* specified font
|
||||
* paths */
|
||||
extern Bool dmxIgnoreBadFontPaths; /**< True if bad font
|
||||
* paths should be
|
||||
* ignored during server
|
||||
* init */
|
||||
extern Bool dmxAddRemoveScreens; /**< True if add and
|
||||
* remove screens support
|
||||
* is enabled */
|
||||
|
||||
/** Wrap screen or GC function pointer */
|
||||
#define DMX_WRAP(_entry, _newfunc, _saved, _actual) \
|
||||
do { \
|
||||
(_saved)->_entry = (_actual)->_entry; \
|
||||
(_actual)->_entry = (_newfunc); \
|
||||
} while (0)
|
||||
|
||||
/** Unwrap screen or GC function pointer */
|
||||
#define DMX_UNWRAP(_entry, _saved, _actual) \
|
||||
do { \
|
||||
(_actual)->_entry = (_saved)->_entry; \
|
||||
} while (0)
|
||||
|
||||
/* Define the MAXSCREENSALLOC/FREE macros, when MAXSCREENS patch has not
|
||||
* been applied to sources. */
|
||||
#ifdef MAXSCREENS
|
||||
#define MAXSCREEN_MAKECONSTSTR1(x) #x
|
||||
#define MAXSCREEN_MAKECONSTSTR2(x) MAXSCREEN_MAKECONSTSTR1(x)
|
||||
|
||||
#define MAXSCREEN_FAILED_TXT "Failed at [" \
|
||||
MAXSCREEN_MAKECONSTSTR2(__LINE__) ":" __FILE__ "] to allocate object: "
|
||||
|
||||
#define _MAXSCREENSALLOCF(o,size,fatal) \
|
||||
do { \
|
||||
if (!o) { \
|
||||
o = xalloc((size) * sizeof(*(o))); \
|
||||
if (o) memset(o, 0, (size) * sizeof(*(o))); \
|
||||
if (!o && fatal) FatalError(MAXSCREEN_FAILED_TXT #o); \
|
||||
} \
|
||||
} while (0)
|
||||
#define _MAXSCREENSALLOCR(o,size,retval) \
|
||||
do { \
|
||||
if (!o) { \
|
||||
o = xalloc((size) * sizeof(*(o))); \
|
||||
if (o) memset(o, 0, (size) * sizeof(*(o))); \
|
||||
if (!o) return retval; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MAXSCREENSFREE(o) \
|
||||
do { \
|
||||
if (o) xfree(o); \
|
||||
o = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define MAXSCREENSALLOC(o) _MAXSCREENSALLOCF(o,MAXSCREENS, 0)
|
||||
#define MAXSCREENSALLOC_FATAL(o) _MAXSCREENSALLOCF(o,MAXSCREENS, 1)
|
||||
#define MAXSCREENSALLOC_RETURN(o,r) _MAXSCREENSALLOCR(o,MAXSCREENS, (r))
|
||||
#define MAXSCREENSALLOCPLUSONE(o) _MAXSCREENSALLOCF(o,MAXSCREENS+1,0)
|
||||
#define MAXSCREENSALLOCPLUSONE_FATAL(o) _MAXSCREENSALLOCF(o,MAXSCREENS+1,1)
|
||||
#define MAXSCREENSCALLOC(o,m) _MAXSCREENSALLOCF(o,MAXSCREENS*(m),0)
|
||||
#define MAXSCREENSCALLOC_FATAL(o,m) _MAXSCREENSALLOCF(o,MAXSCREENS*(m),1)
|
||||
#endif
|
||||
|
||||
#endif /* DMX_H */
|
||||
602
hw/dmx/dmx_glxvisuals.c
Normal file
602
hw/dmx/dmx_glxvisuals.c
Normal file
@@ -0,0 +1,602 @@
|
||||
/*
|
||||
** License Applicability. Except to the extent portions of this file are
|
||||
** made subject to an alternative license as permitted in the SGI Free
|
||||
** Software License B, Version 1.1 (the "License"), the contents of this
|
||||
** file are subject only to the provisions of the License. You may not use
|
||||
** this file except in compliance with the License. You may obtain a copy
|
||||
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
|
||||
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
|
||||
**
|
||||
** http://oss.sgi.com/projects/FreeB
|
||||
**
|
||||
** Note that, as provided in the License, the Software is distributed on an
|
||||
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
|
||||
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
|
||||
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
|
||||
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
**
|
||||
** Original Code. The Original Code is: OpenGL Sample Implementation,
|
||||
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
|
||||
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
|
||||
** Copyright in any portions created by third parties is as indicated
|
||||
** elsewhere herein. All Rights Reserved.
|
||||
**
|
||||
** Additional Notice Provisions: The application programming interfaces
|
||||
** established by SGI in conjunction with the Original Code are The
|
||||
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
|
||||
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
|
||||
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
|
||||
** Window System(R) (Version 1.3), released October 19, 1998. This software
|
||||
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
|
||||
** published by SGI, but has not been independently verified as being
|
||||
** compliant with the OpenGL(R) version 1.2.1 Specification.
|
||||
**
|
||||
*/
|
||||
|
||||
#include "dmx.h"
|
||||
#include <GL/glx.h>
|
||||
#include <GL/glxproto.h>
|
||||
#include "Xext.h"
|
||||
#include "extutil.h"
|
||||
|
||||
#include "dmx_glxvisuals.h"
|
||||
|
||||
__GLXvisualConfig *GetGLXVisualConfigs(Display *dpy, int screen, int *nconfigs)
|
||||
{
|
||||
xGLXGetVisualConfigsReq *req;
|
||||
xGLXGetVisualConfigsReply reply;
|
||||
__GLXvisualConfig *config, *configs;
|
||||
GLint i, j, nvisuals, nprops;
|
||||
INT32 *props, *p;
|
||||
int majorOpcode, dummy;
|
||||
int num_good_visuals;
|
||||
|
||||
if (!XQueryExtension(dpy, "GLX", &majorOpcode, &dummy, &dummy)) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Send the glXGetVisualConfigs request */
|
||||
LockDisplay(dpy);
|
||||
GetReq(GLXGetVisualConfigs,req);
|
||||
req->reqType = majorOpcode;
|
||||
req->glxCode = X_GLXGetVisualConfigs;
|
||||
req->screen = screen;
|
||||
if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
|
||||
/* Something is busted. Punt. */
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nvisuals = (int)reply.numVisuals;
|
||||
if (!nvisuals) {
|
||||
/* This screen does not support GL rendering */
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check number of properties per visual */
|
||||
nprops = (int)reply.numProps;
|
||||
if (nprops < __GLX_MIN_CONFIG_PROPS) {
|
||||
/* Huh? Not in protocol defined limits. Punt */
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
props = (INT32*) Xmalloc(nprops * __GLX_SIZE_CARD32);
|
||||
if (!props) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate memory for our config structure */
|
||||
config = (__GLXvisualConfig*)
|
||||
Xmalloc(nvisuals * sizeof(__GLXvisualConfig));
|
||||
if (!config) {
|
||||
Xfree(props);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
memset(config, 0, nvisuals * sizeof(__GLXvisualConfig));
|
||||
configs = config;
|
||||
num_good_visuals = 0;
|
||||
|
||||
/* Convert config structure into our format */
|
||||
for (i=0; i<nvisuals; i++) {
|
||||
|
||||
/* Read config structure */
|
||||
_XRead(dpy, (char *)props, (nprops * __GLX_SIZE_CARD32));
|
||||
|
||||
/* fill in default values */
|
||||
config->visualRating = GLX_NONE_EXT;
|
||||
config->transparentPixel = GLX_NONE_EXT;
|
||||
|
||||
/* Copy in the first set of properties */
|
||||
config->vid = props[0];
|
||||
config->class = props[1];
|
||||
|
||||
config->rgba = (Bool) props[2];
|
||||
|
||||
config->redSize = props[3];
|
||||
config->greenSize = props[4];
|
||||
config->blueSize = props[5];
|
||||
config->alphaSize = props[6];
|
||||
|
||||
config->accumRedSize = props[7];
|
||||
config->accumGreenSize = props[8];
|
||||
config->accumBlueSize = props[9];
|
||||
config->accumAlphaSize = props[10];
|
||||
|
||||
config->doubleBuffer = (Bool) props[11];
|
||||
config->stereo = (Bool) props[12];
|
||||
|
||||
config->bufferSize = props[13];
|
||||
config->depthSize = props[14];
|
||||
config->stencilSize = props[15];
|
||||
|
||||
config->auxBuffers = props[16];
|
||||
config->level = props[17];
|
||||
|
||||
/* Process remaining properties */
|
||||
p = &props[18];
|
||||
for (j=__GLX_MIN_CONFIG_PROPS; j<nprops; j+=2) {
|
||||
int property = *p++;
|
||||
int value = *p++;
|
||||
|
||||
switch (property) {
|
||||
case GLX_SAMPLES_SGIS:
|
||||
config->multiSampleSize = value;
|
||||
break;
|
||||
case GLX_SAMPLE_BUFFERS_SGIS:
|
||||
config->nMultiSampleBuffers = value;
|
||||
break;
|
||||
|
||||
case GLX_TRANSPARENT_TYPE_EXT:
|
||||
config->transparentPixel = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_INDEX_VALUE_EXT:
|
||||
config->transparentIndex = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_RED_VALUE_EXT:
|
||||
config->transparentRed = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_GREEN_VALUE_EXT:
|
||||
config->transparentGreen = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_BLUE_VALUE_EXT:
|
||||
config->transparentBlue = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
|
||||
config->transparentAlpha = value;
|
||||
break;
|
||||
|
||||
case GLX_VISUAL_CAVEAT_EXT:
|
||||
config->visualRating = value;
|
||||
break;
|
||||
|
||||
/* visualSelectGroup is an internal used property */
|
||||
case GLX_VISUAL_SELECT_GROUP_SGIX:
|
||||
config->visualSelectGroup = value;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Ignore properties we don't recognize */
|
||||
break;
|
||||
}
|
||||
} /* for j */
|
||||
|
||||
/*
|
||||
// filter out overlay visuals (dmx does not support overlays)
|
||||
*/
|
||||
if (config->level == 0) {
|
||||
config++;
|
||||
num_good_visuals++;
|
||||
}
|
||||
|
||||
} /* for i */
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
|
||||
nvisuals = num_good_visuals;
|
||||
|
||||
config = configs;
|
||||
for (i=0; i<nvisuals; i++) {
|
||||
/* XXX hack to fill-in mask info (need a better way to do this) */
|
||||
{
|
||||
XVisualInfo *vis, template;
|
||||
int n;
|
||||
|
||||
template.screen = screen;
|
||||
template.visualid = config->vid;
|
||||
vis = XGetVisualInfo(dpy, VisualScreenMask|VisualIDMask,
|
||||
&template, &n);
|
||||
|
||||
if (vis != NULL) {
|
||||
config->redMask = vis->red_mask;
|
||||
config->greenMask = vis->green_mask;
|
||||
config->blueMask = vis->blue_mask;
|
||||
config->alphaMask = 0; /* XXX */
|
||||
free(vis);
|
||||
}
|
||||
}
|
||||
config++;
|
||||
} /* for i */
|
||||
|
||||
XFree(props);
|
||||
SyncHandle();
|
||||
|
||||
*nconfigs = nvisuals;
|
||||
return( configs );
|
||||
}
|
||||
|
||||
|
||||
__GLXFBConfig *GetGLXFBConfigs(Display *dpy, int glxMajorOpcode, int *nconfigs)
|
||||
{
|
||||
xGLXGetFBConfigsReq *req;
|
||||
xGLXGetFBConfigsReply reply;
|
||||
__GLXFBConfig *config, *fbconfigs;
|
||||
GLint i, j, numFBConfigs, numAttribs;
|
||||
INT32 *attrs, *p;
|
||||
int screen = DefaultScreen( dpy );
|
||||
int numValidConfigs = 0;
|
||||
|
||||
/* Send the glXGetFBConfigs request */
|
||||
LockDisplay(dpy);
|
||||
GetReq(GLXGetFBConfigs, req);
|
||||
req->reqType = glxMajorOpcode;
|
||||
req->glxCode = X_GLXGetFBConfigs;
|
||||
req->screen = screen;
|
||||
|
||||
*nconfigs = 0;
|
||||
|
||||
if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
|
||||
/* Something is busted. Punt. */
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
numFBConfigs = (int)reply.numFBConfigs;
|
||||
if (!numFBConfigs) {
|
||||
/* This screen does not support GL rendering */
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
numAttribs = (int)reply.numAttribs;
|
||||
if (!numAttribs) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
attrs = (INT32*) Xmalloc(2*numAttribs * __GLX_SIZE_CARD32);
|
||||
if (!attrs) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate memory for our config structure */
|
||||
config = (__GLXFBConfig*)
|
||||
Xmalloc(numFBConfigs * sizeof(__GLXFBConfig));
|
||||
if (!config) {
|
||||
Xfree(attrs);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
memset(config, 0, numFBConfigs * sizeof(__GLXFBConfig));
|
||||
fbconfigs = config;
|
||||
|
||||
/* Convert attribute list into our format */
|
||||
for (i=0; i<numFBConfigs; i++) {
|
||||
|
||||
/* Fill in default properties */
|
||||
config->transparentType = GLX_NONE_EXT;
|
||||
config->visualCaveat = GLX_NONE_EXT;
|
||||
config->minRed = 0.;
|
||||
config->maxRed = 1.;
|
||||
config->minGreen = 0.;
|
||||
config->maxGreen = 1.;
|
||||
config->minBlue = 0.;
|
||||
config->maxBlue = 1.;
|
||||
config->minAlpha = 0.;
|
||||
config->maxAlpha = 1.;
|
||||
|
||||
/* Read attribute list */
|
||||
_XRead(dpy, (char *)attrs, (2*numAttribs * __GLX_SIZE_CARD32));
|
||||
|
||||
p = attrs;
|
||||
for (j=0; j<numAttribs; j++) {
|
||||
int attribute = *p++;
|
||||
int value = *p++;
|
||||
|
||||
switch (attribute) {
|
||||
/* core attributes */
|
||||
case GLX_FBCONFIG_ID:
|
||||
config->id = value;
|
||||
break;
|
||||
case GLX_BUFFER_SIZE:
|
||||
config->indexBits = value;
|
||||
break;
|
||||
case GLX_LEVEL:
|
||||
config->level = value;
|
||||
break;
|
||||
case GLX_DOUBLEBUFFER:
|
||||
config->doubleBufferMode = value;
|
||||
break;
|
||||
case GLX_STEREO:
|
||||
config->stereoMode = value;
|
||||
break;
|
||||
case GLX_AUX_BUFFERS:
|
||||
config->maxAuxBuffers = value;
|
||||
break;
|
||||
case GLX_RED_SIZE:
|
||||
config->redBits = value;
|
||||
break;
|
||||
case GLX_GREEN_SIZE:
|
||||
config->greenBits = value;
|
||||
break;
|
||||
case GLX_BLUE_SIZE:
|
||||
config->blueBits = value;
|
||||
break;
|
||||
case GLX_ALPHA_SIZE:
|
||||
config->alphaBits = value;
|
||||
break;
|
||||
case GLX_DEPTH_SIZE:
|
||||
config->depthBits = value;
|
||||
break;
|
||||
case GLX_STENCIL_SIZE:
|
||||
config->stencilBits = value;
|
||||
break;
|
||||
case GLX_ACCUM_RED_SIZE:
|
||||
config->accumRedBits = value;
|
||||
break;
|
||||
case GLX_ACCUM_GREEN_SIZE:
|
||||
config->accumGreenBits = value;
|
||||
break;
|
||||
case GLX_ACCUM_BLUE_SIZE:
|
||||
config->accumBlueBits = value;
|
||||
break;
|
||||
case GLX_ACCUM_ALPHA_SIZE:
|
||||
config->accumAlphaBits = value;
|
||||
break;
|
||||
case GLX_RENDER_TYPE:
|
||||
config->renderType = value;
|
||||
break;
|
||||
case GLX_DRAWABLE_TYPE:
|
||||
config->drawableType = value;
|
||||
break;
|
||||
case GLX_X_VISUAL_TYPE:
|
||||
config->visualType = value;
|
||||
break;
|
||||
case GLX_CONFIG_CAVEAT:
|
||||
config->visualCaveat = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_TYPE:
|
||||
config->transparentType = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_INDEX_VALUE:
|
||||
config->transparentIndex = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_RED_VALUE:
|
||||
config->transparentRed = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_GREEN_VALUE:
|
||||
config->transparentGreen = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_BLUE_VALUE:
|
||||
config->transparentBlue = value;
|
||||
break;
|
||||
case GLX_TRANSPARENT_ALPHA_VALUE:
|
||||
config->transparentAlpha = value;
|
||||
break;
|
||||
case GLX_MAX_PBUFFER_WIDTH:
|
||||
config->maxPbufferWidth = value;
|
||||
break;
|
||||
case GLX_MAX_PBUFFER_HEIGHT:
|
||||
config->maxPbufferHeight = value;
|
||||
break;
|
||||
case GLX_MAX_PBUFFER_PIXELS:
|
||||
config->maxPbufferPixels = value;
|
||||
break;
|
||||
case GLX_VISUAL_ID:
|
||||
config->associatedVisualId = value;
|
||||
break;
|
||||
|
||||
/* visualSelectGroup is an internal used property */
|
||||
case GLX_VISUAL_SELECT_GROUP_SGIX:
|
||||
config->visualSelectGroup = value;
|
||||
break;
|
||||
|
||||
/* SGIS_multisample attributes */
|
||||
case GLX_SAMPLES_SGIS:
|
||||
config->multiSampleSize = value;
|
||||
break;
|
||||
case GLX_SAMPLE_BUFFERS_SGIS:
|
||||
config->nMultiSampleBuffers = value;
|
||||
break;
|
||||
|
||||
/* SGIX_pbuffer specific attributes */
|
||||
case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
|
||||
config->optimalPbufferWidth = value;
|
||||
break;
|
||||
case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
|
||||
config->optimalPbufferHeight = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Ignore attributes we don't recognize */
|
||||
break;
|
||||
}
|
||||
} /* for j */
|
||||
|
||||
/* Fill in derived values */
|
||||
config->screen = screen;
|
||||
|
||||
config->rgbMode = config->renderType & GLX_RGBA_BIT;
|
||||
config->colorIndexMode = !config->rgbMode;
|
||||
|
||||
config->haveAccumBuffer =
|
||||
config->accumRedBits > 0 ||
|
||||
config->accumGreenBits > 0 ||
|
||||
config->accumBlueBits > 0;
|
||||
/* Can't have alpha without color */
|
||||
|
||||
config->haveDepthBuffer = config->depthBits > 0;
|
||||
config->haveStencilBuffer = config->stencilBits > 0;
|
||||
|
||||
/* overlay visuals are not valid for now */
|
||||
if (!config->level) {
|
||||
config++;
|
||||
numValidConfigs++;
|
||||
}
|
||||
|
||||
} /* for i */
|
||||
UnlockDisplay(dpy);
|
||||
|
||||
config = fbconfigs;
|
||||
for (i=0; i<numValidConfigs; i++) {
|
||||
|
||||
/* XXX hack to fill-in mask info (need a better way to do this) */
|
||||
if (config->associatedVisualId != 0) {
|
||||
XVisualInfo *vis, template;
|
||||
int n;
|
||||
|
||||
template.screen = screen;
|
||||
template.visualid = config->associatedVisualId;
|
||||
vis = XGetVisualInfo(dpy, VisualScreenMask|VisualIDMask,
|
||||
&template, &n);
|
||||
|
||||
if (vis != NULL) {
|
||||
config->redMask = (GLuint)vis->red_mask;
|
||||
config->greenMask = (GLuint)vis->green_mask;
|
||||
config->blueMask = (GLuint)vis->blue_mask;
|
||||
config->alphaMask = 0; /* XXX */
|
||||
free(vis);
|
||||
}
|
||||
}
|
||||
|
||||
config++;
|
||||
} /* for i */
|
||||
|
||||
XFree(attrs);
|
||||
SyncHandle();
|
||||
|
||||
*nconfigs = numValidConfigs;
|
||||
return fbconfigs;
|
||||
}
|
||||
|
||||
__GLXvisualConfig *
|
||||
GetGLXVisualConfigsFromFBConfigs(__GLXFBConfig *fbconfigs, int nfbconfigs,
|
||||
XVisualInfo *visuals, int nvisuals,
|
||||
__GLXvisualConfig *glxConfigs, int nGlxConfigs,
|
||||
int *nconfigs)
|
||||
{
|
||||
__GLXvisualConfig *configs = NULL;
|
||||
int i;
|
||||
|
||||
if (!fbconfigs || !nfbconfigs || !nconfigs) return(NULL);
|
||||
*nconfigs = 0;
|
||||
|
||||
/* Allocate memory for our config structure */
|
||||
configs = (__GLXvisualConfig*)
|
||||
Xmalloc(nfbconfigs * sizeof(__GLXvisualConfig));
|
||||
if (!configs) {
|
||||
return NULL;
|
||||
}
|
||||
memset(configs, 0, nfbconfigs * sizeof(__GLXvisualConfig));
|
||||
|
||||
for (i=0; i<nfbconfigs; i++) {
|
||||
__GLXFBConfig *fbcfg = &fbconfigs[i];
|
||||
|
||||
if (fbcfg->associatedVisualId > 0) {
|
||||
__GLXvisualConfig *cfg = configs + (*nconfigs);
|
||||
int j;
|
||||
XVisualInfo *vinfo = NULL;
|
||||
|
||||
for (j=0; j<nvisuals; j++) {
|
||||
if (visuals[j].visualid == fbcfg->associatedVisualId) {
|
||||
vinfo = &visuals[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!vinfo) continue;
|
||||
|
||||
/* skip 16 bit colormap visuals */
|
||||
if (vinfo->depth == 16 &&
|
||||
vinfo->class != TrueColor &&
|
||||
vinfo->class != DirectColor ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(*nconfigs)++;
|
||||
|
||||
/*
|
||||
* if the same visualid exists in the glx configs,
|
||||
* copy the glx attributes from the glx config
|
||||
*/
|
||||
for (j=0; j<nGlxConfigs; j++) {
|
||||
if (glxConfigs[j].vid == vinfo->visualid)
|
||||
break;
|
||||
}
|
||||
if (j < nGlxConfigs) {
|
||||
memcpy(cfg, &glxConfigs[j], sizeof(__GLXvisualConfig) );
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* make glx attributes from the FB config attributes
|
||||
*/
|
||||
cfg->vid = fbcfg->associatedVisualId;
|
||||
cfg->class = vinfo->class;
|
||||
cfg->rgba = !(fbcfg->renderType & GLX_COLOR_INDEX_BIT_SGIX);
|
||||
cfg->redSize = fbcfg->redBits;
|
||||
cfg->greenSize = fbcfg->greenBits;
|
||||
cfg->blueSize = fbcfg->blueBits;
|
||||
cfg->alphaSize = fbcfg->alphaBits;
|
||||
cfg->redMask = fbcfg->redMask;
|
||||
cfg->greenMask = fbcfg->greenMask;
|
||||
cfg->blueMask = fbcfg->blueMask;
|
||||
cfg->alphaMask = fbcfg->alphaMask;
|
||||
cfg->accumRedSize = fbcfg->accumRedBits;
|
||||
cfg->accumGreenSize = fbcfg->accumGreenBits;
|
||||
cfg->accumBlueSize = fbcfg->accumBlueBits;
|
||||
cfg->accumAlphaSize = fbcfg->accumAlphaBits;
|
||||
cfg->doubleBuffer = fbcfg->doubleBufferMode;
|
||||
cfg->stereo = fbcfg->stereoMode;
|
||||
if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
|
||||
cfg->bufferSize = (fbcfg->rgbMode ? (fbcfg->redBits +
|
||||
fbcfg->greenBits +
|
||||
fbcfg->blueBits +
|
||||
fbcfg->alphaBits)
|
||||
: fbcfg->indexBits );
|
||||
}
|
||||
else {
|
||||
cfg->bufferSize = vinfo->depth;
|
||||
}
|
||||
cfg->depthSize = fbcfg->depthBits;
|
||||
cfg->stencilSize = fbcfg->stencilBits;
|
||||
cfg->auxBuffers = fbcfg->maxAuxBuffers;
|
||||
cfg->level = fbcfg->level;
|
||||
cfg->visualRating = fbcfg->visualCaveat;
|
||||
cfg->transparentPixel = fbcfg->transparentType;
|
||||
cfg->transparentRed = fbcfg->transparentRed;
|
||||
cfg->transparentGreen = fbcfg->transparentGreen;
|
||||
cfg->transparentBlue = fbcfg->transparentBlue;
|
||||
cfg->transparentAlpha = fbcfg->transparentAlpha;
|
||||
cfg->transparentIndex = fbcfg->transparentIndex;
|
||||
cfg->multiSampleSize = fbcfg->multiSampleSize;
|
||||
cfg->nMultiSampleBuffers = fbcfg->nMultiSampleBuffers;
|
||||
cfg->visualSelectGroup = fbcfg->visualSelectGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return( configs );
|
||||
}
|
||||
|
||||
64
hw/dmx/dmx_glxvisuals.h
Normal file
64
hw/dmx/dmx_glxvisuals.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
** License Applicability. Except to the extent portions of this file are
|
||||
** made subject to an alternative license as permitted in the SGI Free
|
||||
** Software License B, Version 1.1 (the "License"), the contents of this
|
||||
** file are subject only to the provisions of the License. You may not use
|
||||
** this file except in compliance with the License. You may obtain a copy
|
||||
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
|
||||
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
|
||||
**
|
||||
** http://oss.sgi.com/projects/FreeB
|
||||
**
|
||||
** Note that, as provided in the License, the Software is distributed on an
|
||||
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
|
||||
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
|
||||
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
|
||||
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
**
|
||||
** Original Code. The Original Code is: OpenGL Sample Implementation,
|
||||
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
|
||||
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
|
||||
** Copyright in any portions created by third parties is as indicated
|
||||
** elsewhere herein. All Rights Reserved.
|
||||
**
|
||||
** Additional Notice Provisions: The application programming interfaces
|
||||
** established by SGI in conjunction with the Original Code are The
|
||||
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
|
||||
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
|
||||
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
|
||||
** Window System(R) (Version 1.3), released October 19, 1998. This software
|
||||
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
|
||||
** published by SGI, but has not been independently verified as being
|
||||
** compliant with the OpenGL(R) version 1.2.1 Specification.
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef _GLXVISUALS_H
|
||||
#define _GLXVISUALS_H
|
||||
|
||||
#include <GL/glxint.h>
|
||||
|
||||
/** GLX Visual private area. */
|
||||
typedef struct {
|
||||
int x_visual_depth;
|
||||
int x_visual_class;
|
||||
} dmxGlxVisualPrivate;
|
||||
|
||||
__GLXvisualConfig *GetGLXVisualConfigs(Display *dpy,
|
||||
int screen,
|
||||
int *nconfigs);
|
||||
|
||||
__GLXFBConfig *GetGLXFBConfigs(Display *dpy,
|
||||
int glxMajorOpcode,
|
||||
int *nconfigs);
|
||||
|
||||
__GLXvisualConfig *GetGLXVisualConfigsFromFBConfigs(__GLXFBConfig *fbconfigs,
|
||||
int nfbconfigs,
|
||||
XVisualInfo *visuals,
|
||||
int nvisuals,
|
||||
__GLXvisualConfig
|
||||
*glxConfigs,
|
||||
int nGlxConfigs,
|
||||
int *nconfigs);
|
||||
|
||||
#endif
|
||||
209
hw/dmx/dmxcb.c
Normal file
209
hw/dmx/dmxcb.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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 code queries and modifies the connection block. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxcb.h"
|
||||
#include "dmxinput.h"
|
||||
#include "dmxlog.h"
|
||||
|
||||
extern char *ConnectionInfo;
|
||||
extern int connBlockScreenStart;
|
||||
extern int PanoramiXPixWidth;
|
||||
extern int PanoramiXPixHeight;
|
||||
extern int PanoramiXNumScreens;
|
||||
|
||||
int dmxGlobalWidth, dmxGlobalHeight;
|
||||
|
||||
/** We may want the wall dimensions to be different from the bounding
|
||||
* box dimensions that Xinerama computes, so save those and update them
|
||||
* here.
|
||||
*/
|
||||
void dmxSetWidthHeight(int width, int height)
|
||||
{
|
||||
dmxGlobalWidth = width;
|
||||
dmxGlobalHeight = height;
|
||||
}
|
||||
|
||||
/** Computes the global bounding box for DMX. This may be larger than
|
||||
* the one computed by Xinerama because of the DMX configuration
|
||||
* file. */
|
||||
void dmxComputeWidthHeight(DMXRecomputeFlag flag)
|
||||
{
|
||||
int i;
|
||||
DMXScreenInfo *dmxScreen;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
/* Don't use root* here because this is
|
||||
* the global bounding box. */
|
||||
dmxScreen = &dmxScreens[i];
|
||||
if (w < dmxScreen->scrnWidth + dmxScreen->rootXOrigin)
|
||||
w = dmxScreen->scrnWidth + dmxScreen->rootXOrigin;
|
||||
if (h < dmxScreen->scrnHeight + dmxScreen->rootYOrigin)
|
||||
h = dmxScreen->scrnHeight + dmxScreen->rootYOrigin;
|
||||
}
|
||||
if (!dmxGlobalWidth && !dmxGlobalHeight) {
|
||||
dmxLog(dmxInfo, "Using %dx%d as global bounding box\n", w, h);
|
||||
} else {
|
||||
switch (flag) {
|
||||
case DMX_NO_RECOMPUTE_BOUNDING_BOX:
|
||||
dmxLog(dmxInfo,
|
||||
"Using old bounding box (%dx%d) instead of new (%dx%d)\n",
|
||||
dmxGlobalWidth, dmxGlobalHeight, w, h);
|
||||
w = dmxGlobalWidth;
|
||||
h = dmxGlobalHeight;
|
||||
break;
|
||||
case DMX_RECOMPUTE_BOUNDING_BOX:
|
||||
dmxLog(dmxInfo,
|
||||
"Using %dx%d as global bounding box, instead of %dx%d\n",
|
||||
w, h, dmxGlobalWidth, dmxGlobalHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dmxGlobalWidth = w;
|
||||
dmxGlobalHeight = h;
|
||||
}
|
||||
|
||||
/** A callback routine that hooks into Xinerama and provides a
|
||||
* convenient place to print summary log information during server
|
||||
* startup. This routine does not modify any values. */
|
||||
void dmxConnectionBlockCallback(void)
|
||||
{
|
||||
xWindowRoot *root = (xWindowRoot *)(ConnectionInfo+connBlockScreenStart);
|
||||
int offset = connBlockScreenStart + sizeof(xWindowRoot);
|
||||
int i;
|
||||
Bool *found = NULL;
|
||||
|
||||
MAXSCREENSALLOC(found);
|
||||
if (!found)
|
||||
dmxLog(dmxFatal, "dmxConnectionBlockCallback: out of memory\n");
|
||||
|
||||
dmxLog(dmxInfo, "===== Start of Summary =====\n");
|
||||
if (!noPanoramiXExtension) {
|
||||
if (dmxGlobalWidth && dmxGlobalHeight
|
||||
&& (dmxGlobalWidth != PanoramiXPixWidth
|
||||
|| dmxGlobalHeight != PanoramiXPixHeight)) {
|
||||
dmxLog(dmxInfo,
|
||||
"Changing Xinerama dimensions from %d %d to %d %d\n",
|
||||
PanoramiXPixWidth, PanoramiXPixHeight,
|
||||
dmxGlobalWidth, dmxGlobalHeight);
|
||||
PanoramiXPixWidth = root->pixWidth = dmxGlobalWidth;
|
||||
PanoramiXPixHeight = root->pixHeight = dmxGlobalHeight;
|
||||
} else {
|
||||
dmxGlobalWidth = PanoramiXPixWidth;
|
||||
dmxGlobalHeight = PanoramiXPixHeight;
|
||||
}
|
||||
dmxLog(dmxInfo, "%d screens configured with Xinerama (%d %d)\n",
|
||||
PanoramiXNumScreens, PanoramiXPixWidth, PanoramiXPixHeight);
|
||||
for (i = 0; i < PanoramiXNumScreens; i++) found[i] = FALSE;
|
||||
} else {
|
||||
/* This never happens because we're
|
||||
* either called from a Xinerama
|
||||
* callback or during reconfiguration
|
||||
* (which only works with Xinerama on).
|
||||
* In any case, be reasonable. */
|
||||
dmxLog(dmxInfo, "%d screens configured (%d %d)\n",
|
||||
screenInfo.numScreens, root->pixWidth, root->pixHeight);
|
||||
}
|
||||
|
||||
for (i = 0; i < root->nDepths; i++) {
|
||||
xDepth *depth = (xDepth *)(ConnectionInfo + offset);
|
||||
int voffset = offset + sizeof(xDepth);
|
||||
xVisualType *visual = (xVisualType *)(ConnectionInfo + voffset);
|
||||
int j;
|
||||
|
||||
dmxLog(dmxInfo, "%d visuals at depth %d:\n",
|
||||
depth->nVisuals, depth->depth);
|
||||
for (j = 0; j < depth->nVisuals; j++, visual++) {
|
||||
XVisualInfo vi;
|
||||
|
||||
vi.visual = NULL;
|
||||
vi.visualid = visual->visualID;
|
||||
vi.screen = 0;
|
||||
vi.depth = depth->depth;
|
||||
vi.class = visual->class;
|
||||
vi.red_mask = visual->redMask;
|
||||
vi.green_mask = visual->greenMask;
|
||||
vi.blue_mask = visual->blueMask;
|
||||
vi.colormap_size = visual->colormapEntries;
|
||||
vi.bits_per_rgb = visual->bitsPerRGB;
|
||||
dmxLogVisual(NULL, &vi, 0);
|
||||
|
||||
if (!noPanoramiXExtension) {
|
||||
int k;
|
||||
for (k = 0; k < PanoramiXNumScreens; k++) {
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[k];
|
||||
|
||||
if (dmxScreen->beDisplay) {
|
||||
XVisualInfo *pvi =
|
||||
&dmxScreen->beVisuals[dmxScreen->beDefVisualIndex];
|
||||
if (pvi->depth == depth->depth &&
|
||||
pvi->class == visual->class)
|
||||
found[k] = TRUE;
|
||||
} else {
|
||||
/* Screen #k is detatched, so it always succeeds */
|
||||
found[k] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
offset = voffset + depth->nVisuals * sizeof(xVisualType);
|
||||
}
|
||||
|
||||
dmxInputLogDevices();
|
||||
dmxLog(dmxInfo, "===== End of Summary =====\n");
|
||||
|
||||
if (!noPanoramiXExtension) {
|
||||
Bool fatal = FALSE;
|
||||
for (i = 0; i < PanoramiXNumScreens; i++) {
|
||||
fatal |= !found[i];
|
||||
if (!found[i]) {
|
||||
dmxLog(dmxError,
|
||||
"The default visual for screen #%d does not match "
|
||||
"any of the\n", i);
|
||||
dmxLog(dmxError,
|
||||
"consolidated visuals from Xinerama (listed above)\n");
|
||||
}
|
||||
}
|
||||
if (fatal)
|
||||
dmxLog(dmxFatal,
|
||||
"dmxConnectionBlockCallback: invalid screen(s) found");
|
||||
}
|
||||
MAXSCREENSFREE(found);
|
||||
}
|
||||
54
hw/dmx/dmxcb.h
Normal file
54
hw/dmx/dmxcb.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001,2002 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
|
||||
* Header file for connection block functions. \see dmxcb.c.
|
||||
*/
|
||||
|
||||
#ifndef _DMXCB_H_
|
||||
#define _DMXCB_H_
|
||||
/** The cursor position, in global coordinates. */
|
||||
extern int dmxGlobalWidth, dmxGlobalHeight;
|
||||
|
||||
/** #dmxComputeWidthHeight can either recompute the global bounding box
|
||||
* or not. */
|
||||
typedef enum {
|
||||
DMX_RECOMPUTE_BOUNDING_BOX,
|
||||
DMX_NO_RECOMPUTE_BOUNDING_BOX
|
||||
} DMXRecomputeFlag;
|
||||
|
||||
extern void dmxSetWidthHeight(int width, int height);
|
||||
extern void dmxComputeWidthHeight(DMXRecomputeFlag flag);
|
||||
extern void dmxConnectionBlockCallback(void);
|
||||
#endif
|
||||
150
hw/dmx/dmxclient.h
Normal file
150
hw/dmx/dmxclient.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright (c) 1995 X Consortium
|
||||
* Copyright 2004 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 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, THE X CONSORTIUM,
|
||||
* 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.
|
||||
*
|
||||
* Except as contained in this notice, the name of the X Consortium
|
||||
* shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written
|
||||
* authorization from the X Consortium.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Derived from hw/xnest/Xnest.h by Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* This file includes all client-side include files with proper wrapping.
|
||||
*/
|
||||
|
||||
#ifndef _DMXCLIENT_H_
|
||||
#define _DMXCLIENT_H_
|
||||
|
||||
#define GC XlibGC
|
||||
|
||||
#ifdef _XSERVER64
|
||||
#define DMX64
|
||||
#undef _XSERVER64
|
||||
typedef unsigned long XID64;
|
||||
typedef unsigned long Mask64;
|
||||
typedef unsigned long Atom64;
|
||||
typedef unsigned long VisualID64;
|
||||
typedef unsigned long Time64;
|
||||
#define XID XID64
|
||||
#define Mask Mask64
|
||||
#define Atom Atom64
|
||||
#define VisualID VisualID64
|
||||
#define Time Time64
|
||||
typedef XID Window64;
|
||||
typedef XID Drawable64;
|
||||
typedef XID Font64;
|
||||
typedef XID Pixmap64;
|
||||
typedef XID Cursor64;
|
||||
typedef XID Colormap64;
|
||||
typedef XID GContext64;
|
||||
typedef XID KeySym64;
|
||||
#define Window Window64
|
||||
#define Drawable Drawable64
|
||||
#define Font Font64
|
||||
#define Pixmap Pixmap64
|
||||
#define Cursor Cursor64
|
||||
#define Colormap Colormap64
|
||||
#define GContext GContext64
|
||||
#define KeySym KeySym64
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xlibint.h> /* For _XExtension */
|
||||
#include <X11/X.h> /* from glxserver.h */
|
||||
#include <X11/Xmd.h> /* from glxserver.h */
|
||||
#include <X11/Xproto.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/Xmu/SysUtil.h> /* For XmuSnprintf */
|
||||
|
||||
#ifdef SHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
|
||||
#ifdef RENDER
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#undef PictFormatType
|
||||
#endif
|
||||
|
||||
#ifdef XKB
|
||||
#include <X11/extensions/XKB.h>
|
||||
#include <X11/extensions/XKBstr.h>
|
||||
#endif
|
||||
|
||||
#ifdef XINPUT
|
||||
#include <X11/extensions/XI.h>
|
||||
#endif
|
||||
|
||||
/* Always include these, since we query them even if we don't export XINPUT. */
|
||||
#include <X11/extensions/XInput.h> /* For XDevice */
|
||||
#include <X11/extensions/Xext.h>
|
||||
|
||||
#undef GC
|
||||
|
||||
#ifdef DMX64
|
||||
#define _XSERVER64
|
||||
#undef XID
|
||||
#undef Mask
|
||||
#undef Atom
|
||||
#undef VisualID
|
||||
#undef Time
|
||||
#undef Window
|
||||
#undef Drawable
|
||||
#undef Font
|
||||
#undef Pixmap
|
||||
#undef Cursor
|
||||
#undef Colormap
|
||||
#undef GContext
|
||||
#undef KeySym
|
||||
#endif
|
||||
|
||||
/* These are in exglobals.h, but that conflicts with X11/extensions/XKBsrv.h */
|
||||
extern int ProximityIn;
|
||||
extern int ProximityOut;
|
||||
extern int DeviceValuator;
|
||||
extern int DeviceMotionNotify;
|
||||
extern int DeviceFocusIn;
|
||||
extern int DeviceFocusOut;
|
||||
extern int DeviceStateNotify;
|
||||
extern int DeviceMappingNotify;
|
||||
extern int ChangeDeviceNotify;
|
||||
|
||||
/* Some protocol gets included last, after undefines. */
|
||||
#include <X11/XKBlib.h>
|
||||
#ifdef XKB
|
||||
#include <X11/extensions/XKBproto.h>
|
||||
#define XKB_IN_SERVER
|
||||
#include <X11/extensions/XKBsrv.h>
|
||||
#undef XPointer
|
||||
#endif
|
||||
#include <X11/extensions/XIproto.h>
|
||||
|
||||
#endif
|
||||
216
hw/dmx/dmxcmap.c
Normal file
216
hw/dmx/dmxcmap.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Colormap support. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dmxcmap.h"
|
||||
#include "dmxvisual.h"
|
||||
|
||||
#include "micmap.h"
|
||||
|
||||
static int dmxInitColormapPrivateFunc(ColormapPtr pColormap)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool dmxAllocateColormapPrivates(ColormapPtr pColormap)
|
||||
{
|
||||
static unsigned long dmxColormapGeneration;
|
||||
dmxColormapPrivPtr pCmapPriv;
|
||||
|
||||
if (dmxColormapGeneration != serverGeneration) {
|
||||
if ((dmxColormapPrivateIndex
|
||||
= AllocateColormapPrivateIndex(dmxInitColormapPrivateFunc)) < 0)
|
||||
return FALSE;
|
||||
|
||||
dmxColormapGeneration = serverGeneration;
|
||||
}
|
||||
|
||||
pCmapPriv = (dmxColormapPrivPtr)xalloc(sizeof(*pCmapPriv));
|
||||
if (!pCmapPriv)
|
||||
return FALSE;
|
||||
pCmapPriv->cmap = (Colormap)0;
|
||||
|
||||
DMX_SET_COLORMAP_PRIV(pColormap, pCmapPriv);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Create \a pColormap on the back-end server. */
|
||||
Bool dmxBECreateColormap(ColormapPtr pColormap)
|
||||
{
|
||||
ScreenPtr pScreen = pColormap->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
|
||||
VisualPtr pVisual = pColormap->pVisual;
|
||||
Visual *visual = dmxLookupVisual(pScreen, pVisual);
|
||||
|
||||
pCmapPriv->cmap = XCreateColormap(dmxScreen->beDisplay,
|
||||
dmxScreen->scrnWin,
|
||||
visual,
|
||||
(pVisual->class & DynamicClass ?
|
||||
AllocAll : AllocNone));
|
||||
return (pCmapPriv->cmap != 0);
|
||||
}
|
||||
|
||||
/** Create colormap on back-end server associated with \a pColormap's
|
||||
* screen. */
|
||||
Bool dmxCreateColormap(ColormapPtr pColormap)
|
||||
{
|
||||
ScreenPtr pScreen = pColormap->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
Bool ret = TRUE;
|
||||
|
||||
if (!dmxAllocateColormapPrivates(pColormap))
|
||||
return FALSE;
|
||||
|
||||
if (dmxScreen->beDisplay) {
|
||||
if (!dmxBECreateColormap(pColormap))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
|
||||
if (pScreen->CreateColormap)
|
||||
ret = pScreen->CreateColormap(pColormap);
|
||||
DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Destroy \a pColormap on the back-end server. */
|
||||
Bool dmxBEFreeColormap(ColormapPtr pColormap)
|
||||
{
|
||||
ScreenPtr pScreen = pColormap->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
|
||||
|
||||
if (pCmapPriv->cmap) {
|
||||
XFreeColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
|
||||
pCmapPriv->cmap = (Colormap)0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** Destroy colormap on back-end server associated with \a pColormap's
|
||||
* screen. */
|
||||
void dmxDestroyColormap(ColormapPtr pColormap)
|
||||
{
|
||||
ScreenPtr pScreen = pColormap->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
|
||||
|
||||
if (dmxScreen->beDisplay)
|
||||
dmxBEFreeColormap(pColormap);
|
||||
xfree(pCmapPriv);
|
||||
DMX_SET_COLORMAP_PRIV(pColormap, NULL);
|
||||
|
||||
DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
|
||||
if (pScreen->DestroyColormap)
|
||||
pScreen->DestroyColormap(pColormap);
|
||||
DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen);
|
||||
}
|
||||
|
||||
/** Install colormap on back-end server associated with \a pColormap's
|
||||
* screen. */
|
||||
void dmxInstallColormap(ColormapPtr pColormap)
|
||||
{
|
||||
ScreenPtr pScreen = pColormap->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
|
||||
|
||||
DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
|
||||
if (pScreen->InstallColormap)
|
||||
pScreen->InstallColormap(pColormap);
|
||||
DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
|
||||
|
||||
if (dmxScreen->beDisplay) {
|
||||
XInstallColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/** Store colors in \a pColormap on back-end server associated with \a
|
||||
* pColormap's screen. */
|
||||
void dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem *pdef)
|
||||
{
|
||||
ScreenPtr pScreen = pColormap->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
|
||||
|
||||
if (dmxScreen->beDisplay && (pColormap->pVisual->class & DynamicClass)) {
|
||||
XColor *color = xalloc(sizeof(*color) * ndef);
|
||||
int i;
|
||||
|
||||
if (color) {
|
||||
for (i = 0; i < ndef; i++) {
|
||||
color[i].pixel = pdef[i].pixel;
|
||||
color[i].red = pdef[i].red;
|
||||
color[i].blue = pdef[i].blue;
|
||||
color[i].green = pdef[i].green;
|
||||
color[i].flags = pdef[i].flags;
|
||||
color[i].pad = pdef[i].pad;
|
||||
}
|
||||
XStoreColors(dmxScreen->beDisplay, pCmapPriv->cmap, color, ndef);
|
||||
xfree(color);
|
||||
} else { /* xalloc failed, so fallback */
|
||||
XColor c;
|
||||
for (i = 0; i < ndef; i++) {
|
||||
c.pixel = pdef[i].pixel;
|
||||
c.red = pdef[i].red;
|
||||
c.blue = pdef[i].blue;
|
||||
c.green = pdef[i].green;
|
||||
c.flags = pdef[i].flags;
|
||||
c.pad = pdef[i].pad;
|
||||
XStoreColor(dmxScreen->beDisplay, pCmapPriv->cmap, &c);
|
||||
}
|
||||
}
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
|
||||
if (pScreen->StoreColors)
|
||||
pScreen->StoreColors(pColormap, ndef, pdef);
|
||||
DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen);
|
||||
}
|
||||
|
||||
/** Create the DMX server's default colormap. */
|
||||
Bool dmxCreateDefColormap(ScreenPtr pScreen)
|
||||
{
|
||||
return miCreateDefColormap(pScreen);
|
||||
}
|
||||
71
hw/dmx/dmxcmap.h
Normal file
71
hw/dmx/dmxcmap.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Header file for colormap support. \see dmxcmap.c. */
|
||||
|
||||
#ifndef DMXCMAP_H
|
||||
#define DMXCMAP_H
|
||||
|
||||
#include "colormapst.h"
|
||||
|
||||
/** Colormap private area. */
|
||||
typedef struct _dmxColormapPriv {
|
||||
Colormap cmap;
|
||||
} dmxColormapPrivRec, *dmxColormapPrivPtr;
|
||||
|
||||
|
||||
extern Bool dmxCreateColormap(ColormapPtr pColormap);
|
||||
extern void dmxDestroyColormap(ColormapPtr pColormap);
|
||||
extern void dmxInstallColormap(ColormapPtr pColormap);
|
||||
extern void dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem *pdef);
|
||||
|
||||
extern Bool dmxCreateDefColormap(ScreenPtr pScreen);
|
||||
|
||||
extern Bool dmxBECreateColormap(ColormapPtr pColormap);
|
||||
extern Bool dmxBEFreeColormap(ColormapPtr pColormap);
|
||||
|
||||
/** Private index. \see dmxcmap.c \see dmxscrinit.c \see dmxwindow.c */
|
||||
extern int dmxColormapPrivateIndex;
|
||||
|
||||
/** Set colormap private structure. */
|
||||
#define DMX_SET_COLORMAP_PRIV(_pCMap, _pCMapPriv) \
|
||||
(_pCMap)->devPrivates[dmxColormapPrivateIndex].ptr \
|
||||
= (pointer)(_pCMapPriv);
|
||||
|
||||
/** Get colormap private structure. */
|
||||
#define DMX_GET_COLORMAP_PRIV(_pCMap) \
|
||||
(dmxColormapPrivPtr)(_pCMap)->devPrivates[dmxColormapPrivateIndex].ptr
|
||||
|
||||
#endif /* DMXCMAP_H */
|
||||
922
hw/dmx/dmxcursor.c
Normal file
922
hw/dmx/dmxcursor.c
Normal file
@@ -0,0 +1,922 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* David H. Dawes <dawes@xfree86.org>
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* This file contains code than supports cursor movement, including the
|
||||
* code that initializes and reinitializes the screen positions and
|
||||
* computes screen overlap.
|
||||
*
|
||||
* "This code is based very closely on the XFree86 equivalent
|
||||
* (xfree86/common/xf86Cursor.c)." --David Dawes.
|
||||
*
|
||||
* "This code was then extensively re-written, as explained here."
|
||||
* --Rik Faith
|
||||
*
|
||||
* The code in xf86Cursor.c used edge lists to implement the
|
||||
* CursorOffScreen function. The edge list computation was complex
|
||||
* (especially in the face of arbitrarily overlapping screens) compared
|
||||
* with the speed savings in the CursorOffScreen function. The new
|
||||
* implementation has erred on the side of correctness, readability, and
|
||||
* maintainability over efficiency. For the common (non-edge) case, the
|
||||
* dmxCursorOffScreen function does avoid a loop over all the screens.
|
||||
* When the cursor has left the screen, all the screens are searched,
|
||||
* and the first screen (in dmxScreens order) containing the cursor will
|
||||
* be returned. If run-time profiling shows that this routing is a
|
||||
* performance bottle-neck, then an edge list may have to be
|
||||
* reimplemented. An edge list algorithm is O(edges) whereas the new
|
||||
* algorithm is O(dmxNumScreens). Since edges is usually 1-3 and
|
||||
* dmxNumScreens may be 30-60 for large backend walls, this trade off
|
||||
* may be compelling.
|
||||
*
|
||||
* The xf86InitOrigins routine uses bit masks during the computation and
|
||||
* is therefore limited to the length of a word (e.g., 32 or 64 bits)
|
||||
* screens. Because Xdmx is expected to be used with a large number of
|
||||
* backend displays, this limitation was removed. The new
|
||||
* implementation has erred on the side of readability over efficiency,
|
||||
* using the dmxSL* routines to manage a screen list instead of a
|
||||
* bitmap, and a function call to decrease the length of the main
|
||||
* routine. Both algorithms are of the same order, and both are called
|
||||
* only at server generation time, so trading clarity and long-term
|
||||
* maintainability for efficiency does not seem justified in this case.
|
||||
*/
|
||||
|
||||
#define DMX_CURSOR_DEBUG 0
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dmxcursor.h"
|
||||
#include "dmxlog.h"
|
||||
#include "dmxprop.h"
|
||||
#include "dmxinput.h"
|
||||
|
||||
#include "mipointer.h"
|
||||
#include "windowstr.h"
|
||||
#include "globals.h"
|
||||
#include "cursorstr.h"
|
||||
#include "dixevents.h" /* For GetSpriteCursor() */
|
||||
|
||||
#if DMX_CURSOR_DEBUG
|
||||
#define DMXDBG0(f) dmxLog(dmxDebug,f)
|
||||
#define DMXDBG1(f,a) dmxLog(dmxDebug,f,a)
|
||||
#define DMXDBG2(f,a,b) dmxLog(dmxDebug,f,a,b)
|
||||
#define DMXDBG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c)
|
||||
#define DMXDBG4(f,a,b,c,d) dmxLog(dmxDebug,f,a,b,c,d)
|
||||
#define DMXDBG5(f,a,b,c,d,e) dmxLog(dmxDebug,f,a,b,c,d,e)
|
||||
#define DMXDBG6(f,a,b,c,d,e,g) dmxLog(dmxDebug,f,a,b,c,d,e,g)
|
||||
#define DMXDBG7(f,a,b,c,d,e,g,h) dmxLog(dmxDebug,f,a,b,c,d,e,g,h)
|
||||
#else
|
||||
#define DMXDBG0(f)
|
||||
#define DMXDBG1(f,a)
|
||||
#define DMXDBG2(f,a,b)
|
||||
#define DMXDBG3(f,a,b,c)
|
||||
#define DMXDBG4(f,a,b,c,d)
|
||||
#define DMXDBG5(f,a,b,c,d,e)
|
||||
#define DMXDBG6(f,a,b,c,d,e,g)
|
||||
#define DMXDBG7(f,a,b,c,d,e,g,h)
|
||||
#endif
|
||||
|
||||
static int dmxCursorDoMultiCursors = 1;
|
||||
|
||||
/** Turn off support for displaying multiple cursors on overlapped
|
||||
back-end displays. See #dmxCursorDoMultiCursors. */
|
||||
void dmxCursorNoMulti(void)
|
||||
{
|
||||
dmxCursorDoMultiCursors = 0;
|
||||
}
|
||||
|
||||
static Bool dmxCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen;
|
||||
int i;
|
||||
int localX = *x;
|
||||
int localY = *y;
|
||||
int globalX;
|
||||
int globalY;
|
||||
|
||||
if (screenInfo.numScreens == 1) return FALSE;
|
||||
|
||||
/* On current screen? */
|
||||
dmxScreen = &dmxScreens[(*ppScreen)->myNum];
|
||||
if (localX >= 0
|
||||
&& localX < dmxScreen->rootWidth
|
||||
&& localY >= 0
|
||||
&& localY < dmxScreen->rootHeight) return FALSE;
|
||||
|
||||
/* Convert to global coordinate space */
|
||||
globalX = dmxScreen->rootXOrigin + localX;
|
||||
globalY = dmxScreen->rootYOrigin + localY;
|
||||
|
||||
/* Is cursor on the current screen?
|
||||
* This efficiently exits this routine
|
||||
* for the most common case. */
|
||||
if (ppScreen && *ppScreen) {
|
||||
dmxScreen = &dmxScreens[(*ppScreen)->myNum];
|
||||
if (globalX >= dmxScreen->rootXOrigin
|
||||
&& globalX < dmxScreen->rootXOrigin + dmxScreen->rootWidth
|
||||
&& globalY >= dmxScreen->rootYOrigin
|
||||
&& globalY < dmxScreen->rootYOrigin + dmxScreen->rootHeight)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Find first screen cursor is on */
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
dmxScreen = &dmxScreens[i];
|
||||
if (globalX >= dmxScreen->rootXOrigin
|
||||
&& globalX < dmxScreen->rootXOrigin + dmxScreen->rootWidth
|
||||
&& globalY >= dmxScreen->rootYOrigin
|
||||
&& globalY < dmxScreen->rootYOrigin + dmxScreen->rootHeight) {
|
||||
if (dmxScreen->index == (*ppScreen)->myNum) return FALSE;
|
||||
*ppScreen = screenInfo.screens[dmxScreen->index];
|
||||
*x = globalX - dmxScreen->rootXOrigin;
|
||||
*y = globalY - dmxScreen->rootYOrigin;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void dmxCrossScreen(ScreenPtr pScreen, Bool entering)
|
||||
{
|
||||
}
|
||||
|
||||
static void dmxWarpCursor(ScreenPtr pScreen, int x, int y)
|
||||
{
|
||||
DMXDBG3("dmxWarpCursor(%d,%d,%d)\n", pScreen->myNum, x, y);
|
||||
miPointerWarpCursor(pScreen, x, y);
|
||||
}
|
||||
|
||||
miPointerScreenFuncRec dmxPointerCursorFuncs =
|
||||
{
|
||||
dmxCursorOffScreen,
|
||||
dmxCrossScreen,
|
||||
dmxWarpCursor,
|
||||
dmxeqEnqueue,
|
||||
dmxeqSwitchScreen
|
||||
};
|
||||
|
||||
|
||||
/** Create a list of screens that we'll manipulate. */
|
||||
static int *dmxSLCreate(void)
|
||||
{
|
||||
int *list = malloc(dmxNumScreens * sizeof(*list));
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) list[i] = 1;
|
||||
return list;
|
||||
}
|
||||
|
||||
/** Free list. */
|
||||
static void dmxSLFree(int *list)
|
||||
{
|
||||
free(list);
|
||||
}
|
||||
|
||||
/** Find next uninitialized entry in list. */
|
||||
static int dmxSLFindNext(int *list)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < dmxNumScreens; i++) if (list[i]) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Make one pass over all the screens and return the number updated. */
|
||||
static int dmxTryComputeScreenOrigins(int *screensLeft)
|
||||
{
|
||||
ScreenPtr pScreen;
|
||||
DMXScreenInfo *screen;
|
||||
int i, ref;
|
||||
int changed = 0;
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
if (!screensLeft[i]) continue;
|
||||
screen = &dmxScreens[i];
|
||||
switch (screen->where) {
|
||||
case PosAbsolute:
|
||||
dixScreenOrigins[i].x = screen->whereX;
|
||||
dixScreenOrigins[i].y = screen->whereY;
|
||||
++changed, screensLeft[i] = 0;
|
||||
break;
|
||||
case PosRelative:
|
||||
ref = screen->whereRefScreen;
|
||||
if (screensLeft[ref]) break;
|
||||
dixScreenOrigins[i].x = dixScreenOrigins[ref].x + screen->whereX;
|
||||
dixScreenOrigins[i].y = dixScreenOrigins[ref].y + screen->whereY;
|
||||
++changed, screensLeft[i] = 0;
|
||||
break;
|
||||
case PosRightOf:
|
||||
ref = screen->whereRefScreen;
|
||||
if (screensLeft[ref]) break;
|
||||
pScreen = screenInfo.screens[ref];
|
||||
dixScreenOrigins[i].x = dixScreenOrigins[ref].x + pScreen->width;
|
||||
dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
|
||||
++changed, screensLeft[i] = 0;
|
||||
break;
|
||||
case PosLeftOf:
|
||||
ref = screen->whereRefScreen;
|
||||
if (screensLeft[ref]) break;
|
||||
pScreen = screenInfo.screens[i];
|
||||
dixScreenOrigins[i].x = dixScreenOrigins[ref].x - pScreen->width;
|
||||
dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
|
||||
++changed, screensLeft[i] = 0;
|
||||
break;
|
||||
case PosBelow:
|
||||
ref = screen->whereRefScreen;
|
||||
if (screensLeft[ref]) break;
|
||||
pScreen = screenInfo.screens[ref];
|
||||
dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
|
||||
dixScreenOrigins[i].y = dixScreenOrigins[ref].y + pScreen->height;
|
||||
++changed, screensLeft[i] = 0;
|
||||
break;
|
||||
case PosAbove:
|
||||
ref = screen->whereRefScreen;
|
||||
if (screensLeft[ref]) break;
|
||||
pScreen = screenInfo.screens[i];
|
||||
dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
|
||||
dixScreenOrigins[i].y = dixScreenOrigins[ref].y - pScreen->height;
|
||||
++changed, screensLeft[i] = 0;
|
||||
break;
|
||||
case PosNone:
|
||||
dmxLog(dmxFatal, "No position information for screen %d\n", i);
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void dmxComputeScreenOrigins(void)
|
||||
{
|
||||
int *screensLeft;
|
||||
int i, ref;
|
||||
int minX, minY;
|
||||
|
||||
/* Compute origins based on
|
||||
* configuration information. */
|
||||
screensLeft = dmxSLCreate();
|
||||
while ((i = dmxSLFindNext(screensLeft)) >= 0) {
|
||||
while (dmxTryComputeScreenOrigins(screensLeft));
|
||||
if ((i = dmxSLFindNext(screensLeft)) >= 0) {
|
||||
/* All of the remaining screens are referencing each other.
|
||||
* Assign a value to one of them and go through again. This
|
||||
* guarantees that we will eventually terminate.
|
||||
*/
|
||||
ref = dmxScreens[i].whereRefScreen;
|
||||
dixScreenOrigins[ref].x = dixScreenOrigins[ref].y = 0;
|
||||
screensLeft[ref] = 0;
|
||||
}
|
||||
}
|
||||
dmxSLFree(screensLeft);
|
||||
|
||||
|
||||
/* Justify the topmost and leftmost to
|
||||
* (0,0). */
|
||||
minX = dixScreenOrigins[0].x;
|
||||
minY = dixScreenOrigins[0].y;
|
||||
for (i = 1; i < dmxNumScreens; i++) { /* Compute minX, minY */
|
||||
if (dixScreenOrigins[i].x < minX) minX = dixScreenOrigins[i].x;
|
||||
if (dixScreenOrigins[i].y < minY) minY = dixScreenOrigins[i].y;
|
||||
}
|
||||
if (minX || minY) {
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
dixScreenOrigins[i].x -= minX;
|
||||
dixScreenOrigins[i].y -= minY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Recompute origin information in the #dmxScreens list. This is
|
||||
* either called from #dmxInitOrigins() or from #dmxReconfig(). */
|
||||
void dmxReInitOrigins(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dmxNumScreens > MAXSCREENS)
|
||||
dmxLog(dmxFatal, "dmxNumScreens = %d > MAXSCREENS = %d\n",
|
||||
dmxNumScreens, MAXSCREENS);
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
||||
dmxLogOutput(dmxScreen,
|
||||
"s=%dx%d%+d%+d r=%dx%d%+d%+d @%d,%d"
|
||||
" (be=%dx%d depth=%d bpp=%d)\n",
|
||||
dmxScreen->scrnWidth, dmxScreen->scrnHeight,
|
||||
dmxScreen->scrnX, dmxScreen->scrnY,
|
||||
|
||||
dmxScreen->rootWidth, dmxScreen->rootHeight,
|
||||
dmxScreen->rootX, dmxScreen->rootY,
|
||||
|
||||
dmxScreen->rootXOrigin, dmxScreen->rootYOrigin,
|
||||
dmxScreen->beWidth, dmxScreen->beHeight,
|
||||
dmxScreen->beDepth, dmxScreen->beBPP);
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialize screen origins (and relative position). This is called
|
||||
* for each server generation. For dynamic reconfiguration, use
|
||||
* #dmxReInitOrigins() instead. */
|
||||
void dmxInitOrigins(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dmxNumScreens > MAXSCREENS)
|
||||
dmxLog(dmxFatal, "dmxNumScreens = %d > MAXSCREENS = %d\n",
|
||||
dmxNumScreens, MAXSCREENS);
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
||||
dmxLogOutput(dmxScreen,
|
||||
"(request) s=%dx%d%+d%+d r=%dx%d%+d%+d @%d,%d (%d)"
|
||||
" (be=%dx%d depth=%d bpp=%d)\n",
|
||||
dmxScreen->scrnWidth, dmxScreen->scrnHeight,
|
||||
dmxScreen->scrnX, dmxScreen->scrnY,
|
||||
|
||||
dmxScreen->rootWidth, dmxScreen->rootHeight,
|
||||
dmxScreen->rootX, dmxScreen->rootY,
|
||||
|
||||
dmxScreen->whereX, dmxScreen->whereY,
|
||||
dmxScreen->where,
|
||||
|
||||
dmxScreen->beWidth, dmxScreen->beHeight,
|
||||
dmxScreen->beDepth, dmxScreen->beBPP);
|
||||
}
|
||||
|
||||
dmxComputeScreenOrigins();
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
||||
dmxScreen->rootXOrigin = dixScreenOrigins[i].x;
|
||||
dmxScreen->rootYOrigin = dixScreenOrigins[i].y;
|
||||
}
|
||||
|
||||
dmxReInitOrigins();
|
||||
}
|
||||
|
||||
/** Returns non-zero if the global \a x, \a y coordinate is on the
|
||||
* screen window of the \a dmxScreen. */
|
||||
int dmxOnScreen(int x, int y, DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
#if DMX_CURSOR_DEBUG > 1
|
||||
dmxLog(dmxDebug,
|
||||
"dmxOnScreen %d %d,%d (r=%dx%d%+d%+d@%d,%d s=%dx%d%+d%+d)\n",
|
||||
dmxScreen->index, x, y,
|
||||
dmxScreen->rootWidth, dmxScreen->rootHeight,
|
||||
dmxScreen->rootX, dmxScreen->rootY,
|
||||
dmxScreen->rootXOrigin, dmxScreen->rootYOrigin,
|
||||
dmxScreen->scrnWidth, dmxScreen->scrnHeight,
|
||||
dmxScreen->scrnX, dmxScreen->scrnY);
|
||||
#endif
|
||||
if (x >= dmxScreen->rootXOrigin
|
||||
&& x < dmxScreen->rootXOrigin + dmxScreen->rootWidth
|
||||
&& y >= dmxScreen->rootYOrigin
|
||||
&& y < dmxScreen->rootYOrigin + dmxScreen->rootHeight) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns non-zero if \a a overlaps \a b. */
|
||||
static int dmxDoesOverlap(DMXScreenInfo *a, DMXScreenInfo *b)
|
||||
{
|
||||
if (dmxOnScreen(a->rootXOrigin,
|
||||
a->rootYOrigin, b)) return 1;
|
||||
|
||||
if (dmxOnScreen(a->rootXOrigin,
|
||||
a->rootYOrigin + a->scrnWidth, b)) return 1;
|
||||
|
||||
if (dmxOnScreen(a->rootXOrigin + a->scrnHeight,
|
||||
a->rootYOrigin, b)) return 1;
|
||||
|
||||
if (dmxOnScreen(a->rootXOrigin + a->scrnHeight,
|
||||
a->rootYOrigin + a->scrnWidth, b)) return 1;
|
||||
|
||||
if (dmxOnScreen(b->rootXOrigin,
|
||||
b->rootYOrigin, a)) return 1;
|
||||
|
||||
if (dmxOnScreen(b->rootXOrigin,
|
||||
b->rootYOrigin + b->scrnWidth, a)) return 1;
|
||||
|
||||
if (dmxOnScreen(b->rootXOrigin + b->scrnHeight,
|
||||
b->rootYOrigin, a)) return 1;
|
||||
|
||||
if (dmxOnScreen(b->rootXOrigin + b->scrnHeight,
|
||||
b->rootYOrigin + b->scrnWidth, a)) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Used with #dmxInterateOverlap to print out a list of screens which
|
||||
* overlap each other. */
|
||||
static void *dmxPrintOverlap(DMXScreenInfo *dmxScreen, void *closure)
|
||||
{
|
||||
DMXScreenInfo *a = closure;
|
||||
if (dmxScreen != a) {
|
||||
if (dmxScreen->cursorNotShared)
|
||||
dmxLogOutputCont(a, " [%d/%s]", dmxScreen->index, dmxScreen->name);
|
||||
else
|
||||
dmxLogOutputCont(a, " %d/%s", dmxScreen->index, dmxScreen->name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Iterate over the screens which overlap with the \a start screen,
|
||||
* calling \a f with the \a closure for each argument. Often used with
|
||||
* #dmxPrintOverlap. */
|
||||
static void *dmxIterateOverlap(DMXScreenInfo *start,
|
||||
void *(*f)(DMXScreenInfo *dmxScreen, void *),
|
||||
void *closure)
|
||||
{
|
||||
DMXScreenInfo *pt;
|
||||
|
||||
if (!start->over) return f(start, closure);
|
||||
|
||||
for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
|
||||
void *retval;
|
||||
if ((retval = f(pt, closure))) return retval;
|
||||
if (pt == start) break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Used with #dmxPropertyIterate to determine if screen \a a is the
|
||||
* same as the screen \a closure. */
|
||||
static void *dmxTestSameDisplay(DMXScreenInfo *a, void *closure)
|
||||
{
|
||||
DMXScreenInfo *b = closure;
|
||||
|
||||
if (a == b) return a;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Detects overlapping dmxScreens and creates circular lists. This
|
||||
* uses an O(dmxNumScreens^2) algorithm, but dmxNumScreens is < 100 and
|
||||
* the computation only needs to be performed for every server
|
||||
* generation or dynamic reconfiguration . */
|
||||
void dmxInitOverlap(void)
|
||||
{
|
||||
int i, j;
|
||||
DMXScreenInfo *a, *b, *pt;
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) dmxScreens[i].over = NULL;
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
a = &dmxScreens[i];
|
||||
|
||||
for (j = i+1; j < dmxNumScreens; j++) {
|
||||
b = &dmxScreens[j];
|
||||
if (b->over) continue;
|
||||
|
||||
if (dmxDoesOverlap(a, b)) {
|
||||
DMXDBG6("%d overlaps %d: a=%p %p b=%p %p\n",
|
||||
a->index, b->index, a, a->over, b, b->over);
|
||||
b->over = (a->over ? a->over : a);
|
||||
a->over = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
a = &dmxScreens[i];
|
||||
|
||||
if (!a->over) continue;
|
||||
|
||||
/* Flag all pairs that are on same display */
|
||||
for (pt = a->over; pt != a; pt = pt->over) {
|
||||
if (dmxPropertyIterate(a, dmxTestSameDisplay, pt)) {
|
||||
/* The ->over sets contain the transitive set of screens
|
||||
* that overlap. For screens that are on the same
|
||||
* backend display, we only want to exclude pairs of
|
||||
* screens that mutually overlap on the backend display,
|
||||
* so we call dmxDoesOverlap, which is stricter than the
|
||||
* ->over set. */
|
||||
if (!dmxDoesOverlap(a, pt)) continue;
|
||||
a->cursorNotShared = 1;
|
||||
pt->cursorNotShared = 1;
|
||||
dmxLog(dmxInfo,
|
||||
"Screen %d and %d overlap on %s\n",
|
||||
a->index, pt->index, a->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
a = &dmxScreens[i];
|
||||
|
||||
if (a->over) {
|
||||
dmxLogOutput(a, "Overlaps");
|
||||
dmxIterateOverlap(a, dmxPrintOverlap, a);
|
||||
dmxLogOutputCont(a, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Create \a pCursor on the back-end associated with \a pScreen. */
|
||||
void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
|
||||
CursorBitsPtr pBits = pCursor->bits;
|
||||
Pixmap src, msk;
|
||||
XColor fg, bg;
|
||||
XImage *img;
|
||||
XlibGC gc = NULL;
|
||||
XGCValues v;
|
||||
unsigned long m;
|
||||
int i;
|
||||
|
||||
if (!pCursorPriv)
|
||||
return;
|
||||
|
||||
m = GCFunction | GCPlaneMask | GCForeground | GCBackground | GCClipMask;
|
||||
v.function = GXcopy;
|
||||
v.plane_mask = AllPlanes;
|
||||
v.foreground = 1L;
|
||||
v.background = 0L;
|
||||
v.clip_mask = None;
|
||||
|
||||
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
|
||||
if (dmxScreen->bePixmapFormats[i].depth == 1) {
|
||||
/* Create GC in the back-end servers */
|
||||
gc = XCreateGC(dmxScreen->beDisplay, dmxScreen->scrnDefDrawables[i],
|
||||
m, &v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!gc)
|
||||
dmxLog(dmxFatal, "dmxRealizeCursor: gc not initialized\n");
|
||||
|
||||
src = XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
|
||||
pBits->width, pBits->height, 1);
|
||||
msk = XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
|
||||
pBits->width, pBits->height, 1);
|
||||
|
||||
img = XCreateImage(dmxScreen->beDisplay,
|
||||
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
|
||||
1, XYBitmap, 0, (char *)pBits->source,
|
||||
pBits->width, pBits->height,
|
||||
BitmapPad(dmxScreen->beDisplay), 0);
|
||||
|
||||
XPutImage(dmxScreen->beDisplay, src, gc, img, 0, 0, 0, 0,
|
||||
pBits->width, pBits->height);
|
||||
|
||||
XFree(img);
|
||||
|
||||
img = XCreateImage(dmxScreen->beDisplay,
|
||||
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
|
||||
1, XYBitmap, 0, (char *)pBits->mask,
|
||||
pBits->width, pBits->height,
|
||||
BitmapPad(dmxScreen->beDisplay), 0);
|
||||
|
||||
XPutImage(dmxScreen->beDisplay, msk, gc, img, 0, 0, 0, 0,
|
||||
pBits->width, pBits->height);
|
||||
|
||||
XFree(img);
|
||||
|
||||
fg.red = pCursor->foreRed;
|
||||
fg.green = pCursor->foreGreen;
|
||||
fg.blue = pCursor->foreBlue;
|
||||
|
||||
bg.red = pCursor->backRed;
|
||||
bg.green = pCursor->backGreen;
|
||||
bg.blue = pCursor->backBlue;
|
||||
|
||||
pCursorPriv->cursor = XCreatePixmapCursor(dmxScreen->beDisplay,
|
||||
src, msk,
|
||||
&fg, &bg,
|
||||
pBits->xhot, pBits->yhot);
|
||||
|
||||
XFreePixmap(dmxScreen->beDisplay, src);
|
||||
XFreePixmap(dmxScreen->beDisplay, msk);
|
||||
XFreeGC(dmxScreen->beDisplay, gc);
|
||||
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
static Bool _dmxRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxCursorPrivPtr pCursorPriv;
|
||||
|
||||
DMXDBG2("_dmxRealizeCursor(%d,%p)\n", pScreen->myNum, pCursor);
|
||||
|
||||
pCursor->devPriv[pScreen->myNum] = xalloc(sizeof(*pCursorPriv));
|
||||
if (!pCursor->devPriv[pScreen->myNum])
|
||||
return FALSE;
|
||||
|
||||
pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
|
||||
pCursorPriv->cursor = (Cursor)0;
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
return TRUE;
|
||||
|
||||
dmxBECreateCursor(pScreen, pCursor);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Free \a pCursor on the back-end associated with \a pScreen. */
|
||||
Bool dmxBEFreeCursor(ScreenPtr pScreen, CursorPtr pCursor)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
|
||||
|
||||
if (pCursorPriv) {
|
||||
XFreeCursor(dmxScreen->beDisplay, pCursorPriv->cursor);
|
||||
pCursorPriv->cursor = (Cursor)0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool _dmxUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
DMXDBG3("_dmxUnrealizeCursor(%d,%p) %p\n",
|
||||
pScreen->myNum, pCursor, pCursorPriv);
|
||||
|
||||
if (dmxScreen->beDisplay) {
|
||||
if (dmxBEFreeCursor(pScreen, pCursor))
|
||||
xfree(pCursor->devPriv[pScreen->myNum]);
|
||||
}
|
||||
pCursor->devPriv[pScreen->myNum] = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void _dmxMoveCursor(ScreenPtr pScreen, int x, int y)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
int newX = x + dmxScreen->rootX;
|
||||
int newY = y + dmxScreen->rootY;
|
||||
|
||||
if (newX < 0) newX = 0;
|
||||
if (newY < 0) newY = 0;
|
||||
|
||||
DMXDBG5("_dmxMoveCursor(%d,%d,%d) -> %d,%d\n",
|
||||
pScreen->myNum, x, y, newX, newY);
|
||||
if (dmxScreen->beDisplay) {
|
||||
XWarpPointer(dmxScreen->beDisplay, None, dmxScreen->scrnWin,
|
||||
0, 0, 0, 0, newX, newY);
|
||||
dmxSync(dmxScreen, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void _dmxSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
DMXDBG4("_dmxSetCursor(%d,%p,%d,%d)\n", pScreen->myNum, pCursor, x, y);
|
||||
|
||||
if (pCursor) {
|
||||
dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
|
||||
if (dmxScreen->curCursor != pCursorPriv->cursor) {
|
||||
if (dmxScreen->beDisplay)
|
||||
XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
|
||||
pCursorPriv->cursor);
|
||||
dmxScreen->cursor = pCursor;
|
||||
dmxScreen->curCursor = pCursorPriv->cursor;
|
||||
dmxScreen->cursorVisible = 1;
|
||||
}
|
||||
_dmxMoveCursor(pScreen, x, y);
|
||||
} else {
|
||||
if (dmxScreen->beDisplay)
|
||||
XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
|
||||
dmxScreen->noCursor);
|
||||
dmxScreen->cursor = NULL;
|
||||
dmxScreen->curCursor = (Cursor)0;
|
||||
dmxScreen->cursorVisible = 0;
|
||||
}
|
||||
if (dmxScreen->beDisplay) dmxSync(dmxScreen, TRUE);
|
||||
}
|
||||
|
||||
static Bool dmxRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
|
||||
{
|
||||
DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
|
||||
DMXScreenInfo *pt;
|
||||
|
||||
if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared)
|
||||
return _dmxRealizeCursor(pScreen, pCursor);
|
||||
|
||||
for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
|
||||
if (pt->cursorNotShared) continue;
|
||||
_dmxRealizeCursor(screenInfo.screens[pt->index], pCursor);
|
||||
if (pt == start) break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool dmxUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
|
||||
{
|
||||
DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
|
||||
DMXScreenInfo *pt;
|
||||
|
||||
if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared)
|
||||
return _dmxUnrealizeCursor(pScreen, pCursor);
|
||||
|
||||
for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
|
||||
if (pt->cursorNotShared) continue;
|
||||
_dmxUnrealizeCursor(screenInfo.screens[pt->index], pCursor);
|
||||
if (pt == start) break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static CursorPtr dmxFindCursor(DMXScreenInfo *start)
|
||||
{
|
||||
DMXScreenInfo *pt;
|
||||
|
||||
if (!start || !start->over) return GetSpriteCursor();
|
||||
for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
|
||||
if (pt->cursor) return pt->cursor;
|
||||
if (pt == start) break;
|
||||
}
|
||||
return GetSpriteCursor();
|
||||
}
|
||||
|
||||
/** Move the cursor to coordinates (\a x, \a y)on \a pScreen. This
|
||||
* function is usually called via #dmxPointerSpriteFuncs, except during
|
||||
* reconfiguration when the cursor is repositioned to force an update on
|
||||
* newley overlapping screens and on screens that no longer overlap. */
|
||||
void dmxMoveCursor(ScreenPtr pScreen, int x, int y)
|
||||
{
|
||||
DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
|
||||
DMXScreenInfo *pt;
|
||||
|
||||
DMXDBG3("dmxMoveCursor(%d,%d,%d)\n", pScreen->myNum, x, y);
|
||||
|
||||
if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared) {
|
||||
_dmxMoveCursor(pScreen, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
|
||||
if (pt->cursorNotShared) continue;
|
||||
if (dmxOnScreen(x + start->rootXOrigin, y + start->rootYOrigin, pt)) {
|
||||
if (/* pt != start && */ !pt->cursorVisible) {
|
||||
if (!pt->cursor) {
|
||||
/* This only happens during
|
||||
* reconfiguration when a new overlap
|
||||
* occurs. */
|
||||
CursorPtr pCursor;
|
||||
|
||||
if ((pCursor = dmxFindCursor(start)))
|
||||
_dmxRealizeCursor(screenInfo.screens[pt->index],
|
||||
pt->cursor = pCursor);
|
||||
|
||||
}
|
||||
_dmxSetCursor(screenInfo.screens[pt->index],
|
||||
pt->cursor,
|
||||
x + start->rootXOrigin - pt->rootXOrigin,
|
||||
y + start->rootYOrigin - pt->rootYOrigin);
|
||||
}
|
||||
_dmxMoveCursor(screenInfo.screens[pt->index],
|
||||
x + start->rootXOrigin - pt->rootXOrigin,
|
||||
y + start->rootYOrigin - pt->rootYOrigin);
|
||||
} else if (/* pt != start && */ pt->cursorVisible) {
|
||||
_dmxSetCursor(screenInfo.screens[pt->index],
|
||||
NULL,
|
||||
x + start->rootXOrigin - pt->rootXOrigin,
|
||||
y + start->rootYOrigin - pt->rootYOrigin);
|
||||
}
|
||||
if (pt == start) break;
|
||||
}
|
||||
}
|
||||
|
||||
static void dmxSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
|
||||
{
|
||||
DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
|
||||
DMXScreenInfo *pt;
|
||||
int GX, GY, gx, gy;
|
||||
|
||||
DMXDBG5("dmxSetCursor(%d %p, %p,%d,%d)\n",
|
||||
pScreen->myNum, start, pCursor, x, y);
|
||||
|
||||
/* We do this check here because of two cases:
|
||||
*
|
||||
* 1) if a client calls XWarpPointer()
|
||||
* and Xinerama is not running, we can
|
||||
* have mi's notion of the pointer
|
||||
* position out of phase with DMX's
|
||||
* notion.
|
||||
*
|
||||
* 2) if a down button is held while the
|
||||
* cursor moves outside the root window,
|
||||
* mi's notion of the pointer position
|
||||
* is out of phase with DMX's notion and
|
||||
* the cursor can remain visible when it
|
||||
* shouldn't be. */
|
||||
|
||||
dmxGetGlobalPosition(&GX, &GY);
|
||||
gx = start->rootXOrigin + x;
|
||||
gy = start->rootYOrigin + y;
|
||||
if (x && y && (GX != gx || GY != gy))
|
||||
dmxCoreMotion(gx, gy, 0, DMX_NO_BLOCK);
|
||||
|
||||
if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared) {
|
||||
_dmxSetCursor(pScreen, pCursor, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
|
||||
if (pt->cursorNotShared) continue;
|
||||
if (dmxOnScreen(x + start->rootXOrigin, y + start->rootYOrigin, pt)) {
|
||||
_dmxSetCursor(screenInfo.screens[pt->index], pCursor,
|
||||
x + start->rootXOrigin - pt->rootXOrigin,
|
||||
y + start->rootYOrigin - pt->rootYOrigin);
|
||||
} else {
|
||||
_dmxSetCursor(screenInfo.screens[pt->index], NULL,
|
||||
x + start->rootXOrigin - pt->rootXOrigin,
|
||||
y + start->rootYOrigin - pt->rootYOrigin);
|
||||
}
|
||||
if (pt == start) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This routine is used by the backend input routines to hide the
|
||||
* cursor on a screen that is being used for relative input. \see
|
||||
* dmxbackend.c */
|
||||
void dmxHideCursor(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
int x, y;
|
||||
ScreenPtr pScreen = screenInfo.screens[dmxScreen->index];
|
||||
|
||||
dmxGetGlobalPosition(&x, &y);
|
||||
_dmxSetCursor(pScreen, NULL, x, y);
|
||||
}
|
||||
|
||||
/** This routine is called during reconfiguration to make sure the
|
||||
* cursor is visible. */
|
||||
void dmxCheckCursor(void)
|
||||
{
|
||||
int i;
|
||||
int x, y;
|
||||
ScreenPtr pScreen;
|
||||
DMXScreenInfo *firstScreen;
|
||||
|
||||
dmxGetGlobalPosition(&x, &y);
|
||||
firstScreen = dmxFindFirstScreen(x, y);
|
||||
|
||||
DMXDBG2("dmxCheckCursor %d %d\n", x, y);
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
||||
pScreen = screenInfo.screens[dmxScreen->index];
|
||||
|
||||
if (!dmxOnScreen(x, y, dmxScreen)) {
|
||||
if (firstScreen && i == miPointerCurrentScreen()->myNum)
|
||||
miPointerSetNewScreen(firstScreen->index, x, y);
|
||||
_dmxSetCursor(pScreen, NULL,
|
||||
x - dmxScreen->rootXOrigin,
|
||||
y - dmxScreen->rootYOrigin);
|
||||
} else {
|
||||
if (!dmxScreen->cursor) {
|
||||
CursorPtr pCursor;
|
||||
|
||||
if ((pCursor = dmxFindCursor(dmxScreen))) {
|
||||
_dmxRealizeCursor(pScreen, dmxScreen->cursor = pCursor);
|
||||
}
|
||||
}
|
||||
_dmxSetCursor(pScreen, dmxScreen->cursor,
|
||||
x - dmxScreen->rootXOrigin,
|
||||
y - dmxScreen->rootYOrigin);
|
||||
}
|
||||
}
|
||||
DMXDBG2(" leave dmxCheckCursor %d %d\n", x, y);
|
||||
}
|
||||
|
||||
miPointerSpriteFuncRec dmxPointerSpriteFuncs =
|
||||
{
|
||||
dmxRealizeCursor,
|
||||
dmxUnrealizeCursor,
|
||||
dmxSetCursor,
|
||||
dmxMoveCursor,
|
||||
};
|
||||
70
hw/dmx/dmxcursor.h
Normal file
70
hw/dmx/dmxcursor.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* David H. Dawes <dawes@xfree86.org>
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for cursor support. \see dmxcursor.c. */
|
||||
|
||||
#ifndef DMXCURSOR_H
|
||||
#define DMXCURSOR_H
|
||||
|
||||
#include "mipointer.h"
|
||||
|
||||
/** Cursor private area. */
|
||||
typedef struct _dmxCursorPriv {
|
||||
Cursor cursor;
|
||||
} dmxCursorPrivRec, *dmxCursorPrivPtr;
|
||||
|
||||
/** Cursor functions for mi layer. \see dmxcursor.c \see dmxscrinit.c */
|
||||
extern miPointerScreenFuncRec dmxPointerCursorFuncs;
|
||||
/** Sprite functions for mi layer. \see dmxcursor.c \see dmxscrinit.c */
|
||||
extern miPointerSpriteFuncRec dmxPointerSpriteFuncs;
|
||||
|
||||
extern void dmxReInitOrigins(void);
|
||||
extern void dmxInitOrigins(void);
|
||||
extern void dmxInitOverlap(void);
|
||||
extern void dmxCursorNoMulti(void);
|
||||
extern void dmxMoveCursor(ScreenPtr pScreen, int x, int y);
|
||||
extern void dmxCheckCursor(void);
|
||||
extern int dmxOnScreen(int x, int y, DMXScreenInfo *dmxScreen);
|
||||
extern void dmxHideCursor(DMXScreenInfo *dmxScreen);
|
||||
|
||||
extern void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor);
|
||||
extern Bool dmxBEFreeCursor(ScreenPtr pScreen, CursorPtr pCursor);
|
||||
|
||||
#define DMX_GET_CURSOR_PRIV(_pCursor, _pScreen) \
|
||||
(dmxCursorPrivPtr)(_pCursor)->devPriv[(_pScreen)->myNum]
|
||||
|
||||
#endif /* DMXCURSOR_H */
|
||||
205
hw/dmx/dmxdpms.c
Normal file
205
hw/dmx/dmxdpms.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2003-2004 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Provides DPMS support and unifies all DPMS and other screen-saver
|
||||
* support in one file. If -dpms is given on the command line, or the
|
||||
* Xdmx server is not compiled with DPMS support, then the DPMS extension
|
||||
* does not work for clients, but DPMS on the backends is still disables
|
||||
* (and restored at Xdmx server shutdown time).
|
||||
*/
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxdpms.h"
|
||||
#include "dmxlog.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dpmsproc.h"
|
||||
#include "windowstr.h" /* For screenIsSaved */
|
||||
#include "X11/extensions/dpms.h"
|
||||
|
||||
static unsigned long dpmsGeneration = 0;
|
||||
static Bool dpmsSupported = TRUE;
|
||||
|
||||
static void _dmxDPMSInit(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
int event_base, error_base;
|
||||
int major, minor;
|
||||
CARD16 level, standby, suspend, off;
|
||||
BOOL state;
|
||||
const char *monitor;
|
||||
|
||||
if (dpmsGeneration != serverGeneration) {
|
||||
dpmsSupported = TRUE; /* On unless a backend doesn't support it */
|
||||
dpmsGeneration = serverGeneration;
|
||||
}
|
||||
|
||||
if (DPMSDisabledSwitch) dpmsSupported = FALSE; /* -dpms turns off */
|
||||
|
||||
dmxScreen->dpmsCapable = 0;
|
||||
|
||||
if (!dmxScreen->beDisplay) {
|
||||
dmxLogOutput(dmxScreen,
|
||||
"Cannot determine if DPMS supported (detached screen)\n");
|
||||
dpmsSupported = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DPMSQueryExtension(dmxScreen->beDisplay,
|
||||
&event_base, &error_base)) {
|
||||
dmxLogOutput(dmxScreen, "DPMS not supported\n");
|
||||
dpmsSupported = FALSE;
|
||||
return;
|
||||
}
|
||||
if (!DPMSGetVersion(dmxScreen->beDisplay, &major, &minor)) {
|
||||
dmxLogOutput(dmxScreen, "DPMS not supported\n");
|
||||
dpmsSupported = FALSE;
|
||||
return;
|
||||
}
|
||||
if (!DPMSCapable(dmxScreen->beDisplay)) {
|
||||
dmxLogOutput(dmxScreen, "DPMS %d.%d (not DPMS capable)\n",
|
||||
major, minor);
|
||||
dpmsSupported = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
DPMSInfo(dmxScreen->beDisplay, &level, &state);
|
||||
DPMSGetTimeouts(dmxScreen->beDisplay, &standby, &suspend, &off);
|
||||
DPMSSetTimeouts(dmxScreen->beDisplay, 0, 0, 0);
|
||||
DPMSEnable(dmxScreen->beDisplay);
|
||||
DPMSForceLevel(dmxScreen->beDisplay, DPMSModeOn);
|
||||
dmxScreen->dpmsCapable = 1;
|
||||
dmxScreen->dpmsEnabled = !!state;
|
||||
dmxScreen->dpmsStandby = standby;
|
||||
dmxScreen->dpmsSuspend = suspend;
|
||||
dmxScreen->dpmsOff = off;
|
||||
|
||||
switch (level) {
|
||||
case DPMSModeOn: monitor = "on"; break;
|
||||
case DPMSModeStandby: monitor = "standby"; break;
|
||||
case DPMSModeSuspend: monitor = "suspend"; break;
|
||||
case DPMSModeOff: monitor = "off"; break;
|
||||
default: monitor = "unknown"; break;
|
||||
}
|
||||
|
||||
dmxLogOutput(dmxScreen,
|
||||
"DPMS %d.%d (%s, %s, %d %d %d)\n",
|
||||
major, minor, monitor, state ? "enabled" : "disabled",
|
||||
standby, suspend, off);
|
||||
}
|
||||
|
||||
/** Initialize DPMS support. We save the current settings and turn off
|
||||
* DPMS. The settings are restored in #dmxDPMSTerm. */
|
||||
void dmxDPMSInit(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
int interval, preferBlanking, allowExposures;
|
||||
|
||||
/* Turn off DPMS */
|
||||
_dmxDPMSInit(dmxScreen);
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
return;
|
||||
|
||||
/* Turn off screen saver */
|
||||
XGetScreenSaver(dmxScreen->beDisplay, &dmxScreen->savedTimeout, &interval,
|
||||
&preferBlanking, &allowExposures);
|
||||
XSetScreenSaver(dmxScreen->beDisplay, 0, interval,
|
||||
preferBlanking, allowExposures);
|
||||
XResetScreenSaver(dmxScreen->beDisplay);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Terminate DPMS support on \a dmxScreen. We restore the settings
|
||||
* saved in #dmxDPMSInit. */
|
||||
void dmxDPMSTerm(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
int timeout, interval, preferBlanking, allowExposures;
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
return;
|
||||
|
||||
XGetScreenSaver(dmxScreen->beDisplay, &timeout, &interval,
|
||||
&preferBlanking, &allowExposures);
|
||||
XSetScreenSaver(dmxScreen->beDisplay, dmxScreen->savedTimeout, interval,
|
||||
preferBlanking, allowExposures);
|
||||
if (dmxScreen->dpmsCapable) {
|
||||
/* Restore saved state */
|
||||
DPMSForceLevel(dmxScreen->beDisplay, DPMSModeOn);
|
||||
DPMSSetTimeouts(dmxScreen->beDisplay, dmxScreen->dpmsStandby,
|
||||
dmxScreen->dpmsSuspend, dmxScreen->dpmsOff);
|
||||
if (dmxScreen->dpmsEnabled) DPMSEnable(dmxScreen->beDisplay);
|
||||
else DPMSDisable(dmxScreen->beDisplay);
|
||||
}
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Called when activity is detected so that DPMS power-saving mode can
|
||||
* be deactivated. */
|
||||
void dmxDPMSWakeup(void)
|
||||
{
|
||||
if (screenIsSaved == SCREEN_SAVER_ON)
|
||||
SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
|
||||
#ifdef DPMSExtension
|
||||
if (DPMSPowerLevel) DPMSSet(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DPMSExtension
|
||||
/** This is called on each server generation. It should determine if
|
||||
* DPMS is supported on all of the backends and, if so, return TRUE. */
|
||||
Bool DPMSSupported(void)
|
||||
{
|
||||
return dpmsSupported;
|
||||
}
|
||||
|
||||
/** This is used by clients (e.g., xset) to set the DPMS level. */
|
||||
void DPMSSet(int level)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!dpmsSupported) return;
|
||||
|
||||
if (level < 0) level = DPMSModeOn;
|
||||
if (level > 3) level = DPMSModeOff;
|
||||
|
||||
DPMSPowerLevel = level;
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
||||
if (dmxScreen->beDisplay) {
|
||||
DPMSForceLevel(dmxScreen->beDisplay, level);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
43
hw/dmx/dmxdpms.h
Normal file
43
hw/dmx/dmxdpms.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2003 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for DPMS extension support. \see dmxdpms.c */
|
||||
|
||||
#ifndef _DMXDPMS_H_
|
||||
#define _DMXDPMS_H_
|
||||
extern void dmxDPMSInit(DMXScreenInfo *dmxScreen);
|
||||
extern void dmxDPMSTerm(DMXScreenInfo *dmxScreen);
|
||||
extern void dmxDPMSWakeup(void); /* Call when input is processed */
|
||||
#endif
|
||||
1490
hw/dmx/dmxextension.c
Normal file
1490
hw/dmx/dmxextension.c
Normal file
File diff suppressed because it is too large
Load Diff
119
hw/dmx/dmxextension.h
Normal file
119
hw/dmx/dmxextension.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2003-2004 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for DMX extension support. These routines are called by
|
||||
* function in Xserver/Xext/dmx.c. \see dmxextension.c */
|
||||
|
||||
#ifndef _DMXEXTENSION_H_
|
||||
#define _DMXEXTENSION_H_
|
||||
|
||||
/** Screen attributes. Used by #ProcDMXGetScreenAttributes and
|
||||
* #ProcDMXChangeScreenAttributes. */
|
||||
typedef struct {
|
||||
const char *displayName;
|
||||
int logicalScreen;
|
||||
|
||||
unsigned int screenWindowWidth; /* displayName's coordinate system */
|
||||
unsigned int screenWindowHeight; /* displayName's coordinate system */
|
||||
int screenWindowXoffset; /* displayName's coordinate system */
|
||||
int screenWindowYoffset; /* displayName's coordinate system */
|
||||
|
||||
unsigned int rootWindowWidth; /* screenWindow's coordinate system */
|
||||
unsigned int rootWindowHeight; /* screenWindow's coordinate system */
|
||||
int rootWindowXoffset; /* screenWindow's coordinate system */
|
||||
int rootWindowYoffset; /* screenWindow's coordinate system */
|
||||
|
||||
int rootWindowXorigin; /* global coordinate system */
|
||||
int rootWindowYorigin; /* global coordinate system */
|
||||
} DMXScreenAttributesRec, *DMXScreenAttributesPtr;
|
||||
|
||||
/** Window attributes. Used by #ProcDMXGetWidowAttributes. */
|
||||
typedef struct {
|
||||
int screen;
|
||||
Window window;
|
||||
xRectangle pos;
|
||||
xRectangle vis;
|
||||
} DMXWindowAttributesRec, *DMXWindowAttributesPtr;
|
||||
|
||||
/** Desktop attributes. Used by #ProcDMXGetDesktopAttributes and
|
||||
* #ProcDMXChangeDesktopAttributes. */
|
||||
typedef struct {
|
||||
int width;
|
||||
int height;
|
||||
int shiftX;
|
||||
int shiftY;
|
||||
} DMXDesktopAttributesRec, *DMXDesktopAttributesPtr;
|
||||
|
||||
/** Input attributes. Used by #ProcDMXGetInputAttributes. */
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int inputType;
|
||||
int physicalScreen;
|
||||
int physicalId;
|
||||
int isCore;
|
||||
int sendsCore;
|
||||
int detached;
|
||||
} DMXInputAttributesRec, *DMXInputAttributesPtr;
|
||||
|
||||
|
||||
extern unsigned long dmxGetNumScreens(void);
|
||||
extern void dmxForceWindowCreation(WindowPtr pWindow);
|
||||
extern void dmxFlushPendingSyncs(void);
|
||||
extern Bool dmxGetScreenAttributes(int physical,
|
||||
DMXScreenAttributesPtr attr);
|
||||
extern Bool dmxGetWindowAttributes(WindowPtr pWindow,
|
||||
DMXWindowAttributesPtr attr);
|
||||
extern void dmxGetDesktopAttributes(DMXDesktopAttributesPtr attr);
|
||||
extern int dmxGetInputCount(void);
|
||||
extern int dmxGetInputAttributes(int deviceId,
|
||||
DMXInputAttributesPtr attr);
|
||||
extern int dmxAddInput(DMXInputAttributesPtr attr, int *deviceId);
|
||||
extern int dmxRemoveInput(int deviceId);
|
||||
|
||||
extern int dmxConfigureScreenWindows(int nscreens,
|
||||
CARD32 *screens,
|
||||
DMXScreenAttributesPtr attribs,
|
||||
int *errorScreen);
|
||||
|
||||
extern int dmxConfigureDesktop(DMXDesktopAttributesPtr attribs);
|
||||
|
||||
/* dmxUpdateScreenResources exposed for dmxCreateWindow in dmxwindow.c */
|
||||
extern void dmxUpdateScreenResources(ScreenPtr pScreen,
|
||||
int x, int y, int w, int h);
|
||||
|
||||
extern int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr);
|
||||
extern int dmxDetachScreen(int idx);
|
||||
#endif
|
||||
555
hw/dmx/dmxfont.c
Normal file
555
hw/dmx/dmxfont.c
Normal file
@@ -0,0 +1,555 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* This file provides support for fonts. */
|
||||
|
||||
#define DMX_FONTPATH_DEBUG 0
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dmxfont.h"
|
||||
#include "dmxlog.h"
|
||||
|
||||
#include "fontstruct.h"
|
||||
#include "dixfont.h"
|
||||
#include "dixstruct.h"
|
||||
|
||||
static int (*dmxSaveProcVector[256])(ClientPtr);
|
||||
static int dmxFontLastError;
|
||||
|
||||
static int dmxFontErrorHandler(Display *dpy, XErrorEvent *ev)
|
||||
{
|
||||
dmxFontLastError = ev->error_code;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char **dmxGetFontPath(int *npaths)
|
||||
{
|
||||
char **fp;
|
||||
unsigned char *c, *paths;
|
||||
char *newfp;
|
||||
int len, l, i;
|
||||
|
||||
paths = GetFontPath(npaths, &len);
|
||||
|
||||
newfp = xalloc(*npaths + len);
|
||||
c = (unsigned char *)newfp;
|
||||
fp = xalloc(*npaths * sizeof(*fp));
|
||||
|
||||
memmove(newfp, paths+1, *npaths + len - 1);
|
||||
l = *paths;
|
||||
for (i = 0; i < *npaths; i++) {
|
||||
fp[i] = (char *)c;
|
||||
c += l;
|
||||
l = *c;
|
||||
*c++ = '\0';
|
||||
}
|
||||
|
||||
#if DMX_FONTPATH_DEBUG
|
||||
for (i = 0; i < *npaths; i++)
|
||||
dmxLog(dmxDebug, "FontPath[%d] = %s\n", i, fp[i]);
|
||||
#endif
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
static void dmxFreeFontPath(char **fp)
|
||||
{
|
||||
xfree(fp[0]);
|
||||
xfree(fp);
|
||||
}
|
||||
|
||||
static Bool dmxCheckFontPathElement(DMXScreenInfo *dmxScreen, char *fp)
|
||||
{
|
||||
int (*oldErrorHandler)(Display *, XErrorEvent *);
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
return TRUE;
|
||||
|
||||
dmxFontLastError = 0;
|
||||
oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
|
||||
XSetFontPath(dmxScreen->beDisplay, &fp, 1);
|
||||
dmxSync(dmxScreen, TRUE); /* Must complete before removing handler */
|
||||
XSetErrorHandler(oldErrorHandler);
|
||||
|
||||
return (dmxFontLastError == 0);
|
||||
}
|
||||
|
||||
static int dmxSetFontPath(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
int (*oldErrorHandler)(Display *, XErrorEvent *);
|
||||
char **fp;
|
||||
int result = Success;
|
||||
int npaths;
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
return result;
|
||||
|
||||
fp = dmxGetFontPath(&npaths);
|
||||
if (!fp) return BadAlloc;
|
||||
|
||||
dmxFontLastError = 0;
|
||||
oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
|
||||
XSetFontPath(dmxScreen->beDisplay, fp, npaths);
|
||||
dmxSync(dmxScreen, TRUE); /* Must complete before removing handler */
|
||||
XSetErrorHandler(oldErrorHandler);
|
||||
|
||||
if (dmxFontLastError) {
|
||||
result = dmxFontLastError;
|
||||
/* We could set *error here to the offending path, but it is
|
||||
* ignored, so we don't bother figuring out which path is bad.
|
||||
* If we do add this support in the future, we'll need to add
|
||||
* error to the function's argument list.
|
||||
*/
|
||||
}
|
||||
|
||||
dmxFreeFontPath(fp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int dmxCheckFontPath(DMXScreenInfo *dmxScreen, int *error)
|
||||
{
|
||||
char **oldFontPath;
|
||||
int nOldPaths;
|
||||
int result = Success;
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
return result;
|
||||
|
||||
/* Save old font path */
|
||||
oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);
|
||||
|
||||
result = dmxSetFontPath(dmxScreen);
|
||||
|
||||
/* Restore old font path */
|
||||
XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
|
||||
XFreeFontPath(oldFontPath);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int dmxProcSetFontPath(ClientPtr client)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
unsigned long nbytes, total, n;
|
||||
long nfonts;
|
||||
int i, result;
|
||||
int error;
|
||||
unsigned char *oldFontPath, *tmpFontPath;
|
||||
int nOldPaths;
|
||||
int lenOldPaths;
|
||||
REQUEST(xSetFontPathReq);
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
|
||||
|
||||
nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
|
||||
total = nbytes;
|
||||
ptr = (unsigned char *)&stuff[1];
|
||||
nfonts = stuff->nFonts;
|
||||
|
||||
while (--nfonts >= 0) {
|
||||
if ((total == 0) || (total < (n = (*ptr + 1))))
|
||||
return BadLength;
|
||||
total -= n;
|
||||
ptr += n;
|
||||
}
|
||||
if (total >= 4)
|
||||
return BadLength;
|
||||
|
||||
tmpFontPath = GetFontPath(&nOldPaths, &lenOldPaths);
|
||||
oldFontPath = xalloc(nOldPaths + lenOldPaths);
|
||||
memmove(oldFontPath, tmpFontPath, nOldPaths + lenOldPaths);
|
||||
|
||||
result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
|
||||
&error);
|
||||
if (!result) {
|
||||
for (i = 0; i < dmxNumScreens; i++)
|
||||
if ((result = dmxCheckFontPath(&dmxScreens[i], &error)))
|
||||
break;
|
||||
|
||||
if (result) {
|
||||
int ignoreresult, ignoreerror;
|
||||
|
||||
/* Restore old fontpath in the DMX server */
|
||||
ignoreresult = SetFontPath(client, nOldPaths, oldFontPath,
|
||||
&ignoreerror);
|
||||
} else {
|
||||
result = client->noClientException;
|
||||
client->errorValue = error;
|
||||
}
|
||||
}
|
||||
|
||||
xfree(oldFontPath);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Initialize font support. In addition to the screen function call
|
||||
* pointers, DMX also hooks in at the ProcVector[] level. Here the old
|
||||
* ProcVector function pointers are saved and the new ProcVector
|
||||
* function pointers are initialized. */
|
||||
void dmxInitFonts(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
dmxSaveProcVector[i] = ProcVector[i];
|
||||
|
||||
ProcVector[X_SetFontPath] = dmxProcSetFontPath;
|
||||
}
|
||||
|
||||
/** Reset font support by restoring the original ProcVector function
|
||||
* pointers. */
|
||||
void dmxResetFonts(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
ProcVector[i] = dmxSaveProcVector[i];
|
||||
}
|
||||
|
||||
/** Load the font, \a pFont, on the back-end server associated with \a
|
||||
* pScreen. When a font is loaded, the font path on back-end server is
|
||||
* first initialized to that specified on the command line with the
|
||||
* -fontpath options, and then the font is loaded. */
|
||||
Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
|
||||
char *name;
|
||||
char **oldFontPath = NULL;
|
||||
int nOldPaths;
|
||||
Atom name_atom, value_atom;
|
||||
int i;
|
||||
|
||||
/* Make sure we have a font private struct to work with */
|
||||
if (!pFontPriv)
|
||||
return FALSE;
|
||||
|
||||
/* Don't load a font over top of itself */
|
||||
if (pFontPriv->font[pScreen->myNum]) {
|
||||
return TRUE; /* Already loaded font */
|
||||
}
|
||||
|
||||
/* Save old font path */
|
||||
oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);
|
||||
|
||||
/* Set the font path for the font about to be loaded on the back-end */
|
||||
if (dmxSetFontPath(dmxScreen)) {
|
||||
char **fp;
|
||||
int npaths;
|
||||
Bool *goodfps;
|
||||
|
||||
/* This could fail only when first starting the X server and
|
||||
* loading the default font. If it fails here, then the default
|
||||
* font path is invalid, no default font path will be set, the
|
||||
* DMX server will fail to load the default font, and it will
|
||||
* exit with an error unless we remove the offending font paths
|
||||
* with the -ignorebadfontpaths command line option.
|
||||
*/
|
||||
|
||||
fp = dmxGetFontPath(&npaths);
|
||||
if (!fp) {
|
||||
dmxLog(dmxError,
|
||||
"No default font path set.\n");
|
||||
dmxLog(dmxError,
|
||||
"Please see the Xdmx man page for information on how to\n");
|
||||
dmxLog(dmxError,
|
||||
"initialize the DMX server's default font path.\n");
|
||||
XFreeFontPath(oldFontPath);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dmxFontPath)
|
||||
dmxLog(dmxWarning, "No default font path is set.\n");
|
||||
|
||||
goodfps = xalloc(npaths * sizeof(*goodfps));
|
||||
|
||||
dmxLog(dmxError,
|
||||
"The DMX server failed to set the following font paths on "
|
||||
"screen #%d:\n", pScreen->myNum);
|
||||
|
||||
for (i = 0; i < npaths; i++)
|
||||
if (!(goodfps[i] = dmxCheckFontPathElement(dmxScreen, fp[i])))
|
||||
dmxLog(dmxError, " %s\n", fp[i]);
|
||||
|
||||
if (dmxIgnoreBadFontPaths) {
|
||||
char *newfp;
|
||||
int newnpaths = 0;
|
||||
int len = 0;
|
||||
int j = 0;
|
||||
int error;
|
||||
|
||||
dmxLog(dmxError,
|
||||
"These font paths will not be used because the "
|
||||
"\"-ignorebadfontpaths\"\n");
|
||||
dmxLog(dmxError,
|
||||
"option is set.\n");
|
||||
|
||||
for (i = 0; i < npaths; i++)
|
||||
if (goodfps[i]) {
|
||||
len += strlen(fp[i]) + 1;
|
||||
newnpaths++;
|
||||
}
|
||||
|
||||
if (!newnpaths) {
|
||||
/* No valid font paths were found */
|
||||
dmxLog(dmxError,
|
||||
"After removing the font paths above, no valid font "
|
||||
"paths were\n");
|
||||
dmxLog(dmxError,
|
||||
"available. Please check that the font paths set on "
|
||||
"the command\n");
|
||||
dmxLog(dmxError,
|
||||
"line or in the configuration file via the "
|
||||
"\"-fontpath\" option\n");
|
||||
dmxLog(dmxError,
|
||||
"are valid on all back-end servers. See the Xdmx man "
|
||||
"page for\n");
|
||||
dmxLog(dmxError,
|
||||
"more information on font paths.\n");
|
||||
dmxFreeFontPath(fp);
|
||||
XFreeFontPath(oldFontPath);
|
||||
xfree(goodfps);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
newfp = xalloc(len * sizeof(*newfp));
|
||||
for (i = 0; i < npaths; i++) {
|
||||
if (goodfps[i]) {
|
||||
int n = strlen(fp[i]);
|
||||
newfp[j++] = n;
|
||||
strncpy(&newfp[j], fp[i], n);
|
||||
j += n;
|
||||
}
|
||||
}
|
||||
|
||||
if (SetFontPath(NULL, newnpaths, (unsigned char *)newfp, &error)) {
|
||||
/* Note that this should never happen since all of the
|
||||
* FPEs were previously valid. */
|
||||
dmxLog(dmxError, "Cannot reset the default font path.\n");
|
||||
}
|
||||
} else if (dmxFontPath) {
|
||||
dmxLog(dmxError,
|
||||
"Please remove these font paths from the command line "
|
||||
"or\n");
|
||||
dmxLog(dmxError,
|
||||
"configuration file, or set the \"-ignorebadfontpaths\" "
|
||||
"option to\n");
|
||||
dmxLog(dmxError,
|
||||
"ignore them. For more information on these options, see "
|
||||
"the\n");
|
||||
dmxLog(dmxError,
|
||||
"Xdmx man page.\n");
|
||||
} else {
|
||||
dmxLog(dmxError,
|
||||
"Please specify the font paths that are available on all "
|
||||
"back-end\n");
|
||||
dmxLog(dmxError,
|
||||
"servers with the \"-fontpath\" option, or use the "
|
||||
"\"-ignorebadfontpaths\"\n");
|
||||
dmxLog(dmxError,
|
||||
"to ignore bad defaults. For more information on "
|
||||
"these and other\n");
|
||||
dmxLog(dmxError,
|
||||
"font-path-related options, see the Xdmx man page.\n");
|
||||
}
|
||||
|
||||
if (!dmxIgnoreBadFontPaths ||
|
||||
(dmxIgnoreBadFontPaths && dmxSetFontPath(dmxScreen))) {
|
||||
/* We still have errors so return with error */
|
||||
dmxFreeFontPath(fp);
|
||||
XFreeFontPath(oldFontPath);
|
||||
xfree(goodfps);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find requested font on back-end server */
|
||||
name_atom = MakeAtom("FONT", 4, TRUE);
|
||||
value_atom = 0L;
|
||||
|
||||
for (i = 0; i < pFont->info.nprops; i++) {
|
||||
if ((Atom)pFont->info.props[i].name == name_atom) {
|
||||
value_atom = pFont->info.props[i].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!value_atom) return FALSE;
|
||||
|
||||
name = (char *)NameForAtom(value_atom);
|
||||
if (!name) return FALSE;
|
||||
|
||||
pFontPriv->font[pScreen->myNum] =
|
||||
XLoadQueryFont(dmxScreen->beDisplay, name);
|
||||
|
||||
/* Restore old font path */
|
||||
XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
|
||||
XFreeFontPath(oldFontPath);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
|
||||
if (!pFontPriv->font[pScreen->myNum]) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Realize the font, \a pFont, on the back-end server associated with
|
||||
* \a pScreen. */
|
||||
Bool dmxRealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxFontPrivPtr pFontPriv;
|
||||
|
||||
if (!(pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex))) {
|
||||
FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
|
||||
pFontPriv = xalloc(sizeof(dmxFontPrivRec));
|
||||
if (!pFontPriv) return FALSE;
|
||||
pFontPriv->font = NULL;
|
||||
MAXSCREENSALLOC(pFontPriv->font);
|
||||
if (!pFontPriv->font) {
|
||||
xfree(pFontPriv);
|
||||
return FALSE;
|
||||
}
|
||||
pFontPriv->refcnt = 0;
|
||||
}
|
||||
|
||||
FontSetPrivate(pFont, dmxFontPrivateIndex, (pointer)pFontPriv);
|
||||
|
||||
if (dmxScreen->beDisplay) {
|
||||
if (!dmxBELoadFont(pScreen, pFont))
|
||||
return FALSE;
|
||||
|
||||
pFontPriv->refcnt++;
|
||||
} else {
|
||||
pFontPriv->font[pScreen->myNum] = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Free \a pFont on the back-end associated with \a pScreen. */
|
||||
Bool dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
|
||||
|
||||
if (pFontPriv && pFontPriv->font[pScreen->myNum]) {
|
||||
XFreeFont(dmxScreen->beDisplay, pFontPriv->font[pScreen->myNum]);
|
||||
pFontPriv->font[pScreen->myNum] = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** Unrealize the font, \a pFont, on the back-end server associated with
|
||||
* \a pScreen. */
|
||||
Bool dmxUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxFontPrivPtr pFontPriv;
|
||||
|
||||
if ((pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex))) {
|
||||
/* In case the font failed to load properly */
|
||||
if (!pFontPriv->refcnt) {
|
||||
MAXSCREENSFREE(pFontPriv->font);
|
||||
xfree(pFontPriv);
|
||||
FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
|
||||
} else if (pFontPriv->font[pScreen->myNum]) {
|
||||
if (dmxScreen->beDisplay)
|
||||
dmxBEFreeFont(pScreen, pFont);
|
||||
|
||||
/* The code below is non-obvious, so here's an explanation...
|
||||
*
|
||||
* When creating the default GC, the server opens up the
|
||||
* default font once for each screen, which in turn calls
|
||||
* the RealizeFont function pointer once for each screen.
|
||||
* During this process both dix's font refcnt and DMX's font
|
||||
* refcnt are incremented once for each screen.
|
||||
*
|
||||
* Later, when shutting down the X server, dix shuts down
|
||||
* each screen in reverse order. During this shutdown
|
||||
* procedure, each screen's default GC is freed and then
|
||||
* that screen is closed by calling the CloseScreen function
|
||||
* pointer. screenInfo.numScreens is then decremented after
|
||||
* closing each screen. This procedure means that the dix's
|
||||
* font refcnt for the font used by the default GC's is
|
||||
* decremented once for each screen # greater than 0.
|
||||
* However, since dix's refcnt for the default font is not
|
||||
* yet 0 for each screen greater than 0, no call to the
|
||||
* UnrealizeFont function pointer is made for those screens.
|
||||
* Then, when screen 0 is being closed, dix's font refcnt
|
||||
* for the default GC's font is finally 0 and the font is
|
||||
* unrealized. However, since screenInfo.numScreens has
|
||||
* been decremented already down to 1, only one call to
|
||||
* UnrealizeFont is made (for screen 0). Thus, even though
|
||||
* RealizeFont was called once for each screen,
|
||||
* UnrealizeFont is only called for screen 0.
|
||||
*
|
||||
* This is a bug in dix.
|
||||
*
|
||||
* To avoid the memory leak of pFontPriv for each server
|
||||
* generation, we can also free pFontPriv if the refcnt is
|
||||
* not yet 0 but the # of screens is 1 -- i.e., the case
|
||||
* described in the dix bug above. This is only a temporary
|
||||
* workaround until the bug in dix is solved.
|
||||
*
|
||||
* The other problem is that the font structure allocated by
|
||||
* XLoadQueryFont() above is not freed for screens > 0.
|
||||
* This problem cannot be worked around here since the back-
|
||||
* end displays for screens > 0 have already been closed by
|
||||
* the time this code is called from dix.
|
||||
*
|
||||
* When the bug in dix described above is fixed, then we can
|
||||
* remove the "|| screenInfo.numScreens == 1" code below and
|
||||
* the memory leaks will be eliminated.
|
||||
*/
|
||||
if (--pFontPriv->refcnt == 0
|
||||
#if 1
|
||||
/* Remove this code when the dix bug is fixed */
|
||||
|| screenInfo.numScreens == 1
|
||||
#endif
|
||||
) {
|
||||
MAXSCREENSFREE(pFontPriv->font);
|
||||
xfree(pFontPriv);
|
||||
FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
60
hw/dmx/dmxfont.h
Normal file
60
hw/dmx/dmxfont.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for font-related functions. \see dmxfont.c */
|
||||
|
||||
#ifndef DMXFONT_H
|
||||
#define DMXFONT_H
|
||||
|
||||
#include "fontstruct.h"
|
||||
|
||||
/** Font private area. */
|
||||
typedef struct _dmxFontPriv {
|
||||
int refcnt;
|
||||
XFontStruct **font;
|
||||
} dmxFontPrivRec, *dmxFontPrivPtr;
|
||||
|
||||
extern void dmxInitFonts(void);
|
||||
extern void dmxResetFonts(void);
|
||||
|
||||
extern Bool dmxRealizeFont(ScreenPtr pScreen, FontPtr pFont);
|
||||
extern Bool dmxUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
|
||||
|
||||
extern Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont);
|
||||
extern Bool dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont);
|
||||
|
||||
extern int dmxFontPrivateIndex;
|
||||
|
||||
#endif /* DMXFONT_H */
|
||||
420
hw/dmx/dmxgc.c
Normal file
420
hw/dmx/dmxgc.c
Normal file
@@ -0,0 +1,420 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* This file provides support for GCs. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dmxgc.h"
|
||||
#include "dmxgcops.h"
|
||||
#include "dmxpixmap.h"
|
||||
#include "dmxfont.h"
|
||||
|
||||
#include "gcstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "migc.h"
|
||||
|
||||
static GCFuncs dmxGCFuncs = {
|
||||
dmxValidateGC,
|
||||
dmxChangeGC,
|
||||
dmxCopyGC,
|
||||
dmxDestroyGC,
|
||||
dmxChangeClip,
|
||||
dmxDestroyClip,
|
||||
dmxCopyClip,
|
||||
};
|
||||
|
||||
static GCOps dmxGCOps = {
|
||||
dmxFillSpans,
|
||||
dmxSetSpans,
|
||||
dmxPutImage,
|
||||
dmxCopyArea,
|
||||
dmxCopyPlane,
|
||||
dmxPolyPoint,
|
||||
dmxPolylines,
|
||||
dmxPolySegment,
|
||||
dmxPolyRectangle,
|
||||
dmxPolyArc,
|
||||
dmxFillPolygon,
|
||||
dmxPolyFillRect,
|
||||
dmxPolyFillArc,
|
||||
dmxPolyText8,
|
||||
dmxPolyText16,
|
||||
dmxImageText8,
|
||||
dmxImageText16,
|
||||
dmxImageGlyphBlt,
|
||||
dmxPolyGlyphBlt,
|
||||
dmxPushPixels
|
||||
};
|
||||
|
||||
/** Initialize the GC on \a pScreen, which currently involves allocating
|
||||
* the GC private associated with this screen. */
|
||||
Bool dmxInitGC(ScreenPtr pScreen)
|
||||
{
|
||||
if (!AllocateGCPrivate(pScreen, dmxGCPrivateIndex, sizeof(dmxGCPrivRec)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Create the GC on the back-end server. */
|
||||
void dmxBECreateGC(ScreenPtr pScreen, GCPtr pGC)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
|
||||
if (pGC->depth == dmxScreen->bePixmapFormats[i].depth) {
|
||||
unsigned long mask;
|
||||
XGCValues gcvals;
|
||||
|
||||
mask = GCGraphicsExposures;
|
||||
gcvals.graphics_exposures = FALSE;
|
||||
|
||||
/* Create GC in the back-end servers */
|
||||
pGCPriv->gc = XCreateGC(dmxScreen->beDisplay,
|
||||
dmxScreen->scrnDefDrawables[i],
|
||||
mask, &gcvals);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a graphics context on the back-end server associated /a pGC's
|
||||
* screen. */
|
||||
Bool dmxCreateGC(GCPtr pGC)
|
||||
{
|
||||
ScreenPtr pScreen = pGC->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Bool ret;
|
||||
|
||||
DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
|
||||
if ((ret = pScreen->CreateGC(pGC))) {
|
||||
/* Save the old funcs */
|
||||
pGCPriv->funcs = pGC->funcs;
|
||||
pGCPriv->ops = NULL;
|
||||
|
||||
pGC->funcs = &dmxGCFuncs;
|
||||
|
||||
if (dmxScreen->beDisplay) {
|
||||
dmxBECreateGC(pScreen, pGC);
|
||||
} else {
|
||||
pGCPriv->gc = NULL;
|
||||
}
|
||||
|
||||
/* Check for "magic special case"
|
||||
* 1. see CreateGC in dix/gc.c for more info
|
||||
* 2. see dmxChangeGC for more info
|
||||
*/
|
||||
pGCPriv->msc = (!pGC->tileIsPixel && !pGC->tile.pixmap);
|
||||
}
|
||||
DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Validate a graphics context, \a pGC, locally in the DMX server and
|
||||
* recompute the composite clip, if necessary. */
|
||||
void dmxValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
||||
{
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
|
||||
DMX_GC_FUNC_PROLOGUE(pGC);
|
||||
#if 0
|
||||
pGC->funcs->ValidateGC(pGC, changes, pDrawable);
|
||||
#endif
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW ||
|
||||
pDrawable->type == DRAWABLE_PIXMAP) {
|
||||
/* Save the old ops, since we're about to change the ops in the
|
||||
* epilogue.
|
||||
*/
|
||||
pGCPriv->ops = pGC->ops;
|
||||
} else {
|
||||
pGCPriv->ops = NULL;
|
||||
}
|
||||
|
||||
/* If the client clip is different or moved OR the subwindowMode has
|
||||
* changed OR the window's clip has changed since the last
|
||||
* validation, then we need to recompute the composite clip.
|
||||
*/
|
||||
if ((changes & (GCClipXOrigin |
|
||||
GCClipYOrigin |
|
||||
GCClipMask |
|
||||
GCSubwindowMode)) ||
|
||||
(pDrawable->serialNumber !=
|
||||
(pGC->serialNumber & DRAWABLE_SERIAL_BITS))) {
|
||||
miComputeCompositeClip(pGC, pDrawable);
|
||||
}
|
||||
|
||||
DMX_GC_FUNC_EPILOGUE(pGC);
|
||||
}
|
||||
|
||||
/** Set the values in the graphics context on the back-end server
|
||||
* associated with \a pGC's screen. */
|
||||
void dmxChangeGC(GCPtr pGC, unsigned long mask)
|
||||
{
|
||||
ScreenPtr pScreen = pGC->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
XGCValues v;
|
||||
|
||||
DMX_GC_FUNC_PROLOGUE(pGC);
|
||||
#if 0
|
||||
pGC->funcs->ChangeGC(pGC, mask);
|
||||
#endif
|
||||
|
||||
/* Handle "magic special case" from CreateGC */
|
||||
if (pGCPriv->msc) {
|
||||
/* The "magic special case" is used to handle the case where a
|
||||
* foreground pixel is set when the GC is created so that a
|
||||
* "pseudo default-tile" can be created and used in case the
|
||||
* fillstyle was set to FillTiled. This specific case is tested
|
||||
* in xtest (XCreateGC test #3). What has happened in dix by
|
||||
* the time it reaches here is (1) the pGC->tile.pixel has been
|
||||
* set to pGC->fgPixel and pGC->tileIsPixel is set, (2) if a
|
||||
* tile has also been set, then pGC->tileIsPixel is unset and
|
||||
* pGC->tile.pixmap is initialized; else, the default tile is
|
||||
* created and pGC->tileIsPixel is unset and pGC->tile.pixmap is
|
||||
* initialized to the "pseudo default-tile". In either case,
|
||||
* pGC->tile.pixmap is set; however, in the "magic special case"
|
||||
* the mask is not updated to allow us to detect that we should
|
||||
* initialize the GCTile in the back-end server. Thus, we catch
|
||||
* this case in dmxCreateGC and add GCTile to the mask here.
|
||||
* Are there any cases that I've missed?
|
||||
*/
|
||||
|
||||
/* Make sure that the tile.pixmap is set, just in case the user
|
||||
* set GCTile in the mask but forgot to set vals.pixmap
|
||||
*/
|
||||
if (pGC->tile.pixmap) mask |= GCTile;
|
||||
|
||||
/* This only happens once when the GC is created */
|
||||
pGCPriv->msc = FALSE;
|
||||
}
|
||||
|
||||
/* Update back-end server's gc */
|
||||
if (mask & GCFunction) v.function = pGC->alu;
|
||||
if (mask & GCPlaneMask) v.plane_mask = pGC->planemask;
|
||||
if (mask & GCForeground) v.foreground = pGC->fgPixel;
|
||||
if (mask & GCBackground) v.background = pGC->bgPixel;
|
||||
if (mask & GCLineWidth) v.line_width = pGC->lineWidth;
|
||||
if (mask & GCLineStyle) v.line_style = pGC->lineStyle;
|
||||
if (mask & GCCapStyle) v.cap_style = pGC->capStyle;
|
||||
if (mask & GCJoinStyle) v.join_style = pGC->joinStyle;
|
||||
if (mask & GCFillStyle) v.fill_style = pGC->fillStyle;
|
||||
if (mask & GCFillRule) v.fill_rule = pGC->fillRule;
|
||||
if (mask & GCTile) {
|
||||
if (pGC->tileIsPixel) {
|
||||
mask &= ~GCTile;
|
||||
} else {
|
||||
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->tile.pixmap);
|
||||
v.tile = (Drawable)pPixPriv->pixmap;
|
||||
}
|
||||
}
|
||||
if (mask & GCStipple) {
|
||||
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->stipple);
|
||||
v.stipple = (Drawable)pPixPriv->pixmap;
|
||||
}
|
||||
if (mask & GCTileStipXOrigin) v.ts_x_origin = pGC->patOrg.x;
|
||||
if (mask & GCTileStipYOrigin) v.ts_y_origin = pGC->patOrg.y;
|
||||
if (mask & GCFont) {
|
||||
if (dmxScreen->beDisplay) {
|
||||
dmxFontPrivPtr pFontPriv;
|
||||
pFontPriv = FontGetPrivate(pGC->font, dmxFontPrivateIndex);
|
||||
v.font = pFontPriv->font[pScreen->myNum]->fid;
|
||||
} else {
|
||||
mask &= ~GCFont;
|
||||
}
|
||||
}
|
||||
if (mask & GCSubwindowMode) v.subwindow_mode = pGC->subWindowMode;
|
||||
|
||||
/* Graphics exposures are not needed on the back-ends since they can
|
||||
be generated on the front-end thereby saving bandwidth. */
|
||||
if (mask & GCGraphicsExposures) mask &= ~GCGraphicsExposures;
|
||||
|
||||
if (mask & GCClipXOrigin) v.clip_x_origin = pGC->clipOrg.x;
|
||||
if (mask & GCClipYOrigin) v.clip_y_origin = pGC->clipOrg.y;
|
||||
if (mask & GCClipMask) mask &= ~GCClipMask; /* See ChangeClip */
|
||||
if (mask & GCDashOffset) v.dash_offset = pGC->dashOffset;
|
||||
if (mask & GCDashList) {
|
||||
mask &= ~GCDashList;
|
||||
if (dmxScreen->beDisplay)
|
||||
XSetDashes(dmxScreen->beDisplay, pGCPriv->gc,
|
||||
pGC->dashOffset, (char *)pGC->dash,
|
||||
pGC->numInDashList);
|
||||
}
|
||||
if (mask & GCArcMode) v.arc_mode = pGC->arcMode;
|
||||
|
||||
if (mask && dmxScreen->beDisplay) {
|
||||
XChangeGC(dmxScreen->beDisplay, pGCPriv->gc, mask, &v);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
DMX_GC_FUNC_EPILOGUE(pGC);
|
||||
}
|
||||
|
||||
/** Copy \a pGCSrc to \a pGCDst on the back-end server associated with
|
||||
* \a pGCSrc's screen. */
|
||||
void dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
|
||||
{
|
||||
ScreenPtr pScreen = pGCSrc->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxGCPrivPtr pGCSrcPriv = DMX_GET_GC_PRIV(pGCSrc);
|
||||
dmxGCPrivPtr pGCDstPriv = DMX_GET_GC_PRIV(pGCDst);
|
||||
|
||||
DMX_GC_FUNC_PROLOGUE(pGCDst);
|
||||
pGCDst->funcs->CopyGC(pGCSrc, changes, pGCDst);
|
||||
|
||||
/* Copy the GC on the back-end server */
|
||||
if (dmxScreen->beDisplay)
|
||||
XCopyGC(dmxScreen->beDisplay, pGCSrcPriv->gc, changes, pGCDstPriv->gc);
|
||||
|
||||
DMX_GC_FUNC_EPILOGUE(pGCDst);
|
||||
}
|
||||
|
||||
/** Free the \a pGC on the back-end server. */
|
||||
Bool dmxBEFreeGC(GCPtr pGC)
|
||||
{
|
||||
ScreenPtr pScreen = pGC->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
|
||||
if (pGCPriv->gc) {
|
||||
XFreeGC(dmxScreen->beDisplay, pGCPriv->gc);
|
||||
pGCPriv->gc = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** Destroy the graphics context, \a pGC and free the corresponding GC
|
||||
* on the back-end server. */
|
||||
void dmxDestroyGC(GCPtr pGC)
|
||||
{
|
||||
ScreenPtr pScreen = pGC->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
DMX_GC_FUNC_PROLOGUE(pGC);
|
||||
|
||||
/* Free the GC on the back-end server */
|
||||
if (dmxScreen->beDisplay)
|
||||
dmxBEFreeGC(pGC);
|
||||
|
||||
pGC->funcs->DestroyGC(pGC);
|
||||
DMX_GC_FUNC_EPILOGUE(pGC);
|
||||
}
|
||||
|
||||
/** Change the clip rects for a GC. */
|
||||
void dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
|
||||
{
|
||||
ScreenPtr pScreen = pGC->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
XRectangle *pRects;
|
||||
BoxPtr pBox;
|
||||
int i, nRects;
|
||||
|
||||
DMX_GC_FUNC_PROLOGUE(pGC);
|
||||
pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
|
||||
|
||||
/* Set the client clip on the back-end server */
|
||||
switch (pGC->clientClipType) {
|
||||
case CT_NONE:
|
||||
if (dmxScreen->beDisplay)
|
||||
XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
|
||||
break;
|
||||
|
||||
case CT_REGION:
|
||||
if (dmxScreen->beDisplay) {
|
||||
nRects = REGION_NUM_RECTS((RegionPtr)pGC->clientClip);
|
||||
pRects = xalloc(nRects * sizeof(*pRects));
|
||||
pBox = REGION_RECTS((RegionPtr)pGC->clientClip);
|
||||
|
||||
for (i = 0; i < nRects; i++) {
|
||||
pRects[i].x = pBox[i].x1;
|
||||
pRects[i].y = pBox[i].y1;
|
||||
pRects[i].width = pBox[i].x2 - pBox[i].x1;
|
||||
pRects[i].height = pBox[i].y2 - pBox[i].y1;
|
||||
}
|
||||
|
||||
XSetClipRectangles(dmxScreen->beDisplay, pGCPriv->gc,
|
||||
pGC->clipOrg.x, pGC->clipOrg.y,
|
||||
pRects, nRects, Unsorted);
|
||||
|
||||
xfree(pRects);
|
||||
}
|
||||
break;
|
||||
|
||||
case CT_PIXMAP:
|
||||
case CT_UNSORTED:
|
||||
case CT_YSORTED:
|
||||
case CT_YXSORTED:
|
||||
case CT_YXBANDED:
|
||||
/* These clip types are condensed down to either NONE or REGION
|
||||
in the mi code */
|
||||
break;
|
||||
}
|
||||
|
||||
DMX_GC_FUNC_EPILOGUE(pGC);
|
||||
}
|
||||
|
||||
/** Destroy a GC's clip rects. */
|
||||
void dmxDestroyClip(GCPtr pGC)
|
||||
{
|
||||
ScreenPtr pScreen = pGC->pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
|
||||
DMX_GC_FUNC_PROLOGUE(pGC);
|
||||
pGC->funcs->DestroyClip(pGC);
|
||||
|
||||
/* Set the client clip on the back-end server to None */
|
||||
if (dmxScreen->beDisplay)
|
||||
XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
|
||||
|
||||
DMX_GC_FUNC_EPILOGUE(pGC);
|
||||
}
|
||||
|
||||
/** Copy a GC's clip rects. */
|
||||
void dmxCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
|
||||
{
|
||||
DMX_GC_FUNC_PROLOGUE(pGCDst);
|
||||
pGCDst->funcs->CopyClip(pGCDst, pGCSrc);
|
||||
DMX_GC_FUNC_EPILOGUE(pGCDst);
|
||||
}
|
||||
90
hw/dmx/dmxgc.h
Normal file
90
hw/dmx/dmxgc.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for GC support. \see dmxgc.c */
|
||||
|
||||
#ifndef DMXGC_H
|
||||
#define DMXGC_H
|
||||
|
||||
#include "gcstruct.h"
|
||||
|
||||
/** GC private area. */
|
||||
typedef struct _dmxGCPriv {
|
||||
GCOps *ops;
|
||||
GCFuncs *funcs;
|
||||
XlibGC gc;
|
||||
Bool msc;
|
||||
} dmxGCPrivRec, *dmxGCPrivPtr;
|
||||
|
||||
|
||||
extern Bool dmxInitGC(ScreenPtr pScreen);
|
||||
|
||||
extern Bool dmxCreateGC(GCPtr pGC);
|
||||
extern void dmxValidateGC(GCPtr pGC, unsigned long changes,
|
||||
DrawablePtr pDrawable);
|
||||
extern void dmxChangeGC(GCPtr pGC, unsigned long mask);
|
||||
extern void dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst);
|
||||
extern void dmxDestroyGC(GCPtr pGC);
|
||||
extern void dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
|
||||
extern void dmxDestroyClip(GCPtr pGC);
|
||||
extern void dmxCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
|
||||
|
||||
extern void dmxBECreateGC(ScreenPtr pScreen, GCPtr pGC);
|
||||
extern Bool dmxBEFreeGC(GCPtr pGC);
|
||||
|
||||
/** Private index. \see dmxgc.c \see dmxscrinit.c */
|
||||
extern int dmxGCPrivateIndex;
|
||||
|
||||
/** Get private. */
|
||||
#define DMX_GET_GC_PRIV(_pGC) \
|
||||
(dmxGCPrivPtr)(_pGC)->devPrivates[dmxGCPrivateIndex].ptr
|
||||
|
||||
#define DMX_GC_FUNC_PROLOGUE(_pGC) \
|
||||
do { \
|
||||
dmxGCPrivPtr _pGCPriv = DMX_GET_GC_PRIV(_pGC); \
|
||||
DMX_UNWRAP(funcs, _pGCPriv, (_pGC)); \
|
||||
if (_pGCPriv->ops) \
|
||||
DMX_UNWRAP(ops, _pGCPriv, (_pGC)); \
|
||||
} while (0)
|
||||
|
||||
#define DMX_GC_FUNC_EPILOGUE(_pGC) \
|
||||
do { \
|
||||
dmxGCPrivPtr _pGCPriv = DMX_GET_GC_PRIV(_pGC); \
|
||||
DMX_WRAP(funcs, &dmxGCFuncs, _pGCPriv, (_pGC)); \
|
||||
if (_pGCPriv->ops) \
|
||||
DMX_WRAP(ops, &dmxGCOps, _pGCPriv, (_pGC)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* DMXGC_H */
|
||||
557
hw/dmx/dmxgcops.c
Normal file
557
hw/dmx/dmxgcops.c
Normal file
@@ -0,0 +1,557 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* This file provides support for GC operations. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dmxgc.h"
|
||||
#include "dmxgcops.h"
|
||||
#include "dmxwindow.h"
|
||||
#include "dmxpixmap.h"
|
||||
|
||||
#include "mi.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "dixfontstr.h"
|
||||
|
||||
#define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw) \
|
||||
do { \
|
||||
if ((_pDraw)->type == DRAWABLE_WINDOW) { \
|
||||
dmxWinPrivPtr pWinPriv = \
|
||||
DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw)); \
|
||||
(_draw) = (Drawable)pWinPriv->window; \
|
||||
} else { \
|
||||
dmxPixPrivPtr pPixPriv = \
|
||||
DMX_GET_PIXMAP_PRIV((PixmapPtr)(_pDraw)); \
|
||||
(_draw) = (Drawable)pPixPriv->pixmap; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DMX_GCOPS_OFFSCREEN(_pDraw) \
|
||||
(!dmxScreens[(_pDraw)->pScreen->myNum].beDisplay || \
|
||||
(dmxOffScreenOpt && \
|
||||
(_pDraw)->type == DRAWABLE_WINDOW && \
|
||||
(DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->offscreen || \
|
||||
!DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->window)))
|
||||
|
||||
/** Fill spans -- this function should never be called. */
|
||||
void dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int nInit, DDXPointPtr pptInit, int *pwidthInit,
|
||||
int fSorted)
|
||||
{
|
||||
/* Error -- this should never happen! */
|
||||
}
|
||||
|
||||
/** Set spans -- this function should never be called. */
|
||||
void dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC,
|
||||
char *psrc, DDXPointPtr ppt, int *pwidth, int nspans,
|
||||
int fSorted)
|
||||
{
|
||||
/* Error -- this should never happen! */
|
||||
}
|
||||
|
||||
/** Transfer \a pBits image to back-end server associated with \a
|
||||
* pDrawable's screen. If primitive subdivision optimization is
|
||||
* enabled, then only transfer the sections of \a pBits that are
|
||||
* visible (i.e., not-clipped) to the back-end server. */
|
||||
void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int depth, int x, int y, int w, int h,
|
||||
int leftPad, int format, char *pBits)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
XImage *img;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
img = XCreateImage(dmxScreen->beDisplay,
|
||||
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
|
||||
depth, format, leftPad, pBits, w, h,
|
||||
BitmapPad(dmxScreen->beDisplay),
|
||||
(format == ZPixmap) ?
|
||||
PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad));
|
||||
|
||||
if (img) {
|
||||
Drawable draw;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
if (dmxSubdividePrimitives && pGC->pCompositeClip) {
|
||||
RegionPtr pSubImages;
|
||||
RegionPtr pClip;
|
||||
BoxRec box;
|
||||
BoxPtr pBox;
|
||||
int nBox;
|
||||
|
||||
box.x1 = x;
|
||||
box.y1 = y;
|
||||
box.x2 = x + w;
|
||||
box.y2 = y + h;
|
||||
pSubImages = REGION_CREATE(pGC->pScreen, &box, 1);
|
||||
|
||||
pClip = REGION_CREATE(pGC->pScreen, NullBox, 1);
|
||||
REGION_COPY(pGC->pScreen, pClip, pGC->pCompositeClip);
|
||||
REGION_TRANSLATE(pGC->pScreen, pClip,
|
||||
-pDrawable->x, -pDrawable->y);
|
||||
REGION_INTERSECT(pGC->pScreen, pSubImages, pSubImages, pClip);
|
||||
|
||||
nBox = REGION_NUM_RECTS(pSubImages);
|
||||
pBox = REGION_RECTS(pSubImages);
|
||||
|
||||
while (nBox--) {
|
||||
XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img,
|
||||
pBox->x1 - box.x1,
|
||||
pBox->y1 - box.y1,
|
||||
pBox->x1,
|
||||
pBox->y1,
|
||||
pBox->x2 - pBox->x1,
|
||||
pBox->y2 - pBox->y1);
|
||||
pBox++;
|
||||
}
|
||||
REGION_DESTROY(pGC->pScreen, pClip);
|
||||
REGION_DESTROY(pGC->pScreen, pSubImages);
|
||||
} else {
|
||||
XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
img, 0, 0, x, y, w, h);
|
||||
}
|
||||
XFree(img); /* Use XFree instead of XDestroyImage
|
||||
* because pBits is passed in from the
|
||||
* caller. */
|
||||
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
} else {
|
||||
/* Error -- this should not happen! */
|
||||
}
|
||||
}
|
||||
|
||||
/** Copy area from \a pSrc drawable to \a pDst drawable on the back-end
|
||||
* server associated with \a pSrc drawable's screen. If the offscreen
|
||||
* optimization is enabled, only copy when both \a pSrc and \a pDst are
|
||||
* at least partially visible. */
|
||||
RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||
int srcx, int srcy, int w, int h, int dstx, int dsty)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable srcDraw, dstDraw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
|
||||
return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
|
||||
dstx, dsty, 0L);
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
|
||||
DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
|
||||
|
||||
XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
|
||||
srcx, srcy, w, h, dstx, dsty);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
|
||||
return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
|
||||
dstx, dsty, 0L);
|
||||
}
|
||||
|
||||
/** Copy plane number \a bitPlane from \a pSrc drawable to \a pDst
|
||||
* drawable on the back-end server associated with \a pSrc drawable's
|
||||
* screen. If the offscreen optimization is enabled, only copy when
|
||||
* both \a pSrc and \a pDst are at least partially visible. */
|
||||
RegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||
int srcx, int srcy, int width, int height,
|
||||
int dstx, int dsty, unsigned long bitPlane)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable srcDraw, dstDraw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
|
||||
return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
|
||||
dstx, dsty, bitPlane);
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
|
||||
DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
|
||||
|
||||
XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
|
||||
srcx, srcy, width, height, dstx, dsty, bitPlane);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
|
||||
return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
|
||||
dstx, dsty, bitPlane);
|
||||
}
|
||||
|
||||
/** Render list of points, \a pptInit in \a pDrawable on the back-end
|
||||
* server associated with \a pDrawable's screen. If the offscreen
|
||||
* optimization is enabled, only draw when \a pDrawable is at least
|
||||
* partially visible. */
|
||||
void dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int mode, int npt, DDXPointPtr pptInit)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
(XPoint *)pptInit, npt, mode);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Render list of connected lines, \a pptInit in \a pDrawable on the
|
||||
* back-end server associated with \a pDrawable's screen. If the
|
||||
* offscreen optimization is enabled, only draw when \a pDrawable is at
|
||||
* least partially visible. */
|
||||
void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int mode, int npt, DDXPointPtr pptInit)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
(XPoint *)pptInit, npt, mode);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Render list of disjoint segments, \a pSegs in \a pDrawable on the
|
||||
* back-end server associated with \a pDrawable's screen. If the
|
||||
* offscreen optimization is enabled, only draw when \a pDrawable is at
|
||||
* least partially visible. */
|
||||
void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int nseg, xSegment *pSegs)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
(XSegment *)pSegs, nseg);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Render list of rectangle outlines, \a pRects in \a pDrawable on the
|
||||
* back-end server associated with \a pDrawable's screen. If the
|
||||
* offscreen optimization is enabled, only draw when \a pDrawable is at
|
||||
* least partially visible. */
|
||||
void dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int nrects, xRectangle *pRects)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
(XRectangle *)pRects, nrects);
|
||||
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Render list of arc outlines, \a parcs in \a pDrawable on the
|
||||
* back-end server associated with \a pDrawable's screen. If the
|
||||
* offscreen optimization is enabled, only draw when \a pDrawable is at
|
||||
* least partially visible. */
|
||||
void dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int narcs, xArc *parcs)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
(XArc *)parcs, narcs);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Render a filled polygons in \a pDrawable on the back-end server
|
||||
* associated with \a pDrawable's screen. If the offscreen
|
||||
* optimization is enabled, only draw when \a pDrawable is at least
|
||||
* partially visible. */
|
||||
void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int shape, int mode, int count, DDXPointPtr pPts)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
(XPoint *)pPts, count, shape, mode);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Render list of filled rectangles, \a prectInit in \a pDrawable on
|
||||
* the back-end server associated with \a pDrawable's screen. If the
|
||||
* offscreen optimization is enabled, only draw when \a pDrawable is at
|
||||
* least partially visible. */
|
||||
void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int nrectFill, xRectangle *prectInit)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
(XRectangle *)prectInit, nrectFill);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Render list of filled arcs, \a parcs in \a pDrawable on the back-end
|
||||
* server associated with \a pDrawable's screen. If the offscreen
|
||||
* optimization is enabled, only draw when \a pDrawable is at least
|
||||
* partially visible. */
|
||||
void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int narcs, xArc *parcs)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
(XArc *)parcs, narcs);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Render string of 8-bit \a chars (foreground only) in \a pDrawable on
|
||||
* the back-end server associated with \a pDrawable's screen. If the
|
||||
* offscreen optimization is enabled, only draw when \a pDrawable is at
|
||||
* least partially visible. */
|
||||
int dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, int count, char *chars)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
unsigned long n, i;
|
||||
int w;
|
||||
CharInfoPtr charinfo[255];
|
||||
Drawable draw;
|
||||
|
||||
GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
|
||||
Linear8Bit, &n, charinfo);
|
||||
|
||||
/* Calculate text width */
|
||||
w = 0;
|
||||
for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
|
||||
|
||||
if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
x, y, chars, count);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
return x+w;
|
||||
}
|
||||
|
||||
/** Render string of 16-bit \a chars (foreground only) in \a pDrawable
|
||||
* on the back-end server associated with \a pDrawable's screen. If
|
||||
* the offscreen optimization is enabled, only draw when \a pDrawable
|
||||
* is at least partially visible. */
|
||||
int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, int count, unsigned short *chars)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
unsigned long n, i;
|
||||
int w;
|
||||
CharInfoPtr charinfo[255];
|
||||
Drawable draw;
|
||||
|
||||
GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
|
||||
(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
|
||||
&n, charinfo);
|
||||
|
||||
/* Calculate text width */
|
||||
w = 0;
|
||||
for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
|
||||
|
||||
if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
x, y, (XChar2b *)chars, count);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
return x+w;
|
||||
}
|
||||
|
||||
/** Render string of 8-bit \a chars (both foreground and background) in
|
||||
* \a pDrawable on the back-end server associated with \a pDrawable's
|
||||
* screen. If the offscreen optimization is enabled, only draw when \a
|
||||
* pDrawable is at least partially visible. */
|
||||
void dmxImageText8(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, int count, char *chars)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
x, y, chars, count);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Render string of 16-bit \a chars (both foreground and background) in
|
||||
* \a pDrawable on the back-end server associated with \a pDrawable's
|
||||
* screen. If the offscreen optimization is enabled, only draw when \a
|
||||
* pDrawable is at least partially visible. */
|
||||
void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, int count, unsigned short *chars)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
|
||||
Drawable draw;
|
||||
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
|
||||
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
|
||||
XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
|
||||
x, y, (XChar2b *)chars, count);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Image Glyph Blt -- this function should never be called. */
|
||||
void dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, unsigned int nglyph,
|
||||
CharInfoPtr *ppci, pointer pglyphBase)
|
||||
{
|
||||
/* Error -- this should never happen! */
|
||||
}
|
||||
|
||||
/** Poly Glyph Blt -- this function should never be called. */
|
||||
void dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, unsigned int nglyph,
|
||||
CharInfoPtr *ppci, pointer pglyphBase)
|
||||
{
|
||||
/* Error -- this should never happen! */
|
||||
}
|
||||
|
||||
/** Push Pixels -- this function should never be called. */
|
||||
void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
|
||||
int w, int h, int x, int y)
|
||||
{
|
||||
/* Error -- this should never happen! */
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Miscellaneous drawing commands
|
||||
*/
|
||||
|
||||
/** Get an image from the back-end server associated with \a pDrawable's
|
||||
* screen. If \a pDrawable is a window, it must be viewable to get an
|
||||
* image from it. If it is not viewable, then get the image from the
|
||||
* first ancestor of \a pDrawable that is viewable. If no viewable
|
||||
* ancestor is found, then simply return without getting an image. */
|
||||
void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
|
||||
unsigned int format, unsigned long planeMask, char *pdstLine)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
|
||||
XImage *img;
|
||||
Drawable draw;
|
||||
|
||||
/* Cannot get image from unviewable window */
|
||||
if (pDrawable->type == DRAWABLE_WINDOW) {
|
||||
WindowPtr pWindow = (WindowPtr)pDrawable;
|
||||
if (!pWindow->viewable) {
|
||||
while (!pWindow->viewable && pWindow->parent) {
|
||||
sx += pWindow->origin.x - wBorderWidth(pWindow);
|
||||
sx += pWindow->origin.y - wBorderWidth(pWindow);
|
||||
pWindow = pWindow->parent;
|
||||
}
|
||||
if (!pWindow->viewable) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw);
|
||||
if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable))
|
||||
return;
|
||||
} else {
|
||||
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
|
||||
if (DMX_GCOPS_OFFSCREEN(pDrawable))
|
||||
return;
|
||||
}
|
||||
|
||||
img = XGetImage(dmxScreen->beDisplay, draw,
|
||||
sx, sy, w, h, planeMask, format);
|
||||
if (img) {
|
||||
int len = img->bytes_per_line * img->height;
|
||||
memmove(pdstLine, img->data, len);
|
||||
XDestroyImage(img);
|
||||
}
|
||||
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
|
||||
/** Get Spans -- this function should never be called. */
|
||||
void dmxGetSpans(DrawablePtr pDrawable, int wMax,
|
||||
DDXPointPtr ppt, int *pwidth, int nspans,
|
||||
char *pdstStart)
|
||||
{
|
||||
/* Error -- this should never happen! */
|
||||
}
|
||||
96
hw/dmx/dmxgcops.h
Normal file
96
hw/dmx/dmxgcops.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001,2002 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for gcops support. \see dmxgcops.c */
|
||||
|
||||
#ifndef DMXGCOPS_H
|
||||
#define DMXGCOPS_H
|
||||
|
||||
extern void dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int nInit, DDXPointPtr pptInit, int *pwidthInit,
|
||||
int fSorted);
|
||||
extern void dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC,
|
||||
char *psrc, DDXPointPtr ppt, int *pwidth, int nspans,
|
||||
int fSorted);
|
||||
extern void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int depth, int x, int y, int w, int h,
|
||||
int leftPad, int format, char *pBits);
|
||||
extern RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||
int srcx, int srcy, int w, int h,
|
||||
int dstx, int dsty);
|
||||
extern RegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||
int srcx, int srcy, int width, int height,
|
||||
int dstx, int dsty, unsigned long bitPlane);
|
||||
extern void dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int mode, int npt, DDXPointPtr pptInit);
|
||||
extern void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int mode, int npt, DDXPointPtr pptInit);
|
||||
extern void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int nseg, xSegment *pSegs);
|
||||
extern void dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int nrects, xRectangle *pRects);
|
||||
extern void dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int narcs, xArc *parcs);
|
||||
extern void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int shape, int mode, int count, DDXPointPtr pPts);
|
||||
extern void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int nrectFill, xRectangle *prectInit);
|
||||
extern void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int narcs, xArc *parcs);
|
||||
extern int dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, int count, char *chars);
|
||||
extern int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, int count, unsigned short *chars);
|
||||
extern void dmxImageText8(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, int count, char *chars);
|
||||
extern void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, int count, unsigned short *chars);
|
||||
extern void dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, unsigned int nglyph,
|
||||
CharInfoPtr *ppci, pointer pglyphBase);
|
||||
extern void dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, unsigned int nglyph,
|
||||
CharInfoPtr *ppci, pointer pglyphBase);
|
||||
extern void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
|
||||
int w, int h, int x, int y);
|
||||
|
||||
extern void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
|
||||
unsigned int format, unsigned long planeMask,
|
||||
char *pdstLine);
|
||||
extern void dmxGetSpans(DrawablePtr pDrawable, int wMax,
|
||||
DDXPointPtr ppt, int *pwidth, int nspans,
|
||||
char *pdstStart);
|
||||
|
||||
#endif /* DMXGCOPS_H */
|
||||
1056
hw/dmx/dmxinit.c
Normal file
1056
hw/dmx/dmxinit.c
Normal file
File diff suppressed because it is too large
Load Diff
51
hw/dmx/dmxinit.h
Normal file
51
hw/dmx/dmxinit.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2004 Red Hat Inc., Raleigh, 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for initialization. \see dmxinit.c */
|
||||
|
||||
#ifndef DMXINIT_H
|
||||
#define DMXINIT_H
|
||||
|
||||
#include "scrnintstr.h"
|
||||
|
||||
extern Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen);
|
||||
extern void dmxSetErrorHandler(DMXScreenInfo *dmxScreen);
|
||||
extern void dmxCheckForWM(DMXScreenInfo *dmxScreen);
|
||||
extern void dmxGetScreenAttribs(DMXScreenInfo *dmxScreen);
|
||||
extern Bool dmxGetVisualInfo(DMXScreenInfo *dmxScreen);
|
||||
extern void dmxGetColormaps(DMXScreenInfo *dmxScreen);
|
||||
extern void dmxGetPixmapFormats(DMXScreenInfo *dmxScreen);
|
||||
|
||||
#endif /* DMXINIT_H */
|
||||
101
hw/dmx/dmxinput.c
Normal file
101
hw/dmx/dmxinput.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001,2002 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:
|
||||
* David H. Dawes <dawes@xfree86.org>
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Provide the main entry points for input initialization and processing
|
||||
* that arequired by the dix layer.
|
||||
*/
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxlog.h"
|
||||
#include "dmxinput.h"
|
||||
|
||||
#include "inputstr.h"
|
||||
#include "input.h"
|
||||
|
||||
/** Returns TRUE if the key is a valid modifier. For PC-class
|
||||
* keyboards, all keys can be used as modifiers, so return TRUE
|
||||
* always. */
|
||||
Bool LegalModifier(unsigned int key, DevicePtr pDev)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Called from dix/main.c on each server generation to initialize
|
||||
* inputs. All the work is done in dmxInputInit. \see
|
||||
* dmxInputInit() */
|
||||
void InitInput(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
DMXInputInfo *dmxInput;
|
||||
|
||||
if (!dmxNumInputs)
|
||||
dmxLog(dmxFatal, "InitInput: no inputs specified\n");
|
||||
|
||||
for (i = 0, dmxInput = &dmxInputs[0]; i < dmxNumInputs; i++, dmxInput++)
|
||||
dmxInputInit(dmxInput);
|
||||
if (!dmxeqInitialized()) {
|
||||
dmxLog(dmxWarning, "Use keyboard/mouse pair with the first -input\n");
|
||||
dmxLog(dmxFatal, "At least one core keyboard/mouse pair required\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** Called from dix/dispatch.c in Dispatch() whenever input events
|
||||
* require processing. All the work is done in the lower level
|
||||
* routines. */
|
||||
void ProcessInputEvents(void)
|
||||
{
|
||||
int i;
|
||||
DMXInputInfo *dmxInput;
|
||||
|
||||
for (i = 0, dmxInput = &dmxInputs[0]; i < dmxNumInputs; i++, dmxInput++)
|
||||
if (!dmxInput->detached && dmxInput->processInputEvents)
|
||||
dmxInput->processInputEvents(dmxInput);
|
||||
}
|
||||
|
||||
/** This routine is called from #dmxwindow.c whenever the layout of
|
||||
* windows on the display might have changed. This information is used
|
||||
* by input drivers (currently only the console driver) that provide
|
||||
* information about window layout to the user. */
|
||||
void dmxUpdateWindowInfo(DMXUpdateType type, WindowPtr pWindow)
|
||||
{
|
||||
int i;
|
||||
DMXInputInfo *dmxInput;
|
||||
|
||||
for (i = 0, dmxInput = &dmxInputs[0]; i < dmxNumInputs; i++, dmxInput++)
|
||||
if (!dmxInput->detached && dmxInput->updateWindowInfo)
|
||||
dmxInput->updateWindowInfo(dmxInput, type, pWindow);
|
||||
}
|
||||
163
hw/dmx/dmxinput.h
Normal file
163
hw/dmx/dmxinput.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001,2002 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:
|
||||
* David H. Dawes <dawes@xfree86.org>
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
* Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* This file provides access to:
|
||||
* - global variables available to all hw/dmx routines, and
|
||||
* - enumerations and typedefs needed by input routines in hw/dmx (and
|
||||
* hw/dmx/input).
|
||||
*
|
||||
* The goal is that no files in hw/dmx should include header files from
|
||||
* hw/dmx/input -- the interface defined here should be the only
|
||||
* interface exported to the hw/dmx layer. \see input/dmxinputinit.c.
|
||||
*/
|
||||
|
||||
#ifndef DMXINPUT_H
|
||||
#define DMXINPUT_H
|
||||
|
||||
/** Maximum number of file descriptors for SIGIO handling */
|
||||
#define DMX_MAX_SIGIO_FDS 4
|
||||
|
||||
struct _DMXInputInfo;
|
||||
|
||||
/** Reason why window layout was updated. */
|
||||
typedef enum {
|
||||
DMX_UPDATE_REALIZE, /**< Window realized */
|
||||
DMX_UPDATE_UNREALIZE, /**< Window unrealized */
|
||||
DMX_UPDATE_RESTACK, /**< Stacking order changed */
|
||||
DMX_UPDATE_COPY, /**< Window copied */
|
||||
DMX_UPDATE_RESIZE, /**< Window resized */
|
||||
DMX_UPDATE_REPARENT /**< Window reparented */
|
||||
} DMXUpdateType;
|
||||
|
||||
typedef void (*ProcessInputEventsProc)(struct _DMXInputInfo *);
|
||||
typedef void (*UpdateWindowInfoProc)(struct _DMXInputInfo *,
|
||||
DMXUpdateType, WindowPtr);
|
||||
|
||||
/** An opaque structure that is only exposed in the dmx/input layer. */
|
||||
typedef struct _DMXLocalInputInfo *DMXLocalInputInfoPtr;
|
||||
|
||||
/** State of the SIGIO engine */
|
||||
typedef enum {
|
||||
DMX_NOSIGIO = 0, /**< Device does not use SIGIO at all. */
|
||||
DMX_USESIGIO, /**< Device can use SIGIO, but is not
|
||||
* (e.g., because the VT is switch
|
||||
* away). */
|
||||
DMX_ACTIVESIGIO /**< Device is currently using SIGIO. */
|
||||
} dmxSigioState;
|
||||
|
||||
/** DMXInputInfo is typedef'd in #dmx.h so that all routines can have
|
||||
* access to the global pointers. However, the elements are only
|
||||
* available to input-related routines. */
|
||||
struct _DMXInputInfo {
|
||||
const char *name; /**< Name of input display or device
|
||||
* (from command line or config
|
||||
* file) */
|
||||
Bool freename; /**< If true, free name on destroy */
|
||||
Bool detached; /**< If true, input screen is detached */
|
||||
int inputIdx; /**< Index into #dmxInputs global */
|
||||
int scrnIdx; /**< Index into #dmxScreens global */
|
||||
Bool core; /**< If True, initialize these
|
||||
* devices as devices that send core
|
||||
* events */
|
||||
Bool console; /**< True if console and backend
|
||||
* input share the same backend
|
||||
* display */
|
||||
|
||||
Bool windows; /**< True if window outlines are
|
||||
* draw in console */
|
||||
|
||||
ProcessInputEventsProc processInputEvents;
|
||||
UpdateWindowInfoProc updateWindowInfo;
|
||||
|
||||
/* Local input information */
|
||||
dmxSigioState sigioState; /**< Current stat */
|
||||
int sigioFdCount; /**< Number of fds in use */
|
||||
int sigioFd[DMX_MAX_SIGIO_FDS]; /**< List of fds */
|
||||
Bool sigioAdded[DMX_MAX_SIGIO_FDS]; /**< Active fds */
|
||||
|
||||
|
||||
/** True if a VT switch is pending, but has not yet happened. */
|
||||
int vt_switch_pending;
|
||||
|
||||
/** True if a VT switch has happened. */
|
||||
int vt_switched;
|
||||
|
||||
/** Number of devices handled in this _DMXInputInfo structure. */
|
||||
int numDevs;
|
||||
|
||||
/** List of actual input devices. Each _DMXInputInfo structure can
|
||||
* refer to more than one device. For example, the keyboard and the
|
||||
* pointer of a backend display; or all of the XInput extension
|
||||
* devices on a backend display. */
|
||||
DMXLocalInputInfoPtr *devs;
|
||||
|
||||
char *keycodes; /**< XKB keycodes from command line */
|
||||
char *symbols; /**< XKB symbols from command line */
|
||||
char *geometry; /**< XKB geometry from command line */
|
||||
};
|
||||
|
||||
extern int dmxNumInputs; /**< Number of #dmxInputs */
|
||||
extern DMXInputInfo *dmxInputs; /**< List of inputs */
|
||||
|
||||
extern void dmxInputInit(DMXInputInfo *dmxInput);
|
||||
extern void dmxInputReInit(DMXInputInfo *dmxInput);
|
||||
extern void dmxInputLateReInit(DMXInputInfo *dmxInput);
|
||||
extern void dmxInputFree(DMXInputInfo *dmxInput);
|
||||
extern void dmxInputLogDevices(void);
|
||||
extern void dmxUpdateWindowInfo(DMXUpdateType type, WindowPtr pWindow);
|
||||
|
||||
/* These functions are defined in input/dmxeq.c */
|
||||
extern Bool dmxeqInitialized(void);
|
||||
extern void dmxeqEnqueue(xEvent *e);
|
||||
extern void dmxeqSwitchScreen(ScreenPtr pScreen, Bool fromDIX);
|
||||
|
||||
/* This type is used in input/dmxevents.c. Also, these functions are
|
||||
* defined in input/dmxevents.c */
|
||||
typedef enum {
|
||||
DMX_NO_BLOCK = 0,
|
||||
DMX_BLOCK = 1
|
||||
} DMXBlockType;
|
||||
|
||||
extern void dmxGetGlobalPosition(int *x, int *y);
|
||||
extern DMXScreenInfo *dmxFindFirstScreen(int x, int y);
|
||||
extern void dmxCoreMotion(int x, int y, int delta,
|
||||
DMXBlockType block);
|
||||
|
||||
/* Support for dynamic addition of inputs. This functions is defined in
|
||||
* config/dmxconfig.c */
|
||||
extern DMXInputInfo *dmxConfigAddInput(const char *name, int core);
|
||||
#endif /* DMXINPUT_H */
|
||||
347
hw/dmx/dmxlog.c
Normal file
347
hw/dmx/dmxlog.c
Normal file
@@ -0,0 +1,347 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* 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. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxlog.h"
|
||||
#include "dmxinput.h"
|
||||
#ifdef XINPUT
|
||||
#include "XI.h"
|
||||
#include "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>";
|
||||
}
|
||||
}
|
||||
|
||||
79
hw/dmx/dmxlog.h
Normal file
79
hw/dmx/dmxlog.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* 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 header is included by all files that need to use the DMX logging
|
||||
* facilities. */
|
||||
|
||||
#ifndef _DMXLOG_H_
|
||||
#define _DMXLOG_H_
|
||||
|
||||
/** Logging levels -- output is tunable with #dmxSetLogLevel. */
|
||||
typedef enum {
|
||||
dmxDebug, /**< Usually verbose debugging info */
|
||||
dmxInfo, /**< Non-warning information */
|
||||
dmxWarning, /**< A warning that may indicate DMX
|
||||
* will not function as the user
|
||||
* intends. */
|
||||
dmxError, /**< A non-fatal error that probably
|
||||
* indicates DMX will not function as
|
||||
* desired.*/
|
||||
dmxFatal /**< A fatal error that will cause DMX
|
||||
* to shut down. */
|
||||
} dmxLogLevel;
|
||||
|
||||
/* Logging functions used by Xserver/hw/dmx routines. */
|
||||
extern dmxLogLevel dmxSetLogLevel(dmxLogLevel newLevel);
|
||||
extern dmxLogLevel dmxGetLogLevel(void);
|
||||
extern void dmxLog(dmxLogLevel logLevel, const char *format, ...);
|
||||
extern void dmxLogCont(dmxLogLevel logLevel, const char *format, ...);
|
||||
extern const char *dmxEventName(int type);
|
||||
|
||||
#ifndef DMX_LOG_STANDALONE
|
||||
extern void dmxLogOutput(DMXScreenInfo *dmxScreen, const char *format, ...);
|
||||
extern void dmxLogOutputCont(DMXScreenInfo *dmxScreen, const char *format,
|
||||
...);
|
||||
extern void dmxLogOutputWarning(DMXScreenInfo *dmxScreen, const char *format,
|
||||
...);
|
||||
extern void dmxLogInput(DMXInputInfo *dmxInput, const char *format, ...);
|
||||
extern void dmxLogInputCont(DMXInputInfo *dmxInput, const char *format, ...);
|
||||
extern void dmxLogArgs(dmxLogLevel logLevel, int argc, char **argv);
|
||||
extern void dmxLogVisual(DMXScreenInfo *dmxScreen, XVisualInfo *vi,
|
||||
int defaultVisual);
|
||||
#ifdef XINPUT
|
||||
extern const char *dmxXInputEventName(int type);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1293
hw/dmx/dmxpict.c
Normal file
1293
hw/dmx/dmxpict.c
Normal file
File diff suppressed because it is too large
Load Diff
133
hw/dmx/dmxpict.h
Normal file
133
hw/dmx/dmxpict.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* This file provides access to the externally visible RENDER support
|
||||
* functions, global variables and macros for DMX.
|
||||
*
|
||||
* FIXME: Move function definitions for non-externally visible function
|
||||
* to .c file. */
|
||||
|
||||
#ifndef DMXPICT_H
|
||||
#define DMXPICT_H
|
||||
|
||||
/** Picture private structure */
|
||||
typedef struct _dmxPictPriv {
|
||||
Picture pict; /**< Picture ID from back-end server */
|
||||
Mask savedMask; /**< Mask of picture attributes saved for
|
||||
* lazy window creation. */
|
||||
} dmxPictPrivRec, *dmxPictPrivPtr;
|
||||
|
||||
|
||||
/** Glyph Set private structure */
|
||||
typedef struct _dmxGlyphPriv {
|
||||
GlyphSet *glyphSets; /**< Glyph Set IDs from back-end server */
|
||||
} dmxGlyphPrivRec, *dmxGlyphPrivPtr;
|
||||
|
||||
|
||||
extern void dmxInitRender(void);
|
||||
extern void dmxResetRender(void);
|
||||
|
||||
extern Bool dmxPictureInit(ScreenPtr pScreen,
|
||||
PictFormatPtr formats, int nformats);
|
||||
|
||||
extern void dmxCreatePictureList(WindowPtr pWindow);
|
||||
extern Bool dmxDestroyPictureList(WindowPtr pWindow);
|
||||
|
||||
extern int dmxCreatePicture(PicturePtr pPicture);
|
||||
extern void dmxDestroyPicture(PicturePtr pPicture);
|
||||
extern int dmxChangePictureClip(PicturePtr pPicture, int clipType,
|
||||
pointer value, int n);
|
||||
extern void dmxDestroyPictureClip(PicturePtr pPicture);
|
||||
extern void dmxChangePicture(PicturePtr pPicture, Mask mask);
|
||||
extern void dmxValidatePicture(PicturePtr pPicture, Mask mask);
|
||||
extern void dmxComposite(CARD8 op,
|
||||
PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
|
||||
INT16 xSrc, INT16 ySrc,
|
||||
INT16 xMask, INT16 yMask,
|
||||
INT16 xDst, INT16 yDst,
|
||||
CARD16 width, CARD16 height);
|
||||
extern void dmxGlyphs(CARD8 op,
|
||||
PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat,
|
||||
INT16 xSrc, INT16 ySrc,
|
||||
int nlists, GlyphListPtr lists, GlyphPtr *glyphs);
|
||||
extern void dmxCompositeRects(CARD8 op,
|
||||
PicturePtr pDst,
|
||||
xRenderColor *color,
|
||||
int nRect, xRectangle *rects);
|
||||
extern Bool dmxInitIndexed(ScreenPtr pScreen, PictFormatPtr pFormat);
|
||||
extern void dmxCloseIndexed(ScreenPtr pScreen, PictFormatPtr pFormat);
|
||||
extern void dmxUpdateIndexed(ScreenPtr pScreen, PictFormatPtr pFormat,
|
||||
int ndef, xColorItem *pdef);
|
||||
extern void dmxTrapezoids(CARD8 op,
|
||||
PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat,
|
||||
INT16 xSrc, INT16 ySrc,
|
||||
int ntrap, xTrapezoid *traps);
|
||||
extern void dmxTriangles(CARD8 op,
|
||||
PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat,
|
||||
INT16 xSrc, INT16 ySrc,
|
||||
int ntri, xTriangle *tris);
|
||||
extern void dmxTriStrip(CARD8 op,
|
||||
PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat,
|
||||
INT16 xSrc, INT16 ySrc,
|
||||
int npoint, xPointFixed *points);
|
||||
extern void dmxTriFan(CARD8 op,
|
||||
PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat,
|
||||
INT16 xSrc, INT16 ySrc,
|
||||
int npoint, xPointFixed *points);
|
||||
|
||||
extern Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet);
|
||||
extern Bool dmxBEFreePicture(PicturePtr pPicture);
|
||||
|
||||
extern int dmxPictPrivateIndex; /**< Index for picture private data */
|
||||
extern int dmxGlyphSetPrivateIndex; /**< Index for glyphset private data */
|
||||
|
||||
|
||||
/** Get the picture private data given a picture pointer */
|
||||
#define DMX_GET_PICT_PRIV(_pPict) \
|
||||
(dmxPictPrivPtr)(_pPict)->devPrivates[dmxPictPrivateIndex].ptr
|
||||
|
||||
/** Set the glyphset private data given a glyphset pointer */
|
||||
#define DMX_SET_GLYPH_PRIV(_pGlyph, _pPriv) \
|
||||
GlyphSetSetPrivate((_pGlyph), dmxGlyphSetPrivateIndex, (_pPriv))
|
||||
/** Get the glyphset private data given a glyphset pointer */
|
||||
#define DMX_GET_GLYPH_PRIV(_pGlyph) \
|
||||
(dmxGlyphPrivPtr)GlyphSetGetPrivate((_pGlyph), dmxGlyphSetPrivateIndex)
|
||||
|
||||
#endif /* DMXPICT_H */
|
||||
248
hw/dmx/dmxpixmap.c
Normal file
248
hw/dmx/dmxpixmap.c
Normal file
@@ -0,0 +1,248 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Provides pixmap support. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dmxpixmap.h"
|
||||
|
||||
#include "pixmapstr.h"
|
||||
#include "servermd.h"
|
||||
|
||||
/** Initialize a private area in \a pScreen for pixmap information. */
|
||||
Bool dmxInitPixmap(ScreenPtr pScreen)
|
||||
{
|
||||
#ifdef PIXPRIV
|
||||
if (!AllocatePixmapPrivate(pScreen, dmxPixPrivateIndex,
|
||||
sizeof(dmxPixPrivRec)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
#error Must define PIXPRIV to compile DMX X server
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Create a pixmap on the back-end server. */
|
||||
void dmxBECreatePixmap(PixmapPtr pPixmap)
|
||||
{
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
|
||||
|
||||
/* Make sure we haven't already created this pixmap. This can
|
||||
* happen when the pixmap is used elsewhere (e.g., as a background
|
||||
* or border for a window) and the refcnt > 1.
|
||||
*/
|
||||
if (pPixPriv->pixmap)
|
||||
return;
|
||||
|
||||
if (pPixmap->drawable.width && pPixmap->drawable.height) {
|
||||
pPixPriv->pixmap = XCreatePixmap(dmxScreen->beDisplay,
|
||||
dmxScreen->scrnWin,
|
||||
pPixmap->drawable.width,
|
||||
pPixmap->drawable.height,
|
||||
pPixmap->drawable.depth);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a pixmap for \a pScreen with the specified \a width, \a
|
||||
* height, and \a depth. */
|
||||
PixmapPtr dmxCreatePixmap(ScreenPtr pScreen, int width, int height, int depth)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
PixmapPtr pPixmap;
|
||||
int bpp;
|
||||
dmxPixPrivPtr pPixPriv;
|
||||
|
||||
#if 0
|
||||
DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen);
|
||||
if (pScreen->CreatePixmap)
|
||||
ret = pScreen->CreatePixmap(pPixmap);
|
||||
#endif
|
||||
|
||||
/* Create pixmap on back-end server */
|
||||
if (depth == 24) bpp = 32;
|
||||
else bpp = depth;
|
||||
|
||||
pPixmap = AllocatePixmap(pScreen, 0);
|
||||
if (!pPixmap)
|
||||
return NullPixmap;
|
||||
|
||||
pPixmap->drawable.type = DRAWABLE_PIXMAP;
|
||||
pPixmap->drawable.class = 0;
|
||||
pPixmap->drawable.pScreen = pScreen;
|
||||
pPixmap->drawable.depth = depth;
|
||||
pPixmap->drawable.bitsPerPixel = bpp;
|
||||
pPixmap->drawable.id = 0;
|
||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
pPixmap->drawable.x = 0;
|
||||
pPixmap->drawable.y = 0;
|
||||
pPixmap->drawable.width = width;
|
||||
pPixmap->drawable.height = height;
|
||||
pPixmap->devKind = PixmapBytePad(width, bpp);
|
||||
pPixmap->refcnt = 1;
|
||||
|
||||
pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
|
||||
pPixPriv->pixmap = (Pixmap)0;
|
||||
pPixPriv->detachedImage = NULL;
|
||||
|
||||
/* Create the pixmap on the back-end server */
|
||||
if (dmxScreen->beDisplay) {
|
||||
dmxBECreatePixmap(pPixmap);
|
||||
}
|
||||
|
||||
#if 0
|
||||
DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen);
|
||||
#endif
|
||||
|
||||
return pPixmap;
|
||||
}
|
||||
|
||||
/** Destroy the pixmap on the back-end server. */
|
||||
Bool dmxBEFreePixmap(PixmapPtr pPixmap)
|
||||
{
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
|
||||
|
||||
if (pPixPriv->pixmap) {
|
||||
XFreePixmap(dmxScreen->beDisplay, pPixPriv->pixmap);
|
||||
pPixPriv->pixmap = (Pixmap)0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** Destroy the pixmap pointed to by \a pPixmap. */
|
||||
Bool dmxDestroyPixmap(PixmapPtr pPixmap)
|
||||
{
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
Bool ret = TRUE;
|
||||
|
||||
#if 0
|
||||
DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
|
||||
#endif
|
||||
|
||||
if (--pPixmap->refcnt)
|
||||
return TRUE;
|
||||
|
||||
/* Destroy pixmap on back-end server */
|
||||
if (dmxScreen->beDisplay) {
|
||||
if (dmxBEFreePixmap(pPixmap)) {
|
||||
/* Also make sure that we destroy any detached image */
|
||||
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
|
||||
if (pPixPriv->detachedImage)
|
||||
XDestroyImage(pPixPriv->detachedImage);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
}
|
||||
xfree(pPixmap);
|
||||
|
||||
#if 0
|
||||
if (pScreen->DestroyPixmap)
|
||||
ret = pScreen->DestroyPixmap(pPixmap);
|
||||
DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Create and return a region based on the pixmap pointed to by \a
|
||||
* pPixmap. */
|
||||
RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap)
|
||||
{
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
|
||||
XImage *ximage;
|
||||
RegionPtr pReg, pTmpReg;
|
||||
int x, y;
|
||||
unsigned long previousPixel, currentPixel;
|
||||
BoxRec Box;
|
||||
Bool overlap;
|
||||
|
||||
if (!dmxScreen->beDisplay) {
|
||||
pReg = REGION_CREATE(pScreen, NullBox, 1);
|
||||
return pReg;
|
||||
}
|
||||
|
||||
ximage = XGetImage(dmxScreen->beDisplay, pPixPriv->pixmap, 0, 0,
|
||||
pPixmap->drawable.width, pPixmap->drawable.height,
|
||||
1, XYPixmap);
|
||||
|
||||
pReg = REGION_CREATE(pScreen, NullBox, 1);
|
||||
pTmpReg = REGION_CREATE(pScreen, NullBox, 1);
|
||||
if(!pReg || !pTmpReg) return NullRegion;
|
||||
|
||||
for (y = 0; y < pPixmap->drawable.height; y++) {
|
||||
Box.y1 = y;
|
||||
Box.y2 = y + 1;
|
||||
previousPixel = 0L;
|
||||
for (x = 0; x < pPixmap->drawable.width; x++) {
|
||||
currentPixel = XGetPixel(ximage, x, y);
|
||||
if (previousPixel != currentPixel) {
|
||||
if (previousPixel == 0L) {
|
||||
/* left edge */
|
||||
Box.x1 = x;
|
||||
} else if (currentPixel == 0L) {
|
||||
/* right edge */
|
||||
Box.x2 = x;
|
||||
REGION_RESET(pScreen, pTmpReg, &Box);
|
||||
REGION_APPEND(pScreen, pReg, pTmpReg);
|
||||
}
|
||||
previousPixel = currentPixel;
|
||||
}
|
||||
}
|
||||
if (previousPixel != 0L) {
|
||||
/* right edge because of the end of pixmap */
|
||||
Box.x2 = pPixmap->drawable.width;
|
||||
REGION_RESET(pScreen, pTmpReg, &Box);
|
||||
REGION_APPEND(pScreen, pReg, pTmpReg);
|
||||
}
|
||||
}
|
||||
|
||||
REGION_DESTROY(pScreen, pTmpReg);
|
||||
XDestroyImage(ximage);
|
||||
|
||||
REGION_VALIDATE(pScreen, pReg, &overlap);
|
||||
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
return(pReg);
|
||||
}
|
||||
67
hw/dmx/dmxpixmap.h
Normal file
67
hw/dmx/dmxpixmap.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for pixmap support. \see dmxpixmap.c */
|
||||
|
||||
#ifndef DMXPIXMAP_H
|
||||
#define DMXPIXMAP_H
|
||||
|
||||
#include "pixmapstr.h"
|
||||
|
||||
/** Pixmap private area. */
|
||||
typedef struct _dmxPixPriv {
|
||||
Pixmap pixmap;
|
||||
XImage *detachedImage;
|
||||
} dmxPixPrivRec, *dmxPixPrivPtr;
|
||||
|
||||
|
||||
extern Bool dmxInitPixmap(ScreenPtr pScreen);
|
||||
|
||||
extern PixmapPtr dmxCreatePixmap(ScreenPtr pScreen,
|
||||
int width, int height, int depth);
|
||||
extern Bool dmxDestroyPixmap(PixmapPtr pPixmap);
|
||||
extern RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap);
|
||||
|
||||
extern void dmxBECreatePixmap(PixmapPtr pPixmap);
|
||||
extern Bool dmxBEFreePixmap(PixmapPtr pPixmap);
|
||||
|
||||
/** Private index. \see dmxpicmap.h \see dmxscrinit.c */
|
||||
extern int dmxPixPrivateIndex;
|
||||
|
||||
/** Get pixmap private pointer. */
|
||||
#define DMX_GET_PIXMAP_PRIV(_pPix) \
|
||||
(dmxPixPrivPtr)(_pPix)->devPrivates[dmxPixPrivateIndex].ptr
|
||||
|
||||
#endif /* DMXPIXMAP_H */
|
||||
344
hw/dmx/dmxprop.c
Normal file
344
hw/dmx/dmxprop.c
Normal file
@@ -0,0 +1,344 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002-2003 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
|
||||
*
|
||||
* It is possible for one of the DMX "backend displays" to actually be
|
||||
* smaller than the dimensions of the backend X server. Therefore, it
|
||||
* is possible for more than one of the DMX "backend displays" to be
|
||||
* physically located on the same backend X server. This situation must
|
||||
* be detected so that cursor motion can be handled in an expected
|
||||
* fashion.
|
||||
*
|
||||
* We could analyze the names used for the DMX "backend displays" (e.g.,
|
||||
* the names passed to the -display command-line parameter), but there
|
||||
* are many possible names for a single X display, and failing to detect
|
||||
* sameness leads to very unexpected results. Therefore, whenever the
|
||||
* DMX server opens a window on a backend X server, a property value is
|
||||
* queried and set on that backend to detect when another window is
|
||||
* already open on that server.
|
||||
*
|
||||
* Further, it is possible that two different DMX server instantiations
|
||||
* both have windows on the same physical backend X server. This case
|
||||
* is also detected so that pointer input is not taken from that
|
||||
* particular backend X server.
|
||||
*
|
||||
* The routines in this file handle the property management. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxprop.h"
|
||||
#include "dmxlog.h"
|
||||
|
||||
/** Holds the window id of all DMX windows on the backend X server. */
|
||||
#define DMX_ATOMNAME "DMX_NAME"
|
||||
|
||||
/** The identification string of this DMX server */
|
||||
#define DMX_IDENT "Xdmx"
|
||||
|
||||
extern char *display;
|
||||
|
||||
static int dmxPropertyErrorHandler(Display *dpy, XErrorEvent *ev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const unsigned char *dmxPropertyIdentifier(void)
|
||||
{
|
||||
/* RATS: These buffers are only used in
|
||||
* length-limited calls. */
|
||||
char hostname[256];
|
||||
static char buf[128];
|
||||
static int initialized = 0;
|
||||
|
||||
if (initialized++) return (unsigned char *)buf;
|
||||
|
||||
XmuGetHostname(hostname, sizeof(hostname));
|
||||
XmuSnprintf(buf, sizeof(buf), "%s:%s:%s", DMX_IDENT, hostname, display);
|
||||
return (unsigned char *)buf;
|
||||
}
|
||||
|
||||
/** Starting with the \a start screen, iterate over all of the screens
|
||||
* on the same physical X server as \a start, calling \a f with the
|
||||
* screen and the \a closure. (The common case is that \a start is the
|
||||
* only DMX window on the backend X server.) */
|
||||
void *dmxPropertyIterate(DMXScreenInfo *start,
|
||||
void *(*f)(DMXScreenInfo *dmxScreen, void *),
|
||||
void *closure)
|
||||
{
|
||||
DMXScreenInfo *pt;
|
||||
|
||||
if (!start->next) {
|
||||
if (!start->beDisplay) return NULL;
|
||||
return f(start, closure);
|
||||
}
|
||||
|
||||
for (pt = start->next; /* condition at end of loop */; pt = pt->next) {
|
||||
void *retval;
|
||||
/* beDisplay ban be NULL if a screen was detached */
|
||||
dmxLog(dmxDebug, "pt = %p\n", pt);
|
||||
dmxLog(dmxDebug, "pt->beDisplay = %p\n", pt->beDisplay);
|
||||
if (pt->beDisplay && (retval = f(pt, closure))) return retval;
|
||||
if (pt == start) break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Returns 0 if this is the only Xdmx session on the display; 1
|
||||
* otherwise. */
|
||||
static int dmxPropertyCheckOtherServers(DMXScreenInfo *dmxScreen, Atom atom)
|
||||
{
|
||||
Display *dpy = dmxScreen->beDisplay;
|
||||
XTextProperty tp;
|
||||
XTextProperty tproot;
|
||||
const char *pt;
|
||||
int retcode = 0;
|
||||
char **list = NULL;
|
||||
int count = 0;
|
||||
int i;
|
||||
int (*dmxOldHandler)(Display *, XErrorEvent *);
|
||||
|
||||
if (!dpy)
|
||||
return 0;
|
||||
|
||||
if (!XGetTextProperty(dpy, RootWindow(dpy,0), &tproot, atom)
|
||||
|| !tproot.nitems) return 0;
|
||||
|
||||
/* Ignore BadWindow errors for this
|
||||
* routine because the window id stored
|
||||
* in the property might be old */
|
||||
dmxOldHandler = XSetErrorHandler(dmxPropertyErrorHandler);
|
||||
for (pt = (const char *)tproot.value; pt && *pt; pt = pt ? pt + 1 : NULL) {
|
||||
if ((pt = strchr(pt, ','))) {
|
||||
Window win = strtol(pt+1, NULL, 10);
|
||||
if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
|
||||
if (!strncmp((char *)tp.value, DMX_IDENT, strlen(DMX_IDENT))) {
|
||||
int flag = 0;
|
||||
for (i = 0; i < count; i++)
|
||||
if (!strcmp(list[i], (char *)tp.value)) {
|
||||
++flag;
|
||||
break;
|
||||
}
|
||||
if (flag) continue;
|
||||
++retcode;
|
||||
dmxLogOutputWarning(dmxScreen,
|
||||
"%s also running on %s\n",
|
||||
tp.value, dmxScreen->name);
|
||||
list = xrealloc(list, ++count * sizeof(*list));
|
||||
list[count-1] = xalloc(tp.nitems + 2);
|
||||
strncpy(list[count-1], (char *)tp.value, tp.nitems + 1);
|
||||
}
|
||||
XFree(tp.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
XSetErrorHandler(dmxOldHandler);
|
||||
|
||||
for (i = 0; i < count; i++) xfree(list[i]);
|
||||
xfree(list);
|
||||
XFree(tproot.value);
|
||||
if (!retcode)
|
||||
dmxLogOutput(dmxScreen, "No Xdmx server running on backend\n");
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/** Returns NULL if this is the only Xdmx window on the display.
|
||||
* Otherwise, returns a pointer to the dmxScreen of the other windows on
|
||||
* the display. */
|
||||
static DMXScreenInfo *dmxPropertyCheckOtherWindows(DMXScreenInfo *dmxScreen,
|
||||
Atom atom)
|
||||
{
|
||||
Display *dpy = dmxScreen->beDisplay;
|
||||
const unsigned char *id = dmxPropertyIdentifier();
|
||||
XTextProperty tproot;
|
||||
XTextProperty tp;
|
||||
const char *pt;
|
||||
int (*dmxOldHandler)(Display *, XErrorEvent *);
|
||||
|
||||
if (!dpy)
|
||||
return NULL;
|
||||
|
||||
if (!XGetTextProperty(dpy, RootWindow(dpy,0), &tproot, atom)
|
||||
|| !tproot.nitems) return 0;
|
||||
|
||||
/* Ignore BadWindow errors for this
|
||||
* routine because the window id stored
|
||||
* in the property might be old */
|
||||
dmxOldHandler = XSetErrorHandler(dmxPropertyErrorHandler);
|
||||
for (pt = (const char *)tproot.value; pt && *pt; pt = pt ? pt + 1 : NULL) {
|
||||
if ((pt = strchr(pt, ','))) {
|
||||
Window win = strtol(pt+1, NULL, 10);
|
||||
if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
|
||||
dmxLog(dmxDebug,"On %s/%lu: %s\n",
|
||||
dmxScreen->name, win, tp.value);
|
||||
if (!strncmp((char *)tp.value, (char *)id,
|
||||
strlen((char *)id))) {
|
||||
int idx;
|
||||
|
||||
if (!(pt = strchr((char *)tp.value, ','))) continue;
|
||||
idx = strtol(pt+1, NULL, 10);
|
||||
if (idx < 0 || idx >= dmxNumScreens) continue;
|
||||
if (dmxScreens[idx].scrnWin != win) continue;
|
||||
XSetErrorHandler(dmxOldHandler);
|
||||
return &dmxScreens[idx];
|
||||
}
|
||||
XFree(tp.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
XSetErrorHandler(dmxOldHandler);
|
||||
XFree(tproot.value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns 0 if this is the only Xdmx session on the display; 1
|
||||
* otherwise. */
|
||||
int dmxPropertyDisplay(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
Atom atom;
|
||||
const unsigned char *id = dmxPropertyIdentifier();
|
||||
Display *dpy = dmxScreen->beDisplay;
|
||||
|
||||
if (!dpy)
|
||||
return 0;
|
||||
|
||||
atom = XInternAtom(dpy, DMX_ATOMNAME, False);
|
||||
if (dmxPropertyCheckOtherServers(dmxScreen, atom)) {
|
||||
dmxScreen->shared = 1;
|
||||
return 1;
|
||||
}
|
||||
XChangeProperty(dpy, RootWindow(dpy,0), atom, XA_STRING, 8,
|
||||
PropModeReplace, id, strlen((char *)id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns 1 if the dmxScreen and the display in \a name are on the
|
||||
* same display, or 0 otherwise. We can't just compare the display
|
||||
* names because there can be multiple synonyms for the same display,
|
||||
* some of which cannot be determined without accessing the display
|
||||
* itself (e.g., domain aliases or machines with multiple NICs). */
|
||||
int dmxPropertySameDisplay(DMXScreenInfo *dmxScreen, const char *name)
|
||||
{
|
||||
Display *dpy0 = dmxScreen->beDisplay;
|
||||
Atom atom0;
|
||||
XTextProperty tp0;
|
||||
Display *dpy1 = NULL;
|
||||
Atom atom1;
|
||||
XTextProperty tp1;
|
||||
int retval = 0;
|
||||
|
||||
if (!dpy0)
|
||||
return 0;
|
||||
|
||||
tp0.nitems = 0;
|
||||
tp1.nitems = 0;
|
||||
|
||||
if ((atom0 = XInternAtom(dpy0, DMX_ATOMNAME, True)) == None) {
|
||||
dmxLog(dmxWarning, "No atom on %s\n", dmxScreen->name);
|
||||
return 0;
|
||||
}
|
||||
if (!XGetTextProperty(dpy0, RootWindow(dpy0,0), &tp0, atom0)
|
||||
|| !tp0.nitems) {
|
||||
dmxLog(dmxWarning, "No text property on %s\n", dmxScreen->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dpy1 = XOpenDisplay(name))) {
|
||||
dmxLog(dmxWarning, "Cannot open %s\n", name);
|
||||
goto cleanup;
|
||||
}
|
||||
atom1 = XInternAtom(dpy1, DMX_ATOMNAME, True);
|
||||
if (atom1 == None) {
|
||||
dmxLog(dmxDebug, "No atom on %s\n", name);
|
||||
goto cleanup;
|
||||
}
|
||||
if (!XGetTextProperty(dpy1, RootWindow(dpy1,0), &tp1, atom1)
|
||||
|| !tp1.nitems) {
|
||||
dmxLog(dmxDebug, "No text property on %s\n", name);
|
||||
goto cleanup;
|
||||
}
|
||||
if (!strcmp((char *)tp0.value, (char *)tp1.value)) retval = 1;
|
||||
|
||||
cleanup:
|
||||
if (tp0.nitems) XFree(tp0.value);
|
||||
if (tp1.nitems) XFree(tp1.value);
|
||||
if (dpy1) XCloseDisplay(dpy1);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/** Prints a log message if \a dmxScreen is on the same backend X server
|
||||
* as some other DMX backend (output) screen. Modifies the property
|
||||
* (#DMX_ATOMNAME) on the backend X server to reflect the creation of \a
|
||||
* dmxScreen.
|
||||
*
|
||||
* The root window of the backend X server holds a list of window ids
|
||||
* for all DMX windows (on this DMX server or some other DMX server).
|
||||
*
|
||||
* This list can then be iterated, and the property for each window can
|
||||
* be examined. This property contains the following tuple (no quotes):
|
||||
*
|
||||
* "#DMX_IDENT:<hostname running DMX>:<display name of DMX>,<screen number>"
|
||||
*/
|
||||
void dmxPropertyWindow(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
Atom atom;
|
||||
const unsigned char *id = dmxPropertyIdentifier();
|
||||
Display *dpy = dmxScreen->beDisplay;
|
||||
Window win = dmxScreen->scrnWin;
|
||||
DMXScreenInfo *other;
|
||||
char buf[128]; /* RATS: only used with XmuSnprintf */
|
||||
|
||||
if (!dpy)
|
||||
return; /* FIXME: What should be done here if Xdmx is started
|
||||
* with this screen initially detached?
|
||||
*/
|
||||
|
||||
atom = XInternAtom(dpy, DMX_ATOMNAME, False);
|
||||
if ((other = dmxPropertyCheckOtherWindows(dmxScreen, atom))) {
|
||||
DMXScreenInfo *tmp = dmxScreen->next;
|
||||
dmxScreen->next = (other->next ? other->next : other);
|
||||
other->next = (tmp ? tmp : dmxScreen);
|
||||
dmxLog(dmxDebug, "%d/%s/%lu and %d/%s/%lu are on the same backend\n",
|
||||
dmxScreen->index, dmxScreen->name, dmxScreen->scrnWin,
|
||||
other->index, other->name, other->scrnWin);
|
||||
}
|
||||
|
||||
XmuSnprintf(buf, sizeof(buf), ".%d,%lu", dmxScreen->index,
|
||||
(long unsigned)win);
|
||||
XChangeProperty(dpy, RootWindow(dpy,0), atom, XA_STRING, 8,
|
||||
PropModeAppend, (unsigned char *)buf, strlen(buf));
|
||||
|
||||
XmuSnprintf(buf, sizeof(buf), "%s,%d", id, dmxScreen->index);
|
||||
XChangeProperty(dpy, win, atom, XA_STRING, 8,
|
||||
PropModeAppend, (unsigned char *)buf, strlen(buf));
|
||||
}
|
||||
47
hw/dmx/dmxprop.h
Normal file
47
hw/dmx/dmxprop.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002,2003 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
|
||||
* Interface for property support. \see dmxprop.c */
|
||||
|
||||
#ifndef _DMXPROP_H_
|
||||
#define _DMXPROP_H_
|
||||
extern int dmxPropertyDisplay(DMXScreenInfo *dmxScreen);
|
||||
extern void dmxPropertyWindow(DMXScreenInfo *dmxScreen);
|
||||
extern void *dmxPropertyIterate(DMXScreenInfo *start,
|
||||
void *(*f)(DMXScreenInfo *dmxScreen,
|
||||
void *closure),
|
||||
void *closure);
|
||||
extern int dmxPropertySameDisplay(DMXScreenInfo *dmxScreen, const char *name);
|
||||
#endif
|
||||
562
hw/dmx/dmxscrinit.c
Normal file
562
hw/dmx/dmxscrinit.c
Normal file
@@ -0,0 +1,562 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
* David H. Dawes <dawes@xfree86.org>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* This file provides support for screen initialization. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dmxshadow.h"
|
||||
#include "dmxscrinit.h"
|
||||
#include "dmxcursor.h"
|
||||
#include "dmxgc.h"
|
||||
#include "dmxgcops.h"
|
||||
#include "dmxwindow.h"
|
||||
#include "dmxpixmap.h"
|
||||
#include "dmxfont.h"
|
||||
#include "dmxcmap.h"
|
||||
#include "dmxprop.h"
|
||||
#include "dmxdpms.h"
|
||||
|
||||
#ifdef RENDER
|
||||
#include "dmxpict.h"
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
#include "mipointer.h"
|
||||
#include "micmap.h"
|
||||
|
||||
extern Bool dmxCloseScreen(int idx, ScreenPtr pScreen);
|
||||
static Bool dmxSaveScreen(ScreenPtr pScreen, int what);
|
||||
|
||||
static unsigned long dmxGeneration;
|
||||
static unsigned long *dmxCursorGeneration;
|
||||
|
||||
int dmxGCPrivateIndex; /**< Private index for GCs */
|
||||
int dmxWinPrivateIndex; /**< Private index for Windows */
|
||||
#ifdef PIXPRIV
|
||||
int dmxPixPrivateIndex; /**< Private index for Pixmaps */
|
||||
#endif
|
||||
int dmxFontPrivateIndex; /**< Private index for Fonts */
|
||||
int dmxScreenPrivateIndex; /**< Private index for Screens */
|
||||
int dmxColormapPrivateIndex; /**< Private index for Colormaps */
|
||||
#ifdef RENDER
|
||||
int dmxPictPrivateIndex; /**< Private index for Picts */
|
||||
int dmxGlyphSetPrivateIndex; /**< Private index for GlyphSets */
|
||||
#endif
|
||||
|
||||
/** Initialize the parts of screen \a idx that require access to the
|
||||
* back-end server. */
|
||||
void dmxBEScreenInit(int idx, ScreenPtr pScreen)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
|
||||
XSetWindowAttributes attribs;
|
||||
XGCValues gcvals;
|
||||
unsigned long mask;
|
||||
int i, j;
|
||||
|
||||
/* FIXME: The dmxScreenInit() code currently assumes that it will
|
||||
* not be called if the Xdmx server is started with this screen
|
||||
* detached -- i.e., it assumes that dmxScreen->beDisplay is always
|
||||
* valid. This is not necessarily a valid assumption when full
|
||||
* addition/removal of screens is implemented, but when this code is
|
||||
* broken out for screen reattachment, then we will reevaluate this
|
||||
* assumption.
|
||||
*/
|
||||
|
||||
pScreen->mmWidth = DisplayWidthMM(dmxScreen->beDisplay,
|
||||
DefaultScreen(dmxScreen->beDisplay));
|
||||
pScreen->mmHeight = DisplayHeightMM(dmxScreen->beDisplay,
|
||||
DefaultScreen(dmxScreen->beDisplay));
|
||||
|
||||
pScreen->whitePixel = dmxScreen->beWhitePixel;
|
||||
pScreen->blackPixel = dmxScreen->beBlackPixel;
|
||||
|
||||
/* Handle screen savers and DPMS on the backend */
|
||||
dmxDPMSInit(dmxScreen);
|
||||
|
||||
/* Create root window for screen */
|
||||
mask = CWBackPixel | CWEventMask | CWColormap | CWOverrideRedirect;
|
||||
attribs.background_pixel = dmxScreen->beBlackPixel;
|
||||
attribs.event_mask = (KeyPressMask
|
||||
| KeyReleaseMask
|
||||
| ButtonPressMask
|
||||
| ButtonReleaseMask
|
||||
| EnterWindowMask
|
||||
| LeaveWindowMask
|
||||
| PointerMotionMask
|
||||
| KeymapStateMask
|
||||
| FocusChangeMask);
|
||||
attribs.colormap = dmxScreen->beDefColormaps[dmxScreen->beDefVisualIndex];
|
||||
attribs.override_redirect = True;
|
||||
|
||||
dmxScreen->scrnWin =
|
||||
XCreateWindow(dmxScreen->beDisplay,
|
||||
DefaultRootWindow(dmxScreen->beDisplay),
|
||||
dmxScreen->scrnX,
|
||||
dmxScreen->scrnY,
|
||||
dmxScreen->scrnWidth,
|
||||
dmxScreen->scrnHeight,
|
||||
0,
|
||||
pScreen->rootDepth,
|
||||
InputOutput,
|
||||
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
|
||||
mask,
|
||||
&attribs);
|
||||
dmxPropertyWindow(dmxScreen);
|
||||
|
||||
/*
|
||||
* This turns off the cursor by defining a cursor with no visible
|
||||
* components.
|
||||
*/
|
||||
{
|
||||
char noCursorData[] = {0, 0, 0, 0,
|
||||
0, 0, 0, 0};
|
||||
Pixmap pixmap;
|
||||
XColor color, tmp;
|
||||
|
||||
pixmap = XCreateBitmapFromData(dmxScreen->beDisplay, dmxScreen->scrnWin,
|
||||
noCursorData, 8, 8);
|
||||
XAllocNamedColor(dmxScreen->beDisplay, dmxScreen->beDefColormaps[0],
|
||||
"black", &color, &tmp);
|
||||
dmxScreen->noCursor = XCreatePixmapCursor(dmxScreen->beDisplay,
|
||||
pixmap, pixmap,
|
||||
&color, &color, 0, 0);
|
||||
XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
|
||||
dmxScreen->noCursor);
|
||||
|
||||
XFreePixmap(dmxScreen->beDisplay, pixmap);
|
||||
}
|
||||
|
||||
XMapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
|
||||
|
||||
if (dmxShadowFB) {
|
||||
mask = (GCFunction
|
||||
| GCPlaneMask
|
||||
| GCClipMask);
|
||||
gcvals.function = GXcopy;
|
||||
gcvals.plane_mask = AllPlanes;
|
||||
gcvals.clip_mask = None;
|
||||
|
||||
dmxScreen->shadowGC = XCreateGC(dmxScreen->beDisplay,
|
||||
dmxScreen->scrnWin,
|
||||
mask, &gcvals);
|
||||
|
||||
dmxScreen->shadowFBImage =
|
||||
XCreateImage(dmxScreen->beDisplay,
|
||||
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
|
||||
dmxScreen->beDepth,
|
||||
ZPixmap,
|
||||
0,
|
||||
(char *)dmxScreen->shadow,
|
||||
dmxScreen->scrnWidth, dmxScreen->scrnHeight,
|
||||
dmxScreen->beBPP,
|
||||
PixmapBytePad(dmxScreen->scrnWidth,
|
||||
dmxScreen->beBPP));
|
||||
} else {
|
||||
/* Create default drawables (used during GC creation) */
|
||||
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++)
|
||||
for (j = 0; j < dmxScreen->beNumDepths; j++)
|
||||
if ((dmxScreen->bePixmapFormats[i].depth == 1) ||
|
||||
(dmxScreen->bePixmapFormats[i].depth ==
|
||||
dmxScreen->beDepths[j])) {
|
||||
dmxScreen->scrnDefDrawables[i] = (Drawable)
|
||||
XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
|
||||
1, 1, dmxScreen->bePixmapFormats[i].depth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialize screen number \a idx. */
|
||||
Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[])
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
|
||||
int i, j;
|
||||
|
||||
if (dmxGeneration != serverGeneration) {
|
||||
#ifdef RENDER
|
||||
/* Allocate picture private index */
|
||||
dmxPictPrivateIndex = AllocatePicturePrivateIndex();
|
||||
if (dmxPictPrivateIndex == -1)
|
||||
return FALSE;
|
||||
|
||||
/* Allocate glyph set private index */
|
||||
dmxGlyphSetPrivateIndex = AllocateGlyphSetPrivateIndex();
|
||||
if (dmxGlyphSetPrivateIndex == -1)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
/* Allocate GC private index */
|
||||
dmxGCPrivateIndex = AllocateGCPrivateIndex();
|
||||
if (dmxGCPrivateIndex == -1)
|
||||
return FALSE;
|
||||
|
||||
/* Allocate window private index */
|
||||
dmxWinPrivateIndex = AllocateWindowPrivateIndex();
|
||||
if (dmxWinPrivateIndex == -1)
|
||||
return FALSE;
|
||||
|
||||
#ifdef PIXPRIV
|
||||
/* Allocate pixmap private index */
|
||||
dmxPixPrivateIndex = AllocatePixmapPrivateIndex();
|
||||
if (dmxPixPrivateIndex == -1)
|
||||
return FALSE;
|
||||
#else
|
||||
#error Must define PIXPRIV to compile DMX X server
|
||||
#endif
|
||||
|
||||
/* Allocate font private index */
|
||||
dmxFontPrivateIndex = AllocateFontPrivateIndex();
|
||||
if (dmxFontPrivateIndex == -1)
|
||||
return FALSE;
|
||||
|
||||
/* Allocate screen private index */
|
||||
dmxScreenPrivateIndex = AllocateScreenPrivateIndex();
|
||||
if (dmxScreenPrivateIndex == -1)
|
||||
return FALSE;
|
||||
|
||||
dmxGeneration = serverGeneration;
|
||||
}
|
||||
|
||||
if (dmxShadowFB) {
|
||||
dmxScreen->shadow = shadowAlloc(dmxScreen->scrnWidth,
|
||||
dmxScreen->scrnHeight,
|
||||
dmxScreen->beBPP);
|
||||
} else {
|
||||
if (!dmxInitGC(pScreen)) return FALSE;
|
||||
if (!dmxInitWindow(pScreen)) return FALSE;
|
||||
if (!dmxInitPixmap(pScreen)) return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initalise the visual types. miSetVisualTypesAndMasks() requires
|
||||
* that all of the types for each depth be collected together. It's
|
||||
* intended for slightly different usage to what we would like here.
|
||||
* Maybe a miAddVisualTypeAndMask() function will be added to make
|
||||
* things easier here.
|
||||
*/
|
||||
for (i = 0; i < dmxScreen->beNumDepths; i++) {
|
||||
int depth;
|
||||
int visuals = 0;
|
||||
int bitsPerRgb = 0;
|
||||
int preferredClass = -1;
|
||||
Pixel redMask = 0;
|
||||
Pixel greenMask = 0;
|
||||
Pixel blueMask = 0;
|
||||
|
||||
depth = dmxScreen->beDepths[i];
|
||||
for (j = 0; j < dmxScreen->beNumVisuals; j++) {
|
||||
XVisualInfo *vi;
|
||||
|
||||
vi = &dmxScreen->beVisuals[j];
|
||||
if (vi->depth == depth) {
|
||||
/* Assume the masks are all the same. */
|
||||
visuals |= (1 << vi->class);
|
||||
bitsPerRgb = vi->bits_per_rgb;
|
||||
redMask = vi->red_mask;
|
||||
greenMask = vi->green_mask;
|
||||
blueMask = vi->blue_mask;
|
||||
if (j == dmxScreen->beDefVisualIndex) {
|
||||
preferredClass = vi->class;
|
||||
}
|
||||
}
|
||||
}
|
||||
miSetVisualTypesAndMasks(depth, visuals, bitsPerRgb, preferredClass,
|
||||
redMask, greenMask, blueMask);
|
||||
}
|
||||
|
||||
fbScreenInit(pScreen,
|
||||
dmxShadowFB ? dmxScreen->shadow : NULL,
|
||||
dmxScreen->scrnWidth,
|
||||
dmxScreen->scrnHeight,
|
||||
dmxScreen->beXDPI,
|
||||
dmxScreen->beXDPI,
|
||||
dmxScreen->scrnWidth,
|
||||
dmxScreen->beBPP);
|
||||
#ifdef RENDER
|
||||
(void)dmxPictureInit(pScreen, 0, 0);
|
||||
#endif
|
||||
|
||||
if (dmxShadowFB && !shadowInit(pScreen, dmxShadowUpdateProc, NULL))
|
||||
return FALSE;
|
||||
|
||||
miInitializeBackingStore(pScreen);
|
||||
|
||||
if (dmxShadowFB) {
|
||||
miDCInitialize(pScreen, &dmxPointerCursorFuncs);
|
||||
} else {
|
||||
MAXSCREENSALLOC(dmxCursorGeneration);
|
||||
if (dmxCursorGeneration[idx] != serverGeneration) {
|
||||
if (!(miPointerInitialize(pScreen,
|
||||
&dmxPointerSpriteFuncs,
|
||||
&dmxPointerCursorFuncs,
|
||||
FALSE)))
|
||||
return FALSE;
|
||||
|
||||
dmxCursorGeneration[idx] = serverGeneration;
|
||||
}
|
||||
}
|
||||
|
||||
DMX_WRAP(CloseScreen, dmxCloseScreen, dmxScreen, pScreen);
|
||||
DMX_WRAP(SaveScreen, dmxSaveScreen, dmxScreen, pScreen);
|
||||
|
||||
dmxBEScreenInit(idx, pScreen);
|
||||
|
||||
if (!dmxShadowFB) {
|
||||
/* Wrap GC functions */
|
||||
DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
|
||||
|
||||
/* Wrap Window functions */
|
||||
DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen);
|
||||
DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen);
|
||||
DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen);
|
||||
DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen,
|
||||
pScreen);
|
||||
DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen);
|
||||
DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen);
|
||||
DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen);
|
||||
DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen);
|
||||
DMX_WRAP(PaintWindowBackground, dmxPaintWindowBackground, dmxScreen,
|
||||
pScreen);
|
||||
DMX_WRAP(PaintWindowBorder, dmxPaintWindowBorder, dmxScreen, pScreen);
|
||||
DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen);
|
||||
|
||||
DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
|
||||
DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
|
||||
|
||||
DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
|
||||
|
||||
/* Wrap Image functions */
|
||||
DMX_WRAP(GetImage, dmxGetImage, dmxScreen, pScreen);
|
||||
DMX_WRAP(GetSpans, dmxGetSpans, dmxScreen, pScreen);
|
||||
|
||||
/* Wrap Pixmap functions */
|
||||
DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen);
|
||||
DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen);
|
||||
DMX_WRAP(BitmapToRegion, dmxBitmapToRegion, dmxScreen, pScreen);
|
||||
|
||||
/* Wrap Font functions */
|
||||
DMX_WRAP(RealizeFont, dmxRealizeFont, dmxScreen, pScreen);
|
||||
DMX_WRAP(UnrealizeFont, dmxUnrealizeFont, dmxScreen, pScreen);
|
||||
|
||||
/* Wrap Colormap functions */
|
||||
DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen);
|
||||
DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen);
|
||||
DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
|
||||
DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen);
|
||||
|
||||
#ifdef SHAPE
|
||||
/* Wrap Shape functions */
|
||||
DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!dmxCreateDefColormap(pScreen))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Close the \a pScreen resources on the back-end server. */
|
||||
void dmxBECloseScreen(ScreenPtr pScreen)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
int i;
|
||||
|
||||
/* Restore the back-end screen-saver and DPMS state. */
|
||||
dmxDPMSTerm(dmxScreen);
|
||||
|
||||
/* Free the screen resources */
|
||||
|
||||
XFreeCursor(dmxScreen->beDisplay, dmxScreen->noCursor);
|
||||
dmxScreen->noCursor = (Cursor)0;
|
||||
|
||||
XUnmapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
|
||||
XDestroyWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
|
||||
dmxScreen->scrnWin = (Window)0;
|
||||
|
||||
if (dmxShadowFB) {
|
||||
/* Free the shadow GC and image assocated with the back-end server */
|
||||
XFreeGC(dmxScreen->beDisplay, dmxScreen->shadowGC);
|
||||
dmxScreen->shadowGC = NULL;
|
||||
XFree(dmxScreen->shadowFBImage);
|
||||
dmxScreen->shadowFBImage = NULL;
|
||||
} else {
|
||||
/* Free the default drawables */
|
||||
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
|
||||
XFreePixmap(dmxScreen->beDisplay, dmxScreen->scrnDefDrawables[i]);
|
||||
dmxScreen->scrnDefDrawables[i] = (Drawable)0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free resources allocated during initialization (in dmxinit.c) */
|
||||
for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
|
||||
XFreeColormap(dmxScreen->beDisplay, dmxScreen->beDefColormaps[i]);
|
||||
xfree(dmxScreen->beDefColormaps);
|
||||
dmxScreen->beDefColormaps = NULL;
|
||||
|
||||
#if 0
|
||||
/* Do not free visuals, depths and pixmap formats here. Free them
|
||||
* in dmxCloseScreen() instead -- see comment below. */
|
||||
XFree(dmxScreen->beVisuals);
|
||||
dmxScreen->beVisuals = NULL;
|
||||
|
||||
XFree(dmxScreen->beDepths);
|
||||
dmxScreen->beDepths = NULL;
|
||||
|
||||
XFree(dmxScreen->bePixmapFormats);
|
||||
dmxScreen->bePixmapFormats = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef GLXEXT
|
||||
if (dmxScreen->glxVisuals) {
|
||||
XFree(dmxScreen->glxVisuals);
|
||||
dmxScreen->glxVisuals = NULL;
|
||||
dmxScreen->numGlxVisuals = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Close display */
|
||||
XCloseDisplay(dmxScreen->beDisplay);
|
||||
dmxScreen->beDisplay = NULL;
|
||||
}
|
||||
|
||||
/** Close screen number \a idx. */
|
||||
Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
|
||||
|
||||
/* Reset the proc vectors */
|
||||
if (idx == 0) {
|
||||
#ifdef RENDER
|
||||
dmxResetRender();
|
||||
#endif
|
||||
dmxResetFonts();
|
||||
}
|
||||
|
||||
if (dmxShadowFB) {
|
||||
/* Free the shadow framebuffer */
|
||||
xfree(dmxScreen->shadow);
|
||||
} else {
|
||||
|
||||
#ifdef SHAPE
|
||||
/* Unwrap Shape functions */
|
||||
DMX_UNWRAP(SetShape, dmxScreen, pScreen);
|
||||
#endif
|
||||
|
||||
/* Unwrap the pScreen functions */
|
||||
DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
|
||||
|
||||
DMX_UNWRAP(CreateWindow, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(PositionWindow, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(RestackWindow, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(WindowExposures, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(PaintWindowBackground, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(PaintWindowBorder, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(CopyWindow, dmxScreen, pScreen);
|
||||
|
||||
DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
|
||||
|
||||
DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
|
||||
|
||||
DMX_UNWRAP(GetImage, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(GetSpans, dmxScreen, pScreen);
|
||||
|
||||
DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(BitmapToRegion, dmxScreen, pScreen);
|
||||
|
||||
DMX_UNWRAP(RealizeFont, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(UnrealizeFont, dmxScreen, pScreen);
|
||||
|
||||
DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
|
||||
DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
|
||||
}
|
||||
|
||||
DMX_UNWRAP(SaveScreen, dmxScreen, pScreen);
|
||||
|
||||
if (dmxScreen->beDisplay) {
|
||||
dmxBECloseScreen(pScreen);
|
||||
|
||||
#if 1
|
||||
/* Free visuals, depths and pixmap formats here so that they
|
||||
* won't be freed when a screen is detached, thereby allowing
|
||||
* the screen to be reattached to be compared to the one
|
||||
* previously removed.
|
||||
*/
|
||||
XFree(dmxScreen->beVisuals);
|
||||
dmxScreen->beVisuals = NULL;
|
||||
|
||||
XFree(dmxScreen->beDepths);
|
||||
dmxScreen->beDepths = NULL;
|
||||
|
||||
XFree(dmxScreen->bePixmapFormats);
|
||||
dmxScreen->bePixmapFormats = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
DMX_UNWRAP(CloseScreen, dmxScreen, pScreen);
|
||||
return pScreen->CloseScreen(idx, pScreen);
|
||||
}
|
||||
|
||||
static Bool dmxSaveScreen(ScreenPtr pScreen, int what)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
if (dmxScreen->beDisplay) {
|
||||
switch (what) {
|
||||
case SCREEN_SAVER_OFF:
|
||||
case SCREEN_SAVER_FORCER:
|
||||
XResetScreenSaver(dmxScreen->beDisplay);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
break;
|
||||
case SCREEN_SAVER_ON:
|
||||
case SCREEN_SAVER_CYCLE:
|
||||
XActivateScreenSaver(dmxScreen->beDisplay);
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
52
hw/dmx/dmxscrinit.h
Normal file
52
hw/dmx/dmxscrinit.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
* David H. Dawes <dawes@xfree86.org>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for screen initialization. \see dmxscrinit.c */
|
||||
|
||||
#ifndef DMXSCRINIT_H
|
||||
#define DMXSCRINIT_H
|
||||
|
||||
#include "scrnintstr.h"
|
||||
|
||||
/** Private index. \see dmxscrrinit.c \see input/dmxconcole.c */
|
||||
extern int dmxScreenPrivateIndex;
|
||||
|
||||
extern Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]);
|
||||
|
||||
extern void dmxBEScreenInit(int idx, ScreenPtr pScreen);
|
||||
extern void dmxBECloseScreen(ScreenPtr pScreen);
|
||||
|
||||
#endif /* DMXSCRINIT_H */
|
||||
68
hw/dmx/dmxshadow.c
Normal file
68
hw/dmx/dmxshadow.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
* David H. Dawes <dawes@xfree86.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dmxshadow.h"
|
||||
|
||||
/** \file
|
||||
* This file provides support for the shadow frame buffer. */
|
||||
|
||||
/** Update the screen from the shadow frame buffer. */
|
||||
void dmxShadowUpdateProc(ScreenPtr pScreen, shadowBufPtr pBuf)
|
||||
{
|
||||
RegionPtr damage = &pBuf->damage;
|
||||
int nbox = REGION_NUM_RECTS(damage);
|
||||
BoxPtr pbox = REGION_RECTS(damage);
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
return;
|
||||
|
||||
while (nbox--) {
|
||||
XPutImage(dmxScreen->beDisplay,
|
||||
dmxScreen->scrnWin,
|
||||
dmxScreen->shadowGC,
|
||||
dmxScreen->shadowFBImage,
|
||||
pbox->x1, pbox->y1,
|
||||
pbox->x1, pbox->y1,
|
||||
pbox->x2 - pbox->x1,
|
||||
pbox->y2 - pbox->y1);
|
||||
|
||||
pbox++;
|
||||
}
|
||||
|
||||
dmxSync(dmxScreen, FALSE);
|
||||
}
|
||||
47
hw/dmx/dmxshadow.h
Normal file
47
hw/dmx/dmxshadow.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
* David H. Dawes <dawes@xfree86.org>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for shadow framebuffer support. \see dmxshadow.c */
|
||||
|
||||
#ifndef DMXSHADOW_H
|
||||
#define DMXSHADOW_H
|
||||
|
||||
#include "shadow.h"
|
||||
#include "scrnintstr.h"
|
||||
|
||||
extern void dmxShadowUpdateProc(ScreenPtr pScreen, shadowBufPtr pBuf);
|
||||
|
||||
#endif /* DMXSHADOW_H */
|
||||
219
hw/dmx/dmxstat.c
Normal file
219
hw/dmx/dmxstat.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002, 2003 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
|
||||
*
|
||||
* The DMX server code is written to call #dmxSync() whenever an XSync()
|
||||
* might be necessary. However, since XSync() requires a two way
|
||||
* communication with the other X server, eliminating unnecessary
|
||||
* XSync() calls is a key performance optimization. Support for this
|
||||
* optimization is provided in #dmxsync.c. This file provides routines
|
||||
* that evaluate this optimization by counting the number of XSync()
|
||||
* calls and monitoring their latency. This functionality can be turned
|
||||
* on using the -stat command-line parameter. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxstat.h"
|
||||
#include "dmxlog.h"
|
||||
#include "Xos.h" /* For sys/time.h */
|
||||
|
||||
/** Used to compute a running average of value. */
|
||||
typedef struct _DMXStatAvg {
|
||||
int pos;
|
||||
int count;
|
||||
unsigned long value[DMX_STAT_LENGTH];
|
||||
} DMXStatAvg;
|
||||
|
||||
/** Statistical information about XSync calls. */
|
||||
struct _DMXStatInfo {
|
||||
unsigned long syncCount;
|
||||
unsigned long oldSyncCount;
|
||||
|
||||
DMXStatAvg usec;
|
||||
DMXStatAvg pending;
|
||||
|
||||
unsigned long bins[DMX_STAT_BINS];
|
||||
};
|
||||
|
||||
/* Interval in mS between statistic message log entries. */
|
||||
int dmxStatInterval;
|
||||
static int dmxStatDisplays;
|
||||
static OsTimerPtr dmxStatTimer;
|
||||
|
||||
/** Return the number of microseconds as an unsigned long.
|
||||
* Unfortunately, this is only useful for intervals < about 4 sec. */
|
||||
static unsigned long usec(struct timeval *stop, struct timeval *start)
|
||||
{
|
||||
return (stop->tv_sec - start->tv_sec) * 1000000
|
||||
+ stop->tv_usec - start->tv_usec;
|
||||
}
|
||||
|
||||
static unsigned long avg(DMXStatAvg *data, unsigned long *max)
|
||||
{
|
||||
unsigned long sum;
|
||||
int i;
|
||||
|
||||
*max = 0;
|
||||
if (!data->count) return 0;
|
||||
|
||||
for (i = 0, sum = 0; i < data->count; i++) {
|
||||
if (data->value[i] > *max) *max = data->value[i];
|
||||
sum += data->value[i];
|
||||
}
|
||||
return sum / data->count;
|
||||
}
|
||||
|
||||
/** Turn on XSync statistic gathering and printing. Print every \a
|
||||
* interval seconds, with lines for the first \a displays. If \a
|
||||
* interval is NULL, 1 will be used. If \a displays is NULL, 0 will be
|
||||
* used (meaning a line for every display will be printed). Note that
|
||||
* this function takes string arguments because it will usually be
|
||||
* called from #ddxProcessArgument in #dmxinit.c. */
|
||||
void dmxStatActivate(const char *interval, const char *displays)
|
||||
{
|
||||
dmxStatInterval = (interval ? atoi(interval) : 1) * 1000;
|
||||
dmxStatDisplays = (displays ? atoi(displays) : 0);
|
||||
|
||||
if (dmxStatInterval < 1000) dmxStatInterval = 1000;
|
||||
if (dmxStatDisplays < 0) dmxStatDisplays = 0;
|
||||
}
|
||||
|
||||
/** Allocate a \a DMXStatInfo structure. */
|
||||
DMXStatInfo *dmxStatAlloc(void)
|
||||
{
|
||||
DMXStatInfo *pt = malloc(sizeof(*pt));
|
||||
memset(pt, 0, sizeof(*pt));
|
||||
return pt;
|
||||
}
|
||||
|
||||
/** Free the memory used by a \a DMXStatInfo structure. */
|
||||
void dmxStatFree(DMXStatInfo *pt)
|
||||
{
|
||||
if (pt) free(pt);
|
||||
}
|
||||
|
||||
static void dmxStatValue(DMXStatAvg *data, unsigned long value)
|
||||
{
|
||||
if (data->count != DMX_STAT_LENGTH) ++data->count;
|
||||
if (data->pos >= DMX_STAT_LENGTH-1) data->pos = 0;
|
||||
data->value[data->pos++] = value;
|
||||
}
|
||||
|
||||
/** Note that a XSync() was just done on \a dmxScreen with the \a start
|
||||
* and \a stop times (from gettimeofday()) and the number of
|
||||
* pending-but-not-yet-processed XSync requests. This routine is called
|
||||
* from #dmxDoSync in #dmxsync.c */
|
||||
void dmxStatSync(DMXScreenInfo *dmxScreen,
|
||||
struct timeval *stop, struct timeval *start,
|
||||
unsigned long pending)
|
||||
{
|
||||
DMXStatInfo *s = dmxScreen->stat;
|
||||
unsigned long elapsed = usec(stop, start);
|
||||
unsigned long thresh;
|
||||
int i;
|
||||
|
||||
++s->syncCount;
|
||||
dmxStatValue(&s->usec, elapsed);
|
||||
dmxStatValue(&s->pending, pending);
|
||||
|
||||
for (i = 0, thresh = DMX_STAT_BIN0; i < DMX_STAT_BINS-1; i++) {
|
||||
if (elapsed < thresh) {
|
||||
++s->bins[i];
|
||||
break;
|
||||
}
|
||||
thresh *= DMX_STAT_BINMULT;
|
||||
}
|
||||
if (i == DMX_STAT_BINS-1) ++s->bins[i];
|
||||
}
|
||||
|
||||
/* Actually do the work of printing out the human-readable message. */
|
||||
static CARD32 dmxStatCallback(OsTimerPtr timer, CARD32 t, pointer arg)
|
||||
{
|
||||
int i, j;
|
||||
static int header = 0;
|
||||
int limit = dmxNumScreens;
|
||||
|
||||
if (!dmxNumScreens) {
|
||||
header = 0;
|
||||
return DMX_STAT_INTERVAL;
|
||||
}
|
||||
|
||||
if (!header++ || !(header % 10)) {
|
||||
dmxLog(dmxDebug,
|
||||
" S SyncCount Sync/s avSync mxSync avPend mxPend | "
|
||||
"<10ms <1s >1s\n");
|
||||
}
|
||||
|
||||
if (dmxStatDisplays && dmxStatDisplays < limit) limit = dmxStatDisplays;
|
||||
for (i = 0; i < limit; i++) {
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
||||
DMXStatInfo *s = dmxScreen->stat;
|
||||
unsigned long aSync, mSync;
|
||||
unsigned long aPend, mPend;
|
||||
|
||||
if (!s) continue;
|
||||
|
||||
aSync = avg(&s->usec, &mSync);
|
||||
aPend = avg(&s->pending, &mPend);
|
||||
dmxLog(dmxDebug, "%2d %9lu %7lu %6lu %6lu %6lu %6lu |",
|
||||
i, /* S */
|
||||
s->syncCount, /* SyncCount */
|
||||
(s->syncCount
|
||||
- s->oldSyncCount) * 1000 / dmxStatInterval, /* Sync/s */
|
||||
aSync, /* us/Sync */
|
||||
mSync, /* max/Sync */
|
||||
aPend, /* avgPend */
|
||||
mPend); /* maxPend */
|
||||
for (j = 0; j < DMX_STAT_BINS; j++)
|
||||
dmxLogCont(dmxDebug, " %5lu", s->bins[j]);
|
||||
dmxLogCont(dmxDebug, "\n");
|
||||
|
||||
/* Reset/clear */
|
||||
s->oldSyncCount = s->syncCount;
|
||||
for (j = 0; j < DMX_STAT_BINS; j++) s->bins[j] = 0;
|
||||
}
|
||||
return DMX_STAT_INTERVAL; /* Place on queue again */
|
||||
}
|
||||
|
||||
/** Try to initialize the statistic gathering and printing routines.
|
||||
* Initialization only takes place if #dmxStatActivate has already been
|
||||
* called. We don't need the same generation protection that we used in
|
||||
* dmxSyncInit because our timer is always on a queue -- hence, server
|
||||
* generation will always free it. */
|
||||
void dmxStatInit(void)
|
||||
{
|
||||
if (dmxStatInterval)
|
||||
dmxStatTimer = TimerSet(NULL, 0,
|
||||
dmxStatInterval, dmxStatCallback, NULL);
|
||||
}
|
||||
56
hw/dmx/dmxstat.h
Normal file
56
hw/dmx/dmxstat.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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
|
||||
* Interface for statistic gathering interface. \see dmxstat.c */
|
||||
|
||||
#ifndef _DMXSTAT_H_
|
||||
#define _DMXSTAT_H_
|
||||
|
||||
#define DMX_STAT_LENGTH 10 /**< number of events for moving average */
|
||||
#define DMX_STAT_INTERVAL 1000 /**< msec between printouts */
|
||||
#define DMX_STAT_BINS 3 /**< number of bins */
|
||||
#define DMX_STAT_BIN0 10000 /**< us for bin[0] */
|
||||
#define DMX_STAT_BINMULT 100 /**< multiplier for next bin[] */
|
||||
|
||||
extern int dmxStatInterval; /**< Only for dmxstat.c and dmxsync.c */
|
||||
extern void dmxStatActivate(const char *interval, const char *displays);
|
||||
extern DMXStatInfo *dmxStatAlloc(void);
|
||||
extern void dmxStatFree(DMXStatInfo *);
|
||||
extern void dmxStatInit(void);
|
||||
extern void dmxStatSync(DMXScreenInfo *dmxScreen,
|
||||
struct timeval *stop, struct timeval *start,
|
||||
unsigned long pending);
|
||||
|
||||
#endif
|
||||
190
hw/dmx/dmxsync.c
Normal file
190
hw/dmx/dmxsync.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002-2004 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
|
||||
*
|
||||
* The DMX server code is written to call #dmxSync() whenever an XSync()
|
||||
* might be necessary. However, since XSync() requires a two way
|
||||
* communication with the other X server, eliminating unnecessary
|
||||
* XSync() calls is a key performance optimization. Support for this
|
||||
* optimization is provided here. Statistics about XSync() calls and
|
||||
* latency are gathered in #dmxstat.c.
|
||||
*
|
||||
* During the initial conversion from calling XSync() immediately to the
|
||||
* XSync() batching method implemented in this file, it was noted that,
|
||||
* out of more than 300 \a x11perf tests, 8 tests became more than 100
|
||||
* times faster, with 68 more than 50X faster, 114 more than 10X faster,
|
||||
* and 181 more than 2X faster. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxsync.h"
|
||||
#include "dmxstat.h"
|
||||
#include "dmxlog.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
static int dmxSyncInterval = 100; /* Default interval in milliseconds */
|
||||
static OsTimerPtr dmxSyncTimer;
|
||||
static int dmxSyncPending;
|
||||
|
||||
static void dmxDoSync(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
dmxScreen->needsSync = FALSE;
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
return; /* FIXME: Is this correct behavior for sync stats? */
|
||||
|
||||
if (!dmxStatInterval) {
|
||||
XSync(dmxScreen->beDisplay, False);
|
||||
} else {
|
||||
struct timeval start, stop;
|
||||
|
||||
gettimeofday(&start, 0);
|
||||
XSync(dmxScreen->beDisplay, False);
|
||||
gettimeofday(&stop, 0);
|
||||
dmxStatSync(dmxScreen, &stop, &start, dmxSyncPending);
|
||||
}
|
||||
}
|
||||
|
||||
static CARD32 dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dmxSyncPending) {
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
||||
if (dmxScreen->needsSync) dmxDoSync(dmxScreen);
|
||||
}
|
||||
}
|
||||
dmxSyncPending = 0;
|
||||
return 0; /* Do not place on queue again */
|
||||
}
|
||||
|
||||
static void dmxSyncBlockHandler(pointer blockData, OSTimePtr pTimeout,
|
||||
pointer pReadMask)
|
||||
{
|
||||
TimerForce(dmxSyncTimer);
|
||||
}
|
||||
|
||||
static void dmxSyncWakeupHandler(pointer blockData, int result,
|
||||
pointer pReadMask)
|
||||
{
|
||||
}
|
||||
|
||||
/** Request the XSync() batching optimization with the specified \a
|
||||
* interval (in mS). If the \a interval is 0, 100mS is used. If the \a
|
||||
* interval is less than 0, then the XSync() batching optimization is
|
||||
* not requested (e.g., so the -syncbatch -1 command line option can
|
||||
* turn off the default 100mS XSync() batching).
|
||||
*
|
||||
* Note that the parameter to this routine is a string, since it will
|
||||
* usually be called from #ddxProcessArgument in #dmxinit.c */
|
||||
void dmxSyncActivate(const char *interval)
|
||||
{
|
||||
dmxSyncInterval = (interval ? atoi(interval) : 100);
|
||||
|
||||
if (dmxSyncInterval < 0) dmxSyncInterval = 0;
|
||||
}
|
||||
|
||||
/** Initialize the XSync() batching optimization, but only if
|
||||
* #dmxSyncActivate was last called with a non-negative value. */
|
||||
void dmxSyncInit(void)
|
||||
{
|
||||
if (dmxSyncInterval) {
|
||||
RegisterBlockAndWakeupHandlers(dmxSyncBlockHandler,
|
||||
dmxSyncWakeupHandler,
|
||||
NULL);
|
||||
dmxLog(dmxInfo, "XSync batching with %d ms interval\n",
|
||||
dmxSyncInterval);
|
||||
} else {
|
||||
dmxLog(dmxInfo, "XSync batching disabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** Request an XSync() to the display used by \a dmxScreen. If \a now
|
||||
* is TRUE, call XSync() immediately instead of waiting for the next
|
||||
* XSync() batching point. Note that if XSync() batching was deselected
|
||||
* with #dmxSyncActivate() before #dmxSyncInit() was called, then no
|
||||
* XSync() batching is performed and this function always calles XSync()
|
||||
* immediately.
|
||||
*
|
||||
* (Note that this function uses TimerSet but works correctly in the
|
||||
* face of a server generation. See the source for details.)
|
||||
*
|
||||
* If \a dmxScreen is \a NULL, then all pending syncs will be flushed
|
||||
* immediately.
|
||||
*/
|
||||
void dmxSync(DMXScreenInfo *dmxScreen, Bool now)
|
||||
{
|
||||
static unsigned long dmxGeneration = 0;
|
||||
|
||||
if (dmxSyncInterval) {
|
||||
if (dmxGeneration != serverGeneration) {
|
||||
/* Server generation does a TimerInit, which frees all
|
||||
* timers. So, at this point dmxSyncTimer is either:
|
||||
* 1) NULL, iff dmxGeneration == 0,
|
||||
* 2) freed, if it was on a queue (dmxSyncPending != 0), or
|
||||
* 3) allocated, if it wasn't on a queue (dmxSyncPending == 0)
|
||||
*/
|
||||
if (dmxSyncTimer && !dmxSyncPending) xfree(dmxSyncTimer);
|
||||
dmxSyncTimer = NULL;
|
||||
now = TRUE;
|
||||
dmxGeneration = serverGeneration;
|
||||
}
|
||||
/* Queue sync */
|
||||
if (dmxScreen) {
|
||||
dmxScreen->needsSync = TRUE;
|
||||
++dmxSyncPending;
|
||||
}
|
||||
|
||||
/* Do sync or set time for later */
|
||||
if (now || !dmxScreen) {
|
||||
if (!TimerForce(dmxSyncTimer)) dmxSyncCallback(NULL, 0, NULL);
|
||||
/* At this point, dmxSyncPending == 0 because
|
||||
* dmxSyncCallback must have been called. */
|
||||
if (dmxSyncPending)
|
||||
dmxLog(dmxFatal, "dmxSync(%s,%d): dmxSyncPending = %d\n",
|
||||
dmxScreen ? dmxScreen->name : "", now, dmxSyncPending);
|
||||
} else {
|
||||
dmxScreen->needsSync = TRUE;
|
||||
if (dmxSyncPending == 1)
|
||||
dmxSyncTimer = TimerSet(dmxSyncTimer, 0, dmxSyncInterval,
|
||||
dmxSyncCallback, NULL);
|
||||
}
|
||||
} else {
|
||||
/* If dmxSyncInterval is not being used,
|
||||
* then all the backends are already
|
||||
* up-to-date. */
|
||||
if (dmxScreen) dmxDoSync(dmxScreen);
|
||||
}
|
||||
}
|
||||
44
hw/dmx/dmxsync.h
Normal file
44
hw/dmx/dmxsync.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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
|
||||
* Interface for sync support. \see dmxsync.c */
|
||||
|
||||
#ifndef _DMXSYNC_H_
|
||||
#define _DMXSYNC_H_
|
||||
|
||||
extern void dmxSyncActivate(const char *interval);
|
||||
extern void dmxSyncInit(void);
|
||||
extern void dmxSync(DMXScreenInfo *dmxScreen, Bool now);
|
||||
#endif
|
||||
137
hw/dmx/dmxvisual.c
Normal file
137
hw/dmx/dmxvisual.c
Normal file
@@ -0,0 +1,137 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* This file provides support for visuals. */
|
||||
|
||||
#include "dmx.h"
|
||||
#include "dmxvisual.h"
|
||||
|
||||
#include "scrnintstr.h"
|
||||
|
||||
#ifdef GLXEXT
|
||||
|
||||
#include <GL/glxint.h>
|
||||
|
||||
extern VisualID glxMatchVisualInConfigList(ScreenPtr pScreen,
|
||||
VisualPtr pVisual,
|
||||
__GLXvisualConfig *configs,
|
||||
int nconfigs);
|
||||
|
||||
static Visual *dmxLookupGLXVisual(ScreenPtr pScreen, VisualPtr pVisual)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
int j;
|
||||
VisualID vid;
|
||||
|
||||
vid = glxMatchVisualInConfigList(pScreen, pVisual,
|
||||
dmxScreen->glxVisuals,
|
||||
dmxScreen->numGlxVisuals);
|
||||
if (vid) {
|
||||
/* Find the X visual of the matching GLX visual */
|
||||
for (j = 0; j < dmxScreen->beNumVisuals; j++)
|
||||
if (vid == dmxScreen->beVisuals[j].visualid)
|
||||
return dmxScreen->beVisuals[j].visual;
|
||||
}
|
||||
|
||||
/* No matching visual found */
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return the visual that matched \a pVisual. */
|
||||
Visual *dmxLookupVisual(ScreenPtr pScreen, VisualPtr pVisual)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
int i;
|
||||
#ifdef GLXEXT
|
||||
Visual *retval;
|
||||
#endif
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
return NULL;
|
||||
|
||||
#ifdef GLXEXT
|
||||
if ((retval = dmxLookupGLXVisual(pScreen, pVisual)))
|
||||
return retval;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < dmxScreen->beNumVisuals; i++) {
|
||||
if (pVisual->class == dmxScreen->beVisuals[i].class &&
|
||||
pVisual->bitsPerRGBValue == dmxScreen->beVisuals[i].bits_per_rgb &&
|
||||
pVisual->ColormapEntries == dmxScreen->beVisuals[i].colormap_size &&
|
||||
pVisual->nplanes == dmxScreen->beVisuals[i].depth &&
|
||||
pVisual->redMask == dmxScreen->beVisuals[i].red_mask &&
|
||||
pVisual->greenMask == dmxScreen->beVisuals[i].green_mask &&
|
||||
pVisual->blueMask == dmxScreen->beVisuals[i].blue_mask) {
|
||||
return dmxScreen->beVisuals[i].visual;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Return the visual that matched the \a vid. */
|
||||
Visual *dmxLookupVisualFromID(ScreenPtr pScreen, VisualID vid)
|
||||
{
|
||||
Visual *visual;
|
||||
int i;
|
||||
|
||||
if (!dmxScreens[pScreen->myNum].beDisplay)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < pScreen->numVisuals; i++) {
|
||||
if (pScreen->visuals[i].vid == vid) {
|
||||
visual = dmxLookupVisual(pScreen, &pScreen->visuals[i]);
|
||||
if (visual) return visual;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Return the colormap for the \a visual. */
|
||||
Colormap dmxColormapFromDefaultVisual(ScreenPtr pScreen, Visual *visual)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
int i;
|
||||
|
||||
if (dmxScreen->beDisplay) {
|
||||
for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
|
||||
if (visual == dmxScreen->beVisuals[i].visual)
|
||||
return dmxScreen->beDefColormaps[i];
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
48
hw/dmx/dmxvisual.h
Normal file
48
hw/dmx/dmxvisual.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2002 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for visual support. \see dmxvisual.c */
|
||||
|
||||
#ifndef DMXVISUAL_H
|
||||
#define DMXVISUAL_H
|
||||
|
||||
#include "scrnintstr.h"
|
||||
|
||||
extern Visual *dmxLookupVisual(ScreenPtr pScreen, VisualPtr pVisual);
|
||||
extern Visual *dmxLookupVisualFromID(ScreenPtr pScreen, VisualID vid);
|
||||
extern Colormap dmxColormapFromDefaultVisual(ScreenPtr pScreen,
|
||||
Visual *visual);
|
||||
|
||||
#endif /* DMXVISUAL_H */
|
||||
1083
hw/dmx/dmxwindow.c
Normal file
1083
hw/dmx/dmxwindow.c
Normal file
File diff suppressed because it is too large
Load Diff
149
hw/dmx/dmxwindow.h
Normal file
149
hw/dmx/dmxwindow.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2001-2004 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:
|
||||
* Kevin E. Martin <kem@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Interface for window support. \see dmxwindow.c */
|
||||
|
||||
#ifndef DMXWINDOW_H
|
||||
#define DMXWINDOW_H
|
||||
|
||||
#include "windowstr.h"
|
||||
|
||||
/** Window private area. */
|
||||
typedef struct _dmxWinPriv {
|
||||
Window window;
|
||||
Bool offscreen;
|
||||
Bool mapped;
|
||||
Bool restacked;
|
||||
unsigned long attribMask;
|
||||
Colormap cmap;
|
||||
Visual *visual;
|
||||
#ifdef SHAPE
|
||||
Bool isShaped;
|
||||
#endif
|
||||
#ifdef RENDER
|
||||
Bool hasPict;
|
||||
#endif
|
||||
#ifdef GLXEXT
|
||||
void *swapGroup;
|
||||
int barrier;
|
||||
void (*windowDestroyed)(WindowPtr);
|
||||
void (*windowUnmapped)(WindowPtr);
|
||||
#endif
|
||||
} dmxWinPrivRec, *dmxWinPrivPtr;
|
||||
|
||||
|
||||
extern Bool dmxInitWindow(ScreenPtr pScreen);
|
||||
|
||||
extern Window dmxCreateRootWindow(WindowPtr pWindow);
|
||||
|
||||
extern void dmxGetDefaultWindowAttributes(WindowPtr pWindow,
|
||||
Colormap *cmap,
|
||||
Visual **visual);
|
||||
extern void dmxCreateAndRealizeWindow(WindowPtr pWindow, Bool doSync);
|
||||
|
||||
extern Bool dmxCreateWindow(WindowPtr pWindow);
|
||||
extern Bool dmxDestroyWindow(WindowPtr pWindow);
|
||||
extern Bool dmxPositionWindow(WindowPtr pWindow, int x, int y);
|
||||
extern Bool dmxChangeWindowAttributes(WindowPtr pWindow, unsigned long mask);
|
||||
extern Bool dmxRealizeWindow(WindowPtr pWindow);
|
||||
extern Bool dmxUnrealizeWindow(WindowPtr pWindow);
|
||||
extern void dmxRestackWindow(WindowPtr pWindow, WindowPtr pOldNextSib);
|
||||
extern void dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn,
|
||||
RegionPtr other_exposed);
|
||||
extern void dmxPaintWindowBackground(WindowPtr pWindow, RegionPtr pRegion,
|
||||
int what);
|
||||
extern void dmxPaintWindowBorder(WindowPtr pWindow, RegionPtr pRegion,
|
||||
int what);
|
||||
extern void dmxCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg,
|
||||
RegionPtr prgnSrc);
|
||||
|
||||
extern void dmxResizeWindow(WindowPtr pWindow, int x, int y,
|
||||
unsigned int w, unsigned int h, WindowPtr pSib);
|
||||
extern void dmxReparentWindow(WindowPtr pWindow, WindowPtr pPriorParent);
|
||||
|
||||
extern void dmxChangeBorderWidth(WindowPtr pWindow, unsigned int width);
|
||||
|
||||
extern void dmxResizeScreenWindow(ScreenPtr pScreen,
|
||||
int x, int y, int w, int h);
|
||||
extern void dmxResizeRootWindow(WindowPtr pRoot,
|
||||
int x, int y, int w, int h);
|
||||
|
||||
extern Bool dmxBEDestroyWindow(WindowPtr pWindow);
|
||||
|
||||
#ifdef SHAPE
|
||||
/* Support for shape extension */
|
||||
extern void dmxSetShape(WindowPtr pWindow);
|
||||
#endif
|
||||
|
||||
/** Private index. \see dmxwindow.c \see dmxscrinit.c */
|
||||
extern int dmxWinPrivateIndex;
|
||||
|
||||
/** Get window private pointer. */
|
||||
#define DMX_GET_WINDOW_PRIV(_pWin) \
|
||||
((dmxWinPrivPtr)(_pWin)->devPrivates[dmxWinPrivateIndex].ptr)
|
||||
|
||||
/* All of these macros are only used in dmxwindow.c */
|
||||
#define DMX_WINDOW_FUNC_PROLOGUE(_pGC) \
|
||||
do { \
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(_pGC); \
|
||||
DMX_UNWRAP(funcs, pGCPriv, (_pGC)); \
|
||||
if (pGCPriv->ops) \
|
||||
DMX_UNWRAP(ops, pGCPriv, (_pGC)); \
|
||||
} while (0)
|
||||
|
||||
#define DMX_WINDOW_FUNC_EPILOGUE(_pGC) \
|
||||
do { \
|
||||
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(_pGC); \
|
||||
DMX_WRAP(funcs, &dmxGCFuncs, pGCPriv, (_pGC)); \
|
||||
if (pGCPriv->ops) \
|
||||
DMX_WRAP(ops, &dmxGCOps, pGCPriv, (_pGC)); \
|
||||
} while (0)
|
||||
|
||||
#define DMX_WINDOW_X1(_pWin) \
|
||||
((_pWin)->drawable.x - wBorderWidth(_pWin))
|
||||
#define DMX_WINDOW_Y1(_pWin) \
|
||||
((_pWin)->drawable.y - wBorderWidth(_pWin))
|
||||
#define DMX_WINDOW_X2(_pWin) \
|
||||
((_pWin)->drawable.x + wBorderWidth(_pWin) + (_pWin)->drawable.width)
|
||||
#define DMX_WINDOW_Y2(_pWin) \
|
||||
((_pWin)->drawable.y + wBorderWidth(_pWin) + (_pWin)->drawable.height)
|
||||
|
||||
#define DMX_WINDOW_OFFSCREEN(_pWin) \
|
||||
(DMX_WINDOW_X1(_pWin) >= (_pWin)->drawable.pScreen->width || \
|
||||
DMX_WINDOW_Y1(_pWin) >= (_pWin)->drawable.pScreen->height || \
|
||||
DMX_WINDOW_X2(_pWin) <= 0 || \
|
||||
DMX_WINDOW_Y2(_pWin) <= 0)
|
||||
|
||||
#endif /* DMXWINDOW_H */
|
||||
458
hw/dmx/doc/DMXSpec-v1.txt
Normal file
458
hw/dmx/doc/DMXSpec-v1.txt
Normal file
@@ -0,0 +1,458 @@
|
||||
|
||||
|
||||
Client-to-Server DMX Extension to the X Protocol
|
||||
|
||||
$Date$, $Revision$
|
||||
|
||||
Rickard E. (Rik) Faith (faith@redhat.com)
|
||||
Kevin E. Martin (kem@redhat.com)
|
||||
|
||||
Copyright 2002,2003 Red Hat Inc., Raleigh, North Carolina.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
1. Overview
|
||||
|
||||
The client-to-server DMX extension to the X protocol (DMX) provides
|
||||
normal client applications with the ability to determine information
|
||||
about the characteristics of the Xdmx server and the back-end X
|
||||
servers that DMX is using.
|
||||
|
||||
The name for this extension is "DMX".
|
||||
|
||||
|
||||
|
||||
2. Syntactic conventions
|
||||
|
||||
This document uses the same syntactic conventions requests and data
|
||||
types as [X11R6.4].
|
||||
|
||||
|
||||
|
||||
3. Data types
|
||||
|
||||
No new data types are defined by this extension. All data types
|
||||
referenced in this document are defined in [X11R6.4].
|
||||
|
||||
|
||||
|
||||
4. Requests
|
||||
|
||||
DMXQueryVersion
|
||||
==>
|
||||
majorVersion: CARD32
|
||||
minorVersion: CARD32
|
||||
patchVersion: CARD32
|
||||
|
||||
The protocol this extension actually supports is indicated by
|
||||
majorVersion and minorVersion (patchVersion indicates the
|
||||
patchlevel and is for informational purposes only).
|
||||
|
||||
Any incompatible changes to the protocol should be indicated by
|
||||
incrementing majorVersion.
|
||||
|
||||
Small, upward-compatible changes should be indicated by incrementing
|
||||
minorVersion.
|
||||
|
||||
Servers that support the protocol defined in this document will
|
||||
return a majorVersion of 1 and a minorVersion of 1.
|
||||
|
||||
|
||||
|
||||
DMXGetScreenCount
|
||||
==>
|
||||
screenCount: CARD32
|
||||
|
||||
This request returns the number of back-end screens that the Xdmx
|
||||
server controls. A back-end screen may be managed as a regular X
|
||||
screen in the Xdmx server or may be joined with other back-end
|
||||
screens using Xinerama. (The information returned by this request
|
||||
does not change while Xdmx is running and may be cached on the
|
||||
client side.)
|
||||
|
||||
|
||||
|
||||
DMXGetScreenInformation
|
||||
physicalScreen: CARD32
|
||||
==>
|
||||
displayName: STRING8
|
||||
width: CARD16
|
||||
height: CARD16
|
||||
xoffset: INT16
|
||||
yoffset: INT16
|
||||
logicalScreen: CARD32
|
||||
xorigin: INT16
|
||||
yorigin: INT16
|
||||
|
||||
Errors: Value
|
||||
|
||||
This request returns information about individual back-end screens.
|
||||
The physicalScreen value is between 0 and screenCount-1, inclusive
|
||||
(values outside this range will result in a Value error). The
|
||||
displayname is the name used to open the display, either from the
|
||||
Xdmx command-line or from the configuration file. The width,
|
||||
height, xoffset, and yoffset values comprise a geometry
|
||||
specification (see X(7x)) for the location of the DMX window on the
|
||||
back-end screen. This request will always return non-negative
|
||||
(i.e., normalized) values for xoffset and yoffset. The
|
||||
logicalScreen value is the value of the screen that that Xdmx server
|
||||
exports to clients. When Xinerama is in use, this value is
|
||||
typically 0 for all values of physicalScreen. If Xinerama is in
|
||||
use, the xorigin and yorigin values specify where the physical
|
||||
screen is positioned in the global Xinerama coordinate system.
|
||||
Otherwise, these values are set to 0. (The information returned by
|
||||
this request does not change while Xdmx is running and may be cached
|
||||
on the client side.)
|
||||
|
||||
|
||||
|
||||
DMXGetWindowInformation
|
||||
window: CARD32
|
||||
==>
|
||||
screenCount: CARD32
|
||||
screens: LISTofCARD32
|
||||
windows: LISTofCARD32
|
||||
pos: LISTofRECTANGLE
|
||||
vis: LISTofRECTANGLE
|
||||
|
||||
Errors: Window, Alloc
|
||||
|
||||
This request computed the return values incorrectly for version 1.0
|
||||
of this protocol. Version 1.1 of this protocol conforms to this
|
||||
description.
|
||||
|
||||
Given a window ID on the Xdmx server, this request returns data
|
||||
about how the window is represented on the back-end X servers. For
|
||||
each back-end X server that displays a portion of the window, the
|
||||
following information is returned:
|
||||
1) the number of the physical screen containing that portion
|
||||
(which can be used with the DMXGetScreenInformation request
|
||||
to obtain more information about the screen),
|
||||
2) the window ID on the back-end X server of the window
|
||||
containing that portion,
|
||||
3) the position and dimensions of the window on the back-end, in
|
||||
screen coordinates, and
|
||||
4) the visible area of the window on the back-end, in
|
||||
window-relative coordinates (all zeros for windows that are
|
||||
not visible)
|
||||
Note that DMX allows multiple back-end windows to overlap in their
|
||||
view of the DMX logical window. Further, a logical window does not
|
||||
have to be completely covered by back-end windows -- there may be
|
||||
gaps.
|
||||
|
||||
As an example, consider a 500x500 window that spans the top two
|
||||
1024x768 back-end displays (A and B) of a 2048x1536 DMX display
|
||||
composed of 4 1024x768 back-end displays arranged in a cube:
|
||||
A B
|
||||
C D
|
||||
|
||||
In this case, the DMXGetWindowInformation call would return the
|
||||
following information for the 500x500 window:
|
||||
|
||||
display A: 500x500 window at 1024-250,0 (relative to back end)
|
||||
with 250x500 visible at 0,0 (relative to window origin)
|
||||
|
||||
display B: 500x500 window at -250,0 (relative to back end)
|
||||
with 250x500 visible at 250,0 (relative to window origin)
|
||||
|
||||
display C: 500x500 window at 1024-250,-768 with 0x0 visible at 0,0
|
||||
|
||||
display D: 500x500 window at -250,-768 with 0x0 visible at 0,0
|
||||
|
||||
Note that if the specified window has not yet been mapped when
|
||||
DMXGetWindowInformation is called, then a subsequent XMapWindow call
|
||||
might be buffered in xlib while requests directly to the back-end X
|
||||
servers are processed. This race condition can be solved by calling
|
||||
DMXSync before talking directly to the back-end X servers.
|
||||
|
||||
|
||||
DMXGetInputCount
|
||||
==>
|
||||
inputCount: CARD32
|
||||
|
||||
This request was first supported in version 1.1 of this protocol.
|
||||
|
||||
This request returns the number of input devices connected to the
|
||||
Xdmx server. This number is the same as that returned by
|
||||
XListInputDevices, but is available even when the XInput extension
|
||||
is not supported.
|
||||
|
||||
|
||||
|
||||
DMXGetInputInformation
|
||||
deviceId: CARD32
|
||||
==>
|
||||
inputType: CARD32
|
||||
physicalScreen: CARD32
|
||||
physicalId: CARD32
|
||||
isCore: BOOL
|
||||
sendsCore: BOOL
|
||||
name: STRING8
|
||||
|
||||
Errors: Value
|
||||
|
||||
This request was first supported in version 1.1 of this protocol.
|
||||
|
||||
This request returns information about the specified input device
|
||||
that cannot be obtained from the XListInputDeivices call. The
|
||||
deviceId is the same as that used by the XListInputDevices call, and
|
||||
must be in the range 0 to inputCount-1, inclusive (values outside
|
||||
this range will result in a Value error).
|
||||
|
||||
The value of inputType will always be value, and will be one of the
|
||||
following values:
|
||||
0 for local (and dummy) devices,
|
||||
1 for console devices, and
|
||||
2 for back-end devices.
|
||||
|
||||
For local devices, all other fields returned, except isCore and
|
||||
sendsCore, are invalid.
|
||||
|
||||
For console devices, the physicalScreen and physicalID will be
|
||||
invalid, and the name will return the name of the X server on which
|
||||
the console window is displayed.
|
||||
|
||||
For back-end devices, the physicalScreen will identify the back-end
|
||||
display and can be used as an argument to DMXGetScreenInformation to
|
||||
obtain more information; the physicalId will be the XInput device id
|
||||
on the back-end X server; and the name will be invalid (since it
|
||||
does not provide any additional information that cannot be obtained
|
||||
with DMXGetScreenInformation).
|
||||
|
||||
If isCore is True, then this device is active as a true core input
|
||||
device and will send core events. If sendsCore is True, then this
|
||||
device queried an XInput extension device, but sends core events
|
||||
instead of extension events. Note that this behavior is different
|
||||
from that of XFree86, where XInput extension devices may send both
|
||||
extension events and core events.
|
||||
|
||||
|
||||
|
||||
DMXForceWindowCreation
|
||||
window: CARD32
|
||||
==>
|
||||
|
||||
Errors: Window
|
||||
|
||||
This request was first supported in version 1.2 of this protocol.
|
||||
|
||||
When using the lazy window creation optimization, windows are not
|
||||
created on the back-end X servers until they are required. This
|
||||
request forces the immediate creation of the window requested.
|
||||
|
||||
|
||||
|
||||
DMXReconfigureScreen
|
||||
screen: CARD32
|
||||
x: INT16
|
||||
y: INT16
|
||||
==>
|
||||
status: CARD32
|
||||
|
||||
Errors: Value
|
||||
|
||||
This request was first supported in version 1.3 of this protocol.
|
||||
|
||||
This request reconfigures the screen position to coordinates (x,y)
|
||||
when using the Xinerama extension. Otherwise, it is a NOP. Illegal
|
||||
values for screen will result in a BadValue error. Other non-fatal
|
||||
errors will be returned in status.
|
||||
|
||||
|
||||
|
||||
DMXSync
|
||||
==>
|
||||
|
||||
This request was first supported in version 1.5 of this protocol.
|
||||
|
||||
This request flushes all pending protocol requests between the Xdmx
|
||||
server and each back-end X server. It is used by a client that
|
||||
talks directly to back-end X servers
|
||||
|
||||
To ensure proper synchronization semantics, this request has a
|
||||
reply, but the reply does not carry any information.
|
||||
|
||||
|
||||
|
||||
5. Events
|
||||
|
||||
No new events are defined by this extension.
|
||||
|
||||
|
||||
|
||||
6. Errors
|
||||
|
||||
No new events are defined by this extension.
|
||||
|
||||
|
||||
|
||||
7. Encoding
|
||||
|
||||
DMXQueryVersion
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 0 DMX opcode (X_DMXQueryVersion)
|
||||
2 1 request length
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 majorVersion
|
||||
4 CARD32 minorVersion
|
||||
4 CARD32 patchVersion
|
||||
12 unused
|
||||
|
||||
DMXGetScreenCount
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 1 DMX opcode (X_DMXGetScreenCount)
|
||||
2 1 request length
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 screenCount
|
||||
20 unused
|
||||
|
||||
DMXGetScreenInformation
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 2 DMX opcode (X_DMXGetScreenInformation)
|
||||
2 2 request length
|
||||
4 CARD32 physicalScreen
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 n/4+p reply length
|
||||
4 n displayNameLength
|
||||
2 CARD16 width
|
||||
2 CARD16 height
|
||||
2 INT16 xoffset
|
||||
2 INT16 yoffset
|
||||
4 CARD32 logicalScreen
|
||||
2 INT16 xorigin
|
||||
2 INT16 yorigin
|
||||
4 unused
|
||||
n displayName
|
||||
p pad(n)
|
||||
|
||||
DMXGetWindowInformation
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 3 DMX opcode (X_DMXGetWindowInformation)
|
||||
2 2 request length
|
||||
4 CARD32 window
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 n*6 reply length
|
||||
4 n screenCount
|
||||
20 unused
|
||||
n*4 LISTofCARD32 screens
|
||||
n*4 LISTofCARD32 windows
|
||||
n*8 LISTofRECTANGLE pos
|
||||
n*8 LISTofRECTANGLE vis
|
||||
|
||||
DMXGetInputCount
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 DMX opcode (X_DMXGetInputCount)
|
||||
2 1 request length
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 inputCount
|
||||
20 unused
|
||||
|
||||
DMXGetInputInformation
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 4 DMX opcode (X_DMXGetInputInformation)
|
||||
2 2 request length
|
||||
4 CARD32 deviceId
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 n/4+p reply length
|
||||
4 CARD32 inputType
|
||||
4 CARD32 physicalScreen
|
||||
4 CARD32 physicalId
|
||||
4 n nameLength
|
||||
1 BOOL isCore
|
||||
1 BOOL sendsCore
|
||||
6 unused
|
||||
n name
|
||||
p pad(n)
|
||||
|
||||
DMXForceWindowCreation
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 2 DMX opcode (X_DMXForceWindowCreation)
|
||||
2 2 request length
|
||||
4 CARD32 window
|
||||
==>
|
||||
|
||||
DMXReconfigureScreen
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 2 DMX opcode (X_DMXReconfigureScreen)
|
||||
2 2 request length
|
||||
4 CARD32 screen
|
||||
2 INT16 x
|
||||
2 INT16 y
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 status
|
||||
20 unused
|
||||
|
||||
DMXSync
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 0 DMX opcode (X_DMXSync)
|
||||
2 1 request length
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
24 unused
|
||||
|
||||
|
||||
8. Changes to existing requests/replies/events
|
||||
|
||||
No changes to existing requests, replies, or events are necessitated
|
||||
by this extension.
|
||||
|
||||
|
||||
|
||||
9. Acknowledgments
|
||||
|
||||
|
||||
|
||||
10. References
|
||||
|
||||
[X11R6.4] Robert W. Sheifler. X Window System Protocol, X Consortium
|
||||
Standard, X Version 11, Release 6.4. Available from
|
||||
xc/doc/specs/XProtocol and xc/doc/hardcopy/XProtocol.
|
||||
875
hw/dmx/doc/DMXSpec.txt
Normal file
875
hw/dmx/doc/DMXSpec.txt
Normal file
@@ -0,0 +1,875 @@
|
||||
|
||||
|
||||
Client-to-Server DMX Extension to the X Protocol
|
||||
|
||||
$Date$, $Revision$
|
||||
|
||||
Rickard E. (Rik) Faith (faith@redhat.com)
|
||||
Kevin E. Martin (kem@redhat.com)
|
||||
|
||||
Copyright 2002-2004 Red Hat Inc., Raleigh, North Carolina.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
1. Overview
|
||||
|
||||
The client-to-server DMX extension to the X protocol (DMX) provides
|
||||
normal client applications with the ability to determine information
|
||||
about the characteristics of the Xdmx server and the back-end X
|
||||
servers that DMX is using.
|
||||
|
||||
The name for this extension is "DMX".
|
||||
|
||||
|
||||
|
||||
2. Syntactic conventions
|
||||
|
||||
This document uses the same syntactic conventions requests and data
|
||||
types as [X11R6.4].
|
||||
|
||||
|
||||
|
||||
3. Data types
|
||||
|
||||
No new data types are defined by this extension. All data types
|
||||
referenced in this document are defined in [X11R6.4].
|
||||
|
||||
|
||||
|
||||
4. Requests
|
||||
|
||||
DMXQueryVersion
|
||||
==>
|
||||
majorVersion: CARD32
|
||||
minorVersion: CARD32
|
||||
patchVersion: CARD32
|
||||
|
||||
Errors: None
|
||||
|
||||
The protocol this extension actually supports is indicated by
|
||||
majorVersion and minorVersion (patchVersion indicates the
|
||||
patchlevel and is for informational purposes only).
|
||||
|
||||
Any incompatible changes to the protocol should be indicated by
|
||||
incrementing majorVersion.
|
||||
|
||||
Small, upward-compatible changes should be indicated by incrementing
|
||||
minorVersion.
|
||||
|
||||
Servers that support the protocol defined in this document will
|
||||
return a majorVersion of 2 and a minorVersion of 2.
|
||||
|
||||
(Version 1.5 was the last version in the 1.x series; version 2.0 was
|
||||
a testing version that was poorly defined.)
|
||||
|
||||
|
||||
|
||||
DMXSync
|
||||
==>
|
||||
status: CARD32
|
||||
|
||||
Errors: None
|
||||
|
||||
This request was first supported in version 1.5 of this protocol.
|
||||
The status field in the reply was introduced in version 2.0 of this
|
||||
protocol. Since the status field is ignored, no changes to the
|
||||
underlying protocol were required.
|
||||
|
||||
This request flushes all pending protocol requests between the Xdmx
|
||||
server and each back-end X server. It is used by clients that
|
||||
talk directly to back-end X servers to ensure that all pending Xdmx
|
||||
requests have reached all back-end servers and have been processed
|
||||
by those servers.
|
||||
|
||||
The value of status is always 0.
|
||||
|
||||
|
||||
|
||||
DMXForceWindowCreation
|
||||
window: CARD32
|
||||
==>
|
||||
status: CARD32
|
||||
|
||||
Errors: Window
|
||||
|
||||
This request was first supported in version 1.2 of this protocol.
|
||||
This request was changed to have a reply in version 2.0 of this
|
||||
protocol. The old version of this request was deprecated and will
|
||||
return BadImplementation.
|
||||
|
||||
When using the lazy window creation optimization, windows are not
|
||||
created on the back-end X servers until they are required. This
|
||||
request forces the immediate creation of the window requested.
|
||||
|
||||
The value of status is always 0.
|
||||
|
||||
|
||||
|
||||
|
||||
DMXGetScreenCount
|
||||
==>
|
||||
screenCount: CARD32
|
||||
|
||||
Errors: None
|
||||
|
||||
This request returns the number of screens that the Xdmx server
|
||||
controls. Since a DMX screen usually fills all of the available
|
||||
area on a back-end server, there is usually a one-to-one
|
||||
correspondence between DMX screens and backend servers. However, it
|
||||
is also possible for a DMX screen to cover only part of the
|
||||
available area on a back-end server, and for more than one DMX
|
||||
screen to occupy different parts of the visible area on the same
|
||||
back-end server.
|
||||
|
||||
A DMX screen may be managed as a regular X screen in the Xdmx server
|
||||
or may be joined with other DMX screens using Xinerama.
|
||||
|
||||
|
||||
|
||||
DMXGetScreenAttributes
|
||||
physicalScreen: CARD32
|
||||
==>
|
||||
displayName: STRING8
|
||||
logicalScreen: CARD32
|
||||
screenWindowWidth: CARD16
|
||||
screenWindowHeight: CARD16
|
||||
screenWindowXoffset: INT16
|
||||
screenWindowYoffset: INT16
|
||||
rootWindowWidth: CARD16
|
||||
rootWindowHeight: CARD16
|
||||
rootWindowXoffset: INT16
|
||||
rootWindowYoffset: INT16
|
||||
rootWindowXorigin: INT16
|
||||
rootWindowYorigin: INT16
|
||||
|
||||
Errors: Value
|
||||
|
||||
This request is new in version 2.0 of this protocol. The old
|
||||
DMXGetScreenInformation request is deprecated and will now return
|
||||
BadImplementation.
|
||||
|
||||
This request returns attributes about a single DMX screen.
|
||||
|
||||
The physicalScreen value is between 0 and screenCount-1, inclusive
|
||||
(values outside this range will result in a Value error).
|
||||
|
||||
The displayname is the name used to open the display, either from
|
||||
the Xdmx command-line or from the configuration file.
|
||||
|
||||
The logicalScreen value is the value of the screen that that Xdmx
|
||||
server exports to clients. When Xinerama is in use, this value is
|
||||
typically 0 for all values of physicalScreen. If Xinerama is in
|
||||
use, the rootWindowXOrigin and rootWindowYOrigin values specify
|
||||
where the physical screen is positioned in the global Xinerama
|
||||
coordinate system. Otherwise, these values are set to 0.
|
||||
|
||||
The screenWindow values comprise a geometry specification (see
|
||||
X(7x)) for the location of the DMX screen on the back-end screen.
|
||||
The coordinant system of the back-end display is used.
|
||||
|
||||
The first four rootWindow values comprise a geometry specification
|
||||
(see X(7x)) for the location of the root window on the screen
|
||||
window. The coordinant system of the screen window is used. In
|
||||
most cases, the root window will have the same geometry as the DMX
|
||||
screen window, and will occupy the same area of the back-end
|
||||
display. (This would not be the case, for example, if automatic
|
||||
projector alignment is used.)
|
||||
|
||||
|
||||
|
||||
DMXChangeScreensAttributes
|
||||
screenCount: CARD32
|
||||
maskCount: CARD32
|
||||
screens: LISTofCARD32
|
||||
valueMasks: LISTofCARD32
|
||||
valueList: LISTofVALUES
|
||||
==>
|
||||
status: CARD32
|
||||
errorScreen: CARD32
|
||||
|
||||
Errors: Length, Alloc
|
||||
|
||||
This request was first supported in version 2.0 of this protocol.
|
||||
(A singular version of this request with the ability to change some
|
||||
RootWindow attributes was supported in version 1.3 of this protocol,
|
||||
has been deprecated, and will return BadImplementation.)
|
||||
|
||||
This request changes the geometries and positions of the DMX screen
|
||||
and DMX root windows on the back-end X servers.
|
||||
|
||||
The valueMask and valueList specify which attributes are to be
|
||||
changed. The possible values are:
|
||||
|
||||
Attribute Type
|
||||
|
||||
ScreenWindowWidth CARD16
|
||||
ScreenWindowHeight CARD16
|
||||
ScreenWindowXoffset INT16
|
||||
ScreenWindowYoffset INT16
|
||||
RootWindowWidth CARD16
|
||||
RootWindowHeight CARD16
|
||||
RootWindowXoffset INT16
|
||||
RootWindowYoffset INT16
|
||||
RootWindowXorigin INT16
|
||||
RootWindowYorigin INT16
|
||||
|
||||
The attribute values have the same meaning as do the corresponding
|
||||
values for DMXGetScreenAttributes.
|
||||
|
||||
Non-fatal errors will be returned in status (0 otherwise):
|
||||
DmxBadXinerama: Xinerama is not active
|
||||
DmxBadValue: The resulting position is not allowed
|
||||
(e.g., one corner is outside the bounding box)
|
||||
On error, errorScreen will contain the number of the screen that
|
||||
caused the first error.
|
||||
|
||||
|
||||
|
||||
DMXAddScreen
|
||||
displayName: STRING8
|
||||
physicalScreen: CARD32
|
||||
valueMask: CARD32
|
||||
valueList: LISTofVALUES
|
||||
==>
|
||||
status: CARD32
|
||||
physicalScreen: CARD32
|
||||
|
||||
Errors: Length, Alloc, Value
|
||||
|
||||
This request was first supported in version 2.2 of this protocol.
|
||||
|
||||
This request re-attaches the back-end physicalScreen to the Xdmx
|
||||
server. Only back-end screens that have been previously detached
|
||||
with DMXRemoveScreen may be added. The name of the back-end display
|
||||
is given in displayName, and this will replace the name of the
|
||||
back-end screen that was detached. Both the displayName and
|
||||
physicalScreen must be correct for this request to work.
|
||||
|
||||
The valueMask and valueList specify the attributes to be used. The
|
||||
possible values are:
|
||||
|
||||
Attribute Type
|
||||
|
||||
ScreenWindowWidth CARD16
|
||||
ScreenWindowHeight CARD16
|
||||
ScreenWindowXoffset INT16
|
||||
ScreenWindowYoffset INT16
|
||||
RootWindowWidth CARD16
|
||||
RootWindowHeight CARD16
|
||||
RootWindowXoffset INT16
|
||||
RootWindowYoffset INT16
|
||||
RootWindowXorigin INT16
|
||||
RootWindowYorigin INT16
|
||||
|
||||
The attribute values have the same meaning as do the corresponding
|
||||
values for DMXGetScreenAttributes.
|
||||
|
||||
On success, status will be 0 and physicalScreen will contain the new
|
||||
screen number. On failure, status will be non-zero. The status
|
||||
will be 1 if any of the following occured:
|
||||
* the -addremovescreens command-line option was not specified on
|
||||
the Xdmx command line
|
||||
* the value of physicalScreen is out of range
|
||||
* physicalScreen has not been detached (with DMXRemoveScreen)
|
||||
* displayName cannot be opened
|
||||
* the visuals of displayname do not match the visuals that Xdmx
|
||||
is using
|
||||
* the screen data for displayName does not match the data for the
|
||||
previously removed display
|
||||
The status will be DmxBadValue if the attribute values are out of
|
||||
range.
|
||||
|
||||
|
||||
|
||||
DMXRemoveScreen
|
||||
physicalScreen: CARD32
|
||||
==>
|
||||
status: CARD32
|
||||
|
||||
Errors: None
|
||||
|
||||
This request was first supported in version 2.2 of this protocol.
|
||||
|
||||
This request detaches the physicalScreen screen.
|
||||
|
||||
On success, status will be 0. On failure, the status will 1 if any
|
||||
of the following occur:
|
||||
* the -addremovescreens command-line option was not specified on
|
||||
the Xdmx command line
|
||||
* the value of physicalScreen is out of range
|
||||
* the back-end screen has already been detached.
|
||||
|
||||
|
||||
|
||||
DMXGetWindowAttributes
|
||||
window: CARD32
|
||||
==>
|
||||
screenCount: CARD32
|
||||
screens: LISTofCARD32
|
||||
windows: LISTofCARD32
|
||||
pos: LISTofRECTANGLE
|
||||
vis: LISTofRECTANGLE
|
||||
|
||||
Errors: Window, Alloc
|
||||
|
||||
This request computes the return values incorrectly for version 1.0
|
||||
of this protocol. Version 1.1 of this protocol conforms to this
|
||||
description. In version 2.0, the name of this request was changed
|
||||
from DMXGetWindowInformation. However, since the request itself did
|
||||
not change, no changes to the underlying protocol were made.
|
||||
|
||||
Given a window ID on the Xdmx server, this request returns data
|
||||
about how the window is represented on the back-end X servers. For
|
||||
each back-end X server that displays a portion of the window, the
|
||||
following information is returned:
|
||||
1) the number of the physical screen containing that portion
|
||||
(which can be used with the DMXGetScreenAttributes request
|
||||
to obtain more information about the screen),
|
||||
2) the window ID on the back-end X server of the window
|
||||
containing that portion,
|
||||
3) the position and dimensions of the window on the back-end, in
|
||||
screen coordinates, and
|
||||
4) the visible area of the window on the back-end, in
|
||||
window-relative coordinates (all zeros for windows that are
|
||||
not visible).
|
||||
Note that DMX allows multiple back-end windows to overlap in their
|
||||
view of the DMX logical window. Further, a logical window does not
|
||||
have to be completely covered by back-end windows -- there may be
|
||||
gaps.
|
||||
|
||||
As an example, consider a 500x500 window that spans the top two
|
||||
1024x768 back-end displays (A and B) of a 2048x1536 DMX display
|
||||
composed of 4 1024x768 back-end displays arranged in a cube:
|
||||
A B
|
||||
C D
|
||||
|
||||
In this case, the DMXGetWindowAttributes call would return the
|
||||
following information for the 500x500 window:
|
||||
|
||||
display A: 500x500 window at 1024-250,0 (relative to back end)
|
||||
with 250x500 visible at 0,0 (relative to window origin)
|
||||
|
||||
display B: 500x500 window at -250,0 (relative to back end)
|
||||
with 250x500 visible at 250,0 (relative to window origin)
|
||||
|
||||
display C: 500x500 window at 1024-250,-768 with 0x0 visible at 0,0
|
||||
|
||||
display D: 500x500 window at -250,-768 with 0x0 visible at 0,0
|
||||
|
||||
Note that if the specified window has not yet been mapped when
|
||||
DMXGetWindowAttributes is called, then a subsequent XMapWindow call
|
||||
might be buffered in xlib while requests directly to the back-end X
|
||||
servers are processed. This race condition can be solved by calling
|
||||
DMXSync before talking directly to the back-end X servers.
|
||||
|
||||
|
||||
|
||||
DMXGetDesktopAttributes
|
||||
==>
|
||||
width: INT16
|
||||
height: INT16
|
||||
shiftX: INT16
|
||||
shiftY: INT16
|
||||
|
||||
Errors: None
|
||||
|
||||
This request was first supported in version 2.0 of this protocol.
|
||||
|
||||
This request returns the size of the bounding box of the whole
|
||||
screen in width and height. The shiftX and shiftY values will
|
||||
always be 0. The global bounding box is computed whether or not
|
||||
Xinerama is active, and may be larger than the Xinerama screen size
|
||||
because of information in the configuration file.
|
||||
|
||||
|
||||
|
||||
DMXChangeDesktopAttributes
|
||||
valueMask: BITMASK
|
||||
valueList: LISTofVALUE
|
||||
==>
|
||||
status: CARD32
|
||||
|
||||
Errors: Length, Value
|
||||
|
||||
This request was first supported in version 2.0 of this protocol.
|
||||
|
||||
This request resizes the bounding box of the whole screen when using
|
||||
the Xinerama extension. Otherwise, it has no effect on the screen
|
||||
layout. The valueMask and valueList specify which attributes are to
|
||||
be changed. The possible values are:
|
||||
|
||||
Attriubute Type
|
||||
|
||||
Width INT16
|
||||
Height INT16
|
||||
ShiftX INT16
|
||||
ShiftY INT16
|
||||
|
||||
Width and Height specify the new width and height for the bounding
|
||||
box. ShiftX and ShiftY specify where the Xinerama origin will be
|
||||
placed with respect to the origin of the new bounding box. This
|
||||
allows the left and upper edges of the bounding box to be changed
|
||||
without changing the visual position of the windows on the desktop.
|
||||
If Width or Height is not specified, the current values will be
|
||||
used. If ShiftX or ShiftY is not specified, 0 will be used.
|
||||
|
||||
All coordinants are in the global DMX coordinant system. If
|
||||
Xinerama is not active, this request is not useful.
|
||||
|
||||
Non-fatal errors will be returned in status (0 otherwise):
|
||||
DmxBadXinerama: Xinerama is not active
|
||||
DmxBadValue: The size of the bounding box is too large
|
||||
|
||||
|
||||
|
||||
DMXGetInputCount
|
||||
==>
|
||||
inputCount: CARD32
|
||||
|
||||
This request was first supported in version 1.1 of this protocol.
|
||||
|
||||
This request returns the number of input devices connected to the
|
||||
Xdmx server. This number is the same as that returned by
|
||||
XListInputDevices, but is available even when the XInput extension
|
||||
is not supported.
|
||||
|
||||
|
||||
|
||||
DMXGetInputAttributes
|
||||
deviceId: CARD32
|
||||
==>
|
||||
inputType: CARD32
|
||||
physicalScreen: CARD32
|
||||
physicalId: CARD32
|
||||
isCore: BOOL
|
||||
sendsCore: BOOL
|
||||
detached: BOOL
|
||||
name: STRING8
|
||||
|
||||
Errors: Value
|
||||
|
||||
This request was first supported in version 1.1 of this protocol.
|
||||
In version 2.0, the name of this request was changed from
|
||||
DMXGetInputInformation. However, since the request itself did not
|
||||
change, no changes to the underlying protocol were made. In version
|
||||
2.2, the name of detached was changed from reservation. There was
|
||||
no change in underlying protocol.
|
||||
|
||||
This request returns information about the specified input device
|
||||
that cannot be obtained from the XListInputDeivices call. The
|
||||
deviceId is the same as that used by the XListInputDevices call, and
|
||||
must be in the range 0 to inputCount-1, inclusive (values outside
|
||||
this range will result in a Value error).
|
||||
|
||||
The value of inputType will always be valid, and will be one of the
|
||||
following values:
|
||||
0 for local (and dummy) devices,
|
||||
1 for console devices, and
|
||||
2 for back-end devices.
|
||||
|
||||
For local devices, all other fields returned, except isCore and
|
||||
sendsCore, are invalid.
|
||||
|
||||
For console devices, the physicalScreen and physicalID will be
|
||||
invalid, and the name will return the name of the X server on which
|
||||
the console window is displayed.
|
||||
|
||||
For back-end devices, the physicalScreen will identify the back-end
|
||||
display and can be used as an argument to DMXGetScreenAttributes to
|
||||
obtain more information; the physicalId will be the XInput device id
|
||||
on the back-end X server; and the name will be invalid (since it
|
||||
does not provide any additional information that cannot be obtained
|
||||
with DMXGetScreenAttributes).
|
||||
|
||||
If isCore is True, then this device is active as a true core input
|
||||
device and will send core events. If sendsCore is True, then this
|
||||
device is an XInput extension device, but sends core events instead
|
||||
of extension events. Note that this behavior is different from that
|
||||
of XFree86 or Xorg, where XInput extension devices may send both
|
||||
extension events and core events.
|
||||
|
||||
If detached is True, then this device has been detached and is no
|
||||
longer producing input events. The device may be reattached using
|
||||
DMXAddInput.
|
||||
|
||||
|
||||
|
||||
DMXAddInput
|
||||
displayName: STRING8
|
||||
valueMask: CARD32
|
||||
valueList: LISTofVALUES
|
||||
==>
|
||||
status: CARD32
|
||||
physicalId: CARD32
|
||||
|
||||
Errors: Value, Access
|
||||
|
||||
This request was first supported in version 2.2 of this protocol.
|
||||
|
||||
The valueMask and valueList specify the attributes to be used. The
|
||||
possible values are:
|
||||
|
||||
Attribute Type
|
||||
|
||||
InputType CARD32
|
||||
InputPhysicalScreen CARD32
|
||||
InputSendsCore BOOL
|
||||
|
||||
This request attaches an input device to the Xdmx server. The value
|
||||
of inputType will be one:
|
||||
1 for console devices, and
|
||||
2 for back-end devices.
|
||||
Other values of InputType will return a BadValue error. Local
|
||||
devices (inputType=0 in DMXGetInputAttributes) cannot be attached or
|
||||
removed. For console devices, displayName will store the name of
|
||||
the display to be used.
|
||||
|
||||
For back-end devices, InputPhysicalScreen will specify the screen
|
||||
number. BadValue will be returned if the screen number is out of
|
||||
range. BadAccess will be returned if the input has already been
|
||||
attached or if the backend screen is currently detached.
|
||||
|
||||
If InputSendsCore is True, the new device will be added as a true
|
||||
core device.
|
||||
|
||||
If a device was removed with DMXRemoveInput an attempt will be made
|
||||
to reconnect the previous devices (InputSendsCore is ignored in this
|
||||
case).
|
||||
|
||||
|
||||
|
||||
DMXRemoveInput
|
||||
physicalId: CARD32
|
||||
==>
|
||||
status: CARD32
|
||||
|
||||
Errors: Value, Access
|
||||
|
||||
This request was first supported in version 2.2 of this protocol.
|
||||
|
||||
This request detaches the input device with physicalId, and all
|
||||
associated inputs (e.g., if the physicalId is a backend mouse, and a
|
||||
keyboard is also attached to the backend, then both devices will be
|
||||
detached). If the physicalId is outside the valid range (0 to one
|
||||
less than the value returned by DMXInputCount), BadValue is
|
||||
returned. If the physicalId has already been detached, BadAccess is
|
||||
returned. The status is always 0.
|
||||
|
||||
|
||||
|
||||
5. Events
|
||||
|
||||
No new events are defined by this extension.
|
||||
|
||||
|
||||
|
||||
6. Errors
|
||||
|
||||
No new events are defined by this extension.
|
||||
|
||||
|
||||
|
||||
7. Encoding
|
||||
|
||||
Deprecated DMX opcodes:
|
||||
DMXGetScreenInformation 2
|
||||
DMXForceWindowCreation 6
|
||||
DMXReconfigureScreen 7
|
||||
|
||||
Valid DMX opcodes:
|
||||
DMXQueryVersion 0
|
||||
DMXSync 8
|
||||
DMXForceWindowCreation 9
|
||||
|
||||
DMXGetScreenCount 1
|
||||
DMXGetScreenAttributes 10
|
||||
DMXChangeScreensAttributes 11
|
||||
DMXAddScreen 12
|
||||
DMXRemoveScreen 13
|
||||
|
||||
DMXGetWindowAttributes 3
|
||||
|
||||
DMXGetDesktopAttributes 14
|
||||
DMXChangeDesktopAttributes 15
|
||||
|
||||
DMXGetInputCount 4
|
||||
DMXGetInputAttributes 5
|
||||
DMXAddInput 16
|
||||
DMXRemoveInput 17
|
||||
|
||||
DMXQueryVersion
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 0 DMX opcode (X_DMXQueryVersion)
|
||||
2 1 request length
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 majorVersion
|
||||
4 CARD32 minorVersion
|
||||
4 CARD32 patchVersion
|
||||
12 unused
|
||||
|
||||
DMXSync
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 8 DMX opcode (X_DMXSync)
|
||||
2 1 request length
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 status
|
||||
20 unused
|
||||
|
||||
DMXForceWindowCreation
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 9 DMX opcode (X_DMXForceWindowCreation)
|
||||
2 2 request length
|
||||
4 CARD32 window
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 status
|
||||
20 unused
|
||||
|
||||
|
||||
DMXGetScreenCount
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 1 DMX opcode (X_DMXGetScreenCount)
|
||||
2 1 request length
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 screenCount
|
||||
20 unused
|
||||
|
||||
DMXGetScreenAttributes
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 10 DMX opcode (X_DMXGetScreenAttributes)
|
||||
2 2 request length
|
||||
4 CARD32 physicalScreen
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 1+(n+p)/4 reply length
|
||||
4 n displayNameLength
|
||||
4 CARD32 logicalScreen
|
||||
2 CARD16 screenWindowWidth
|
||||
2 CARD16 screenWindowHeight
|
||||
2 INT16 screenWindowXoffset
|
||||
2 INT16 screenWindowYoffset
|
||||
2 CARD16 rootWindowWidth
|
||||
2 CARD16 rootWindowHeight
|
||||
2 INT16 rootWindowXoffset
|
||||
2 INT16 rootWindowYoffset
|
||||
2 INT16 rootWindowXorigin
|
||||
2 INT16 rootWindowYorigin
|
||||
n displayName
|
||||
p pad(n)
|
||||
|
||||
DMXChangeScreensAttributes
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 11 DMX opcode (X_DMXChangeScreenAttributes)
|
||||
2 3+s+m+n request length
|
||||
4 s screenCount
|
||||
4 m maskCount
|
||||
4s LISTofCARD32 screens
|
||||
4m LISTofCARD32 valueMasks
|
||||
4n LISTofVALUES valueList
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 status
|
||||
4 CARD32 errorScreen
|
||||
16 unused
|
||||
|
||||
|
||||
DMXAddScreen
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 12 DMX opcode (X_DMXAddScreen)
|
||||
2 3+m+(n+p)/4 request length
|
||||
4 n displayNameLength
|
||||
4 CARD32 physicalScreen
|
||||
4 CARD32 valueMask
|
||||
4m LISTofVALUES valueList
|
||||
n displayName
|
||||
p pad(n)
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 status
|
||||
4 CARD32 physicalScreen
|
||||
16 unused
|
||||
|
||||
DMXRemoveScreen
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 13 DMX opcode (X_DMXRemoveScreen)
|
||||
2 2 request length
|
||||
4 CARD32 physicalScreen
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 status
|
||||
20 unused
|
||||
|
||||
DMXGetWindowAttributes
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 3 DMX opcode (X_DMXGetWindowAttributes)
|
||||
2 2 request length
|
||||
4 CARD32 window
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 n*6 reply length
|
||||
4 n screenCount
|
||||
20 unused
|
||||
n*4 LISTofCARD32 screens
|
||||
n*4 LISTofCARD32 windows
|
||||
n*8 LISTofRECTANGLE pos
|
||||
n*8 LISTofRECTANGLE vis
|
||||
|
||||
DMXGetDesktopAttributes
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 14 DMX opcode (X_DMXGetDesktopAttributes)
|
||||
2 1 request length
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
2 INT16 width
|
||||
2 INT16 height
|
||||
2 INT16 shiftX
|
||||
2 INT16 shiftY
|
||||
16 unused
|
||||
|
||||
DMXChangeDesktopAttributes
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 15 DMX opcode (X_DMXChangeDesktopAttributes)
|
||||
2 2+n request length
|
||||
4 BITMASK valueMask
|
||||
4n LISTofVALUES valueList
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 status
|
||||
20 unused
|
||||
|
||||
DMXGetInputCount
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 4 DMX opcode (X_DMXGetInputCount)
|
||||
2 1 request length
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 inputCount
|
||||
20 unused
|
||||
|
||||
DMXGetInputAttributes
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 5 DMX opcode (X_DMXGetInputAttributes)
|
||||
2 2 request length
|
||||
4 CARD32 deviceId
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 (n+p)/4 reply length
|
||||
4 CARD32 inputType
|
||||
4 CARD32 physicalScreen
|
||||
4 CARD32 physicalId
|
||||
4 n nameLength
|
||||
1 BOOL isCore
|
||||
1 BOOL sendsCore
|
||||
1 BOOL detached
|
||||
5 unused
|
||||
n name
|
||||
p pad(n)
|
||||
|
||||
DMXAddInput
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 16 DMX opcode (X_DMXAddInput)
|
||||
2 3+m+(n+p)/4 request length
|
||||
4 n displayNameLength
|
||||
4 CARD32 valueMask
|
||||
4m LISTofVALUES valueList
|
||||
n displayName
|
||||
p pad(n)
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 status
|
||||
4 CARD32 physicalId
|
||||
16 unused
|
||||
|
||||
DMXRemoveInput
|
||||
1 CARD8 opcode (X assigned)
|
||||
1 17 DMX opcode (X_DMXRemoveInput)
|
||||
2 3 request length
|
||||
4 CARD32 physicalId
|
||||
==>
|
||||
1 1 Reply
|
||||
1 unused
|
||||
2 CARD16 sequence number
|
||||
4 0 reply length
|
||||
4 CARD32 status
|
||||
20 unused
|
||||
|
||||
|
||||
8. Changes to existing requests/replies/events
|
||||
|
||||
No changes to existing requests, replies, or events are necessitated
|
||||
by this extension.
|
||||
|
||||
|
||||
|
||||
9. Acknowledgments
|
||||
|
||||
|
||||
|
||||
10. References
|
||||
|
||||
[X11R6.4] Robert W. Sheifler. X Window System Protocol, X Consortium
|
||||
Standard, X Version 11, Release 6.4. Available from
|
||||
xc/doc/specs/XProtocol and xc/doc/hardcopy/XProtocol.
|
||||
2778
hw/dmx/doc/dmx.sgml
Normal file
2778
hw/dmx/doc/dmx.sgml
Normal file
File diff suppressed because it is too large
Load Diff
2989
hw/dmx/doc/dmx.txt
Normal file
2989
hw/dmx/doc/dmx.txt
Normal file
File diff suppressed because it is too large
Load Diff
1090
hw/dmx/doc/doxygen.conf
Normal file
1090
hw/dmx/doc/doxygen.conf
Normal file
File diff suppressed because it is too large
Load Diff
49
hw/dmx/doc/doxygen.css
Normal file
49
hw/dmx/doc/doxygen.css
Normal file
@@ -0,0 +1,49 @@
|
||||
H1 { text-align: center; }
|
||||
CAPTION { font-weight: bold }
|
||||
A.qindex {}
|
||||
A.qindexRef {}
|
||||
A.el { text-decoration: none; font-weight: bold }
|
||||
A.elRef { font-weight: bold }
|
||||
A.code { text-decoration: none; font-weight: normal; color: #4444ee }
|
||||
A.codeRef { font-weight: normal; color: #4444ee }
|
||||
A:hover { text-decoration: none; background-color: #f2f2ff }
|
||||
DL.el { margin-left: -1cm }
|
||||
DIV.fragment { width: 100%; border: none; background-color: #eeeeee }
|
||||
DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
|
||||
TD.md { background-color: #f2f2ff; font-weight: bold; }
|
||||
TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; }
|
||||
TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; }
|
||||
DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }
|
||||
DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }
|
||||
BODY { background: white }
|
||||
TD.indexkey {
|
||||
background-color: #eeeeff;
|
||||
font-weight: bold;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px
|
||||
}
|
||||
TD.indexvalue {
|
||||
background-color: #eeeeff;
|
||||
font-style: italic;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px
|
||||
}
|
||||
FONT.keyword { color: #008000 }
|
||||
FONT.keywordtype { color: #604020 }
|
||||
FONT.keywordflow { color: #e08000 }
|
||||
FONT.comment { color: #800000 }
|
||||
FONT.preprocessor { color: #806020 }
|
||||
FONT.stringliteral { color: #002080 }
|
||||
FONT.charliteral { color: #008080 }
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user