Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nx-libs
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dimbor
nx-libs
Commits
e01b9177
Commit
e01b9177
authored
Oct 10, 2011
by
Reinhard Tartler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Imported nxagent-3.5.0-5.tar.gz
Summary: Imported nxagent-3.5.0-5.tar.gz Keywords: Imported nxagent-3.5.0-5.tar.gz into Git repository
parent
39b738a6
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
332 additions
and
7788 deletions
+332
-7788
Args.c
nx-X11/programs/Xserver/hw/nxagent/Args.c
+4
-0
Args.h
nx-X11/programs/Xserver/hw/nxagent/Args.h
+2
-0
CHANGELOG
nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+19
-0
Cursor.c
nx-X11/programs/Xserver/hw/nxagent/Cursor.c
+1
-25
Display.c
nx-X11/programs/Xserver/hw/nxagent/Display.c
+2
-0
Events.c
nx-X11/programs/Xserver/hw/nxagent/Events.c
+4
-4
Extensions.c
nx-X11/programs/Xserver/hw/nxagent/Extensions.c
+133
-9
Imakefile
nx-X11/programs/Xserver/hw/nxagent/Imakefile
+4
-4
Init.c
nx-X11/programs/Xserver/hw/nxagent/Init.c
+20
-0
Init.h
nx-X11/programs/Xserver/hw/nxagent/Init.h
+2
-0
NXrandr.c
nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
+0
-1229
NXrandr.c.NX.original
nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
+0
-1229
NXrandr.c.XF86.original
nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original
+0
-1197
Reconnect.c
nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+2
-1
Screen.c
nx-X11/programs/Xserver/hw/nxagent/Screen.c
+132
-78
Screen.h
nx-X11/programs/Xserver/hw/nxagent/Screen.h
+1
-1
Window.c
nx-X11/programs/Xserver/hw/nxagent/Window.c
+4
-3
NXdixfonts.c
nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
+2
-1
NXrandr.c
nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
+0
-1344
NXrandr.c.NX.original
nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
+0
-1344
NXrandr.c.X.original
nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original
+0
-1319
No files found.
nx-X11/programs/Xserver/hw/nxagent/Args.c
View file @
e01b9177
...
@@ -135,6 +135,8 @@ char *nxagentKeyboard = NULL;
...
@@ -135,6 +135,8 @@ char *nxagentKeyboard = NULL;
Bool
nxagentOnce
=
True
;
Bool
nxagentOnce
=
True
;
int
nxagentRemoteMajor
=
-
1
;
static
void
nxagentParseOptionString
(
char
*
);
static
void
nxagentParseOptionString
(
char
*
);
/*
/*
...
@@ -1578,6 +1580,8 @@ N/A
...
@@ -1578,6 +1580,8 @@ N/A
nxagentAlphaCompat
=
0
;
nxagentAlphaCompat
=
0
;
}
}
nxagentRemoteMajor
=
remoteMajor
;
if
(
nxagentPackMethod
==
-
1
)
if
(
nxagentPackMethod
==
-
1
)
{
{
nxagentPackMethod
=
packMethod
;
nxagentPackMethod
=
packMethod
;
...
...
nx-X11/programs/Xserver/hw/nxagent/Args.h
View file @
e01b9177
...
@@ -81,4 +81,6 @@ void nxagentSetCoalescence(void);
...
@@ -81,4 +81,6 @@ void nxagentSetCoalescence(void);
extern
int
nxagentUserDefinedFontPath
;
extern
int
nxagentUserDefinedFontPath
;
extern
int
nxagentRemoteMajor
;
#endif
/* __Args_H__ */
#endif
/* __Args_H__ */
nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
View file @
e01b9177
ChangeLog:
ChangeLog:
nxagent-3.5.0-5
- The NX agent failed to resize its own window to fit the desktop size
in shadow sessions. TR07I02561 is now fixed also in shadow mode.
nxagent-3.5.0-4
- Fixed TR07I02530. Solved a buffer overflow occurring when the '-fp'
option value exceeds 1024 characters.
- Extended list of the available screen geometries.
nxagent-3.5.0-3
- Fixed TR08I02572. Upgraded RandR extension to version 1.2.
- Fixed TR07I02561. The NX agent failed to resize its own window to
fit the desktop size.
nxagent-3.5.0-2
nxagent-3.5.0-2
- Fixed TR0502449. Initialized font server path even if font server
- Fixed TR0502449. Initialized font server path even if font server
...
...
nx-X11/programs/Xserver/hw/nxagent/Cursor.c
View file @
e01b9177
...
@@ -293,31 +293,7 @@ void nxagentRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor,
...
@@ -293,31 +293,7 @@ void nxagentRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor,
Bool
nxagentSetCursorPosition
(
ScreenPtr
pScreen
,
int
x
,
int
y
,
Bool
nxagentSetCursorPosition
(
ScreenPtr
pScreen
,
int
x
,
int
y
,
Bool
generateEvent
)
Bool
generateEvent
)
{
{
/*
return
1
;
* Don't warp the cursor if the requesting client
* is the server client itself or a shadow agent.
*/
if
(
requestingClient
!=
NULL
&&
requestingClient
!=
serverClient
&&
nxagentClientHint
(
requestingClient
)
!=
NXAGENT_SHADOW
)
{
int
i
;
#ifdef TEST
fprintf
(
stderr
,
"nxagentSetCursorPosition: Moving the cursor at position [%d,%d].
\n
"
,
x
,
y
);
#endif
for
(
i
=
0
;
i
<
nxagentNumScreens
;
i
++
)
{
XWarpPointer
(
nxagentDisplay
,
nxagentDefaultWindows
[
i
],
nxagentDefaultWindows
[
pScreen
->
myNum
],
0
,
0
,
0
,
0
,
x
,
y
);
}
}
return
True
;
}
}
void
nxagentReconnectCursor
(
pointer
p0
,
XID
x1
,
pointer
p2
)
void
nxagentReconnectCursor
(
pointer
p0
,
XID
x1
,
pointer
p2
)
...
...
nx-X11/programs/Xserver/hw/nxagent/Display.c
View file @
e01b9177
...
@@ -2406,6 +2406,8 @@ Bool nxagentReconnectDisplay(void *p0)
...
@@ -2406,6 +2406,8 @@ Bool nxagentReconnectDisplay(void *p0)
nxagentPackQuality
=
-
1
;
nxagentPackQuality
=
-
1
;
nxagentSplitThreshold
=
-
1
;
nxagentSplitThreshold
=
-
1
;
nxagentRemoteMajor
=
-
1
;
nxagentInstallSignalHandlers
();
nxagentInstallSignalHandlers
();
nxagentInstallDisplayHandlers
();
nxagentInstallDisplayHandlers
();
...
...
nx-X11/programs/Xserver/hw/nxagent/Events.c
View file @
e01b9177
...
@@ -591,8 +591,8 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
...
@@ -591,8 +591,8 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
nxagentLaunchDialog
(
DIALOG_ENABLE_DESKTOP_RESIZE_MODE
);
nxagentLaunchDialog
(
DIALOG_ENABLE_DESKTOP_RESIZE_MODE
);
nxagent
RRSetScreenConfig
(
pScreen
,
nxagentOption
(
Width
),
nxagent
ChangeScreenConfig
(
0
,
nxagentOption
(
Width
),
nxagentOption
(
Height
),
nxagentOption
(
Height
)
);
0
,
0
);
if
(
nxagentOption
(
ClientOs
)
==
ClientOsWinnt
)
if
(
nxagentOption
(
ClientOs
)
==
ClientOsWinnt
)
{
{
...
@@ -3461,8 +3461,8 @@ int nxagentHandleConfigureNotify(XEvent* X)
...
@@ -3461,8 +3461,8 @@ int nxagentHandleConfigureNotify(XEvent* X)
nxagentOption
(
Width
),
nxagentOption
(
Height
));
nxagentOption
(
Width
),
nxagentOption
(
Height
));
#endif
#endif
nxagent
RRSetScreenConfig
(
screenInfo
.
screens
[
DefaultScreen
(
nxagentDisplay
)]
,
nxagent
ChangeScreenConfig
(
0
,
nxagentOption
(
Width
)
,
nxagentOption
(
Width
),
nxagentOption
(
Height
)
);
nxagentOption
(
Height
),
0
,
0
);
}
}
}
}
...
...
nx-X11/programs/Xserver/hw/nxagent/Extensions.c
View file @
e01b9177
...
@@ -22,11 +22,19 @@
...
@@ -22,11 +22,19 @@
#include "Agent.h"
#include "Agent.h"
#include "Display.h"
#include "Display.h"
#include "Screen.h"
#include "Screen.h"
#include "Options.h"
#include "Extensions.h"
#include "Extensions.h"
#include "Windows.h"
void
GlxExtensionInit
(
void
);
void
GlxExtensionInit
(
void
);
void
GlxWrapInitVisuals
(
void
*
procPtr
);
void
GlxWrapInitVisuals
(
void
*
procPtr
);
static
int
nxagentRandRScreenSetSize
(
ScreenPtr
pScreen
,
CARD16
width
,
CARD16
height
,
CARD32
mmWidth
,
CARD32
mmHeight
);
static
int
nxagentRandRInitSizes
(
ScreenPtr
pScreen
);
#ifdef __DARWIN__
#ifdef __DARWIN__
void
DarwinHandleGUI
(
int
argc
,
char
*
argv
[])
void
DarwinHandleGUI
(
int
argc
,
char
*
argv
[])
...
@@ -75,6 +83,8 @@ void nxagentInitRandRExtension(ScreenPtr pScreen)
...
@@ -75,6 +83,8 @@ void nxagentInitRandRExtension(ScreenPtr pScreen)
fprintf
(
stderr
,
"Warning: Failed to initialize the RandR extension.
\n
"
);
fprintf
(
stderr
,
"Warning: Failed to initialize the RandR extension.
\n
"
);
}
}
nxagentRandRInitSizes
(
pScreen
);
/*
/*
* RRScreenInit sets these pointers to NULL,
* RRScreenInit sets these pointers to NULL,
* so requiring the server to set up its own
* so requiring the server to set up its own
...
@@ -84,12 +94,31 @@ void nxagentInitRandRExtension(ScreenPtr pScreen)
...
@@ -84,12 +94,31 @@ void nxagentInitRandRExtension(ScreenPtr pScreen)
pRandRScrPriv
=
rrGetScrPriv
(
pScreen
);
pRandRScrPriv
=
rrGetScrPriv
(
pScreen
);
pRandRScrPriv
->
rrGetInfo
=
nxagentRandRGetInfo
;
pRandRScrPriv
->
rrGetInfo
=
nxagentRandRGetInfo
;
#if RANDR_12_INTERFACE
pRandRScrPriv
->
rrScreenSetSize
=
nxagentRandRScreenSetSize
;
#endif
#if RANDR_10_INTERFACE
pRandRScrPriv
->
rrSetConfig
=
nxagentRandRSetConfig
;
pRandRScrPriv
->
rrSetConfig
=
nxagentRandRSetConfig
;
#endif
}
}
int
nxagentRandRGetInfo
(
ScreenPtr
pScreen
,
Rotation
*
pRotations
)
int
nxagentRandRGetInfo
(
ScreenPtr
pScreen
,
Rotation
*
pRotations
)
{
{
/*
* Rotation is not supported.
*/
*
pRotations
=
RR_Rotate_0
;
return
1
;
}
static
int
nxagentRandRInitSizes
(
ScreenPtr
pScreen
)
{
RRScreenSizePtr
pSize
;
RRScreenSizePtr
pSize
;
rrScrPrivPtr
pRandRScrPriv
=
rrGetScrPriv
(
pScreen
);
int
width
;
int
width
;
int
height
;
int
height
;
...
@@ -97,8 +126,16 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
...
@@ -97,8 +126,16 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
int
maxWidth
;
int
maxWidth
;
int
maxHeight
;
int
maxHeight
;
int
w
[]
=
{
0
,
160
,
320
,
640
,
800
,
1024
,
0
,
0
};
/*
int
h
[]
=
{
0
,
120
,
240
,
480
,
600
,
768
,
0
,
0
};
int w[] = {0, 160, 320, 640, 800, 1024, 1152, 1280, 1280, 1280, 1280, 1280,
1280, 1360, 1440, 1600, 1600, 1680, 1920, 1920, 0, 0};
int h[] = {0, 120, 240, 480, 600, 768, 864, 600, 720, 800, 854, 960,
1024, 768, 900, 900, 1200, 1050, 1080, 1200, 0, 0};
*/
int
w
[]
=
{
0
,
320
,
640
,
640
,
800
,
800
,
1024
,
1024
,
1152
,
1280
,
1280
,
1280
,
1360
,
1440
,
1600
,
1600
,
1680
,
1920
,
1920
,
0
,
0
};
int
h
[]
=
{
0
,
240
,
360
,
480
,
480
,
600
,
600
,
768
,
864
,
720
,
800
,
1024
,
768
,
900
,
900
,
1200
,
1050
,
1080
,
1200
,
0
,
0
};
int
i
;
int
i
;
int
nSizes
;
int
nSizes
;
...
@@ -107,12 +144,6 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
...
@@ -107,12 +144,6 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
int
mmHeight
;
int
mmHeight
;
/*
/*
* Rotation is not supported.
*/
*
pRotations
=
RR_Rotate_0
;
/*
* Register all the supported sizes. The third
* Register all the supported sizes. The third
* parameter is the refresh rate.
* parameter is the refresh rate.
*/
*/
...
@@ -185,13 +216,106 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
...
@@ -185,13 +216,106 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
return
1
;
return
1
;
}
}
#if RANDR_10_INTERFACE
int
nxagentRandRSetConfig
(
ScreenPtr
pScreen
,
Rotation
rotation
,
int
nxagentRandRSetConfig
(
ScreenPtr
pScreen
,
Rotation
rotation
,
int
rate
,
RRScreenSizePtr
pSize
)
int
rate
,
RRScreenSizePtr
pSize
)
{
{
int
r
;
rrScrPrivPtr
pRandRScrPriv
;
UpdateCurrentTime
();
/*
/*
* Whatever size is OK for us.
* Whatever size is OK for us.
*/
*/
r
eturn
nxagentResizeScreen
(
pScreen
,
pSize
->
width
,
pSize
->
height
,
r
=
nxagentResizeScreen
(
pScreen
,
pSize
->
width
,
pSize
->
height
,
pSize
->
mmWidth
,
pSize
->
mmHeight
);
pSize
->
mmWidth
,
pSize
->
mmHeight
);
nxagentMoveViewport
(
pScreen
,
0
,
0
);
return
r
;
}
}
#endif
#if RANDR_12_INTERFACE
void
nxagentRandRSetWindowsSize
(
int
width
,
int
height
)
{
if
(
width
==
0
)
{
if
(
nxagentOption
(
Fullscreen
)
==
1
)
{
width
=
WidthOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
));
}
else
{
width
=
nxagentOption
(
Width
);
}
}
if
(
height
==
0
)
{
if
(
nxagentOption
(
Fullscreen
)
==
1
)
{
height
=
HeightOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
));
}
else
{
height
=
nxagentOption
(
Height
);
}
}
XResizeWindow
(
nxagentDisplay
,
nxagentDefaultWindows
[
0
],
width
,
height
);
if
(
nxagentOption
(
Rootless
)
==
0
)
{
XMoveResizeWindow
(
nxagentDisplay
,
nxagentInputWindows
[
0
],
0
,
0
,
width
,
height
);
}
}
int
nxagentRandRScreenSetSize
(
ScreenPtr
pScreen
,
CARD16
width
,
CARD16
height
,
CARD32
mmWidth
,
CARD32
mmHeight
)
{
int
result
;
rrScrPrivPtr
pRandRScrPriv
;
UpdateCurrentTime
();
if
(
nxagentOption
(
DesktopResize
)
==
1
&&
(
nxagentOption
(
Fullscreen
)
==
1
||
width
>
WidthOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
))
||
height
>
HeightOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
))))
{
if
(
nxagentOption
(
ClientOs
)
!=
ClientOsWinnt
/*&& nxagentOption(ClientOs) != ClientNXPlayer*/
)
{
nxagentChangeOption
(
DesktopResize
,
0
);
}
}
if
(
nxagentOption
(
DesktopResize
)
==
1
&&
nxagentOption
(
Fullscreen
)
==
0
&&
nxagentOption
(
AllScreens
)
==
0
)
{
nxagentChangeOption
(
Width
,
width
);
nxagentChangeOption
(
Height
,
height
);
}
result
=
nxagentResizeScreen
(
pScreen
,
width
,
height
,
mmWidth
,
mmHeight
);
if
(
result
==
1
&&
nxagentOption
(
DesktopResize
)
==
1
&&
nxagentOption
(
Fullscreen
)
==
0
&&
nxagentOption
(
AllScreens
)
==
0
)
{
nxagentRandRSetWindowsSize
(
width
,
height
);
nxagentSetWMNormalHints
(
pScreen
->
myNum
);
}
nxagentMoveViewport
(
pScreen
,
0
,
0
);
return
result
;
}
#endif
nx-X11/programs/Xserver/hw/nxagent/Imakefile
View file @
e01b9177
...
@@ -7,8 +7,7 @@ SRCS1 = os2Stub.c
...
@@ -7,8 +7,7 @@ SRCS1 = os2Stub.c
OBJS1 = os2Stub.o
OBJS1 = os2Stub.o
#endif
#endif
SRCS = NXrandr.c \
SRCS = NXwindow.c \
NXwindow.c \
NXevents.c \
NXevents.c \
NXproperty.c \
NXproperty.c \
NXdixfonts.c \
NXdixfonts.c \
...
@@ -70,8 +69,7 @@ SRCS = NXrandr.c \
...
@@ -70,8 +69,7 @@ SRCS = NXrandr.c \
miinitext.c \
miinitext.c \
$(SRCS1)
$(SRCS1)
OBJS = NXrandr.o \
OBJS = NXwindow.o \
NXwindow.o \
NXevents.o \
NXevents.o \
NXproperty.o \
NXproperty.o \
NXdixfonts.o \
NXdixfonts.o \
...
@@ -206,6 +204,8 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(UPG_DEFINES) \
...
@@ -206,6 +204,8 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(UPG_DEFINES) \
-DNXAGENT_SPLASH \
-DNXAGENT_SPLASH \
-DNXAGENT_ARTSD \
-DNXAGENT_ARTSD \
-UNX_DEBUG_INPUT \
-UNX_DEBUG_INPUT \
-DRANDR_10_INTERFACE \
-DRANDR_12_INTERFACE \
-UPANORAMIX \
-UPANORAMIX \
-UDEBUG_TREE
-UDEBUG_TREE
...
...
nx-X11/programs/Xserver/hw/nxagent/Init.c
View file @
e01b9177
...
@@ -128,6 +128,10 @@ void OsVendorEndRedirectErrorFFunction();
...
@@ -128,6 +128,10 @@ void OsVendorEndRedirectErrorFFunction();
* new X server tree.
* new X server tree.
*/
*/
static
void
nxagentGrabServerCallback
(
CallbackListPtr
*
callbacks
,
pointer
data
,
pointer
args
);
#ifdef NXAGENT_UPGRADE
#ifdef NXAGENT_UPGRADE
void
ddxInitGlobals
(
void
)
void
ddxInitGlobals
(
void
)
...
@@ -209,6 +213,11 @@ void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
...
@@ -209,6 +213,11 @@ void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
NXUnsetLibraryPath
(
1
);
NXUnsetLibraryPath
(
1
);
if
(
serverGeneration
==
1
)
{
AddCallback
(
&
ServerGrabCallback
,
nxagentGrabServerCallback
,
NULL
);
}
if
(
nxagentUserDefinedFontPath
==
0
)
if
(
nxagentUserDefinedFontPath
==
0
)
{
{
#ifdef TEST
#ifdef TEST
...
@@ -479,6 +488,17 @@ void OsVendorEndRedirectErrorFFunction()
...
@@ -479,6 +488,17 @@ void OsVendorEndRedirectErrorFFunction()
int
SelectWaitTime
=
10000
;
/* usec */
int
SelectWaitTime
=
10000
;
/* usec */
#endif
#endif
ServerGrabInfoRec
nxagentGrabServerInfo
;
static
void
nxagentGrabServerCallback
(
CallbackListPtr
*
callbacks
,
pointer
data
,
pointer
args
)
{
ServerGrabInfoRec
*
grab
=
(
ServerGrabInfoRec
*
)
args
;
nxagentGrabServerInfo
.
client
=
grab
->
client
;
nxagentGrabServerInfo
.
grabstate
=
grab
->
grabstate
;
}
#ifdef DPMSExtension
#ifdef DPMSExtension
void
DPMSSet
(
int
level
)
void
DPMSSet
(
int
level
)
...
...
nx-X11/programs/Xserver/hw/nxagent/Init.h
View file @
e01b9177
...
@@ -37,4 +37,6 @@ extern int nxagentDoFullGeneration;
...
@@ -37,4 +37,6 @@ extern int nxagentDoFullGeneration;
extern
int
nxagentBackingStore
;
extern
int
nxagentBackingStore
;
extern
int
nxagentSaveUnder
;
extern
int
nxagentSaveUnder
;
extern
ServerGrabInfoRec
nxagentGrabServerInfo
;
#endif
/* __Init_H__ */
#endif
/* __Init_H__ */
nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
deleted
100644 → 0
View file @
39b738a6
#ifdef NXAGENT_UPGRADE
#include "X/NXrandr.c"
#else
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */
/* */
/* NXAGENT, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of Medialogic S.p.A. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
/*
* $XFree86: xc/programs/Xserver/randr/randr.c,v 1.19 2003/02/08 03:52:30 dawes Exp $
*
* Copyright 2000, Compaq Computer Corporation,
* Copyright 2002, Hewlett Packard, Inc.
*
* 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, and that the name of Compaq or HP not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission. HP makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
*/
#define NEED_REPLIES
#define NEED_EVENTS
#include "X.h"
#include "Xproto.h"
#include "misc.h"
#include "os.h"
#include "dixstruct.h"
#include "resource.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "servermd.h"
#include "randr.h"
#include "randrproto.h"
#include "../../randr/randrstr.h"
#include "render.h"
/* we share subpixel order information */
#include "picturestr.h"
#include "Xfuncproto.h"
#ifdef EXTMODULE
#include "xf86_ansic.h"
#endif
#define RR_VALIDATE
int
RRGeneration
;
int
RRNScreens
;
static
int
ProcRRQueryVersion
(
ClientPtr
pClient
);
static
int
ProcRRDispatch
(
ClientPtr
pClient
);
static
int
SProcRRDispatch
(
ClientPtr
pClient
);
static
int
SProcRRQueryVersion
(
ClientPtr
pClient
);
#define wrap(priv,real,mem,func) {\
priv->mem = real->mem; \
real->mem = func; \
}
#define unwrap(priv,real,mem) {\
real->mem = priv->mem; \
}
static
CARD8
RRReqCode
;
static
int
RRErrBase
;
static
int
RREventBase
;
static
RESTYPE
ClientType
,
EventType
;
/* resource types for event masks */
static
int
RRClientPrivateIndex
;
typedef
struct
_RRTimes
{
TimeStamp
setTime
;
TimeStamp
configTime
;
}
RRTimesRec
,
*
RRTimesPtr
;
typedef
struct
_RRClient
{
int
major_version
;
int
minor_version
;
/* RRTimesRec times[0]; */
}
RRClientRec
,
*
RRClientPtr
;
/*
* each window has a list of clients requesting
* RRNotify events. Each client has a resource
* for each window it selects RRNotify input for,
* this resource is used to delete the RRNotifyRec
* entry from the per-window queue.
*/
typedef
struct
_RREvent
*
RREventPtr
;
typedef
struct
_RREvent
{
RREventPtr
next
;
ClientPtr
client
;
WindowPtr
window
;
XID
clientResource
;
int
mask
;
}
RREventRec
;
int
rrPrivIndex
=
-
1
;
#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
static
Bool
RRClientKnowsRates
(
ClientPtr
pClient
)
{
rrClientPriv
(
pClient
);
return
(
pRRClient
->
major_version
>
1
||
(
pRRClient
->
major_version
==
1
&&
pRRClient
->
minor_version
>=
1
));
}
static
void
RRClientCallback
(
CallbackListPtr
*
list
,
pointer
closure
,
pointer
data
)
{
NewClientInfoRec
*
clientinfo
=
(
NewClientInfoRec
*
)
data
;
ClientPtr
pClient
=
clientinfo
->
client
;
rrClientPriv
(
pClient
);
RRTimesPtr
pTimes
=
(
RRTimesPtr
)
(
pRRClient
+
1
);
int
i
;
pRRClient
->
major_version
=
0
;
pRRClient
->
minor_version
=
0
;
for
(
i
=
0
;
i
<
screenInfo
.
numScreens
;
i
++
)
{
ScreenPtr
pScreen
=
screenInfo
.
screens
[
i
];
rrScrPriv
(
pScreen
);
if
(
pScrPriv
)
{
pTimes
[
i
].
setTime
=
pScrPriv
->
lastSetTime
;
pTimes
[
i
].
configTime
=
pScrPriv
->
lastConfigTime
;
}
}
}
static
void
RRResetProc
(
ExtensionEntry
*
extEntry
)
{
}
static
Bool
RRCloseScreen
(
int
i
,
ScreenPtr
pScreen
)
{
rrScrPriv
(
pScreen
);
unwrap
(
pScrPriv
,
pScreen
,
CloseScreen
);
if
(
pScrPriv
->
pSizes
)
xfree
(
pScrPriv
->
pSizes
);
xfree
(
pScrPriv
);
RRNScreens
-=
1
;
/* ok, one fewer screen with RandR running */
return
(
*
pScreen
->
CloseScreen
)
(
i
,
pScreen
);
}
static
void
SRRScreenChangeNotifyEvent
(
xRRScreenChangeNotifyEvent
*
from
,
xRRScreenChangeNotifyEvent
*
to
)
{
to
->
type
=
from
->
type
;
to
->
rotation
=
from
->
rotation
;
cpswaps
(
from
->
sequenceNumber
,
to
->
sequenceNumber
);
cpswapl
(
from
->
timestamp
,
to
->
timestamp
);
cpswapl
(
from
->
configTimestamp
,
to
->
configTimestamp
);
cpswapl
(
from
->
root
,
to
->
root
);
cpswapl
(
from
->
window
,
to
->
window
);
cpswaps
(
from
->
sizeID
,
to
->
sizeID
);
cpswaps
(
from
->
widthInPixels
,
to
->
widthInPixels
);
cpswaps
(
from
->
heightInPixels
,
to
->
heightInPixels
);
cpswaps
(
from
->
widthInMillimeters
,
to
->
widthInMillimeters
);
cpswaps
(
from
->
heightInMillimeters
,
to
->
heightInMillimeters
);
cpswaps
(
from
->
subpixelOrder
,
to
->
subpixelOrder
);
}
Bool
RRScreenInit
(
ScreenPtr
pScreen
)
{
rrScrPrivPtr
pScrPriv
;
if
(
RRGeneration
!=
serverGeneration
)
{
if
((
rrPrivIndex
=
AllocateScreenPrivateIndex
())
<
0
)
return
FALSE
;
RRGeneration
=
serverGeneration
;
}
pScrPriv
=
(
rrScrPrivPtr
)
xalloc
(
sizeof
(
rrScrPrivRec
));
if
(
!
pScrPriv
)
return
FALSE
;
SetRRScreen
(
pScreen
,
pScrPriv
);
/*
* Calling function best set these function vectors
*/
pScrPriv
->
rrSetConfig
=
0
;
pScrPriv
->
rrGetInfo
=
0
;
/*
* This value doesn't really matter -- any client must call
* GetScreenInfo before reading it which will automatically update
* the time
*/
pScrPriv
->
lastSetTime
=
currentTime
;
pScrPriv
->
lastConfigTime
=
currentTime
;
wrap
(
pScrPriv
,
pScreen
,
CloseScreen
,
RRCloseScreen
);
pScrPriv
->
rotations
=
RR_Rotate_0
;
pScrPriv
->
nSizes
=
0
;
pScrPriv
->
nSizesInUse
=
0
;
pScrPriv
->
pSizes
=
0
;
pScrPriv
->
rotation
=
RR_Rotate_0
;
pScrPriv
->
size
=
-
1
;
RRNScreens
+=
1
;
/* keep count of screens that implement randr */
return
TRUE
;
}
/*ARGSUSED*/
static
int
RRFreeClient
(
pointer
data
,
XID
id
)
{
RREventPtr
pRREvent
;
WindowPtr
pWin
;
RREventPtr
*
pHead
,
pCur
,
pPrev
;
pRREvent
=
(
RREventPtr
)
data
;
pWin
=
pRREvent
->
window
;
pHead
=
(
RREventPtr
*
)
LookupIDByType
(
pWin
->
drawable
.
id
,
EventType
);
if
(
pHead
)
{
pPrev
=
0
;
for
(
pCur
=
*
pHead
;
pCur
&&
pCur
!=
pRREvent
;
pCur
=
pCur
->
next
)
pPrev
=
pCur
;
if
(
pCur
)
{
if
(
pPrev
)
pPrev
->
next
=
pRREvent
->
next
;
else
*
pHead
=
pRREvent
->
next
;
}
}
xfree
((
pointer
)
pRREvent
);
return
1
;
}
/*ARGSUSED*/
static
int
RRFreeEvents
(
pointer
data
,
XID
id
)
{
RREventPtr
*
pHead
,
pCur
,
pNext
;
pHead
=
(
RREventPtr
*
)
data
;
for
(
pCur
=
*
pHead
;
pCur
;
pCur
=
pNext
)
{
pNext
=
pCur
->
next
;
FreeResource
(
pCur
->
clientResource
,
ClientType
);
xfree
((
pointer
)
pCur
);
}
xfree
((
pointer
)
pHead
);
return
1
;
}
void
RRExtensionInit
(
void
)
{
ExtensionEntry
*
extEntry
;
if
(
RRNScreens
==
0
)
return
;
RRClientPrivateIndex
=
AllocateClientPrivateIndex
();
if
(
!
AllocateClientPrivate
(
RRClientPrivateIndex
,
sizeof
(
RRClientRec
)
+
screenInfo
.
numScreens
*
sizeof
(
RRTimesRec
)))
return
;
if
(
!
AddCallback
(
&
ClientStateCallback
,
RRClientCallback
,
0
))
return
;
ClientType
=
CreateNewResourceType
(
RRFreeClient
);
if
(
!
ClientType
)
return
;
EventType
=
CreateNewResourceType
(
RRFreeEvents
);
if
(
!
EventType
)
return
;
extEntry
=
AddExtension
(
RANDR_NAME
,
RRNumberEvents
,
RRNumberErrors
,
ProcRRDispatch
,
SProcRRDispatch
,
RRResetProc
,
StandardMinorOpcode
);
if
(
!
extEntry
)
return
;
RRReqCode
=
(
CARD8
)
extEntry
->
base
;
RRErrBase
=
extEntry
->
errorBase
;
RREventBase
=
extEntry
->
eventBase
;
EventSwapVector
[
RREventBase
+
RRScreenChangeNotify
]
=
(
EventSwapPtr
)
SRRScreenChangeNotifyEvent
;
return
;
}
int
TellChanged
(
WindowPtr
pWin
,
pointer
value
)
{
RREventPtr
*
pHead
,
pRREvent
;
ClientPtr
client
;
xRRScreenChangeNotifyEvent
se
;
ScreenPtr
pScreen
=
pWin
->
drawable
.
pScreen
;
rrScrPriv
(
pScreen
);
RRScreenSizePtr
pSize
;
WindowPtr
pRoot
=
WindowTable
[
pScreen
->
myNum
];
pHead
=
(
RREventPtr
*
)
LookupIDByType
(
pWin
->
drawable
.
id
,
EventType
);
if
(
!
pHead
)
return
WT_WALKCHILDREN
;
se
.
type
=
RRScreenChangeNotify
+
RREventBase
;
se
.
rotation
=
(
CARD8
)
pScrPriv
->
rotation
;
se
.
timestamp
=
pScrPriv
->
lastSetTime
.
milliseconds
;
se
.
configTimestamp
=
pScrPriv
->
lastConfigTime
.
milliseconds
;
se
.
root
=
pRoot
->
drawable
.
id
;
se
.
window
=
pWin
->
drawable
.
id
;
se
.
subpixelOrder
=
PictureGetSubpixelOrder
(
pScreen
);
if
(
pScrPriv
->
size
>=
0
)
{
pSize
=
&
pScrPriv
->
pSizes
[
pScrPriv
->
size
];
se
.
sizeID
=
pSize
->
id
;
se
.
widthInPixels
=
pSize
->
width
;
se
.
heightInPixels
=
pSize
->
height
;
se
.
widthInMillimeters
=
pSize
->
mmWidth
;
se
.
heightInMillimeters
=
pSize
->
mmHeight
;
}
else
{
/*
* This "shouldn't happen", but a broken DDX can
* forget to set the current configuration on GetInfo
*/
se
.
sizeID
=
0xffff
;
se
.
widthInPixels
=
0
;
se
.
heightInPixels
=
0
;
se
.
widthInMillimeters
=
0
;
se
.
heightInMillimeters
=
0
;
}
for
(
pRREvent
=
*
pHead
;
pRREvent
;
pRREvent
=
pRREvent
->
next
)
{
client
=
pRREvent
->
client
;
if
(
client
==
serverClient
||
client
->
clientGone
)
continue
;
se
.
sequenceNumber
=
client
->
sequence
;
if
(
pRREvent
->
mask
&
RRScreenChangeNotifyMask
)
WriteEventsToClient
(
client
,
1
,
(
xEvent
*
)
&
se
);
}
return
WT_WALKCHILDREN
;
}
Bool
RRGetInfo
(
ScreenPtr
pScreen
)
{
rrScrPriv
(
pScreen
);
int
i
,
j
,
k
,
l
;
Bool
changed
;
Rotation
rotations
;
RRScreenSizePtr
pSize
;
RRScreenRatePtr
pRate
;
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
pSize
=
&
pScrPriv
->
pSizes
[
i
];
pSize
->
oldReferenced
=
pSize
->
referenced
;
pSize
->
referenced
=
FALSE
;
for
(
k
=
0
;
k
<
pSize
->
nRates
;
k
++
)
{
pRate
=
&
pSize
->
pRates
[
k
];
pRate
->
oldReferenced
=
pRate
->
referenced
;
pRate
->
referenced
=
FALSE
;
}
}
if
(
!
(
*
pScrPriv
->
rrGetInfo
)
(
pScreen
,
&
rotations
))
return
FALSE
;
changed
=
FALSE
;
/*
* Check whether anything changed and simultaneously generate
* the protocol id values for the objects
*/
if
(
rotations
!=
pScrPriv
->
rotations
)
{
pScrPriv
->
rotations
=
rotations
;
changed
=
TRUE
;
}
j
=
0
;
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
pSize
=
&
pScrPriv
->
pSizes
[
i
];
if
(
pSize
->
oldReferenced
!=
pSize
->
referenced
)
changed
=
TRUE
;
if
(
pSize
->
referenced
)
pSize
->
id
=
j
++
;
l
=
0
;
for
(
k
=
0
;
k
<
pSize
->
nRates
;
k
++
)
{
pRate
=
&
pSize
->
pRates
[
k
];
if
(
pRate
->
oldReferenced
!=
pRate
->
referenced
)
changed
=
TRUE
;
if
(
pRate
->
referenced
)
l
++
;
}
pSize
->
nRatesInUse
=
l
;
}
pScrPriv
->
nSizesInUse
=
j
;
if
(
changed
)
{
UpdateCurrentTime
();
pScrPriv
->
lastConfigTime
=
currentTime
;
WalkTree
(
pScreen
,
TellChanged
,
(
pointer
)
pScreen
);
}
return
TRUE
;
}
void
RRSendConfigNotify
(
ScreenPtr
pScreen
)
{
WindowPtr
pWin
=
WindowTable
[
pScreen
->
myNum
];
xEvent
event
;
event
.
u
.
u
.
type
=
ConfigureNotify
;
event
.
u
.
configureNotify
.
window
=
pWin
->
drawable
.
id
;
event
.
u
.
configureNotify
.
aboveSibling
=
None
;
event
.
u
.
configureNotify
.
x
=
0
;
event
.
u
.
configureNotify
.
y
=
0
;
/* XXX xinerama stuff ? */
event
.
u
.
configureNotify
.
width
=
pWin
->
drawable
.
width
;
event
.
u
.
configureNotify
.
height
=
pWin
->
drawable
.
height
;
event
.
u
.
configureNotify
.
borderWidth
=
wBorderWidth
(
pWin
);
event
.
u
.
configureNotify
.
override
=
pWin
->
overrideRedirect
;
DeliverEvents
(
pWin
,
&
event
,
1
,
NullWindow
);
}
static
int
ProcRRQueryVersion
(
ClientPtr
client
)
{
xRRQueryVersionReply
rep
;
register
int
n
;
REQUEST
(
xRRQueryVersionReq
);
rrClientPriv
(
client
);
REQUEST_SIZE_MATCH
(
xRRQueryVersionReq
);
pRRClient
->
major_version
=
stuff
->
majorVersion
;
pRRClient
->
minor_version
=
stuff
->
minorVersion
;
rep
.
type
=
X_Reply
;
rep
.
length
=
0
;
rep
.
sequenceNumber
=
client
->
sequence
;
rep
.
majorVersion
=
RANDR_MAJOR
;
rep
.
minorVersion
=
RANDR_MINOR
;
if
(
client
->
swapped
)
{
swaps
(
&
rep
.
sequenceNumber
,
n
);
swapl
(
&
rep
.
length
,
n
);
swapl
(
&
rep
.
majorVersion
,
n
);
swapl
(
&
rep
.
minorVersion
,
n
);
}
WriteToClient
(
client
,
sizeof
(
xRRQueryVersionReply
),
(
char
*
)
&
rep
);
return
(
client
->
noClientException
);
}
extern
char
*
ConnectionInfo
;
static
int
padlength
[
4
]
=
{
0
,
3
,
2
,
1
};
void
RREditConnectionInfo
(
ScreenPtr
pScreen
)
{
xConnSetup
*
connSetup
;
char
*
vendor
;
xPixmapFormat
*
formats
;
xWindowRoot
*
root
;
xDepth
*
depth
;
xVisualType
*
visual
;
int
screen
=
0
;
int
d
;
connSetup
=
(
xConnSetup
*
)
ConnectionInfo
;
vendor
=
(
char
*
)
connSetup
+
sizeof
(
xConnSetup
);
formats
=
(
xPixmapFormat
*
)
((
char
*
)
vendor
+
connSetup
->
nbytesVendor
+
padlength
[
connSetup
->
nbytesVendor
&
3
]);
root
=
(
xWindowRoot
*
)
((
char
*
)
formats
+
sizeof
(
xPixmapFormat
)
*
screenInfo
.
numPixmapFormats
);
while
(
screen
!=
pScreen
->
myNum
)
{
depth
=
(
xDepth
*
)
((
char
*
)
root
+
sizeof
(
xWindowRoot
));
for
(
d
=
0
;
d
<
root
->
nDepths
;
d
++
)
{
visual
=
(
xVisualType
*
)
((
char
*
)
depth
+
sizeof
(
xDepth
));
depth
=
(
xDepth
*
)
((
char
*
)
visual
+
depth
->
nVisuals
*
sizeof
(
xVisualType
));
}
root
=
(
xWindowRoot
*
)
((
char
*
)
depth
);
screen
++
;
}
root
->
pixWidth
=
pScreen
->
width
;
root
->
pixHeight
=
pScreen
->
height
;
root
->
mmWidth
=
pScreen
->
mmWidth
;
root
->
mmHeight
=
pScreen
->
mmHeight
;
}
static
int
ProcRRGetScreenInfo
(
ClientPtr
client
)
{
REQUEST
(
xRRGetScreenInfoReq
);
xRRGetScreenInfoReply
rep
;
WindowPtr
pWin
;
int
n
;
ScreenPtr
pScreen
;
rrScrPrivPtr
pScrPriv
;
CARD8
*
extra
;
int
extraLen
;
REQUEST_SIZE_MATCH
(
xRRGetScreenInfoReq
);
pWin
=
(
WindowPtr
)
SecurityLookupWindow
(
stuff
->
window
,
client
,
SecurityReadAccess
);
if
(
!
pWin
)
return
BadWindow
;
pScreen
=
pWin
->
drawable
.
pScreen
;
pScrPriv
=
rrGetScrPriv
(
pScreen
);
rep
.
pad
=
0
;
if
(
!
pScrPriv
)
{
rep
.
type
=
X_Reply
;
rep
.
setOfRotations
=
RR_Rotate_0
;;
rep
.
sequenceNumber
=
client
->
sequence
;
rep
.
length
=
0
;
rep
.
root
=
WindowTable
[
pWin
->
drawable
.
pScreen
->
myNum
]
->
drawable
.
id
;
rep
.
timestamp
=
currentTime
.
milliseconds
;
rep
.
configTimestamp
=
currentTime
.
milliseconds
;
rep
.
nSizes
=
0
;
rep
.
sizeID
=
0
;
rep
.
rotation
=
RR_Rotate_0
;
rep
.
rate
=
0
;
rep
.
nrateEnts
=
0
;
extra
=
0
;
extraLen
=
0
;
}
else
{
int
i
,
j
;
xScreenSizes
*
size
;
CARD16
*
rates
;
CARD8
*
data8
;
Bool
has_rate
=
RRClientKnowsRates
(
client
);
RRGetInfo
(
pScreen
);
rep
.
type
=
X_Reply
;
rep
.
setOfRotations
=
pScrPriv
->
rotations
;
rep
.
sequenceNumber
=
client
->
sequence
;
rep
.
length
=
0
;
rep
.
root
=
WindowTable
[
pWin
->
drawable
.
pScreen
->
myNum
]
->
drawable
.
id
;
rep
.
timestamp
=
pScrPriv
->
lastSetTime
.
milliseconds
;
rep
.
configTimestamp
=
pScrPriv
->
lastConfigTime
.
milliseconds
;
rep
.
rotation
=
pScrPriv
->
rotation
;
rep
.
nSizes
=
pScrPriv
->
nSizesInUse
;
rep
.
rate
=
pScrPriv
->
rate
;
rep
.
nrateEnts
=
0
;
if
(
has_rate
)
{
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
RRScreenSizePtr
pSize
=
&
pScrPriv
->
pSizes
[
i
];
if
(
pSize
->
referenced
)
{
rep
.
nrateEnts
+=
(
1
+
pSize
->
nRatesInUse
);
}
}
}
if
(
pScrPriv
->
size
>=
0
)
rep
.
sizeID
=
pScrPriv
->
pSizes
[
pScrPriv
->
size
].
id
;
else
return
BadImplementation
;
extraLen
=
(
rep
.
nSizes
*
sizeof
(
xScreenSizes
)
+
rep
.
nrateEnts
*
sizeof
(
CARD16
));
extra
=
(
CARD8
*
)
xalloc
(
extraLen
);
if
(
!
extra
)
return
BadAlloc
;
/*
* First comes the size information
*/
size
=
(
xScreenSizes
*
)
extra
;
rates
=
(
CARD16
*
)
(
size
+
rep
.
nSizes
);
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
RRScreenSizePtr
pSize
=
&
pScrPriv
->
pSizes
[
i
];
if
(
pSize
->
referenced
)
{
size
->
widthInPixels
=
pSize
->
width
;
size
->
heightInPixels
=
pSize
->
height
;
size
->
widthInMillimeters
=
pSize
->
mmWidth
;
size
->
heightInMillimeters
=
pSize
->
mmHeight
;
if
(
client
->
swapped
)
{
swaps
(
&
size
->
widthInPixels
,
n
);
swaps
(
&
size
->
heightInPixels
,
n
);
swaps
(
&
size
->
widthInMillimeters
,
n
);
swaps
(
&
size
->
heightInMillimeters
,
n
);
}
size
++
;
if
(
has_rate
)
{
*
rates
=
pSize
->
nRatesInUse
;
if
(
client
->
swapped
)
{
swaps
(
rates
,
n
);
}
rates
++
;
for
(
j
=
0
;
j
<
pSize
->
nRates
;
j
++
)
{
RRScreenRatePtr
pRate
=
&
pSize
->
pRates
[
j
];
if
(
pRate
->
referenced
)
{
*
rates
=
pRate
->
rate
;
if
(
client
->
swapped
)
{
swaps
(
rates
,
n
);
}
rates
++
;
}
}
}
}
}
data8
=
(
CARD8
*
)
rates
;
if
(
data8
-
(
CARD8
*
)
extra
!=
extraLen
)
FatalError
(
"RRGetScreenInfo bad extra len %d != %d
\n
"
,
data8
-
(
CARD8
*
)
extra
,
extraLen
);
rep
.
length
=
(
extraLen
+
3
)
>>
2
;
}
if
(
client
->
swapped
)
{
swaps
(
&
rep
.
sequenceNumber
,
n
);
swapl
(
&
rep
.
length
,
n
);
swapl
(
&
rep
.
timestamp
,
n
);
swaps
(
&
rep
.
rotation
,
n
);
swaps
(
&
rep
.
nSizes
,
n
);
swaps
(
&
rep
.
sizeID
,
n
);
swaps
(
&
rep
.
rate
,
n
);
swaps
(
&
rep
.
nrateEnts
,
n
);
}
WriteToClient
(
client
,
sizeof
(
xRRGetScreenInfoReply
),
(
char
*
)
&
rep
);
if
(
extraLen
)
{
WriteToClient
(
client
,
extraLen
,
(
char
*
)
extra
);
xfree
(
extra
);
}
return
(
client
->
noClientException
);
}
static
int
ProcRRSetScreenConfig
(
ClientPtr
client
)
{
REQUEST
(
xRRSetScreenConfigReq
);
xRRSetScreenConfigReply
rep
;
DrawablePtr
pDraw
;
int
n
;
ScreenPtr
pScreen
;
rrScrPrivPtr
pScrPriv
;
TimeStamp
configTime
;
TimeStamp
time
;
RRScreenSizePtr
pSize
;
int
i
;
Rotation
rotation
;
int
rate
;
short
oldWidth
,
oldHeight
;
Bool
has_rate
;
UpdateCurrentTime
();
if
(
RRClientKnowsRates
(
client
))
{
REQUEST_SIZE_MATCH
(
xRRSetScreenConfigReq
);
has_rate
=
TRUE
;
}
else
{
REQUEST_SIZE_MATCH
(
xRR1_0SetScreenConfigReq
);
has_rate
=
FALSE
;
}
SECURITY_VERIFY_DRAWABLE
(
pDraw
,
stuff
->
drawable
,
client
,
SecurityWriteAccess
);
pScreen
=
pDraw
->
pScreen
;
pScrPriv
=
rrGetScrPriv
(
pScreen
);
time
=
ClientTimeToServerTime
(
stuff
->
timestamp
);
configTime
=
ClientTimeToServerTime
(
stuff
->
configTimestamp
);
oldWidth
=
pScreen
->
width
;
oldHeight
=
pScreen
->
height
;
if
(
!
pScrPriv
)
{
time
=
currentTime
;
rep
.
status
=
RRSetConfigFailed
;
goto
sendReply
;
}
if
(
!
RRGetInfo
(
pScreen
))
return
BadAlloc
;
/*
* if the client's config timestamp is not the same as the last config
* timestamp, then the config information isn't up-to-date and
* can't even be validated
*/
if
(
CompareTimeStamps
(
configTime
,
pScrPriv
->
lastConfigTime
)
!=
0
)
{
rep
.
status
=
RRSetConfigInvalidConfigTime
;
goto
sendReply
;
}
/*
* Search for the requested size
*/
pSize
=
0
;
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
pSize
=
&
pScrPriv
->
pSizes
[
i
];
if
(
pSize
->
referenced
&&
pSize
->
id
==
stuff
->
sizeID
)
{
break
;
}
}
if
(
i
==
pScrPriv
->
nSizes
)
{
/*
* Invalid size ID
*/
client
->
errorValue
=
stuff
->
sizeID
;
return
BadValue
;
}
/*
* Validate requested rotation
*/
rotation
=
(
Rotation
)
stuff
->
rotation
;
/* test the rotation bits only! */
switch
(
rotation
&
0xf
)
{
case
RR_Rotate_0
:
case
RR_Rotate_90
:
case
RR_Rotate_180
:
case
RR_Rotate_270
:
break
;
default:
/*
* Invalid rotation
*/
client
->
errorValue
=
stuff
->
rotation
;
return
BadValue
;
}
if
((
~
pScrPriv
->
rotations
)
&
rotation
)
{
/*
* requested rotation or reflection not supported by screen
*/
client
->
errorValue
=
stuff
->
rotation
;
return
BadMatch
;
}
/*
* Validate requested refresh
*/
if
(
has_rate
)
rate
=
(
int
)
stuff
->
rate
;
else
rate
=
0
;
if
(
rate
)
{
for
(
i
=
0
;
i
<
pSize
->
nRates
;
i
++
)
{
RRScreenRatePtr
pRate
=
&
pSize
->
pRates
[
i
];
if
(
pRate
->
referenced
&&
pRate
->
rate
==
rate
)
break
;
}
if
(
i
==
pSize
->
nRates
)
{
/*
* Invalid rate
*/
client
->
errorValue
=
rate
;
return
BadValue
;
}
}
/*
* Make sure the requested set-time is not older than
* the last set-time
*/
if
(
CompareTimeStamps
(
time
,
pScrPriv
->
lastSetTime
)
<
0
)
{
rep
.
status
=
RRSetConfigInvalidTime
;
goto
sendReply
;
}
/*
* call out to ddx routine to effect the change
*/
if
(
!
(
*
pScrPriv
->
rrSetConfig
)
(
pScreen
,
rotation
,
rate
,
pSize
))
{
/*
* unknown DDX failure, report to client
*/
rep
.
status
=
RRSetConfigFailed
;
goto
sendReply
;
}
/*
* set current extension configuration pointers
*/
RRSetCurrentConfig
(
pScreen
,
rotation
,
rate
,
pSize
);
/*
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree
(
pScreen
,
TellChanged
,
(
pointer
)
pScreen
);
/*
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if
(
oldWidth
!=
pScreen
->
width
||
oldHeight
!=
pScreen
->
height
)
RRSendConfigNotify
(
pScreen
);
RREditConnectionInfo
(
pScreen
);
/*
* Fix pointer bounds and location
*/
ScreenRestructured
(
pScreen
);
pScrPriv
->
lastSetTime
=
time
;
/*
* Report Success
*/
rep
.
status
=
RRSetConfigSuccess
;
sendReply:
rep
.
type
=
X_Reply
;
/* rep.status has already been filled in */
rep
.
length
=
0
;
rep
.
sequenceNumber
=
client
->
sequence
;
rep
.
newTimestamp
=
pScrPriv
->
lastSetTime
.
milliseconds
;
rep
.
newConfigTimestamp
=
pScrPriv
->
lastConfigTime
.
milliseconds
;
rep
.
root
=
WindowTable
[
pDraw
->
pScreen
->
myNum
]
->
drawable
.
id
;
if
(
client
->
swapped
)
{
swaps
(
&
rep
.
sequenceNumber
,
n
);
swapl
(
&
rep
.
length
,
n
);
swapl
(
&
rep
.
newTimestamp
,
n
);
swapl
(
&
rep
.
newConfigTimestamp
,
n
);
swapl
(
&
rep
.
root
,
n
);
}
WriteToClient
(
client
,
sizeof
(
xRRSetScreenConfigReply
),
(
char
*
)
&
rep
);
return
(
client
->
noClientException
);
}
static
int
ProcRRSelectInput
(
ClientPtr
client
)
{
REQUEST
(
xRRSelectInputReq
);
rrClientPriv
(
client
);
RRTimesPtr
pTimes
;
WindowPtr
pWin
;
RREventPtr
pRREvent
,
pNewRREvent
,
*
pHead
;
XID
clientResource
;
REQUEST_SIZE_MATCH
(
xRRSelectInputReq
);
pWin
=
SecurityLookupWindow
(
stuff
->
window
,
client
,
SecurityWriteAccess
);
if
(
!
pWin
)
return
BadWindow
;
pHead
=
(
RREventPtr
*
)
SecurityLookupIDByType
(
client
,
pWin
->
drawable
.
id
,
EventType
,
SecurityWriteAccess
);
if
(
stuff
->
enable
&
(
RRScreenChangeNotifyMask
))
{
ScreenPtr
pScreen
=
pWin
->
drawable
.
pScreen
;
rrScrPriv
(
pScreen
);
if
(
pHead
)
{
/* check for existing entry. */
for
(
pRREvent
=
*
pHead
;
pRREvent
;
pRREvent
=
pRREvent
->
next
)
if
(
pRREvent
->
client
==
client
)
return
Success
;
}
/* build the entry */
pNewRREvent
=
(
RREventPtr
)
xalloc
(
sizeof
(
RREventRec
));
if
(
!
pNewRREvent
)
return
BadAlloc
;
pNewRREvent
->
next
=
0
;
pNewRREvent
->
client
=
client
;
pNewRREvent
->
window
=
pWin
;
pNewRREvent
->
mask
=
stuff
->
enable
;
/*
* add a resource that will be deleted when
* the client goes away
*/
clientResource
=
FakeClientID
(
client
->
index
);
pNewRREvent
->
clientResource
=
clientResource
;
if
(
!
AddResource
(
clientResource
,
ClientType
,
(
pointer
)
pNewRREvent
))
return
BadAlloc
;
/*
* create a resource to contain a pointer to the list
* of clients selecting input. This must be indirect as
* the list may be arbitrarily rearranged which cannot be
* done through the resource database.
*/
if
(
!
pHead
)
{
pHead
=
(
RREventPtr
*
)
xalloc
(
sizeof
(
RREventPtr
));
if
(
!
pHead
||
!
AddResource
(
pWin
->
drawable
.
id
,
EventType
,
(
pointer
)
pHead
))
{
FreeResource
(
clientResource
,
RT_NONE
);
return
BadAlloc
;
}
*
pHead
=
0
;
}
pNewRREvent
->
next
=
*
pHead
;
*
pHead
=
pNewRREvent
;
/*
* Now see if the client needs an event
*/
if
(
pScrPriv
)
{
pTimes
=
&
((
RRTimesPtr
)
(
pRRClient
+
1
))[
pScreen
->
myNum
];
if
(
CompareTimeStamps
(
pTimes
->
setTime
,
pScrPriv
->
lastSetTime
)
!=
0
||
CompareTimeStamps
(
pTimes
->
configTime
,
pScrPriv
->
lastConfigTime
)
!=
0
)
{
TellChanged
(
pWin
,
(
pointer
)
pScreen
);
}
}
}
else
if
(
stuff
->
enable
==
xFalse
)
{
/* delete the interest */
if
(
pHead
)
{
pNewRREvent
=
0
;
for
(
pRREvent
=
*
pHead
;
pRREvent
;
pRREvent
=
pRREvent
->
next
)
{
if
(
pRREvent
->
client
==
client
)
break
;
pNewRREvent
=
pRREvent
;
}
if
(
pRREvent
)
{
FreeResource
(
pRREvent
->
clientResource
,
ClientType
);
if
(
pNewRREvent
)
pNewRREvent
->
next
=
pRREvent
->
next
;
else
*
pHead
=
pRREvent
->
next
;
xfree
(
pRREvent
);
}
}
}
else
{
client
->
errorValue
=
stuff
->
enable
;
return
BadValue
;
}
return
Success
;
}
static
int
ProcRRDispatch
(
ClientPtr
client
)
{
REQUEST
(
xReq
);
switch
(
stuff
->
data
)
{
case
X_RRQueryVersion
:
return
ProcRRQueryVersion
(
client
);
case
X_RRSetScreenConfig
:
return
ProcRRSetScreenConfig
(
client
);
case
X_RRSelectInput
:
return
ProcRRSelectInput
(
client
);
case
X_RRGetScreenInfo
:
return
ProcRRGetScreenInfo
(
client
);
default:
return
BadRequest
;
}
}
static
int
SProcRRQueryVersion
(
ClientPtr
client
)
{
register
int
n
;
REQUEST
(
xRRQueryVersionReq
);
swaps
(
&
stuff
->
length
,
n
);
swapl
(
&
stuff
->
majorVersion
,
n
);
swapl
(
&
stuff
->
minorVersion
,
n
);
return
ProcRRQueryVersion
(
client
);
}
static
int
SProcRRGetScreenInfo
(
ClientPtr
client
)
{
register
int
n
;
REQUEST
(
xRRGetScreenInfoReq
);
swaps
(
&
stuff
->
length
,
n
);
swapl
(
&
stuff
->
window
,
n
);
return
ProcRRGetScreenInfo
(
client
);
}
static
int
SProcRRSetScreenConfig
(
ClientPtr
client
)
{
register
int
n
;
REQUEST
(
xRRSetScreenConfigReq
);
if
(
RRClientKnowsRates
(
client
))
{
REQUEST_SIZE_MATCH
(
xRRSetScreenConfigReq
);
swaps
(
&
stuff
->
rate
,
n
);
}
else
{
REQUEST_SIZE_MATCH
(
xRR1_0SetScreenConfigReq
);
}
swaps
(
&
stuff
->
length
,
n
);
swapl
(
&
stuff
->
drawable
,
n
);
swapl
(
&
stuff
->
timestamp
,
n
);
swaps
(
&
stuff
->
sizeID
,
n
);
swaps
(
&
stuff
->
rotation
,
n
);
return
ProcRRSetScreenConfig
(
client
);
}
static
int
SProcRRSelectInput
(
ClientPtr
client
)
{
register
int
n
;
REQUEST
(
xRRSelectInputReq
);
swaps
(
&
stuff
->
length
,
n
);
swapl
(
&
stuff
->
window
,
n
);
return
ProcRRSelectInput
(
client
);
}
static
int
SProcRRDispatch
(
ClientPtr
client
)
{
REQUEST
(
xReq
);
switch
(
stuff
->
data
)
{
case
X_RRQueryVersion
:
return
SProcRRQueryVersion
(
client
);
case
X_RRSetScreenConfig
:
return
SProcRRSetScreenConfig
(
client
);
case
X_RRSelectInput
:
return
SProcRRSelectInput
(
client
);
case
X_RRGetScreenInfo
:
return
SProcRRGetScreenInfo
(
client
);
default:
return
BadRequest
;
}
}
static
Bool
RRScreenSizeMatches
(
RRScreenSizePtr
a
,
RRScreenSizePtr
b
)
{
if
(
a
->
width
!=
b
->
width
)
return
FALSE
;
if
(
a
->
height
!=
b
->
height
)
return
FALSE
;
if
(
a
->
mmWidth
!=
b
->
mmWidth
)
return
FALSE
;
if
(
a
->
mmHeight
!=
b
->
mmHeight
)
return
FALSE
;
return
TRUE
;
}
RRScreenSizePtr
RRRegisterSize
(
ScreenPtr
pScreen
,
short
width
,
short
height
,
short
mmWidth
,
short
mmHeight
)
{
rrScrPriv
(
pScreen
);
int
i
;
RRScreenSize
tmp
;
RRScreenSizePtr
pNew
;
if
(
!
pScrPriv
)
return
0
;
/*
* FIXME: The compiler reports that field
* id is used uninitialized here.
*/
tmp
.
id
=
0
;
tmp
.
width
=
width
;
tmp
.
height
=
height
;
tmp
.
mmWidth
=
mmWidth
;
tmp
.
mmHeight
=
mmHeight
;
tmp
.
pRates
=
0
;
tmp
.
nRates
=
0
;
tmp
.
nRatesInUse
=
0
;
tmp
.
referenced
=
TRUE
;
tmp
.
oldReferenced
=
FALSE
;
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
if
(
RRScreenSizeMatches
(
&
tmp
,
&
pScrPriv
->
pSizes
[
i
]))
{
pScrPriv
->
pSizes
[
i
].
referenced
=
TRUE
;
return
&
pScrPriv
->
pSizes
[
i
];
}
pNew
=
xrealloc
(
pScrPriv
->
pSizes
,
(
pScrPriv
->
nSizes
+
1
)
*
sizeof
(
RRScreenSize
));
if
(
!
pNew
)
return
0
;
pNew
[
pScrPriv
->
nSizes
++
]
=
tmp
;
pScrPriv
->
pSizes
=
pNew
;
return
&
pNew
[
pScrPriv
->
nSizes
-
1
];
}
Bool
RRRegisterRate
(
ScreenPtr
pScreen
,
RRScreenSizePtr
pSize
,
int
rate
)
{
rrScrPriv
(
pScreen
);
int
i
;
RRScreenRatePtr
pNew
,
pRate
;
if
(
!
pScrPriv
)
return
FALSE
;
for
(
i
=
0
;
i
<
pSize
->
nRates
;
i
++
)
{
pRate
=
&
pSize
->
pRates
[
i
];
if
(
pRate
->
rate
==
rate
)
{
pRate
->
referenced
=
TRUE
;
return
TRUE
;
}
}
pNew
=
xrealloc
(
pSize
->
pRates
,
(
pSize
->
nRates
+
1
)
*
sizeof
(
RRScreenRate
));
if
(
!
pNew
)
return
FALSE
;
pRate
=
&
pNew
[
pSize
->
nRates
++
];
pRate
->
rate
=
rate
;
pRate
->
referenced
=
TRUE
;
pRate
->
oldReferenced
=
FALSE
;
pSize
->
pRates
=
pNew
;
return
TRUE
;
}
void
RRSetCurrentConfig
(
ScreenPtr
pScreen
,
Rotation
rotation
,
int
rate
,
RRScreenSizePtr
pSize
)
{
rrScrPriv
(
pScreen
);
if
(
!
pScrPriv
)
return
;
pScrPriv
->
rotation
=
rotation
;
pScrPriv
->
size
=
pSize
-
pScrPriv
->
pSizes
;
pScrPriv
->
rate
=
rate
;
}
#endif
/* #ifdef NXAGENT_UPGRADE */
nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
deleted
100644 → 0
View file @
39b738a6
#ifdef NXAGENT_UPGRADE
#include "X/NXrandr.c"
#else
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */
/* */
/* NXAGENT, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of Medialogic S.p.A. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
/*
* $XFree86: xc/programs/Xserver/randr/randr.c,v 1.19 2003/02/08 03:52:30 dawes Exp $
*
* Copyright 2000, Compaq Computer Corporation,
* Copyright 2002, Hewlett Packard, Inc.
*
* 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, and that the name of Compaq or HP not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission. HP makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
*/
#define NEED_REPLIES
#define NEED_EVENTS
#include "X.h"
#include "Xproto.h"
#include "misc.h"
#include "os.h"
#include "dixstruct.h"
#include "resource.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "servermd.h"
#include "randr.h"
#include "randrproto.h"
#include "../../randr/randrstr.h"
#include "render.h" /* we share subpixel order information */
#include "picturestr.h"
#include "Xfuncproto.h"
#ifdef EXTMODULE
#include "xf86_ansic.h"
#endif
#define RR_VALIDATE
int RRGeneration;
int RRNScreens;
static int ProcRRQueryVersion (ClientPtr pClient);
static int ProcRRDispatch (ClientPtr pClient);
static int SProcRRDispatch (ClientPtr pClient);
static int SProcRRQueryVersion (ClientPtr pClient);
#define wrap(priv,real,mem,func) {\
priv->mem = real->mem; \
real->mem = func; \
}
#define unwrap(priv,real,mem) {\
real->mem = priv->mem; \
}
static CARD8 RRReqCode;
static int RRErrBase;
static int RREventBase;
static RESTYPE ClientType, EventType; /* resource types for event masks */
static int RRClientPrivateIndex;
typedef struct _RRTimes {
TimeStamp setTime;
TimeStamp configTime;
} RRTimesRec, *RRTimesPtr;
typedef struct _RRClient {
int major_version;
int minor_version;
/* RRTimesRec times[0]; */
} RRClientRec, *RRClientPtr;
/*
* each window has a list of clients requesting
* RRNotify events. Each client has a resource
* for each window it selects RRNotify input for,
* this resource is used to delete the RRNotifyRec
* entry from the per-window queue.
*/
typedef struct _RREvent *RREventPtr;
typedef struct _RREvent {
RREventPtr next;
ClientPtr client;
WindowPtr window;
XID clientResource;
int mask;
} RREventRec;
int rrPrivIndex = -1;
#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
static Bool
RRClientKnowsRates (ClientPtr pClient)
{
rrClientPriv(pClient);
return (pRRClient->major_version > 1 ||
(pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
}
static void
RRClientCallback (CallbackListPtr *list,
pointer closure,
pointer data)
{
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
ClientPtr pClient = clientinfo->client;
rrClientPriv(pClient);
RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
int i;
pRRClient->major_version = 0;
pRRClient->minor_version = 0;
for (i = 0; i < screenInfo.numScreens; i++)
{
ScreenPtr pScreen = screenInfo.screens[i];
rrScrPriv(pScreen);
if (pScrPriv)
{
pTimes[i].setTime = pScrPriv->lastSetTime;
pTimes[i].configTime = pScrPriv->lastConfigTime;
}
}
}
static void
RRResetProc (ExtensionEntry *extEntry)
{
}
static Bool
RRCloseScreen (int i, ScreenPtr pScreen)
{
rrScrPriv(pScreen);
unwrap (pScrPriv, pScreen, CloseScreen);
if (pScrPriv->pSizes)
xfree (pScrPriv->pSizes);
xfree (pScrPriv);
RRNScreens -= 1; /* ok, one fewer screen with RandR running */
return (*pScreen->CloseScreen) (i, pScreen);
}
static void
SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
xRRScreenChangeNotifyEvent *to)
{
to->type = from->type;
to->rotation = from->rotation;
cpswaps(from->sequenceNumber, to->sequenceNumber);
cpswapl(from->timestamp, to->timestamp);
cpswapl(from->configTimestamp, to->configTimestamp);
cpswapl(from->root, to->root);
cpswapl(from->window, to->window);
cpswaps(from->sizeID, to->sizeID);
cpswaps(from->widthInPixels, to->widthInPixels);
cpswaps(from->heightInPixels, to->heightInPixels);
cpswaps(from->widthInMillimeters, to->widthInMillimeters);
cpswaps(from->heightInMillimeters, to->heightInMillimeters);
cpswaps(from->subpixelOrder, to->subpixelOrder);
}
Bool RRScreenInit(ScreenPtr pScreen)
{
rrScrPrivPtr pScrPriv;
if (RRGeneration != serverGeneration)
{
if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
return FALSE;
RRGeneration = serverGeneration;
}
pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
if (!pScrPriv)
return FALSE;
SetRRScreen(pScreen, pScrPriv);
/*
* Calling function best set these function vectors
*/
pScrPriv->rrSetConfig = 0;
pScrPriv->rrGetInfo = 0;
/*
* This value doesn't really matter -- any client must call
* GetScreenInfo before reading it which will automatically update
* the time
*/
pScrPriv->lastSetTime = currentTime;
pScrPriv->lastConfigTime = currentTime;
wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
pScrPriv->rotations = RR_Rotate_0;
pScrPriv->nSizes = 0;
pScrPriv->nSizesInUse = 0;
pScrPriv->pSizes = 0;
pScrPriv->rotation = RR_Rotate_0;
pScrPriv->size = -1;
RRNScreens += 1; /* keep count of screens that implement randr */
return TRUE;
}
/*ARGSUSED*/
static int
RRFreeClient (pointer data, XID id)
{
RREventPtr pRREvent;
WindowPtr pWin;
RREventPtr *pHead, pCur, pPrev;
pRREvent = (RREventPtr) data;
pWin = pRREvent->window;
pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType);
if (pHead) {
pPrev = 0;
for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
pPrev = pCur;
if (pCur)
{
if (pPrev)
pPrev->next = pRREvent->next;
else
*pHead = pRREvent->next;
}
}
xfree ((pointer) pRREvent);
return 1;
}
/*ARGSUSED*/
static int
RRFreeEvents (pointer data, XID id)
{
RREventPtr *pHead, pCur, pNext;
pHead = (RREventPtr *) data;
for (pCur = *pHead; pCur; pCur = pNext) {
pNext = pCur->next;
FreeResource (pCur->clientResource, ClientType);
xfree ((pointer) pCur);
}
xfree ((pointer) pHead);
return 1;
}
void
RRExtensionInit (void)
{
ExtensionEntry *extEntry;
if (RRNScreens == 0) return;
RRClientPrivateIndex = AllocateClientPrivateIndex ();
if (!AllocateClientPrivate (RRClientPrivateIndex,
sizeof (RRClientRec) +
screenInfo.numScreens * sizeof (RRTimesRec)))
return;
if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
return;
ClientType = CreateNewResourceType(RRFreeClient);
if (!ClientType)
return;
EventType = CreateNewResourceType(RRFreeEvents);
if (!EventType)
return;
extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
ProcRRDispatch, SProcRRDispatch,
RRResetProc, StandardMinorOpcode);
if (!extEntry)
return;
RRReqCode = (CARD8) extEntry->base;
RRErrBase = extEntry->errorBase;
RREventBase = extEntry->eventBase;
EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
SRRScreenChangeNotifyEvent;
return;
}
int
TellChanged (WindowPtr pWin, pointer value)
{
RREventPtr *pHead, pRREvent;
ClientPtr client;
xRRScreenChangeNotifyEvent se;
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv(pScreen);
RRScreenSizePtr pSize;
WindowPtr pRoot = WindowTable[pScreen->myNum];
pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType);
if (!pHead)
return WT_WALKCHILDREN;
se.type = RRScreenChangeNotify + RREventBase;
se.rotation = (CARD8) pScrPriv->rotation;
se.timestamp = pScrPriv->lastSetTime.milliseconds;
se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
se.root = pRoot->drawable.id;
se.window = pWin->drawable.id;
se.subpixelOrder = PictureGetSubpixelOrder (pScreen);
if (pScrPriv->size >= 0)
{
pSize = &pScrPriv->pSizes[pScrPriv->size];
se.sizeID = pSize->id;
se.widthInPixels = pSize->width;
se.heightInPixels = pSize->height;
se.widthInMillimeters = pSize->mmWidth;
se.heightInMillimeters = pSize->mmHeight;
}
else
{
/*
* This "shouldn't happen", but a broken DDX can
* forget to set the current configuration on GetInfo
*/
se.sizeID = 0xffff;
se.widthInPixels = 0;
se.heightInPixels = 0;
se.widthInMillimeters = 0;
se.heightInMillimeters = 0;
}
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
{
client = pRREvent->client;
if (client == serverClient || client->clientGone)
continue;
se.sequenceNumber = client->sequence;
if(pRREvent->mask & RRScreenChangeNotifyMask)
WriteEventsToClient (client, 1, (xEvent *) &se);
}
return WT_WALKCHILDREN;
}
Bool
RRGetInfo (ScreenPtr pScreen)
{
rrScrPriv (pScreen);
int i, j, k, l;
Bool changed;
Rotation rotations;
RRScreenSizePtr pSize;
RRScreenRatePtr pRate;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
pSize->oldReferenced = pSize->referenced;
pSize->referenced = FALSE;
for (k = 0; k < pSize->nRates; k++)
{
pRate = &pSize->pRates[k];
pRate->oldReferenced = pRate->referenced;
pRate->referenced = FALSE;
}
}
if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
return FALSE;
changed = FALSE;
/*
* Check whether anything changed and simultaneously generate
* the protocol id values for the objects
*/
if (rotations != pScrPriv->rotations)
{
pScrPriv->rotations = rotations;
changed = TRUE;
}
j = 0;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
if (pSize->oldReferenced != pSize->referenced)
changed = TRUE;
if (pSize->referenced)
pSize->id = j++;
l = 0;
for (k = 0; k < pSize->nRates; k++)
{
pRate = &pSize->pRates[k];
if (pRate->oldReferenced != pRate->referenced)
changed = TRUE;
if (pRate->referenced)
l++;
}
pSize->nRatesInUse = l;
}
pScrPriv->nSizesInUse = j;
if (changed)
{
UpdateCurrentTime ();
pScrPriv->lastConfigTime = currentTime;
WalkTree (pScreen, TellChanged, (pointer) pScreen);
}
return TRUE;
}
void
RRSendConfigNotify (ScreenPtr pScreen)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
xEvent event;
event.u.u.type = ConfigureNotify;
event.u.configureNotify.window = pWin->drawable.id;
event.u.configureNotify.aboveSibling = None;
event.u.configureNotify.x = 0;
event.u.configureNotify.y = 0;
/* XXX xinerama stuff ? */
event.u.configureNotify.width = pWin->drawable.width;
event.u.configureNotify.height = pWin->drawable.height;
event.u.configureNotify.borderWidth = wBorderWidth (pWin);
event.u.configureNotify.override = pWin->overrideRedirect;
DeliverEvents(pWin, &event, 1, NullWindow);
}
static int
ProcRRQueryVersion (ClientPtr client)
{
xRRQueryVersionReply rep;
register int n;
REQUEST(xRRQueryVersionReq);
rrClientPriv(client);
REQUEST_SIZE_MATCH(xRRQueryVersionReq);
pRRClient->major_version = stuff->majorVersion;
pRRClient->minor_version = stuff->minorVersion;
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.majorVersion = RANDR_MAJOR;
rep.minorVersion = RANDR_MINOR;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.majorVersion, n);
swapl(&rep.minorVersion, n);
}
WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep);
return (client->noClientException);
}
extern char *ConnectionInfo;
static int padlength[4] = {0, 3, 2, 1};
void
RREditConnectionInfo (ScreenPtr pScreen)
{
xConnSetup *connSetup;
char *vendor;
xPixmapFormat *formats;
xWindowRoot *root;
xDepth *depth;
xVisualType *visual;
int screen = 0;
int d;
connSetup = (xConnSetup *) ConnectionInfo;
vendor = (char *) connSetup + sizeof (xConnSetup);
formats = (xPixmapFormat *) ((char *) vendor +
connSetup->nbytesVendor +
padlength[connSetup->nbytesVendor & 3]);
root = (xWindowRoot *) ((char *) formats +
sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
while (screen != pScreen->myNum)
{
depth = (xDepth *) ((char *) root +
sizeof (xWindowRoot));
for (d = 0; d < root->nDepths; d++)
{
visual = (xVisualType *) ((char *) depth +
sizeof (xDepth));
depth = (xDepth *) ((char *) visual +
depth->nVisuals * sizeof (xVisualType));
}
root = (xWindowRoot *) ((char *) depth);
screen++;
}
root->pixWidth = pScreen->width;
root->pixHeight = pScreen->height;
root->mmWidth = pScreen->mmWidth;
root->mmHeight = pScreen->mmHeight;
}
static int
ProcRRGetScreenInfo (ClientPtr client)
{
REQUEST(xRRGetScreenInfoReq);
xRRGetScreenInfoReply rep;
WindowPtr pWin;
int n;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
CARD8 *extra;
int extraLen;
REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
SecurityReadAccess);
if (!pWin)
return BadWindow;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
rep.pad = 0;
if (!pScrPriv)
{
rep.type = X_Reply;
rep.setOfRotations = RR_Rotate_0;;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
rep.timestamp = currentTime.milliseconds;
rep.configTimestamp = currentTime.milliseconds;
rep.nSizes = 0;
rep.sizeID = 0;
rep.rotation = RR_Rotate_0;
rep.rate = 0;
rep.nrateEnts = 0;
extra = 0;
extraLen = 0;
}
else
{
int i, j;
xScreenSizes *size;
CARD16 *rates;
CARD8 *data8;
Bool has_rate = RRClientKnowsRates (client);
RRGetInfo (pScreen);
rep.type = X_Reply;
rep.setOfRotations = pScrPriv->rotations;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.rotation = pScrPriv->rotation;
rep.nSizes = pScrPriv->nSizesInUse;
rep.rate = pScrPriv->rate;
rep.nrateEnts = 0;
if (has_rate)
{
for (i = 0; i < pScrPriv->nSizes; i++)
{
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
if (pSize->referenced)
{
rep.nrateEnts += (1 + pSize->nRatesInUse);
}
}
}
if (pScrPriv->size >= 0)
rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id;
else
return BadImplementation;
extraLen = (rep.nSizes * sizeof (xScreenSizes) +
rep.nrateEnts * sizeof (CARD16));
extra = (CARD8 *) xalloc (extraLen);
if (!extra)
return BadAlloc;
/*
* First comes the size information
*/
size = (xScreenSizes *) extra;
rates = (CARD16 *) (size + rep.nSizes);
for (i = 0; i < pScrPriv->nSizes; i++)
{
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
if (pSize->referenced)
{
size->widthInPixels = pSize->width;
size->heightInPixels = pSize->height;
size->widthInMillimeters = pSize->mmWidth;
size->heightInMillimeters = pSize->mmHeight;
if (client->swapped)
{
swaps (&size->widthInPixels, n);
swaps (&size->heightInPixels, n);
swaps (&size->widthInMillimeters, n);
swaps (&size->heightInMillimeters, n);
}
size++;
if (has_rate)
{
*rates = pSize->nRatesInUse;
if (client->swapped)
{
swaps (rates, n);
}
rates++;
for (j = 0; j < pSize->nRates; j++)
{
RRScreenRatePtr pRate = &pSize->pRates[j];
if (pRate->referenced)
{
*rates = pRate->rate;
if (client->swapped)
{
swaps (rates, n);
}
rates++;
}
}
}
}
}
data8 = (CARD8 *) rates;
if (data8 - (CARD8 *) extra != extraLen)
FatalError ("RRGetScreenInfo bad extra len %d != %d\n",
data8 - (CARD8 *) extra, extraLen);
rep.length = (extraLen + 3) >> 2;
}
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.timestamp, n);
swaps(&rep.rotation, n);
swaps(&rep.nSizes, n);
swaps(&rep.sizeID, n);
swaps(&rep.rate, n);
swaps(&rep.nrateEnts, n);
}
WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
if (extraLen)
{
WriteToClient (client, extraLen, (char *) extra);
xfree (extra);
}
return (client->noClientException);
}
static int
ProcRRSetScreenConfig (ClientPtr client)
{
REQUEST(xRRSetScreenConfigReq);
xRRSetScreenConfigReply rep;
DrawablePtr pDraw;
int n;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
TimeStamp configTime;
TimeStamp time;
RRScreenSizePtr pSize;
int i;
Rotation rotation;
int rate;
short oldWidth, oldHeight;
Bool has_rate;
UpdateCurrentTime ();
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
has_rate = TRUE;
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
has_rate = FALSE;
}
SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client,
SecurityWriteAccess);
pScreen = pDraw->pScreen;
pScrPriv= rrGetScrPriv(pScreen);
time = ClientTimeToServerTime(stuff->timestamp);
configTime = ClientTimeToServerTime(stuff->configTimestamp);
oldWidth = pScreen->width;
oldHeight = pScreen->height;
if (!pScrPriv)
{
time = currentTime;
rep.status = RRSetConfigFailed;
goto sendReply;
}
if (!RRGetInfo (pScreen))
return BadAlloc;
/*
* if the client's config timestamp is not the same as the last config
* timestamp, then the config information isn't up-to-date and
* can't even be validated
*/
if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
{
rep.status = RRSetConfigInvalidConfigTime;
goto sendReply;
}
/*
* Search for the requested size
*/
pSize = 0;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
if (pSize->referenced && pSize->id == stuff->sizeID)
{
break;
}
}
if (i == pScrPriv->nSizes)
{
/*
* Invalid size ID
*/
client->errorValue = stuff->sizeID;
return BadValue;
}
/*
* Validate requested rotation
*/
rotation = (Rotation) stuff->rotation;
/* test the rotation bits only! */
switch (rotation & 0xf) {
case RR_Rotate_0:
case RR_Rotate_90:
case RR_Rotate_180:
case RR_Rotate_270:
break;
default:
/*
* Invalid rotation
*/
client->errorValue = stuff->rotation;
return BadValue;
}
if ((~pScrPriv->rotations) & rotation)
{
/*
* requested rotation or reflection not supported by screen
*/
client->errorValue = stuff->rotation;
return BadMatch;
}
/*
* Validate requested refresh
*/
if (has_rate)
rate = (int) stuff->rate;
else
rate = 0;
if (rate)
{
for (i = 0; i < pSize->nRates; i++)
{
RRScreenRatePtr pRate = &pSize->pRates[i];
if (pRate->referenced && pRate->rate == rate)
break;
}
if (i == pSize->nRates)
{
/*
* Invalid rate
*/
client->errorValue = rate;
return BadValue;
}
}
/*
* Make sure the requested set-time is not older than
* the last set-time
*/
if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
{
rep.status = RRSetConfigInvalidTime;
goto sendReply;
}
/*
* call out to ddx routine to effect the change
*/
if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
pSize))
{
/*
* unknown DDX failure, report to client
*/
rep.status = RRSetConfigFailed;
goto sendReply;
}
/*
* set current extension configuration pointers
*/
RRSetCurrentConfig (pScreen, rotation, rate, pSize);
/*
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree (pScreen, TellChanged, (pointer) pScreen);
/*
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if (oldWidth != pScreen->width || oldHeight != pScreen->height)
RRSendConfigNotify (pScreen);
RREditConnectionInfo (pScreen);
/*
* Fix pointer bounds and location
*/
ScreenRestructured (pScreen);
pScrPriv->lastSetTime = time;
/*
* Report Success
*/
rep.status = RRSetConfigSuccess;
sendReply:
rep.type = X_Reply;
/* rep.status has already been filled in */
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
if (client->swapped)
{
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.newTimestamp, n);
swapl(&rep.newConfigTimestamp, n);
swapl(&rep.root, n);
}
WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
return (client->noClientException);
}
static int
ProcRRSelectInput (ClientPtr client)
{
REQUEST(xRRSelectInputReq);
rrClientPriv(client);
RRTimesPtr pTimes;
WindowPtr pWin;
RREventPtr pRREvent, pNewRREvent, *pHead;
XID clientResource;
REQUEST_SIZE_MATCH(xRRSelectInputReq);
pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess);
if (!pWin)
return BadWindow;
pHead = (RREventPtr *)SecurityLookupIDByType(client,
pWin->drawable.id, EventType,
SecurityWriteAccess);
if (stuff->enable & (RRScreenChangeNotifyMask))
{
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv (pScreen);
if (pHead)
{
/* check for existing entry. */
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
if (pRREvent->client == client)
return Success;
}
/* build the entry */
pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
if (!pNewRREvent)
return BadAlloc;
pNewRREvent->next = 0;
pNewRREvent->client = client;
pNewRREvent->window = pWin;
pNewRREvent->mask = stuff->enable;
/*
* add a resource that will be deleted when
* the client goes away
*/
clientResource = FakeClientID (client->index);
pNewRREvent->clientResource = clientResource;
if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent))
return BadAlloc;
/*
* create a resource to contain a pointer to the list
* of clients selecting input. This must be indirect as
* the list may be arbitrarily rearranged which cannot be
* done through the resource database.
*/
if (!pHead)
{
pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
if (!pHead ||
!AddResource (pWin->drawable.id, EventType, (pointer)pHead))
{
FreeResource (clientResource, RT_NONE);
return BadAlloc;
}
*pHead = 0;
}
pNewRREvent->next = *pHead;
*pHead = pNewRREvent;
/*
* Now see if the client needs an event
*/
if (pScrPriv)
{
pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
if (CompareTimeStamps (pTimes->setTime,
pScrPriv->lastSetTime) != 0 ||
CompareTimeStamps (pTimes->configTime,
pScrPriv->lastConfigTime) != 0)
{
TellChanged (pWin, (pointer) pScreen);
}
}
}
else if (stuff->enable == xFalse)
{
/* delete the interest */
if (pHead) {
pNewRREvent = 0;
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
if (pRREvent->client == client)
break;
pNewRREvent = pRREvent;
}
if (pRREvent) {
FreeResource (pRREvent->clientResource, ClientType);
if (pNewRREvent)
pNewRREvent->next = pRREvent->next;
else
*pHead = pRREvent->next;
xfree (pRREvent);
}
}
}
else
{
client->errorValue = stuff->enable;
return BadValue;
}
return Success;
}
static int
ProcRRDispatch (ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_RRQueryVersion:
return ProcRRQueryVersion(client);
case X_RRSetScreenConfig:
return ProcRRSetScreenConfig(client);
case X_RRSelectInput:
return ProcRRSelectInput(client);
case X_RRGetScreenInfo:
return ProcRRGetScreenInfo(client);
default:
return BadRequest;
}
}
static int
SProcRRQueryVersion (ClientPtr client)
{
register int n;
REQUEST(xRRQueryVersionReq);
swaps(&stuff->length, n);
swapl(&stuff->majorVersion, n);
swapl(&stuff->minorVersion, n);
return ProcRRQueryVersion(client);
}
static int
SProcRRGetScreenInfo (ClientPtr client)
{
register int n;
REQUEST(xRRGetScreenInfoReq);
swaps(&stuff->length, n);
swapl(&stuff->window, n);
return ProcRRGetScreenInfo(client);
}
static int
SProcRRSetScreenConfig (ClientPtr client)
{
register int n;
REQUEST(xRRSetScreenConfigReq);
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
swaps (&stuff->rate, n);
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
}
swaps(&stuff->length, n);
swapl(&stuff->drawable, n);
swapl(&stuff->timestamp, n);
swaps(&stuff->sizeID, n);
swaps(&stuff->rotation, n);
return ProcRRSetScreenConfig(client);
}
static int
SProcRRSelectInput (ClientPtr client)
{
register int n;
REQUEST(xRRSelectInputReq);
swaps(&stuff->length, n);
swapl(&stuff->window, n);
return ProcRRSelectInput(client);
}
static int
SProcRRDispatch (ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_RRQueryVersion:
return SProcRRQueryVersion(client);
case X_RRSetScreenConfig:
return SProcRRSetScreenConfig(client);
case X_RRSelectInput:
return SProcRRSelectInput(client);
case X_RRGetScreenInfo:
return SProcRRGetScreenInfo(client);
default:
return BadRequest;
}
}
static Bool
RRScreenSizeMatches (RRScreenSizePtr a,
RRScreenSizePtr b)
{
if (a->width != b->width)
return FALSE;
if (a->height != b->height)
return FALSE;
if (a->mmWidth != b->mmWidth)
return FALSE;
if (a->mmHeight != b->mmHeight)
return FALSE;
return TRUE;
}
RRScreenSizePtr
RRRegisterSize (ScreenPtr pScreen,
short width,
short height,
short mmWidth,
short mmHeight)
{
rrScrPriv (pScreen);
int i;
RRScreenSize tmp;
RRScreenSizePtr pNew;
if (!pScrPriv)
return 0;
/*
* FIXME: The compiler reports that field
* id is used uninitialized here.
*/
tmp.id = 0;
tmp.width = width;
tmp.height= height;
tmp.mmWidth = mmWidth;
tmp.mmHeight = mmHeight;
tmp.pRates = 0;
tmp.nRates = 0;
tmp.nRatesInUse = 0;
tmp.referenced = TRUE;
tmp.oldReferenced = FALSE;
for (i = 0; i < pScrPriv->nSizes; i++)
if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
{
pScrPriv->pSizes[i].referenced = TRUE;
return &pScrPriv->pSizes[i];
}
pNew = xrealloc (pScrPriv->pSizes,
(pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
if (!pNew)
return 0;
pNew[pScrPriv->nSizes++] = tmp;
pScrPriv->pSizes = pNew;
return &pNew[pScrPriv->nSizes-1];
}
Bool RRRegisterRate (ScreenPtr pScreen,
RRScreenSizePtr pSize,
int rate)
{
rrScrPriv(pScreen);
int i;
RRScreenRatePtr pNew, pRate;
if (!pScrPriv)
return FALSE;
for (i = 0; i < pSize->nRates; i++)
{
pRate = &pSize->pRates[i];
if (pRate->rate == rate)
{
pRate->referenced = TRUE;
return TRUE;
}
}
pNew = xrealloc (pSize->pRates,
(pSize->nRates + 1) * sizeof (RRScreenRate));
if (!pNew)
return FALSE;
pRate = &pNew[pSize->nRates++];
pRate->rate = rate;
pRate->referenced = TRUE;
pRate->oldReferenced = FALSE;
pSize->pRates = pNew;
return TRUE;
}
void
RRSetCurrentConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize)
{
rrScrPriv (pScreen);
if (!pScrPriv)
return;
pScrPriv->rotation = rotation;
pScrPriv->size = pSize - pScrPriv->pSizes;
pScrPriv->rate = rate;
}
#endif /* #ifdef NXAGENT_UPGRADE */
nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original
deleted
100644 → 0
View file @
39b738a6
/*
* $XFree86: xc/programs/Xserver/randr/randr.c,v 1.19 2003/02/08 03:52:30 dawes Exp $
*
* Copyright 2000, Compaq Computer Corporation,
* Copyright 2002, Hewlett Packard, Inc.
*
* 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, and that the name of Compaq or HP not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission. HP makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
*/
#define NEED_REPLIES
#define NEED_EVENTS
#include "X.h"
#include "Xproto.h"
#include "misc.h"
#include "os.h"
#include "dixstruct.h"
#include "resource.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "servermd.h"
#include "randr.h"
#include "randrproto.h"
#include "randrstr.h"
#include "render.h" /* we share subpixel order information */
#include "picturestr.h"
#include "Xfuncproto.h"
#ifdef EXTMODULE
#include "xf86_ansic.h"
#endif
#define RR_VALIDATE
int RRGeneration;
int RRNScreens;
static int ProcRRQueryVersion (ClientPtr pClient);
static int ProcRRDispatch (ClientPtr pClient);
static int SProcRRDispatch (ClientPtr pClient);
static int SProcRRQueryVersion (ClientPtr pClient);
#define wrap(priv,real,mem,func) {\
priv->mem = real->mem; \
real->mem = func; \
}
#define unwrap(priv,real,mem) {\
real->mem = priv->mem; \
}
static CARD8 RRReqCode;
static int RRErrBase;
static int RREventBase;
static RESTYPE ClientType, EventType; /* resource types for event masks */
static int RRClientPrivateIndex;
typedef struct _RRTimes {
TimeStamp setTime;
TimeStamp configTime;
} RRTimesRec, *RRTimesPtr;
typedef struct _RRClient {
int major_version;
int minor_version;
/* RRTimesRec times[0]; */
} RRClientRec, *RRClientPtr;
/*
* each window has a list of clients requesting
* RRNotify events. Each client has a resource
* for each window it selects RRNotify input for,
* this resource is used to delete the RRNotifyRec
* entry from the per-window queue.
*/
typedef struct _RREvent *RREventPtr;
typedef struct _RREvent {
RREventPtr next;
ClientPtr client;
WindowPtr window;
XID clientResource;
int mask;
} RREventRec;
int rrPrivIndex = -1;
#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
static Bool
RRClientKnowsRates (ClientPtr pClient)
{
rrClientPriv(pClient);
return (pRRClient->major_version > 1 ||
(pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
}
static void
RRClientCallback (CallbackListPtr *list,
pointer closure,
pointer data)
{
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
ClientPtr pClient = clientinfo->client;
rrClientPriv(pClient);
RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
int i;
pRRClient->major_version = 0;
pRRClient->minor_version = 0;
for (i = 0; i < screenInfo.numScreens; i++)
{
ScreenPtr pScreen = screenInfo.screens[i];
rrScrPriv(pScreen);
if (pScrPriv)
{
pTimes[i].setTime = pScrPriv->lastSetTime;
pTimes[i].configTime = pScrPriv->lastConfigTime;
}
}
}
static void
RRResetProc (ExtensionEntry *extEntry)
{
}
static Bool
RRCloseScreen (int i, ScreenPtr pScreen)
{
rrScrPriv(pScreen);
unwrap (pScrPriv, pScreen, CloseScreen);
if (pScrPriv->pSizes)
xfree (pScrPriv->pSizes);
xfree (pScrPriv);
RRNScreens -= 1; /* ok, one fewer screen with RandR running */
return (*pScreen->CloseScreen) (i, pScreen);
}
static void
SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
xRRScreenChangeNotifyEvent *to)
{
to->type = from->type;
to->rotation = from->rotation;
cpswaps(from->sequenceNumber, to->sequenceNumber);
cpswapl(from->timestamp, to->timestamp);
cpswapl(from->configTimestamp, to->configTimestamp);
cpswapl(from->root, to->root);
cpswapl(from->window, to->window);
cpswaps(from->sizeID, to->sizeID);
cpswaps(from->widthInPixels, to->widthInPixels);
cpswaps(from->heightInPixels, to->heightInPixels);
cpswaps(from->widthInMillimeters, to->widthInMillimeters);
cpswaps(from->heightInMillimeters, to->heightInMillimeters);
cpswaps(from->subpixelOrder, to->subpixelOrder);
}
Bool RRScreenInit(ScreenPtr pScreen)
{
rrScrPrivPtr pScrPriv;
if (RRGeneration != serverGeneration)
{
if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
return FALSE;
RRGeneration = serverGeneration;
}
pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
if (!pScrPriv)
return FALSE;
SetRRScreen(pScreen, pScrPriv);
/*
* Calling function best set these function vectors
*/
pScrPriv->rrSetConfig = 0;
pScrPriv->rrGetInfo = 0;
/*
* This value doesn't really matter -- any client must call
* GetScreenInfo before reading it which will automatically update
* the time
*/
pScrPriv->lastSetTime = currentTime;
pScrPriv->lastConfigTime = currentTime;
wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
pScrPriv->rotations = RR_Rotate_0;
pScrPriv->nSizes = 0;
pScrPriv->nSizesInUse = 0;
pScrPriv->pSizes = 0;
pScrPriv->rotation = RR_Rotate_0;
pScrPriv->size = -1;
RRNScreens += 1; /* keep count of screens that implement randr */
return TRUE;
}
/*ARGSUSED*/
static int
RRFreeClient (pointer data, XID id)
{
RREventPtr pRREvent;
WindowPtr pWin;
RREventPtr *pHead, pCur, pPrev;
pRREvent = (RREventPtr) data;
pWin = pRREvent->window;
pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType);
if (pHead) {
pPrev = 0;
for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
pPrev = pCur;
if (pCur)
{
if (pPrev)
pPrev->next = pRREvent->next;
else
*pHead = pRREvent->next;
}
}
xfree ((pointer) pRREvent);
return 1;
}
/*ARGSUSED*/
static int
RRFreeEvents (pointer data, XID id)
{
RREventPtr *pHead, pCur, pNext;
pHead = (RREventPtr *) data;
for (pCur = *pHead; pCur; pCur = pNext) {
pNext = pCur->next;
FreeResource (pCur->clientResource, ClientType);
xfree ((pointer) pCur);
}
xfree ((pointer) pHead);
return 1;
}
void
RRExtensionInit (void)
{
ExtensionEntry *extEntry;
if (RRNScreens == 0) return;
RRClientPrivateIndex = AllocateClientPrivateIndex ();
if (!AllocateClientPrivate (RRClientPrivateIndex,
sizeof (RRClientRec) +
screenInfo.numScreens * sizeof (RRTimesRec)))
return;
if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
return;
ClientType = CreateNewResourceType(RRFreeClient);
if (!ClientType)
return;
EventType = CreateNewResourceType(RRFreeEvents);
if (!EventType)
return;
extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
ProcRRDispatch, SProcRRDispatch,
RRResetProc, StandardMinorOpcode);
if (!extEntry)
return;
RRReqCode = (CARD8) extEntry->base;
RRErrBase = extEntry->errorBase;
RREventBase = extEntry->eventBase;
EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
SRRScreenChangeNotifyEvent;
return;
}
static int
TellChanged (WindowPtr pWin, pointer value)
{
RREventPtr *pHead, pRREvent;
ClientPtr client;
xRRScreenChangeNotifyEvent se;
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv(pScreen);
RRScreenSizePtr pSize;
WindowPtr pRoot = WindowTable[pScreen->myNum];
pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType);
if (!pHead)
return WT_WALKCHILDREN;
se.type = RRScreenChangeNotify + RREventBase;
se.rotation = (CARD8) pScrPriv->rotation;
se.timestamp = pScrPriv->lastSetTime.milliseconds;
se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
se.root = pRoot->drawable.id;
se.window = pWin->drawable.id;
se.subpixelOrder = PictureGetSubpixelOrder (pScreen);
if (pScrPriv->size >= 0)
{
pSize = &pScrPriv->pSizes[pScrPriv->size];
se.sizeID = pSize->id;
se.widthInPixels = pSize->width;
se.heightInPixels = pSize->height;
se.widthInMillimeters = pSize->mmWidth;
se.heightInMillimeters = pSize->mmHeight;
}
else
{
/*
* This "shouldn't happen", but a broken DDX can
* forget to set the current configuration on GetInfo
*/
se.sizeID = 0xffff;
se.widthInPixels = 0;
se.heightInPixels = 0;
se.widthInMillimeters = 0;
se.heightInMillimeters = 0;
}
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
{
client = pRREvent->client;
if (client == serverClient || client->clientGone)
continue;
se.sequenceNumber = client->sequence;
if(pRREvent->mask & RRScreenChangeNotifyMask)
WriteEventsToClient (client, 1, (xEvent *) &se);
}
return WT_WALKCHILDREN;
}
static Bool
RRGetInfo (ScreenPtr pScreen)
{
rrScrPriv (pScreen);
int i, j, k, l;
Bool changed;
Rotation rotations;
RRScreenSizePtr pSize;
RRScreenRatePtr pRate;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
pSize->oldReferenced = pSize->referenced;
pSize->referenced = FALSE;
for (k = 0; k < pSize->nRates; k++)
{
pRate = &pSize->pRates[k];
pRate->oldReferenced = pRate->referenced;
pRate->referenced = FALSE;
}
}
if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
return FALSE;
changed = FALSE;
/*
* Check whether anything changed and simultaneously generate
* the protocol id values for the objects
*/
if (rotations != pScrPriv->rotations)
{
pScrPriv->rotations = rotations;
changed = TRUE;
}
j = 0;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
if (pSize->oldReferenced != pSize->referenced)
changed = TRUE;
if (pSize->referenced)
pSize->id = j++;
l = 0;
for (k = 0; k < pSize->nRates; k++)
{
pRate = &pSize->pRates[k];
if (pRate->oldReferenced != pRate->referenced)
changed = TRUE;
if (pRate->referenced)
l++;
}
pSize->nRatesInUse = l;
}
pScrPriv->nSizesInUse = j;
if (changed)
{
UpdateCurrentTime ();
pScrPriv->lastConfigTime = currentTime;
WalkTree (pScreen, TellChanged, (pointer) pScreen);
}
return TRUE;
}
static void
RRSendConfigNotify (ScreenPtr pScreen)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
xEvent event;
event.u.u.type = ConfigureNotify;
event.u.configureNotify.window = pWin->drawable.id;
event.u.configureNotify.aboveSibling = None;
event.u.configureNotify.x = 0;
event.u.configureNotify.y = 0;
/* XXX xinerama stuff ? */
event.u.configureNotify.width = pWin->drawable.width;
event.u.configureNotify.height = pWin->drawable.height;
event.u.configureNotify.borderWidth = wBorderWidth (pWin);
event.u.configureNotify.override = pWin->overrideRedirect;
DeliverEvents(pWin, &event, 1, NullWindow);
}
static int
ProcRRQueryVersion (ClientPtr client)
{
xRRQueryVersionReply rep;
register int n;
REQUEST(xRRQueryVersionReq);
rrClientPriv(client);
REQUEST_SIZE_MATCH(xRRQueryVersionReq);
pRRClient->major_version = stuff->majorVersion;
pRRClient->minor_version = stuff->minorVersion;
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.majorVersion = RANDR_MAJOR;
rep.minorVersion = RANDR_MINOR;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.majorVersion, n);
swapl(&rep.minorVersion, n);
}
WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep);
return (client->noClientException);
}
extern char *ConnectionInfo;
static int padlength[4] = {0, 3, 2, 1};
static void
RREditConnectionInfo (ScreenPtr pScreen)
{
xConnSetup *connSetup;
char *vendor;
xPixmapFormat *formats;
xWindowRoot *root;
xDepth *depth;
xVisualType *visual;
int screen = 0;
int d;
connSetup = (xConnSetup *) ConnectionInfo;
vendor = (char *) connSetup + sizeof (xConnSetup);
formats = (xPixmapFormat *) ((char *) vendor +
connSetup->nbytesVendor +
padlength[connSetup->nbytesVendor & 3]);
root = (xWindowRoot *) ((char *) formats +
sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
while (screen != pScreen->myNum)
{
depth = (xDepth *) ((char *) root +
sizeof (xWindowRoot));
for (d = 0; d < root->nDepths; d++)
{
visual = (xVisualType *) ((char *) depth +
sizeof (xDepth));
depth = (xDepth *) ((char *) visual +
depth->nVisuals * sizeof (xVisualType));
}
root = (xWindowRoot *) ((char *) depth);
screen++;
}
root->pixWidth = pScreen->width;
root->pixHeight = pScreen->height;
root->mmWidth = pScreen->mmWidth;
root->mmHeight = pScreen->mmHeight;
}
static int
ProcRRGetScreenInfo (ClientPtr client)
{
REQUEST(xRRGetScreenInfoReq);
xRRGetScreenInfoReply rep;
WindowPtr pWin;
int n;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
CARD8 *extra;
int extraLen;
REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
SecurityReadAccess);
if (!pWin)
return BadWindow;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
rep.pad = 0;
if (!pScrPriv)
{
rep.type = X_Reply;
rep.setOfRotations = RR_Rotate_0;;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
rep.timestamp = currentTime.milliseconds;
rep.configTimestamp = currentTime.milliseconds;
rep.nSizes = 0;
rep.sizeID = 0;
rep.rotation = RR_Rotate_0;
rep.rate = 0;
rep.nrateEnts = 0;
extra = 0;
extraLen = 0;
}
else
{
int i, j;
xScreenSizes *size;
CARD16 *rates;
CARD8 *data8;
Bool has_rate = RRClientKnowsRates (client);
RRGetInfo (pScreen);
rep.type = X_Reply;
rep.setOfRotations = pScrPriv->rotations;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.rotation = pScrPriv->rotation;
rep.nSizes = pScrPriv->nSizesInUse;
rep.rate = pScrPriv->rate;
rep.nrateEnts = 0;
if (has_rate)
{
for (i = 0; i < pScrPriv->nSizes; i++)
{
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
if (pSize->referenced)
{
rep.nrateEnts += (1 + pSize->nRatesInUse);
}
}
}
if (pScrPriv->size >= 0)
rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id;
else
return BadImplementation;
extraLen = (rep.nSizes * sizeof (xScreenSizes) +
rep.nrateEnts * sizeof (CARD16));
extra = (CARD8 *) xalloc (extraLen);
if (!extra)
return BadAlloc;
/*
* First comes the size information
*/
size = (xScreenSizes *) extra;
rates = (CARD16 *) (size + rep.nSizes);
for (i = 0; i < pScrPriv->nSizes; i++)
{
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
if (pSize->referenced)
{
size->widthInPixels = pSize->width;
size->heightInPixels = pSize->height;
size->widthInMillimeters = pSize->mmWidth;
size->heightInMillimeters = pSize->mmHeight;
if (client->swapped)
{
swaps (&size->widthInPixels, n);
swaps (&size->heightInPixels, n);
swaps (&size->widthInMillimeters, n);
swaps (&size->heightInMillimeters, n);
}
size++;
if (has_rate)
{
*rates = pSize->nRatesInUse;
if (client->swapped)
{
swaps (rates, n);
}
rates++;
for (j = 0; j < pSize->nRates; j++)
{
RRScreenRatePtr pRate = &pSize->pRates[j];
if (pRate->referenced)
{
*rates = pRate->rate;
if (client->swapped)
{
swaps (rates, n);
}
rates++;
}
}
}
}
}
data8 = (CARD8 *) rates;
if (data8 - (CARD8 *) extra != extraLen)
FatalError ("RRGetScreenInfo bad extra len %d != %d\n",
data8 - (CARD8 *) extra, extraLen);
rep.length = (extraLen + 3) >> 2;
}
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.timestamp, n);
swaps(&rep.rotation, n);
swaps(&rep.nSizes, n);
swaps(&rep.sizeID, n);
swaps(&rep.rate, n);
swaps(&rep.nrateEnts, n);
}
WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
if (extraLen)
{
WriteToClient (client, extraLen, (char *) extra);
xfree (extra);
}
return (client->noClientException);
}
static int
ProcRRSetScreenConfig (ClientPtr client)
{
REQUEST(xRRSetScreenConfigReq);
xRRSetScreenConfigReply rep;
DrawablePtr pDraw;
int n;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
TimeStamp configTime;
TimeStamp time;
RRScreenSizePtr pSize;
int i;
Rotation rotation;
int rate;
short oldWidth, oldHeight;
Bool has_rate;
UpdateCurrentTime ();
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
has_rate = TRUE;
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
has_rate = FALSE;
}
SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client,
SecurityWriteAccess);
pScreen = pDraw->pScreen;
pScrPriv= rrGetScrPriv(pScreen);
time = ClientTimeToServerTime(stuff->timestamp);
configTime = ClientTimeToServerTime(stuff->configTimestamp);
oldWidth = pScreen->width;
oldHeight = pScreen->height;
if (!pScrPriv)
{
time = currentTime;
rep.status = RRSetConfigFailed;
goto sendReply;
}
if (!RRGetInfo (pScreen))
return BadAlloc;
/*
* if the client's config timestamp is not the same as the last config
* timestamp, then the config information isn't up-to-date and
* can't even be validated
*/
if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
{
rep.status = RRSetConfigInvalidConfigTime;
goto sendReply;
}
/*
* Search for the requested size
*/
pSize = 0;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
if (pSize->referenced && pSize->id == stuff->sizeID)
{
break;
}
}
if (i == pScrPriv->nSizes)
{
/*
* Invalid size ID
*/
client->errorValue = stuff->sizeID;
return BadValue;
}
/*
* Validate requested rotation
*/
rotation = (Rotation) stuff->rotation;
/* test the rotation bits only! */
switch (rotation & 0xf) {
case RR_Rotate_0:
case RR_Rotate_90:
case RR_Rotate_180:
case RR_Rotate_270:
break;
default:
/*
* Invalid rotation
*/
client->errorValue = stuff->rotation;
return BadValue;
}
if ((~pScrPriv->rotations) & rotation)
{
/*
* requested rotation or reflection not supported by screen
*/
client->errorValue = stuff->rotation;
return BadMatch;
}
/*
* Validate requested refresh
*/
if (has_rate)
rate = (int) stuff->rate;
else
rate = 0;
if (rate)
{
for (i = 0; i < pSize->nRates; i++)
{
RRScreenRatePtr pRate = &pSize->pRates[i];
if (pRate->referenced && pRate->rate == rate)
break;
}
if (i == pSize->nRates)
{
/*
* Invalid rate
*/
client->errorValue = rate;
return BadValue;
}
}
/*
* Make sure the requested set-time is not older than
* the last set-time
*/
if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
{
rep.status = RRSetConfigInvalidTime;
goto sendReply;
}
/*
* call out to ddx routine to effect the change
*/
if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
pSize))
{
/*
* unknown DDX failure, report to client
*/
rep.status = RRSetConfigFailed;
goto sendReply;
}
/*
* set current extension configuration pointers
*/
RRSetCurrentConfig (pScreen, rotation, rate, pSize);
/*
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree (pScreen, TellChanged, (pointer) pScreen);
/*
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if (oldWidth != pScreen->width || oldHeight != pScreen->height)
RRSendConfigNotify (pScreen);
RREditConnectionInfo (pScreen);
/*
* Fix pointer bounds and location
*/
ScreenRestructured (pScreen);
pScrPriv->lastSetTime = time;
/*
* Report Success
*/
rep.status = RRSetConfigSuccess;
sendReply:
rep.type = X_Reply;
/* rep.status has already been filled in */
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
if (client->swapped)
{
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.newTimestamp, n);
swapl(&rep.newConfigTimestamp, n);
swapl(&rep.root, n);
}
WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
return (client->noClientException);
}
static int
ProcRRSelectInput (ClientPtr client)
{
REQUEST(xRRSelectInputReq);
rrClientPriv(client);
RRTimesPtr pTimes;
WindowPtr pWin;
RREventPtr pRREvent, pNewRREvent, *pHead;
XID clientResource;
REQUEST_SIZE_MATCH(xRRSelectInputReq);
pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess);
if (!pWin)
return BadWindow;
pHead = (RREventPtr *)SecurityLookupIDByType(client,
pWin->drawable.id, EventType,
SecurityWriteAccess);
if (stuff->enable & (RRScreenChangeNotifyMask))
{
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv (pScreen);
if (pHead)
{
/* check for existing entry. */
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
if (pRREvent->client == client)
return Success;
}
/* build the entry */
pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
if (!pNewRREvent)
return BadAlloc;
pNewRREvent->next = 0;
pNewRREvent->client = client;
pNewRREvent->window = pWin;
pNewRREvent->mask = stuff->enable;
/*
* add a resource that will be deleted when
* the client goes away
*/
clientResource = FakeClientID (client->index);
pNewRREvent->clientResource = clientResource;
if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent))
return BadAlloc;
/*
* create a resource to contain a pointer to the list
* of clients selecting input. This must be indirect as
* the list may be arbitrarily rearranged which cannot be
* done through the resource database.
*/
if (!pHead)
{
pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
if (!pHead ||
!AddResource (pWin->drawable.id, EventType, (pointer)pHead))
{
FreeResource (clientResource, RT_NONE);
return BadAlloc;
}
*pHead = 0;
}
pNewRREvent->next = *pHead;
*pHead = pNewRREvent;
/*
* Now see if the client needs an event
*/
if (pScrPriv)
{
pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
if (CompareTimeStamps (pTimes->setTime,
pScrPriv->lastSetTime) != 0 ||
CompareTimeStamps (pTimes->configTime,
pScrPriv->lastConfigTime) != 0)
{
TellChanged (pWin, (pointer) pScreen);
}
}
}
else if (stuff->enable == xFalse)
{
/* delete the interest */
if (pHead) {
pNewRREvent = 0;
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
if (pRREvent->client == client)
break;
pNewRREvent = pRREvent;
}
if (pRREvent) {
FreeResource (pRREvent->clientResource, ClientType);
if (pNewRREvent)
pNewRREvent->next = pRREvent->next;
else
*pHead = pRREvent->next;
xfree (pRREvent);
}
}
}
else
{
client->errorValue = stuff->enable;
return BadValue;
}
return Success;
}
static int
ProcRRDispatch (ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_RRQueryVersion:
return ProcRRQueryVersion(client);
case X_RRSetScreenConfig:
return ProcRRSetScreenConfig(client);
case X_RRSelectInput:
return ProcRRSelectInput(client);
case X_RRGetScreenInfo:
return ProcRRGetScreenInfo(client);
default:
return BadRequest;
}
}
static int
SProcRRQueryVersion (ClientPtr client)
{
register int n;
REQUEST(xRRQueryVersionReq);
swaps(&stuff->length, n);
swapl(&stuff->majorVersion, n);
swapl(&stuff->minorVersion, n);
return ProcRRQueryVersion(client);
}
static int
SProcRRGetScreenInfo (ClientPtr client)
{
register int n;
REQUEST(xRRGetScreenInfoReq);
swaps(&stuff->length, n);
swapl(&stuff->window, n);
return ProcRRGetScreenInfo(client);
}
static int
SProcRRSetScreenConfig (ClientPtr client)
{
register int n;
REQUEST(xRRSetScreenConfigReq);
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
swaps (&stuff->rate, n);
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
}
swaps(&stuff->length, n);
swapl(&stuff->drawable, n);
swapl(&stuff->timestamp, n);
swaps(&stuff->sizeID, n);
swaps(&stuff->rotation, n);
return ProcRRSetScreenConfig(client);
}
static int
SProcRRSelectInput (ClientPtr client)
{
register int n;
REQUEST(xRRSelectInputReq);
swaps(&stuff->length, n);
swapl(&stuff->window, n);
return ProcRRSelectInput(client);
}
static int
SProcRRDispatch (ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_RRQueryVersion:
return SProcRRQueryVersion(client);
case X_RRSetScreenConfig:
return SProcRRSetScreenConfig(client);
case X_RRSelectInput:
return SProcRRSelectInput(client);
case X_RRGetScreenInfo:
return SProcRRGetScreenInfo(client);
default:
return BadRequest;
}
}
static Bool
RRScreenSizeMatches (RRScreenSizePtr a,
RRScreenSizePtr b)
{
if (a->width != b->width)
return FALSE;
if (a->height != b->height)
return FALSE;
if (a->mmWidth != b->mmWidth)
return FALSE;
if (a->mmHeight != b->mmHeight)
return FALSE;
return TRUE;
}
RRScreenSizePtr
RRRegisterSize (ScreenPtr pScreen,
short width,
short height,
short mmWidth,
short mmHeight)
{
rrScrPriv (pScreen);
int i;
RRScreenSize tmp;
RRScreenSizePtr pNew;
if (!pScrPriv)
return 0;
tmp.width = width;
tmp.height= height;
tmp.mmWidth = mmWidth;
tmp.mmHeight = mmHeight;
tmp.pRates = 0;
tmp.nRates = 0;
tmp.nRatesInUse = 0;
tmp.referenced = TRUE;
tmp.oldReferenced = FALSE;
for (i = 0; i < pScrPriv->nSizes; i++)
if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
{
pScrPriv->pSizes[i].referenced = TRUE;
return &pScrPriv->pSizes[i];
}
pNew = xrealloc (pScrPriv->pSizes,
(pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
if (!pNew)
return 0;
pNew[pScrPriv->nSizes++] = tmp;
pScrPriv->pSizes = pNew;
return &pNew[pScrPriv->nSizes-1];
}
Bool RRRegisterRate (ScreenPtr pScreen,
RRScreenSizePtr pSize,
int rate)
{
rrScrPriv(pScreen);
int i;
RRScreenRatePtr pNew, pRate;
if (!pScrPriv)
return FALSE;
for (i = 0; i < pSize->nRates; i++)
{
pRate = &pSize->pRates[i];
if (pRate->rate == rate)
{
pRate->referenced = TRUE;
return TRUE;
}
}
pNew = xrealloc (pSize->pRates,
(pSize->nRates + 1) * sizeof (RRScreenRate));
if (!pNew)
return FALSE;
pRate = &pNew[pSize->nRates++];
pRate->rate = rate;
pRate->referenced = TRUE;
pRate->oldReferenced = FALSE;
pSize->pRates = pNew;
return TRUE;
}
void
RRSetCurrentConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize)
{
rrScrPriv (pScreen);
if (!pScrPriv)
return;
pScrPriv->rotation = rotation;
pScrPriv->size = pSize - pScrPriv->pSizes;
pScrPriv->rate = rate;
}
nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
View file @
e01b9177
...
@@ -598,7 +598,8 @@ Bool nxagentReconnectSession(void)
...
@@ -598,7 +598,8 @@ Bool nxagentReconnectSession(void)
if
(
nxagentResizeDesktopAtStartup
||
nxagentOption
(
Rootless
)
==
True
)
if
(
nxagentResizeDesktopAtStartup
||
nxagentOption
(
Rootless
)
==
True
)
{
{
nxagentRRSetScreenConfig
(
nxagentDefaultScreen
,
nxagentOption
(
RootWidth
),
nxagentOption
(
RootHeight
));
nxagentChangeScreenConfig
(
0
,
nxagentOption
(
RootWidth
),
nxagentOption
(
RootHeight
),
0
,
0
);
nxagentResizeDesktopAtStartup
=
False
;
nxagentResizeDesktopAtStartup
=
False
;
}
}
...
...
nx-X11/programs/Xserver/hw/nxagent/Screen.c
View file @
e01b9177
...
@@ -2121,7 +2121,7 @@ static void nxagentSetRootClip (ScreenPtr pScreen, Bool enable)
...
@@ -2121,7 +2121,7 @@ static void nxagentSetRootClip (ScreenPtr pScreen, Bool enable)
(
*
pScreen
->
ValidateTree
)(
pWin
,
NullWindow
,
VTOther
);
(
*
pScreen
->
ValidateTree
)(
pWin
,
NullWindow
,
VTOther
);
}
}
if
(
pWin
->
backStorage
&&
if
(
pWin
->
backStorage
&&
pOldClip
&&
((
pWin
->
backingStore
==
Always
)
||
WasViewable
))
((
pWin
->
backingStore
==
Always
)
||
WasViewable
))
{
{
if
(
!
WasViewable
)
if
(
!
WasViewable
)
...
@@ -2266,6 +2266,52 @@ FIXME: We should try to restore the previously
...
@@ -2266,6 +2266,52 @@ FIXME: We should try to restore the previously
nxagentChangeOption
(
ViewportYSpan
,
nxagentOption
(
Height
)
-
nxagentOption
(
RootHeight
));
nxagentChangeOption
(
ViewportYSpan
,
nxagentOption
(
Height
)
-
nxagentOption
(
RootHeight
));
/*
/*
* Change agent window size and size hints.
*/
if
((
nxagentOption
(
Fullscreen
)
==
0
&&
nxagentOption
(
AllScreens
)
==
0
))
{
sizeHints
.
flags
=
PPosition
|
PMinSize
|
PMaxSize
;
sizeHints
.
x
=
nxagentOption
(
X
);
sizeHints
.
y
=
nxagentOption
(
Y
);
sizeHints
.
min_width
=
MIN_NXAGENT_WIDTH
;
sizeHints
.
min_height
=
MIN_NXAGENT_HEIGHT
;
sizeHints
.
width
=
width
;
sizeHints
.
height
=
height
;
if
(
nxagentOption
(
DesktopResize
)
==
1
)
{
sizeHints
.
max_width
=
WidthOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
));
sizeHints
.
max_height
=
HeightOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
));
}
else
{
sizeHints
.
max_width
=
nxagentOption
(
RootWidth
);
sizeHints
.
max_height
=
nxagentOption
(
RootHeight
);
}
if
(
nxagentUserGeometry
.
flag
&
XValue
||
nxagentUserGeometry
.
flag
&
YValue
)
{
sizeHints
.
flags
|=
USPosition
;
}
if
(
nxagentUserGeometry
.
flag
&
WidthValue
||
nxagentUserGeometry
.
flag
&
HeightValue
)
{
sizeHints
.
flags
|=
USSize
;
}
XSetWMNormalHints
(
nxagentDisplay
,
nxagentDefaultWindows
[
pScreen
->
myNum
],
&
sizeHints
);
XResizeWindow
(
nxagentDisplay
,
nxagentDefaultWindows
[
pScreen
->
myNum
],
width
,
height
);
if
(
nxagentOption
(
Rootless
)
==
0
)
{
XResizeWindow
(
nxagentDisplay
,
nxagentInputWindows
[
pScreen
->
myNum
],
width
,
height
);
}
}
/*
* Set properties for the agent root window.
* Set properties for the agent root window.
*/
*/
...
@@ -2654,9 +2700,12 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
...
@@ -2654,9 +2700,12 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
nxagentShadowCreateMainWindow
(
pScreen
,
pWin
,
nxagentShadowWidth
,
nxagentShadowHeight
);
nxagentShadowCreateMainWindow
(
pScreen
,
pWin
,
nxagentShadowWidth
,
nxagentShadowHeight
);
if
(
nxagentRemoteMajor
<=
3
)
{
nxagentShadowSetWindowsSize
();
nxagentShadowSetWindowsSize
();
nxagentSetWMNormalHints
(
0
);
nxagentSetWMNormalHints
(
0
);
}
XMapWindow
(
nxagentDisplay
,
nxagentDefaultWindows
[
0
]);
XMapWindow
(
nxagentDisplay
,
nxagentDefaultWindows
[
0
]);
...
@@ -3453,118 +3502,123 @@ Bool nxagentReconnectScreen(void *p0)
...
@@ -3453,118 +3502,123 @@ Bool nxagentReconnectScreen(void *p0)
return
True
;
return
True
;
}
}
int
nxagentRRSetScreenConfig
(
ScreenPtr
pScreen
,
int
width
,
int
height
)
RRModePtr
nxagentRRCustomMode
=
NULL
;
int
nxagentChangeScreenConfig
(
int
screen
,
int
width
,
int
height
,
int
mmWidth
,
int
mmHeight
)
{
{
ScreenPtr
pScreen
;
rrScrPrivPtr
pScrPriv
;
rrScrPrivPtr
pScrPriv
;
RRScreenSizePtr
pSize
;
RROutputPtr
output
;
Rotation
rotation
;
RRCrtcPtr
crtc
;
int
rate
;
RRModePtr
mode
;
short
oldWidth
,
oldHeight
;
xRRModeInfo
modeInfo
;
int
mmWidth
,
mmHeight
;
char
name
[
100
];
int
oldSize
;
int
r
,
c
,
m
;
RRScreenSizePtr
oldSizes
;
int
refresh
=
60
;
int
doNotify
=
1
;
pScrPriv
=
rrGetScrPriv
(
pScreen
);
if
(
WindowTable
[
screen
]
==
NULL
)
oldWidth
=
pScreen
->
width
;
oldHeight
=
pScreen
->
height
;
if
(
!
pScrPriv
)
{
{
return
1
;
return
0
;
}
}
if
(
!
RRGetInfo
(
pScreen
))
UpdateCurrentTime
();
if
(
nxagentGrabServerInfo
.
grabstate
==
SERVER_GRABBED
)
{
{
return
1
;
/*
* If any client grabbed the server it won't expect that screen
* configuration changes until it releases the grab. That could
* get an X error because available modes are chanded meanwhile.
*/
#ifdef TEST
fprintf
(
stderr
,
"nxagentChangeScreenConfig: Cancel with grabbed server.
\n
"
);
#endif
return
0
;
}
}
rotation
=
RR_Rotate_0
;
pScreen
=
WindowTable
[
screen
]
->
drawable
.
pScreen
;
rate
=
0
;
#ifdef TEST
fprintf
(
stderr
,
"nxagentChangeScreenConfig: Changing config to %dx%d.
\n
"
,
width
,
height
);
#endif
mmWidth
=
(
width
*
254
+
monitorResolution
*
5
)
/
(
monitorResolution
*
10
);
r
=
nxagentResizeScreen
(
pScreen
,
width
,
height
,
mmWidth
,
mmHeight
);
if
(
mmWidth
<
1
)
if
(
r
!=
0
)
{
{
mmWidth
=
1
;
pScrPriv
=
rrGetScrPriv
(
pScreen
);
}
mmHeight
=
(
height
*
254
+
monitorResolution
*
5
)
/
(
monitorResolution
*
10
);
if
(
pScrPriv
)
{
output
=
RRFirstOutput
(
pScreen
);
if
(
mmHeight
<
1
)
if
(
output
&&
output
->
crtc
)
{
{
mmHeight
=
1
;
crtc
=
output
->
crtc
;
}
pSize
=
xalloc
(
sizeof
(
RRScreenSize
));
for
(
c
=
0
;
c
<
pScrPriv
->
numCrtcs
;
c
++
)
{
RRCrtcSet
(
pScrPriv
->
crtcs
[
c
],
NULL
,
0
,
0
,
RR_Rotate_0
,
0
,
NULL
);
}
pSize
->
width
=
width
;
memset
(
&
modeInfo
,
'\0'
,
sizeof
(
modeInfo
));
pSize
->
height
=
height
;
sprintf
(
name
,
"%dx%d"
,
width
,
height
);
pSize
->
mmWidth
=
mmWidth
;
pSize
->
mmHeight
=
mmHeight
;
/*
modeInfo
.
width
=
width
;
* call out to ddx routine to effect the change
modeInfo
.
height
=
height
;
*/
modeInfo
.
hTotal
=
width
;
modeInfo
.
vTotal
=
height
;
modeInfo
.
dotClock
=
((
CARD32
)
width
*
(
CARD32
)
height
*
(
CARD32
)
refresh
);
modeInfo
.
nameLength
=
strlen
(
name
);
if
(
!
(
*
pScrPriv
->
rrSetConfig
)
(
pScreen
,
rotation
,
rate
,
if
(
nxagentRRCustomMode
!=
NULL
)
pSize
))
{
{
/*
RROutputDeleteUserMode
(
output
,
nxagentRRCustomMode
);
* unknown DDX failure.
FreeResource
(
nxagentRRCustomMode
->
mode
.
id
,
0
);
*/
xfree
(
pSize
);
if
(
crtc
!=
NULL
&&
crtc
->
mode
==
nxagentRRCustomMode
)
{
return
1
;
RRCrtcSet
(
crtc
,
NULL
,
0
,
0
,
RR_Rotate_0
,
0
,
NULL
)
;
}
}
/*
#ifdef TEST
* TellChanged uses this privates.
fprintf
(
stderr
,
"nxagentChangeScreenConfig: "
*/
"Going to destroy mode %p with refcnt %d.
\n
"
,
nxagentRRCustomMode
,
nxagentRRCustomMode
->
refcnt
);
#endif
oldSize
=
pScrPriv
->
size
;
RRModeDestroy
(
nxagentRRCustomMode
)
;
oldSizes
=
pScrPriv
->
pSizes
;
}
pScrPriv
->
size
=
0
;
nxagentRRCustomMode
=
RRModeGet
(
&
modeInfo
,
name
);
pScrPriv
->
pSizes
=
pSize
;
/*
RROutputAddUserMode
(
output
,
nxagentRRCustomMode
);
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree
(
pScreen
,
TellChanged
,
(
pointer
)
pScreen
);
RRCrtcSet
(
crtc
,
nxagentRRCustomMode
,
0
,
0
,
RR_Rotate_0
,
1
,
&
output
);
/*
RROutputChanged
(
output
,
1
);
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if
(
oldWidth
!=
pScreen
->
width
||
oldHeight
!=
pScreen
->
height
)
doNotify
=
0
;
{
RRSendConfigNotify
(
pScreen
);
}
}
RREditConnectionInfo
(
pScreen
)
;
pScrPriv
->
lastSetTime
=
currentTime
;
/*
pScrPriv
->
changed
=
1
;
* Fix pointer bounds and location
pScrPriv
->
configChanged
=
1
;
*/
}
ScreenRestructured
(
pScreen
);
/*
* Restore old privates.
*/
pScrPriv
->
pSizes
=
oldSizes
;
pScrPriv
->
size
=
oldSize
;
xfree
(
pSize
);
if
(
doNotify
)
{
RRScreenSizeNotify
(
pScreen
);
}
}
return
0
;
return
r
;
}
}
void
nxagentSaveAreas
(
PixmapPtr
pPixmap
,
RegionPtr
prgnSave
,
int
xorg
,
int
yorg
,
WindowPtr
pWin
)
void
nxagentSaveAreas
(
PixmapPtr
pPixmap
,
RegionPtr
prgnSave
,
int
xorg
,
int
yorg
,
WindowPtr
pWin
)
...
...
nx-X11/programs/Xserver/hw/nxagent/Screen.h
View file @
e01b9177
...
@@ -100,7 +100,7 @@ Bool nxagentMagicPixelZone(int x, int y);
...
@@ -100,7 +100,7 @@ Bool nxagentMagicPixelZone(int x, int y);
Bool
nxagentResizeScreen
(
ScreenPtr
pScreen
,
int
width
,
int
height
,
Bool
nxagentResizeScreen
(
ScreenPtr
pScreen
,
int
width
,
int
height
,
int
mmWidth
,
int
mmHeight
);
int
mmWidth
,
int
mmHeight
);
int
nxagent
RRSetScreenConfig
(
ScreenPtr
pScreen
,
int
width
,
int
h
eight
);
int
nxagent
ChangeScreenConfig
(
int
screen
,
int
width
,
int
height
,
int
mmWidth
,
int
mmH
eight
);
extern
Bool
nxagentReconnectScreen
(
void
*
p0
);
extern
Bool
nxagentReconnectScreen
(
void
*
p0
);
...
...
nx-X11/programs/Xserver/hw/nxagent/Window.c
View file @
e01b9177
...
@@ -899,8 +899,8 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
...
@@ -899,8 +899,8 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
{
{
if
(
nxagentOption
(
Shadow
)
==
0
)
if
(
nxagentOption
(
Shadow
)
==
0
)
{
{
nxagent
RRSetScreenConfig
(
pScreen
,
WidthOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
)),
nxagent
ChangeScreenConfig
(
0
,
WidthOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
)),
HeightOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
))
);
HeightOfScreen
(
DefaultScreenOfDisplay
(
nxagentDisplay
)),
0
,
0
);
}
}
else
else
{
{
...
@@ -953,7 +953,8 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
...
@@ -953,7 +953,8 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
if
(
nxagentOption
(
Shadow
)
==
0
)
if
(
nxagentOption
(
Shadow
)
==
0
)
{
{
nxagentRRSetScreenConfig
(
pScreen
,
nxagentOption
(
RootWidth
),
nxagentOption
(
RootHeight
));
nxagentChangeScreenConfig
(
0
,
nxagentOption
(
RootWidth
),
nxagentOption
(
RootHeight
),
0
,
0
);
}
}
}
}
...
...
nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
View file @
e01b9177
...
@@ -148,7 +148,8 @@ static const char *_NXGetFontPath(const char *path)
...
@@ -148,7 +148,8 @@ static const char *_NXGetFontPath(const char *path)
_NXGetFontPathError:
_NXGetFontPathError:
strcpy
(
_NXFontPath
,
path
);
strncpy
(
_NXFontPath
,
path
,
1023
);
_NXFontPath
[
1023
]
=
'\0'
;
#ifdef NX_TRANS_TEST
#ifdef NX_TRANS_TEST
fprintf
(
stderr
,
"_NXGetFontPath: Using default font path [%s].
\n
"
,
_NXFontPath
);
fprintf
(
stderr
,
"_NXGetFontPath: Using default font path [%s].
\n
"
,
_NXFontPath
);
...
...
nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
deleted
100644 → 0
View file @
39b738a6
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */
/* */
/* NXAGENT, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of Medialogic S.p.A. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
/*
* $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $
*
* Copyright © 2000, Compaq Computer Corporation,
* Copyright © 2002, Hewlett Packard, Inc.
*
* 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, and that the name of Compaq or HP not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission. HP makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
*/
#define NEED_REPLIES
#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "misc.h"
#include "os.h"
#include "dixstruct.h"
#include "resource.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "servermd.h"
#include <X11/extensions/randr.h>
#include <X11/extensions/randrproto.h>
#include "../../randr/randrstr.h"
#ifdef RENDER
#include <X11/extensions/render.h>
/* we share subpixel order information */
#include "picturestr.h"
#endif
#include <X11/Xfuncproto.h>
#ifdef EXTMODULE
#include "xf86_ansic.h"
#endif
/* From render.h */
#ifndef SubPixelUnknown
#define SubPixelUnknown 0
#endif
#define RR_VALIDATE
int
RRGeneration
;
int
RRNScreens
;
static
int
ProcRRQueryVersion
(
ClientPtr
pClient
);
static
int
ProcRRDispatch
(
ClientPtr
pClient
);
static
int
SProcRRDispatch
(
ClientPtr
pClient
);
static
int
SProcRRQueryVersion
(
ClientPtr
pClient
);
#define wrap(priv,real,mem,func) {\
priv->mem = real->mem; \
real->mem = func; \
}
#define unwrap(priv,real,mem) {\
real->mem = priv->mem; \
}
#if 0
static CARD8 RRReqCode;
static int RRErrBase;
#endif
static
int
RREventBase
;
static
RESTYPE
ClientType
,
EventType
;
/* resource types for event masks */
static
int
RRClientPrivateIndex
;
typedef
struct
_RRTimes
{
TimeStamp
setTime
;
TimeStamp
configTime
;
}
RRTimesRec
,
*
RRTimesPtr
;
typedef
struct
_RRClient
{
int
major_version
;
int
minor_version
;
/* RRTimesRec times[0]; */
}
RRClientRec
,
*
RRClientPtr
;
/*
* each window has a list of clients requesting
* RRNotify events. Each client has a resource
* for each window it selects RRNotify input for,
* this resource is used to delete the RRNotifyRec
* entry from the per-window queue.
*/
typedef
struct
_RREvent
*
RREventPtr
;
typedef
struct
_RREvent
{
RREventPtr
next
;
ClientPtr
client
;
WindowPtr
window
;
XID
clientResource
;
int
mask
;
}
RREventRec
;
int
rrPrivIndex
=
-
1
;
#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
static
Bool
RRClientKnowsRates
(
ClientPtr
pClient
)
{
rrClientPriv
(
pClient
);
return
(
pRRClient
->
major_version
>
1
||
(
pRRClient
->
major_version
==
1
&&
pRRClient
->
minor_version
>=
1
));
}
static
void
RRClientCallback
(
CallbackListPtr
*
list
,
pointer
closure
,
pointer
data
)
{
NewClientInfoRec
*
clientinfo
=
(
NewClientInfoRec
*
)
data
;
ClientPtr
pClient
=
clientinfo
->
client
;
rrClientPriv
(
pClient
);
RRTimesPtr
pTimes
=
(
RRTimesPtr
)
(
pRRClient
+
1
);
int
i
;
pRRClient
->
major_version
=
0
;
pRRClient
->
minor_version
=
0
;
for
(
i
=
0
;
i
<
screenInfo
.
numScreens
;
i
++
)
{
ScreenPtr
pScreen
=
screenInfo
.
screens
[
i
];
rrScrPriv
(
pScreen
);
if
(
pScrPriv
)
{
pTimes
[
i
].
setTime
=
pScrPriv
->
lastSetTime
;
pTimes
[
i
].
configTime
=
pScrPriv
->
lastConfigTime
;
}
}
}
static
void
RRResetProc
(
ExtensionEntry
*
extEntry
)
{
}
static
Bool
RRCloseScreen
(
int
i
,
ScreenPtr
pScreen
)
{
rrScrPriv
(
pScreen
);
unwrap
(
pScrPriv
,
pScreen
,
CloseScreen
);
if
(
pScrPriv
->
pSizes
)
xfree
(
pScrPriv
->
pSizes
);
xfree
(
pScrPriv
);
RRNScreens
-=
1
;
/* ok, one fewer screen with RandR running */
return
(
*
pScreen
->
CloseScreen
)
(
i
,
pScreen
);
}
static
void
SRRScreenChangeNotifyEvent
(
xRRScreenChangeNotifyEvent
*
from
,
xRRScreenChangeNotifyEvent
*
to
)
{
to
->
type
=
from
->
type
;
to
->
rotation
=
from
->
rotation
;
cpswaps
(
from
->
sequenceNumber
,
to
->
sequenceNumber
);
cpswapl
(
from
->
timestamp
,
to
->
timestamp
);
cpswapl
(
from
->
configTimestamp
,
to
->
configTimestamp
);
cpswapl
(
from
->
root
,
to
->
root
);
cpswapl
(
from
->
window
,
to
->
window
);
cpswaps
(
from
->
sizeID
,
to
->
sizeID
);
cpswaps
(
from
->
widthInPixels
,
to
->
widthInPixels
);
cpswaps
(
from
->
heightInPixels
,
to
->
heightInPixels
);
cpswaps
(
from
->
widthInMillimeters
,
to
->
widthInMillimeters
);
cpswaps
(
from
->
heightInMillimeters
,
to
->
heightInMillimeters
);
cpswaps
(
from
->
subpixelOrder
,
to
->
subpixelOrder
);
}
Bool
RRScreenInit
(
ScreenPtr
pScreen
)
{
rrScrPrivPtr
pScrPriv
;
if
(
RRGeneration
!=
serverGeneration
)
{
if
((
rrPrivIndex
=
AllocateScreenPrivateIndex
())
<
0
)
return
FALSE
;
RRGeneration
=
serverGeneration
;
}
pScrPriv
=
(
rrScrPrivPtr
)
xalloc
(
sizeof
(
rrScrPrivRec
));
if
(
!
pScrPriv
)
return
FALSE
;
SetRRScreen
(
pScreen
,
pScrPriv
);
/*
* Calling function best set these function vectors
*/
pScrPriv
->
rrSetConfig
=
0
;
pScrPriv
->
rrGetInfo
=
0
;
/*
* This value doesn't really matter -- any client must call
* GetScreenInfo before reading it which will automatically update
* the time
*/
pScrPriv
->
lastSetTime
=
currentTime
;
pScrPriv
->
lastConfigTime
=
currentTime
;
wrap
(
pScrPriv
,
pScreen
,
CloseScreen
,
RRCloseScreen
);
pScrPriv
->
rotations
=
RR_Rotate_0
;
pScrPriv
->
nSizes
=
0
;
pScrPriv
->
nSizesInUse
=
0
;
pScrPriv
->
pSizes
=
0
;
pScrPriv
->
rotation
=
RR_Rotate_0
;
pScrPriv
->
size
=
-
1
;
RRNScreens
+=
1
;
/* keep count of screens that implement randr */
return
TRUE
;
}
/*ARGSUSED*/
static
int
RRFreeClient
(
pointer
data
,
XID
id
)
{
RREventPtr
pRREvent
;
WindowPtr
pWin
;
RREventPtr
*
pHead
,
pCur
,
pPrev
;
pRREvent
=
(
RREventPtr
)
data
;
pWin
=
pRREvent
->
window
;
pHead
=
(
RREventPtr
*
)
LookupIDByType
(
pWin
->
drawable
.
id
,
EventType
);
if
(
pHead
)
{
pPrev
=
0
;
for
(
pCur
=
*
pHead
;
pCur
&&
pCur
!=
pRREvent
;
pCur
=
pCur
->
next
)
pPrev
=
pCur
;
if
(
pCur
)
{
if
(
pPrev
)
pPrev
->
next
=
pRREvent
->
next
;
else
*
pHead
=
pRREvent
->
next
;
}
}
xfree
((
pointer
)
pRREvent
);
return
1
;
}
/*ARGSUSED*/
static
int
RRFreeEvents
(
pointer
data
,
XID
id
)
{
RREventPtr
*
pHead
,
pCur
,
pNext
;
pHead
=
(
RREventPtr
*
)
data
;
for
(
pCur
=
*
pHead
;
pCur
;
pCur
=
pNext
)
{
pNext
=
pCur
->
next
;
FreeResource
(
pCur
->
clientResource
,
ClientType
);
xfree
((
pointer
)
pCur
);
}
xfree
((
pointer
)
pHead
);
return
1
;
}
void
RRExtensionInit
(
void
)
{
ExtensionEntry
*
extEntry
;
if
(
RRNScreens
==
0
)
return
;
RRClientPrivateIndex
=
AllocateClientPrivateIndex
();
if
(
!
AllocateClientPrivate
(
RRClientPrivateIndex
,
sizeof
(
RRClientRec
)
+
screenInfo
.
numScreens
*
sizeof
(
RRTimesRec
)))
return
;
if
(
!
AddCallback
(
&
ClientStateCallback
,
RRClientCallback
,
0
))
return
;
ClientType
=
CreateNewResourceType
(
RRFreeClient
);
if
(
!
ClientType
)
return
;
EventType
=
CreateNewResourceType
(
RRFreeEvents
);
if
(
!
EventType
)
return
;
extEntry
=
AddExtension
(
RANDR_NAME
,
RRNumberEvents
,
RRNumberErrors
,
ProcRRDispatch
,
SProcRRDispatch
,
RRResetProc
,
StandardMinorOpcode
);
if
(
!
extEntry
)
return
;
#if 0
RRReqCode = (CARD8) extEntry->base;
RRErrBase = extEntry->errorBase;
#endif
RREventBase
=
extEntry
->
eventBase
;
EventSwapVector
[
RREventBase
+
RRScreenChangeNotify
]
=
(
EventSwapPtr
)
SRRScreenChangeNotifyEvent
;
return
;
}
int
TellChanged
(
WindowPtr
pWin
,
pointer
value
)
{
RREventPtr
*
pHead
,
pRREvent
;
ClientPtr
client
;
xRRScreenChangeNotifyEvent
se
;
ScreenPtr
pScreen
=
pWin
->
drawable
.
pScreen
;
rrScrPriv
(
pScreen
);
RRScreenSizePtr
pSize
;
WindowPtr
pRoot
=
WindowTable
[
pScreen
->
myNum
];
pHead
=
(
RREventPtr
*
)
LookupIDByType
(
pWin
->
drawable
.
id
,
EventType
);
if
(
!
pHead
)
return
WT_WALKCHILDREN
;
se
.
type
=
RRScreenChangeNotify
+
RREventBase
;
se
.
rotation
=
(
CARD8
)
pScrPriv
->
rotation
;
se
.
timestamp
=
pScrPriv
->
lastSetTime
.
milliseconds
;
se
.
configTimestamp
=
pScrPriv
->
lastConfigTime
.
milliseconds
;
se
.
root
=
pRoot
->
drawable
.
id
;
se
.
window
=
pWin
->
drawable
.
id
;
#ifdef RENDER
se
.
subpixelOrder
=
PictureGetSubpixelOrder
(
pScreen
);
#else
se
.
subpixelOrder
=
SubPixelUnknown
;
#endif
if
(
pScrPriv
->
size
>=
0
)
{
pSize
=
&
pScrPriv
->
pSizes
[
pScrPriv
->
size
];
se
.
sizeID
=
pSize
->
id
;
se
.
widthInPixels
=
pSize
->
width
;
se
.
heightInPixels
=
pSize
->
height
;
se
.
widthInMillimeters
=
pSize
->
mmWidth
;
se
.
heightInMillimeters
=
pSize
->
mmHeight
;
}
else
{
/*
* This "shouldn't happen", but a broken DDX can
* forget to set the current configuration on GetInfo
*/
se
.
sizeID
=
0xffff
;
se
.
widthInPixels
=
0
;
se
.
heightInPixels
=
0
;
se
.
widthInMillimeters
=
0
;
se
.
heightInMillimeters
=
0
;
}
for
(
pRREvent
=
*
pHead
;
pRREvent
;
pRREvent
=
pRREvent
->
next
)
{
client
=
pRREvent
->
client
;
if
(
client
==
serverClient
||
client
->
clientGone
)
continue
;
se
.
sequenceNumber
=
client
->
sequence
;
if
(
pRREvent
->
mask
&
RRScreenChangeNotifyMask
)
WriteEventsToClient
(
client
,
1
,
(
xEvent
*
)
&
se
);
}
return
WT_WALKCHILDREN
;
}
Bool
RRGetInfo
(
ScreenPtr
pScreen
)
{
rrScrPriv
(
pScreen
);
int
i
,
j
,
k
,
l
;
Bool
changed
;
Rotation
rotations
;
RRScreenSizePtr
pSize
;
RRScreenRatePtr
pRate
;
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
pSize
=
&
pScrPriv
->
pSizes
[
i
];
pSize
->
oldReferenced
=
pSize
->
referenced
;
pSize
->
referenced
=
FALSE
;
for
(
k
=
0
;
k
<
pSize
->
nRates
;
k
++
)
{
pRate
=
&
pSize
->
pRates
[
k
];
pRate
->
oldReferenced
=
pRate
->
referenced
;
pRate
->
referenced
=
FALSE
;
}
}
if
(
!
(
*
pScrPriv
->
rrGetInfo
)
(
pScreen
,
&
rotations
))
return
FALSE
;
changed
=
FALSE
;
/*
* Check whether anything changed and simultaneously generate
* the protocol id values for the objects
*/
if
(
rotations
!=
pScrPriv
->
rotations
)
{
pScrPriv
->
rotations
=
rotations
;
changed
=
TRUE
;
}
j
=
0
;
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
pSize
=
&
pScrPriv
->
pSizes
[
i
];
if
(
pSize
->
oldReferenced
!=
pSize
->
referenced
)
changed
=
TRUE
;
if
(
pSize
->
referenced
)
pSize
->
id
=
j
++
;
l
=
0
;
for
(
k
=
0
;
k
<
pSize
->
nRates
;
k
++
)
{
pRate
=
&
pSize
->
pRates
[
k
];
if
(
pRate
->
oldReferenced
!=
pRate
->
referenced
)
changed
=
TRUE
;
if
(
pRate
->
referenced
)
l
++
;
}
pSize
->
nRatesInUse
=
l
;
}
pScrPriv
->
nSizesInUse
=
j
;
if
(
changed
)
{
UpdateCurrentTime
();
pScrPriv
->
lastConfigTime
=
currentTime
;
WalkTree
(
pScreen
,
TellChanged
,
(
pointer
)
pScreen
);
}
return
TRUE
;
}
void
RRSendConfigNotify
(
ScreenPtr
pScreen
)
{
WindowPtr
pWin
=
WindowTable
[
pScreen
->
myNum
];
xEvent
event
;
event
.
u
.
u
.
type
=
ConfigureNotify
;
event
.
u
.
configureNotify
.
window
=
pWin
->
drawable
.
id
;
event
.
u
.
configureNotify
.
aboveSibling
=
None
;
event
.
u
.
configureNotify
.
x
=
0
;
event
.
u
.
configureNotify
.
y
=
0
;
/* XXX xinerama stuff ? */
event
.
u
.
configureNotify
.
width
=
pWin
->
drawable
.
width
;
event
.
u
.
configureNotify
.
height
=
pWin
->
drawable
.
height
;
event
.
u
.
configureNotify
.
borderWidth
=
wBorderWidth
(
pWin
);
event
.
u
.
configureNotify
.
override
=
pWin
->
overrideRedirect
;
DeliverEvents
(
pWin
,
&
event
,
1
,
NullWindow
);
}
static
int
ProcRRQueryVersion
(
ClientPtr
client
)
{
xRRQueryVersionReply
rep
;
register
int
n
;
REQUEST
(
xRRQueryVersionReq
);
rrClientPriv
(
client
);
REQUEST_SIZE_MATCH
(
xRRQueryVersionReq
);
pRRClient
->
major_version
=
stuff
->
majorVersion
;
pRRClient
->
minor_version
=
stuff
->
minorVersion
;
rep
.
type
=
X_Reply
;
rep
.
length
=
0
;
rep
.
sequenceNumber
=
client
->
sequence
;
rep
.
majorVersion
=
RANDR_MAJOR
;
rep
.
minorVersion
=
RANDR_MINOR
;
if
(
client
->
swapped
)
{
swaps
(
&
rep
.
sequenceNumber
,
n
);
swapl
(
&
rep
.
length
,
n
);
swapl
(
&
rep
.
majorVersion
,
n
);
swapl
(
&
rep
.
minorVersion
,
n
);
}
WriteToClient
(
client
,
sizeof
(
xRRQueryVersionReply
),
(
char
*
)
&
rep
);
return
(
client
->
noClientException
);
}
extern
char
*
ConnectionInfo
;
static
int
padlength
[
4
]
=
{
0
,
3
,
2
,
1
};
void
RREditConnectionInfo
(
ScreenPtr
pScreen
)
{
xConnSetup
*
connSetup
;
char
*
vendor
;
xPixmapFormat
*
formats
;
xWindowRoot
*
root
;
xDepth
*
depth
;
xVisualType
*
visual
;
int
screen
=
0
;
int
d
;
connSetup
=
(
xConnSetup
*
)
ConnectionInfo
;
vendor
=
(
char
*
)
connSetup
+
sizeof
(
xConnSetup
);
formats
=
(
xPixmapFormat
*
)
((
char
*
)
vendor
+
connSetup
->
nbytesVendor
+
padlength
[
connSetup
->
nbytesVendor
&
3
]);
root
=
(
xWindowRoot
*
)
((
char
*
)
formats
+
sizeof
(
xPixmapFormat
)
*
screenInfo
.
numPixmapFormats
);
while
(
screen
!=
pScreen
->
myNum
)
{
depth
=
(
xDepth
*
)
((
char
*
)
root
+
sizeof
(
xWindowRoot
));
for
(
d
=
0
;
d
<
root
->
nDepths
;
d
++
)
{
visual
=
(
xVisualType
*
)
((
char
*
)
depth
+
sizeof
(
xDepth
));
depth
=
(
xDepth
*
)
((
char
*
)
visual
+
depth
->
nVisuals
*
sizeof
(
xVisualType
));
}
root
=
(
xWindowRoot
*
)
((
char
*
)
depth
);
screen
++
;
}
root
->
pixWidth
=
pScreen
->
width
;
root
->
pixHeight
=
pScreen
->
height
;
root
->
mmWidth
=
pScreen
->
mmWidth
;
root
->
mmHeight
=
pScreen
->
mmHeight
;
}
static
int
ProcRRGetScreenInfo
(
ClientPtr
client
)
{
REQUEST
(
xRRGetScreenInfoReq
);
xRRGetScreenInfoReply
rep
;
WindowPtr
pWin
;
int
n
;
ScreenPtr
pScreen
;
rrScrPrivPtr
pScrPriv
;
CARD8
*
extra
;
unsigned
long
extraLen
;
REQUEST_SIZE_MATCH
(
xRRGetScreenInfoReq
);
pWin
=
(
WindowPtr
)
SecurityLookupWindow
(
stuff
->
window
,
client
,
SecurityReadAccess
);
if
(
!
pWin
)
return
BadWindow
;
pScreen
=
pWin
->
drawable
.
pScreen
;
pScrPriv
=
rrGetScrPriv
(
pScreen
);
rep
.
pad
=
0
;
if
(
!
pScrPriv
)
{
rep
.
type
=
X_Reply
;
rep
.
setOfRotations
=
RR_Rotate_0
;;
rep
.
sequenceNumber
=
client
->
sequence
;
rep
.
length
=
0
;
rep
.
root
=
WindowTable
[
pWin
->
drawable
.
pScreen
->
myNum
]
->
drawable
.
id
;
rep
.
timestamp
=
currentTime
.
milliseconds
;
rep
.
configTimestamp
=
currentTime
.
milliseconds
;
rep
.
nSizes
=
0
;
rep
.
sizeID
=
0
;
rep
.
rotation
=
RR_Rotate_0
;
rep
.
rate
=
0
;
rep
.
nrateEnts
=
0
;
extra
=
0
;
extraLen
=
0
;
}
else
{
int
i
,
j
;
xScreenSizes
*
size
;
CARD16
*
rates
;
CARD8
*
data8
;
Bool
has_rate
=
RRClientKnowsRates
(
client
);
RRGetInfo
(
pScreen
);
rep
.
type
=
X_Reply
;
rep
.
setOfRotations
=
pScrPriv
->
rotations
;
rep
.
sequenceNumber
=
client
->
sequence
;
rep
.
length
=
0
;
rep
.
root
=
WindowTable
[
pWin
->
drawable
.
pScreen
->
myNum
]
->
drawable
.
id
;
rep
.
timestamp
=
pScrPriv
->
lastSetTime
.
milliseconds
;
rep
.
configTimestamp
=
pScrPriv
->
lastConfigTime
.
milliseconds
;
rep
.
rotation
=
pScrPriv
->
rotation
;
rep
.
nSizes
=
pScrPriv
->
nSizesInUse
;
rep
.
rate
=
pScrPriv
->
rate
;
rep
.
nrateEnts
=
0
;
if
(
has_rate
)
{
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
RRScreenSizePtr
pSize
=
&
pScrPriv
->
pSizes
[
i
];
if
(
pSize
->
referenced
)
{
rep
.
nrateEnts
+=
(
1
+
pSize
->
nRatesInUse
);
}
}
}
if
(
pScrPriv
->
size
>=
0
)
rep
.
sizeID
=
pScrPriv
->
pSizes
[
pScrPriv
->
size
].
id
;
else
return
BadImplementation
;
extraLen
=
(
rep
.
nSizes
*
sizeof
(
xScreenSizes
)
+
rep
.
nrateEnts
*
sizeof
(
CARD16
));
extra
=
(
CARD8
*
)
xalloc
(
extraLen
);
if
(
!
extra
)
return
BadAlloc
;
/*
* First comes the size information
*/
size
=
(
xScreenSizes
*
)
extra
;
rates
=
(
CARD16
*
)
(
size
+
rep
.
nSizes
);
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
RRScreenSizePtr
pSize
=
&
pScrPriv
->
pSizes
[
i
];
if
(
pSize
->
referenced
)
{
size
->
widthInPixels
=
pSize
->
width
;
size
->
heightInPixels
=
pSize
->
height
;
size
->
widthInMillimeters
=
pSize
->
mmWidth
;
size
->
heightInMillimeters
=
pSize
->
mmHeight
;
if
(
client
->
swapped
)
{
swaps
(
&
size
->
widthInPixels
,
n
);
swaps
(
&
size
->
heightInPixels
,
n
);
swaps
(
&
size
->
widthInMillimeters
,
n
);
swaps
(
&
size
->
heightInMillimeters
,
n
);
}
size
++
;
if
(
has_rate
)
{
*
rates
=
pSize
->
nRatesInUse
;
if
(
client
->
swapped
)
{
swaps
(
rates
,
n
);
}
rates
++
;
for
(
j
=
0
;
j
<
pSize
->
nRates
;
j
++
)
{
RRScreenRatePtr
pRate
=
&
pSize
->
pRates
[
j
];
if
(
pRate
->
referenced
)
{
*
rates
=
pRate
->
rate
;
if
(
client
->
swapped
)
{
swaps
(
rates
,
n
);
}
rates
++
;
}
}
}
}
}
data8
=
(
CARD8
*
)
rates
;
if
(
data8
-
(
CARD8
*
)
extra
!=
extraLen
)
FatalError
(
"RRGetScreenInfo bad extra len %ld != %ld
\n
"
,
(
unsigned
long
)(
data8
-
(
CARD8
*
)
extra
),
extraLen
);
rep
.
length
=
(
extraLen
+
3
)
>>
2
;
}
if
(
client
->
swapped
)
{
swaps
(
&
rep
.
sequenceNumber
,
n
);
swapl
(
&
rep
.
length
,
n
);
swapl
(
&
rep
.
timestamp
,
n
);
swaps
(
&
rep
.
rotation
,
n
);
swaps
(
&
rep
.
nSizes
,
n
);
swaps
(
&
rep
.
sizeID
,
n
);
swaps
(
&
rep
.
rate
,
n
);
swaps
(
&
rep
.
nrateEnts
,
n
);
}
WriteToClient
(
client
,
sizeof
(
xRRGetScreenInfoReply
),
(
char
*
)
&
rep
);
if
(
extraLen
)
{
WriteToClient
(
client
,
extraLen
,
(
char
*
)
extra
);
xfree
(
extra
);
}
return
(
client
->
noClientException
);
}
static
int
ProcRRSetScreenConfig
(
ClientPtr
client
)
{
REQUEST
(
xRRSetScreenConfigReq
);
xRRSetScreenConfigReply
rep
;
DrawablePtr
pDraw
;
int
n
;
ScreenPtr
pScreen
;
rrScrPrivPtr
pScrPriv
;
TimeStamp
configTime
;
TimeStamp
time
;
RRScreenSizePtr
pSize
;
int
i
;
Rotation
rotation
;
int
rate
;
short
oldWidth
,
oldHeight
;
Bool
has_rate
;
UpdateCurrentTime
();
if
(
RRClientKnowsRates
(
client
))
{
REQUEST_SIZE_MATCH
(
xRRSetScreenConfigReq
);
has_rate
=
TRUE
;
}
else
{
REQUEST_SIZE_MATCH
(
xRR1_0SetScreenConfigReq
);
has_rate
=
FALSE
;
}
SECURITY_VERIFY_DRAWABLE
(
pDraw
,
stuff
->
drawable
,
client
,
SecurityWriteAccess
);
pScreen
=
pDraw
->
pScreen
;
pScrPriv
=
rrGetScrPriv
(
pScreen
);
time
=
ClientTimeToServerTime
(
stuff
->
timestamp
);
configTime
=
ClientTimeToServerTime
(
stuff
->
configTimestamp
);
oldWidth
=
pScreen
->
width
;
oldHeight
=
pScreen
->
height
;
if
(
!
pScrPriv
)
{
time
=
currentTime
;
rep
.
status
=
RRSetConfigFailed
;
goto
sendReply
;
}
if
(
!
RRGetInfo
(
pScreen
))
return
BadAlloc
;
/*
* if the client's config timestamp is not the same as the last config
* timestamp, then the config information isn't up-to-date and
* can't even be validated
*/
if
(
CompareTimeStamps
(
configTime
,
pScrPriv
->
lastConfigTime
)
!=
0
)
{
rep
.
status
=
RRSetConfigInvalidConfigTime
;
goto
sendReply
;
}
/*
* Search for the requested size
*/
pSize
=
0
;
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
{
pSize
=
&
pScrPriv
->
pSizes
[
i
];
if
(
pSize
->
referenced
&&
pSize
->
id
==
stuff
->
sizeID
)
{
break
;
}
}
if
(
i
==
pScrPriv
->
nSizes
)
{
/*
* Invalid size ID
*/
client
->
errorValue
=
stuff
->
sizeID
;
return
BadValue
;
}
/*
* Validate requested rotation
*/
rotation
=
(
Rotation
)
stuff
->
rotation
;
/* test the rotation bits only! */
switch
(
rotation
&
0xf
)
{
case
RR_Rotate_0
:
case
RR_Rotate_90
:
case
RR_Rotate_180
:
case
RR_Rotate_270
:
break
;
default:
/*
* Invalid rotation
*/
client
->
errorValue
=
stuff
->
rotation
;
return
BadValue
;
}
if
((
~
pScrPriv
->
rotations
)
&
rotation
)
{
/*
* requested rotation or reflection not supported by screen
*/
client
->
errorValue
=
stuff
->
rotation
;
return
BadMatch
;
}
/*
* Validate requested refresh
*/
if
(
has_rate
)
rate
=
(
int
)
stuff
->
rate
;
else
rate
=
0
;
if
(
rate
)
{
for
(
i
=
0
;
i
<
pSize
->
nRates
;
i
++
)
{
RRScreenRatePtr
pRate
=
&
pSize
->
pRates
[
i
];
if
(
pRate
->
referenced
&&
pRate
->
rate
==
rate
)
break
;
}
if
(
i
==
pSize
->
nRates
)
{
/*
* Invalid rate
*/
client
->
errorValue
=
rate
;
return
BadValue
;
}
}
/*
* Make sure the requested set-time is not older than
* the last set-time
*/
if
(
CompareTimeStamps
(
time
,
pScrPriv
->
lastSetTime
)
<
0
)
{
rep
.
status
=
RRSetConfigInvalidTime
;
goto
sendReply
;
}
/*
* call out to ddx routine to effect the change
*/
if
(
!
(
*
pScrPriv
->
rrSetConfig
)
(
pScreen
,
rotation
,
rate
,
pSize
))
{
/*
* unknown DDX failure, report to client
*/
rep
.
status
=
RRSetConfigFailed
;
goto
sendReply
;
}
/*
* set current extension configuration pointers
*/
RRSetCurrentConfig
(
pScreen
,
rotation
,
rate
,
pSize
);
/*
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree
(
pScreen
,
TellChanged
,
(
pointer
)
pScreen
);
/*
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if
(
oldWidth
!=
pScreen
->
width
||
oldHeight
!=
pScreen
->
height
)
RRSendConfigNotify
(
pScreen
);
RREditConnectionInfo
(
pScreen
);
/*
* Fix pointer bounds and location
*/
ScreenRestructured
(
pScreen
);
pScrPriv
->
lastSetTime
=
time
;
/*
* Report Success
*/
rep
.
status
=
RRSetConfigSuccess
;
sendReply:
rep
.
type
=
X_Reply
;
/* rep.status has already been filled in */
rep
.
length
=
0
;
rep
.
sequenceNumber
=
client
->
sequence
;
rep
.
newTimestamp
=
pScrPriv
->
lastSetTime
.
milliseconds
;
rep
.
newConfigTimestamp
=
pScrPriv
->
lastConfigTime
.
milliseconds
;
rep
.
root
=
WindowTable
[
pDraw
->
pScreen
->
myNum
]
->
drawable
.
id
;
if
(
client
->
swapped
)
{
swaps
(
&
rep
.
sequenceNumber
,
n
);
swapl
(
&
rep
.
length
,
n
);
swapl
(
&
rep
.
newTimestamp
,
n
);
swapl
(
&
rep
.
newConfigTimestamp
,
n
);
swapl
(
&
rep
.
root
,
n
);
}
WriteToClient
(
client
,
sizeof
(
xRRSetScreenConfigReply
),
(
char
*
)
&
rep
);
return
(
client
->
noClientException
);
}
int
RRSetScreenConfig
(
ScreenPtr
pScreen
,
Rotation
rotation
,
int
rate
,
RRScreenSizePtr
pSize
)
{
rrScrPrivPtr
pScrPriv
;
int
i
;
short
oldWidth
,
oldHeight
;
pScrPriv
=
rrGetScrPriv
(
pScreen
);
oldWidth
=
pScreen
->
width
;
oldHeight
=
pScreen
->
height
;
if
(
!
RRGetInfo
(
pScreen
))
return
BadAlloc
;
/*
* Validate requested rotation
*/
/* test the rotation bits only! */
switch
(
rotation
&
0xf
)
{
case
RR_Rotate_0
:
case
RR_Rotate_90
:
case
RR_Rotate_180
:
case
RR_Rotate_270
:
break
;
default:
/*
* Invalid rotation
*/
return
BadValue
;
}
if
((
~
pScrPriv
->
rotations
)
&
rotation
)
{
/*
* requested rotation or reflection not supported by screen
*/
return
BadMatch
;
}
/*
* Validate requested refresh
*/
if
(
rate
)
{
for
(
i
=
0
;
i
<
pSize
->
nRates
;
i
++
)
{
RRScreenRatePtr
pRate
=
&
pSize
->
pRates
[
i
];
if
(
pRate
->
referenced
&&
pRate
->
rate
==
rate
)
break
;
}
if
(
i
==
pSize
->
nRates
)
{
/*
* Invalid rate
*/
return
BadValue
;
}
}
/*
* call out to ddx routine to effect the change
*/
if
(
!
(
*
pScrPriv
->
rrSetConfig
)
(
pScreen
,
rotation
,
rate
,
pSize
))
{
/*
* unknown DDX failure, report to client
*/
return
BadImplementation
;
}
/*
* set current extension configuration pointers
*/
RRSetCurrentConfig
(
pScreen
,
rotation
,
rate
,
pSize
);
/*
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree
(
pScreen
,
TellChanged
,
(
pointer
)
pScreen
);
/*
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if
(
oldWidth
!=
pScreen
->
width
||
oldHeight
!=
pScreen
->
height
)
RRSendConfigNotify
(
pScreen
);
RREditConnectionInfo
(
pScreen
);
/*
* Fix pointer bounds and location
*/
ScreenRestructured
(
pScreen
);
return
Success
;
}
static
int
ProcRRSelectInput
(
ClientPtr
client
)
{
REQUEST
(
xRRSelectInputReq
);
rrClientPriv
(
client
);
RRTimesPtr
pTimes
;
WindowPtr
pWin
;
RREventPtr
pRREvent
,
pNewRREvent
,
*
pHead
;
XID
clientResource
;
REQUEST_SIZE_MATCH
(
xRRSelectInputReq
);
pWin
=
SecurityLookupWindow
(
stuff
->
window
,
client
,
SecurityWriteAccess
);
if
(
!
pWin
)
return
BadWindow
;
pHead
=
(
RREventPtr
*
)
SecurityLookupIDByType
(
client
,
pWin
->
drawable
.
id
,
EventType
,
SecurityWriteAccess
);
if
(
stuff
->
enable
&
(
RRScreenChangeNotifyMask
))
{
ScreenPtr
pScreen
=
pWin
->
drawable
.
pScreen
;
rrScrPriv
(
pScreen
);
if
(
pHead
)
{
/* check for existing entry. */
for
(
pRREvent
=
*
pHead
;
pRREvent
;
pRREvent
=
pRREvent
->
next
)
if
(
pRREvent
->
client
==
client
)
return
Success
;
}
/* build the entry */
pNewRREvent
=
(
RREventPtr
)
xalloc
(
sizeof
(
RREventRec
));
if
(
!
pNewRREvent
)
return
BadAlloc
;
pNewRREvent
->
next
=
0
;
pNewRREvent
->
client
=
client
;
pNewRREvent
->
window
=
pWin
;
pNewRREvent
->
mask
=
stuff
->
enable
;
/*
* add a resource that will be deleted when
* the client goes away
*/
clientResource
=
FakeClientID
(
client
->
index
);
pNewRREvent
->
clientResource
=
clientResource
;
if
(
!
AddResource
(
clientResource
,
ClientType
,
(
pointer
)
pNewRREvent
))
return
BadAlloc
;
/*
* create a resource to contain a pointer to the list
* of clients selecting input. This must be indirect as
* the list may be arbitrarily rearranged which cannot be
* done through the resource database.
*/
if
(
!
pHead
)
{
pHead
=
(
RREventPtr
*
)
xalloc
(
sizeof
(
RREventPtr
));
if
(
!
pHead
||
!
AddResource
(
pWin
->
drawable
.
id
,
EventType
,
(
pointer
)
pHead
))
{
FreeResource
(
clientResource
,
RT_NONE
);
return
BadAlloc
;
}
*
pHead
=
0
;
}
pNewRREvent
->
next
=
*
pHead
;
*
pHead
=
pNewRREvent
;
/*
* Now see if the client needs an event
*/
if
(
pScrPriv
)
{
pTimes
=
&
((
RRTimesPtr
)
(
pRRClient
+
1
))[
pScreen
->
myNum
];
if
(
CompareTimeStamps
(
pTimes
->
setTime
,
pScrPriv
->
lastSetTime
)
!=
0
||
CompareTimeStamps
(
pTimes
->
configTime
,
pScrPriv
->
lastConfigTime
)
!=
0
)
{
TellChanged
(
pWin
,
(
pointer
)
pScreen
);
}
}
}
else
if
(
stuff
->
enable
==
xFalse
)
{
/* delete the interest */
if
(
pHead
)
{
pNewRREvent
=
0
;
for
(
pRREvent
=
*
pHead
;
pRREvent
;
pRREvent
=
pRREvent
->
next
)
{
if
(
pRREvent
->
client
==
client
)
break
;
pNewRREvent
=
pRREvent
;
}
if
(
pRREvent
)
{
FreeResource
(
pRREvent
->
clientResource
,
ClientType
);
if
(
pNewRREvent
)
pNewRREvent
->
next
=
pRREvent
->
next
;
else
*
pHead
=
pRREvent
->
next
;
xfree
(
pRREvent
);
}
}
}
else
{
client
->
errorValue
=
stuff
->
enable
;
return
BadValue
;
}
return
Success
;
}
static
int
ProcRRDispatch
(
ClientPtr
client
)
{
REQUEST
(
xReq
);
switch
(
stuff
->
data
)
{
case
X_RRQueryVersion
:
return
ProcRRQueryVersion
(
client
);
case
X_RRSetScreenConfig
:
return
ProcRRSetScreenConfig
(
client
);
case
X_RRSelectInput
:
return
ProcRRSelectInput
(
client
);
case
X_RRGetScreenInfo
:
return
ProcRRGetScreenInfo
(
client
);
default:
return
BadRequest
;
}
}
static
int
SProcRRQueryVersion
(
ClientPtr
client
)
{
register
int
n
;
REQUEST
(
xRRQueryVersionReq
);
swaps
(
&
stuff
->
length
,
n
);
swapl
(
&
stuff
->
majorVersion
,
n
);
swapl
(
&
stuff
->
minorVersion
,
n
);
return
ProcRRQueryVersion
(
client
);
}
static
int
SProcRRGetScreenInfo
(
ClientPtr
client
)
{
register
int
n
;
REQUEST
(
xRRGetScreenInfoReq
);
swaps
(
&
stuff
->
length
,
n
);
swapl
(
&
stuff
->
window
,
n
);
return
ProcRRGetScreenInfo
(
client
);
}
static
int
SProcRRSetScreenConfig
(
ClientPtr
client
)
{
register
int
n
;
REQUEST
(
xRRSetScreenConfigReq
);
if
(
RRClientKnowsRates
(
client
))
{
REQUEST_SIZE_MATCH
(
xRRSetScreenConfigReq
);
swaps
(
&
stuff
->
rate
,
n
);
}
else
{
REQUEST_SIZE_MATCH
(
xRR1_0SetScreenConfigReq
);
}
swaps
(
&
stuff
->
length
,
n
);
swapl
(
&
stuff
->
drawable
,
n
);
swapl
(
&
stuff
->
timestamp
,
n
);
swaps
(
&
stuff
->
sizeID
,
n
);
swaps
(
&
stuff
->
rotation
,
n
);
return
ProcRRSetScreenConfig
(
client
);
}
static
int
SProcRRSelectInput
(
ClientPtr
client
)
{
register
int
n
;
REQUEST
(
xRRSelectInputReq
);
swaps
(
&
stuff
->
length
,
n
);
swapl
(
&
stuff
->
window
,
n
);
return
ProcRRSelectInput
(
client
);
}
static
int
SProcRRDispatch
(
ClientPtr
client
)
{
REQUEST
(
xReq
);
switch
(
stuff
->
data
)
{
case
X_RRQueryVersion
:
return
SProcRRQueryVersion
(
client
);
case
X_RRSetScreenConfig
:
return
SProcRRSetScreenConfig
(
client
);
case
X_RRSelectInput
:
return
SProcRRSelectInput
(
client
);
case
X_RRGetScreenInfo
:
return
SProcRRGetScreenInfo
(
client
);
default:
return
BadRequest
;
}
}
static
Bool
RRScreenSizeMatches
(
RRScreenSizePtr
a
,
RRScreenSizePtr
b
)
{
if
(
a
->
width
!=
b
->
width
)
return
FALSE
;
if
(
a
->
height
!=
b
->
height
)
return
FALSE
;
if
(
a
->
mmWidth
!=
b
->
mmWidth
)
return
FALSE
;
if
(
a
->
mmHeight
!=
b
->
mmHeight
)
return
FALSE
;
return
TRUE
;
}
RRScreenSizePtr
RRRegisterSize
(
ScreenPtr
pScreen
,
short
width
,
short
height
,
short
mmWidth
,
short
mmHeight
)
{
rrScrPriv
(
pScreen
);
int
i
;
RRScreenSize
tmp
;
RRScreenSizePtr
pNew
;
if
(
!
pScrPriv
)
return
0
;
/*
* FIXME: The compiler reports that field
* id is used uninitialized here.
*/
tmp
.
id
=
0
;
tmp
.
width
=
width
;
tmp
.
height
=
height
;
tmp
.
mmWidth
=
mmWidth
;
tmp
.
mmHeight
=
mmHeight
;
tmp
.
pRates
=
0
;
tmp
.
nRates
=
0
;
tmp
.
nRatesInUse
=
0
;
tmp
.
referenced
=
TRUE
;
tmp
.
oldReferenced
=
FALSE
;
for
(
i
=
0
;
i
<
pScrPriv
->
nSizes
;
i
++
)
if
(
RRScreenSizeMatches
(
&
tmp
,
&
pScrPriv
->
pSizes
[
i
]))
{
pScrPriv
->
pSizes
[
i
].
referenced
=
TRUE
;
return
&
pScrPriv
->
pSizes
[
i
];
}
pNew
=
xrealloc
(
pScrPriv
->
pSizes
,
(
pScrPriv
->
nSizes
+
1
)
*
sizeof
(
RRScreenSize
));
if
(
!
pNew
)
return
0
;
pNew
[
pScrPriv
->
nSizes
++
]
=
tmp
;
pScrPriv
->
pSizes
=
pNew
;
return
&
pNew
[
pScrPriv
->
nSizes
-
1
];
}
Bool
RRRegisterRate
(
ScreenPtr
pScreen
,
RRScreenSizePtr
pSize
,
int
rate
)
{
rrScrPriv
(
pScreen
);
int
i
;
RRScreenRatePtr
pNew
,
pRate
;
if
(
!
pScrPriv
)
return
FALSE
;
for
(
i
=
0
;
i
<
pSize
->
nRates
;
i
++
)
{
pRate
=
&
pSize
->
pRates
[
i
];
if
(
pRate
->
rate
==
rate
)
{
pRate
->
referenced
=
TRUE
;
return
TRUE
;
}
}
pNew
=
xrealloc
(
pSize
->
pRates
,
(
pSize
->
nRates
+
1
)
*
sizeof
(
RRScreenRate
));
if
(
!
pNew
)
return
FALSE
;
pRate
=
&
pNew
[
pSize
->
nRates
++
];
pRate
->
rate
=
rate
;
pRate
->
referenced
=
TRUE
;
pRate
->
oldReferenced
=
FALSE
;
pSize
->
pRates
=
pNew
;
return
TRUE
;
}
void
RRSetCurrentConfig
(
ScreenPtr
pScreen
,
Rotation
rotation
,
int
rate
,
RRScreenSizePtr
pSize
)
{
rrScrPriv
(
pScreen
);
if
(
!
pScrPriv
)
return
;
pScrPriv
->
rotation
=
rotation
;
pScrPriv
->
size
=
pSize
-
pScrPriv
->
pSizes
;
pScrPriv
->
rate
=
rate
;
}
nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
deleted
100644 → 0
View file @
39b738a6
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */
/* */
/* NXAGENT, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of Medialogic S.p.A. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
/*
* $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $
*
* Copyright © 2000, Compaq Computer Corporation,
* Copyright © 2002, Hewlett Packard, Inc.
*
* 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, and that the name of Compaq or HP not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission. HP makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
*/
#define NEED_REPLIES
#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "misc.h"
#include "os.h"
#include "dixstruct.h"
#include "resource.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "servermd.h"
#include <X11/extensions/randr.h>
#include <X11/extensions/randrproto.h>
#include "../../randr/randrstr.h"
#ifdef RENDER
#include <X11/extensions/render.h> /* we share subpixel order information */
#include "picturestr.h"
#endif
#include <X11/Xfuncproto.h>
#ifdef EXTMODULE
#include "xf86_ansic.h"
#endif
/* From render.h */
#ifndef SubPixelUnknown
#define SubPixelUnknown 0
#endif
#define RR_VALIDATE
int RRGeneration;
int RRNScreens;
static int ProcRRQueryVersion (ClientPtr pClient);
static int ProcRRDispatch (ClientPtr pClient);
static int SProcRRDispatch (ClientPtr pClient);
static int SProcRRQueryVersion (ClientPtr pClient);
#define wrap(priv,real,mem,func) {\
priv->mem = real->mem; \
real->mem = func; \
}
#define unwrap(priv,real,mem) {\
real->mem = priv->mem; \
}
#if 0
static CARD8 RRReqCode;
static int RRErrBase;
#endif
static int RREventBase;
static RESTYPE ClientType, EventType; /* resource types for event masks */
static int RRClientPrivateIndex;
typedef struct _RRTimes {
TimeStamp setTime;
TimeStamp configTime;
} RRTimesRec, *RRTimesPtr;
typedef struct _RRClient {
int major_version;
int minor_version;
/* RRTimesRec times[0]; */
} RRClientRec, *RRClientPtr;
/*
* each window has a list of clients requesting
* RRNotify events. Each client has a resource
* for each window it selects RRNotify input for,
* this resource is used to delete the RRNotifyRec
* entry from the per-window queue.
*/
typedef struct _RREvent *RREventPtr;
typedef struct _RREvent {
RREventPtr next;
ClientPtr client;
WindowPtr window;
XID clientResource;
int mask;
} RREventRec;
int rrPrivIndex = -1;
#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
static Bool
RRClientKnowsRates (ClientPtr pClient)
{
rrClientPriv(pClient);
return (pRRClient->major_version > 1 ||
(pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
}
static void
RRClientCallback (CallbackListPtr *list,
pointer closure,
pointer data)
{
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
ClientPtr pClient = clientinfo->client;
rrClientPriv(pClient);
RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
int i;
pRRClient->major_version = 0;
pRRClient->minor_version = 0;
for (i = 0; i < screenInfo.numScreens; i++)
{
ScreenPtr pScreen = screenInfo.screens[i];
rrScrPriv(pScreen);
if (pScrPriv)
{
pTimes[i].setTime = pScrPriv->lastSetTime;
pTimes[i].configTime = pScrPriv->lastConfigTime;
}
}
}
static void
RRResetProc (ExtensionEntry *extEntry)
{
}
static Bool
RRCloseScreen (int i, ScreenPtr pScreen)
{
rrScrPriv(pScreen);
unwrap (pScrPriv, pScreen, CloseScreen);
if (pScrPriv->pSizes)
xfree (pScrPriv->pSizes);
xfree (pScrPriv);
RRNScreens -= 1; /* ok, one fewer screen with RandR running */
return (*pScreen->CloseScreen) (i, pScreen);
}
static void
SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
xRRScreenChangeNotifyEvent *to)
{
to->type = from->type;
to->rotation = from->rotation;
cpswaps(from->sequenceNumber, to->sequenceNumber);
cpswapl(from->timestamp, to->timestamp);
cpswapl(from->configTimestamp, to->configTimestamp);
cpswapl(from->root, to->root);
cpswapl(from->window, to->window);
cpswaps(from->sizeID, to->sizeID);
cpswaps(from->widthInPixels, to->widthInPixels);
cpswaps(from->heightInPixels, to->heightInPixels);
cpswaps(from->widthInMillimeters, to->widthInMillimeters);
cpswaps(from->heightInMillimeters, to->heightInMillimeters);
cpswaps(from->subpixelOrder, to->subpixelOrder);
}
Bool RRScreenInit(ScreenPtr pScreen)
{
rrScrPrivPtr pScrPriv;
if (RRGeneration != serverGeneration)
{
if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
return FALSE;
RRGeneration = serverGeneration;
}
pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
if (!pScrPriv)
return FALSE;
SetRRScreen(pScreen, pScrPriv);
/*
* Calling function best set these function vectors
*/
pScrPriv->rrSetConfig = 0;
pScrPriv->rrGetInfo = 0;
/*
* This value doesn't really matter -- any client must call
* GetScreenInfo before reading it which will automatically update
* the time
*/
pScrPriv->lastSetTime = currentTime;
pScrPriv->lastConfigTime = currentTime;
wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
pScrPriv->rotations = RR_Rotate_0;
pScrPriv->nSizes = 0;
pScrPriv->nSizesInUse = 0;
pScrPriv->pSizes = 0;
pScrPriv->rotation = RR_Rotate_0;
pScrPriv->size = -1;
RRNScreens += 1; /* keep count of screens that implement randr */
return TRUE;
}
/*ARGSUSED*/
static int
RRFreeClient (pointer data, XID id)
{
RREventPtr pRREvent;
WindowPtr pWin;
RREventPtr *pHead, pCur, pPrev;
pRREvent = (RREventPtr) data;
pWin = pRREvent->window;
pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType);
if (pHead) {
pPrev = 0;
for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
pPrev = pCur;
if (pCur)
{
if (pPrev)
pPrev->next = pRREvent->next;
else
*pHead = pRREvent->next;
}
}
xfree ((pointer) pRREvent);
return 1;
}
/*ARGSUSED*/
static int
RRFreeEvents (pointer data, XID id)
{
RREventPtr *pHead, pCur, pNext;
pHead = (RREventPtr *) data;
for (pCur = *pHead; pCur; pCur = pNext) {
pNext = pCur->next;
FreeResource (pCur->clientResource, ClientType);
xfree ((pointer) pCur);
}
xfree ((pointer) pHead);
return 1;
}
void
RRExtensionInit (void)
{
ExtensionEntry *extEntry;
if (RRNScreens == 0) return;
RRClientPrivateIndex = AllocateClientPrivateIndex ();
if (!AllocateClientPrivate (RRClientPrivateIndex,
sizeof (RRClientRec) +
screenInfo.numScreens * sizeof (RRTimesRec)))
return;
if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
return;
ClientType = CreateNewResourceType(RRFreeClient);
if (!ClientType)
return;
EventType = CreateNewResourceType(RRFreeEvents);
if (!EventType)
return;
extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
ProcRRDispatch, SProcRRDispatch,
RRResetProc, StandardMinorOpcode);
if (!extEntry)
return;
#if 0
RRReqCode = (CARD8) extEntry->base;
RRErrBase = extEntry->errorBase;
#endif
RREventBase = extEntry->eventBase;
EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
SRRScreenChangeNotifyEvent;
return;
}
int
TellChanged (WindowPtr pWin, pointer value)
{
RREventPtr *pHead, pRREvent;
ClientPtr client;
xRRScreenChangeNotifyEvent se;
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv(pScreen);
RRScreenSizePtr pSize;
WindowPtr pRoot = WindowTable[pScreen->myNum];
pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType);
if (!pHead)
return WT_WALKCHILDREN;
se.type = RRScreenChangeNotify + RREventBase;
se.rotation = (CARD8) pScrPriv->rotation;
se.timestamp = pScrPriv->lastSetTime.milliseconds;
se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
se.root = pRoot->drawable.id;
se.window = pWin->drawable.id;
#ifdef RENDER
se.subpixelOrder = PictureGetSubpixelOrder (pScreen);
#else
se.subpixelOrder = SubPixelUnknown;
#endif
if (pScrPriv->size >= 0)
{
pSize = &pScrPriv->pSizes[pScrPriv->size];
se.sizeID = pSize->id;
se.widthInPixels = pSize->width;
se.heightInPixels = pSize->height;
se.widthInMillimeters = pSize->mmWidth;
se.heightInMillimeters = pSize->mmHeight;
}
else
{
/*
* This "shouldn't happen", but a broken DDX can
* forget to set the current configuration on GetInfo
*/
se.sizeID = 0xffff;
se.widthInPixels = 0;
se.heightInPixels = 0;
se.widthInMillimeters = 0;
se.heightInMillimeters = 0;
}
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
{
client = pRREvent->client;
if (client == serverClient || client->clientGone)
continue;
se.sequenceNumber = client->sequence;
if(pRREvent->mask & RRScreenChangeNotifyMask)
WriteEventsToClient (client, 1, (xEvent *) &se);
}
return WT_WALKCHILDREN;
}
Bool
RRGetInfo (ScreenPtr pScreen)
{
rrScrPriv (pScreen);
int i, j, k, l;
Bool changed;
Rotation rotations;
RRScreenSizePtr pSize;
RRScreenRatePtr pRate;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
pSize->oldReferenced = pSize->referenced;
pSize->referenced = FALSE;
for (k = 0; k < pSize->nRates; k++)
{
pRate = &pSize->pRates[k];
pRate->oldReferenced = pRate->referenced;
pRate->referenced = FALSE;
}
}
if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
return FALSE;
changed = FALSE;
/*
* Check whether anything changed and simultaneously generate
* the protocol id values for the objects
*/
if (rotations != pScrPriv->rotations)
{
pScrPriv->rotations = rotations;
changed = TRUE;
}
j = 0;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
if (pSize->oldReferenced != pSize->referenced)
changed = TRUE;
if (pSize->referenced)
pSize->id = j++;
l = 0;
for (k = 0; k < pSize->nRates; k++)
{
pRate = &pSize->pRates[k];
if (pRate->oldReferenced != pRate->referenced)
changed = TRUE;
if (pRate->referenced)
l++;
}
pSize->nRatesInUse = l;
}
pScrPriv->nSizesInUse = j;
if (changed)
{
UpdateCurrentTime ();
pScrPriv->lastConfigTime = currentTime;
WalkTree (pScreen, TellChanged, (pointer) pScreen);
}
return TRUE;
}
void
RRSendConfigNotify (ScreenPtr pScreen)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
xEvent event;
event.u.u.type = ConfigureNotify;
event.u.configureNotify.window = pWin->drawable.id;
event.u.configureNotify.aboveSibling = None;
event.u.configureNotify.x = 0;
event.u.configureNotify.y = 0;
/* XXX xinerama stuff ? */
event.u.configureNotify.width = pWin->drawable.width;
event.u.configureNotify.height = pWin->drawable.height;
event.u.configureNotify.borderWidth = wBorderWidth (pWin);
event.u.configureNotify.override = pWin->overrideRedirect;
DeliverEvents(pWin, &event, 1, NullWindow);
}
static int
ProcRRQueryVersion (ClientPtr client)
{
xRRQueryVersionReply rep;
register int n;
REQUEST(xRRQueryVersionReq);
rrClientPriv(client);
REQUEST_SIZE_MATCH(xRRQueryVersionReq);
pRRClient->major_version = stuff->majorVersion;
pRRClient->minor_version = stuff->minorVersion;
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.majorVersion = RANDR_MAJOR;
rep.minorVersion = RANDR_MINOR;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.majorVersion, n);
swapl(&rep.minorVersion, n);
}
WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep);
return (client->noClientException);
}
extern char *ConnectionInfo;
static int padlength[4] = {0, 3, 2, 1};
void
RREditConnectionInfo (ScreenPtr pScreen)
{
xConnSetup *connSetup;
char *vendor;
xPixmapFormat *formats;
xWindowRoot *root;
xDepth *depth;
xVisualType *visual;
int screen = 0;
int d;
connSetup = (xConnSetup *) ConnectionInfo;
vendor = (char *) connSetup + sizeof (xConnSetup);
formats = (xPixmapFormat *) ((char *) vendor +
connSetup->nbytesVendor +
padlength[connSetup->nbytesVendor & 3]);
root = (xWindowRoot *) ((char *) formats +
sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
while (screen != pScreen->myNum)
{
depth = (xDepth *) ((char *) root +
sizeof (xWindowRoot));
for (d = 0; d < root->nDepths; d++)
{
visual = (xVisualType *) ((char *) depth +
sizeof (xDepth));
depth = (xDepth *) ((char *) visual +
depth->nVisuals * sizeof (xVisualType));
}
root = (xWindowRoot *) ((char *) depth);
screen++;
}
root->pixWidth = pScreen->width;
root->pixHeight = pScreen->height;
root->mmWidth = pScreen->mmWidth;
root->mmHeight = pScreen->mmHeight;
}
static int
ProcRRGetScreenInfo (ClientPtr client)
{
REQUEST(xRRGetScreenInfoReq);
xRRGetScreenInfoReply rep;
WindowPtr pWin;
int n;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
CARD8 *extra;
unsigned long extraLen;
REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
SecurityReadAccess);
if (!pWin)
return BadWindow;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
rep.pad = 0;
if (!pScrPriv)
{
rep.type = X_Reply;
rep.setOfRotations = RR_Rotate_0;;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
rep.timestamp = currentTime.milliseconds;
rep.configTimestamp = currentTime.milliseconds;
rep.nSizes = 0;
rep.sizeID = 0;
rep.rotation = RR_Rotate_0;
rep.rate = 0;
rep.nrateEnts = 0;
extra = 0;
extraLen = 0;
}
else
{
int i, j;
xScreenSizes *size;
CARD16 *rates;
CARD8 *data8;
Bool has_rate = RRClientKnowsRates (client);
RRGetInfo (pScreen);
rep.type = X_Reply;
rep.setOfRotations = pScrPriv->rotations;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.rotation = pScrPriv->rotation;
rep.nSizes = pScrPriv->nSizesInUse;
rep.rate = pScrPriv->rate;
rep.nrateEnts = 0;
if (has_rate)
{
for (i = 0; i < pScrPriv->nSizes; i++)
{
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
if (pSize->referenced)
{
rep.nrateEnts += (1 + pSize->nRatesInUse);
}
}
}
if (pScrPriv->size >= 0)
rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id;
else
return BadImplementation;
extraLen = (rep.nSizes * sizeof (xScreenSizes) +
rep.nrateEnts * sizeof (CARD16));
extra = (CARD8 *) xalloc (extraLen);
if (!extra)
return BadAlloc;
/*
* First comes the size information
*/
size = (xScreenSizes *) extra;
rates = (CARD16 *) (size + rep.nSizes);
for (i = 0; i < pScrPriv->nSizes; i++)
{
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
if (pSize->referenced)
{
size->widthInPixels = pSize->width;
size->heightInPixels = pSize->height;
size->widthInMillimeters = pSize->mmWidth;
size->heightInMillimeters = pSize->mmHeight;
if (client->swapped)
{
swaps (&size->widthInPixels, n);
swaps (&size->heightInPixels, n);
swaps (&size->widthInMillimeters, n);
swaps (&size->heightInMillimeters, n);
}
size++;
if (has_rate)
{
*rates = pSize->nRatesInUse;
if (client->swapped)
{
swaps (rates, n);
}
rates++;
for (j = 0; j < pSize->nRates; j++)
{
RRScreenRatePtr pRate = &pSize->pRates[j];
if (pRate->referenced)
{
*rates = pRate->rate;
if (client->swapped)
{
swaps (rates, n);
}
rates++;
}
}
}
}
}
data8 = (CARD8 *) rates;
if (data8 - (CARD8 *) extra != extraLen)
FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n",
(unsigned long)(data8 - (CARD8 *) extra), extraLen);
rep.length = (extraLen + 3) >> 2;
}
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.timestamp, n);
swaps(&rep.rotation, n);
swaps(&rep.nSizes, n);
swaps(&rep.sizeID, n);
swaps(&rep.rate, n);
swaps(&rep.nrateEnts, n);
}
WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
if (extraLen)
{
WriteToClient (client, extraLen, (char *) extra);
xfree (extra);
}
return (client->noClientException);
}
static int
ProcRRSetScreenConfig (ClientPtr client)
{
REQUEST(xRRSetScreenConfigReq);
xRRSetScreenConfigReply rep;
DrawablePtr pDraw;
int n;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
TimeStamp configTime;
TimeStamp time;
RRScreenSizePtr pSize;
int i;
Rotation rotation;
int rate;
short oldWidth, oldHeight;
Bool has_rate;
UpdateCurrentTime ();
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
has_rate = TRUE;
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
has_rate = FALSE;
}
SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client,
SecurityWriteAccess);
pScreen = pDraw->pScreen;
pScrPriv = rrGetScrPriv(pScreen);
time = ClientTimeToServerTime(stuff->timestamp);
configTime = ClientTimeToServerTime(stuff->configTimestamp);
oldWidth = pScreen->width;
oldHeight = pScreen->height;
if (!pScrPriv)
{
time = currentTime;
rep.status = RRSetConfigFailed;
goto sendReply;
}
if (!RRGetInfo (pScreen))
return BadAlloc;
/*
* if the client's config timestamp is not the same as the last config
* timestamp, then the config information isn't up-to-date and
* can't even be validated
*/
if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
{
rep.status = RRSetConfigInvalidConfigTime;
goto sendReply;
}
/*
* Search for the requested size
*/
pSize = 0;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
if (pSize->referenced && pSize->id == stuff->sizeID)
{
break;
}
}
if (i == pScrPriv->nSizes)
{
/*
* Invalid size ID
*/
client->errorValue = stuff->sizeID;
return BadValue;
}
/*
* Validate requested rotation
*/
rotation = (Rotation) stuff->rotation;
/* test the rotation bits only! */
switch (rotation & 0xf) {
case RR_Rotate_0:
case RR_Rotate_90:
case RR_Rotate_180:
case RR_Rotate_270:
break;
default:
/*
* Invalid rotation
*/
client->errorValue = stuff->rotation;
return BadValue;
}
if ((~pScrPriv->rotations) & rotation)
{
/*
* requested rotation or reflection not supported by screen
*/
client->errorValue = stuff->rotation;
return BadMatch;
}
/*
* Validate requested refresh
*/
if (has_rate)
rate = (int) stuff->rate;
else
rate = 0;
if (rate)
{
for (i = 0; i < pSize->nRates; i++)
{
RRScreenRatePtr pRate = &pSize->pRates[i];
if (pRate->referenced && pRate->rate == rate)
break;
}
if (i == pSize->nRates)
{
/*
* Invalid rate
*/
client->errorValue = rate;
return BadValue;
}
}
/*
* Make sure the requested set-time is not older than
* the last set-time
*/
if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
{
rep.status = RRSetConfigInvalidTime;
goto sendReply;
}
/*
* call out to ddx routine to effect the change
*/
if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
pSize))
{
/*
* unknown DDX failure, report to client
*/
rep.status = RRSetConfigFailed;
goto sendReply;
}
/*
* set current extension configuration pointers
*/
RRSetCurrentConfig (pScreen, rotation, rate, pSize);
/*
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree (pScreen, TellChanged, (pointer) pScreen);
/*
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if (oldWidth != pScreen->width || oldHeight != pScreen->height)
RRSendConfigNotify (pScreen);
RREditConnectionInfo (pScreen);
/*
* Fix pointer bounds and location
*/
ScreenRestructured (pScreen);
pScrPriv->lastSetTime = time;
/*
* Report Success
*/
rep.status = RRSetConfigSuccess;
sendReply:
rep.type = X_Reply;
/* rep.status has already been filled in */
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
if (client->swapped)
{
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.newTimestamp, n);
swapl(&rep.newConfigTimestamp, n);
swapl(&rep.root, n);
}
WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
return (client->noClientException);
}
int
RRSetScreenConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize)
{
rrScrPrivPtr pScrPriv;
int i;
short oldWidth, oldHeight;
pScrPriv = rrGetScrPriv(pScreen);
oldWidth = pScreen->width;
oldHeight = pScreen->height;
if (!RRGetInfo (pScreen))
return BadAlloc;
/*
* Validate requested rotation
*/
/* test the rotation bits only! */
switch (rotation & 0xf) {
case RR_Rotate_0:
case RR_Rotate_90:
case RR_Rotate_180:
case RR_Rotate_270:
break;
default:
/*
* Invalid rotation
*/
return BadValue;
}
if ((~pScrPriv->rotations) & rotation)
{
/*
* requested rotation or reflection not supported by screen
*/
return BadMatch;
}
/*
* Validate requested refresh
*/
if (rate)
{
for (i = 0; i < pSize->nRates; i++)
{
RRScreenRatePtr pRate = &pSize->pRates[i];
if (pRate->referenced && pRate->rate == rate)
break;
}
if (i == pSize->nRates)
{
/*
* Invalid rate
*/
return BadValue;
}
}
/*
* call out to ddx routine to effect the change
*/
if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
pSize))
{
/*
* unknown DDX failure, report to client
*/
return BadImplementation;
}
/*
* set current extension configuration pointers
*/
RRSetCurrentConfig (pScreen, rotation, rate, pSize);
/*
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree (pScreen, TellChanged, (pointer) pScreen);
/*
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if (oldWidth != pScreen->width || oldHeight != pScreen->height)
RRSendConfigNotify (pScreen);
RREditConnectionInfo (pScreen);
/*
* Fix pointer bounds and location
*/
ScreenRestructured (pScreen);
return Success;
}
static int
ProcRRSelectInput (ClientPtr client)
{
REQUEST(xRRSelectInputReq);
rrClientPriv(client);
RRTimesPtr pTimes;
WindowPtr pWin;
RREventPtr pRREvent, pNewRREvent, *pHead;
XID clientResource;
REQUEST_SIZE_MATCH(xRRSelectInputReq);
pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess);
if (!pWin)
return BadWindow;
pHead = (RREventPtr *)SecurityLookupIDByType(client,
pWin->drawable.id, EventType,
SecurityWriteAccess);
if (stuff->enable & (RRScreenChangeNotifyMask))
{
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv (pScreen);
if (pHead)
{
/* check for existing entry. */
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
if (pRREvent->client == client)
return Success;
}
/* build the entry */
pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
if (!pNewRREvent)
return BadAlloc;
pNewRREvent->next = 0;
pNewRREvent->client = client;
pNewRREvent->window = pWin;
pNewRREvent->mask = stuff->enable;
/*
* add a resource that will be deleted when
* the client goes away
*/
clientResource = FakeClientID (client->index);
pNewRREvent->clientResource = clientResource;
if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent))
return BadAlloc;
/*
* create a resource to contain a pointer to the list
* of clients selecting input. This must be indirect as
* the list may be arbitrarily rearranged which cannot be
* done through the resource database.
*/
if (!pHead)
{
pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
if (!pHead ||
!AddResource (pWin->drawable.id, EventType, (pointer)pHead))
{
FreeResource (clientResource, RT_NONE);
return BadAlloc;
}
*pHead = 0;
}
pNewRREvent->next = *pHead;
*pHead = pNewRREvent;
/*
* Now see if the client needs an event
*/
if (pScrPriv)
{
pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
if (CompareTimeStamps (pTimes->setTime,
pScrPriv->lastSetTime) != 0 ||
CompareTimeStamps (pTimes->configTime,
pScrPriv->lastConfigTime) != 0)
{
TellChanged (pWin, (pointer) pScreen);
}
}
}
else if (stuff->enable == xFalse)
{
/* delete the interest */
if (pHead) {
pNewRREvent = 0;
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
if (pRREvent->client == client)
break;
pNewRREvent = pRREvent;
}
if (pRREvent) {
FreeResource (pRREvent->clientResource, ClientType);
if (pNewRREvent)
pNewRREvent->next = pRREvent->next;
else
*pHead = pRREvent->next;
xfree (pRREvent);
}
}
}
else
{
client->errorValue = stuff->enable;
return BadValue;
}
return Success;
}
static int
ProcRRDispatch (ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_RRQueryVersion:
return ProcRRQueryVersion(client);
case X_RRSetScreenConfig:
return ProcRRSetScreenConfig(client);
case X_RRSelectInput:
return ProcRRSelectInput(client);
case X_RRGetScreenInfo:
return ProcRRGetScreenInfo(client);
default:
return BadRequest;
}
}
static int
SProcRRQueryVersion (ClientPtr client)
{
register int n;
REQUEST(xRRQueryVersionReq);
swaps(&stuff->length, n);
swapl(&stuff->majorVersion, n);
swapl(&stuff->minorVersion, n);
return ProcRRQueryVersion(client);
}
static int
SProcRRGetScreenInfo (ClientPtr client)
{
register int n;
REQUEST(xRRGetScreenInfoReq);
swaps(&stuff->length, n);
swapl(&stuff->window, n);
return ProcRRGetScreenInfo(client);
}
static int
SProcRRSetScreenConfig (ClientPtr client)
{
register int n;
REQUEST(xRRSetScreenConfigReq);
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
swaps (&stuff->rate, n);
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
}
swaps(&stuff->length, n);
swapl(&stuff->drawable, n);
swapl(&stuff->timestamp, n);
swaps(&stuff->sizeID, n);
swaps(&stuff->rotation, n);
return ProcRRSetScreenConfig(client);
}
static int
SProcRRSelectInput (ClientPtr client)
{
register int n;
REQUEST(xRRSelectInputReq);
swaps(&stuff->length, n);
swapl(&stuff->window, n);
return ProcRRSelectInput(client);
}
static int
SProcRRDispatch (ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_RRQueryVersion:
return SProcRRQueryVersion(client);
case X_RRSetScreenConfig:
return SProcRRSetScreenConfig(client);
case X_RRSelectInput:
return SProcRRSelectInput(client);
case X_RRGetScreenInfo:
return SProcRRGetScreenInfo(client);
default:
return BadRequest;
}
}
static Bool
RRScreenSizeMatches (RRScreenSizePtr a,
RRScreenSizePtr b)
{
if (a->width != b->width)
return FALSE;
if (a->height != b->height)
return FALSE;
if (a->mmWidth != b->mmWidth)
return FALSE;
if (a->mmHeight != b->mmHeight)
return FALSE;
return TRUE;
}
RRScreenSizePtr
RRRegisterSize (ScreenPtr pScreen,
short width,
short height,
short mmWidth,
short mmHeight)
{
rrScrPriv (pScreen);
int i;
RRScreenSize tmp;
RRScreenSizePtr pNew;
if (!pScrPriv)
return 0;
/*
* FIXME: The compiler reports that field
* id is used uninitialized here.
*/
tmp.id = 0;
tmp.width = width;
tmp.height= height;
tmp.mmWidth = mmWidth;
tmp.mmHeight = mmHeight;
tmp.pRates = 0;
tmp.nRates = 0;
tmp.nRatesInUse = 0;
tmp.referenced = TRUE;
tmp.oldReferenced = FALSE;
for (i = 0; i < pScrPriv->nSizes; i++)
if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
{
pScrPriv->pSizes[i].referenced = TRUE;
return &pScrPriv->pSizes[i];
}
pNew = xrealloc (pScrPriv->pSizes,
(pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
if (!pNew)
return 0;
pNew[pScrPriv->nSizes++] = tmp;
pScrPriv->pSizes = pNew;
return &pNew[pScrPriv->nSizes-1];
}
Bool RRRegisterRate (ScreenPtr pScreen,
RRScreenSizePtr pSize,
int rate)
{
rrScrPriv(pScreen);
int i;
RRScreenRatePtr pNew, pRate;
if (!pScrPriv)
return FALSE;
for (i = 0; i < pSize->nRates; i++)
{
pRate = &pSize->pRates[i];
if (pRate->rate == rate)
{
pRate->referenced = TRUE;
return TRUE;
}
}
pNew = xrealloc (pSize->pRates,
(pSize->nRates + 1) * sizeof (RRScreenRate));
if (!pNew)
return FALSE;
pRate = &pNew[pSize->nRates++];
pRate->rate = rate;
pRate->referenced = TRUE;
pRate->oldReferenced = FALSE;
pSize->pRates = pNew;
return TRUE;
}
void
RRSetCurrentConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize)
{
rrScrPriv (pScreen);
if (!pScrPriv)
return;
pScrPriv->rotation = rotation;
pScrPriv->size = pSize - pScrPriv->pSizes;
pScrPriv->rate = rate;
}
nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original
deleted
100644 → 0
View file @
39b738a6
/*
* $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $
*
* Copyright © 2000, Compaq Computer Corporation,
* Copyright © 2002, Hewlett Packard, Inc.
*
* 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, and that the name of Compaq or HP not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission. HP makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
*/
#define NEED_REPLIES
#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "misc.h"
#include "os.h"
#include "dixstruct.h"
#include "resource.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "servermd.h"
#include <X11/extensions/randr.h>
#include <X11/extensions/randrproto.h>
#include "randrstr.h"
#ifdef RENDER
#include <X11/extensions/render.h> /* we share subpixel order information */
#include "picturestr.h"
#endif
#include <X11/Xfuncproto.h>
#ifdef EXTMODULE
#include "xf86_ansic.h"
#endif
/* From render.h */
#ifndef SubPixelUnknown
#define SubPixelUnknown 0
#endif
#define RR_VALIDATE
int RRGeneration;
int RRNScreens;
static int ProcRRQueryVersion (ClientPtr pClient);
static int ProcRRDispatch (ClientPtr pClient);
static int SProcRRDispatch (ClientPtr pClient);
static int SProcRRQueryVersion (ClientPtr pClient);
#define wrap(priv,real,mem,func) {\
priv->mem = real->mem; \
real->mem = func; \
}
#define unwrap(priv,real,mem) {\
real->mem = priv->mem; \
}
#if 0
static CARD8 RRReqCode;
static int RRErrBase;
#endif
static int RREventBase;
static RESTYPE ClientType, EventType; /* resource types for event masks */
static int RRClientPrivateIndex;
typedef struct _RRTimes {
TimeStamp setTime;
TimeStamp configTime;
} RRTimesRec, *RRTimesPtr;
typedef struct _RRClient {
int major_version;
int minor_version;
/* RRTimesRec times[0]; */
} RRClientRec, *RRClientPtr;
/*
* each window has a list of clients requesting
* RRNotify events. Each client has a resource
* for each window it selects RRNotify input for,
* this resource is used to delete the RRNotifyRec
* entry from the per-window queue.
*/
typedef struct _RREvent *RREventPtr;
typedef struct _RREvent {
RREventPtr next;
ClientPtr client;
WindowPtr window;
XID clientResource;
int mask;
} RREventRec;
int rrPrivIndex = -1;
#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
static Bool
RRClientKnowsRates (ClientPtr pClient)
{
rrClientPriv(pClient);
return (pRRClient->major_version > 1 ||
(pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
}
static void
RRClientCallback (CallbackListPtr *list,
pointer closure,
pointer data)
{
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
ClientPtr pClient = clientinfo->client;
rrClientPriv(pClient);
RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
int i;
pRRClient->major_version = 0;
pRRClient->minor_version = 0;
for (i = 0; i < screenInfo.numScreens; i++)
{
ScreenPtr pScreen = screenInfo.screens[i];
rrScrPriv(pScreen);
if (pScrPriv)
{
pTimes[i].setTime = pScrPriv->lastSetTime;
pTimes[i].configTime = pScrPriv->lastConfigTime;
}
}
}
static void
RRResetProc (ExtensionEntry *extEntry)
{
}
static Bool
RRCloseScreen (int i, ScreenPtr pScreen)
{
rrScrPriv(pScreen);
unwrap (pScrPriv, pScreen, CloseScreen);
if (pScrPriv->pSizes)
xfree (pScrPriv->pSizes);
xfree (pScrPriv);
RRNScreens -= 1; /* ok, one fewer screen with RandR running */
return (*pScreen->CloseScreen) (i, pScreen);
}
static void
SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
xRRScreenChangeNotifyEvent *to)
{
to->type = from->type;
to->rotation = from->rotation;
cpswaps(from->sequenceNumber, to->sequenceNumber);
cpswapl(from->timestamp, to->timestamp);
cpswapl(from->configTimestamp, to->configTimestamp);
cpswapl(from->root, to->root);
cpswapl(from->window, to->window);
cpswaps(from->sizeID, to->sizeID);
cpswaps(from->widthInPixels, to->widthInPixels);
cpswaps(from->heightInPixels, to->heightInPixels);
cpswaps(from->widthInMillimeters, to->widthInMillimeters);
cpswaps(from->heightInMillimeters, to->heightInMillimeters);
cpswaps(from->subpixelOrder, to->subpixelOrder);
}
Bool RRScreenInit(ScreenPtr pScreen)
{
rrScrPrivPtr pScrPriv;
if (RRGeneration != serverGeneration)
{
if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
return FALSE;
RRGeneration = serverGeneration;
}
pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
if (!pScrPriv)
return FALSE;
SetRRScreen(pScreen, pScrPriv);
/*
* Calling function best set these function vectors
*/
pScrPriv->rrSetConfig = 0;
pScrPriv->rrGetInfo = 0;
/*
* This value doesn't really matter -- any client must call
* GetScreenInfo before reading it which will automatically update
* the time
*/
pScrPriv->lastSetTime = currentTime;
pScrPriv->lastConfigTime = currentTime;
wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
pScrPriv->rotations = RR_Rotate_0;
pScrPriv->nSizes = 0;
pScrPriv->nSizesInUse = 0;
pScrPriv->pSizes = 0;
pScrPriv->rotation = RR_Rotate_0;
pScrPriv->size = -1;
RRNScreens += 1; /* keep count of screens that implement randr */
return TRUE;
}
/*ARGSUSED*/
static int
RRFreeClient (pointer data, XID id)
{
RREventPtr pRREvent;
WindowPtr pWin;
RREventPtr *pHead, pCur, pPrev;
pRREvent = (RREventPtr) data;
pWin = pRREvent->window;
pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType);
if (pHead) {
pPrev = 0;
for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
pPrev = pCur;
if (pCur)
{
if (pPrev)
pPrev->next = pRREvent->next;
else
*pHead = pRREvent->next;
}
}
xfree ((pointer) pRREvent);
return 1;
}
/*ARGSUSED*/
static int
RRFreeEvents (pointer data, XID id)
{
RREventPtr *pHead, pCur, pNext;
pHead = (RREventPtr *) data;
for (pCur = *pHead; pCur; pCur = pNext) {
pNext = pCur->next;
FreeResource (pCur->clientResource, ClientType);
xfree ((pointer) pCur);
}
xfree ((pointer) pHead);
return 1;
}
void
RRExtensionInit (void)
{
ExtensionEntry *extEntry;
if (RRNScreens == 0) return;
RRClientPrivateIndex = AllocateClientPrivateIndex ();
if (!AllocateClientPrivate (RRClientPrivateIndex,
sizeof (RRClientRec) +
screenInfo.numScreens * sizeof (RRTimesRec)))
return;
if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
return;
ClientType = CreateNewResourceType(RRFreeClient);
if (!ClientType)
return;
EventType = CreateNewResourceType(RRFreeEvents);
if (!EventType)
return;
extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
ProcRRDispatch, SProcRRDispatch,
RRResetProc, StandardMinorOpcode);
if (!extEntry)
return;
#if 0
RRReqCode = (CARD8) extEntry->base;
RRErrBase = extEntry->errorBase;
#endif
RREventBase = extEntry->eventBase;
EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
SRRScreenChangeNotifyEvent;
return;
}
static int
TellChanged (WindowPtr pWin, pointer value)
{
RREventPtr *pHead, pRREvent;
ClientPtr client;
xRRScreenChangeNotifyEvent se;
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv(pScreen);
RRScreenSizePtr pSize;
WindowPtr pRoot = WindowTable[pScreen->myNum];
pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType);
if (!pHead)
return WT_WALKCHILDREN;
se.type = RRScreenChangeNotify + RREventBase;
se.rotation = (CARD8) pScrPriv->rotation;
se.timestamp = pScrPriv->lastSetTime.milliseconds;
se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
se.root = pRoot->drawable.id;
se.window = pWin->drawable.id;
#ifdef RENDER
se.subpixelOrder = PictureGetSubpixelOrder (pScreen);
#else
se.subpixelOrder = SubPixelUnknown;
#endif
if (pScrPriv->size >= 0)
{
pSize = &pScrPriv->pSizes[pScrPriv->size];
se.sizeID = pSize->id;
se.widthInPixels = pSize->width;
se.heightInPixels = pSize->height;
se.widthInMillimeters = pSize->mmWidth;
se.heightInMillimeters = pSize->mmHeight;
}
else
{
/*
* This "shouldn't happen", but a broken DDX can
* forget to set the current configuration on GetInfo
*/
se.sizeID = 0xffff;
se.widthInPixels = 0;
se.heightInPixels = 0;
se.widthInMillimeters = 0;
se.heightInMillimeters = 0;
}
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
{
client = pRREvent->client;
if (client == serverClient || client->clientGone)
continue;
se.sequenceNumber = client->sequence;
if(pRREvent->mask & RRScreenChangeNotifyMask)
WriteEventsToClient (client, 1, (xEvent *) &se);
}
return WT_WALKCHILDREN;
}
static Bool
RRGetInfo (ScreenPtr pScreen)
{
rrScrPriv (pScreen);
int i, j, k, l;
Bool changed;
Rotation rotations;
RRScreenSizePtr pSize;
RRScreenRatePtr pRate;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
pSize->oldReferenced = pSize->referenced;
pSize->referenced = FALSE;
for (k = 0; k < pSize->nRates; k++)
{
pRate = &pSize->pRates[k];
pRate->oldReferenced = pRate->referenced;
pRate->referenced = FALSE;
}
}
if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
return FALSE;
changed = FALSE;
/*
* Check whether anything changed and simultaneously generate
* the protocol id values for the objects
*/
if (rotations != pScrPriv->rotations)
{
pScrPriv->rotations = rotations;
changed = TRUE;
}
j = 0;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
if (pSize->oldReferenced != pSize->referenced)
changed = TRUE;
if (pSize->referenced)
pSize->id = j++;
l = 0;
for (k = 0; k < pSize->nRates; k++)
{
pRate = &pSize->pRates[k];
if (pRate->oldReferenced != pRate->referenced)
changed = TRUE;
if (pRate->referenced)
l++;
}
pSize->nRatesInUse = l;
}
pScrPriv->nSizesInUse = j;
if (changed)
{
UpdateCurrentTime ();
pScrPriv->lastConfigTime = currentTime;
WalkTree (pScreen, TellChanged, (pointer) pScreen);
}
return TRUE;
}
static void
RRSendConfigNotify (ScreenPtr pScreen)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
xEvent event;
event.u.u.type = ConfigureNotify;
event.u.configureNotify.window = pWin->drawable.id;
event.u.configureNotify.aboveSibling = None;
event.u.configureNotify.x = 0;
event.u.configureNotify.y = 0;
/* XXX xinerama stuff ? */
event.u.configureNotify.width = pWin->drawable.width;
event.u.configureNotify.height = pWin->drawable.height;
event.u.configureNotify.borderWidth = wBorderWidth (pWin);
event.u.configureNotify.override = pWin->overrideRedirect;
DeliverEvents(pWin, &event, 1, NullWindow);
}
static int
ProcRRQueryVersion (ClientPtr client)
{
xRRQueryVersionReply rep;
register int n;
REQUEST(xRRQueryVersionReq);
rrClientPriv(client);
REQUEST_SIZE_MATCH(xRRQueryVersionReq);
pRRClient->major_version = stuff->majorVersion;
pRRClient->minor_version = stuff->minorVersion;
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.majorVersion = RANDR_MAJOR;
rep.minorVersion = RANDR_MINOR;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.majorVersion, n);
swapl(&rep.minorVersion, n);
}
WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep);
return (client->noClientException);
}
extern char *ConnectionInfo;
static int padlength[4] = {0, 3, 2, 1};
static void
RREditConnectionInfo (ScreenPtr pScreen)
{
xConnSetup *connSetup;
char *vendor;
xPixmapFormat *formats;
xWindowRoot *root;
xDepth *depth;
xVisualType *visual;
int screen = 0;
int d;
connSetup = (xConnSetup *) ConnectionInfo;
vendor = (char *) connSetup + sizeof (xConnSetup);
formats = (xPixmapFormat *) ((char *) vendor +
connSetup->nbytesVendor +
padlength[connSetup->nbytesVendor & 3]);
root = (xWindowRoot *) ((char *) formats +
sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
while (screen != pScreen->myNum)
{
depth = (xDepth *) ((char *) root +
sizeof (xWindowRoot));
for (d = 0; d < root->nDepths; d++)
{
visual = (xVisualType *) ((char *) depth +
sizeof (xDepth));
depth = (xDepth *) ((char *) visual +
depth->nVisuals * sizeof (xVisualType));
}
root = (xWindowRoot *) ((char *) depth);
screen++;
}
root->pixWidth = pScreen->width;
root->pixHeight = pScreen->height;
root->mmWidth = pScreen->mmWidth;
root->mmHeight = pScreen->mmHeight;
}
static int
ProcRRGetScreenInfo (ClientPtr client)
{
REQUEST(xRRGetScreenInfoReq);
xRRGetScreenInfoReply rep;
WindowPtr pWin;
int n;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
CARD8 *extra;
unsigned long extraLen;
REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
SecurityReadAccess);
if (!pWin)
return BadWindow;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
rep.pad = 0;
if (!pScrPriv)
{
rep.type = X_Reply;
rep.setOfRotations = RR_Rotate_0;;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
rep.timestamp = currentTime.milliseconds;
rep.configTimestamp = currentTime.milliseconds;
rep.nSizes = 0;
rep.sizeID = 0;
rep.rotation = RR_Rotate_0;
rep.rate = 0;
rep.nrateEnts = 0;
extra = 0;
extraLen = 0;
}
else
{
int i, j;
xScreenSizes *size;
CARD16 *rates;
CARD8 *data8;
Bool has_rate = RRClientKnowsRates (client);
RRGetInfo (pScreen);
rep.type = X_Reply;
rep.setOfRotations = pScrPriv->rotations;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.rotation = pScrPriv->rotation;
rep.nSizes = pScrPriv->nSizesInUse;
rep.rate = pScrPriv->rate;
rep.nrateEnts = 0;
if (has_rate)
{
for (i = 0; i < pScrPriv->nSizes; i++)
{
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
if (pSize->referenced)
{
rep.nrateEnts += (1 + pSize->nRatesInUse);
}
}
}
if (pScrPriv->size >= 0)
rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id;
else
return BadImplementation;
extraLen = (rep.nSizes * sizeof (xScreenSizes) +
rep.nrateEnts * sizeof (CARD16));
extra = (CARD8 *) xalloc (extraLen);
if (!extra)
return BadAlloc;
/*
* First comes the size information
*/
size = (xScreenSizes *) extra;
rates = (CARD16 *) (size + rep.nSizes);
for (i = 0; i < pScrPriv->nSizes; i++)
{
RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
if (pSize->referenced)
{
size->widthInPixels = pSize->width;
size->heightInPixels = pSize->height;
size->widthInMillimeters = pSize->mmWidth;
size->heightInMillimeters = pSize->mmHeight;
if (client->swapped)
{
swaps (&size->widthInPixels, n);
swaps (&size->heightInPixels, n);
swaps (&size->widthInMillimeters, n);
swaps (&size->heightInMillimeters, n);
}
size++;
if (has_rate)
{
*rates = pSize->nRatesInUse;
if (client->swapped)
{
swaps (rates, n);
}
rates++;
for (j = 0; j < pSize->nRates; j++)
{
RRScreenRatePtr pRate = &pSize->pRates[j];
if (pRate->referenced)
{
*rates = pRate->rate;
if (client->swapped)
{
swaps (rates, n);
}
rates++;
}
}
}
}
}
data8 = (CARD8 *) rates;
if (data8 - (CARD8 *) extra != extraLen)
FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n",
(unsigned long)(data8 - (CARD8 *) extra), extraLen);
rep.length = (extraLen + 3) >> 2;
}
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.timestamp, n);
swaps(&rep.rotation, n);
swaps(&rep.nSizes, n);
swaps(&rep.sizeID, n);
swaps(&rep.rate, n);
swaps(&rep.nrateEnts, n);
}
WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
if (extraLen)
{
WriteToClient (client, extraLen, (char *) extra);
xfree (extra);
}
return (client->noClientException);
}
static int
ProcRRSetScreenConfig (ClientPtr client)
{
REQUEST(xRRSetScreenConfigReq);
xRRSetScreenConfigReply rep;
DrawablePtr pDraw;
int n;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
TimeStamp configTime;
TimeStamp time;
RRScreenSizePtr pSize;
int i;
Rotation rotation;
int rate;
short oldWidth, oldHeight;
Bool has_rate;
UpdateCurrentTime ();
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
has_rate = TRUE;
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
has_rate = FALSE;
}
SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client,
SecurityWriteAccess);
pScreen = pDraw->pScreen;
pScrPriv = rrGetScrPriv(pScreen);
time = ClientTimeToServerTime(stuff->timestamp);
configTime = ClientTimeToServerTime(stuff->configTimestamp);
oldWidth = pScreen->width;
oldHeight = pScreen->height;
if (!pScrPriv)
{
time = currentTime;
rep.status = RRSetConfigFailed;
goto sendReply;
}
if (!RRGetInfo (pScreen))
return BadAlloc;
/*
* if the client's config timestamp is not the same as the last config
* timestamp, then the config information isn't up-to-date and
* can't even be validated
*/
if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
{
rep.status = RRSetConfigInvalidConfigTime;
goto sendReply;
}
/*
* Search for the requested size
*/
pSize = 0;
for (i = 0; i < pScrPriv->nSizes; i++)
{
pSize = &pScrPriv->pSizes[i];
if (pSize->referenced && pSize->id == stuff->sizeID)
{
break;
}
}
if (i == pScrPriv->nSizes)
{
/*
* Invalid size ID
*/
client->errorValue = stuff->sizeID;
return BadValue;
}
/*
* Validate requested rotation
*/
rotation = (Rotation) stuff->rotation;
/* test the rotation bits only! */
switch (rotation & 0xf) {
case RR_Rotate_0:
case RR_Rotate_90:
case RR_Rotate_180:
case RR_Rotate_270:
break;
default:
/*
* Invalid rotation
*/
client->errorValue = stuff->rotation;
return BadValue;
}
if ((~pScrPriv->rotations) & rotation)
{
/*
* requested rotation or reflection not supported by screen
*/
client->errorValue = stuff->rotation;
return BadMatch;
}
/*
* Validate requested refresh
*/
if (has_rate)
rate = (int) stuff->rate;
else
rate = 0;
if (rate)
{
for (i = 0; i < pSize->nRates; i++)
{
RRScreenRatePtr pRate = &pSize->pRates[i];
if (pRate->referenced && pRate->rate == rate)
break;
}
if (i == pSize->nRates)
{
/*
* Invalid rate
*/
client->errorValue = rate;
return BadValue;
}
}
/*
* Make sure the requested set-time is not older than
* the last set-time
*/
if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
{
rep.status = RRSetConfigInvalidTime;
goto sendReply;
}
/*
* call out to ddx routine to effect the change
*/
if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
pSize))
{
/*
* unknown DDX failure, report to client
*/
rep.status = RRSetConfigFailed;
goto sendReply;
}
/*
* set current extension configuration pointers
*/
RRSetCurrentConfig (pScreen, rotation, rate, pSize);
/*
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree (pScreen, TellChanged, (pointer) pScreen);
/*
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if (oldWidth != pScreen->width || oldHeight != pScreen->height)
RRSendConfigNotify (pScreen);
RREditConnectionInfo (pScreen);
/*
* Fix pointer bounds and location
*/
ScreenRestructured (pScreen);
pScrPriv->lastSetTime = time;
/*
* Report Success
*/
rep.status = RRSetConfigSuccess;
sendReply:
rep.type = X_Reply;
/* rep.status has already been filled in */
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
if (client->swapped)
{
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.newTimestamp, n);
swapl(&rep.newConfigTimestamp, n);
swapl(&rep.root, n);
}
WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
return (client->noClientException);
}
int
RRSetScreenConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize)
{
rrScrPrivPtr pScrPriv;
int i;
short oldWidth, oldHeight;
pScrPriv = rrGetScrPriv(pScreen);
oldWidth = pScreen->width;
oldHeight = pScreen->height;
if (!RRGetInfo (pScreen))
return BadAlloc;
/*
* Validate requested rotation
*/
/* test the rotation bits only! */
switch (rotation & 0xf) {
case RR_Rotate_0:
case RR_Rotate_90:
case RR_Rotate_180:
case RR_Rotate_270:
break;
default:
/*
* Invalid rotation
*/
return BadValue;
}
if ((~pScrPriv->rotations) & rotation)
{
/*
* requested rotation or reflection not supported by screen
*/
return BadMatch;
}
/*
* Validate requested refresh
*/
if (rate)
{
for (i = 0; i < pSize->nRates; i++)
{
RRScreenRatePtr pRate = &pSize->pRates[i];
if (pRate->referenced && pRate->rate == rate)
break;
}
if (i == pSize->nRates)
{
/*
* Invalid rate
*/
return BadValue;
}
}
/*
* call out to ddx routine to effect the change
*/
if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
pSize))
{
/*
* unknown DDX failure, report to client
*/
return BadImplementation;
}
/*
* set current extension configuration pointers
*/
RRSetCurrentConfig (pScreen, rotation, rate, pSize);
/*
* Deliver ScreenChangeNotify events whenever
* the configuration is updated
*/
WalkTree (pScreen, TellChanged, (pointer) pScreen);
/*
* Deliver ConfigureNotify events when root changes
* pixel size
*/
if (oldWidth != pScreen->width || oldHeight != pScreen->height)
RRSendConfigNotify (pScreen);
RREditConnectionInfo (pScreen);
/*
* Fix pointer bounds and location
*/
ScreenRestructured (pScreen);
return Success;
}
static int
ProcRRSelectInput (ClientPtr client)
{
REQUEST(xRRSelectInputReq);
rrClientPriv(client);
RRTimesPtr pTimes;
WindowPtr pWin;
RREventPtr pRREvent, pNewRREvent, *pHead;
XID clientResource;
REQUEST_SIZE_MATCH(xRRSelectInputReq);
pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess);
if (!pWin)
return BadWindow;
pHead = (RREventPtr *)SecurityLookupIDByType(client,
pWin->drawable.id, EventType,
SecurityWriteAccess);
if (stuff->enable & (RRScreenChangeNotifyMask))
{
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv (pScreen);
if (pHead)
{
/* check for existing entry. */
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
if (pRREvent->client == client)
return Success;
}
/* build the entry */
pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
if (!pNewRREvent)
return BadAlloc;
pNewRREvent->next = 0;
pNewRREvent->client = client;
pNewRREvent->window = pWin;
pNewRREvent->mask = stuff->enable;
/*
* add a resource that will be deleted when
* the client goes away
*/
clientResource = FakeClientID (client->index);
pNewRREvent->clientResource = clientResource;
if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent))
return BadAlloc;
/*
* create a resource to contain a pointer to the list
* of clients selecting input. This must be indirect as
* the list may be arbitrarily rearranged which cannot be
* done through the resource database.
*/
if (!pHead)
{
pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
if (!pHead ||
!AddResource (pWin->drawable.id, EventType, (pointer)pHead))
{
FreeResource (clientResource, RT_NONE);
return BadAlloc;
}
*pHead = 0;
}
pNewRREvent->next = *pHead;
*pHead = pNewRREvent;
/*
* Now see if the client needs an event
*/
if (pScrPriv)
{
pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
if (CompareTimeStamps (pTimes->setTime,
pScrPriv->lastSetTime) != 0 ||
CompareTimeStamps (pTimes->configTime,
pScrPriv->lastConfigTime) != 0)
{
TellChanged (pWin, (pointer) pScreen);
}
}
}
else if (stuff->enable == xFalse)
{
/* delete the interest */
if (pHead) {
pNewRREvent = 0;
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
if (pRREvent->client == client)
break;
pNewRREvent = pRREvent;
}
if (pRREvent) {
FreeResource (pRREvent->clientResource, ClientType);
if (pNewRREvent)
pNewRREvent->next = pRREvent->next;
else
*pHead = pRREvent->next;
xfree (pRREvent);
}
}
}
else
{
client->errorValue = stuff->enable;
return BadValue;
}
return Success;
}
static int
ProcRRDispatch (ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_RRQueryVersion:
return ProcRRQueryVersion(client);
case X_RRSetScreenConfig:
return ProcRRSetScreenConfig(client);
case X_RRSelectInput:
return ProcRRSelectInput(client);
case X_RRGetScreenInfo:
return ProcRRGetScreenInfo(client);
default:
return BadRequest;
}
}
static int
SProcRRQueryVersion (ClientPtr client)
{
register int n;
REQUEST(xRRQueryVersionReq);
swaps(&stuff->length, n);
swapl(&stuff->majorVersion, n);
swapl(&stuff->minorVersion, n);
return ProcRRQueryVersion(client);
}
static int
SProcRRGetScreenInfo (ClientPtr client)
{
register int n;
REQUEST(xRRGetScreenInfoReq);
swaps(&stuff->length, n);
swapl(&stuff->window, n);
return ProcRRGetScreenInfo(client);
}
static int
SProcRRSetScreenConfig (ClientPtr client)
{
register int n;
REQUEST(xRRSetScreenConfigReq);
if (RRClientKnowsRates (client))
{
REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
swaps (&stuff->rate, n);
}
else
{
REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
}
swaps(&stuff->length, n);
swapl(&stuff->drawable, n);
swapl(&stuff->timestamp, n);
swaps(&stuff->sizeID, n);
swaps(&stuff->rotation, n);
return ProcRRSetScreenConfig(client);
}
static int
SProcRRSelectInput (ClientPtr client)
{
register int n;
REQUEST(xRRSelectInputReq);
swaps(&stuff->length, n);
swapl(&stuff->window, n);
return ProcRRSelectInput(client);
}
static int
SProcRRDispatch (ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_RRQueryVersion:
return SProcRRQueryVersion(client);
case X_RRSetScreenConfig:
return SProcRRSetScreenConfig(client);
case X_RRSelectInput:
return SProcRRSelectInput(client);
case X_RRGetScreenInfo:
return SProcRRGetScreenInfo(client);
default:
return BadRequest;
}
}
static Bool
RRScreenSizeMatches (RRScreenSizePtr a,
RRScreenSizePtr b)
{
if (a->width != b->width)
return FALSE;
if (a->height != b->height)
return FALSE;
if (a->mmWidth != b->mmWidth)
return FALSE;
if (a->mmHeight != b->mmHeight)
return FALSE;
return TRUE;
}
RRScreenSizePtr
RRRegisterSize (ScreenPtr pScreen,
short width,
short height,
short mmWidth,
short mmHeight)
{
rrScrPriv (pScreen);
int i;
RRScreenSize tmp;
RRScreenSizePtr pNew;
if (!pScrPriv)
return 0;
tmp.width = width;
tmp.height= height;
tmp.mmWidth = mmWidth;
tmp.mmHeight = mmHeight;
tmp.pRates = 0;
tmp.nRates = 0;
tmp.nRatesInUse = 0;
tmp.referenced = TRUE;
tmp.oldReferenced = FALSE;
for (i = 0; i < pScrPriv->nSizes; i++)
if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
{
pScrPriv->pSizes[i].referenced = TRUE;
return &pScrPriv->pSizes[i];
}
pNew = xrealloc (pScrPriv->pSizes,
(pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
if (!pNew)
return 0;
pNew[pScrPriv->nSizes++] = tmp;
pScrPriv->pSizes = pNew;
return &pNew[pScrPriv->nSizes-1];
}
Bool RRRegisterRate (ScreenPtr pScreen,
RRScreenSizePtr pSize,
int rate)
{
rrScrPriv(pScreen);
int i;
RRScreenRatePtr pNew, pRate;
if (!pScrPriv)
return FALSE;
for (i = 0; i < pSize->nRates; i++)
{
pRate = &pSize->pRates[i];
if (pRate->rate == rate)
{
pRate->referenced = TRUE;
return TRUE;
}
}
pNew = xrealloc (pSize->pRates,
(pSize->nRates + 1) * sizeof (RRScreenRate));
if (!pNew)
return FALSE;
pRate = &pNew[pSize->nRates++];
pRate->rate = rate;
pRate->referenced = TRUE;
pRate->oldReferenced = FALSE;
pSize->pRates = pNew;
return TRUE;
}
void
RRSetCurrentConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize)
{
rrScrPriv (pScreen);
if (!pScrPriv)
return;
pScrPriv->rotation = rotation;
pScrPriv->size = pSize - pScrPriv->pSizes;
pScrPriv->rate = rate;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment