diff options
Diffstat (limited to 'xorg-server/hw')
61 files changed, 11482 insertions, 11461 deletions
diff --git a/xorg-server/hw/dmx/config/Makefile.am b/xorg-server/hw/dmx/config/Makefile.am index de4ce315d..75181436e 100644 --- a/xorg-server/hw/dmx/config/Makefile.am +++ b/xorg-server/hw/dmx/config/Makefile.am @@ -22,6 +22,10 @@ MAINTAINERCLEANFILES = $(BUILT_SOURCES) libdmxconfig_a_SOURCES = $(LIBSRCS) +if NEED_STRLCAT +libdmxconfig_a_SOURCES += $(top_srcdir)/os/strlcpy.c +endif + if GLX GLX_DEFS = @GL_CFLAGS@ endif diff --git a/xorg-server/hw/dmx/config/dmxcompat.c b/xorg-server/hw/dmx/config/dmxcompat.c index b4190ffcc..1c72084fa 100644 --- a/xorg-server/hw/dmx/config/dmxcompat.c +++ b/xorg-server/hw/dmx/config/dmxcompat.c @@ -42,6 +42,7 @@ #include <dmx-config.h> #endif +#include "os.h" #include "dmxconfig.h" #include "dmxparse.h" #include "dmxcompat.h" @@ -94,8 +95,7 @@ static void dmxVDLDisplayEntry(const char *buf, char *end; pt = strchr(buf, ' '); - strncpy(name, buf, pt-buf); - name[pt-buf] = '\0'; + strlcpy(name, buf, 1+pt-buf); *len = strlen(name); *x = strtol(pt, &end, 10); diff --git a/xorg-server/hw/dmx/config/scanner.l b/xorg-server/hw/dmx/config/scanner.l index cef99d088..e527d6df5 100644 --- a/xorg-server/hw/dmx/config/scanner.l +++ b/xorg-server/hw/dmx/config/scanner.l @@ -39,6 +39,7 @@ #include "dmxparse.h" #include "parser.h" +#include "os.h" #include <string.h> #include <stdlib.h> #include <ctype.h> @@ -152,7 +153,7 @@ static int getdimension(int token, const char *text, int leng) char *tmp = dmxConfigAlloc(leng+1); int x, y; - strncpy(tmp, text, leng); + strlcpy(tmp, text, leng+1); x = strtol(tmp, &endptr, 10); while (*endptr && !isdigit(*endptr)) ++endptr; y = strtol(endptr, NULL, 10); diff --git a/xorg-server/hw/dmx/dmxinit.c b/xorg-server/hw/dmx/dmxinit.c index 359ba9f2f..99223caa8 100644 --- a/xorg-server/hw/dmx/dmxinit.c +++ b/xorg-server/hw/dmx/dmxinit.c @@ -138,7 +138,7 @@ static int dmxErrorHandler(Display *dpy, XErrorEvent *ev) for (ext = dpy->ext_procs; ext && ext->codes.major_opcode != ev->request_code; ext = ext->next); - if (ext) strncpy(buf, ext->name, sizeof(buf)); + if (ext) strlcpy(buf, ext->name, sizeof(buf)); else buf[0] = '\0'; } dmxLog(dmxWarning, " Major opcode: %d (%s)\n", @@ -800,20 +800,17 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[]) /* RATS: Assuming the fp string (which comes from the command-line argv vector) is NULL-terminated, the buffer is large enough for the strcpy. */ -static void dmxSetDefaultFontPath(char *fp) +static void dmxSetDefaultFontPath(const char *fp) { - int fplen = strlen(fp) + 1; - if (dmxFontPath) { - int len; + int fplen = strlen(fp) + 1; + int len = strlen(dmxFontPath); - len = strlen(dmxFontPath); dmxFontPath = realloc(dmxFontPath, len+fplen+1); dmxFontPath[len] = ','; strncpy(&dmxFontPath[len+1], fp, fplen); } else { - dmxFontPath = malloc(fplen); - strncpy(dmxFontPath, fp, fplen); + dmxFontPath = strdup(fp); } defaultFontPath = dmxFontPath; diff --git a/xorg-server/hw/dmx/doc/dmx.xml b/xorg-server/hw/dmx/doc/dmx.xml index 845eec97a..793aacea0 100644 --- a/xorg-server/hw/dmx/doc/dmx.xml +++ b/xorg-server/hw/dmx/doc/dmx.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ + <!ENTITY % defs SYSTEM "/xserver/doc/xml/xserver.ent"> %defs; ]> <article> @@ -14,6 +15,7 @@ <author><firstname>Rickard E.</firstname><surname>Faith</surname></author> </authorgroup> <pubdate>29 June 2004 (created 25 July 2001)</pubdate> + <releaseinfo>X Server Version &xserver.version;</releaseinfo> <abstract><para> This document covers the motivation, background, design, and implementation of the distributed multihead X (DMX) system. It diff --git a/xorg-server/hw/dmx/doc/scaled.xml b/xorg-server/hw/dmx/doc/scaled.xml index 575cafd9d..30c9b9f50 100644 --- a/xorg-server/hw/dmx/doc/scaled.xml +++ b/xorg-server/hw/dmx/doc/scaled.xml @@ -1,725 +1,727 @@ -<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
- "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
-]>
- <article>
-
- <articleinfo>
- <!-- Title information -->
- <title>Scaled Window Support in DMX</title>
- <authorgroup>
- <author><firstname>Kevin E.</firstname><surname>Martin</surname></author>
- <author><firstname>Rickard E.</firstname><surname>Faith</surname></author>
- </authorgroup>
- <pubdate>15 October 2003 (created 19 September 2003)</pubdate>
- <abstract>
- <para>
- This document investigates the possibility of adding scaled window
- support to the DMX X server, thereby allowing a window or some
- selected part of the logical DMX area to be displayed using a
- scaling factor. For example, this might allow the contents of a
- window to be magnified for easier viewing. In particular, scaling
- for the VNC client is explored. <emphasis remap="it">Copyright 2003
- by Red Hat, Inc., Raleigh, North Carolina</emphasis>
- </para>
- </abstract>
- </articleinfo>
-
- <!-- Begin the document -->
- <sect1><title>Introduction</title>
- <sect2><title>DMX</title>
- <para>
- The DMX X server (Xdmx) is a proxy server that is designed
- to allow X servers on multiple machines to be combined into
- a single multi-headed X server. Combined with Xinerama,
- these heads can appear as a single very high-resolution
- screen. Typical applications include the creation of a
- video wall with 16 1280x1024 displays arranged in a
- rectangle, for a total resolution of of 5120x4096.
- </para>
- </sect2>
- <sect2><title>Problem Statement</title>
- <para>
- Applications displayed on a physically large video wall that
- provides high pixel-resolution may be difficult to see,
- especially if the application is designed for use on a
- typical desktop computer with a relatively small display
- located close to the human operator. The goal of this paper
- is to describe and discuss solutions to this problem.
- </para>
- <para>
- The original driving problem for this work is to provide
- scaling for the <command>vncviewer</command> application when
- displayed using DMX (VNC scaling is currently available only
- with the Windows client, and there is no plan to extend that
- capability to other clients). While this specific problem
- will be addressed in this paper, the general solution space
- will also be explored, since this may lead to a good
- solution not only for <command>vncviewer</command> but also for
- other applications.
- </para>
- </sect2>
- <sect2><title>Task</title>
- <para>
- For reference, here is the original description of the task
- this paper addresses:
- <itemizedlist>
- <listitem><para>Scaled window support (for VNC)
- <itemizedlist>
- <listitem><para>
- Investigate possibility of implementing a "scaled
- window" extension:
- <itemizedlist>
- <listitem><para>
- Add XCreateScaledWindow call that could be used
- in place of XCreateWindow
- </para></listitem>
- <listitem><para>
- All primitives drawn to scaled window would be
- scaled by appropriate (integral?) scaling factor
- </para></listitem>
- </itemizedlist>
- </para></listitem>
- <listitem><para>
- Alternate approach: special case VNC support
- </para></listitem>
- </itemizedlist>
- </para></listitem>
- </itemizedlist>
- </para>
- </sect2>
- </sect1>
-
- <sect1><title>Previous Work</title>
- <para>
- This section reviews relevant previous work.
- </para>
- <sect2><title>VNC</title>
- <sect3><title>Scaling under VNC</title>
- <para>
- When using the <command>vncviewer</command> program for Windows, it
- is possible to specify a scaling factor (as numerator and
- denominator). When scaling is in effect, the viewer
- software uses StretchBlt (instead of BitBlt) to display
- the pixels for the user. When this call is made, the
- viewer already has received all of the pixel information
- (at full unscaled resolution).
- </para>
- <para>
- The scaling in VNC is primitive. It does not conserve
- bandwidth, it does not treat textual information
- differently (i.e., by using a suitably scaled font), and
- it does not provide any anti-aliasing other than that
- provided by the underlying (Windows-only) system library.
- </para>
- </sect3>
- </sect2>
- <sect2><title>The X Video Extension</title>
- <para>
- The X Video Extension is a widely-available extension to the
- X11 protocol that provides support for streaming video.
- Integral to this support is the ability to arbitrarily scale
- the output. In version 2.2 of the X Video specification,
- support for scaled still images was provided, using both
- shared memory and traditional transport. The API for this
- support uses calls that are quite similar to XCreateWindow,
- XPutImage, and XShmPutImage. Currently, most of the drivers
- implemented in XFree86 only support data in various YUV
- formats. However, several modern video adaptors support RGB
- as well.
- </para>
- <para>
- Note, though, that the target output for this scaling is an
- overlay plane -- so X Video provides functionality that is
- fundamentally different from that provided by the Windows
- StrechBlt call.
- </para>
- </sect2>
- </sect1>
-
- <sect1><title>Possible Solutions</title>
- <para>
- This section briefly discusses possible solutions, including
- major advantages and disadvantages from both the
- implementation and the end-user programmer standpoint.
- </para>
- <sect2><title>VNC-like Scaling</title>
- <sect3><title>Software Scaling</title>
- <para>
- The <command>vncviewer</command> application could be modified to
- provide software scaling. This is not a general solution,
- but it does solve one of the goals of this work.
- </para>
- <para>
- A prototype of this solution was implemented and a patch
- against <filename>vnc-3.3.7-unixsrc</filename> is available in the
- <filename>dmx/external</filename> directory. Because of limited time
- available for this work, all of the edge cases were not
- considered and the solution works well mainly for integer
- scaling.
- </para>
- <para>
- Currently, <command>vncviewer</command> writes to the X display
- with XPutImage, XCopyArea, and XFillRectangle. All
- instances of these calls have to be aware of scaling
- and must round correctly. In the prototype solution,
- rounding is incorrect and can cause artifacts.
- </para>
- <para>
- A better solution would be to cache all updates to the
- desktop image in <command>vncviewer</command> and only send the
- damaged area to the X display with XPutImage. This would
- allow the damaged area to be computed so that rounding
- errors do not create artifacts. This method is probably
- similar to what is used in the Window client. (The whole
- VNC suite is being re-written in C++ and the forthcoming
- version 4 has not been evaluated.)
- </para>
- </sect3>
- <sect3><title>Scaling with the X Video Extension</title>
- <para>
- The scaling in the Windows <command>vncviewer</command> application
- makes use of a scaled blit that is supplied by the
- underlying system library. Several video cards currently
- provide support for a scaled blit, and some X servers
- (including XFree86) expose this capability to applications
- via the XvPutImage interface of the X Video Extension.
- The capability exposed by XvPutImage results in the scaled
- image being drawn to an overlay plane. Most video cards
- also provide support for a scaled blit into the normal
- output planes, but this is not exposed via XvPutImage.
- </para>
- <para>
- The <command>vncviewer</command> program could be modified to use
- the X Video Extension to provide scaling under X11 that is
- similar to the scaling currently provided under Windows.
- Unfortunately, Xdmx does not currently export the X Video
- Extension, so this would not provide an immediate solution
- usable with DMX.
- </para>
- <para>
- A very early-stage proof-of-concept prototype was
- implemented and a preliminary patch against
- <filename>vnc-3.3.7-unixsrc</filename> is available in the
- <filename>dmx/external</filename> directory. This prototype was
- implemented to better understand the problems that must be
- solved to make this solution viable:
- <itemizedlist>
- <listitem><para>
- As noted under the software scaling section above,
- <command>vncviewer</command> writes to the X display with
- several different calls. These calls write to the
- normal output planes and are compatible with
- XvPutImage, which writes to an overlay plane. To
- eliminate artifacts caused by this problem,
- <command>vncviewer</command> should be modified so that a cached
- copy of the desktop is available, either as a
- client-side image or a server-side off-screen pixmap,
- so that XvPutImage would be the only method for
- writing to the X display.
- </para></listitem>
- <listitem>
- <para>
- Although several modern graphics adaptors support
- hardware scaling using an RGB format (e.g., ATI
- Radeon, nVidia, etc.), XFree86 drivers typically
- only implement YUV formats. YUV generally compress
- the pixel information in some way. For example, two
- commonly implemented formats, YUY2 and UYVY provide
- intensity information for every RGB pixel, but only
- provide chroma and luminance information for pairs
- of horizontal pixels. Since VNC uses
- pixel-resolution for communicating updates on the
- wire, additional artifacts are introduced (because
- there may not be enough information from the wire to
- update a pair of pixels).
- </para>
- <para>
- Further, the well-known problem with YUV encoding
- is even more evident when the image is a desktop
- instead of a movie. For example, consider a
- 1-pixel-wide vertical window border. If the border
- changes in color but not intensity (e.g., because a
- window manager uses color to indicate focus), there
- may or may not be a change in the YUY2 image,
- depending on the algorithm used for RGB to YUV
- conversion and on how the border pixel is ordered in
- the pair of pixels used by the algorithm.
- </para>
- <para>
- Many of these artifacts could be eliminated if
- <command>vncviewer</command> cached a complete RGB image of
- the desktop, and only did the conversion to YUV for
- properly aligned areas of damage. The remaining artifacts
- could be eliminated if an RGB format was used with X
- Video (which may require the extension of existing
- XFree86 drivers to support RGB).
- </para>
- </listitem>
- <listitem><para>
- Most modern video cards support exactly one overlay
- plane that is suitable for use with X Video.
- Therefore, only one application can use X Video at any
- given time. This is a severe limitation in a desktop
- environment.
- </para></listitem>
- </itemizedlist>
- </para>
- <sect4><title>Implementing the X Video Extension for DMX</title>
- <para>
- The user-level API for X Video is fairly simple, but the
- underlying support required for the full specification
- is large. However, since the API provides a method to
- query supported capabilities, a usable subset of X
- Video can be implemented that would support XvPutImage
- and little else. This would require support for the
- following:
- <itemizedlist>
- <listitem><para>
- X Video Extension API calls, including the
- following:
- <itemizedlist>
- <listitem><para>XvQueryExtension</para></listitem>
- <listitem><para>XvQueryAdaptors</para></listitem>
- <listitem><para>XvQueryPortAttributes</para></listitem>
- <listitem><para>XvFreeAdaptorInfo</para></listitem>
- <listitem><para>XvListImageFormats</para></listitem>
- <listitem><para>XvGrabPort</para></listitem>
- <listitem><para>XvCreateImage</para></listitem>
- <listitem><para>XvPutImage</para></listitem>
- <listitem><para>XvShmCreateImage</para></listitem>
- <listitem><para>XvShmPutImage</para></listitem>
- </itemizedlist>
- </para></listitem>
- <listitem><para>
- Support for querying back-end X Video Extension
- capabilities.
- </para></listitem>
- <listitem><para>
- Support for sending the image to the back-ends.
- Because X Video requires sending full images, there
- may be a trade-off between bandwidth limitations and
- additional complexity to divide the image up such
- that is scales properly.
- </para></listitem>
- <listitem><para>
- Possible support for a software fall-back. For
- example, if all of the back-ends do not support the X
- Video Extension, software scaling can be implemented
- such that the image is sent to the back-end with
- XPutImage. This pathway would have poor
- performance.
- </para></listitem>
- </itemizedlist>
- </para>
- </sect4>
- <sect4><title>Supporting RGB formats for the X Video Extension</title>
- <para>
- Assuming an XFree86 driver already supports the X Video
- Extension, and assuming the target hardware supports an
- RGB format, then adding support for that format is
- relatively simple and straightforward.
- </para>
- </sect4>
- </sect3>
- <sect3><title>Scaling with an XPutImageScaled Extension</title>
- <para>
- Instead of (or in addition to) implementing the X Video
- Extension in DMX, one obvious solution would be to
- implement a new extension that provides access to
- hardware-assisted scaled blits, similar to the StretchBlt
- call available under Windows. This call would scale RGB
- images and would not use the overlay plane (unlike the X
- Video Extension).
- </para>
- <para>
- This approach has many of the same advantages and
- disadvantages as the XCopyAreaScaled Extension, discussed
- in the next section. Discussion of XPutImageScaled is
- deferred in favor of XCopyAreaScaled for the following
- reasons:
- <itemizedlist>
- <listitem><para>
- XPutImageScaled can be emulated with XCopyAreaScaled
- by first using XPutImage to copy the image to an
- off-screen pixmap, and then calling XCopyAreaScaled
- between that off-screen pixmap and the target
- drawable.
- </para></listitem>
- <listitem><para>
- Since XCopyAreaScaled would copy between two areas of
- on-screen or off-screen memory, it has additional uses
- and can be viewed as efficiently providing a superset
- of XPutImageScaled functionality.
- </para></listitem>
- </itemizedlist>
- </para>
- </sect3>
- <sect3><title>Scaling with an XCopyAreaScaled Extension</title>
- <para>
- As noted in the previous section, because XCopyAreaScaled
- provides a superset of the functionality provided by
- XPutImageScaled, we will consider this extension instead.
- </para>
- <para>
- First, XCopyAreaScaled would provide for RGB scaling
- between pixmaps (i.e., on-screen or off-screen areas of
- memory that reside on the video card). Unlike the X Video
- Extension, which writes into an overlay plane,
- XCopyAreaScaled would write into the non-overlay areas of
- the screen. Key points to consider are as follows:
- <itemizedlist>
- <listitem><para>
- Because different planes are involved, the two scaling
- operations are usually implemented in hardware
- differently, so an XCopyAreaScaled extension could be
- added in a manner that would neither conflict with nor
- interact with the X Video extension in any way.
- </para></listitem>
- <listitem><para>
- The XCopyAreaScaled extension provides new
- functionality that the X Video Extension does not
- provide. Based on anecdotal feedback, we believe that
- many people outside the DMX and VNC communities would
- be excited about this extension.
- </para></listitem>
- <listitem><para>
- The main drawback to this extension is that it is new
- and needs to be implemented at the driver level in
- XFree86 for each video card to be supported. At the
- present time, it is more likely that the X Video
- Extension will be implemented for a particular piece
- hardware because the X Video extension has multimedia
- uses. However, over time, we would expect the
- XCopyAreaScaled extension to be implemented along with
- the X Video extension, especially if it becomes
- popular.
- </para></listitem>
- <listitem><para>
- Another drawback is that not all modern cards provide
- support for a simple scaled blit operation. However,
- these cards usually do provide a 3D pipeline which
- could be used to provide this functionality in a
- manner that is transparent to the client application
- that is using the XCopyAreaScaled extension. However,
- this implementation pathway would make this extension
- somewhat more difficult to implement on certain cards.
- </para></listitem>
- </itemizedlist>
- </para>
- </sect3>
- <sect3><title>Scaling with OpenGL</title>
- <para>
- Another general solution to the scaling problem is to use
- the texture scaling found in all 3D hardware. This
- ability is already exposed through OpenGL and can be
- exploited by clients without X server modification (i.e.,
- other than the ability to support OpenGL). An application
- using OpenGL would transmit the non-scaled image to the X
- server as a texture, and would then display a single
- non-transformed rect using that texture. This also works
- around the single overlay problem with the X Video
- Extension as well as the need to implement additional
- scaled primitive extensions.
- </para>
- <para>
- The downside is that most OpenGL implementations require
- power of 2 texture sizes and this can be very wasteful of
- memory if, for example, the application needs to scale a
- 1025x1025 image, which would require a 2048x2048 texture
- area (even a 640x480 image would require a 1024x512
- texture). Another downside is that some OpenGL
- implementations have a limited about of texture memory and
- cannot handle textures that are very large. For example,
- they might limit the texture size to 1024x1024.
- </para>
- </sect3>
- </sect2>
- <sect2><title>Application-transparent Scaling for DMX
- </title><sect3><title>Back-end Scaling Without Disconnect/Reconnect</title>
- <para>
- VNC does scaling on the client side (in the
- <command>vncviewer</command> application). Implementing a similar
- solution for DMX would require support in the back-end X
- servers and, therefore, is not a general solution.
- </para>
- <para>
- XFree86 already implements some support for "scaling" that
- could be used with DMX: if, in the XF86Config file,
- multiple Modes are listed in the Display Subsection of the
- Screen Section, then pressing Ctrl-Alt-Plus and
- Ctrl-Alt-Minus can be used to iterate through the listed
- modes. The display dimensions will change to the
- dimensions in the Modes line, but the logical dimensions
- of the X server (i.e., the dimensions that Xdmx knows
- about) will not change.
- </para>
- <para>
- Further, the dimensions of the XFree86 display are under
- software control (via the XFree86-VidModeExtension), so
- the Xdmx server could change the screen dimensions on a
- per-display basis, thereby scaling the information on part
- of that display.
- </para>
- <para>
- However, this scaling appears to have limited use. For
- example, assume a 4 by 4 display wall consisting of 16
- 1280x1024 displays. If all of the back-end servers were
- simultaneously configured to display 640x480, the left
- hand corner of each display would be magnified, but the
- composite result would be unreadable. Magnifying one
- display at a time could be usable, but could have limited
- utility, since the result would still be no larger than a
- single display.
- </para>
- </sect3>
- <sect3><title>Back-end Scaling With Disconnect/Reconnect</title>
- <para>
- Disconnect and reconnect features are not currently
- supported in DMX, but are scheduled to be implemented in
- the future. These features, combined with the
- XFree86-VidModeExtension Extension, would allow an
- application to do the following:
- <itemizedlist>
- <listitem><para>
- Disconnect a specific back-end server (via the DMX
- Extension),
- </para></listitem>
- <listitem><para>
- reconfigure the XFree86 back-end server resolution,
- and
- </para></listitem>
- <listitem><para>
- reconnect the back-end server to DMX -- at a new
- origin with the new screen resolution.
- </para></listitem>
- </itemizedlist>
- </para>
- <para>
- For example, consider a display wall consisting of 16
- 1280x1024 displays with a total resolution of 5120x4096.
- All of the screens could be disconnected, repositioned,
- and reconnected each at a resolution of 640x480. The
- total resolution of the display wall would be 2560x1920,
- allowing a view of a selected area approximately
- one-fourth of the size of the DMX display. This change
- would be completely application independent (except,
- perhaps, for a DMX-aware window manager). When work at
- the increased resolution was completed, the back-end
- servers could be disconnected, reconfigured, and
- reconnected for the original 5120x4096 view.
- </para>
- <para>
- Support for this type of scaling can be implemented in a
- DMX-aware X11 client assuming the DMX server support
- arbitrary disconnect and reconnect semantics. Because
- this application cannot be written before
- disconnect/reconnect is implemented, this solution will
- not be discussed further in this paper.
- </para>
- </sect3>
- <sect3><title>Server-side Scaling</title>
- <para>
- In earlier versions of DMX, a frame buffer was maintained
- on the server side, and XPutImage was used to move the
- information from the server to the client (similar to some
- early VNC implementations). The use of a server-side
- frame buffer would allow the server to do scaling, but is
- not a recommended solution because of overall performance
- issues and server-side memory issues (i.e., the frame
- buffer would be very large for large display walls).
- </para>
- <para>
- Exploration of this path is not recommended.
- </para>
- </sect3>
- </sect2>
- <sect2><title>XCreateScaledWindow API</title>
- <para>
- The implementation of X Video Extension in DMX, and the use
- of XvPutImage by applications requiring scaling requires
- significant changes in DMX Further, XvPutImage is,
- essentially a scaled blit, and it is only useful for
- applications which are already using (or can be modified to
- use) XPutImage. Therefore, a more general API will be
- discussed as another possibility.
- </para>
- <para>
- X applications typically create windows with the
- XCreateWindow call. A new extension could provide an
- XCreateScaledWindow call that could be used in place of the
- XCreateWindow call and be otherwise transparent to the
- application. This would allow applications, even those that
- do not depend on XPutImage, to take advantage of window
- scaling. In this section we describe how the call would
- work, what transparency it provides, and how to solve the
- potential problems that transparency creates.
- </para>
- <sect3><title>XCreateWindow</title>
- <para>
- The XCreateWindow call takes width and height as
- parameters. An XCreateScaledWindow call could take all
- the same parameters, with the addition of a scaling factor.
- </para>
- </sect3>
- <sect3><title>XSetWindowAttributes</title>
- <para>
- An X11 window has several attributes that would have to be
- scaled:
- <itemizedlist>
- <listitem><para>Background and border pixmaps</para></listitem>
- <listitem><para>Border width</para></listitem>
- <listitem><para>Cursor</para></listitem>
- </itemizedlist>
- </para>
- </sect3>
- <sect3><title>XGetWindowAttributes, XGetGeometry</title>
- <para>
- For transparency, calls that query the window attributes
- should return unscaled information. This suggests that
- all unscaled pixmaps and window attributes should be
- cached.
- </para>
- <para>
- Unfortunately, a window manager requires the scaled
- geometry to properly decorate the window. The X server
- can probably determine which client is acting as the
- window manager (e.g., because that client will select
- events that are used exclusively by the window manager).
- However, other Scaled Window Extension aware clients may
- also need to determine the scaled geometry. Therefore, at
- least two additional extension calls should be
- implemented: XGetScaledWindowAttributes and
- XGetScaledGeometry.
- </para>
- </sect3>
- <sect3><title>Popup and Child window positions</title>
- <para>
- Some applications may position popup and child windows
- based on an unscaled notion of the main window geometry.
- In this case, additional modifications to the client would
- be required.
- </para>
- </sect3>
- <sect3><title>Events</title>
- <para>
- Most events (e.g., for mouse motion) return information
- about the coordinates at which the even occurred. These
- coordinates would have to be modified so that unscaled
- values were presented to the client.
- </para>
- </sect3>
- <sect3><title>Implementation</title>
- <para>
- There are many implementation issues, some of which are
- similar to the issues involved in implementing the X Video
- Extension for DMX. The window contents must be scaled,
- either by performing all operations to a frame buffer and
- then writing the image to the display (perhaps using
- hardware scaling support), or by modifying all of the
- various drawing operations to perform scaling. Because of
- the complexity involved, the frame buffer option is
- recommended.
- </para>
- </sect3>
- </sect2>
- </sect1>
-
- <sect1><title>Conclusion and Recommendations
- </title><para>
- We recommend a three phase implementation strategy, based on
- how an application could be written to take advantage of
- scaling:
- <orderedlist>
- <listitem>
- <para>
- The XCopyAreaScaled extension should be implemented, since
- this is the ideal solution for applications like VNC, and
- since making use of this extension will require minimal
- changes to applications that already use XPutImage or
- XCopyArea.
- </para>
- <para>
- The initial implementation work would include the design
- of the X protocol extension, writing this up in the
- usual format for extension documentation, implementation
- of the protocol transport pieces in XFree86,
- implementation of a software fall-back in XFree86 and
- DMX, one example hardware implementation for XFree86,
- and implementation of support for this extension in DMX.
- </para>
- <para>
- We suggest implementing the extension first on the ATI
- Radeon cards. However, since these cards do not provide
- a 2D scaled blit primitive, the implementation would
- have to make use of the 3D texture engine to emulate a
- scaled blit. This is recommended, since other modern
- graphics cards also do not provide a simple 2D scaled
- blit operation and an example of the more difficult
- implementation pathway would be helpful to others.
- </para>
- </listitem>
- <listitem>
- <para>
- Until XCopyAreaScaled is widely supported, applications
- that require scaling will have to fall back to another
- scaling method. We suggest OpenGL as the first fall-back
- method because it is widely available and supported by
- DMX.
- </para>
- <para>
- A project centered around OpenGL-based scaling would
- implement this scaling in VNC as an example. This work
- would include re-writing the <command>vncviewer</command>
- rendering engine to cache a master copy of the desktop
- image for all operations.
- </para>
- </listitem>
- <listitem>
- <para>
- Since OpenGL is not implemented everywhere, and may not
- provide hardware-assisted performance in every
- implementation, an application that requires scaling
- should also fall back to using the X Video Extension.
- </para>
- <para>
- This project would add support for the X Video Extension
- to DMX and would add support to VNC to take advantage of
- this extension without introducing artifacts. This
- would require modifying the <command>vncviewer</command> rendering
- engine to cache a master copy of the desktop image for
- all operations. This project should also add support
- for the RGB format to at least one XFree86 driver (e.g.,
- ATI Radeon).
- </para>
- <para>
- The X Video Extension is one of the few popular
- extensions that DMX does not support. We recommend
- implementing the X Video Extension even if scaling is
- the specific goal of that work.
- </para>
- </listitem>
- </orderedlist>
- </para>
- <para>
- We do <emphasis>not</emphasis> recommend implementation of the
- XCreateScaledWindow extension because of the complexity
- involved. We do <emphasis>not</emphasis> recommend implementation of the
- XPutImageScaled extension because it requires the same amount
- of work as the XCopyAreaScaled extension, but provides less
- functionality. Further, server-side scaling with a large
- frame buffer is <emphasis>not</emphasis> recommended because of the
- performance implications.
- </para>
- <para>
- The back-end scaling, especially with disconnect/reconnect
- support should be explored in the future after
- disconnect/reconnect is implemented, but not at the present
- time.
- </para>
- </sect1>
-
- </article>
- <!-- Local Variables: -->
- <!-- fill-column: 72 -->
- <!-- End: -->
+<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ + <!ENTITY % defs SYSTEM "/xserver/doc/xml/xserver.ent"> %defs; +]> + <article> + + <articleinfo> + <!-- Title information --> + <title>Scaled Window Support in DMX</title> + <authorgroup> + <author><firstname>Kevin E.</firstname><surname>Martin</surname></author> + <author><firstname>Rickard E.</firstname><surname>Faith</surname></author> + </authorgroup> + <pubdate>15 October 2003 (created 19 September 2003)</pubdate> + <releaseinfo>X Server Version &xserver.version;</releaseinfo> + <abstract> + <para> + This document investigates the possibility of adding scaled window + support to the DMX X server, thereby allowing a window or some + selected part of the logical DMX area to be displayed using a + scaling factor. For example, this might allow the contents of a + window to be magnified for easier viewing. In particular, scaling + for the VNC client is explored. <emphasis remap="it">Copyright 2003 + by Red Hat, Inc., Raleigh, North Carolina</emphasis> + </para> + </abstract> + </articleinfo> + + <!-- Begin the document --> + <sect1><title>Introduction</title> + <sect2><title>DMX</title> + <para> + The DMX X server (Xdmx) is a proxy server that is designed + to allow X servers on multiple machines to be combined into + a single multi-headed X server. Combined with Xinerama, + these heads can appear as a single very high-resolution + screen. Typical applications include the creation of a + video wall with 16 1280x1024 displays arranged in a + rectangle, for a total resolution of of 5120x4096. + </para> + </sect2> + <sect2><title>Problem Statement</title> + <para> + Applications displayed on a physically large video wall that + provides high pixel-resolution may be difficult to see, + especially if the application is designed for use on a + typical desktop computer with a relatively small display + located close to the human operator. The goal of this paper + is to describe and discuss solutions to this problem. + </para> + <para> + The original driving problem for this work is to provide + scaling for the <command>vncviewer</command> application when + displayed using DMX (VNC scaling is currently available only + with the Windows client, and there is no plan to extend that + capability to other clients). While this specific problem + will be addressed in this paper, the general solution space + will also be explored, since this may lead to a good + solution not only for <command>vncviewer</command> but also for + other applications. + </para> + </sect2> + <sect2><title>Task</title> + <para> + For reference, here is the original description of the task + this paper addresses: + <itemizedlist> + <listitem><para>Scaled window support (for VNC) + <itemizedlist> + <listitem><para> + Investigate possibility of implementing a "scaled + window" extension: + <itemizedlist> + <listitem><para> + Add XCreateScaledWindow call that could be used + in place of XCreateWindow + </para></listitem> + <listitem><para> + All primitives drawn to scaled window would be + scaled by appropriate (integral?) scaling factor + </para></listitem> + </itemizedlist> + </para></listitem> + <listitem><para> + Alternate approach: special case VNC support + </para></listitem> + </itemizedlist> + </para></listitem> + </itemizedlist> + </para> + </sect2> + </sect1> + + <sect1><title>Previous Work</title> + <para> + This section reviews relevant previous work. + </para> + <sect2><title>VNC</title> + <sect3><title>Scaling under VNC</title> + <para> + When using the <command>vncviewer</command> program for Windows, it + is possible to specify a scaling factor (as numerator and + denominator). When scaling is in effect, the viewer + software uses StretchBlt (instead of BitBlt) to display + the pixels for the user. When this call is made, the + viewer already has received all of the pixel information + (at full unscaled resolution). + </para> + <para> + The scaling in VNC is primitive. It does not conserve + bandwidth, it does not treat textual information + differently (i.e., by using a suitably scaled font), and + it does not provide any anti-aliasing other than that + provided by the underlying (Windows-only) system library. + </para> + </sect3> + </sect2> + <sect2><title>The X Video Extension</title> + <para> + The X Video Extension is a widely-available extension to the + X11 protocol that provides support for streaming video. + Integral to this support is the ability to arbitrarily scale + the output. In version 2.2 of the X Video specification, + support for scaled still images was provided, using both + shared memory and traditional transport. The API for this + support uses calls that are quite similar to XCreateWindow, + XPutImage, and XShmPutImage. Currently, most of the drivers + implemented in XFree86 only support data in various YUV + formats. However, several modern video adaptors support RGB + as well. + </para> + <para> + Note, though, that the target output for this scaling is an + overlay plane -- so X Video provides functionality that is + fundamentally different from that provided by the Windows + StrechBlt call. + </para> + </sect2> + </sect1> + + <sect1><title>Possible Solutions</title> + <para> + This section briefly discusses possible solutions, including + major advantages and disadvantages from both the + implementation and the end-user programmer standpoint. + </para> + <sect2><title>VNC-like Scaling</title> + <sect3><title>Software Scaling</title> + <para> + The <command>vncviewer</command> application could be modified to + provide software scaling. This is not a general solution, + but it does solve one of the goals of this work. + </para> + <para> + A prototype of this solution was implemented and a patch + against <filename>vnc-3.3.7-unixsrc</filename> is available in the + <filename>dmx/external</filename> directory. Because of limited time + available for this work, all of the edge cases were not + considered and the solution works well mainly for integer + scaling. + </para> + <para> + Currently, <command>vncviewer</command> writes to the X display + with XPutImage, XCopyArea, and XFillRectangle. All + instances of these calls have to be aware of scaling + and must round correctly. In the prototype solution, + rounding is incorrect and can cause artifacts. + </para> + <para> + A better solution would be to cache all updates to the + desktop image in <command>vncviewer</command> and only send the + damaged area to the X display with XPutImage. This would + allow the damaged area to be computed so that rounding + errors do not create artifacts. This method is probably + similar to what is used in the Window client. (The whole + VNC suite is being re-written in C++ and the forthcoming + version 4 has not been evaluated.) + </para> + </sect3> + <sect3><title>Scaling with the X Video Extension</title> + <para> + The scaling in the Windows <command>vncviewer</command> application + makes use of a scaled blit that is supplied by the + underlying system library. Several video cards currently + provide support for a scaled blit, and some X servers + (including XFree86) expose this capability to applications + via the XvPutImage interface of the X Video Extension. + The capability exposed by XvPutImage results in the scaled + image being drawn to an overlay plane. Most video cards + also provide support for a scaled blit into the normal + output planes, but this is not exposed via XvPutImage. + </para> + <para> + The <command>vncviewer</command> program could be modified to use + the X Video Extension to provide scaling under X11 that is + similar to the scaling currently provided under Windows. + Unfortunately, Xdmx does not currently export the X Video + Extension, so this would not provide an immediate solution + usable with DMX. + </para> + <para> + A very early-stage proof-of-concept prototype was + implemented and a preliminary patch against + <filename>vnc-3.3.7-unixsrc</filename> is available in the + <filename>dmx/external</filename> directory. This prototype was + implemented to better understand the problems that must be + solved to make this solution viable: + <itemizedlist> + <listitem><para> + As noted under the software scaling section above, + <command>vncviewer</command> writes to the X display with + several different calls. These calls write to the + normal output planes and are compatible with + XvPutImage, which writes to an overlay plane. To + eliminate artifacts caused by this problem, + <command>vncviewer</command> should be modified so that a cached + copy of the desktop is available, either as a + client-side image or a server-side off-screen pixmap, + so that XvPutImage would be the only method for + writing to the X display. + </para></listitem> + <listitem> + <para> + Although several modern graphics adaptors support + hardware scaling using an RGB format (e.g., ATI + Radeon, nVidia, etc.), XFree86 drivers typically + only implement YUV formats. YUV generally compress + the pixel information in some way. For example, two + commonly implemented formats, YUY2 and UYVY provide + intensity information for every RGB pixel, but only + provide chroma and luminance information for pairs + of horizontal pixels. Since VNC uses + pixel-resolution for communicating updates on the + wire, additional artifacts are introduced (because + there may not be enough information from the wire to + update a pair of pixels). + </para> + <para> + Further, the well-known problem with YUV encoding + is even more evident when the image is a desktop + instead of a movie. For example, consider a + 1-pixel-wide vertical window border. If the border + changes in color but not intensity (e.g., because a + window manager uses color to indicate focus), there + may or may not be a change in the YUY2 image, + depending on the algorithm used for RGB to YUV + conversion and on how the border pixel is ordered in + the pair of pixels used by the algorithm. + </para> + <para> + Many of these artifacts could be eliminated if + <command>vncviewer</command> cached a complete RGB image of + the desktop, and only did the conversion to YUV for + properly aligned areas of damage. The remaining artifacts + could be eliminated if an RGB format was used with X + Video (which may require the extension of existing + XFree86 drivers to support RGB). + </para> + </listitem> + <listitem><para> + Most modern video cards support exactly one overlay + plane that is suitable for use with X Video. + Therefore, only one application can use X Video at any + given time. This is a severe limitation in a desktop + environment. + </para></listitem> + </itemizedlist> + </para> + <sect4><title>Implementing the X Video Extension for DMX</title> + <para> + The user-level API for X Video is fairly simple, but the + underlying support required for the full specification + is large. However, since the API provides a method to + query supported capabilities, a usable subset of X + Video can be implemented that would support XvPutImage + and little else. This would require support for the + following: + <itemizedlist> + <listitem><para> + X Video Extension API calls, including the + following: + <itemizedlist> + <listitem><para>XvQueryExtension</para></listitem> + <listitem><para>XvQueryAdaptors</para></listitem> + <listitem><para>XvQueryPortAttributes</para></listitem> + <listitem><para>XvFreeAdaptorInfo</para></listitem> + <listitem><para>XvListImageFormats</para></listitem> + <listitem><para>XvGrabPort</para></listitem> + <listitem><para>XvCreateImage</para></listitem> + <listitem><para>XvPutImage</para></listitem> + <listitem><para>XvShmCreateImage</para></listitem> + <listitem><para>XvShmPutImage</para></listitem> + </itemizedlist> + </para></listitem> + <listitem><para> + Support for querying back-end X Video Extension + capabilities. + </para></listitem> + <listitem><para> + Support for sending the image to the back-ends. + Because X Video requires sending full images, there + may be a trade-off between bandwidth limitations and + additional complexity to divide the image up such + that is scales properly. + </para></listitem> + <listitem><para> + Possible support for a software fall-back. For + example, if all of the back-ends do not support the X + Video Extension, software scaling can be implemented + such that the image is sent to the back-end with + XPutImage. This pathway would have poor + performance. + </para></listitem> + </itemizedlist> + </para> + </sect4> + <sect4><title>Supporting RGB formats for the X Video Extension</title> + <para> + Assuming an XFree86 driver already supports the X Video + Extension, and assuming the target hardware supports an + RGB format, then adding support for that format is + relatively simple and straightforward. + </para> + </sect4> + </sect3> + <sect3><title>Scaling with an XPutImageScaled Extension</title> + <para> + Instead of (or in addition to) implementing the X Video + Extension in DMX, one obvious solution would be to + implement a new extension that provides access to + hardware-assisted scaled blits, similar to the StretchBlt + call available under Windows. This call would scale RGB + images and would not use the overlay plane (unlike the X + Video Extension). + </para> + <para> + This approach has many of the same advantages and + disadvantages as the XCopyAreaScaled Extension, discussed + in the next section. Discussion of XPutImageScaled is + deferred in favor of XCopyAreaScaled for the following + reasons: + <itemizedlist> + <listitem><para> + XPutImageScaled can be emulated with XCopyAreaScaled + by first using XPutImage to copy the image to an + off-screen pixmap, and then calling XCopyAreaScaled + between that off-screen pixmap and the target + drawable. + </para></listitem> + <listitem><para> + Since XCopyAreaScaled would copy between two areas of + on-screen or off-screen memory, it has additional uses + and can be viewed as efficiently providing a superset + of XPutImageScaled functionality. + </para></listitem> + </itemizedlist> + </para> + </sect3> + <sect3><title>Scaling with an XCopyAreaScaled Extension</title> + <para> + As noted in the previous section, because XCopyAreaScaled + provides a superset of the functionality provided by + XPutImageScaled, we will consider this extension instead. + </para> + <para> + First, XCopyAreaScaled would provide for RGB scaling + between pixmaps (i.e., on-screen or off-screen areas of + memory that reside on the video card). Unlike the X Video + Extension, which writes into an overlay plane, + XCopyAreaScaled would write into the non-overlay areas of + the screen. Key points to consider are as follows: + <itemizedlist> + <listitem><para> + Because different planes are involved, the two scaling + operations are usually implemented in hardware + differently, so an XCopyAreaScaled extension could be + added in a manner that would neither conflict with nor + interact with the X Video extension in any way. + </para></listitem> + <listitem><para> + The XCopyAreaScaled extension provides new + functionality that the X Video Extension does not + provide. Based on anecdotal feedback, we believe that + many people outside the DMX and VNC communities would + be excited about this extension. + </para></listitem> + <listitem><para> + The main drawback to this extension is that it is new + and needs to be implemented at the driver level in + XFree86 for each video card to be supported. At the + present time, it is more likely that the X Video + Extension will be implemented for a particular piece + hardware because the X Video extension has multimedia + uses. However, over time, we would expect the + XCopyAreaScaled extension to be implemented along with + the X Video extension, especially if it becomes + popular. + </para></listitem> + <listitem><para> + Another drawback is that not all modern cards provide + support for a simple scaled blit operation. However, + these cards usually do provide a 3D pipeline which + could be used to provide this functionality in a + manner that is transparent to the client application + that is using the XCopyAreaScaled extension. However, + this implementation pathway would make this extension + somewhat more difficult to implement on certain cards. + </para></listitem> + </itemizedlist> + </para> + </sect3> + <sect3><title>Scaling with OpenGL</title> + <para> + Another general solution to the scaling problem is to use + the texture scaling found in all 3D hardware. This + ability is already exposed through OpenGL and can be + exploited by clients without X server modification (i.e., + other than the ability to support OpenGL). An application + using OpenGL would transmit the non-scaled image to the X + server as a texture, and would then display a single + non-transformed rect using that texture. This also works + around the single overlay problem with the X Video + Extension as well as the need to implement additional + scaled primitive extensions. + </para> + <para> + The downside is that most OpenGL implementations require + power of 2 texture sizes and this can be very wasteful of + memory if, for example, the application needs to scale a + 1025x1025 image, which would require a 2048x2048 texture + area (even a 640x480 image would require a 1024x512 + texture). Another downside is that some OpenGL + implementations have a limited about of texture memory and + cannot handle textures that are very large. For example, + they might limit the texture size to 1024x1024. + </para> + </sect3> + </sect2> + <sect2><title>Application-transparent Scaling for DMX + </title><sect3><title>Back-end Scaling Without Disconnect/Reconnect</title> + <para> + VNC does scaling on the client side (in the + <command>vncviewer</command> application). Implementing a similar + solution for DMX would require support in the back-end X + servers and, therefore, is not a general solution. + </para> + <para> + XFree86 already implements some support for "scaling" that + could be used with DMX: if, in the XF86Config file, + multiple Modes are listed in the Display Subsection of the + Screen Section, then pressing Ctrl-Alt-Plus and + Ctrl-Alt-Minus can be used to iterate through the listed + modes. The display dimensions will change to the + dimensions in the Modes line, but the logical dimensions + of the X server (i.e., the dimensions that Xdmx knows + about) will not change. + </para> + <para> + Further, the dimensions of the XFree86 display are under + software control (via the XFree86-VidModeExtension), so + the Xdmx server could change the screen dimensions on a + per-display basis, thereby scaling the information on part + of that display. + </para> + <para> + However, this scaling appears to have limited use. For + example, assume a 4 by 4 display wall consisting of 16 + 1280x1024 displays. If all of the back-end servers were + simultaneously configured to display 640x480, the left + hand corner of each display would be magnified, but the + composite result would be unreadable. Magnifying one + display at a time could be usable, but could have limited + utility, since the result would still be no larger than a + single display. + </para> + </sect3> + <sect3><title>Back-end Scaling With Disconnect/Reconnect</title> + <para> + Disconnect and reconnect features are not currently + supported in DMX, but are scheduled to be implemented in + the future. These features, combined with the + XFree86-VidModeExtension Extension, would allow an + application to do the following: + <itemizedlist> + <listitem><para> + Disconnect a specific back-end server (via the DMX + Extension), + </para></listitem> + <listitem><para> + reconfigure the XFree86 back-end server resolution, + and + </para></listitem> + <listitem><para> + reconnect the back-end server to DMX -- at a new + origin with the new screen resolution. + </para></listitem> + </itemizedlist> + </para> + <para> + For example, consider a display wall consisting of 16 + 1280x1024 displays with a total resolution of 5120x4096. + All of the screens could be disconnected, repositioned, + and reconnected each at a resolution of 640x480. The + total resolution of the display wall would be 2560x1920, + allowing a view of a selected area approximately + one-fourth of the size of the DMX display. This change + would be completely application independent (except, + perhaps, for a DMX-aware window manager). When work at + the increased resolution was completed, the back-end + servers could be disconnected, reconfigured, and + reconnected for the original 5120x4096 view. + </para> + <para> + Support for this type of scaling can be implemented in a + DMX-aware X11 client assuming the DMX server support + arbitrary disconnect and reconnect semantics. Because + this application cannot be written before + disconnect/reconnect is implemented, this solution will + not be discussed further in this paper. + </para> + </sect3> + <sect3><title>Server-side Scaling</title> + <para> + In earlier versions of DMX, a frame buffer was maintained + on the server side, and XPutImage was used to move the + information from the server to the client (similar to some + early VNC implementations). The use of a server-side + frame buffer would allow the server to do scaling, but is + not a recommended solution because of overall performance + issues and server-side memory issues (i.e., the frame + buffer would be very large for large display walls). + </para> + <para> + Exploration of this path is not recommended. + </para> + </sect3> + </sect2> + <sect2><title>XCreateScaledWindow API</title> + <para> + The implementation of X Video Extension in DMX, and the use + of XvPutImage by applications requiring scaling requires + significant changes in DMX Further, XvPutImage is, + essentially a scaled blit, and it is only useful for + applications which are already using (or can be modified to + use) XPutImage. Therefore, a more general API will be + discussed as another possibility. + </para> + <para> + X applications typically create windows with the + XCreateWindow call. A new extension could provide an + XCreateScaledWindow call that could be used in place of the + XCreateWindow call and be otherwise transparent to the + application. This would allow applications, even those that + do not depend on XPutImage, to take advantage of window + scaling. In this section we describe how the call would + work, what transparency it provides, and how to solve the + potential problems that transparency creates. + </para> + <sect3><title>XCreateWindow</title> + <para> + The XCreateWindow call takes width and height as + parameters. An XCreateScaledWindow call could take all + the same parameters, with the addition of a scaling factor. + </para> + </sect3> + <sect3><title>XSetWindowAttributes</title> + <para> + An X11 window has several attributes that would have to be + scaled: + <itemizedlist> + <listitem><para>Background and border pixmaps</para></listitem> + <listitem><para>Border width</para></listitem> + <listitem><para>Cursor</para></listitem> + </itemizedlist> + </para> + </sect3> + <sect3><title>XGetWindowAttributes, XGetGeometry</title> + <para> + For transparency, calls that query the window attributes + should return unscaled information. This suggests that + all unscaled pixmaps and window attributes should be + cached. + </para> + <para> + Unfortunately, a window manager requires the scaled + geometry to properly decorate the window. The X server + can probably determine which client is acting as the + window manager (e.g., because that client will select + events that are used exclusively by the window manager). + However, other Scaled Window Extension aware clients may + also need to determine the scaled geometry. Therefore, at + least two additional extension calls should be + implemented: XGetScaledWindowAttributes and + XGetScaledGeometry. + </para> + </sect3> + <sect3><title>Popup and Child window positions</title> + <para> + Some applications may position popup and child windows + based on an unscaled notion of the main window geometry. + In this case, additional modifications to the client would + be required. + </para> + </sect3> + <sect3><title>Events</title> + <para> + Most events (e.g., for mouse motion) return information + about the coordinates at which the even occurred. These + coordinates would have to be modified so that unscaled + values were presented to the client. + </para> + </sect3> + <sect3><title>Implementation</title> + <para> + There are many implementation issues, some of which are + similar to the issues involved in implementing the X Video + Extension for DMX. The window contents must be scaled, + either by performing all operations to a frame buffer and + then writing the image to the display (perhaps using + hardware scaling support), or by modifying all of the + various drawing operations to perform scaling. Because of + the complexity involved, the frame buffer option is + recommended. + </para> + </sect3> + </sect2> + </sect1> + + <sect1><title>Conclusion and Recommendations + </title><para> + We recommend a three phase implementation strategy, based on + how an application could be written to take advantage of + scaling: + <orderedlist> + <listitem> + <para> + The XCopyAreaScaled extension should be implemented, since + this is the ideal solution for applications like VNC, and + since making use of this extension will require minimal + changes to applications that already use XPutImage or + XCopyArea. + </para> + <para> + The initial implementation work would include the design + of the X protocol extension, writing this up in the + usual format for extension documentation, implementation + of the protocol transport pieces in XFree86, + implementation of a software fall-back in XFree86 and + DMX, one example hardware implementation for XFree86, + and implementation of support for this extension in DMX. + </para> + <para> + We suggest implementing the extension first on the ATI + Radeon cards. However, since these cards do not provide + a 2D scaled blit primitive, the implementation would + have to make use of the 3D texture engine to emulate a + scaled blit. This is recommended, since other modern + graphics cards also do not provide a simple 2D scaled + blit operation and an example of the more difficult + implementation pathway would be helpful to others. + </para> + </listitem> + <listitem> + <para> + Until XCopyAreaScaled is widely supported, applications + that require scaling will have to fall back to another + scaling method. We suggest OpenGL as the first fall-back + method because it is widely available and supported by + DMX. + </para> + <para> + A project centered around OpenGL-based scaling would + implement this scaling in VNC as an example. This work + would include re-writing the <command>vncviewer</command> + rendering engine to cache a master copy of the desktop + image for all operations. + </para> + </listitem> + <listitem> + <para> + Since OpenGL is not implemented everywhere, and may not + provide hardware-assisted performance in every + implementation, an application that requires scaling + should also fall back to using the X Video Extension. + </para> + <para> + This project would add support for the X Video Extension + to DMX and would add support to VNC to take advantage of + this extension without introducing artifacts. This + would require modifying the <command>vncviewer</command> rendering + engine to cache a master copy of the desktop image for + all operations. This project should also add support + for the RGB format to at least one XFree86 driver (e.g., + ATI Radeon). + </para> + <para> + The X Video Extension is one of the few popular + extensions that DMX does not support. We recommend + implementing the X Video Extension even if scaling is + the specific goal of that work. + </para> + </listitem> + </orderedlist> + </para> + <para> + We do <emphasis>not</emphasis> recommend implementation of the + XCreateScaledWindow extension because of the complexity + involved. We do <emphasis>not</emphasis> recommend implementation of the + XPutImageScaled extension because it requires the same amount + of work as the XCopyAreaScaled extension, but provides less + functionality. Further, server-side scaling with a large + frame buffer is <emphasis>not</emphasis> recommended because of the + performance implications. + </para> + <para> + The back-end scaling, especially with disconnect/reconnect + support should be explored in the future after + disconnect/reconnect is implemented, but not at the present + time. + </para> + </sect1> + + </article> + <!-- Local Variables: --> + <!-- fill-column: 72 --> + <!-- End: --> diff --git a/xorg-server/hw/dmx/examples/ev.c b/xorg-server/hw/dmx/examples/ev.c index ba45c2b25..ed23b8aa9 100644 --- a/xorg-server/hw/dmx/examples/ev.c +++ b/xorg-server/hw/dmx/examples/ev.c @@ -60,7 +60,7 @@ int main(int argc, char **argv) #define test_bit(bit) (mask[(bit)/8] & (1 << ((bit)%8))) for (i = 0; i < 32; i++) { - sprintf(name, "/dev/input/event%d", i); + snprintf(name, sizeof(name), "/dev/input/event%d", i); if ((fd = open(name, O_RDONLY, 0)) >= 0) { ioctl(fd, EVIOCGVERSION, &version); ioctl(fd, EVIOCGNAME(sizeof(buf)), buf); @@ -92,7 +92,7 @@ int main(int argc, char **argv) } if (argc > 1) { - sprintf(name, "/dev/input/event%d", atoi(argv[1])); + snprintf(name, sizeof(name), "/dev/input/event%d", atoi(argv[1])); if ((fd = open(name, O_RDWR, 0)) >= 0) { printf("%s: open, fd = %d\n", name, fd); for (i = 0; i < LED_MAX; i++) { diff --git a/xorg-server/hw/dmx/glxProxy/compsize.c b/xorg-server/hw/dmx/glxProxy/compsize.c index 3bb562e05..5a5d5d0f1 100644 --- a/xorg-server/hw/dmx/glxProxy/compsize.c +++ b/xorg-server/hw/dmx/glxProxy/compsize.c @@ -1,558 +1,559 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include <GL/gl.h>
-
-GLint __glFogiv_size(GLenum pname)
-{
- switch (pname) {
- case GL_FOG_COLOR: return 4;
- case GL_FOG_DENSITY: return 1;
- case GL_FOG_END: return 1;
- case GL_FOG_MODE: return 1;
- case GL_FOG_INDEX: return 1;
- case GL_FOG_START: return 1;
- default:
- return 0;
- }
-}
-
-GLint __glFogfv_size(GLenum pname)
-{
- return __glFogiv_size(pname);
-}
-
-GLint __glCallLists_size(GLsizei n, GLenum type)
-{
- GLint size;
-
- if (n < 0) return 0;
- switch (type) {
- case GL_BYTE: size = 1; break;
- case GL_UNSIGNED_BYTE: size = 1; break;
- case GL_SHORT: size = 2; break;
- case GL_UNSIGNED_SHORT: size = 2; break;
- case GL_INT: size = 4; break;
- case GL_UNSIGNED_INT: size = 4; break;
- case GL_FLOAT: size = 4; break;
- case GL_2_BYTES: size = 2; break;
- case GL_3_BYTES: size = 3; break;
- case GL_4_BYTES: size = 4; break;
- default:
- return 0;
- }
- return n * size;
-}
-
-GLint __glDrawPixels_size(GLenum format, GLenum type, GLsizei w, GLsizei h)
-{
- GLint elements, esize;
-
- switch (format) {
- case GL_COLOR_INDEX:
- case GL_STENCIL_INDEX:
- case GL_DEPTH_COMPONENT:
- elements = 1;
- break;
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_LUMINANCE:
- elements = 1;
- break;
- case GL_LUMINANCE_ALPHA:
- elements = 2;
- break;
- case GL_RGB:
- elements = 3;
- break;
- case GL_RGBA:
- case GL_ABGR_EXT:
- elements = 4;
- break;
- default:
- return 0;
- }
- switch (type) {
- case GL_BITMAP:
- if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) {
- return (h * ((w+7)/8));
- } else {
- return 0;
- }
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- esize = 1;
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- esize = 1;
- elements = 1;
- break;
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- esize = 2;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- esize = 2;
- elements = 1;
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- esize = 4;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- esize = 4;
- elements = 1;
- break;
- default:
- return 0;
- }
- return elements * esize * w * h;
-}
-
-GLint __glBitmap_size(GLsizei w, GLsizei h)
-{
- return __glDrawPixels_size(GL_COLOR_INDEX, GL_BITMAP, w, h);
-}
-
-GLint __glTexGendv_size(GLenum e)
-{
- switch (e) {
- case GL_TEXTURE_GEN_MODE:
- return 1;
- case GL_OBJECT_PLANE:
- case GL_EYE_PLANE:
- return 4;
- default:
- return 0;
- }
-}
-
-GLint __glTexGenfv_size(GLenum e)
-{
- return __glTexGendv_size(e);
-}
-
-GLint __glTexGeniv_size(GLenum e)
-{
- return __glTexGendv_size(e);
-}
-
-GLint __glTexParameterfv_size(GLenum e)
-{
- switch (e) {
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- case GL_TEXTURE_WRAP_R:
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_MAG_FILTER:
- return 1;
- case GL_TEXTURE_BORDER_COLOR:
- return 4;
- case GL_TEXTURE_PRIORITY:
- return 1;
- case GL_TEXTURE_MIN_LOD:
- case GL_TEXTURE_MAX_LOD:
- case GL_TEXTURE_BASE_LEVEL:
- case GL_TEXTURE_MAX_LEVEL:
- return 1;
- default:
- return 0;
- }
-}
-
-GLint __glTexParameteriv_size(GLenum e)
-{
- return __glTexParameterfv_size(e);
-}
-
-GLint __glTexEnvfv_size(GLenum e)
-{
- switch (e) {
- case GL_TEXTURE_ENV_MODE:
- return 1;
- case GL_TEXTURE_ENV_COLOR:
- return 4;
- default:
- return 0;
- }
-}
-
-GLint __glTexEnviv_size(GLenum e)
-{
- return __glTexEnvfv_size(e);
-}
-
-GLint __glTexImage1D_size(GLenum format, GLenum type, GLsizei w)
-{
- GLint elements, esize;
-
- if (w < 0) return 0;
- switch (format) {
- case GL_COLOR_INDEX:
- elements = 1;
- break;
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_LUMINANCE:
- elements = 1;
- break;
- case GL_LUMINANCE_ALPHA:
- elements = 2;
- break;
- case GL_RGB:
- elements = 3;
- break;
- case GL_RGBA:
- case GL_ABGR_EXT:
- elements = 4;
- break;
- default:
- return 0;
- }
- switch (type) {
- case GL_BITMAP:
- if (format == GL_COLOR_INDEX) {
- return (w+7)/8;
- } else {
- return 0;
- }
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- esize = 1;
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- esize = 1;
- elements = 1;
- break;
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- esize = 2;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- esize = 2;
- elements = 1;
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- esize = 4;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- esize = 4;
- elements = 1;
- break;
- default:
- return 0;
- }
- return elements * esize * w;
-}
-
-GLint __glTexImage2D_size(GLenum format, GLenum type, GLsizei w, GLsizei h)
-{
- GLint elements, esize;
-
- if (w < 0) return 0;
- if (h < 0) return 0;
- switch (format) {
- case GL_COLOR_INDEX:
- elements = 1;
- break;
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_LUMINANCE:
- elements = 1;
- break;
- case GL_LUMINANCE_ALPHA:
- elements = 2;
- break;
- case GL_RGB:
- elements = 3;
- break;
- case GL_RGBA:
- case GL_ABGR_EXT:
- elements = 4;
- break;
- default:
- return 0;
- }
- switch (type) {
- case GL_BITMAP:
- if (format == GL_COLOR_INDEX) {
- return (h * ((w+7)/8));
- } else {
- return 0;
- }
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- esize = 1;
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- esize = 1;
- elements = 1;
- break;
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- esize = 2;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- esize = 2;
- elements = 1;
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- esize = 4;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- esize = 4;
- elements = 1;
- break;
- default:
- return 0;
- }
- return elements * esize * w * h;
-}
-
-GLint __glTexImage3D_size(GLenum format, GLenum type, GLsizei w, GLsizei h,
- GLsizei d)
-{
- GLint elements, esize;
-
- if (w < 0) return 0;
- if (h < 0) return 0;
- if (d < 0) return 0;
- switch (format) {
- case GL_COLOR_INDEX:
- elements = 1;
- break;
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_LUMINANCE:
- elements = 1;
- break;
- case GL_LUMINANCE_ALPHA:
- elements = 2;
- break;
- case GL_RGB:
- elements = 3;
- break;
- case GL_RGBA:
- case GL_ABGR_EXT:
- elements = 4;
- break;
- default:
- return 0;
- }
- switch (type) {
- case GL_BITMAP:
- if (format == GL_COLOR_INDEX) {
- return (d * (h * ((w+7)/8)));
- } else {
- return 0;
- }
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- esize = 1;
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- esize = 1;
- elements = 1;
- break;
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- esize = 2;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- esize = 2;
- elements = 1;
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- esize = 4;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- esize = 4;
- elements = 1;
- break;
- default:
- return 0;
- }
- return elements * esize * w * h * d;
-}
-
-GLint __glLightfv_size(GLenum pname)
-{
- switch (pname) {
- case GL_SPOT_EXPONENT: return 1;
- case GL_SPOT_CUTOFF: return 1;
- case GL_AMBIENT: return 4;
- case GL_DIFFUSE: return 4;
- case GL_SPECULAR: return 4;
- case GL_POSITION: return 4;
- case GL_SPOT_DIRECTION: return 3;
- case GL_CONSTANT_ATTENUATION: return 1;
- case GL_LINEAR_ATTENUATION: return 1;
- case GL_QUADRATIC_ATTENUATION: return 1;
- default:
- return 0;
- }
-}
-
-GLint __glLightiv_size(GLenum pname)
-{
- return __glLightfv_size(pname);
-}
-
-GLint __glLightModelfv_size(GLenum pname)
-{
- switch (pname) {
- case GL_LIGHT_MODEL_AMBIENT: return 4;
- case GL_LIGHT_MODEL_LOCAL_VIEWER: return 1;
- case GL_LIGHT_MODEL_TWO_SIDE: return 1;
- case GL_LIGHT_MODEL_COLOR_CONTROL: return 1;
- default:
- return 0;
- }
-}
-
-GLint __glLightModeliv_size(GLenum pname)
-{
- return __glLightModelfv_size(pname);
-}
-
-GLint __glMaterialfv_size(GLenum pname)
-{
- switch (pname) {
- case GL_SHININESS: return 1;
- case GL_EMISSION: return 4;
- case GL_AMBIENT: return 4;
- case GL_DIFFUSE: return 4;
- case GL_SPECULAR: return 4;
- case GL_AMBIENT_AND_DIFFUSE: return 4;
- case GL_COLOR_INDEXES: return 3;
- default:
- return 0;
- }
-}
-
-GLint __glMaterialiv_size(GLenum pname)
-{
- return __glMaterialfv_size(pname);
-}
-
-GLint __glColorTableParameterfv_size(GLenum pname)
-{
- switch (pname) {
- case GL_COLOR_TABLE_FORMAT:
- case GL_COLOR_TABLE_WIDTH:
- case GL_COLOR_TABLE_RED_SIZE:
- case GL_COLOR_TABLE_GREEN_SIZE:
- case GL_COLOR_TABLE_BLUE_SIZE:
- case GL_COLOR_TABLE_ALPHA_SIZE:
- case GL_COLOR_TABLE_LUMINANCE_SIZE:
- case GL_COLOR_TABLE_INTENSITY_SIZE:
- return 1;
- case GL_COLOR_TABLE_SCALE:
- case GL_COLOR_TABLE_BIAS:
- return 4;
- default:
- return -1;
- }
-}
-
-GLint __glColorTableParameteriv_size(GLenum pname)
-{
- return __glColorTableParameterfv_size(pname);
-}
-
-GLint __glConvolutionParameterfv_size(GLenum pname)
-{
- switch(pname) {
- case GL_CONVOLUTION_BORDER_MODE:
- return 1;
- case GL_CONVOLUTION_BORDER_COLOR:
- case GL_CONVOLUTION_FILTER_SCALE:
- case GL_CONVOLUTION_FILTER_BIAS:
- return 4;
- default: /* error: bad enum value */
- return -1;
- }
-}
-
-GLint __glConvolutionParameteriv_size(GLenum pname)
-{
- return __glConvolutionParameterfv_size(pname);
-}
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#include <GL/gl.h> +#include "compsize.h" + +GLint __glFogiv_size(GLenum pname) +{ + switch (pname) { + case GL_FOG_COLOR: return 4; + case GL_FOG_DENSITY: return 1; + case GL_FOG_END: return 1; + case GL_FOG_MODE: return 1; + case GL_FOG_INDEX: return 1; + case GL_FOG_START: return 1; + default: + return 0; + } +} + +GLint __glFogfv_size(GLenum pname) +{ + return __glFogiv_size(pname); +} + +GLint __glCallLists_size(GLsizei n, GLenum type) +{ + GLint size; + + if (n < 0) return 0; + switch (type) { + case GL_BYTE: size = 1; break; + case GL_UNSIGNED_BYTE: size = 1; break; + case GL_SHORT: size = 2; break; + case GL_UNSIGNED_SHORT: size = 2; break; + case GL_INT: size = 4; break; + case GL_UNSIGNED_INT: size = 4; break; + case GL_FLOAT: size = 4; break; + case GL_2_BYTES: size = 2; break; + case GL_3_BYTES: size = 3; break; + case GL_4_BYTES: size = 4; break; + default: + return 0; + } + return n * size; +} + +GLint __glDrawPixels_size(GLenum format, GLenum type, GLsizei w, GLsizei h) +{ + GLint elements, esize; + + switch (format) { + case GL_COLOR_INDEX: + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + elements = 1; + break; + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + elements = 1; + break; + case GL_LUMINANCE_ALPHA: + elements = 2; + break; + case GL_RGB: + elements = 3; + break; + case GL_RGBA: + case GL_ABGR_EXT: + elements = 4; + break; + default: + return 0; + } + switch (type) { + case GL_BITMAP: + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { + return (h * ((w+7)/8)); + } else { + return 0; + } + case GL_BYTE: + case GL_UNSIGNED_BYTE: + esize = 1; + break; + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + esize = 1; + elements = 1; + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + esize = 2; + break; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + esize = 2; + elements = 1; + break; + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + esize = 4; + break; + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + esize = 4; + elements = 1; + break; + default: + return 0; + } + return elements * esize * w * h; +} + +GLint __glBitmap_size(GLsizei w, GLsizei h) +{ + return __glDrawPixels_size(GL_COLOR_INDEX, GL_BITMAP, w, h); +} + +GLint __glTexGendv_size(GLenum e) +{ + switch (e) { + case GL_TEXTURE_GEN_MODE: + return 1; + case GL_OBJECT_PLANE: + case GL_EYE_PLANE: + return 4; + default: + return 0; + } +} + +GLint __glTexGenfv_size(GLenum e) +{ + return __glTexGendv_size(e); +} + +GLint __glTexGeniv_size(GLenum e) +{ + return __glTexGendv_size(e); +} + +GLint __glTexParameterfv_size(GLenum e) +{ + switch (e) { + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + return 1; + case GL_TEXTURE_BORDER_COLOR: + return 4; + case GL_TEXTURE_PRIORITY: + return 1; + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + return 1; + default: + return 0; + } +} + +GLint __glTexParameteriv_size(GLenum e) +{ + return __glTexParameterfv_size(e); +} + +GLint __glTexEnvfv_size(GLenum e) +{ + switch (e) { + case GL_TEXTURE_ENV_MODE: + return 1; + case GL_TEXTURE_ENV_COLOR: + return 4; + default: + return 0; + } +} + +GLint __glTexEnviv_size(GLenum e) +{ + return __glTexEnvfv_size(e); +} + +GLint __glTexImage1D_size(GLenum format, GLenum type, GLsizei w) +{ + GLint elements, esize; + + if (w < 0) return 0; + switch (format) { + case GL_COLOR_INDEX: + elements = 1; + break; + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + elements = 1; + break; + case GL_LUMINANCE_ALPHA: + elements = 2; + break; + case GL_RGB: + elements = 3; + break; + case GL_RGBA: + case GL_ABGR_EXT: + elements = 4; + break; + default: + return 0; + } + switch (type) { + case GL_BITMAP: + if (format == GL_COLOR_INDEX) { + return (w+7)/8; + } else { + return 0; + } + case GL_BYTE: + case GL_UNSIGNED_BYTE: + esize = 1; + break; + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + esize = 1; + elements = 1; + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + esize = 2; + break; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + esize = 2; + elements = 1; + break; + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + esize = 4; + break; + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + esize = 4; + elements = 1; + break; + default: + return 0; + } + return elements * esize * w; +} + +GLint __glTexImage2D_size(GLenum format, GLenum type, GLsizei w, GLsizei h) +{ + GLint elements, esize; + + if (w < 0) return 0; + if (h < 0) return 0; + switch (format) { + case GL_COLOR_INDEX: + elements = 1; + break; + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + elements = 1; + break; + case GL_LUMINANCE_ALPHA: + elements = 2; + break; + case GL_RGB: + elements = 3; + break; + case GL_RGBA: + case GL_ABGR_EXT: + elements = 4; + break; + default: + return 0; + } + switch (type) { + case GL_BITMAP: + if (format == GL_COLOR_INDEX) { + return (h * ((w+7)/8)); + } else { + return 0; + } + case GL_BYTE: + case GL_UNSIGNED_BYTE: + esize = 1; + break; + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + esize = 1; + elements = 1; + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + esize = 2; + break; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + esize = 2; + elements = 1; + break; + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + esize = 4; + break; + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + esize = 4; + elements = 1; + break; + default: + return 0; + } + return elements * esize * w * h; +} + +GLint __glTexImage3D_size(GLenum format, GLenum type, GLsizei w, GLsizei h, + GLsizei d) +{ + GLint elements, esize; + + if (w < 0) return 0; + if (h < 0) return 0; + if (d < 0) return 0; + switch (format) { + case GL_COLOR_INDEX: + elements = 1; + break; + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + elements = 1; + break; + case GL_LUMINANCE_ALPHA: + elements = 2; + break; + case GL_RGB: + elements = 3; + break; + case GL_RGBA: + case GL_ABGR_EXT: + elements = 4; + break; + default: + return 0; + } + switch (type) { + case GL_BITMAP: + if (format == GL_COLOR_INDEX) { + return (d * (h * ((w+7)/8))); + } else { + return 0; + } + case GL_BYTE: + case GL_UNSIGNED_BYTE: + esize = 1; + break; + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + esize = 1; + elements = 1; + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + esize = 2; + break; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + esize = 2; + elements = 1; + break; + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + esize = 4; + break; + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + esize = 4; + elements = 1; + break; + default: + return 0; + } + return elements * esize * w * h * d; +} + +GLint __glLightfv_size(GLenum pname) +{ + switch (pname) { + case GL_SPOT_EXPONENT: return 1; + case GL_SPOT_CUTOFF: return 1; + case GL_AMBIENT: return 4; + case GL_DIFFUSE: return 4; + case GL_SPECULAR: return 4; + case GL_POSITION: return 4; + case GL_SPOT_DIRECTION: return 3; + case GL_CONSTANT_ATTENUATION: return 1; + case GL_LINEAR_ATTENUATION: return 1; + case GL_QUADRATIC_ATTENUATION: return 1; + default: + return 0; + } +} + +GLint __glLightiv_size(GLenum pname) +{ + return __glLightfv_size(pname); +} + +GLint __glLightModelfv_size(GLenum pname) +{ + switch (pname) { + case GL_LIGHT_MODEL_AMBIENT: return 4; + case GL_LIGHT_MODEL_LOCAL_VIEWER: return 1; + case GL_LIGHT_MODEL_TWO_SIDE: return 1; + case GL_LIGHT_MODEL_COLOR_CONTROL: return 1; + default: + return 0; + } +} + +GLint __glLightModeliv_size(GLenum pname) +{ + return __glLightModelfv_size(pname); +} + +GLint __glMaterialfv_size(GLenum pname) +{ + switch (pname) { + case GL_SHININESS: return 1; + case GL_EMISSION: return 4; + case GL_AMBIENT: return 4; + case GL_DIFFUSE: return 4; + case GL_SPECULAR: return 4; + case GL_AMBIENT_AND_DIFFUSE: return 4; + case GL_COLOR_INDEXES: return 3; + default: + return 0; + } +} + +GLint __glMaterialiv_size(GLenum pname) +{ + return __glMaterialfv_size(pname); +} + +GLint __glColorTableParameterfv_size(GLenum pname) +{ + switch (pname) { + case GL_COLOR_TABLE_FORMAT: + case GL_COLOR_TABLE_WIDTH: + case GL_COLOR_TABLE_RED_SIZE: + case GL_COLOR_TABLE_GREEN_SIZE: + case GL_COLOR_TABLE_BLUE_SIZE: + case GL_COLOR_TABLE_ALPHA_SIZE: + case GL_COLOR_TABLE_LUMINANCE_SIZE: + case GL_COLOR_TABLE_INTENSITY_SIZE: + return 1; + case GL_COLOR_TABLE_SCALE: + case GL_COLOR_TABLE_BIAS: + return 4; + default: + return -1; + } +} + +GLint __glColorTableParameteriv_size(GLenum pname) +{ + return __glColorTableParameterfv_size(pname); +} + +GLint __glConvolutionParameterfv_size(GLenum pname) +{ + switch(pname) { + case GL_CONVOLUTION_BORDER_MODE: + return 1; + case GL_CONVOLUTION_BORDER_COLOR: + case GL_CONVOLUTION_FILTER_SCALE: + case GL_CONVOLUTION_FILTER_BIAS: + return 4; + default: /* error: bad enum value */ + return -1; + } +} + +GLint __glConvolutionParameteriv_size(GLenum pname) +{ + return __glConvolutionParameterfv_size(pname); +} diff --git a/xorg-server/hw/dmx/glxProxy/compsize.h b/xorg-server/hw/dmx/glxProxy/compsize.h new file mode 100644 index 000000000..856c6f5ad --- /dev/null +++ b/xorg-server/hw/dmx/glxProxy/compsize.h @@ -0,0 +1,51 @@ +/* + * Copyright 2011 Apple Inc. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __compsize_h__ +#define __compsize_h__ + +extern GLint __glColorTableParameterfv_size(GLenum pname); +extern GLint __glColorTableParameteriv_size(GLenum pname); +extern GLint __glConvolutionParameterfv_size(GLenum pname); +extern GLint __glConvolutionParameteriv_size(GLenum pname); +extern GLint __glFogfv_size(GLenum pname); +extern GLint __glFogiv_size(GLenum pname); +extern GLint __glLightModelfv_size(GLenum pname); +extern GLint __glLightModeliv_size(GLenum pname); +extern GLint __glLightfv_size(GLenum pname); +extern GLint __glLightiv_size(GLenum pname); +extern GLint __glMaterialfv_size(GLenum pname); +extern GLint __glMaterialiv_size(GLenum pname); +extern GLint __glTexEnvfv_size(GLenum e); +extern GLint __glTexEnviv_size(GLenum e); +extern GLint __glTexGendv_size(GLenum e); +extern GLint __glTexGenfv_size(GLenum e); +extern GLint __glTexGeniv_size(GLenum e); +extern GLint __glTexParameterfv_size(GLenum e); +extern GLint __glTexParameteriv_size(GLenum e); + +#endif /* !__compsize_h__ */ diff --git a/xorg-server/hw/dmx/glxProxy/g_renderswap.c b/xorg-server/hw/dmx/glxProxy/g_renderswap.c index 39316a99b..e434a71b6 100644 --- a/xorg-server/hw/dmx/glxProxy/g_renderswap.c +++ b/xorg-server/hw/dmx/glxProxy/g_renderswap.c @@ -1,2433 +1,2434 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include "glxserver.h"
-#include "glxext.h"
-#include "g_disptab.h"
-#include "unpack.h"
-
-void __glXDispSwap_CallList(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_ListBase(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_Begin(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_Color3bv(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_Color3dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 24);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Color3fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
-}
-
-void __glXDispSwap_Color3iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Color3sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Color3ubv(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_Color3uiv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 3);
-}
-
-void __glXDispSwap_Color3usv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
-}
-
-void __glXDispSwap_Color4bv(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_Color4dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 32);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
-}
-
-void __glXDispSwap_Color4fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_Color4iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_Color4sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_Color4ubv(GLbyte *pc)
-{
-
-}
-
-void __glXDispSwap_Color4uiv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_Color4usv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_EdgeFlagv(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_End(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_Indexdv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 8);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_Indexfv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_Indexiv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_Indexsv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_Normal3bv(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_Normal3dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 24);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Normal3fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Normal3iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Normal3sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_RasterPos2dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 16);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_RasterPos2fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_RasterPos2iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_RasterPos2sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_RasterPos3dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 24);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_RasterPos3fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_RasterPos3iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_RasterPos3sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_RasterPos4dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 32);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_RasterPos4fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_RasterPos4iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_RasterPos4sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_Rectdv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 32);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
- __GLX_SWAP_DOUBLE_ARRAY(pc + 16, 2);
-
-}
-
-void __glXDispSwap_Rectfv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
- __GLX_SWAP_FLOAT_ARRAY(pc + 8, 2);
-
-}
-
-void __glXDispSwap_Rectiv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 2);
- __GLX_SWAP_INT_ARRAY(pc + 8, 2);
-
-}
-
-void __glXDispSwap_Rectsv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 2);
- __GLX_SWAP_SHORT_ARRAY(pc + 4, 2);
-
-}
-
-void __glXDispSwap_TexCoord1dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 8);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_TexCoord1fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_TexCoord1iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_TexCoord1sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_TexCoord2dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 16);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_TexCoord2fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_TexCoord2iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_TexCoord2sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_TexCoord3dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 24);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_TexCoord3fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_TexCoord3iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_TexCoord3sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_TexCoord4dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 32);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_TexCoord4fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_TexCoord4iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_TexCoord4sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_Vertex2dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 16);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_Vertex2fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_Vertex2iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_Vertex2sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_Vertex3dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 24);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Vertex3fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Vertex3iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Vertex3sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_Vertex4dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 32);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_Vertex4fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_Vertex4iv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_Vertex4sv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_ClipPlane(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 36);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_INT(pc + 32);
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_ColorMaterial(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_CullFace(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_Fogf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
-
-}
-
-void __glXDispSwap_Fogfv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- pname = *(GLenum *)(pc + 0);
- compsize = __glFogfv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_FLOAT_ARRAY(pc + 4, compsize);
-
-}
-
-void __glXDispSwap_Fogi(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_Fogiv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- pname = *(GLenum *)(pc + 0);
- compsize = __glFogiv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT_ARRAY(pc + 4, compsize);
-
-}
-
-void __glXDispSwap_FrontFace(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_Hint(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_Lightf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
-}
-
-void __glXDispSwap_Lightfv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glLightfv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_Lighti(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_Lightiv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glLightiv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_LightModelf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
-
-}
-
-void __glXDispSwap_LightModelfv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- pname = *(GLenum *)(pc + 0);
- compsize = __glLightModelfv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_FLOAT_ARRAY(pc + 4, compsize);
-
-}
-
-void __glXDispSwap_LightModeli(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_LightModeliv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- pname = *(GLenum *)(pc + 0);
- compsize = __glLightModeliv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT_ARRAY(pc + 4, compsize);
-
-}
-
-void __glXDispSwap_LineStipple(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_SHORT(pc + 4);
-
-}
-
-void __glXDispSwap_LineWidth(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
-
-}
-
-void __glXDispSwap_Materialf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
-}
-
-void __glXDispSwap_Materialfv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glMaterialfv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_Materiali(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_Materialiv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glMaterialiv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_PointSize(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
-
-}
-
-void __glXDispSwap_PolygonMode(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_Scissor(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
-
-}
-
-void __glXDispSwap_ShadeModel(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_TexParameterf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
-}
-
-void __glXDispSwap_TexParameterfv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glTexParameterfv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_TexParameteri(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_TexParameteriv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glTexParameteriv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_TexEnvf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
-}
-
-void __glXDispSwap_TexEnvfv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glTexEnvfv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_TexEnvi(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_TexEnviv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glTexEnviv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_TexGend(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 16);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_DOUBLE(pc + 0);
-
-}
-
-void __glXDispSwap_TexGendv(GLbyte *pc)
-{
- GLenum pname;
- GLint cmdlen;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glTexGendv_size(pname);
- if (compsize < 0) compsize = 0;
- cmdlen = __GLX_PAD(8+compsize*8);
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, cmdlen);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_DOUBLE_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_TexGenf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
-}
-
-void __glXDispSwap_TexGenfv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glTexGenfv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_TexGeni(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_TexGeniv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glTexGeniv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_InitNames(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_LoadName(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_PassThrough(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
-
-}
-
-void __glXDispSwap_PopName(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_PushName(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_DrawBuffer(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_Clear(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_ClearAccum(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
- __GLX_SWAP_FLOAT(pc + 12);
-
-}
-
-void __glXDispSwap_ClearIndex(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
-
-}
-
-void __glXDispSwap_ClearColor(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
- __GLX_SWAP_FLOAT(pc + 12);
-
-}
-
-void __glXDispSwap_ClearStencil(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_ClearDepth(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 8);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE(pc + 0);
-
-}
-
-void __glXDispSwap_StencilMask(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_ColorMask(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_DepthMask(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_IndexMask(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_Accum(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
-
-}
-
-void __glXDispSwap_Disable(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_Enable(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_PopAttrib(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_PushAttrib(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_MapGrid1d(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 20);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_INT(pc + 16);
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
-
-}
-
-void __glXDispSwap_MapGrid1f(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
-}
-
-void __glXDispSwap_MapGrid2d(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 40);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_INT(pc + 32);
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
- __GLX_SWAP_INT(pc + 36);
- __GLX_SWAP_DOUBLE(pc + 16);
- __GLX_SWAP_DOUBLE(pc + 24);
-
-}
-
-void __glXDispSwap_MapGrid2f(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_FLOAT(pc + 16);
- __GLX_SWAP_FLOAT(pc + 20);
-
-}
-
-void __glXDispSwap_EvalCoord1dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 8);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_EvalCoord1fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_EvalCoord2dv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 16);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_EvalCoord2fv(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_EvalMesh1(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_EvalPoint1(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_EvalMesh2(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
-
-}
-
-void __glXDispSwap_EvalPoint2(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_AlphaFunc(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
-
-}
-
-void __glXDispSwap_BlendFunc(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_LogicOp(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_StencilFunc(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_StencilOp(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_DepthFunc(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_PixelZoom(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
-
-}
-
-void __glXDispSwap_PixelTransferf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
-
-}
-
-void __glXDispSwap_PixelTransferi(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_PixelMapfv(GLbyte *pc)
-{
- GLint mapsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- mapsize = *(GLint *)(pc + 4);
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 8, mapsize);
-
-}
-
-void __glXDispSwap_PixelMapuiv(GLbyte *pc)
-{
- GLint mapsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- mapsize = *(GLint *)(pc + 4);
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 8, mapsize);
-
-}
-
-void __glXDispSwap_PixelMapusv(GLbyte *pc)
-{
- GLint mapsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- mapsize = *(GLint *)(pc + 4);
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_SHORT_ARRAY(pc + 8, mapsize);
-
-}
-
-void __glXDispSwap_ReadBuffer(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_CopyPixels(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
-
-}
-
-void __glXDispSwap_DepthRange(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 16);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
-
-}
-
-void __glXDispSwap_Frustum(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 48);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
- __GLX_SWAP_DOUBLE(pc + 16);
- __GLX_SWAP_DOUBLE(pc + 24);
- __GLX_SWAP_DOUBLE(pc + 32);
- __GLX_SWAP_DOUBLE(pc + 40);
-
-}
-
-void __glXDispSwap_LoadIdentity(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_LoadMatrixf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 16);
-
-}
-
-void __glXDispSwap_LoadMatrixd(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 128);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 16);
-
-}
-
-void __glXDispSwap_MatrixMode(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_MultMatrixf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_FLOAT_ARRAY(pc + 0, 16);
-
-}
-
-void __glXDispSwap_MultMatrixd(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 128);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 16);
-
-}
-
-void __glXDispSwap_Ortho(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 48);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
- __GLX_SWAP_DOUBLE(pc + 16);
- __GLX_SWAP_DOUBLE(pc + 24);
- __GLX_SWAP_DOUBLE(pc + 32);
- __GLX_SWAP_DOUBLE(pc + 40);
-
-}
-
-void __glXDispSwap_PopMatrix(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_PushMatrix(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_Rotated(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 32);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
- __GLX_SWAP_DOUBLE(pc + 16);
- __GLX_SWAP_DOUBLE(pc + 24);
-
-}
-
-void __glXDispSwap_Rotatef(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
- __GLX_SWAP_FLOAT(pc + 12);
-
-}
-
-void __glXDispSwap_Scaled(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 24);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
- __GLX_SWAP_DOUBLE(pc + 16);
-
-}
-
-void __glXDispSwap_Scalef(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
-}
-
-void __glXDispSwap_Translated(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 24);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_DOUBLE(pc + 0);
- __GLX_SWAP_DOUBLE(pc + 8);
- __GLX_SWAP_DOUBLE(pc + 16);
-
-}
-
-void __glXDispSwap_Translatef(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
-}
-
-void __glXDispSwap_Viewport(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
-
-}
-
-void __glXDispSwap_PolygonOffset(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
-
-}
-
-void __glXDispSwap_CopyTexImage1D(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
- __GLX_SWAP_INT(pc + 20);
- __GLX_SWAP_INT(pc + 24);
-
-}
-
-void __glXDispSwap_CopyTexImage2D(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
- __GLX_SWAP_INT(pc + 20);
- __GLX_SWAP_INT(pc + 24);
- __GLX_SWAP_INT(pc + 28);
-
-}
-
-void __glXDispSwap_CopyTexSubImage1D(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
- __GLX_SWAP_INT(pc + 20);
-
-}
-
-void __glXDispSwap_CopyTexSubImage2D(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
- __GLX_SWAP_INT(pc + 20);
- __GLX_SWAP_INT(pc + 24);
- __GLX_SWAP_INT(pc + 28);
-
-}
-
-void __glXDispSwap_BindTexture(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_PrioritizeTextures(GLbyte *pc)
-{
- GLsizei n;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- n = *(GLsizei *)(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 4, n);
- __GLX_SWAP_FLOAT_ARRAY(pc + 4+n*4, n);
-
-}
-
-void __glXDispSwap_Indexubv(GLbyte *pc)
-{
-}
-
-void __glXDispSwap_BlendColor(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_FLOAT(pc + 0);
- __GLX_SWAP_FLOAT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
- __GLX_SWAP_FLOAT(pc + 12);
-
-}
-
-void __glXDispSwap_BlendEquation(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_ColorTableParameterfv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glColorTableParameterfv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_ColorTableParameteriv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glColorTableParameteriv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_CopyColorTable(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
-
-}
-
-void __glXDispSwap_CopyColorSubTable(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
-
-}
-
-void __glXDispSwap_ConvolutionParameterf(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_FLOAT(pc + 8);
-
-}
-
-void __glXDispSwap_ConvolutionParameterfv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glConvolutionParameterfv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_ConvolutionParameteri(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_ConvolutionParameteriv(GLbyte *pc)
-{
- GLenum pname;
- GLint compsize;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 4);
- pname = *(GLenum *)(pc + 4);
- compsize = __glConvolutionParameteriv_size(pname);
- if (compsize < 0) compsize = 0;
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
-
-}
-
-void __glXDispSwap_CopyConvolutionFilter1D(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
-
-}
-
-void __glXDispSwap_CopyConvolutionFilter2D(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
- __GLX_SWAP_INT(pc + 20);
-
-}
-
-void __glXDispSwap_Histogram(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
-
-}
-
-void __glXDispSwap_Minmax(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
-
-}
-
-void __glXDispSwap_ResetHistogram(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_ResetMinmax(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_CopyTexSubImage3D(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
- __GLX_SWAP_INT(pc + 20);
- __GLX_SWAP_INT(pc + 24);
- __GLX_SWAP_INT(pc + 28);
- __GLX_SWAP_INT(pc + 32);
-
-}
-
-void __glXDispSwap_ActiveTextureARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
-
-}
-
-void __glXDispSwap_MultiTexCoord1dvARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 12);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1);
-
-}
-
-void __glXDispSwap_MultiTexCoord1fvARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 4, 1);
-
-}
-
-void __glXDispSwap_MultiTexCoord1ivARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 4, 1);
-
-}
-
-void __glXDispSwap_MultiTexCoord1svARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_SHORT_ARRAY(pc + 4, 1);
-
-}
-
-void __glXDispSwap_MultiTexCoord2dvARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 20);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_INT(pc + 16);
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
-
-}
-
-void __glXDispSwap_MultiTexCoord2fvARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 4, 2);
-
-}
-
-void __glXDispSwap_MultiTexCoord2ivARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 4, 2);
-
-}
-
-void __glXDispSwap_MultiTexCoord2svARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_SHORT_ARRAY(pc + 4, 2);
-
-}
-
-void __glXDispSwap_MultiTexCoord3dvARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 28);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_INT(pc + 24);
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
-
-}
-
-void __glXDispSwap_MultiTexCoord3fvARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 4, 3);
-
-}
-
-void __glXDispSwap_MultiTexCoord3ivARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 4, 3);
-
-}
-
-void __glXDispSwap_MultiTexCoord3svARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_SHORT_ARRAY(pc + 4, 3);
-
-}
-
-void __glXDispSwap_MultiTexCoord4dvARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-
-#ifdef __GLX_ALIGN64
- if ((unsigned long)(pc) & 7) {
- __GLX_MEM_COPY(pc-4, pc, 36);
- pc -= 4;
- }
-#endif
- __GLX_SWAP_INT(pc + 32);
- __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
-
-}
-
-void __glXDispSwap_MultiTexCoord4fvARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_FLOAT_ARRAY(pc + 4, 4);
-
-}
-
-void __glXDispSwap_MultiTexCoord4ivARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_INT_ARRAY(pc + 4, 4);
-
-}
-
-void __glXDispSwap_MultiTexCoord4svARB(GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(pc + 0);
- __GLX_SWAP_SHORT_ARRAY(pc + 4, 4);
-
-}
-
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#include "glxserver.h" +#include "glxext.h" +#include "g_disptab.h" +#include "unpack.h" +#include "compsize.h" + +void __glXDispSwap_CallList(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_ListBase(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_Begin(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_Color3bv(GLbyte *pc) +{ +} + +void __glXDispSwap_Color3dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 24); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Color3fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3); +} + +void __glXDispSwap_Color3iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Color3sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Color3ubv(GLbyte *pc) +{ +} + +void __glXDispSwap_Color3uiv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 3); +} + +void __glXDispSwap_Color3usv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 3); +} + +void __glXDispSwap_Color4bv(GLbyte *pc) +{ +} + +void __glXDispSwap_Color4dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 32); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4); +} + +void __glXDispSwap_Color4fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_Color4iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_Color4sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_Color4ubv(GLbyte *pc) +{ + +} + +void __glXDispSwap_Color4uiv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_Color4usv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_EdgeFlagv(GLbyte *pc) +{ +} + +void __glXDispSwap_End(GLbyte *pc) +{ +} + +void __glXDispSwap_Indexdv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 8); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_Indexfv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_Indexiv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_Indexsv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_Normal3bv(GLbyte *pc) +{ +} + +void __glXDispSwap_Normal3dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 24); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Normal3fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Normal3iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Normal3sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_RasterPos2dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 16); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_RasterPos2fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_RasterPos2iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_RasterPos2sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_RasterPos3dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 24); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_RasterPos3fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_RasterPos3iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_RasterPos3sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_RasterPos4dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 32); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_RasterPos4fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_RasterPos4iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_RasterPos4sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_Rectdv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 32); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2); + __GLX_SWAP_DOUBLE_ARRAY(pc + 16, 2); + +} + +void __glXDispSwap_Rectfv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2); + __GLX_SWAP_FLOAT_ARRAY(pc + 8, 2); + +} + +void __glXDispSwap_Rectiv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 2); + __GLX_SWAP_INT_ARRAY(pc + 8, 2); + +} + +void __glXDispSwap_Rectsv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 2); + __GLX_SWAP_SHORT_ARRAY(pc + 4, 2); + +} + +void __glXDispSwap_TexCoord1dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 8); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_TexCoord1fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_TexCoord1iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_TexCoord1sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_TexCoord2dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 16); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_TexCoord2fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_TexCoord2iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_TexCoord2sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_TexCoord3dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 24); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_TexCoord3fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_TexCoord3iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_TexCoord3sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_TexCoord4dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 32); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_TexCoord4fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_TexCoord4iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_TexCoord4sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_Vertex2dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 16); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_Vertex2fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_Vertex2iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_Vertex2sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_Vertex3dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 24); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Vertex3fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Vertex3iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Vertex3sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_Vertex4dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 32); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_Vertex4fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_Vertex4iv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_Vertex4sv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_ClipPlane(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 36); + pc -= 4; + } +#endif + __GLX_SWAP_INT(pc + 32); + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_ColorMaterial(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_CullFace(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_Fogf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + +} + +void __glXDispSwap_Fogfv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + pname = *(GLenum *)(pc + 0); + compsize = __glFogfv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_FLOAT_ARRAY(pc + 4, compsize); + +} + +void __glXDispSwap_Fogi(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_Fogiv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + pname = *(GLenum *)(pc + 0); + compsize = __glFogiv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT_ARRAY(pc + 4, compsize); + +} + +void __glXDispSwap_FrontFace(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_Hint(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_Lightf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + +} + +void __glXDispSwap_Lightfv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glLightfv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_Lighti(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_Lightiv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glLightiv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_LightModelf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + +} + +void __glXDispSwap_LightModelfv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + pname = *(GLenum *)(pc + 0); + compsize = __glLightModelfv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_FLOAT_ARRAY(pc + 4, compsize); + +} + +void __glXDispSwap_LightModeli(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_LightModeliv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + pname = *(GLenum *)(pc + 0); + compsize = __glLightModeliv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT_ARRAY(pc + 4, compsize); + +} + +void __glXDispSwap_LineStipple(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_SHORT(pc + 4); + +} + +void __glXDispSwap_LineWidth(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + +} + +void __glXDispSwap_Materialf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + +} + +void __glXDispSwap_Materialfv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glMaterialfv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_Materiali(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_Materialiv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glMaterialiv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_PointSize(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + +} + +void __glXDispSwap_PolygonMode(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_Scissor(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + +} + +void __glXDispSwap_ShadeModel(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_TexParameterf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + +} + +void __glXDispSwap_TexParameterfv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glTexParameterfv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_TexParameteri(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_TexParameteriv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glTexParameteriv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_TexEnvf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + +} + +void __glXDispSwap_TexEnvfv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glTexEnvfv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_TexEnvi(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_TexEnviv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glTexEnviv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_TexGend(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 16); + pc -= 4; + } +#endif + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_DOUBLE(pc + 0); + +} + +void __glXDispSwap_TexGendv(GLbyte *pc) +{ + GLenum pname; + GLint cmdlen; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glTexGendv_size(pname); + if (compsize < 0) compsize = 0; + cmdlen = __GLX_PAD(8+compsize*8); + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, cmdlen); + pc -= 4; + } +#endif + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_DOUBLE_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_TexGenf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + +} + +void __glXDispSwap_TexGenfv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glTexGenfv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_TexGeni(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_TexGeniv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glTexGeniv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_InitNames(GLbyte *pc) +{ +} + +void __glXDispSwap_LoadName(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_PassThrough(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + +} + +void __glXDispSwap_PopName(GLbyte *pc) +{ +} + +void __glXDispSwap_PushName(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_DrawBuffer(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_Clear(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_ClearAccum(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + __GLX_SWAP_FLOAT(pc + 12); + +} + +void __glXDispSwap_ClearIndex(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + +} + +void __glXDispSwap_ClearColor(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + __GLX_SWAP_FLOAT(pc + 12); + +} + +void __glXDispSwap_ClearStencil(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_ClearDepth(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 8); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE(pc + 0); + +} + +void __glXDispSwap_StencilMask(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_ColorMask(GLbyte *pc) +{ +} + +void __glXDispSwap_DepthMask(GLbyte *pc) +{ +} + +void __glXDispSwap_IndexMask(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_Accum(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + +} + +void __glXDispSwap_Disable(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_Enable(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_PopAttrib(GLbyte *pc) +{ +} + +void __glXDispSwap_PushAttrib(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_MapGrid1d(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 20); + pc -= 4; + } +#endif + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + +} + +void __glXDispSwap_MapGrid1f(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + +} + +void __glXDispSwap_MapGrid2d(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 40); + pc -= 4; + } +#endif + __GLX_SWAP_INT(pc + 32); + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_INT(pc + 36); + __GLX_SWAP_DOUBLE(pc + 16); + __GLX_SWAP_DOUBLE(pc + 24); + +} + +void __glXDispSwap_MapGrid2f(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_FLOAT(pc + 16); + __GLX_SWAP_FLOAT(pc + 20); + +} + +void __glXDispSwap_EvalCoord1dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 8); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_EvalCoord1fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_EvalCoord2dv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 16); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_EvalCoord2fv(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_EvalMesh1(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_EvalPoint1(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_EvalMesh2(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + +} + +void __glXDispSwap_EvalPoint2(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_AlphaFunc(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + +} + +void __glXDispSwap_BlendFunc(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_LogicOp(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_StencilFunc(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_StencilOp(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_DepthFunc(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_PixelZoom(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + +} + +void __glXDispSwap_PixelTransferf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + +} + +void __glXDispSwap_PixelTransferi(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_PixelMapfv(GLbyte *pc) +{ + GLint mapsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + mapsize = *(GLint *)(pc + 4); + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 8, mapsize); + +} + +void __glXDispSwap_PixelMapuiv(GLbyte *pc) +{ + GLint mapsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + mapsize = *(GLint *)(pc + 4); + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 8, mapsize); + +} + +void __glXDispSwap_PixelMapusv(GLbyte *pc) +{ + GLint mapsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + mapsize = *(GLint *)(pc + 4); + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_SHORT_ARRAY(pc + 8, mapsize); + +} + +void __glXDispSwap_ReadBuffer(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_CopyPixels(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + +} + +void __glXDispSwap_DepthRange(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 16); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + +} + +void __glXDispSwap_Frustum(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 48); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_DOUBLE(pc + 16); + __GLX_SWAP_DOUBLE(pc + 24); + __GLX_SWAP_DOUBLE(pc + 32); + __GLX_SWAP_DOUBLE(pc + 40); + +} + +void __glXDispSwap_LoadIdentity(GLbyte *pc) +{ +} + +void __glXDispSwap_LoadMatrixf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 16); + +} + +void __glXDispSwap_LoadMatrixd(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 128); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 16); + +} + +void __glXDispSwap_MatrixMode(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_MultMatrixf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_FLOAT_ARRAY(pc + 0, 16); + +} + +void __glXDispSwap_MultMatrixd(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 128); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 16); + +} + +void __glXDispSwap_Ortho(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 48); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_DOUBLE(pc + 16); + __GLX_SWAP_DOUBLE(pc + 24); + __GLX_SWAP_DOUBLE(pc + 32); + __GLX_SWAP_DOUBLE(pc + 40); + +} + +void __glXDispSwap_PopMatrix(GLbyte *pc) +{ +} + +void __glXDispSwap_PushMatrix(GLbyte *pc) +{ +} + +void __glXDispSwap_Rotated(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 32); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_DOUBLE(pc + 16); + __GLX_SWAP_DOUBLE(pc + 24); + +} + +void __glXDispSwap_Rotatef(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + __GLX_SWAP_FLOAT(pc + 12); + +} + +void __glXDispSwap_Scaled(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 24); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_DOUBLE(pc + 16); + +} + +void __glXDispSwap_Scalef(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + +} + +void __glXDispSwap_Translated(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 24); + pc -= 4; + } +#endif + __GLX_SWAP_DOUBLE(pc + 0); + __GLX_SWAP_DOUBLE(pc + 8); + __GLX_SWAP_DOUBLE(pc + 16); + +} + +void __glXDispSwap_Translatef(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + +} + +void __glXDispSwap_Viewport(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + +} + +void __glXDispSwap_PolygonOffset(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + +} + +void __glXDispSwap_CopyTexImage1D(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_INT(pc + 20); + __GLX_SWAP_INT(pc + 24); + +} + +void __glXDispSwap_CopyTexImage2D(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_INT(pc + 20); + __GLX_SWAP_INT(pc + 24); + __GLX_SWAP_INT(pc + 28); + +} + +void __glXDispSwap_CopyTexSubImage1D(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_INT(pc + 20); + +} + +void __glXDispSwap_CopyTexSubImage2D(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_INT(pc + 20); + __GLX_SWAP_INT(pc + 24); + __GLX_SWAP_INT(pc + 28); + +} + +void __glXDispSwap_BindTexture(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_PrioritizeTextures(GLbyte *pc) +{ + GLsizei n; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + n = *(GLsizei *)(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 4, n); + __GLX_SWAP_FLOAT_ARRAY(pc + 4+n*4, n); + +} + +void __glXDispSwap_Indexubv(GLbyte *pc) +{ +} + +void __glXDispSwap_BlendColor(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_FLOAT(pc + 0); + __GLX_SWAP_FLOAT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + __GLX_SWAP_FLOAT(pc + 12); + +} + +void __glXDispSwap_BlendEquation(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_ColorTableParameterfv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glColorTableParameterfv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_ColorTableParameteriv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glColorTableParameteriv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_CopyColorTable(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + +} + +void __glXDispSwap_CopyColorSubTable(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + +} + +void __glXDispSwap_ConvolutionParameterf(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_FLOAT(pc + 8); + +} + +void __glXDispSwap_ConvolutionParameterfv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glConvolutionParameterfv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_ConvolutionParameteri(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_ConvolutionParameteriv(GLbyte *pc) +{ + GLenum pname; + GLint compsize; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 4); + pname = *(GLenum *)(pc + 4); + compsize = __glConvolutionParameteriv_size(pname); + if (compsize < 0) compsize = 0; + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 8, compsize); + +} + +void __glXDispSwap_CopyConvolutionFilter1D(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + +} + +void __glXDispSwap_CopyConvolutionFilter2D(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_INT(pc + 20); + +} + +void __glXDispSwap_Histogram(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + +} + +void __glXDispSwap_Minmax(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + +} + +void __glXDispSwap_ResetHistogram(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_ResetMinmax(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_CopyTexSubImage3D(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_INT(pc + 20); + __GLX_SWAP_INT(pc + 24); + __GLX_SWAP_INT(pc + 28); + __GLX_SWAP_INT(pc + 32); + +} + +void __glXDispSwap_ActiveTextureARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + +} + +void __glXDispSwap_MultiTexCoord1dvARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 12); + pc -= 4; + } +#endif + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1); + +} + +void __glXDispSwap_MultiTexCoord1fvARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 4, 1); + +} + +void __glXDispSwap_MultiTexCoord1ivARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 4, 1); + +} + +void __glXDispSwap_MultiTexCoord1svARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_SHORT_ARRAY(pc + 4, 1); + +} + +void __glXDispSwap_MultiTexCoord2dvARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 20); + pc -= 4; + } +#endif + __GLX_SWAP_INT(pc + 16); + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2); + +} + +void __glXDispSwap_MultiTexCoord2fvARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 4, 2); + +} + +void __glXDispSwap_MultiTexCoord2ivARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 4, 2); + +} + +void __glXDispSwap_MultiTexCoord2svARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_SHORT_ARRAY(pc + 4, 2); + +} + +void __glXDispSwap_MultiTexCoord3dvARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 28); + pc -= 4; + } +#endif + __GLX_SWAP_INT(pc + 24); + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3); + +} + +void __glXDispSwap_MultiTexCoord3fvARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 4, 3); + +} + +void __glXDispSwap_MultiTexCoord3ivARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 4, 3); + +} + +void __glXDispSwap_MultiTexCoord3svARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_SHORT_ARRAY(pc + 4, 3); + +} + +void __glXDispSwap_MultiTexCoord4dvARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + +#ifdef __GLX_ALIGN64 + if ((unsigned long)(pc) & 7) { + __GLX_MEM_COPY(pc-4, pc, 36); + pc -= 4; + } +#endif + __GLX_SWAP_INT(pc + 32); + __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4); + +} + +void __glXDispSwap_MultiTexCoord4fvARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_FLOAT_ARRAY(pc + 4, 4); + +} + +void __glXDispSwap_MultiTexCoord4ivARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_INT_ARRAY(pc + 4, 4); + +} + +void __glXDispSwap_MultiTexCoord4svARB(GLbyte *pc) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(pc + 0); + __GLX_SWAP_SHORT_ARRAY(pc + 4, 4); + +} + diff --git a/xorg-server/hw/dmx/glxProxy/glxcmds.c b/xorg-server/hw/dmx/glxProxy/glxcmds.c index a76201da0..fb4bce850 100644 --- a/xorg-server/hw/dmx/glxProxy/glxcmds.c +++ b/xorg-server/hw/dmx/glxProxy/glxcmds.c @@ -52,6 +52,8 @@ #include "glxvisuals.h" #include "glxswap.h" +#include "glxcmds.h" + #ifdef PANORAMIX #include "panoramiXsrv.h" #endif diff --git a/xorg-server/hw/dmx/glxProxy/glxcmds.h b/xorg-server/hw/dmx/glxProxy/glxcmds.h new file mode 100644 index 000000000..ae866be29 --- /dev/null +++ b/xorg-server/hw/dmx/glxProxy/glxcmds.h @@ -0,0 +1,37 @@ +/* + * Copyright 2011 Apple Inc. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __GLX_cmds_h__ +#define __GLX_cmds_h__ + +extern int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc); +extern int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc); +extern int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc); +extern int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc); +extern int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc); + +#endif /* !__GLX_cmds_h__ */ diff --git a/xorg-server/hw/dmx/glxProxy/glxcmdsswap.c b/xorg-server/hw/dmx/glxProxy/glxcmdsswap.c index ca41c1585..f28a79df6 100644 --- a/xorg-server/hw/dmx/glxProxy/glxcmdsswap.c +++ b/xorg-server/hw/dmx/glxProxy/glxcmdsswap.c @@ -1,1059 +1,1062 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include "glxserver.h"
-#include "glxutil.h"
-#include <GL/glxtokens.h>
-#include <g_disptab.h>
-#include <pixmapstr.h>
-#include <windowstr.h>
-#include "unpack.h"
-#include "glxext.h"
-#include "glxvendor.h"
-
-extern int glxIsExtensionSupported( char *ext );
-
-/************************************************************************/
-
-/*
-** Byteswapping versions of GLX commands. In most cases they just swap
-** the incoming arguments and then call the unswapped routine. For commands
-** that have replies, a separate swapping routine for the reply is provided;
-** it is called at the end of the unswapped routine.
-*/
-
-int __glXSwapCreateContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->visual);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->shareList);
-
- return __glXCreateContext(cl, pc);
-}
-
-int __glXSwapCreateNewContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->shareList);
-
- return __glXCreateNewContext(cl, pc);
-}
-
-int __glXSwapCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->shareList);
-
- return __glXCreateContextWithConfigSGIX(cl, pc);
-}
-
-int __glXSwapQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryMaxSwapBarriersSGIXReq *req =
- (xGLXQueryMaxSwapBarriersSGIXReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
-
- return __glXQueryMaxSwapBarriersSGIX(cl, pc);
-}
-
-int __glXSwapBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->barrier);
-
- return __glXBindSwapBarrierSGIX(cl, pc);
-}
-
-int __glXSwapJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->member);
-
- return __glXJoinSwapGroupSGIX(cl, pc);
-}
-
-int __glXSwapDestroyContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
-
- return __glXDestroyContext(cl, pc);
-}
-
-int __glXSwapMakeCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->oldContextTag);
-
- return __glXMakeCurrent(cl, pc);
-}
-
-int __glXSwapMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->readdrawable);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->oldContextTag);
-
- return __glXMakeContextCurrent(cl, pc);
-}
-
-int __glXSwapMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->readable);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->oldContextTag);
-
- return __glXMakeCurrentReadSGI(cl, pc);
-}
-
-int __glXSwapIsDirect(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
-
- return __glXIsDirect(cl, pc);
-}
-
-int __glXSwapQueryVersion(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->majorVersion);
- __GLX_SWAP_INT(&req->minorVersion);
-
- return __glXQueryVersion(cl, pc);
-}
-
-int __glXSwapWaitGL(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- return __glXWaitGL(cl, pc);
-}
-
-int __glXSwapWaitX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- return __glXWaitX(cl, pc);
-}
-
-int __glXSwapCopyContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->source);
- __GLX_SWAP_INT(&req->dest);
- __GLX_SWAP_INT(&req->mask);
-
- return __glXCopyContext(cl, pc);
-}
-
-int __glXSwapGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
- xGLXGetVisualConfigsReply reply;
- __GLXscreenInfo *pGlxScreen;
- __GLXvisualConfig *pGlxVisual;
- CARD32 buf[__GLX_TOTAL_CONFIG];
- unsigned int screen;
- int i, p;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_INT(&req->screen);
- screen = req->screen;
- if (screen >= screenInfo.numScreens) {
- /* The client library must send a valid screen number. */
- client->errorValue = screen;
- return BadValue;
- }
- pGlxScreen = &__glXActiveScreens[screen];
-
- reply.numVisuals = pGlxScreen->numGLXVisuals;
- reply.numProps = __GLX_TOTAL_CONFIG;
- reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
- __GLX_TOTAL_CONFIG) >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- __GLX_SWAP_INT(&reply.numVisuals);
- __GLX_SWAP_INT(&reply.numProps);
- WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
-
- for (i=0; i < pGlxScreen->numVisuals; i++) {
- pGlxVisual = &pGlxScreen->pGlxVisual[i];
- if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) {
- /* not a usable visual */
- continue;
- }
- p = 0;
- buf[p++] = pGlxVisual->vid;
- buf[p++] = pGlxVisual->class;
- buf[p++] = pGlxVisual->rgba;
-
- buf[p++] = pGlxVisual->redSize;
- buf[p++] = pGlxVisual->greenSize;
- buf[p++] = pGlxVisual->blueSize;
- buf[p++] = pGlxVisual->alphaSize;
- buf[p++] = pGlxVisual->accumRedSize;
- buf[p++] = pGlxVisual->accumGreenSize;
- buf[p++] = pGlxVisual->accumBlueSize;
- buf[p++] = pGlxVisual->accumAlphaSize;
-
- buf[p++] = pGlxVisual->doubleBuffer;
- buf[p++] = pGlxVisual->stereo;
-
- buf[p++] = pGlxVisual->bufferSize;
- buf[p++] = pGlxVisual->depthSize;
- buf[p++] = pGlxVisual->stencilSize;
- buf[p++] = pGlxVisual->auxBuffers;
- buf[p++] = pGlxVisual->level;
- /*
- ** Add token/value pairs for extensions.
- */
- buf[p++] = GLX_VISUAL_CAVEAT_EXT;
- buf[p++] = pGlxVisual->visualRating;
- buf[p++] = GLX_TRANSPARENT_TYPE_EXT;
- buf[p++] = pGlxVisual->transparentPixel;
- buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentRed;
- buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentGreen;
- buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentBlue;
- buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentAlpha;
- buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentIndex;
-
- __GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG);
- WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
- (char *)buf);
- }
- return Success;
-}
-
-int __glXSwapCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->visual);
- __GLX_SWAP_INT(&req->pixmap);
- __GLX_SWAP_INT(&req->glxpixmap);
-
- return __glXCreateGLXPixmap(cl, pc);
-}
-
-int __glXSwapCreatePixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->pixmap);
- __GLX_SWAP_INT(&req->glxpixmap);
- __GLX_SWAP_INT(&req->numAttribs);
-
- return __glXCreatePixmap(cl, pc);
-}
-
-int __glXSwapDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->glxpixmap);
-
- return __glXDestroyGLXPixmap(cl, pc);
-}
-
-int __glXSwapSwapBuffers(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(&req->drawable);
-
- return __glXSwapBuffers(cl, pc);
-}
-
-int __glXSwapUseXFont(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(&req->font);
- __GLX_SWAP_INT(&req->first);
- __GLX_SWAP_INT(&req->count);
- __GLX_SWAP_INT(&req->listBase);
-
- return __glXUseXFont(cl, pc);
-}
-
-
-int __glXSwapQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryExtensionsStringReq *req = NULL;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
-
- return __glXQueryExtensionsString(cl, pc);
-}
-
-int __glXSwapQueryServerString(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->name);
-
- return __glXQueryServerString(cl, pc);
-}
-
-int __glXSwapClientInfo(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXClientInfoReq *req = (xGLXClientInfoReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->major);
- __GLX_SWAP_INT(&req->minor);
- __GLX_SWAP_INT(&req->numbytes);
-
- return __glXClientInfo(cl, pc);
-}
-
-int __glXSwapQueryContextInfoEXT(__GLXclientState *cl, char *pc)
-{
- xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
-
- return __glXQueryContextInfoEXT(cl, (GLbyte *)pc);
-}
-
-/************************************************************************/
-
-/*
-** Swap replies.
-*/
-
-void __glXSwapMakeCurrentReply(ClientPtr client, xGLXMakeCurrentReadSGIReply *reply)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->contextTag);
- __GLX_SWAP_INT(&reply->writeVid);
- __GLX_SWAP_INT(&reply->writeType);
- __GLX_SWAP_INT(&reply->readVid);
- __GLX_SWAP_INT(&reply->readType);
- WriteToClient(client, sz_xGLXMakeCurrentReadSGIReply, (char *)reply);
-}
-
-void __glXSwapIsDirectReply(ClientPtr client, xGLXIsDirectReply *reply)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- WriteToClient(client, sz_xGLXIsDirectReply, (char *)reply);
-}
-
-void __glXSwapQueryVersionReply(ClientPtr client, xGLXQueryVersionReply *reply)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->majorVersion);
- __GLX_SWAP_INT(&reply->minorVersion);
- WriteToClient(client, sz_xGLXQueryVersionReply, (char *)reply);
-}
-
-void glxSwapQueryExtensionsStringReply(ClientPtr client,
- xGLXQueryExtensionsStringReply *reply, char *buf)
-{
- int length = reply->length;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->n);
- WriteToClient(client, sz_xGLXQueryExtensionsStringReply, (char *)reply);
- __GLX_SWAP_INT_ARRAY((int *)buf, length);
- WriteToClient(client, length << 2, buf);
-}
-
-void glxSwapQueryServerStringReply(ClientPtr client,
- xGLXQueryServerStringReply *reply, char *buf)
-{
- int length = reply->length;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->n);
- WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)reply);
- /** no swap is needed for an array of chars **/
- /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */
- WriteToClient(client, length << 2, buf);
-}
-
-void __glXSwapQueryContextInfoEXTReply(ClientPtr client, xGLXQueryContextInfoEXTReply *reply, int *buf)
-{
- int length = reply->length;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->n);
- WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)reply);
- __GLX_SWAP_INT_ARRAY((int *)buf, length);
- WriteToClient(client, length << 2, (char *)buf);
-}
-
-
-void __glXSwapQueryContextReply(ClientPtr client,
- xGLXQueryContextReply *reply, int *buf)
-{
- int length = reply->length;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->n);
- WriteToClient(client, sz_xGLXQueryContextReply, (char *)reply);
- __GLX_SWAP_INT_ARRAY((int *)buf, length);
- WriteToClient(client, length << 2, (char *)buf);
-}
-
-void __glXSwapGetDrawableAttributesReply(ClientPtr client,
- xGLXGetDrawableAttributesReply *reply, int *buf)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->numAttribs);
- __GLX_SWAP_INT_ARRAY( buf, reply->length );
- WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)reply);
- WriteToClient(client, reply->length << 2, (char *)buf);
-}
-
-void __glXSwapQueryMaxSwapBarriersSGIXReply(ClientPtr client, xGLXQueryMaxSwapBarriersSGIXReply *reply)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->max);
- WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, (char *)reply);
-}
-
-/************************************************************************/
-
-/*
-** Render and Renderlarge are not in the GLX API. They are used by the GLX
-** client library to send batches of GL rendering commands.
-*/
-
-int __glXSwapRender(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXRenderReq *req;
- int left;
- __GLXrenderHeader *hdr;
- ClientPtr client = cl->client;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- /*
- ** NOTE: much of this code also appears in the nonswapping version of this
- ** routine, __glXRender(). Any changes made here should also be
- ** duplicated there.
- */
-
- req = (xGLXRenderReq *) pc;
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- pc += sz_xGLXRenderReq;
- left = (req->length << 2) - sz_xGLXRenderReq;
- while (left > 0) {
- void (* proc)(GLbyte *);
- CARD16 opcode;
-
- /*
- ** Verify that the header length and the overall length agree.
- ** Also, each command must be word aligned.
- */
- hdr = (__GLXrenderHeader *) pc;
- __GLX_SWAP_SHORT(&hdr->length);
- __GLX_SWAP_SHORT(&hdr->opcode);
-
- /*
- * call the command procedure to swap any arguments
- */
- opcode = hdr->opcode;
- if ( (opcode >= __GLX_MIN_RENDER_OPCODE) &&
- (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
- proc = __glXSwapRenderTable[opcode];
-#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
- } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) &&
- (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
- int index = opcode - __GLX_MIN_RENDER_OPCODE_EXT;
- __GLXRenderSwapInfo *info = &__glXSwapRenderTable_EXT[index];
- if (info->swapfunc) {
- proc = info->swapfunc;
- }
- else {
- proc = NULL;
- if (info->elem_size == 4 && info->nelems > 0) {
- __GLX_SWAP_INT_ARRAY( (int *)(pc + __GLX_RENDER_HDR_SIZE),
- info->nelems );
- }
- else if (info->elem_size == 2 && info->nelems > 0) {
- __GLX_SWAP_SHORT_ARRAY( (short *)(pc + __GLX_RENDER_HDR_SIZE),
- info->nelems );
- }
- else if (info->elem_size == 8 && info->nelems > 0) {
- __GLX_SWAP_DOUBLE_ARRAY( (double *)(pc + __GLX_RENDER_HDR_SIZE),
- info->nelems );
- }
- }
-#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
- } else {
- client->errorValue = 0;
- return __glXBadRenderRequest;
- }
-
- if (proc != NULL)
- (*proc)(pc + __GLX_RENDER_HDR_SIZE);
-
- /*
- * proceed to the next command
- */
- pc += hdr->length;
- left -= hdr->length;
- }
-
- return __glXRender( cl, (GLbyte *)req );
-}
-
-/*
-** Execute a large rendering request (one that spans multiple X requests).
-*/
-int __glXSwapRenderLarge(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXRenderLargeReq *req;
- __GLXrenderLargeHeader *hdr;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- req = (xGLXRenderLargeReq *) pc;
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(&req->dataBytes);
- __GLX_SWAP_SHORT(&req->requestNumber);
- __GLX_SWAP_SHORT(&req->requestTotal);
-
- pc += sz_xGLXRenderLargeReq;
-
- if (req->requestNumber == 1) {
- void (* proc)(GLbyte *) = NULL;
- __GLXRenderSwapInfo *info = NULL;
- CARD16 opcode;
-
- hdr = (__GLXrenderLargeHeader *) pc;
- __GLX_SWAP_INT(&hdr->length);
- __GLX_SWAP_INT(&hdr->opcode);
-
- /*
- * call the command procedure to swap any arguments
- * Note that we are assuming that all arguments that needs to be
- * swaped are on the first req only !
- */
- opcode = hdr->opcode;
- if ( (opcode >= __GLX_MIN_RENDER_OPCODE) &&
- (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
- proc = __glXSwapRenderTable[opcode];
-#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
- } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) &&
- (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
- int index = opcode - __GLX_MIN_RENDER_OPCODE_EXT;
- info = &__glXSwapRenderTable_EXT[index];
- if (info->swapfunc) {
- proc = info->swapfunc;
- }
-#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
- } else {
- client->errorValue = 0;
- cl->largeCmdRequestsTotal = 0;
- return __glXBadLargeRequest;
- }
-
- /*
- ** Make enough space in the buffer, then copy the entire request.
- */
- if (cl->largeCmdBufSize < hdr->length) {
- if (!cl->largeCmdBuf) {
- cl->largeCmdBuf = (GLbyte *) malloc(hdr->length);
- } else {
- cl->largeCmdBuf = (GLbyte *) realloc(cl->largeCmdBuf, hdr->length);
- }
- if (!cl->largeCmdBuf) {
- cl->largeCmdRequestsTotal = 0;
- return BadAlloc;
- }
- cl->largeCmdBufSize = hdr->length;
- }
- memcpy(cl->largeCmdBuf, pc, req->dataBytes);
-
- cl->largeCmdBytesSoFar = req->dataBytes;
- cl->largeCmdBytesTotal = hdr->length;
- cl->largeCmdRequestsSoFar = 1;
- cl->largeCmdRequestsTotal = req->requestTotal;
- cl->largeCmdRequestsSwapProc = proc;
- cl->largeCmdMaxReqDataSize = req->dataBytes;
- cl->largeCmdRequestsSwap_info = info;
-
- return Success;
-
-
- }
- else if (req->requestNumber < cl->largeCmdRequestsTotal) {
- /*
- * This is not the first nor last request - just copy the data
- */
- if ( cl->largeCmdBytesSoFar + req->dataBytes > cl->largeCmdBytesTotal) {
- cl->largeCmdRequestsTotal = 0;
- return __glXBadLargeRequest;
- }
-
- memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar,
- pc, req->dataBytes);
-
- cl->largeCmdBytesSoFar += req->dataBytes;
-
- if (req->dataBytes > cl->largeCmdMaxReqDataSize)
- cl->largeCmdMaxReqDataSize = req->dataBytes;
-
- return Success;
- }
- else if (req->requestNumber == cl->largeCmdRequestsTotal) {
- /*
- * this is the last request
- * copy the remainder bytes, call the procedure to swap any
- * needed data, and then call to transfer the command to all
- * back-end servers
- */
- if ( cl->largeCmdBytesSoFar + req->dataBytes > cl->largeCmdBytesTotal) {
- cl->largeCmdRequestsTotal = 0;
- return __glXBadLargeRequest;
- }
-
- memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar,
- pc, req->dataBytes);
-
- cl->largeCmdBytesSoFar += req->dataBytes;
-
- if (req->dataBytes > cl->largeCmdMaxReqDataSize)
- cl->largeCmdMaxReqDataSize = req->dataBytes;
-
- if (cl->largeCmdRequestsSwapProc != NULL) {
- (*cl->largeCmdRequestsSwapProc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
- }
- else if (cl->largeCmdRequestsSwap_info &&
- cl->largeCmdRequestsSwap_info->nelems > 0) {
- if (cl->largeCmdRequestsSwap_info->elem_size == 4) {
- __GLX_SWAP_INT_ARRAY( (int *)(pc + __GLX_RENDER_LARGE_HDR_SIZE),
- cl->largeCmdRequestsSwap_info->nelems );
- }
- else if (cl->largeCmdRequestsSwap_info->elem_size == 2) {
- __GLX_SWAP_SHORT_ARRAY( (short *)(pc + __GLX_RENDER_LARGE_HDR_SIZE),
- cl->largeCmdRequestsSwap_info->nelems );
- }
- else if (cl->largeCmdRequestsSwap_info->elem_size == 8) {
- __GLX_SWAP_DOUBLE_ARRAY( (double *)(pc + __GLX_RENDER_LARGE_HDR_SIZE),
- cl->largeCmdRequestsSwap_info->nelems );
- }
- }
-
- cl->largeCmdRequestsTotal = 0;
- return( __glXSendLargeCommand(cl, req->contextTag) );
-
- }
- else {
- cl->largeCmdRequestsTotal = 0;
- return __glXBadLargeRequest;
- }
-
-}
-
-/************************************************************************/
-
-/*
-** No support is provided for the vendor-private requests other than
-** allocating these entry points in the dispatch table.
-*/
-
-int __glXSwapVendorPrivate(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req;
- CARD32 vendorCode;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- req = (xGLXVendorPrivateReq *) pc;
- vendorCode = req->vendorCode;
- __GLX_SWAP_INT(&vendorCode);
-
-
- switch( vendorCode ) {
-
- case X_GLvop_DeleteTexturesEXT:
- return __glXVForwardSingleReqSwap( cl, pc );
- break;
-
- case X_GLXvop_SwapIntervalSGI:
- if (glxIsExtensionSupported("SGI_swap_control")) {
- return __glXVForwardSingleReqSwap( cl, pc );
- }
- else {
- return Success;
- }
- break;
-
-#if 0 /* glx 1.3 */
- case X_GLXvop_CreateGLXVideoSourceSGIX:
- break;
- case X_GLXvop_DestroyGLXVideoSourceSGIX:
- break;
- case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
- break;
- case X_GLXvop_DestroyGLXPbufferSGIX:
- break;
- case X_GLXvop_ChangeDrawableAttributesSGIX:
- break;
-#endif
-
- case X_GLXvop_JoinSwapGroupSGIX:
- return __glXSwapJoinSwapGroupSGIX( cl, pc );
- break;
-
- case X_GLXvop_BindSwapBarrierSGIX:
- return __glXSwapBindSwapBarrierSGIX( cl, pc );
- break;
-
- case X_GLXvop_CreateContextWithConfigSGIX:
- return __glXSwapCreateContextWithConfigSGIX( cl, pc );
- break;
-
- default:
- /*
- ** unsupported private request
- */
- cl->client->errorValue = req->vendorCode;
- return __glXUnsupportedPrivateRequest;
- }
-
-}
-
-int __glXSwapVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateWithReplyReq *req;
- CARD32 vendorCode;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- req = (xGLXVendorPrivateWithReplyReq *) pc;
- vendorCode = req->vendorCode;
- __GLX_SWAP_INT(&vendorCode);
-
- switch( vendorCode ) {
-
- case X_GLvop_GetConvolutionFilterEXT:
- case X_GLvop_GetSeparableFilterEXT:
- case X_GLvop_GetHistogramEXT:
- case X_GLvop_GetMinmaxEXT:
- return( __glXNoSuchSingleOpcode(cl, pc) );
- break;
-
- case X_GLvop_GetConvolutionParameterfvEXT:
- case X_GLvop_GetConvolutionParameterivEXT:
- case X_GLvop_GetHistogramParameterivEXT:
- case X_GLvop_GetMinmaxParameterfvEXT:
- case X_GLvop_GetMinmaxParameterivEXT:
- case X_GLvop_GenTexturesEXT:
- return( __glXVForwardAllWithReplySwapiv(cl, pc) );
- break;
-
- case X_GLvop_AreTexturesResidentEXT:
- case X_GLvop_IsTextureEXT:
- return( __glXVForwardPipe0WithReplySwap(cl, pc) );
- break;
-
-#if 0 /* glx1.3 */
- case X_GLvop_GetDetailTexFuncSGIS:
- case X_GLvop_GetSharpenTexFuncSGIS:
- case X_GLvop_GetColorTableSGI:
- case X_GLvop_GetColorTableParameterfvSGI:
- case X_GLvop_GetColorTableParameterivSGI:
- case X_GLvop_GetTexFilterFuncSGIS:
- case X_GLvop_GetInstrumentsSGIX:
- case X_GLvop_InstrumentsBufferSGIX:
- case X_GLvop_PollInstrumentsSGIX:
- case X_GLvop_FlushRasterSGIX:
- case X_GLXvop_CreateGLXPbufferSGIX:
- case X_GLXvop_GetDrawableAttributesSGIX:
- case X_GLXvop_QueryHyperpipeNetworkSGIX:
- case X_GLXvop_QueryHyperpipeConfigSGIX:
- case X_GLXvop_HyperpipeConfigSGIX:
- case X_GLXvop_DestroyHyperpipeConfigSGIX:
-#endif
- case X_GLXvop_QueryMaxSwapBarriersSGIX:
- return( __glXSwapQueryMaxSwapBarriersSGIX(cl, pc) );
- break;
-
- case X_GLXvop_GetFBConfigsSGIX:
- return( __glXSwapGetFBConfigsSGIX(cl, pc) );
- break;
-
- case X_GLXvop_MakeCurrentReadSGI:
- return( __glXSwapMakeCurrentReadSGI(cl, pc) );
- break;
-
- case X_GLXvop_QueryContextInfoEXT:
- return( __glXSwapQueryContextInfoEXT(cl,(char *)pc) );
- break;
-
- default:
- /*
- ** unsupported private request
- */
- cl->client->errorValue = req->vendorCode;
- return __glXUnsupportedPrivateRequest;
- }
-
-}
-
-int __glXSwapGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
-
- return __glXGetFBConfigs(cl, pc);
-}
-
-int __glXSwapGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc;
- xGLXGetFBConfigsReq new_req;
-
- new_req.reqType = req->reqType;
- new_req.glxCode = req->glxCode;
- new_req.length = req->length;
- new_req.screen = req->screen;
-
- return( __glXSwapGetFBConfigs( cl, (GLbyte *)&new_req ) );
-}
-
-int __glXSwapCreateWindow(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->window);
- __GLX_SWAP_INT(&req->glxwindow);
- __GLX_SWAP_INT(&req->numAttribs);
-
- return( __glXCreateWindow( cl, (GLbyte *)pc ) );
-}
-
-int __glXSwapDestroyWindow(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->glxwindow);
-
- return( __glXDestroyWindow( cl, (GLbyte *)pc ) );
-}
-
-int __glXSwapQueryContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryContextReq *req = (xGLXQueryContextReq *)pc;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
-
- return( __glXQueryContext(cl, (GLbyte *)pc) );
-
-}
-
-int __glXSwapCreatePbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc;
- int nattr = req->numAttribs;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->pbuffer);
- __GLX_SWAP_INT(&req->numAttribs);
- __GLX_SWAP_INT_ARRAY( (int *)(req+1), nattr*2 );
-
- return( __glXCreatePbuffer( cl, pc ) );
-}
-
-int __glXSwapDestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->pbuffer);
-
- return( __glXDestroyPbuffer( cl, (GLbyte *)pc ) );
-}
-
-int __glXSwapGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
-
- return( __glXGetDrawableAttributes(cl, pc) );
-}
-
-int __glXSwapChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->numAttribs);
- __GLX_SWAP_INT_ARRAY( (int *)(req+1), req->numAttribs * 2 );
-
- return( __glXChangeDrawableAttributes(cl, pc) );
-}
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#include "glxserver.h" +#include "glxutil.h" +#include <GL/glxtokens.h> +#include <g_disptab.h> +#include <pixmapstr.h> +#include <windowstr.h> +#include "unpack.h" +#include "glxcmds.h" +#include "glxext.h" +#include "glxvendor.h" + +extern int glxIsExtensionSupported( char *ext ); + +int __glXSwapGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc); + +/************************************************************************/ + +/* +** Byteswapping versions of GLX commands. In most cases they just swap +** the incoming arguments and then call the unswapped routine. For commands +** that have replies, a separate swapping routine for the reply is provided; +** it is called at the end of the unswapped routine. +*/ + +int __glXSwapCreateContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->visual); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->shareList); + + return __glXCreateContext(cl, pc); +} + +int __glXSwapCreateNewContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->shareList); + + return __glXCreateNewContext(cl, pc); +} + +int __glXSwapCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->shareList); + + return __glXCreateContextWithConfigSGIX(cl, pc); +} + +int __glXSwapQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXQueryMaxSwapBarriersSGIXReq *req = + (xGLXQueryMaxSwapBarriersSGIXReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + + return __glXQueryMaxSwapBarriersSGIX(cl, pc); +} + +int __glXSwapBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->barrier); + + return __glXBindSwapBarrierSGIX(cl, pc); +} + +int __glXSwapJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->member); + + return __glXJoinSwapGroupSGIX(cl, pc); +} + +int __glXSwapDestroyContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + + return __glXDestroyContext(cl, pc); +} + +int __glXSwapMakeCurrent(__GLXclientState *cl, GLbyte *pc) +{ + xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->oldContextTag); + + return __glXMakeCurrent(cl, pc); +} + +int __glXSwapMakeContextCurrent(__GLXclientState *cl, GLbyte *pc) +{ + xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->readdrawable); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->oldContextTag); + + return __glXMakeContextCurrent(cl, pc); +} + +int __glXSwapMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) +{ + xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->readable); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->oldContextTag); + + return __glXMakeCurrentReadSGI(cl, pc); +} + +int __glXSwapIsDirect(__GLXclientState *cl, GLbyte *pc) +{ + xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + + return __glXIsDirect(cl, pc); +} + +int __glXSwapQueryVersion(__GLXclientState *cl, GLbyte *pc) +{ + xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->majorVersion); + __GLX_SWAP_INT(&req->minorVersion); + + return __glXQueryVersion(cl, pc); +} + +int __glXSwapWaitGL(__GLXclientState *cl, GLbyte *pc) +{ + xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + return __glXWaitGL(cl, pc); +} + +int __glXSwapWaitX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXWaitXReq *req = (xGLXWaitXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + return __glXWaitX(cl, pc); +} + +int __glXSwapCopyContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->source); + __GLX_SWAP_INT(&req->dest); + __GLX_SWAP_INT(&req->mask); + + return __glXCopyContext(cl, pc); +} + +int __glXSwapGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; + xGLXGetVisualConfigsReply reply; + __GLXscreenInfo *pGlxScreen; + __GLXvisualConfig *pGlxVisual; + CARD32 buf[__GLX_TOTAL_CONFIG]; + unsigned int screen; + int i, p; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_INT(&req->screen); + screen = req->screen; + if (screen >= screenInfo.numScreens) { + /* The client library must send a valid screen number. */ + client->errorValue = screen; + return BadValue; + } + pGlxScreen = &__glXActiveScreens[screen]; + + reply.numVisuals = pGlxScreen->numGLXVisuals; + reply.numProps = __GLX_TOTAL_CONFIG; + reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 * + __GLX_TOTAL_CONFIG) >> 2; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + __GLX_SWAP_SHORT(&reply.sequenceNumber); + __GLX_SWAP_INT(&reply.length); + __GLX_SWAP_INT(&reply.numVisuals); + __GLX_SWAP_INT(&reply.numProps); + WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); + + for (i=0; i < pGlxScreen->numVisuals; i++) { + pGlxVisual = &pGlxScreen->pGlxVisual[i]; + if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) { + /* not a usable visual */ + continue; + } + p = 0; + buf[p++] = pGlxVisual->vid; + buf[p++] = pGlxVisual->class; + buf[p++] = pGlxVisual->rgba; + + buf[p++] = pGlxVisual->redSize; + buf[p++] = pGlxVisual->greenSize; + buf[p++] = pGlxVisual->blueSize; + buf[p++] = pGlxVisual->alphaSize; + buf[p++] = pGlxVisual->accumRedSize; + buf[p++] = pGlxVisual->accumGreenSize; + buf[p++] = pGlxVisual->accumBlueSize; + buf[p++] = pGlxVisual->accumAlphaSize; + + buf[p++] = pGlxVisual->doubleBuffer; + buf[p++] = pGlxVisual->stereo; + + buf[p++] = pGlxVisual->bufferSize; + buf[p++] = pGlxVisual->depthSize; + buf[p++] = pGlxVisual->stencilSize; + buf[p++] = pGlxVisual->auxBuffers; + buf[p++] = pGlxVisual->level; + /* + ** Add token/value pairs for extensions. + */ + buf[p++] = GLX_VISUAL_CAVEAT_EXT; + buf[p++] = pGlxVisual->visualRating; + buf[p++] = GLX_TRANSPARENT_TYPE_EXT; + buf[p++] = pGlxVisual->transparentPixel; + buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT; + buf[p++] = pGlxVisual->transparentRed; + buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT; + buf[p++] = pGlxVisual->transparentGreen; + buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT; + buf[p++] = pGlxVisual->transparentBlue; + buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT; + buf[p++] = pGlxVisual->transparentAlpha; + buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT; + buf[p++] = pGlxVisual->transparentIndex; + + __GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG); + WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, + (char *)buf); + } + return Success; +} + +int __glXSwapCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->visual); + __GLX_SWAP_INT(&req->pixmap); + __GLX_SWAP_INT(&req->glxpixmap); + + return __glXCreateGLXPixmap(cl, pc); +} + +int __glXSwapCreatePixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->pixmap); + __GLX_SWAP_INT(&req->glxpixmap); + __GLX_SWAP_INT(&req->numAttribs); + + return __glXCreatePixmap(cl, pc); +} + +int __glXSwapDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->glxpixmap); + + return __glXDestroyGLXPixmap(cl, pc); +} + +int __glXSwapSwapBuffers(__GLXclientState *cl, GLbyte *pc) +{ + xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(&req->drawable); + + return __glXSwapBuffers(cl, pc); +} + +int __glXSwapUseXFont(__GLXclientState *cl, GLbyte *pc) +{ + xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(&req->font); + __GLX_SWAP_INT(&req->first); + __GLX_SWAP_INT(&req->count); + __GLX_SWAP_INT(&req->listBase); + + return __glXUseXFont(cl, pc); +} + + +int __glXSwapQueryExtensionsString(__GLXclientState *cl, GLbyte *pc) +{ + xGLXQueryExtensionsStringReq *req = NULL; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + + return __glXQueryExtensionsString(cl, pc); +} + +int __glXSwapQueryServerString(__GLXclientState *cl, GLbyte *pc) +{ + xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->name); + + return __glXQueryServerString(cl, pc); +} + +int __glXSwapClientInfo(__GLXclientState *cl, GLbyte *pc) +{ + xGLXClientInfoReq *req = (xGLXClientInfoReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->major); + __GLX_SWAP_INT(&req->minor); + __GLX_SWAP_INT(&req->numbytes); + + return __glXClientInfo(cl, pc); +} + +int __glXSwapQueryContextInfoEXT(__GLXclientState *cl, char *pc) +{ + xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + + return __glXQueryContextInfoEXT(cl, (GLbyte *)pc); +} + +/************************************************************************/ + +/* +** Swap replies. +*/ + +void __glXSwapMakeCurrentReply(ClientPtr client, xGLXMakeCurrentReadSGIReply *reply) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->contextTag); + __GLX_SWAP_INT(&reply->writeVid); + __GLX_SWAP_INT(&reply->writeType); + __GLX_SWAP_INT(&reply->readVid); + __GLX_SWAP_INT(&reply->readType); + WriteToClient(client, sz_xGLXMakeCurrentReadSGIReply, (char *)reply); +} + +void __glXSwapIsDirectReply(ClientPtr client, xGLXIsDirectReply *reply) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + WriteToClient(client, sz_xGLXIsDirectReply, (char *)reply); +} + +void __glXSwapQueryVersionReply(ClientPtr client, xGLXQueryVersionReply *reply) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->majorVersion); + __GLX_SWAP_INT(&reply->minorVersion); + WriteToClient(client, sz_xGLXQueryVersionReply, (char *)reply); +} + +void glxSwapQueryExtensionsStringReply(ClientPtr client, + xGLXQueryExtensionsStringReply *reply, char *buf) +{ + int length = reply->length; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->n); + WriteToClient(client, sz_xGLXQueryExtensionsStringReply, (char *)reply); + __GLX_SWAP_INT_ARRAY((int *)buf, length); + WriteToClient(client, length << 2, buf); +} + +void glxSwapQueryServerStringReply(ClientPtr client, + xGLXQueryServerStringReply *reply, char *buf) +{ + int length = reply->length; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->n); + WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)reply); + /** no swap is needed for an array of chars **/ + /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */ + WriteToClient(client, length << 2, buf); +} + +void __glXSwapQueryContextInfoEXTReply(ClientPtr client, xGLXQueryContextInfoEXTReply *reply, int *buf) +{ + int length = reply->length; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->n); + WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)reply); + __GLX_SWAP_INT_ARRAY((int *)buf, length); + WriteToClient(client, length << 2, (char *)buf); +} + + +void __glXSwapQueryContextReply(ClientPtr client, + xGLXQueryContextReply *reply, int *buf) +{ + int length = reply->length; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->n); + WriteToClient(client, sz_xGLXQueryContextReply, (char *)reply); + __GLX_SWAP_INT_ARRAY((int *)buf, length); + WriteToClient(client, length << 2, (char *)buf); +} + +void __glXSwapGetDrawableAttributesReply(ClientPtr client, + xGLXGetDrawableAttributesReply *reply, int *buf) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->numAttribs); + __GLX_SWAP_INT_ARRAY( buf, reply->length ); + WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)reply); + WriteToClient(client, reply->length << 2, (char *)buf); +} + +void __glXSwapQueryMaxSwapBarriersSGIXReply(ClientPtr client, xGLXQueryMaxSwapBarriersSGIXReply *reply) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->max); + WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, (char *)reply); +} + +/************************************************************************/ + +/* +** Render and Renderlarge are not in the GLX API. They are used by the GLX +** client library to send batches of GL rendering commands. +*/ + +int __glXSwapRender(__GLXclientState *cl, GLbyte *pc) +{ + xGLXRenderReq *req; + int left; + __GLXrenderHeader *hdr; + ClientPtr client = cl->client; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + /* + ** NOTE: much of this code also appears in the nonswapping version of this + ** routine, __glXRender(). Any changes made here should also be + ** duplicated there. + */ + + req = (xGLXRenderReq *) pc; + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + pc += sz_xGLXRenderReq; + left = (req->length << 2) - sz_xGLXRenderReq; + while (left > 0) { + void (* proc)(GLbyte *); + CARD16 opcode; + + /* + ** Verify that the header length and the overall length agree. + ** Also, each command must be word aligned. + */ + hdr = (__GLXrenderHeader *) pc; + __GLX_SWAP_SHORT(&hdr->length); + __GLX_SWAP_SHORT(&hdr->opcode); + + /* + * call the command procedure to swap any arguments + */ + opcode = hdr->opcode; + if ( (opcode >= __GLX_MIN_RENDER_OPCODE) && + (opcode <= __GLX_MAX_RENDER_OPCODE) ) { + proc = __glXSwapRenderTable[opcode]; +#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT + } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) && + (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) { + int index = opcode - __GLX_MIN_RENDER_OPCODE_EXT; + __GLXRenderSwapInfo *info = &__glXSwapRenderTable_EXT[index]; + if (info->swapfunc) { + proc = info->swapfunc; + } + else { + proc = NULL; + if (info->elem_size == 4 && info->nelems > 0) { + __GLX_SWAP_INT_ARRAY( (int *)(pc + __GLX_RENDER_HDR_SIZE), + info->nelems ); + } + else if (info->elem_size == 2 && info->nelems > 0) { + __GLX_SWAP_SHORT_ARRAY( (short *)(pc + __GLX_RENDER_HDR_SIZE), + info->nelems ); + } + else if (info->elem_size == 8 && info->nelems > 0) { + __GLX_SWAP_DOUBLE_ARRAY( (double *)(pc + __GLX_RENDER_HDR_SIZE), + info->nelems ); + } + } +#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */ + } else { + client->errorValue = 0; + return __glXBadRenderRequest; + } + + if (proc != NULL) + (*proc)(pc + __GLX_RENDER_HDR_SIZE); + + /* + * proceed to the next command + */ + pc += hdr->length; + left -= hdr->length; + } + + return __glXRender( cl, (GLbyte *)req ); +} + +/* +** Execute a large rendering request (one that spans multiple X requests). +*/ +int __glXSwapRenderLarge(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXRenderLargeReq *req; + __GLXrenderLargeHeader *hdr; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + req = (xGLXRenderLargeReq *) pc; + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(&req->dataBytes); + __GLX_SWAP_SHORT(&req->requestNumber); + __GLX_SWAP_SHORT(&req->requestTotal); + + pc += sz_xGLXRenderLargeReq; + + if (req->requestNumber == 1) { + void (* proc)(GLbyte *) = NULL; + __GLXRenderSwapInfo *info = NULL; + CARD16 opcode; + + hdr = (__GLXrenderLargeHeader *) pc; + __GLX_SWAP_INT(&hdr->length); + __GLX_SWAP_INT(&hdr->opcode); + + /* + * call the command procedure to swap any arguments + * Note that we are assuming that all arguments that needs to be + * swaped are on the first req only ! + */ + opcode = hdr->opcode; + if ( (opcode >= __GLX_MIN_RENDER_OPCODE) && + (opcode <= __GLX_MAX_RENDER_OPCODE) ) { + proc = __glXSwapRenderTable[opcode]; +#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT + } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) && + (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) { + int index = opcode - __GLX_MIN_RENDER_OPCODE_EXT; + info = &__glXSwapRenderTable_EXT[index]; + if (info->swapfunc) { + proc = info->swapfunc; + } +#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */ + } else { + client->errorValue = 0; + cl->largeCmdRequestsTotal = 0; + return __glXBadLargeRequest; + } + + /* + ** Make enough space in the buffer, then copy the entire request. + */ + if (cl->largeCmdBufSize < hdr->length) { + if (!cl->largeCmdBuf) { + cl->largeCmdBuf = (GLbyte *) malloc(hdr->length); + } else { + cl->largeCmdBuf = (GLbyte *) realloc(cl->largeCmdBuf, hdr->length); + } + if (!cl->largeCmdBuf) { + cl->largeCmdRequestsTotal = 0; + return BadAlloc; + } + cl->largeCmdBufSize = hdr->length; + } + memcpy(cl->largeCmdBuf, pc, req->dataBytes); + + cl->largeCmdBytesSoFar = req->dataBytes; + cl->largeCmdBytesTotal = hdr->length; + cl->largeCmdRequestsSoFar = 1; + cl->largeCmdRequestsTotal = req->requestTotal; + cl->largeCmdRequestsSwapProc = proc; + cl->largeCmdMaxReqDataSize = req->dataBytes; + cl->largeCmdRequestsSwap_info = info; + + return Success; + + + } + else if (req->requestNumber < cl->largeCmdRequestsTotal) { + /* + * This is not the first nor last request - just copy the data + */ + if ( cl->largeCmdBytesSoFar + req->dataBytes > cl->largeCmdBytesTotal) { + cl->largeCmdRequestsTotal = 0; + return __glXBadLargeRequest; + } + + memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, + pc, req->dataBytes); + + cl->largeCmdBytesSoFar += req->dataBytes; + + if (req->dataBytes > cl->largeCmdMaxReqDataSize) + cl->largeCmdMaxReqDataSize = req->dataBytes; + + return Success; + } + else if (req->requestNumber == cl->largeCmdRequestsTotal) { + /* + * this is the last request + * copy the remainder bytes, call the procedure to swap any + * needed data, and then call to transfer the command to all + * back-end servers + */ + if ( cl->largeCmdBytesSoFar + req->dataBytes > cl->largeCmdBytesTotal) { + cl->largeCmdRequestsTotal = 0; + return __glXBadLargeRequest; + } + + memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, + pc, req->dataBytes); + + cl->largeCmdBytesSoFar += req->dataBytes; + + if (req->dataBytes > cl->largeCmdMaxReqDataSize) + cl->largeCmdMaxReqDataSize = req->dataBytes; + + if (cl->largeCmdRequestsSwapProc != NULL) { + (*cl->largeCmdRequestsSwapProc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE); + } + else if (cl->largeCmdRequestsSwap_info && + cl->largeCmdRequestsSwap_info->nelems > 0) { + if (cl->largeCmdRequestsSwap_info->elem_size == 4) { + __GLX_SWAP_INT_ARRAY( (int *)(pc + __GLX_RENDER_LARGE_HDR_SIZE), + cl->largeCmdRequestsSwap_info->nelems ); + } + else if (cl->largeCmdRequestsSwap_info->elem_size == 2) { + __GLX_SWAP_SHORT_ARRAY( (short *)(pc + __GLX_RENDER_LARGE_HDR_SIZE), + cl->largeCmdRequestsSwap_info->nelems ); + } + else if (cl->largeCmdRequestsSwap_info->elem_size == 8) { + __GLX_SWAP_DOUBLE_ARRAY( (double *)(pc + __GLX_RENDER_LARGE_HDR_SIZE), + cl->largeCmdRequestsSwap_info->nelems ); + } + } + + cl->largeCmdRequestsTotal = 0; + return( __glXSendLargeCommand(cl, req->contextTag) ); + + } + else { + cl->largeCmdRequestsTotal = 0; + return __glXBadLargeRequest; + } + +} + +/************************************************************************/ + +/* +** No support is provided for the vendor-private requests other than +** allocating these entry points in the dispatch table. +*/ + +int __glXSwapVendorPrivate(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateReq *req; + CARD32 vendorCode; + + __GLX_DECLARE_SWAP_VARIABLES; + + req = (xGLXVendorPrivateReq *) pc; + vendorCode = req->vendorCode; + __GLX_SWAP_INT(&vendorCode); + + + switch( vendorCode ) { + + case X_GLvop_DeleteTexturesEXT: + return __glXVForwardSingleReqSwap( cl, pc ); + break; + + case X_GLXvop_SwapIntervalSGI: + if (glxIsExtensionSupported("SGI_swap_control")) { + return __glXVForwardSingleReqSwap( cl, pc ); + } + else { + return Success; + } + break; + +#if 0 /* glx 1.3 */ + case X_GLXvop_CreateGLXVideoSourceSGIX: + break; + case X_GLXvop_DestroyGLXVideoSourceSGIX: + break; + case X_GLXvop_CreateGLXPixmapWithConfigSGIX: + break; + case X_GLXvop_DestroyGLXPbufferSGIX: + break; + case X_GLXvop_ChangeDrawableAttributesSGIX: + break; +#endif + + case X_GLXvop_JoinSwapGroupSGIX: + return __glXSwapJoinSwapGroupSGIX( cl, pc ); + break; + + case X_GLXvop_BindSwapBarrierSGIX: + return __glXSwapBindSwapBarrierSGIX( cl, pc ); + break; + + case X_GLXvop_CreateContextWithConfigSGIX: + return __glXSwapCreateContextWithConfigSGIX( cl, pc ); + break; + + default: + /* + ** unsupported private request + */ + cl->client->errorValue = req->vendorCode; + return __glXUnsupportedPrivateRequest; + } + +} + +int __glXSwapVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateWithReplyReq *req; + CARD32 vendorCode; + + __GLX_DECLARE_SWAP_VARIABLES; + + req = (xGLXVendorPrivateWithReplyReq *) pc; + vendorCode = req->vendorCode; + __GLX_SWAP_INT(&vendorCode); + + switch( vendorCode ) { + + case X_GLvop_GetConvolutionFilterEXT: + case X_GLvop_GetSeparableFilterEXT: + case X_GLvop_GetHistogramEXT: + case X_GLvop_GetMinmaxEXT: + return( __glXNoSuchSingleOpcode(cl, pc) ); + break; + + case X_GLvop_GetConvolutionParameterfvEXT: + case X_GLvop_GetConvolutionParameterivEXT: + case X_GLvop_GetHistogramParameterivEXT: + case X_GLvop_GetMinmaxParameterfvEXT: + case X_GLvop_GetMinmaxParameterivEXT: + case X_GLvop_GenTexturesEXT: + return( __glXVForwardAllWithReplySwapiv(cl, pc) ); + break; + + case X_GLvop_AreTexturesResidentEXT: + case X_GLvop_IsTextureEXT: + return( __glXVForwardPipe0WithReplySwap(cl, pc) ); + break; + +#if 0 /* glx1.3 */ + case X_GLvop_GetDetailTexFuncSGIS: + case X_GLvop_GetSharpenTexFuncSGIS: + case X_GLvop_GetColorTableSGI: + case X_GLvop_GetColorTableParameterfvSGI: + case X_GLvop_GetColorTableParameterivSGI: + case X_GLvop_GetTexFilterFuncSGIS: + case X_GLvop_GetInstrumentsSGIX: + case X_GLvop_InstrumentsBufferSGIX: + case X_GLvop_PollInstrumentsSGIX: + case X_GLvop_FlushRasterSGIX: + case X_GLXvop_CreateGLXPbufferSGIX: + case X_GLXvop_GetDrawableAttributesSGIX: + case X_GLXvop_QueryHyperpipeNetworkSGIX: + case X_GLXvop_QueryHyperpipeConfigSGIX: + case X_GLXvop_HyperpipeConfigSGIX: + case X_GLXvop_DestroyHyperpipeConfigSGIX: +#endif + case X_GLXvop_QueryMaxSwapBarriersSGIX: + return( __glXSwapQueryMaxSwapBarriersSGIX(cl, pc) ); + break; + + case X_GLXvop_GetFBConfigsSGIX: + return( __glXSwapGetFBConfigsSGIX(cl, pc) ); + break; + + case X_GLXvop_MakeCurrentReadSGI: + return( __glXSwapMakeCurrentReadSGI(cl, pc) ); + break; + + case X_GLXvop_QueryContextInfoEXT: + return( __glXSwapQueryContextInfoEXT(cl,(char *)pc) ); + break; + + default: + /* + ** unsupported private request + */ + cl->client->errorValue = req->vendorCode; + return __glXUnsupportedPrivateRequest; + } + +} + +int __glXSwapGetFBConfigs(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + + return __glXGetFBConfigs(cl, pc); +} + +int __glXSwapGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc; + xGLXGetFBConfigsReq new_req; + + new_req.reqType = req->reqType; + new_req.glxCode = req->glxCode; + new_req.length = req->length; + new_req.screen = req->screen; + + return( __glXSwapGetFBConfigs( cl, (GLbyte *)&new_req ) ); +} + +int __glXSwapCreateWindow(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->window); + __GLX_SWAP_INT(&req->glxwindow); + __GLX_SWAP_INT(&req->numAttribs); + + return( __glXCreateWindow( cl, (GLbyte *)pc ) ); +} + +int __glXSwapDestroyWindow(__GLXclientState *cl, GLbyte *pc) +{ + xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->glxwindow); + + return( __glXDestroyWindow( cl, (GLbyte *)pc ) ); +} + +int __glXSwapQueryContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXQueryContextReq *req = (xGLXQueryContextReq *)pc; + + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + + return( __glXQueryContext(cl, (GLbyte *)pc) ); + +} + +int __glXSwapCreatePbuffer(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc; + int nattr = req->numAttribs; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->pbuffer); + __GLX_SWAP_INT(&req->numAttribs); + __GLX_SWAP_INT_ARRAY( (int *)(req+1), nattr*2 ); + + return( __glXCreatePbuffer( cl, pc ) ); +} + +int __glXSwapDestroyPbuffer(__GLXclientState *cl, GLbyte *pc) +{ + xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->pbuffer); + + return( __glXDestroyPbuffer( cl, (GLbyte *)pc ) ); +} + +int __glXSwapGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + + return( __glXGetDrawableAttributes(cl, pc) ); +} + +int __glXSwapChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->numAttribs); + __GLX_SWAP_INT_ARRAY( (int *)(req+1), req->numAttribs * 2 ); + + return( __glXChangeDrawableAttributes(cl, pc) ); +} diff --git a/xorg-server/hw/dmx/glxProxy/glxscreens.c b/xorg-server/hw/dmx/glxProxy/glxscreens.c index 01e041c8f..baa4a65a7 100644 --- a/xorg-server/hw/dmx/glxProxy/glxscreens.c +++ b/xorg-server/hw/dmx/glxProxy/glxscreens.c @@ -120,8 +120,9 @@ static void CalcServerVersionAndExtensions( void ) __glXVersionMinor = GLX_SERVER_MINOR_VERSION; } - sprintf(GLXServerVersion, "%d.%d DMX %d back-end server(s)", - __glXVersionMajor, __glXVersionMinor, __glXNumActiveScreens ); + snprintf(GLXServerVersion, sizeof(GLXServerVersion), + "%d.%d DMX %d back-end server(s)", + __glXVersionMajor, __glXVersionMinor, __glXNumActiveScreens ); /* * set the ExtensionsString to the minimum extensions string */ diff --git a/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c index 94feb7826..69ad8a517 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c @@ -1,1015 +1,1016 @@ -/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- * Authored by Matthew Allum <mallum@openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * 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 OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd 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.
- *
- * Authors:
- * Dodji Seketeli <dodji@openedhand.com>
- */
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-/*
- * including some server headers (like kdrive-config.h)
- * might define the macro _XSERVER64
- * on 64 bits machines. That macro must _NOT_ be defined for Xlib
- * client code, otherwise bad things happen.
- * So let's undef that macro if necessary.
- */
-#ifdef _XSERVER64
-#undef _XSERVER64
-#endif
-#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
-#include <X11/extensions/Xvlib.h>
-#include <X11/extensions/Xvproto.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
-#define _HAVE_XALLOC_DECLS
-
-#include "hostx.h"
-#include "ephyrhostvideo.h"
-#include "ephyrlog.h"
-
-#ifndef TRUE
-#define TRUE 1
-#endif /*TRUE*/
-
-#ifndef FALSE
-#define FALSE 0
-#endif /*FALSE*/
-
-static XExtensionInfo _xv_info_data;
-static XExtensionInfo *xv_info = &_xv_info_data;
-static char *xv_extension_name = XvName;
-static char *xv_error_string(Display *dpy, int code, XExtCodes *codes,
- char * buf, int n);
-static int xv_close_display(Display *dpy, XExtCodes *codes);
-static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire);
-
-static XExtensionHooks xv_extension_hooks = {
- NULL, /* create_gc */
- NULL, /* copy_gc */
- NULL, /* flush_gc */
- NULL, /* free_gc */
- NULL, /* create_font */
- NULL, /* free_font */
- xv_close_display, /* close_display */
- xv_wire_to_event, /* wire_to_event */
- NULL, /* event_to_wire */
- NULL, /* error */
- xv_error_string /* error_string */
-};
-
-
-static char *xv_error_list[] =
-{
- "BadPort", /* XvBadPort */
- "BadEncoding", /* XvBadEncoding */
- "BadControl" /* XvBadControl */
-};
-
-
-#define XvCheckExtension(dpy, i, val) \
- XextCheckExtension(dpy, i, xv_extension_name, val)
-#define XvGetReq(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
- req->reqType = info->codes->major_opcode;\
- req->xvReqType = xv_##name; \
- req->length = (SIZEOF(xv##name##Req))>>2;\
- dpy->bufptr += SIZEOF(xv##name##Req);\
- dpy->request++
-
-static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
-
-
-static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
- xv_extension_name,
- &xv_extension_hooks,
- XvNumEvents, NULL)
-
-static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
- XvNumErrors, xv_error_list)
-
-struct _EphyrHostXVAdaptorArray {
- XvAdaptorInfo *adaptors ;
- unsigned int nb_adaptors ;
-};
-
-/*heavily copied from libx11*/
-#define BUFSIZE 2048
-static void
-ephyrHostXVLogXErrorEvent (Display *a_display,
- XErrorEvent *a_err_event,
- FILE *a_fp)
-{
- char buffer[BUFSIZ];
- char mesg[BUFSIZ];
- char number[32];
- const char *mtype = "XlibMessage";
- register _XExtension *ext = (_XExtension *)NULL;
- _XExtension *bext = (_XExtension *)NULL;
- Display *dpy = a_display ;
-
- XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
- XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
- (void) fprintf(a_fp, "%s: %s\n ", mesg, buffer);
- XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
- mesg, BUFSIZ);
- (void) fprintf(a_fp, mesg, a_err_event->request_code);
- if (a_err_event->request_code < 128) {
- sprintf(number, "%d", a_err_event->request_code);
- XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
- } else {
- for (ext = dpy->ext_procs;
- ext && (ext->codes.major_opcode != a_err_event->request_code);
- ext = ext->next)
- ;
- if (ext)
- strcpy(buffer, ext->name);
- else
- buffer[0] = '\0';
- }
- (void) fprintf(a_fp, " (%s)\n", buffer);
- if (a_err_event->request_code >= 128) {
- XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
- mesg, BUFSIZ);
- fputs(" ", a_fp);
- (void) fprintf(a_fp, mesg, a_err_event->minor_code);
- if (ext) {
- sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code);
- XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
- (void) fprintf(a_fp, " (%s)", buffer);
- }
- fputs("\n", a_fp);
- }
- if (a_err_event->error_code >= 128) {
- /* kludge, try to find the extension that caused it */
- buffer[0] = '\0';
- for (ext = dpy->ext_procs; ext; ext = ext->next) {
- if (ext->error_string)
- (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes,
- buffer, BUFSIZ);
- if (buffer[0]) {
- bext = ext;
- break;
- }
- if (ext->codes.first_error &&
- ext->codes.first_error < (int)a_err_event->error_code &&
- (!bext || ext->codes.first_error > bext->codes.first_error))
- bext = ext;
- }
- if (bext)
- sprintf(buffer, "%s.%d", bext->name,
- a_err_event->error_code - bext->codes.first_error);
- else
- strcpy(buffer, "Value");
- XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
- if (mesg[0]) {
- fputs(" ", a_fp);
- (void) fprintf(a_fp, mesg, a_err_event->resourceid);
- fputs("\n", a_fp);
- }
- /* let extensions try to print the values */
- for (ext = dpy->ext_procs; ext; ext = ext->next) {
- if (ext->error_values)
- (*ext->error_values)(dpy, a_err_event, a_fp);
- }
- } else if ((a_err_event->error_code == BadWindow) ||
- (a_err_event->error_code == BadPixmap) ||
- (a_err_event->error_code == BadCursor) ||
- (a_err_event->error_code == BadFont) ||
- (a_err_event->error_code == BadDrawable) ||
- (a_err_event->error_code == BadColor) ||
- (a_err_event->error_code == BadGC) ||
- (a_err_event->error_code == BadIDChoice) ||
- (a_err_event->error_code == BadValue) ||
- (a_err_event->error_code == BadAtom)) {
- if (a_err_event->error_code == BadValue)
- XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
- mesg, BUFSIZ);
- else if (a_err_event->error_code == BadAtom)
- XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
- mesg, BUFSIZ);
- else
- XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
- mesg, BUFSIZ);
- fputs(" ", a_fp);
- (void) fprintf(a_fp, mesg, a_err_event->resourceid);
- fputs("\n", a_fp);
- }
- XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
- mesg, BUFSIZ);
- fputs(" ", a_fp);
- (void) fprintf(a_fp, mesg, a_err_event->serial);
- XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
- mesg, BUFSIZ);
- fputs("\n ", a_fp);
- (void) fprintf(a_fp, mesg, dpy->request);
- fputs("\n", a_fp);
-}
-
-static int
-ephyrHostXVErrorHandler (Display *a_display,
- XErrorEvent *a_error_event)
-{
- EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ;
- ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ;
- return Success ;
-}
-
-void
-ephyrHostXVInit (void)
-{
- static Bool s_initialized ;
-
- if (s_initialized)
- return ;
- XSetErrorHandler (ephyrHostXVErrorHandler) ;
- s_initialized = TRUE ;
-}
-
-Bool
-ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
-{
- EphyrHostXVAdaptorArray *result=NULL ;
- int ret=0 ;
- Bool is_ok=FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- result = calloc (1, sizeof (EphyrHostXVAdaptorArray)) ;
- if (!result)
- goto out ;
-
- ret = XvQueryAdaptors (hostx_get_display (),
- DefaultRootWindow (hostx_get_display ()),
- &result->nb_adaptors,
- &result->adaptors) ;
- if (ret != Success) {
- EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
- goto out ;
- }
- *a_adaptors = result ;
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-void
-ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
-{
- if (!a_adaptors)
- return ;
- if (a_adaptors->adaptors) {
- XvFreeAdaptorInfo (a_adaptors->adaptors) ;
- a_adaptors->adaptors = NULL ;
- a_adaptors->nb_adaptors = 0 ;
- }
- XFree (a_adaptors) ;
-}
-
-int
-ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
- return a_this->nb_adaptors ;
-}
-
-EphyrHostXVAdaptor*
-ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
- int a_index)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
-
- if (a_index >= a_this->nb_adaptors)
- return NULL ;
- return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ;
-}
-
-char
-ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
- return ((XvAdaptorInfo*)a_this)->type ;
-}
-
-const char*
-ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
-
- return ((XvAdaptorInfo*)a_this)->name ;
-}
-
-EphyrHostVideoFormat*
-ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
- int *a_nb_formats)
-{
- EphyrHostVideoFormat *formats=NULL ;
- int nb_formats=0, i=0 ;
- XVisualInfo *visual_info, visual_info_template ;
- int nb_visual_info ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
-
- nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
- formats = calloc (nb_formats, sizeof (EphyrHostVideoFormat)) ;
- for (i=0; i < nb_formats; i++) {
- memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
- visual_info_template.visualid =
- ((XvAdaptorInfo*)a_this)->formats[i].visual_id;
- visual_info = XGetVisualInfo (hostx_get_display (),
- VisualIDMask,
- &visual_info_template,
- &nb_visual_info) ;
- formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ;
- formats[i].visual_class = visual_info->class ;
- XFree (visual_info) ;
- }
- if (a_nb_formats)
- *a_nb_formats = nb_formats ;
- return formats ;
-}
-
-int
-ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
-
- return ((XvAdaptorInfo*)a_this)->num_ports ;
-}
-
-int
-ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
-
- return ((XvAdaptorInfo*)a_this)->base_id ;
-}
-
-Bool
-ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
-
- if ((((XvAdaptorInfo*)a_this)->type & (XvVideoMask | XvInputMask)) ==
- (XvVideoMask | XvInputMask))
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- if ((((XvAdaptorInfo*)a_this)->type & (XvVideoMask | XvOutputMask)) ==
- (XvVideoMask | XvOutputMask))
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
-
- if ((((XvAdaptorInfo*)a_this)->type & (XvStillMask | XvInputMask)) ==
- (XvStillMask | XvInputMask))
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
-
- if ((((XvAdaptorInfo*)a_this)->type & (XvStillMask | XvOutputMask)) ==
- (XvStillMask | XvOutputMask))
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
-
- if ((((XvAdaptorInfo*)a_this)->type & (XvImageMask | XvInputMask)) ==
- (XvImageMask | XvInputMask))
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVQueryEncodings (int a_port_id,
- EphyrHostEncoding **a_encodings,
- unsigned int *a_num_encodings)
-{
- EphyrHostEncoding *encodings=NULL ;
- XvEncodingInfo *encoding_info=NULL ;
- unsigned int num_encodings=0, i;
- int ret=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
-
- ret = XvQueryEncodings (hostx_get_display (),
- a_port_id,
- &num_encodings,
- &encoding_info) ;
- if (num_encodings && encoding_info) {
- encodings = calloc (num_encodings, sizeof (EphyrHostEncoding)) ;
- for (i=0; i<num_encodings; i++) {
- encodings[i].id = encoding_info[i].encoding_id ;
- encodings[i].name = strdup (encoding_info[i].name) ;
- encodings[i].width = encoding_info[i].width ;
- encodings[i].height = encoding_info[i].height ;
- encodings[i].rate.numerator = encoding_info[i].rate.numerator ;
- encodings[i].rate.denominator = encoding_info[i].rate.denominator ;
- }
- }
- if (encoding_info) {
- XvFreeEncodingInfo (encoding_info) ;
- encoding_info = NULL ;
- }
- *a_encodings = encodings ;
- *a_num_encodings = num_encodings ;
-
- if (ret != Success)
- return FALSE ;
- return TRUE ;
-}
-
-void
-ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
- int a_num_encodings)
-{
- int i=0 ;
-
- if (!a_encodings)
- return ;
- for (i=0; i < a_num_encodings; i++) {
- free(a_encodings[i].name) ;
- a_encodings[i].name = NULL ;
- }
- free(a_encodings) ;
-}
-
-void
-ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
-{
- if (!a_attributes)
- return ;
- XFree (a_attributes) ;
-}
-
-Bool
-ephyrHostXVQueryPortAttributes (int a_port_id,
- EphyrHostAttribute **a_attributes,
- int *a_num_attributes)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
-
- *a_attributes =
- (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
- a_port_id,
- a_num_attributes);
-
- return TRUE ;
-}
-
-Bool
-ephyrHostXVQueryImageFormats (int a_port_id,
- EphyrHostImageFormat **a_formats,
- int *a_num_format)
-{
- XvImageFormatValues *result=NULL ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
-
- result = XvListImageFormats (hostx_get_display (),
- a_port_id,
- a_num_format) ;
- *a_formats = (EphyrHostImageFormat*) result ;
- return TRUE ;
-
-}
-
-Bool
-ephyrHostXVSetPortAttribute (int a_port_id,
- int a_atom,
- int a_attr_value)
-{
- int res=Success ;
-
- EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n",
- a_atom,
- XGetAtomName (hostx_get_display (), a_atom),
- a_attr_value) ;
-
- res = XvSetPortAttribute (hostx_get_display (),
- a_port_id,
- a_atom,
- a_attr_value) ;
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
- return FALSE ;
- }
- XFlush (hostx_get_display ()) ;
- EPHYR_LOG ("leave\n") ;
-
- return TRUE ;
-}
-
-Bool
-ephyrHostXVGetPortAttribute (int a_port_id,
- int a_atom,
- int *a_attr_value)
-{
- int res=Success ;
- Bool ret=FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
-
- EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
- a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ;
-
- res = XvGetPortAttribute (hostx_get_display (),
- a_port_id,
- a_atom,
- a_attr_value) ;
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
- goto out ;
- }
- EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ;
-
- ret = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return ret ;
-}
-
-Bool
-ephyrHostXVQueryBestSize (int a_port_id,
- Bool a_motion,
- unsigned int a_frame_w,
- unsigned int a_frame_h,
- unsigned int a_drw_w,
- unsigned int a_drw_h,
- unsigned int *a_actual_w,
- unsigned int *a_actual_h)
-{
- int res=0 ;
- Bool is_ok=FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ;
-
- EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n",
- a_frame_w, a_frame_h,
- a_drw_w, a_drw_h) ;
-
- res = XvQueryBestSize (hostx_get_display (),
- a_port_id,
- a_motion,
- a_frame_w, a_frame_h,
- a_drw_w, a_drw_h,
- a_actual_w, a_actual_h) ;
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
- goto out ;
- }
- XSync (hostx_get_display (), FALSE) ;
-
- EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-static Bool
-xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
-{
- XExtDisplayInfo *info = xv_find_display (dpy);
- XvEvent *re = (XvEvent *)host;
- xvEvent *event = (xvEvent *)wire;
-
- XvCheckExtension(dpy, info, False);
-
- switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
- case XvVideoNotify:
- re->xvvideo.type = event->u.u.type & 0x7f;
- re->xvvideo.serial =
- _XSetLastRequestRead(dpy, (xGenericReply *)event);
- re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
- re->xvvideo.display = dpy;
- re->xvvideo.time = event->u.videoNotify.time;
- re->xvvideo.reason = event->u.videoNotify.reason;
- re->xvvideo.drawable = event->u.videoNotify.drawable;
- re->xvvideo.port_id = event->u.videoNotify.port;
- break;
- case XvPortNotify:
- re->xvport.type = event->u.u.type & 0x7f;
- re->xvport.serial =
- _XSetLastRequestRead(dpy, (xGenericReply *)event);
- re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
- re->xvport.display = dpy;
- re->xvport.time = event->u.portNotify.time;
- re->xvport.port_id = event->u.portNotify.port;
- re->xvport.attribute = event->u.portNotify.attribute;
- re->xvport.value = event->u.portNotify.value;
- break;
- default:
- return False;
- }
-
- return True ;
-}
-
-Bool
-ephyrHostXVQueryImageAttributes (int a_port_id,
- int a_image_id /*image fourcc code*/,
- unsigned short *a_width,
- unsigned short *a_height,
- int *a_image_size,
- int *a_pitches,
- int *a_offsets)
-{
- Display *dpy = hostx_get_display () ;
- Bool ret=FALSE ;
- XExtDisplayInfo *info = xv_find_display (dpy);
- xvQueryImageAttributesReq *req=NULL;
- xvQueryImageAttributesReply rep;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ;
-
- XvCheckExtension (dpy, info, FALSE);
-
- LockDisplay (dpy);
-
- XvGetReq (QueryImageAttributes, req);
- req->id = a_image_id;
- req->port = a_port_id;
- req->width = *a_width;
- req->height = *a_height;
- /*
- * read the reply
- */
- if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
- EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ;
- goto out ;
- }
- if (a_pitches && a_offsets) {
- _XRead (dpy,
- (char*)a_pitches,
- rep.num_planes << 2);
- _XRead (dpy,
- (char*)a_offsets,
- rep.num_planes << 2);
- } else {
- _XEatData(dpy, rep.length << 2);
- }
- *a_width = rep.width ;
- *a_height = rep.height ;
- *a_image_size = rep.data_size ;
-
- ret = TRUE ;
-
-out:
- UnlockDisplay (dpy) ;
- SyncHandle ();
- return ret ;
-}
-
-Bool
-ephyrHostGetAtom (const char* a_name,
- Bool a_create_if_not_exists,
- int *a_atom)
-{
- int atom=None ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ;
-
- atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists);
- if (atom == None) {
- return FALSE ;
- }
- *a_atom = atom ;
- return TRUE ;
-}
-
-char*
-ephyrHostGetAtomName (int a_atom)
-{
- return XGetAtomName (hostx_get_display (), a_atom) ;
-}
-
-void
-ephyrHostFree (void *a_pointer)
-{
- if (a_pointer)
- XFree (a_pointer) ;
-}
-
-Bool
-ephyrHostXVPutImage (int a_screen_num,
- int a_port_id,
- int a_image_id,
- int a_drw_x,
- int a_drw_y,
- int a_drw_w,
- int a_drw_h,
- int a_src_x,
- int a_src_y,
- int a_src_w,
- int a_src_h,
- int a_image_width,
- int a_image_height,
- unsigned char *a_buf,
- EphyrHostBox *a_clip_rects,
- int a_clip_rect_nums )
-{
- Bool is_ok=TRUE ;
- XvImage *xv_image=NULL ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy = hostx_get_display () ;
- XRectangle *rects=NULL ;
- int res = 0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
-
- EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
-
- memset (&gc_values, 0, sizeof (gc_values)) ;
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- xv_image = (XvImage*) XvCreateImage (hostx_get_display (),
- a_port_id, a_image_id,
- NULL, a_image_width, a_image_height) ;
- if (!xv_image) {
- EPHYR_LOG_ERROR ("failed to create image\n") ;
- goto out ;
- }
- xv_image->data = (char*)a_buf ;
- if (a_clip_rect_nums) {
- int i=0 ;
- rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
- for (i=0; i < a_clip_rect_nums; i++) {
- rects[i].x = a_clip_rects[i].x1 ;
- rects[i].y = a_clip_rects[i].y1 ;
- rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
- rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
- EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n",
- rects[i].x, rects[i].y,
- rects[i].width, rects[i].height) ;
- }
- XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
- /*this always returns 1*/
- }
- res = XvPutImage (dpy, a_port_id,
- hostx_get_window (a_screen_num),
- gc, xv_image,
- a_src_x, a_src_y, a_src_w, a_src_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ;
- goto out ;
- }
- is_ok = TRUE ;
-
-out:
- if (xv_image) {
- XFree (xv_image) ;
- xv_image = NULL ;
- }
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- free(rects);
- rects = NULL;
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-Bool
-ephyrHostXVPutVideo (int a_screen_num, int a_port_id,
- int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
- int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
-{
- Bool is_ok=FALSE ;
- int res=FALSE ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy=hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ;
- goto out ;
- }
-
- is_ok = TRUE ;
-
-out:
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- return is_ok ;
-}
-
-Bool
-ephyrHostXVGetVideo (int a_screen_num, int a_port_id,
- int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
- int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
-{
- Bool is_ok=FALSE ;
- int res=FALSE ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy=hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ;
- goto out ;
- }
-
- is_ok = TRUE ;
-
-out:
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- return is_ok ;
-}
-
-Bool
-ephyrHostXVPutStill (int a_screen_num, int a_port_id,
- int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
- int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
-{
- Bool is_ok=FALSE ;
- int res=FALSE ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy=hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ;
- goto out ;
- }
-
- is_ok = TRUE ;
-
-out:
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- return is_ok ;
-}
-
-Bool
-ephyrHostXVGetStill (int a_screen_num, int a_port_id,
- int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
- int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
-{
- Bool is_ok=FALSE ;
- int res=FALSE ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy=hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ;
- goto out ;
- }
-
- is_ok = TRUE ;
-
-out:
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- return is_ok ;
-}
-
-Bool
-ephyrHostXVStopVideo (int a_screen_num, int a_port_id)
-{
- int ret=0 ;
- Bool is_ok=FALSE ;
- Display *dpy = hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ;
- if (ret != Success) {
- EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
- goto out ;
- }
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
+/* + * Xephyr - A kdrive X server thats runs in a host X window. + * Authored by Matthew Allum <mallum@openedhand.com> + * + * Copyright © 2007 OpenedHand Ltd + * + * 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 OpenedHand Ltd not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OpenedHand Ltd makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OpenedHand Ltd 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. + * + * Authors: + * Dodji Seketeli <dodji@openedhand.com> + */ +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +/* + * including some server headers (like kdrive-config.h) + * might define the macro _XSERVER64 + * on 64 bits machines. That macro must _NOT_ be defined for Xlib + * client code, otherwise bad things happen. + * So let's undef that macro if necessary. + */ +#ifdef _XSERVER64 +#undef _XSERVER64 +#endif +#include <X11/Xutil.h> +#include <X11/Xlibint.h> +#include <X11/extensions/Xvlib.h> +#include <X11/extensions/Xvproto.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#define _HAVE_XALLOC_DECLS + +#include "hostx.h" +#include "ephyrhostvideo.h" +#include "ephyrlog.h" + +#ifndef TRUE +#define TRUE 1 +#endif /*TRUE*/ + +#ifndef FALSE +#define FALSE 0 +#endif /*FALSE*/ + +static XExtensionInfo _xv_info_data; +static XExtensionInfo *xv_info = &_xv_info_data; +static char *xv_extension_name = XvName; +static char *xv_error_string(Display *dpy, int code, XExtCodes *codes, + char * buf, int n); +static int xv_close_display(Display *dpy, XExtCodes *codes); +static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire); + +static XExtensionHooks xv_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + xv_close_display, /* close_display */ + xv_wire_to_event, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + xv_error_string /* error_string */ +}; + + +static char *xv_error_list[] = +{ + "BadPort", /* XvBadPort */ + "BadEncoding", /* XvBadEncoding */ + "BadControl" /* XvBadControl */ +}; + + +#define XvCheckExtension(dpy, i, val) \ + XextCheckExtension(dpy, i, xv_extension_name, val) +#define XvGetReq(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = info->codes->major_opcode;\ + req->xvReqType = xv_##name; \ + req->length = (SIZEOF(xv##name##Req))>>2;\ + dpy->bufptr += SIZEOF(xv##name##Req);\ + dpy->request++ + +static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info) + + +static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info, + xv_extension_name, + &xv_extension_hooks, + XvNumEvents, NULL) + +static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name, + XvNumErrors, xv_error_list) + +struct _EphyrHostXVAdaptorArray { + XvAdaptorInfo *adaptors ; + unsigned int nb_adaptors ; +}; + +/*heavily copied from libx11*/ +#define BUFSIZE 2048 +static void +ephyrHostXVLogXErrorEvent (Display *a_display, + XErrorEvent *a_err_event, + FILE *a_fp) +{ + char buffer[BUFSIZ]; + char mesg[BUFSIZ]; + char number[32]; + const char *mtype = "XlibMessage"; + register _XExtension *ext = (_XExtension *)NULL; + _XExtension *bext = (_XExtension *)NULL; + Display *dpy = a_display ; + + XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ); + XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); + (void) fprintf(a_fp, "%s: %s\n ", mesg, buffer); + XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", + mesg, BUFSIZ); + (void) fprintf(a_fp, mesg, a_err_event->request_code); + if (a_err_event->request_code < 128) { + snprintf(number, sizeof(number), "%d", a_err_event->request_code); + XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); + } else { + for (ext = dpy->ext_procs; + ext && (ext->codes.major_opcode != a_err_event->request_code); + ext = ext->next) + ; + if (ext) + strcpy(buffer, ext->name); + else + buffer[0] = '\0'; + } + (void) fprintf(a_fp, " (%s)\n", buffer); + if (a_err_event->request_code >= 128) { + XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", + mesg, BUFSIZ); + fputs(" ", a_fp); + (void) fprintf(a_fp, mesg, a_err_event->minor_code); + if (ext) { + snprintf(mesg, sizeof(mesg), "%s.%d", + ext->name, a_err_event->minor_code); + XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); + (void) fprintf(a_fp, " (%s)", buffer); + } + fputs("\n", a_fp); + } + if (a_err_event->error_code >= 128) { + /* kludge, try to find the extension that caused it */ + buffer[0] = '\0'; + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->error_string) + (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes, + buffer, BUFSIZ); + if (buffer[0]) { + bext = ext; + break; + } + if (ext->codes.first_error && + ext->codes.first_error < (int)a_err_event->error_code && + (!bext || ext->codes.first_error > bext->codes.first_error)) + bext = ext; + } + if (bext) + snprintf(buffer, sizeof(buffer), "%s.%d", bext->name, + a_err_event->error_code - bext->codes.first_error); + else + strcpy(buffer, "Value"); + XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); + if (mesg[0]) { + fputs(" ", a_fp); + (void) fprintf(a_fp, mesg, a_err_event->resourceid); + fputs("\n", a_fp); + } + /* let extensions try to print the values */ + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->error_values) + (*ext->error_values)(dpy, a_err_event, a_fp); + } + } else if ((a_err_event->error_code == BadWindow) || + (a_err_event->error_code == BadPixmap) || + (a_err_event->error_code == BadCursor) || + (a_err_event->error_code == BadFont) || + (a_err_event->error_code == BadDrawable) || + (a_err_event->error_code == BadColor) || + (a_err_event->error_code == BadGC) || + (a_err_event->error_code == BadIDChoice) || + (a_err_event->error_code == BadValue) || + (a_err_event->error_code == BadAtom)) { + if (a_err_event->error_code == BadValue) + XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", + mesg, BUFSIZ); + else if (a_err_event->error_code == BadAtom) + XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", + mesg, BUFSIZ); + else + XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", + mesg, BUFSIZ); + fputs(" ", a_fp); + (void) fprintf(a_fp, mesg, a_err_event->resourceid); + fputs("\n", a_fp); + } + XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", + mesg, BUFSIZ); + fputs(" ", a_fp); + (void) fprintf(a_fp, mesg, a_err_event->serial); + XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", + mesg, BUFSIZ); + fputs("\n ", a_fp); + (void) fprintf(a_fp, mesg, dpy->request); + fputs("\n", a_fp); +} + +static int +ephyrHostXVErrorHandler (Display *a_display, + XErrorEvent *a_error_event) +{ + EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ; + ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ; + return Success ; +} + +void +ephyrHostXVInit (void) +{ + static Bool s_initialized ; + + if (s_initialized) + return ; + XSetErrorHandler (ephyrHostXVErrorHandler) ; + s_initialized = TRUE ; +} + +Bool +ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) +{ + EphyrHostXVAdaptorArray *result=NULL ; + int ret=0 ; + Bool is_ok=FALSE ; + + EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ; + + EPHYR_LOG ("enter\n") ; + + result = calloc (1, sizeof (EphyrHostXVAdaptorArray)) ; + if (!result) + goto out ; + + ret = XvQueryAdaptors (hostx_get_display (), + DefaultRootWindow (hostx_get_display ()), + &result->nb_adaptors, + &result->adaptors) ; + if (ret != Success) { + EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ; + goto out ; + } + *a_adaptors = result ; + is_ok = TRUE ; + +out: + EPHYR_LOG ("leave\n") ; + return is_ok ; +} + +void +ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) +{ + if (!a_adaptors) + return ; + if (a_adaptors->adaptors) { + XvFreeAdaptorInfo (a_adaptors->adaptors) ; + a_adaptors->adaptors = NULL ; + a_adaptors->nb_adaptors = 0 ; + } + XFree (a_adaptors) ; +} + +int +ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; + return a_this->nb_adaptors ; +} + +EphyrHostXVAdaptor* +ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this, + int a_index) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ; + + if (a_index >= a_this->nb_adaptors) + return NULL ; + return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ; +} + +char +ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; + return ((XvAdaptorInfo*)a_this)->type ; +} + +const char* +ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ; + + return ((XvAdaptorInfo*)a_this)->name ; +} + +EphyrHostVideoFormat* +ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this, + int *a_nb_formats) +{ + EphyrHostVideoFormat *formats=NULL ; + int nb_formats=0, i=0 ; + XVisualInfo *visual_info, visual_info_template ; + int nb_visual_info ; + + EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ; + + nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ; + formats = calloc (nb_formats, sizeof (EphyrHostVideoFormat)) ; + for (i=0; i < nb_formats; i++) { + memset (&visual_info_template, 0, sizeof (visual_info_template)) ; + visual_info_template.visualid = + ((XvAdaptorInfo*)a_this)->formats[i].visual_id; + visual_info = XGetVisualInfo (hostx_get_display (), + VisualIDMask, + &visual_info_template, + &nb_visual_info) ; + formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ; + formats[i].visual_class = visual_info->class ; + XFree (visual_info) ; + } + if (a_nb_formats) + *a_nb_formats = nb_formats ; + return formats ; +} + +int +ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; + + return ((XvAdaptorInfo*)a_this)->num_ports ; +} + +int +ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; + + return ((XvAdaptorInfo*)a_this)->base_id ; +} + +Bool +ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this, + Bool *a_result) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ; + + if ((((XvAdaptorInfo*)a_this)->type & (XvVideoMask | XvInputMask)) == + (XvVideoMask | XvInputMask)) + *a_result = TRUE ; + else + *a_result = FALSE ; + return TRUE ; +} + +Bool +ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this, + Bool *a_result) +{ + if ((((XvAdaptorInfo*)a_this)->type & (XvVideoMask | XvOutputMask)) == + (XvVideoMask | XvOutputMask)) + *a_result = TRUE ; + else + *a_result = FALSE ; + return TRUE ; +} + +Bool +ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this, + Bool *a_result) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ; + + if ((((XvAdaptorInfo*)a_this)->type & (XvStillMask | XvInputMask)) == + (XvStillMask | XvInputMask)) + *a_result = TRUE ; + else + *a_result = FALSE ; + return TRUE ; +} + +Bool +ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this, + Bool *a_result) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ; + + if ((((XvAdaptorInfo*)a_this)->type & (XvStillMask | XvOutputMask)) == + (XvStillMask | XvOutputMask)) + *a_result = TRUE ; + else + *a_result = FALSE ; + return TRUE ; +} + +Bool +ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this, + Bool *a_result) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ; + + if ((((XvAdaptorInfo*)a_this)->type & (XvImageMask | XvInputMask)) == + (XvImageMask | XvInputMask)) + *a_result = TRUE ; + else + *a_result = FALSE ; + return TRUE ; +} + +Bool +ephyrHostXVQueryEncodings (int a_port_id, + EphyrHostEncoding **a_encodings, + unsigned int *a_num_encodings) +{ + EphyrHostEncoding *encodings=NULL ; + XvEncodingInfo *encoding_info=NULL ; + unsigned int num_encodings=0, i; + int ret=0 ; + + EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ; + + ret = XvQueryEncodings (hostx_get_display (), + a_port_id, + &num_encodings, + &encoding_info) ; + if (num_encodings && encoding_info) { + encodings = calloc (num_encodings, sizeof (EphyrHostEncoding)) ; + for (i=0; i<num_encodings; i++) { + encodings[i].id = encoding_info[i].encoding_id ; + encodings[i].name = strdup (encoding_info[i].name) ; + encodings[i].width = encoding_info[i].width ; + encodings[i].height = encoding_info[i].height ; + encodings[i].rate.numerator = encoding_info[i].rate.numerator ; + encodings[i].rate.denominator = encoding_info[i].rate.denominator ; + } + } + if (encoding_info) { + XvFreeEncodingInfo (encoding_info) ; + encoding_info = NULL ; + } + *a_encodings = encodings ; + *a_num_encodings = num_encodings ; + + if (ret != Success) + return FALSE ; + return TRUE ; +} + +void +ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings, + int a_num_encodings) +{ + int i=0 ; + + if (!a_encodings) + return ; + for (i=0; i < a_num_encodings; i++) { + free(a_encodings[i].name) ; + a_encodings[i].name = NULL ; + } + free(a_encodings) ; +} + +void +ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes) +{ + if (!a_attributes) + return ; + XFree (a_attributes) ; +} + +Bool +ephyrHostXVQueryPortAttributes (int a_port_id, + EphyrHostAttribute **a_attributes, + int *a_num_attributes) +{ + EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ; + + *a_attributes = + (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (), + a_port_id, + a_num_attributes); + + return TRUE ; +} + +Bool +ephyrHostXVQueryImageFormats (int a_port_id, + EphyrHostImageFormat **a_formats, + int *a_num_format) +{ + XvImageFormatValues *result=NULL ; + + EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ; + + result = XvListImageFormats (hostx_get_display (), + a_port_id, + a_num_format) ; + *a_formats = (EphyrHostImageFormat*) result ; + return TRUE ; + +} + +Bool +ephyrHostXVSetPortAttribute (int a_port_id, + int a_atom, + int a_attr_value) +{ + int res=Success ; + + EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n", + a_atom, + XGetAtomName (hostx_get_display (), a_atom), + a_attr_value) ; + + res = XvSetPortAttribute (hostx_get_display (), + a_port_id, + a_atom, + a_attr_value) ; + if (res != Success) { + EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ; + return FALSE ; + } + XFlush (hostx_get_display ()) ; + EPHYR_LOG ("leave\n") ; + + return TRUE ; +} + +Bool +ephyrHostXVGetPortAttribute (int a_port_id, + int a_atom, + int *a_attr_value) +{ + int res=Success ; + Bool ret=FALSE ; + + EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ; + + EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n", + a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ; + + res = XvGetPortAttribute (hostx_get_display (), + a_port_id, + a_atom, + a_attr_value) ; + if (res != Success) { + EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ; + goto out ; + } + EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ; + + ret = TRUE ; + +out: + EPHYR_LOG ("leave\n") ; + return ret ; +} + +Bool +ephyrHostXVQueryBestSize (int a_port_id, + Bool a_motion, + unsigned int a_frame_w, + unsigned int a_frame_h, + unsigned int a_drw_w, + unsigned int a_drw_h, + unsigned int *a_actual_w, + unsigned int *a_actual_h) +{ + int res=0 ; + Bool is_ok=FALSE ; + + EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ; + + EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n", + a_frame_w, a_frame_h, + a_drw_w, a_drw_h) ; + + res = XvQueryBestSize (hostx_get_display (), + a_port_id, + a_motion, + a_frame_w, a_frame_h, + a_drw_w, a_drw_h, + a_actual_w, a_actual_h) ; + if (res != Success) { + EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ; + goto out ; + } + XSync (hostx_get_display (), FALSE) ; + + EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ; + is_ok = TRUE ; + +out: + EPHYR_LOG ("leave\n") ; + return is_ok ; +} + +static Bool +xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire) +{ + XExtDisplayInfo *info = xv_find_display (dpy); + XvEvent *re = (XvEvent *)host; + xvEvent *event = (xvEvent *)wire; + + XvCheckExtension(dpy, info, False); + + switch ((event->u.u.type & 0x7F) - info->codes->first_event) { + case XvVideoNotify: + re->xvvideo.type = event->u.u.type & 0x7f; + re->xvvideo.serial = + _XSetLastRequestRead(dpy, (xGenericReply *)event); + re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0); + re->xvvideo.display = dpy; + re->xvvideo.time = event->u.videoNotify.time; + re->xvvideo.reason = event->u.videoNotify.reason; + re->xvvideo.drawable = event->u.videoNotify.drawable; + re->xvvideo.port_id = event->u.videoNotify.port; + break; + case XvPortNotify: + re->xvport.type = event->u.u.type & 0x7f; + re->xvport.serial = + _XSetLastRequestRead(dpy, (xGenericReply *)event); + re->xvport.send_event = ((event->u.u.type & 0x80) != 0); + re->xvport.display = dpy; + re->xvport.time = event->u.portNotify.time; + re->xvport.port_id = event->u.portNotify.port; + re->xvport.attribute = event->u.portNotify.attribute; + re->xvport.value = event->u.portNotify.value; + break; + default: + return False; + } + + return True ; +} + +Bool +ephyrHostXVQueryImageAttributes (int a_port_id, + int a_image_id /*image fourcc code*/, + unsigned short *a_width, + unsigned short *a_height, + int *a_image_size, + int *a_pitches, + int *a_offsets) +{ + Display *dpy = hostx_get_display () ; + Bool ret=FALSE ; + XExtDisplayInfo *info = xv_find_display (dpy); + xvQueryImageAttributesReq *req=NULL; + xvQueryImageAttributesReply rep; + + EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ; + EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ; + EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ; + + XvCheckExtension (dpy, info, FALSE); + + LockDisplay (dpy); + + XvGetReq (QueryImageAttributes, req); + req->id = a_image_id; + req->port = a_port_id; + req->width = *a_width; + req->height = *a_height; + /* + * read the reply + */ + if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { + EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ; + goto out ; + } + if (a_pitches && a_offsets) { + _XRead (dpy, + (char*)a_pitches, + rep.num_planes << 2); + _XRead (dpy, + (char*)a_offsets, + rep.num_planes << 2); + } else { + _XEatData(dpy, rep.length << 2); + } + *a_width = rep.width ; + *a_height = rep.height ; + *a_image_size = rep.data_size ; + + ret = TRUE ; + +out: + UnlockDisplay (dpy) ; + SyncHandle (); + return ret ; +} + +Bool +ephyrHostGetAtom (const char* a_name, + Bool a_create_if_not_exists, + int *a_atom) +{ + int atom=None ; + + EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ; + + atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists); + if (atom == None) { + return FALSE ; + } + *a_atom = atom ; + return TRUE ; +} + +char* +ephyrHostGetAtomName (int a_atom) +{ + return XGetAtomName (hostx_get_display (), a_atom) ; +} + +void +ephyrHostFree (void *a_pointer) +{ + if (a_pointer) + XFree (a_pointer) ; +} + +Bool +ephyrHostXVPutImage (int a_screen_num, + int a_port_id, + int a_image_id, + int a_drw_x, + int a_drw_y, + int a_drw_w, + int a_drw_h, + int a_src_x, + int a_src_y, + int a_src_w, + int a_src_h, + int a_image_width, + int a_image_height, + unsigned char *a_buf, + EphyrHostBox *a_clip_rects, + int a_clip_rect_nums ) +{ + Bool is_ok=TRUE ; + XvImage *xv_image=NULL ; + GC gc=0 ; + XGCValues gc_values; + Display *dpy = hostx_get_display () ; + XRectangle *rects=NULL ; + int res = 0 ; + + EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ; + + EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ; + + memset (&gc_values, 0, sizeof (gc_values)) ; + gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); + if (!gc) { + EPHYR_LOG_ERROR ("failed to create gc \n") ; + goto out ; + } + xv_image = (XvImage*) XvCreateImage (hostx_get_display (), + a_port_id, a_image_id, + NULL, a_image_width, a_image_height) ; + if (!xv_image) { + EPHYR_LOG_ERROR ("failed to create image\n") ; + goto out ; + } + xv_image->data = (char*)a_buf ; + if (a_clip_rect_nums) { + int i=0 ; + rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ; + for (i=0; i < a_clip_rect_nums; i++) { + rects[i].x = a_clip_rects[i].x1 ; + rects[i].y = a_clip_rects[i].y1 ; + rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1; + rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1; + EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n", + rects[i].x, rects[i].y, + rects[i].width, rects[i].height) ; + } + XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ; + /*this always returns 1*/ + } + res = XvPutImage (dpy, a_port_id, + hostx_get_window (a_screen_num), + gc, xv_image, + a_src_x, a_src_y, a_src_w, a_src_h, + a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; + if (res != Success) { + EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ; + goto out ; + } + is_ok = TRUE ; + +out: + if (xv_image) { + XFree (xv_image) ; + xv_image = NULL ; + } + if (gc) { + XFreeGC (dpy, gc) ; + gc = NULL ; + } + free(rects); + rects = NULL; + EPHYR_LOG ("leave\n") ; + return is_ok ; +} + +Bool +ephyrHostXVPutVideo (int a_screen_num, int a_port_id, + int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h, + int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) +{ + Bool is_ok=FALSE ; + int res=FALSE ; + GC gc=0 ; + XGCValues gc_values; + Display *dpy=hostx_get_display () ; + + EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; + + gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); + if (!gc) { + EPHYR_LOG_ERROR ("failed to create gc \n") ; + goto out ; + } + res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc, + a_vid_x, a_vid_y, a_vid_w, a_vid_h, + a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; + + if (res != Success) { + EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ; + goto out ; + } + + is_ok = TRUE ; + +out: + if (gc) { + XFreeGC (dpy, gc) ; + gc = NULL ; + } + return is_ok ; +} + +Bool +ephyrHostXVGetVideo (int a_screen_num, int a_port_id, + int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h, + int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) +{ + Bool is_ok=FALSE ; + int res=FALSE ; + GC gc=0 ; + XGCValues gc_values; + Display *dpy=hostx_get_display () ; + + EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; + + gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); + if (!gc) { + EPHYR_LOG_ERROR ("failed to create gc \n") ; + goto out ; + } + res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc, + a_vid_x, a_vid_y, a_vid_w, a_vid_h, + a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; + + if (res != Success) { + EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ; + goto out ; + } + + is_ok = TRUE ; + +out: + if (gc) { + XFreeGC (dpy, gc) ; + gc = NULL ; + } + return is_ok ; +} + +Bool +ephyrHostXVPutStill (int a_screen_num, int a_port_id, + int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h, + int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) +{ + Bool is_ok=FALSE ; + int res=FALSE ; + GC gc=0 ; + XGCValues gc_values; + Display *dpy=hostx_get_display () ; + + EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; + + gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); + if (!gc) { + EPHYR_LOG_ERROR ("failed to create gc \n") ; + goto out ; + } + res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc, + a_vid_x, a_vid_y, a_vid_w, a_vid_h, + a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; + + if (res != Success) { + EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ; + goto out ; + } + + is_ok = TRUE ; + +out: + if (gc) { + XFreeGC (dpy, gc) ; + gc = NULL ; + } + return is_ok ; +} + +Bool +ephyrHostXVGetStill (int a_screen_num, int a_port_id, + int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h, + int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) +{ + Bool is_ok=FALSE ; + int res=FALSE ; + GC gc=0 ; + XGCValues gc_values; + Display *dpy=hostx_get_display () ; + + EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; + + gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values); + if (!gc) { + EPHYR_LOG_ERROR ("failed to create gc \n") ; + goto out ; + } + res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc, + a_vid_x, a_vid_y, a_vid_w, a_vid_h, + a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; + + if (res != Success) { + EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ; + goto out ; + } + + is_ok = TRUE ; + +out: + if (gc) { + XFreeGC (dpy, gc) ; + gc = NULL ; + } + return is_ok ; +} + +Bool +ephyrHostXVStopVideo (int a_screen_num, int a_port_id) +{ + int ret=0 ; + Bool is_ok=FALSE ; + Display *dpy = hostx_get_display () ; + + EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; + + EPHYR_LOG ("enter\n") ; + + ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ; + if (ret != Success) { + EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ; + goto out ; + } + is_ok = TRUE ; + +out: + EPHYR_LOG ("leave\n") ; + return is_ok ; +} + diff --git a/xorg-server/hw/kdrive/linux/linux.c b/xorg-server/hw/kdrive/linux/linux.c index a53db4965..194e7cd59 100644 --- a/xorg-server/hw/kdrive/linux/linux.c +++ b/xorg-server/hw/kdrive/linux/linux.c @@ -109,7 +109,7 @@ LinuxInit (void) close(fd); } - sprintf(vtname,"/dev/tty%d",vtno); /* /dev/tty1-64 */ + snprintf(vtname,sizeof(vtname),"/dev/tty%d",vtno); /* /dev/tty1-64 */ if ((LinuxConsoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) < 0) { diff --git a/xorg-server/hw/kdrive/src/kinput.c b/xorg-server/hw/kdrive/src/kinput.c index 27e33043f..be2c3986f 100644 --- a/xorg-server/hw/kdrive/src/kinput.c +++ b/xorg-server/hw/kdrive/src/kinput.c @@ -1072,12 +1072,10 @@ KdGetOptions (InputOption **options, char *string) if (strchr(string, '=')) { tam_key = (strchr(string, '=') - string); - key = malloc(tam_key + 1); + key = strndup(string, tam_key); if (!key) goto out; - strncpy(key, string, tam_key); - key[tam_key] = '\0'; value = strdup(strchr(string, '=') + 1); if (!value) goto out; diff --git a/xorg-server/hw/vfb/InitOutput.c b/xorg-server/hw/vfb/InitOutput.c index 121854781..3e5d05100 100644 --- a/xorg-server/hw/vfb/InitOutput.c +++ b/xorg-server/hw/vfb/InitOutput.c @@ -560,7 +560,8 @@ vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb) char dummyBuffer[DUMMY_BUFFER_SIZE]; int currentFileSize, writeThisTime; - sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, (int) (pvfb - vfbScreens)); + snprintf(pvfb->mmap_file, sizeof(pvfb->mmap_file), "%s/Xvfb_screen%d", + pfbdir, (int) (pvfb - vfbScreens)); if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666))) { perror("open"); diff --git a/xorg-server/hw/xfree86/common/Makefile.am b/xorg-server/hw/xfree86/common/Makefile.am index a27372103..27921777d 100644 --- a/xorg-server/hw/xfree86/common/Makefile.am +++ b/xorg-server/hw/xfree86/common/Makefile.am @@ -35,7 +35,7 @@ xf86DefModeSet.c: $(srcdir)/modeline2c.awk $(MODEDEFSOURCES) BUILT_SOURCES = xf86DefModeSet.c AM_LDFLAGS = -r -libcommon_la_SOURCES = xf86Configure.c xf86ShowOpts.c xf86Bus.c xf86Config.c \ +libcommon_la_SOURCES = xf86Configure.c xf86Bus.c xf86Config.c \ xf86Cursor.c $(DGASOURCES) xf86DPMS.c \ xf86Events.c xf86Globals.c xf86AutoConfig.c \ xf86Option.c xf86Init.c \ diff --git a/xorg-server/hw/xfree86/common/xf86.h b/xorg-server/hw/xfree86/common/xf86.h index 3185baf3a..f216d5e8c 100644 --- a/xorg-server/hw/xfree86/common/xf86.h +++ b/xorg-server/hw/xfree86/common/xf86.h @@ -104,7 +104,6 @@ extern _X_EXPORT Bool xf86ParsePciBusString(const char *busID, int *bus, int *device, int *func); extern _X_EXPORT Bool xf86ComparePciBusString(const char *busID, int bus, int device, int func); -extern _X_EXPORT void xf86FormatPciBusNumber(int busnum, char *buffer); extern _X_EXPORT Bool xf86IsPrimaryPci(struct pci_device * pPci); extern _X_EXPORT Bool xf86CheckPciMemBase(struct pci_device * pPci, memType base); diff --git a/xorg-server/hw/xfree86/common/xf86AutoConfig.c b/xorg-server/hw/xfree86/common/xf86AutoConfig.c index 7fc6518d3..0c465682a 100644 --- a/xorg-server/hw/xfree86/common/xf86AutoConfig.c +++ b/xorg-server/hw/xfree86/common/xf86AutoConfig.c @@ -267,6 +267,7 @@ listPossibleVideoDrivers(char *matches[], int nmatches) #endif } +#if !defined(sun) /* Fallback to platform default frame buffer driver */ if (i < (nmatches - 1)) { #if !defined(__linux__) && defined(__sparc__) @@ -275,6 +276,7 @@ listPossibleVideoDrivers(char *matches[], int nmatches) matches[i++] = xnfstrdup("fbdev"); #endif } +#endif /* !sun */ } /* copy a screen section and enter the desired driver diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c index cb4be4210..fef4bf1fe 100644 --- a/xorg-server/hw/xfree86/common/xf86Config.c +++ b/xorg-server/hw/xfree86/common/xf86Config.c @@ -195,8 +195,7 @@ xf86ValidateFontPath(char *path) dirlen = p1 - path_elem; else dirlen = strlen(path_elem); - strncpy(dir_elem, path_elem, dirlen); - dir_elem[dirlen] = '\0'; + strlcpy(dir_elem, path_elem, dirlen + 1); flag = stat(dir_elem, &stat_buf); if (flag == 0) if (!S_ISDIR(stat_buf.st_mode)) @@ -249,9 +248,9 @@ xf86ModulelistFromConfig(pointer **optlist) { int count = 0, i = 0; char **modulearray; - char *ignore[] = { "GLcore", "speedo", "bitmap", "drm", - "freetype", "type1", - NULL }; + const char *ignore[] = { "GLcore", "speedo", "bitmap", "drm", + "freetype", "type1", + NULL }; pointer *optarray; XF86LoadPtr modp; Bool found; @@ -523,7 +522,7 @@ fixup_video_driver_list(char **drivers) } static char ** -GenerateDriverlist(char * dirname) +GenerateDriverlist(const char * dirname) { char **ret; const char *subdirs[] = { dirname, NULL }; @@ -554,7 +553,7 @@ xf86DriverlistFromCompile(void) * available is printed. */ static void -xf86ConfigError(char *msg, ...) +xf86ConfigError(const char *msg, ...) { va_list ap; @@ -2301,8 +2300,8 @@ checkInput(serverLayoutPtr layout, Bool implicit_layout) { ConfigStatus xf86HandleConfigFile(Bool autoconfig) { - const char *filename, *dirname, *sysdirname; - char *filesearch, *dirsearch; + char *filename, *dirname, *sysdirname; + const char *filesearch, *dirsearch; MessageType filefrom = X_DEFAULT; MessageType dirfrom = X_DEFAULT; char *scanptr; @@ -2353,6 +2352,10 @@ xf86HandleConfigFile(Bool autoconfig) return CONFIG_NOFILE; } + free(filename); + free(dirname); + free(sysdirname); + if ((xf86configptr = xf86readConfigFile ()) == NULL) { xf86Msg(X_ERROR, "Problem parsing the config file\n"); return CONFIG_PARSE_ERROR; diff --git a/xorg-server/hw/xfree86/common/xf86Config.h b/xorg-server/hw/xfree86/common/xf86Config.h index de287041a..411fc2cc1 100644 --- a/xorg-server/hw/xfree86/common/xf86Config.h +++ b/xorg-server/hw/xfree86/common/xf86Config.h @@ -51,7 +51,7 @@ typedef enum _ConfigStatus { } ConfigStatus; typedef struct _ModuleDefault { - char *name; + const char *name; Bool toLoad; XF86OptionPtr load_opt; } ModuleDefault; diff --git a/xorg-server/hw/xfree86/common/xf86Configure.c b/xorg-server/hw/xfree86/common/xf86Configure.c index 99b8b48d7..24f367ec0 100644 --- a/xorg-server/hw/xfree86/common/xf86Configure.c +++ b/xorg-server/hw/xfree86/common/xf86Configure.c @@ -58,17 +58,17 @@ Bool xf86DoConfigurePass1 = TRUE; static Bool foundMouse = FALSE; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -static char *DFLT_MOUSE_DEV = "/dev/sysmouse"; -static char *DFLT_MOUSE_PROTO = "auto"; +static const char *DFLT_MOUSE_DEV = "/dev/sysmouse"; +static const char *DFLT_MOUSE_PROTO = "auto"; #elif defined(linux) -static char DFLT_MOUSE_DEV[] = "/dev/input/mice"; -static char DFLT_MOUSE_PROTO[] = "auto"; +static const char *DFLT_MOUSE_DEV = "/dev/input/mice"; +static const char *DFLT_MOUSE_PROTO = "auto"; #elif defined(WSCONS_SUPPORT) -static char *DFLT_MOUSE_DEV = "/dev/wsmouse"; -static char *DFLT_MOUSE_PROTO = "wsmouse"; +static const char *DFLT_MOUSE_DEV = "/dev/wsmouse"; +static const char *DFLT_MOUSE_PROTO = "wsmouse"; #else -static char *DFLT_MOUSE_DEV = "/dev/mouse"; -static char *DFLT_MOUSE_PROTO = "auto"; +static const char *DFLT_MOUSE_DEV = "/dev/mouse"; +static const char *DFLT_MOUSE_PROTO = "auto"; #endif /* @@ -516,9 +516,9 @@ void DoConfigure(void) { int i,j, screennum = -1; - char *home = NULL; + const char *home = NULL; char filename[PATH_MAX]; - char *addslash = ""; + const char *addslash = ""; XF86ConfigPtr xf86config = NULL; char **vlist, **vl; int *dev2screen; @@ -757,3 +757,54 @@ bail: fflush(stderr); exit(0); } + +/* Xorg -showopts: + * For each driver module installed, print out the list + * of options and their argument types, then exit + * + * Author: Marcus Schaefer, ms@suse.de + */ + +void DoShowOptions (void) { + int i = 0; + char **vlist = 0; + char *pSymbol = 0; + XF86ModuleData *initData = 0; + if (! (vlist = xf86DriverlistFromCompile())) { + ErrorF("Missing output drivers\n"); + goto bail; + } + xf86LoadModules (vlist,0); + free(vlist); + for (i = 0; i < xf86NumDrivers; i++) { + if (xf86DriverList[i]->AvailableOptions) { + OptionInfoPtr pOption = (OptionInfoPtr)(*xf86DriverList[i]->AvailableOptions)(0,0); + if (! pOption) { + ErrorF ("(EE) Couldn't read option table for %s driver\n", + xf86DriverList[i]->driverName + ); + continue; + } + XNFasprintf(&pSymbol, "%sModuleData", + xf86DriverList[i]->driverName); + initData = LoaderSymbol (pSymbol); + if (initData) { + XF86ModuleVersionInfo *vers = initData->vers; + OptionInfoPtr p; + ErrorF ("Driver[%d]:%s[%s] {\n", + i,xf86DriverList[i]->driverName,vers->vendor + ); + for (p = pOption; p->name != NULL; p++) { + ErrorF ("\t%s:%s\n", p->name, + optionTypeToString(p->type)); + } + ErrorF ("}\n"); + } + } + } + bail: + OsCleanup (TRUE); + AbortDDX (EXIT_ERR_DRIVERS); + fflush (stderr); + exit (0); +} diff --git a/xorg-server/hw/xfree86/common/xf86Globals.c b/xorg-server/hw/xfree86/common/xf86Globals.c index f46799615..d576fb915 100644 --- a/xorg-server/hw/xfree86/common/xf86Globals.c +++ b/xorg-server/hw/xfree86/common/xf86Globals.c @@ -163,7 +163,7 @@ const char *xf86VisualNames[] = { }; /* Parameters set only from the command line */ -char *xf86ServerName = "no-name"; +const char *xf86ServerName = "no-name"; Bool xf86fpFlag = FALSE; Bool xf86sFlag = FALSE; Bool xf86bsEnableFlag = FALSE; diff --git a/xorg-server/hw/xfree86/common/xf86Mode.c b/xorg-server/hw/xfree86/common/xf86Mode.c index df0884794..d202d4079 100644 --- a/xorg-server/hw/xfree86/common/xf86Mode.c +++ b/xorg-server/hw/xfree86/common/xf86Mode.c @@ -1,2130 +1,2130 @@ -/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * LCM() and scanLineWidth() are:
- *
- * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
- *
- * 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 Marc Aurele La France not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Marc Aurele La France makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as-is" without express or implied warranty.
- *
- * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL MARC AURELE LA FRANCE 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.
- *
- * Copyright 1990,91,92,93 by Thomas Roell, Germany.
- * Copyright 1991,92,93 by SGCS (Snitily Graphics Consulting Services), USA.
- *
- * 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 Thomas Roell nor
- * SGCS be used in advertising or publicity pertaining to distribution
- * of the software without specific, written prior permission.
- * Thomas Roell nor SGCS makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS 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.
- */
-
-/*
- * Authors: Dirk Hohndel <hohndel@XFree86.Org>
- * David Dawes <dawes@XFree86.Org>
- * Marc La France <tsi@XFree86.Org>
- * ... and others
- *
- * This file includes helper functions for mode related things.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "xf86Modes.h"
-#include "os.h"
-#include "servermd.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "edid.h"
-
-static void
-printModeRejectMessage(int index, DisplayModePtr p, int status)
-{
- char *type;
-
- if (p->type & M_T_BUILTIN)
- type = "built-in ";
- else if (p->type & M_T_DEFAULT)
- type = "default ";
- else if (p->type & M_T_DRIVER)
- type = "driver ";
- else
- type = "";
-
- xf86DrvMsg(index, X_INFO, "Not using %smode \"%s\" (%s)\n", type, p->name,
- xf86ModeStatusToString(status));
-}
-
-/*
- * xf86GetNearestClock --
- * Find closest clock to given frequency (in kHz). This assumes the
- * number of clocks is greater than zero.
- */
-int
-xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
- int DivFactor, int MulFactor, int *divider)
-{
- int nearestClock = 0, nearestDiv = 1;
- int minimumGap = abs(freq - scrp->clock[0]);
- int i, j, k, gap;
-
- if (allowDiv2)
- k = 2;
- else
- k = 1;
-
- /* Must set this here in case the best match is scrp->clock[0] */
- if (divider != NULL)
- *divider = 0;
-
- for (i = 0; i < scrp->numClocks; i++) {
- for (j = 1; j <= k; j++) {
- gap = abs((freq * j) - ((scrp->clock[i] * DivFactor) / MulFactor));
- if ((gap < minimumGap) ||
- ((gap == minimumGap) && (j < nearestDiv))) {
- minimumGap = gap;
- nearestClock = i;
- nearestDiv = j;
- if (divider != NULL)
- *divider = (j - 1) * V_CLKDIV2;
- }
- }
- }
- return nearestClock;
-}
-
-/*
- * xf86ModeStatusToString
- *
- * Convert a ModeStatus value to a printable message
- */
-
-const char *
-xf86ModeStatusToString(ModeStatus status)
-{
- switch (status) {
- case MODE_OK:
- return "Mode OK";
- case MODE_HSYNC:
- return "hsync out of range";
- case MODE_VSYNC:
- return "vrefresh out of range";
- case MODE_H_ILLEGAL:
- return "illegal horizontal timings";
- case MODE_V_ILLEGAL:
- return "illegal vertical timings";
- case MODE_BAD_WIDTH:
- return "width requires unsupported line pitch";
- case MODE_NOMODE:
- return "no mode of this name";
- case MODE_NO_INTERLACE:
- return "interlace mode not supported";
- case MODE_NO_DBLESCAN:
- return "doublescan mode not supported";
- case MODE_NO_VSCAN:
- return "multiscan mode not supported";
- case MODE_MEM:
- return "insufficient memory for mode";
- case MODE_VIRTUAL_X:
- return "width too large for virtual size";
- case MODE_VIRTUAL_Y:
- return "height too large for virtual size";
- case MODE_MEM_VIRT:
- return "insufficient memory given virtual size";
- case MODE_NOCLOCK:
- return "no clock available for mode";
- case MODE_CLOCK_HIGH:
- return "mode clock too high";
- case MODE_CLOCK_LOW:
- return "mode clock too low";
- case MODE_CLOCK_RANGE:
- return "bad mode clock/interlace/doublescan";
- case MODE_BAD_HVALUE:
- return "horizontal timing out of range";
- case MODE_BAD_VVALUE:
- return "vertical timing out of range";
- case MODE_BAD_VSCAN:
- return "VScan value out of range";
- case MODE_HSYNC_NARROW:
- return "horizontal sync too narrow";
- case MODE_HSYNC_WIDE:
- return "horizontal sync too wide";
- case MODE_HBLANK_NARROW:
- return "horizontal blanking too narrow";
- case MODE_HBLANK_WIDE:
- return "horizontal blanking too wide";
- case MODE_VSYNC_NARROW:
- return "vertical sync too narrow";
- case MODE_VSYNC_WIDE:
- return "vertical sync too wide";
- case MODE_VBLANK_NARROW:
- return "vertical blanking too narrow";
- case MODE_VBLANK_WIDE:
- return "vertical blanking too wide";
- case MODE_PANEL:
- return "exceeds panel dimensions";
- case MODE_INTERLACE_WIDTH:
- return "width too large for interlaced mode";
- case MODE_ONE_WIDTH:
- return "all modes must have the same width";
- case MODE_ONE_HEIGHT:
- return "all modes must have the same height";
- case MODE_ONE_SIZE:
- return "all modes must have the same resolution";
- case MODE_NO_REDUCED:
- return "monitor doesn't support reduced blanking";
- case MODE_BANDWIDTH:
- return "mode requires too much memory bandwidth";
- case MODE_BAD:
- return "unknown reason";
- case MODE_ERROR:
- return "internal error";
- default:
- return "unknown";
- }
-}
-
-/*
- * xf86ShowClockRanges() -- Print the clock ranges allowed
- * and the clock values scaled by ClockMulFactor and ClockDivFactor
- */
-void
-xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges)
-{
- ClockRangePtr cp;
- int MulFactor = 1;
- int DivFactor = 1;
- int i, j;
- int scaledClock;
-
- for (cp = clockRanges; cp != NULL; cp = cp->next) {
- DivFactor = max(1, cp->ClockDivFactor);
- MulFactor = max(1, cp->ClockMulFactor);
- if (scrp->progClock) {
- if (cp->minClock) {
- if (cp->maxClock) {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Clock range: %6.2f to %6.2f MHz\n",
- (double)cp->minClock / 1000.0,
- (double)cp->maxClock / 1000.0);
- } else {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Minimum clock: %6.2f MHz\n",
- (double)cp->minClock / 1000.0);
- }
- } else {
- if (cp->maxClock) {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Maximum clock: %6.2f MHz\n",
- (double)cp->maxClock / 1000.0);
- }
- }
- } else if (DivFactor > 1 || MulFactor > 1) {
- j = 0;
- for (i = 0; i < scrp->numClocks; i++) {
- scaledClock = (scrp->clock[i] * DivFactor) / MulFactor;
- if (scaledClock >= cp->minClock && scaledClock <= cp->maxClock) {
- if ((j % 8) == 0) {
- if (j > 0)
- xf86ErrorF("\n");
- xf86DrvMsg(scrp->scrnIndex, X_INFO, "scaled clocks:");
- }
- xf86ErrorF(" %6.2f", (double)scaledClock / 1000.0);
- j++;
- }
- }
- xf86ErrorF("\n");
- }
- }
-}
-
-static Bool
-modeInClockRange(ClockRangePtr cp, DisplayModePtr p)
-{
- return ((p->Clock >= cp->minClock) &&
- (p->Clock <= cp->maxClock) &&
- (cp->interlaceAllowed || !(p->Flags & V_INTERLACE)) &&
- (cp->doubleScanAllowed ||
- ((p->VScan <= 1) && !(p->Flags & V_DBLSCAN))));
-}
-
-/*
- * xf86FindClockRangeForMode() [... like the name says ...]
- */
-static ClockRangePtr
-xf86FindClockRangeForMode(ClockRangePtr clockRanges, DisplayModePtr p)
-{
- ClockRangePtr cp;
-
- for (cp = clockRanges; ; cp = cp->next)
- if (!cp || modeInClockRange(cp, p))
- return cp;
-}
-
-
-/*
- * xf86HandleBuiltinMode() - handles built-in modes
- */
-static ModeStatus
-xf86HandleBuiltinMode(ScrnInfoPtr scrp,
- DisplayModePtr p,
- DisplayModePtr modep,
- ClockRangePtr clockRanges,
- Bool allowDiv2)
-{
- ClockRangePtr cp;
- int extraFlags = 0;
- int MulFactor = 1;
- int DivFactor = 1;
- int clockIndex;
-
- /* Reject previously rejected modes */
- if (p->status != MODE_OK)
- return p->status;
-
- /* Reject previously considered modes */
- if (p->prev)
- return MODE_NOMODE;
-
- if ((p->type & M_T_CLOCK_C) == M_T_CLOCK_C) {
- /* Check clock is in range */
- cp = xf86FindClockRangeForMode(clockRanges, p);
- if (cp == NULL){
- modep->type = p->type;
- p->status = MODE_CLOCK_RANGE;
- return MODE_CLOCK_RANGE;
- }
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- if (!scrp->progClock) {
- clockIndex = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
- cp->ClockDivFactor,
- cp->ClockMulFactor, &extraFlags);
- modep->Clock = (scrp->clock[clockIndex] * DivFactor)
- / MulFactor;
- modep->ClockIndex = clockIndex;
- modep->SynthClock = scrp->clock[clockIndex];
- if (extraFlags & V_CLKDIV2) {
- modep->Clock /= 2;
- modep->SynthClock /= 2;
- }
- } else {
- modep->Clock = p->Clock;
- modep->ClockIndex = -1;
- modep->SynthClock = (modep->Clock * MulFactor)
- / DivFactor;
- }
- modep->PrivFlags = cp->PrivFlags;
- } else {
- if(!scrp->progClock) {
- modep->Clock = p->Clock;
- modep->ClockIndex = p->ClockIndex;
- modep->SynthClock = p->SynthClock;
- } else {
- modep->Clock = p->Clock;
- modep->ClockIndex = -1;
- modep->SynthClock = p->SynthClock;
- }
- modep->PrivFlags = p->PrivFlags;
- }
- modep->type = p->type;
- modep->HDisplay = p->HDisplay;
- modep->HSyncStart = p->HSyncStart;
- modep->HSyncEnd = p->HSyncEnd;
- modep->HTotal = p->HTotal;
- modep->HSkew = p->HSkew;
- modep->VDisplay = p->VDisplay;
- modep->VSyncStart = p->VSyncStart;
- modep->VSyncEnd = p->VSyncEnd;
- modep->VTotal = p->VTotal;
- modep->VScan = p->VScan;
- modep->Flags = p->Flags | extraFlags;
- modep->CrtcHDisplay = p->CrtcHDisplay;
- modep->CrtcHBlankStart = p->CrtcHBlankStart;
- modep->CrtcHSyncStart = p->CrtcHSyncStart;
- modep->CrtcHSyncEnd = p->CrtcHSyncEnd;
- modep->CrtcHBlankEnd = p->CrtcHBlankEnd;
- modep->CrtcHTotal = p->CrtcHTotal;
- modep->CrtcHSkew = p->CrtcHSkew;
- modep->CrtcVDisplay = p->CrtcVDisplay;
- modep->CrtcVBlankStart = p->CrtcVBlankStart;
- modep->CrtcVSyncStart = p->CrtcVSyncStart;
- modep->CrtcVSyncEnd = p->CrtcVSyncEnd;
- modep->CrtcVBlankEnd = p->CrtcVBlankEnd;
- modep->CrtcVTotal = p->CrtcVTotal;
- modep->CrtcHAdjusted = p->CrtcHAdjusted;
- modep->CrtcVAdjusted = p->CrtcVAdjusted;
- modep->HSync = p->HSync;
- modep->VRefresh = p->VRefresh;
- modep->Private = p->Private;
- modep->PrivSize = p->PrivSize;
-
- p->prev = modep;
-
- return MODE_OK;
-}
-
-/*
- * xf86LookupMode
- *
- * This function returns a mode from the given list which matches the
- * given name. When multiple modes with the same name are available,
- * the method of picking the matching mode is determined by the
- * strategy selected.
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * modep pointer to the returned mode, which must have the name
- * field filled in.
- * clockRanges a list of clock ranges. This is optional when all the
- * modes are built-in modes.
- * strategy how to decide which mode to use from multiple modes with
- * the same name
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * modePool the list of monitor modes compatible with the driver
- * clocks a list of discrete clocks
- * numClocks number of discrete clocks
- * progClock clock is programmable
- *
- * If a mode was found, its values are filled in to the area pointed to
- * by modep, If a mode was not found the return value indicates the
- * reason.
- */
-
-ModeStatus
-xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
- ClockRangePtr clockRanges, LookupModeFlags strategy)
-{
- DisplayModePtr p, bestMode = NULL;
- ClockRangePtr cp;
- int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
- double refresh, bestRefresh = 0.0;
- Bool found = FALSE;
- int extraFlags = 0;
- int clockIndex = -1;
- int MulFactor = 1;
- int DivFactor = 1;
- int ModePrivFlags = 0;
- ModeStatus status = MODE_NOMODE;
- Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
- int n;
- const int types[] = {
- M_T_BUILTIN | M_T_PREFERRED,
- M_T_BUILTIN,
- M_T_USERDEF | M_T_PREFERRED,
- M_T_USERDEF,
- M_T_DRIVER | M_T_PREFERRED,
- M_T_DRIVER,
- 0
- };
- const int ntypes = sizeof(types) / sizeof(int);
-
- strategy &= ~(LOOKUP_CLKDIV2 | LOOKUP_OPTIONAL_TOLERANCES);
-
- /* Some sanity checking */
- if (scrp == NULL || scrp->modePool == NULL ||
- (!scrp->progClock && scrp->numClocks == 0)) {
- ErrorF("xf86LookupMode: called with invalid scrnInfoRec\n");
- return MODE_ERROR;
- }
- if (modep == NULL || modep->name == NULL) {
- ErrorF("xf86LookupMode: called with invalid modep\n");
- return MODE_ERROR;
- }
- for (cp = clockRanges; cp != NULL; cp = cp->next) {
- /* DivFactor and MulFactor must be > 0 */
- cp->ClockDivFactor = max(1, cp->ClockDivFactor);
- cp->ClockMulFactor = max(1, cp->ClockMulFactor);
- }
-
- /* Scan the mode pool for matching names */
- for (n = 0; n < ntypes; n++) {
- int type = types[n];
- for (p = scrp->modePool; p != NULL; p = p->next) {
-
- /* scan through the modes in the sort order above */
- if ((p->type & type) != type)
- continue;
-
- if (strcmp(p->name, modep->name) == 0) {
-
- /* Skip over previously rejected modes */
- if (p->status != MODE_OK) {
- if (!found)
- status = p->status;
- continue;
- }
-
- /* Skip over previously considered modes */
- if (p->prev)
- continue;
-
- if (p->type & M_T_BUILTIN) {
- return xf86HandleBuiltinMode(scrp, p,modep, clockRanges,
- allowDiv2);
- }
-
- /* Check clock is in range */
- cp = xf86FindClockRangeForMode(clockRanges, p);
- if (cp == NULL) {
- /*
- * XXX Could do more here to provide a more detailed
- * reason for not finding a mode.
- */
- p->status = MODE_CLOCK_RANGE;
- if (!found)
- status = MODE_CLOCK_RANGE;
- continue;
- }
-
- /*
- * If programmable clock and strategy is not
- * LOOKUP_BEST_REFRESH, the required mode has been found,
- * otherwise record the refresh and continue looking.
- */
- if (scrp->progClock) {
- found = TRUE;
- if (strategy != LOOKUP_BEST_REFRESH) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- break;
- }
- refresh = xf86ModeVRefresh(p);
- if (p->Flags & V_INTERLACE)
- refresh /= INTERLACE_REFRESH_WEIGHT;
- if (refresh > bestRefresh) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- bestRefresh = refresh;
- }
- continue;
- }
-
- /*
- * Clock is in range, so if it is not a programmable clock, find
- * a matching clock.
- */
-
- i = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
- cp->ClockDivFactor, cp->ClockMulFactor, &k);
- /*
- * If the clock is too far from the requested clock, this
- * mode is no good.
- */
- if (k & V_CLKDIV2)
- gap = abs((p->Clock * 2) -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- else
- gap = abs(p->Clock -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- if (gap > minimumGap) {
- p->status = MODE_NOCLOCK;
- if (!found)
- status = MODE_NOCLOCK;
- continue;
- }
- found = TRUE;
-
- if (strategy == LOOKUP_BEST_REFRESH) {
- refresh = xf86ModeVRefresh(p);
- if (p->Flags & V_INTERLACE)
- refresh /= INTERLACE_REFRESH_WEIGHT;
- if (refresh > bestRefresh) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- bestRefresh = refresh;
- }
- continue;
- }
- if (strategy == LOOKUP_CLOSEST_CLOCK) {
- if (gap < minimumGap) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- minimumGap = gap;
- }
- continue;
- }
- /*
- * If strategy is neither LOOKUP_BEST_REFRESH or
- * LOOKUP_CLOSEST_CLOCK the required mode has been found.
- */
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- break;
- }
- }
- if (found) break;
- }
- if (!found || bestMode == NULL)
- return status;
-
- /* Fill in the mode parameters */
- if (scrp->progClock) {
- modep->Clock = bestMode->Clock;
- modep->ClockIndex = -1;
- modep->SynthClock = (modep->Clock * MulFactor) / DivFactor;
- } else {
- modep->Clock = (scrp->clock[clockIndex] * DivFactor) /
- MulFactor;
- modep->ClockIndex = clockIndex;
- modep->SynthClock = scrp->clock[clockIndex];
- if (extraFlags & V_CLKDIV2) {
- modep->Clock /= 2;
- modep->SynthClock /= 2;
- }
- }
- modep->type = bestMode->type;
- modep->PrivFlags = ModePrivFlags;
- modep->HDisplay = bestMode->HDisplay;
- modep->HSyncStart = bestMode->HSyncStart;
- modep->HSyncEnd = bestMode->HSyncEnd;
- modep->HTotal = bestMode->HTotal;
- modep->HSkew = bestMode->HSkew;
- modep->VDisplay = bestMode->VDisplay;
- modep->VSyncStart = bestMode->VSyncStart;
- modep->VSyncEnd = bestMode->VSyncEnd;
- modep->VTotal = bestMode->VTotal;
- modep->VScan = bestMode->VScan;
- modep->Flags = bestMode->Flags | extraFlags;
- modep->CrtcHDisplay = bestMode->CrtcHDisplay;
- modep->CrtcHBlankStart = bestMode->CrtcHBlankStart;
- modep->CrtcHSyncStart = bestMode->CrtcHSyncStart;
- modep->CrtcHSyncEnd = bestMode->CrtcHSyncEnd;
- modep->CrtcHBlankEnd = bestMode->CrtcHBlankEnd;
- modep->CrtcHTotal = bestMode->CrtcHTotal;
- modep->CrtcHSkew = bestMode->CrtcHSkew;
- modep->CrtcVDisplay = bestMode->CrtcVDisplay;
- modep->CrtcVBlankStart = bestMode->CrtcVBlankStart;
- modep->CrtcVSyncStart = bestMode->CrtcVSyncStart;
- modep->CrtcVSyncEnd = bestMode->CrtcVSyncEnd;
- modep->CrtcVBlankEnd = bestMode->CrtcVBlankEnd;
- modep->CrtcVTotal = bestMode->CrtcVTotal;
- modep->CrtcHAdjusted = bestMode->CrtcHAdjusted;
- modep->CrtcVAdjusted = bestMode->CrtcVAdjusted;
- modep->HSync = bestMode->HSync;
- modep->VRefresh = bestMode->VRefresh;
- modep->Private = bestMode->Private;
- modep->PrivSize = bestMode->PrivSize;
-
- bestMode->prev = modep;
-
- return MODE_OK;
-}
-
-/*
- * xf86CheckModeForMonitor
- *
- * This function takes a mode and monitor description, and determines
- * if the mode is valid for the monitor.
- */
-ModeStatus
-xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor)
-{
- int i;
-
- /* Sanity checks */
- if (mode == NULL || monitor == NULL) {
- ErrorF("xf86CheckModeForMonitor: called with invalid parameters\n");
- return MODE_ERROR;
- }
-
- DebugF("xf86CheckModeForMonitor(%p %s, %p %s)\n",
- mode, mode->name, monitor, monitor->id);
-
- /* Some basic mode validity checks */
- if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
- mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
- return MODE_H_ILLEGAL;
-
- if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
- mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
- return MODE_V_ILLEGAL;
-
- if (monitor->nHsync > 0) {
- /* Check hsync against the allowed ranges */
- float hsync = xf86ModeHSync(mode);
- for (i = 0; i < monitor->nHsync; i++)
- if ((hsync > monitor->hsync[i].lo * (1.0 - SYNC_TOLERANCE)) &&
- (hsync < monitor->hsync[i].hi * (1.0 + SYNC_TOLERANCE)))
- break;
-
- /* Now see whether we ran out of sync ranges without finding a match */
- if (i == monitor->nHsync)
- return MODE_HSYNC;
- }
-
- if (monitor->nVrefresh > 0) {
- /* Check vrefresh against the allowed ranges */
- float vrefrsh = xf86ModeVRefresh(mode);
- for (i = 0; i < monitor->nVrefresh; i++)
- if ((vrefrsh > monitor->vrefresh[i].lo * (1.0 - SYNC_TOLERANCE)) &&
- (vrefrsh < monitor->vrefresh[i].hi * (1.0 + SYNC_TOLERANCE)))
- break;
-
- /* Now see whether we ran out of refresh ranges without finding a match */
- if (i == monitor->nVrefresh)
- return MODE_VSYNC;
- }
-
- /* Force interlaced modes to have an odd VTotal */
- if (mode->Flags & V_INTERLACE)
- mode->CrtcVTotal = mode->VTotal |= 1;
-
- /*
- * This code stops cvt -r modes, and only cvt -r modes, from hitting 15y+
- * old CRTs which might, when there is a lot of solar flare activity and
- * when the celestial bodies are unfavourably aligned, implode trying to
- * sync to it. It's called "Protecting the user from doing anything stupid".
- * -- libv
- */
-
- if (xf86ModeIsReduced(mode)) {
- if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER))
- return MODE_NO_REDUCED;
- }
-
- if ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock))
- return MODE_CLOCK_HIGH;
-
- return MODE_OK;
-}
-
-/*
- * xf86CheckModeSize
- *
- * An internal routine to check if a mode fits in video memory. This tries to
- * avoid overflows that would otherwise occur when video memory size is greater
- * than 256MB.
- */
-static Bool
-xf86CheckModeSize(ScrnInfoPtr scrp, int w, int x, int y)
-{
- int bpp = scrp->fbFormat.bitsPerPixel,
- pad = scrp->fbFormat.scanlinePad;
- int lineWidth, lastWidth;
-
- if (scrp->depth == 4)
- pad *= 4; /* 4 planes */
-
- /* Sanity check */
- if ((w < 0) || (x < 0) || (y <= 0))
- return FALSE;
-
- lineWidth = (((w * bpp) + pad - 1) / pad) * pad;
- lastWidth = x * bpp;
-
- /*
- * At this point, we need to compare
- *
- * (lineWidth * (y - 1)) + lastWidth
- *
- * against
- *
- * scrp->videoRam * (1024 * 8)
- *
- * These are bit quantities. To avoid overflows, do the comparison in
- * terms of BITMAP_SCANLINE_PAD units. This assumes BITMAP_SCANLINE_PAD
- * is a power of 2. We currently use 32, which limits us to a video
- * memory size of 8GB.
- */
-
- lineWidth = (lineWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
- lastWidth = (lastWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
-
- if ((lineWidth * (y - 1) + lastWidth) >
- (scrp->videoRam * ((1024 * 8) / BITMAP_SCANLINE_PAD)))
- return FALSE;
-
- return TRUE;
-}
-
-/*
- * xf86InitialCheckModeForDriver
- *
- * This function checks if a mode satisfies a driver's initial requirements:
- * - mode size fits within the available pixel area (memory)
- * - width lies within the range of supported line pitches
- * - mode size fits within virtual size (if fixed)
- * - horizontal timings are in range
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * mode mode to check
- * maxPitch (optional) maximum line pitch
- * virtualX (optional) virtual width requested
- * virtualY (optional) virtual height requested
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * monitor pointer to structure for monitor section
- * fbFormat pixel format for the framebuffer
- * videoRam video memory size (in kB)
- * maxHValue maximum horizontal timing value
- * maxVValue maximum vertical timing value
- */
-
-ModeStatus
-xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
- ClockRangePtr clockRanges,
- LookupModeFlags strategy,
- int maxPitch, int virtualX, int virtualY)
-{
- ClockRangePtr cp;
- ModeStatus status;
- Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
- int i, needDiv2;
-
- /* Sanity checks */
- if (!scrp || !mode || !clockRanges) {
- ErrorF("xf86InitialCheckModeForDriver: "
- "called with invalid parameters\n");
- return MODE_ERROR;
- }
-
- DebugF("xf86InitialCheckModeForDriver(%p, %p %s, %p, 0x%x, %d, %d, %d)\n",
- scrp, mode, mode->name , clockRanges, strategy, maxPitch, virtualX, virtualY);
-
- /* Some basic mode validity checks */
- if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
- mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
- return MODE_H_ILLEGAL;
-
- if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
- mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
- return MODE_V_ILLEGAL;
-
- if (!xf86CheckModeSize(scrp, mode->HDisplay, mode->HDisplay,
- mode->VDisplay))
- return MODE_MEM;
-
- if (maxPitch > 0 && mode->HDisplay > maxPitch)
- return MODE_BAD_WIDTH;
-
- if (virtualX > 0 && mode->HDisplay > virtualX)
- return MODE_VIRTUAL_X;
-
- if (virtualY > 0 && mode->VDisplay > virtualY)
- return MODE_VIRTUAL_Y;
-
- if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
- return MODE_BAD_HVALUE;
-
- if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
- return MODE_BAD_VVALUE;
-
- /*
- * The use of the DisplayModeRec's Crtc* and SynthClock elements below is
- * provisional, in that they are later reused by the driver at mode-set
- * time. Here, they are temporarily enlisted to contain the mode timings
- * as seen by the CRT or panel (rather than the CRTC). The driver's
- * ValidMode() is allowed to modify these so it can deal with such things
- * as mode stretching and/or centering. The driver should >NOT< modify the
- * user-supplied values as these are reported back when mode validation is
- * said and done.
- */
- /*
- * NOTE: We (ab)use the mode->Crtc* values here to store timing
- * information for the calculation of Hsync and Vrefresh. Before
- * these values are calculated the driver is given the opportunity
- * to either set these HSync and VRefresh itself or modify the timing
- * values.
- * The difference to the final calculation is small but imortand:
- * here we pass the flag INTERLACE_HALVE_V regardless if the driver
- * sets it or not. This way our calculation of VRefresh has the same
- * effect as if we do if (flags & V_INTERLACE) refresh *= 2.0
- * This dual use of the mode->Crtc* values will certainly create
- * confusion and is bad software design. However since it's part of
- * the driver API it's hard to change.
- */
-
- if (scrp->ValidMode) {
-
- xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
-
- cp = xf86FindClockRangeForMode(clockRanges, mode);
- if (!cp)
- return MODE_CLOCK_RANGE;
-
- if (cp->ClockMulFactor < 1)
- cp->ClockMulFactor = 1;
- if (cp->ClockDivFactor < 1)
- cp->ClockDivFactor = 1;
-
- /*
- * XXX The effect of clock dividers and multipliers on the monitor's
- * pixel clock needs to be verified.
- */
- if (scrp->progClock) {
- mode->SynthClock = mode->Clock;
- } else {
- i = xf86GetNearestClock(scrp, mode->Clock, allowDiv2,
- cp->ClockDivFactor, cp->ClockMulFactor,
- &needDiv2);
- mode->SynthClock = (scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor;
- if (needDiv2 & V_CLKDIV2)
- mode->SynthClock /= 2;
- }
-
- status = (*scrp->ValidMode)(scrp->scrnIndex, mode, FALSE,
- MODECHECK_INITIAL);
- if (status != MODE_OK)
- return status;
-
- if (mode->HSync <= 0.0)
- mode->HSync = (float)mode->SynthClock / (float)mode->CrtcHTotal;
- if (mode->VRefresh <= 0.0)
- mode->VRefresh = (mode->SynthClock * 1000.0)
- / (mode->CrtcHTotal * mode->CrtcVTotal);
- }
-
- mode->HSync = xf86ModeHSync(mode);
- mode->VRefresh = xf86ModeVRefresh(mode);
-
- /* Assume it is OK */
- return MODE_OK;
-}
-
-/*
- * xf86CheckModeForDriver
- *
- * This function is for checking modes while the server is running (for
- * use mainly by the VidMode extension).
- *
- * This function checks if a mode satisfies a driver's requirements:
- * - width lies within the line pitch
- * - mode size fits within virtual size
- * - horizontal/vertical timings are in range
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * mode mode to check
- * flags not (currently) used
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * maxHValue maximum horizontal timing value
- * maxVValue maximum vertical timing value
- * virtualX virtual width
- * virtualY virtual height
- * clockRanges allowable clock ranges
- */
-
-ModeStatus
-xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, int flags)
-{
- ClockRangePtr cp;
- int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
- int extraFlags = 0;
- int clockIndex = -1;
- int MulFactor = 1;
- int DivFactor = 1;
- int ModePrivFlags = 0;
- ModeStatus status = MODE_NOMODE;
-
- /* Some sanity checking */
- if (scrp == NULL || (!scrp->progClock && scrp->numClocks == 0)) {
- ErrorF("xf86CheckModeForDriver: called with invalid scrnInfoRec\n");
- return MODE_ERROR;
- }
- if (mode == NULL) {
- ErrorF("xf86CheckModeForDriver: called with invalid modep\n");
- return MODE_ERROR;
- }
-
- /* Check the mode size */
- if (mode->HDisplay > scrp->virtualX)
- return MODE_VIRTUAL_X;
-
- if (mode->VDisplay > scrp->virtualY)
- return MODE_VIRTUAL_Y;
-
- if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
- return MODE_BAD_HVALUE;
-
- if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
- return MODE_BAD_VVALUE;
-
- for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
- /* DivFactor and MulFactor must be > 0 */
- cp->ClockDivFactor = max(1, cp->ClockDivFactor);
- cp->ClockMulFactor = max(1, cp->ClockMulFactor);
- }
-
- if (scrp->progClock) {
- /* Check clock is in range */
- for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
- if (modeInClockRange(cp, mode))
- break;
- }
- if (cp == NULL) {
- return MODE_CLOCK_RANGE;
- }
- /*
- * If programmable clock the required mode has been found
- */
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- } else {
- status = MODE_CLOCK_RANGE;
- /* Check clock is in range */
- for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
- if (modeInClockRange(cp, mode)) {
- /*
- * Clock is in range, so if it is not a programmable clock,
- * find a matching clock.
- */
-
- i = xf86GetNearestClock(scrp, mode->Clock, 0,
- cp->ClockDivFactor, cp->ClockMulFactor, &k);
- /*
- * If the clock is too far from the requested clock, this
- * mode is no good.
- */
- if (k & V_CLKDIV2)
- gap = abs((mode->Clock * 2) -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- else
- gap = abs(mode->Clock -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- if (gap > minimumGap) {
- status = MODE_NOCLOCK;
- continue;
- }
-
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- break;
- }
- }
- if (cp == NULL)
- return status;
- }
-
- /* Fill in the mode parameters */
- if (scrp->progClock) {
- mode->ClockIndex = -1;
- mode->SynthClock = (mode->Clock * MulFactor) / DivFactor;
- } else {
- mode->Clock = (scrp->clock[clockIndex] * DivFactor) / MulFactor;
- mode->ClockIndex = clockIndex;
- mode->SynthClock = scrp->clock[clockIndex];
- if (extraFlags & V_CLKDIV2) {
- mode->Clock /= 2;
- mode->SynthClock /= 2;
- }
- }
- mode->PrivFlags = ModePrivFlags;
-
- return MODE_OK;
-}
-
-static int
-inferVirtualSize(ScrnInfoPtr scrp, DisplayModePtr modes, int *vx, int *vy)
-{
- float aspect = 0.0;
- MonPtr mon = scrp->monitor;
- xf86MonPtr DDC;
- int x = 0, y = 0;
- DisplayModePtr mode;
-
- if (!mon) return 0;
- DDC = mon->DDC;
-
- if (DDC && DDC->ver.revision >= 4) {
- /* For 1.4, we might actually get native pixel format. How novel. */
- if (PREFERRED_TIMING_MODE(DDC->features.msc)) {
- for (mode = modes; mode; mode = mode->next) {
- if (mode->type & (M_T_DRIVER | M_T_PREFERRED)) {
- x = mode->HDisplay;
- y = mode->VDisplay;
- goto found;
- }
- }
- }
- /*
- * Even if we don't, we might get aspect ratio from extra CVT info
- * or from the monitor size fields. TODO.
- */
- }
-
- /*
- * Technically this triggers if either is zero. That wasn't legal
- * before EDID 1.4, but right now we'll get that wrong. TODO.
- */
- if (!aspect) {
- if (!mon->widthmm || !mon->heightmm)
- aspect = 4.0/3.0;
- else
- aspect = (float)mon->widthmm / (float)mon->heightmm;
- }
-
- /* find the largest M_T_DRIVER mode with that aspect ratio */
- for (mode = modes; mode; mode = mode->next) {
- float mode_aspect, metaspect;
- if (!(mode->type & (M_T_DRIVER|M_T_USERDEF)))
- continue;
- mode_aspect = (float)mode->HDisplay / (float)mode->VDisplay;
- metaspect = aspect / mode_aspect;
- /* 5% slop or so, since we only get size in centimeters */
- if (fabs(1.0 - metaspect) < 0.05) {
- if ((mode->HDisplay > x) && (mode->VDisplay > y)) {
- x = mode->HDisplay;
- y = mode->VDisplay;
- }
- }
- }
-
- if (!x || !y) {
- xf86DrvMsg(scrp->scrnIndex, X_WARNING,
- "Unable to estimate virtual size\n");
- return 0;
- }
-
-found:
- *vx = x;
- *vy = y;
-
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Estimated virtual size for aspect ratio %.4f is %dx%d\n",
- aspect, *vx, *vy);
-
- return 1;
-}
-
-/* Least common multiple */
-static unsigned int
-LCM(unsigned int x, unsigned int y)
-{
- unsigned int m = x, n = y, o;
-
- while ((o = m % n))
- {
- m = n;
- n = o;
- }
-
- return (x / n) * y;
-}
-
-/*
- * Given various screen attributes, determine the minimum scanline width such
- * that each scanline is server and DDX padded and any pixels with imbedded
- * bank boundaries are off-screen. This function returns -1 if such a width
- * cannot exist.
- */
-static int
-scanLineWidth(
- unsigned int xsize, /* pixels */
- unsigned int ysize, /* pixels */
- unsigned int width, /* pixels */
- unsigned long BankSize, /* char's */
- PixmapFormatRec *pBankFormat,
- unsigned int nWidthUnit /* bits */
-)
-{
- unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit;
- unsigned long minBitsPerScanline, maxBitsPerScanline;
-
- /* Sanity checks */
-
- if (!nWidthUnit || !pBankFormat)
- return -1;
-
- nBitsPerBank = BankSize * 8;
- if (nBitsPerBank % pBankFormat->scanlinePad)
- return -1;
-
- if (xsize > width)
- width = xsize;
- nBitsPerScanlinePadUnit = LCM(pBankFormat->scanlinePad, nWidthUnit);
- nBitsPerScanline =
- (((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) /
- nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit;
- width = nBitsPerScanline / pBankFormat->bitsPerPixel;
-
- if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel))
- return (int)width;
-
- /*
- * Scanlines will be server-pad aligned at this point. They will also be
- * a multiple of nWidthUnit bits long. Ensure that pixels with imbedded
- * bank boundaries are off-screen.
- *
- * It seems reasonable to limit total frame buffer size to 1/16 of the
- * theoretical maximum address space size. On a machine with 32-bit
- * addresses (to 8-bit quantities) this turns out to be 256MB. Not only
- * does this provide a simple limiting condition for the loops below, but
- * it also prevents unsigned long wraparounds.
- */
- if (!ysize)
- return -1;
-
- minBitsPerScanline = xsize * pBankFormat->bitsPerPixel;
- if (minBitsPerScanline > nBitsPerBank)
- return -1;
-
- if (ysize == 1)
- return (int)width;
-
- maxBitsPerScanline =
- (((unsigned long)(-1) >> 1) - minBitsPerScanline) / (ysize - 1);
- while (nBitsPerScanline <= maxBitsPerScanline)
- {
- unsigned long BankBase, BankUnit;
-
- BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) *
- nBitsPerBank;
- if (!(BankUnit % nBitsPerScanline))
- return (int)width;
-
- for (BankBase = BankUnit; ; BankBase += nBitsPerBank)
- {
- unsigned long x, y;
-
- y = BankBase / nBitsPerScanline;
- if (y >= ysize)
- return (int)width;
-
- x = BankBase % nBitsPerScanline;
- if (!(x % pBankFormat->bitsPerPixel))
- continue;
-
- if (x < minBitsPerScanline)
- {
- /*
- * Skip ahead certain widths by dividing the excess scanline
- * amongst the y's.
- */
- y *= nBitsPerScanlinePadUnit;
- nBitsPerScanline +=
- ((x + y - 1) / y) * nBitsPerScanlinePadUnit;
- width = nBitsPerScanline / pBankFormat->bitsPerPixel;
- break;
- }
-
- if (BankBase != BankUnit)
- continue;
-
- if (!(nBitsPerScanline % x))
- return (int)width;
-
- BankBase = ((nBitsPerScanline - minBitsPerScanline) /
- (nBitsPerScanline - x)) * BankUnit;
- }
- }
-
- return -1;
-}
-
-/*
- * xf86ValidateModes
- *
- * This function takes a set of mode names, modes and limiting conditions,
- * and selects a set of modes and parameters based on those conditions.
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * availModes the list of modes available for the monitor
- * modeNames (optional) list of mode names that the screen is requesting
- * clockRanges a list of clock ranges
- * linePitches (optional) a list of line pitches
- * minPitch (optional) minimum line pitch (in pixels)
- * maxPitch (optional) maximum line pitch (in pixels)
- * pitchInc (mandatory) pitch increment (in bits)
- * minHeight (optional) minimum virtual height (in pixels)
- * maxHeight (optional) maximum virtual height (in pixels)
- * virtualX (optional) virtual width requested (in pixels)
- * virtualY (optional) virtual height requested (in pixels)
- * apertureSize size of video aperture (in bytes)
- * strategy how to decide which mode to use from multiple modes with
- * the same name
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * clocks a list of discrete clocks
- * numClocks number of discrete clocks
- * progClock clock is programmable
- * monitor pointer to structure for monitor section
- * fbFormat format of the framebuffer
- * videoRam video memory size
- * maxHValue maximum horizontal timing value
- * maxVValue maximum vertical timing value
- * xInc horizontal timing increment (defaults to 8 pixels)
- *
- * The function fills in the following ScrnInfoRec fields:
- * modePool A subset of the modes available to the monitor which
- * are compatible with the driver.
- * modes one mode entry for each of the requested modes, with the
- * status field filled in to indicate if the mode has been
- * accepted or not.
- * virtualX the resulting virtual width
- * virtualY the resulting virtual height
- * displayWidth the resulting line pitch
- *
- * The function's return value is the number of matching modes found, or -1
- * if an unrecoverable error was encountered.
- */
-
-int
-xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
- char **modeNames, ClockRangePtr clockRanges,
- int *linePitches, int minPitch, int maxPitch, int pitchInc,
- int minHeight, int maxHeight, int virtualX, int virtualY,
- int apertureSize, LookupModeFlags strategy)
-{
- DisplayModePtr p, q, r, new, last, *endp;
- int i, numModes = 0;
- ModeStatus status;
- int linePitch = -1, virtX = 0, virtY = 0;
- int newLinePitch, newVirtX, newVirtY;
- int modeSize; /* in pixels */
- Bool validateAllDefaultModes = FALSE;
- Bool userModes = FALSE;
- int saveType;
- PixmapFormatRec *BankFormat;
- ClockRangePtr cp;
- ClockRangePtr storeClockRanges;
- int numTimings = 0;
- range hsync[MAX_HSYNC];
- range vrefresh[MAX_VREFRESH];
- Bool inferred_virtual = FALSE;
-
- DebugF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n",
- scrp, availModes, modeNames, clockRanges,
- linePitches, minPitch, maxPitch, pitchInc,
- minHeight, maxHeight, virtualX, virtualY,
- apertureSize, strategy
- );
-
- /* Some sanity checking */
- if (scrp == NULL || scrp->name == NULL || !scrp->monitor ||
- (!scrp->progClock && scrp->numClocks == 0)) {
- ErrorF("xf86ValidateModes: called with invalid scrnInfoRec\n");
- return -1;
- }
- if (linePitches != NULL && linePitches[0] <= 0) {
- ErrorF("xf86ValidateModes: called with invalid linePitches\n");
- return -1;
- }
- if (pitchInc <= 0) {
- ErrorF("xf86ValidateModes: called with invalid pitchInc\n");
- return -1;
- }
- if ((virtualX > 0) != (virtualY > 0)) {
- ErrorF("xf86ValidateModes: called with invalid virtual resolution\n");
- return -1;
- }
-
- /*
- * If requested by the driver, allow missing hsync and/or vrefresh ranges
- * in the monitor section.
- */
- if (strategy & LOOKUP_OPTIONAL_TOLERANCES) {
- strategy &= ~LOOKUP_OPTIONAL_TOLERANCES;
- } else {
- const char *type = "";
- Bool specified = FALSE;
-
- if (scrp->monitor->nHsync <= 0) {
- if (numTimings > 0) {
- scrp->monitor->nHsync = numTimings;
- for (i = 0; i < numTimings; i++) {
- scrp->monitor->hsync[i].lo = hsync[i].lo;
- scrp->monitor->hsync[i].hi = hsync[i].hi;
- }
- } else {
- scrp->monitor->hsync[0].lo = 31.5;
- scrp->monitor->hsync[0].hi = 48.0;
- scrp->monitor->nHsync = 1;
- }
- type = "default ";
- } else {
- specified = TRUE;
- }
- for (i = 0; i < scrp->monitor->nHsync; i++) {
- if (scrp->monitor->hsync[i].lo == scrp->monitor->hsync[i].hi)
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %shsync value of %.2f kHz\n",
- scrp->monitor->id, type,
- scrp->monitor->hsync[i].lo);
- else
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %shsync range of %.2f-%.2f kHz\n",
- scrp->monitor->id, type,
- scrp->monitor->hsync[i].lo,
- scrp->monitor->hsync[i].hi);
- }
-
- type = "";
- if (scrp->monitor->nVrefresh <= 0) {
- if (numTimings > 0) {
- scrp->monitor->nVrefresh = numTimings;
- for (i = 0; i < numTimings; i++) {
- scrp->monitor->vrefresh[i].lo = vrefresh[i].lo;
- scrp->monitor->vrefresh[i].hi = vrefresh[i].hi;
- }
- } else {
- scrp->monitor->vrefresh[0].lo = 50;
- scrp->monitor->vrefresh[0].hi = 70;
- scrp->monitor->nVrefresh = 1;
- }
- type = "default ";
- } else {
- specified = TRUE;
- }
- for (i = 0; i < scrp->monitor->nVrefresh; i++) {
- if (scrp->monitor->vrefresh[i].lo == scrp->monitor->vrefresh[i].hi)
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %svrefresh value of %.2f Hz\n",
- scrp->monitor->id, type,
- scrp->monitor->vrefresh[i].lo);
- else
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %svrefresh range of %.2f-%.2f Hz\n",
- scrp->monitor->id, type,
- scrp->monitor->vrefresh[i].lo,
- scrp->monitor->vrefresh[i].hi);
- }
-
- type = "";
- if (!scrp->monitor->maxPixClock && !specified) {
- type = "default ";
- scrp->monitor->maxPixClock = 65000.0;
- }
- if (scrp->monitor->maxPixClock) {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %smaximum pixel clock of %.2f MHz\n",
- scrp->monitor->id, type,
- (float)scrp->monitor->maxPixClock / 1000.0);
- }
- }
-
- /*
- * Store the clockRanges for later use by the VidMode extension.
- */
- storeClockRanges = scrp->clockRanges;
- while (storeClockRanges != NULL) {
- storeClockRanges = storeClockRanges->next;
- }
- for (cp = clockRanges; cp != NULL; cp = cp->next,
- storeClockRanges = storeClockRanges->next) {
- storeClockRanges = xnfalloc(sizeof(ClockRange));
- if (scrp->clockRanges == NULL)
- scrp->clockRanges = storeClockRanges;
- memcpy(storeClockRanges, cp, sizeof(ClockRange));
- }
-
- /* Determine which pixmap format to pass to scanLineWidth() */
- if (scrp->depth > 4)
- BankFormat = &scrp->fbFormat;
- else
- BankFormat = xf86GetPixFormat(scrp, 1); /* >not< scrp->depth! */
-
- if (scrp->xInc <= 0)
- scrp->xInc = 8; /* Suitable for VGA and others */
-
-#define _VIRTUALX(x) ((((x) + scrp->xInc - 1) / scrp->xInc) * scrp->xInc)
-
- /*
- * Determine maxPitch if it wasn't given explicitly. Note linePitches
- * always takes precedence if is non-NULL. In that case the minPitch and
- * maxPitch values passed are ignored.
- */
- if (linePitches) {
- minPitch = maxPitch = linePitches[0];
- for (i = 1; linePitches[i] > 0; i++) {
- if (linePitches[i] > maxPitch)
- maxPitch = linePitches[i];
- if (linePitches[i] < minPitch)
- minPitch = linePitches[i];
- }
- }
-
- /* Initial check of virtual size against other constraints */
- scrp->virtualFrom = X_PROBED;
- /*
- * Initialise virtX and virtY if the values are fixed.
- */
- if (virtualY > 0) {
- if (maxHeight > 0 && virtualY > maxHeight) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual height (%d) is too large for the hardware "
- "(max %d)\n", virtualY, maxHeight);
- return -1;
- }
-
- if (minHeight > 0 && virtualY < minHeight) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual height (%d) is too small for the hardware "
- "(min %d)\n", virtualY, minHeight);
- return -1;
- }
-
- virtualX = _VIRTUALX(virtualX);
- if (linePitches != NULL) {
- for (i = 0; linePitches[i] != 0; i++) {
- if ((linePitches[i] >= virtualX) &&
- (linePitches[i] ==
- scanLineWidth(virtualX, virtualY, linePitches[i],
- apertureSize, BankFormat, pitchInc))) {
- linePitch = linePitches[i];
- break;
- }
- }
- } else {
- linePitch = scanLineWidth(virtualX, virtualY, minPitch,
- apertureSize, BankFormat, pitchInc);
- }
-
- if ((linePitch < minPitch) || (linePitch > maxPitch)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual width (%d) is too large for the hardware "
- "(max %d)\n", virtualX, maxPitch);
- return -1;
- }
-
- if (!xf86CheckModeSize(scrp, linePitch, virtualX, virtualY)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual size (%dx%d) (pitch %d) exceeds video memory\n",
- virtualX, virtualY, linePitch);
- return -1;
- }
-
- virtX = virtualX;
- virtY = virtualY;
- scrp->virtualFrom = X_CONFIG;
- } else if (!modeNames || !*modeNames) {
- /* No virtual size given in the config, try to infer */
- /* XXX this doesn't take m{in,ax}Pitch into account; oh well */
- inferred_virtual = inferVirtualSize(scrp, availModes, &virtX, &virtY);
- if (inferred_virtual)
- linePitch = scanLineWidth(virtX, virtY, minPitch, apertureSize,
- BankFormat, pitchInc);
- }
-
- /* Print clock ranges and scaled clocks */
- xf86ShowClockRanges(scrp, clockRanges);
-
- /*
- * If scrp->modePool hasn't been setup yet, set it up now. This allows the
- * modes that the driver definitely can't use to be weeded out early. Note
- * that a modePool mode's prev field is used to hold a pointer to the
- * member of the scrp->modes list for which a match was considered.
- */
- if (scrp->modePool == NULL) {
- q = NULL;
- for (p = availModes; p != NULL; p = p->next) {
- status = xf86InitialCheckModeForDriver(scrp, p, clockRanges,
- strategy, maxPitch,
- virtX, virtY);
-
- if (status == MODE_OK) {
- status = xf86CheckModeForMonitor(p, scrp->monitor);
- }
-
- if (status == MODE_OK) {
- new = xnfalloc(sizeof(DisplayModeRec));
- *new = *p;
- new->next = NULL;
- if (!q) {
- scrp->modePool = new;
- } else {
- q->next = new;
- }
- new->prev = NULL;
- q = new;
- q->name = xnfstrdup(p->name);
- q->status = MODE_OK;
- } else {
- printModeRejectMessage(scrp->scrnIndex, p, status);
- }
- }
-
- if (scrp->modePool == NULL) {
- xf86DrvMsg(scrp->scrnIndex, X_WARNING, "Mode pool is empty\n");
- return 0;
- }
- } else {
- for (p = scrp->modePool; p != NULL; p = p->next) {
- p->prev = NULL;
- p->status = MODE_OK;
- }
- }
-
- /*
- * Allocate one entry in scrp->modes for each named mode.
- */
- while (scrp->modes)
- xf86DeleteMode(&scrp->modes, scrp->modes);
- endp = &scrp->modes;
- last = NULL;
- if (modeNames != NULL) {
- for (i = 0; modeNames[i] != NULL; i++) {
- userModes = TRUE;
- new = xnfcalloc(1, sizeof(DisplayModeRec));
- new->prev = last;
- new->type = M_T_USERDEF;
- new->name = xnfstrdup(modeNames[i]);
- if (new->prev)
- new->prev->next = new;
- *endp = last = new;
- endp = &new->next;
- }
- }
-
- /* Lookup each mode */
-#ifdef RANDR
- if (!xf86Info.disableRandR
-#ifdef PANORAMIX
- && noPanoramiXExtension
-#endif
- )
- validateAllDefaultModes = TRUE;
-#endif
-
- for (p = scrp->modes; ; p = p->next) {
- Bool repeat;
-
- /*
- * If the supplied mode names don't produce a valid mode, scan through
- * unconsidered modePool members until one survives validation. This
- * is done in decreasing order by mode pixel area.
- */
-
- if (p == NULL) {
- if ((numModes > 0) && !validateAllDefaultModes)
- break;
-
- validateAllDefaultModes = TRUE;
- r = NULL;
- modeSize = 0;
- for (q = scrp->modePool; q != NULL; q = q->next) {
- if ((q->prev == NULL) && (q->status == MODE_OK)) {
- /*
- * Deal with the case where this mode wasn't considered
- * because of a builtin mode of the same name.
- */
- for (p = scrp->modes; p != NULL; p = p->next) {
- if ((p->status != MODE_OK) &&
- !strcmp(p->name, q->name))
- break;
- }
-
- if (p != NULL)
- q->prev = p;
- else {
- /*
- * A quick check to not allow default modes with
- * horizontal timing parameters that CRTs may have
- * problems with.
- */
- if (!scrp->monitor->reducedblanking &&
- (q->type & M_T_DEFAULT) &&
- ((double)q->HTotal / (double)q->HDisplay) < 1.15)
- continue;
-
- if (modeSize < (q->HDisplay * q->VDisplay)) {
- r = q;
- modeSize = q->HDisplay * q->VDisplay;
- }
- }
- }
- }
-
- if (r == NULL)
- break;
-
- p = xnfcalloc(1, sizeof(DisplayModeRec));
- p->prev = last;
- p->name = xnfstrdup(r->name);
- if (!userModes)
- p->type = M_T_USERDEF;
- if (p->prev)
- p->prev->next = p;
- *endp = last = p;
- endp = &p->next;
- }
-
- repeat = FALSE;
- lookupNext:
- if (repeat && ((status = p->status) != MODE_OK))
- printModeRejectMessage(scrp->scrnIndex, p, status);
- saveType = p->type;
- status = xf86LookupMode(scrp, p, clockRanges, strategy);
- if (repeat && status == MODE_NOMODE)
- continue;
- if (status != MODE_OK)
- printModeRejectMessage(scrp->scrnIndex, p, status);
- if (status == MODE_ERROR) {
- ErrorF("xf86ValidateModes: "
- "unexpected result from xf86LookupMode()\n");
- return -1;
- }
- if (status != MODE_OK) {
- if (p->status == MODE_OK)
- p->status = status;
- continue;
- }
- p->type |= saveType;
- repeat = TRUE;
-
- newLinePitch = linePitch;
- newVirtX = virtX;
- newVirtY = virtY;
-
- /*
- * Don't let non-user defined modes increase the virtual size
- */
- if (!(p->type & M_T_USERDEF) && (numModes > 0)) {
- if (p->HDisplay > virtX) {
- p->status = MODE_VIRTUAL_X;
- goto lookupNext;
- }
- if (p->VDisplay > virtY) {
- p->status = MODE_VIRTUAL_Y;
- goto lookupNext;
- }
- }
- /*
- * Adjust virtual width and height if the mode is too large for the
- * current values and if they are not fixed.
- */
- if (virtualX <= 0 && p->HDisplay > newVirtX)
- newVirtX = _VIRTUALX(p->HDisplay);
- if (virtualY <= 0 && p->VDisplay > newVirtY) {
- if (maxHeight > 0 && p->VDisplay > maxHeight) {
- p->status = MODE_VIRTUAL_Y; /* ? */
- goto lookupNext;
- }
- newVirtY = p->VDisplay;
- }
-
- /*
- * If virtual resolution is to be increased, revalidate it.
- */
- if ((virtX != newVirtX) || (virtY != newVirtY)) {
- if (linePitches != NULL) {
- newLinePitch = -1;
- for (i = 0; linePitches[i] != 0; i++) {
- if ((linePitches[i] >= newVirtX) &&
- (linePitches[i] >= linePitch) &&
- (linePitches[i] ==
- scanLineWidth(newVirtX, newVirtY, linePitches[i],
- apertureSize, BankFormat, pitchInc))) {
- newLinePitch = linePitches[i];
- break;
- }
- }
- } else {
- if (linePitch < minPitch)
- linePitch = minPitch;
- newLinePitch = scanLineWidth(newVirtX, newVirtY, linePitch,
- apertureSize, BankFormat,
- pitchInc);
- }
- if ((newLinePitch < minPitch) || (newLinePitch > maxPitch)) {
- p->status = MODE_BAD_WIDTH;
- goto lookupNext;
- }
-
- /*
- * Check that the pixel area required by the new virtual height
- * and line pitch isn't too large.
- */
- if (!xf86CheckModeSize(scrp, newLinePitch, newVirtX, newVirtY)) {
- p->status = MODE_MEM_VIRT;
- goto lookupNext;
- }
- }
-
- if (scrp->ValidMode) {
- /*
- * Give the driver a final say, passing it the proposed virtual
- * geometry.
- */
- scrp->virtualX = newVirtX;
- scrp->virtualY = newVirtY;
- scrp->displayWidth = newLinePitch;
- p->status = (scrp->ValidMode)(scrp->scrnIndex, p, FALSE,
- MODECHECK_FINAL);
-
- if (p->status != MODE_OK) {
- goto lookupNext;
- }
- }
-
- /* Mode has passed all the tests */
- virtX = newVirtX;
- virtY = newVirtY;
- linePitch = newLinePitch;
- p->status = MODE_OK;
- numModes++;
- }
-
- /*
- * If we estimated the virtual size above, we may have filtered away all
- * the modes that maximally match that size; scan again to find out and
- * fix up if so.
- */
- if (inferred_virtual) {
- int vx = 0, vy = 0;
- for (p = scrp->modes; p; p = p->next) {
- if (p->HDisplay > vx && p->VDisplay > vy) {
- vx = p->HDisplay;
- vy = p->VDisplay;
- }
- }
- if (vx < virtX || vy < virtY) {
- const int types[] = {
- M_T_BUILTIN | M_T_PREFERRED,
- M_T_BUILTIN,
- M_T_DRIVER | M_T_PREFERRED,
- M_T_DRIVER,
- 0
- };
- const int ntypes = sizeof(types) / sizeof(int);
- int n;
-
- /*
- * We did not find the estimated virtual size. So now we want to
- * find the largest mode available, but we want to search in the
- * modes in the order of "types" listed above.
- */
- for (n = 0; n < ntypes; n++) {
- int type = types[n];
-
- vx = 0; vy = 0;
- for (p = scrp->modes; p; p = p->next) {
- /* scan through the modes in the sort order above */
- if ((p->type & type) != type)
- continue;
- if (p->HDisplay > vx && p->VDisplay > vy) {
- vx = p->HDisplay;
- vy = p->VDisplay;
- }
- }
- if (vx && vy)
- /* Found one */
- break;
- }
- xf86DrvMsg(scrp->scrnIndex, X_WARNING,
- "Shrinking virtual size estimate from %dx%d to %dx%d\n",
- virtX, virtY, vx, vy);
- virtX = _VIRTUALX(vx);
- virtY = vy;
- for (p = scrp->modes; p; p = p->next) {
- if (numModes > 0) {
- if (p->HDisplay > virtX)
- p->status = MODE_VIRTUAL_X;
- if (p->VDisplay > virtY)
- p->status = MODE_VIRTUAL_Y;
- if (p->status != MODE_OK) {
- numModes--;
- printModeRejectMessage(scrp->scrnIndex, p, p->status);
- }
- }
- }
- if (linePitches != NULL) {
- for (i = 0; linePitches[i] != 0; i++) {
- if ((linePitches[i] >= virtX) &&
- (linePitches[i] ==
- scanLineWidth(virtX, virtY, linePitches[i],
- apertureSize, BankFormat, pitchInc))) {
- linePitch = linePitches[i];
- break;
- }
- }
- } else {
- linePitch = scanLineWidth(virtX, virtY, minPitch,
- apertureSize, BankFormat, pitchInc);
- }
- }
- }
-
- /* Update the ScrnInfoRec parameters */
-
- scrp->virtualX = virtX;
- scrp->virtualY = virtY;
- scrp->displayWidth = linePitch;
-
- if (numModes <= 0)
- return 0;
-
- /* Make the mode list into a circular list by joining up the ends */
- p = scrp->modes;
- while (p->next != NULL)
- p = p->next;
- /* p is now the last mode on the list */
- p->next = scrp->modes;
- scrp->modes->prev = p;
-
- if (minHeight > 0 && virtY < minHeight) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual height (%d) is too small for the hardware "
- "(min %d)\n", virtY, minHeight);
- return -1;
- }
-
- return numModes;
-}
-
-/*
- * xf86DeleteMode
- *
- * This function removes a mode from a list of modes.
- *
- * There are different types of mode lists:
- *
- * - singly linked linear lists, ending in NULL
- * - doubly linked linear lists, starting and ending in NULL
- * - doubly linked circular lists
- *
- */
-
-void
-xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)
-{
- /* Catch the easy/insane cases */
- if (modeList == NULL || *modeList == NULL || mode == NULL)
- return;
-
- /* If the mode is at the start of the list, move the start of the list */
- if (*modeList == mode)
- *modeList = mode->next;
-
- /* If mode is the only one on the list, set the list to NULL */
- if ((mode == mode->prev) && (mode == mode->next)) {
- *modeList = NULL;
- } else {
- if ((mode->prev != NULL) && (mode->prev->next == mode))
- mode->prev->next = mode->next;
- if ((mode->next != NULL) && (mode->next->prev == mode))
- mode->next->prev = mode->prev;
- }
-
- free(mode->name);
- free(mode);
-}
-
-/*
- * xf86PruneDriverModes
- *
- * Remove modes from the driver's mode list which have been marked as
- * invalid.
- */
-
-void
-xf86PruneDriverModes(ScrnInfoPtr scrp)
-{
- DisplayModePtr first, p, n;
-
- p = scrp->modes;
- if (p == NULL)
- return;
-
- do {
- if (!(first = scrp->modes))
- return;
- n = p->next;
- if (p->status != MODE_OK) {
- xf86DeleteMode(&(scrp->modes), p);
- }
- p = n;
- } while (p != NULL && p != first);
-
- /* modePool is no longer needed, turf it */
- while (scrp->modePool) {
- /*
- * A modePool mode's prev field is used to hold a pointer to the
- * member of the scrp->modes list for which a match was considered.
- * Clear that pointer first, otherwise xf86DeleteMode might get
- * confused
- */
- scrp->modePool->prev = NULL;
- xf86DeleteMode(&scrp->modePool, scrp->modePool);
- }
-}
-
-
-/*
- * xf86SetCrtcForModes
- *
- * Goes through the screen's mode list, and initialises the Crtc
- * parameters for each mode. The initialisation includes adjustments
- * for interlaced and double scan modes.
- */
-void
-xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)
-{
- DisplayModePtr p;
-
- /*
- * Store adjustFlags for use with the VidMode extension. There is an
- * implicit assumption here that SetCrtcForModes is called once.
- */
- scrp->adjustFlags = adjustFlags;
-
- p = scrp->modes;
- if (p == NULL)
- return;
-
- do {
- xf86SetModeCrtc(p, adjustFlags);
- DebugF("%sMode %s: %d (%d) %d %d (%d) %d %d (%d) %d %d (%d) %d\n",
- (p->type & M_T_DEFAULT) ? "Default " : "",
- p->name, p->CrtcHDisplay, p->CrtcHBlankStart,
- p->CrtcHSyncStart, p->CrtcHSyncEnd, p->CrtcHBlankEnd,
- p->CrtcHTotal, p->CrtcVDisplay, p->CrtcVBlankStart,
- p->CrtcVSyncStart, p->CrtcVSyncEnd, p->CrtcVBlankEnd,
- p->CrtcVTotal);
- p = p->next;
- } while (p != NULL && p != scrp->modes);
-}
-
-void
-xf86PrintModes(ScrnInfoPtr scrp)
-{
- DisplayModePtr p;
- float hsync, refresh = 0;
- char *desc, *desc2, *prefix, *uprefix;
-
- if (scrp == NULL)
- return;
-
- xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d "
- "(pitch %d)\n", scrp->virtualX, scrp->virtualY,
- scrp->displayWidth);
-
- p = scrp->modes;
- if (p == NULL)
- return;
-
- do {
- desc = desc2 = "";
- hsync = xf86ModeHSync(p);
- refresh = xf86ModeVRefresh(p);
- if (p->Flags & V_INTERLACE) {
- desc = " (I)";
- }
- if (p->Flags & V_DBLSCAN) {
- desc = " (D)";
- }
- if (p->VScan > 1) {
- desc2 = " (VScan)";
- }
- if (p->type & M_T_BUILTIN)
- prefix = "Built-in mode";
- else if (p->type & M_T_DEFAULT)
- prefix = "Default mode";
- else if (p->type & M_T_DRIVER)
- prefix = "Driver mode";
- else
- prefix = "Mode";
- if (p->type & M_T_USERDEF)
- uprefix = "*";
- else
- uprefix = " ";
- if (hsync == 0 || refresh == 0) {
- if (p->name)
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
- "%s%s \"%s\"\n", uprefix, prefix, p->name);
- else
- xf86DrvMsg(scrp->scrnIndex, X_PROBED,
- "%s%s %dx%d (unnamed)\n",
- uprefix, prefix, p->HDisplay, p->VDisplay);
- } else if (p->Clock == p->SynthClock) {
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
- "%s%s \"%s\": %.1f MHz, %.1f kHz, %.1f Hz%s%s\n",
- uprefix, prefix, p->name, p->Clock / 1000.0,
- hsync, refresh, desc, desc2);
- } else {
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
- "%s%s \"%s\": %.1f MHz (scaled from %.1f MHz), "
- "%.1f kHz, %.1f Hz%s%s\n",
- uprefix, prefix, p->name, p->Clock / 1000.0,
- p->SynthClock / 1000.0, hsync, refresh, desc, desc2);
- }
- if (hsync != 0 && refresh != 0)
- xf86PrintModeline(scrp->scrnIndex,p);
- p = p->next;
- } while (p != NULL && p != scrp->modes);
-}
+/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +/* + * LCM() and scanLineWidth() are: + * + * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * + * 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 Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE 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. + * + * Copyright 1990,91,92,93 by Thomas Roell, Germany. + * Copyright 1991,92,93 by SGCS (Snitily Graphics Consulting Services), USA. + * + * 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 Thomas Roell nor + * SGCS be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Thomas Roell nor SGCS makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + * THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS 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. + */ + +/* + * Authors: Dirk Hohndel <hohndel@XFree86.Org> + * David Dawes <dawes@XFree86.Org> + * Marc La France <tsi@XFree86.Org> + * ... and others + * + * This file includes helper functions for mode related things. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include "xf86Modes.h" +#include "os.h" +#include "servermd.h" +#include "globals.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "edid.h" + +static void +printModeRejectMessage(int index, DisplayModePtr p, int status) +{ + const char *type; + + if (p->type & M_T_BUILTIN) + type = "built-in "; + else if (p->type & M_T_DEFAULT) + type = "default "; + else if (p->type & M_T_DRIVER) + type = "driver "; + else + type = ""; + + xf86DrvMsg(index, X_INFO, "Not using %smode \"%s\" (%s)\n", type, p->name, + xf86ModeStatusToString(status)); +} + +/* + * xf86GetNearestClock -- + * Find closest clock to given frequency (in kHz). This assumes the + * number of clocks is greater than zero. + */ +int +xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2, + int DivFactor, int MulFactor, int *divider) +{ + int nearestClock = 0, nearestDiv = 1; + int minimumGap = abs(freq - scrp->clock[0]); + int i, j, k, gap; + + if (allowDiv2) + k = 2; + else + k = 1; + + /* Must set this here in case the best match is scrp->clock[0] */ + if (divider != NULL) + *divider = 0; + + for (i = 0; i < scrp->numClocks; i++) { + for (j = 1; j <= k; j++) { + gap = abs((freq * j) - ((scrp->clock[i] * DivFactor) / MulFactor)); + if ((gap < minimumGap) || + ((gap == minimumGap) && (j < nearestDiv))) { + minimumGap = gap; + nearestClock = i; + nearestDiv = j; + if (divider != NULL) + *divider = (j - 1) * V_CLKDIV2; + } + } + } + return nearestClock; +} + +/* + * xf86ModeStatusToString + * + * Convert a ModeStatus value to a printable message + */ + +const char * +xf86ModeStatusToString(ModeStatus status) +{ + switch (status) { + case MODE_OK: + return "Mode OK"; + case MODE_HSYNC: + return "hsync out of range"; + case MODE_VSYNC: + return "vrefresh out of range"; + case MODE_H_ILLEGAL: + return "illegal horizontal timings"; + case MODE_V_ILLEGAL: + return "illegal vertical timings"; + case MODE_BAD_WIDTH: + return "width requires unsupported line pitch"; + case MODE_NOMODE: + return "no mode of this name"; + case MODE_NO_INTERLACE: + return "interlace mode not supported"; + case MODE_NO_DBLESCAN: + return "doublescan mode not supported"; + case MODE_NO_VSCAN: + return "multiscan mode not supported"; + case MODE_MEM: + return "insufficient memory for mode"; + case MODE_VIRTUAL_X: + return "width too large for virtual size"; + case MODE_VIRTUAL_Y: + return "height too large for virtual size"; + case MODE_MEM_VIRT: + return "insufficient memory given virtual size"; + case MODE_NOCLOCK: + return "no clock available for mode"; + case MODE_CLOCK_HIGH: + return "mode clock too high"; + case MODE_CLOCK_LOW: + return "mode clock too low"; + case MODE_CLOCK_RANGE: + return "bad mode clock/interlace/doublescan"; + case MODE_BAD_HVALUE: + return "horizontal timing out of range"; + case MODE_BAD_VVALUE: + return "vertical timing out of range"; + case MODE_BAD_VSCAN: + return "VScan value out of range"; + case MODE_HSYNC_NARROW: + return "horizontal sync too narrow"; + case MODE_HSYNC_WIDE: + return "horizontal sync too wide"; + case MODE_HBLANK_NARROW: + return "horizontal blanking too narrow"; + case MODE_HBLANK_WIDE: + return "horizontal blanking too wide"; + case MODE_VSYNC_NARROW: + return "vertical sync too narrow"; + case MODE_VSYNC_WIDE: + return "vertical sync too wide"; + case MODE_VBLANK_NARROW: + return "vertical blanking too narrow"; + case MODE_VBLANK_WIDE: + return "vertical blanking too wide"; + case MODE_PANEL: + return "exceeds panel dimensions"; + case MODE_INTERLACE_WIDTH: + return "width too large for interlaced mode"; + case MODE_ONE_WIDTH: + return "all modes must have the same width"; + case MODE_ONE_HEIGHT: + return "all modes must have the same height"; + case MODE_ONE_SIZE: + return "all modes must have the same resolution"; + case MODE_NO_REDUCED: + return "monitor doesn't support reduced blanking"; + case MODE_BANDWIDTH: + return "mode requires too much memory bandwidth"; + case MODE_BAD: + return "unknown reason"; + case MODE_ERROR: + return "internal error"; + default: + return "unknown"; + } +} + +/* + * xf86ShowClockRanges() -- Print the clock ranges allowed + * and the clock values scaled by ClockMulFactor and ClockDivFactor + */ +void +xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges) +{ + ClockRangePtr cp; + int MulFactor = 1; + int DivFactor = 1; + int i, j; + int scaledClock; + + for (cp = clockRanges; cp != NULL; cp = cp->next) { + DivFactor = max(1, cp->ClockDivFactor); + MulFactor = max(1, cp->ClockMulFactor); + if (scrp->progClock) { + if (cp->minClock) { + if (cp->maxClock) { + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "Clock range: %6.2f to %6.2f MHz\n", + (double)cp->minClock / 1000.0, + (double)cp->maxClock / 1000.0); + } else { + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "Minimum clock: %6.2f MHz\n", + (double)cp->minClock / 1000.0); + } + } else { + if (cp->maxClock) { + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "Maximum clock: %6.2f MHz\n", + (double)cp->maxClock / 1000.0); + } + } + } else if (DivFactor > 1 || MulFactor > 1) { + j = 0; + for (i = 0; i < scrp->numClocks; i++) { + scaledClock = (scrp->clock[i] * DivFactor) / MulFactor; + if (scaledClock >= cp->minClock && scaledClock <= cp->maxClock) { + if ((j % 8) == 0) { + if (j > 0) + xf86ErrorF("\n"); + xf86DrvMsg(scrp->scrnIndex, X_INFO, "scaled clocks:"); + } + xf86ErrorF(" %6.2f", (double)scaledClock / 1000.0); + j++; + } + } + xf86ErrorF("\n"); + } + } +} + +static Bool +modeInClockRange(ClockRangePtr cp, DisplayModePtr p) +{ + return ((p->Clock >= cp->minClock) && + (p->Clock <= cp->maxClock) && + (cp->interlaceAllowed || !(p->Flags & V_INTERLACE)) && + (cp->doubleScanAllowed || + ((p->VScan <= 1) && !(p->Flags & V_DBLSCAN)))); +} + +/* + * xf86FindClockRangeForMode() [... like the name says ...] + */ +static ClockRangePtr +xf86FindClockRangeForMode(ClockRangePtr clockRanges, DisplayModePtr p) +{ + ClockRangePtr cp; + + for (cp = clockRanges; ; cp = cp->next) + if (!cp || modeInClockRange(cp, p)) + return cp; +} + + +/* + * xf86HandleBuiltinMode() - handles built-in modes + */ +static ModeStatus +xf86HandleBuiltinMode(ScrnInfoPtr scrp, + DisplayModePtr p, + DisplayModePtr modep, + ClockRangePtr clockRanges, + Bool allowDiv2) +{ + ClockRangePtr cp; + int extraFlags = 0; + int MulFactor = 1; + int DivFactor = 1; + int clockIndex; + + /* Reject previously rejected modes */ + if (p->status != MODE_OK) + return p->status; + + /* Reject previously considered modes */ + if (p->prev) + return MODE_NOMODE; + + if ((p->type & M_T_CLOCK_C) == M_T_CLOCK_C) { + /* Check clock is in range */ + cp = xf86FindClockRangeForMode(clockRanges, p); + if (cp == NULL){ + modep->type = p->type; + p->status = MODE_CLOCK_RANGE; + return MODE_CLOCK_RANGE; + } + DivFactor = cp->ClockDivFactor; + MulFactor = cp->ClockMulFactor; + if (!scrp->progClock) { + clockIndex = xf86GetNearestClock(scrp, p->Clock, allowDiv2, + cp->ClockDivFactor, + cp->ClockMulFactor, &extraFlags); + modep->Clock = (scrp->clock[clockIndex] * DivFactor) + / MulFactor; + modep->ClockIndex = clockIndex; + modep->SynthClock = scrp->clock[clockIndex]; + if (extraFlags & V_CLKDIV2) { + modep->Clock /= 2; + modep->SynthClock /= 2; + } + } else { + modep->Clock = p->Clock; + modep->ClockIndex = -1; + modep->SynthClock = (modep->Clock * MulFactor) + / DivFactor; + } + modep->PrivFlags = cp->PrivFlags; + } else { + if(!scrp->progClock) { + modep->Clock = p->Clock; + modep->ClockIndex = p->ClockIndex; + modep->SynthClock = p->SynthClock; + } else { + modep->Clock = p->Clock; + modep->ClockIndex = -1; + modep->SynthClock = p->SynthClock; + } + modep->PrivFlags = p->PrivFlags; + } + modep->type = p->type; + modep->HDisplay = p->HDisplay; + modep->HSyncStart = p->HSyncStart; + modep->HSyncEnd = p->HSyncEnd; + modep->HTotal = p->HTotal; + modep->HSkew = p->HSkew; + modep->VDisplay = p->VDisplay; + modep->VSyncStart = p->VSyncStart; + modep->VSyncEnd = p->VSyncEnd; + modep->VTotal = p->VTotal; + modep->VScan = p->VScan; + modep->Flags = p->Flags | extraFlags; + modep->CrtcHDisplay = p->CrtcHDisplay; + modep->CrtcHBlankStart = p->CrtcHBlankStart; + modep->CrtcHSyncStart = p->CrtcHSyncStart; + modep->CrtcHSyncEnd = p->CrtcHSyncEnd; + modep->CrtcHBlankEnd = p->CrtcHBlankEnd; + modep->CrtcHTotal = p->CrtcHTotal; + modep->CrtcHSkew = p->CrtcHSkew; + modep->CrtcVDisplay = p->CrtcVDisplay; + modep->CrtcVBlankStart = p->CrtcVBlankStart; + modep->CrtcVSyncStart = p->CrtcVSyncStart; + modep->CrtcVSyncEnd = p->CrtcVSyncEnd; + modep->CrtcVBlankEnd = p->CrtcVBlankEnd; + modep->CrtcVTotal = p->CrtcVTotal; + modep->CrtcHAdjusted = p->CrtcHAdjusted; + modep->CrtcVAdjusted = p->CrtcVAdjusted; + modep->HSync = p->HSync; + modep->VRefresh = p->VRefresh; + modep->Private = p->Private; + modep->PrivSize = p->PrivSize; + + p->prev = modep; + + return MODE_OK; +} + +/* + * xf86LookupMode + * + * This function returns a mode from the given list which matches the + * given name. When multiple modes with the same name are available, + * the method of picking the matching mode is determined by the + * strategy selected. + * + * This function takes the following parameters: + * scrp ScrnInfoPtr + * modep pointer to the returned mode, which must have the name + * field filled in. + * clockRanges a list of clock ranges. This is optional when all the + * modes are built-in modes. + * strategy how to decide which mode to use from multiple modes with + * the same name + * + * In addition, the following fields from the ScrnInfoRec are used: + * modePool the list of monitor modes compatible with the driver + * clocks a list of discrete clocks + * numClocks number of discrete clocks + * progClock clock is programmable + * + * If a mode was found, its values are filled in to the area pointed to + * by modep, If a mode was not found the return value indicates the + * reason. + */ + +ModeStatus +xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep, + ClockRangePtr clockRanges, LookupModeFlags strategy) +{ + DisplayModePtr p, bestMode = NULL; + ClockRangePtr cp; + int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1; + double refresh, bestRefresh = 0.0; + Bool found = FALSE; + int extraFlags = 0; + int clockIndex = -1; + int MulFactor = 1; + int DivFactor = 1; + int ModePrivFlags = 0; + ModeStatus status = MODE_NOMODE; + Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0; + int n; + const int types[] = { + M_T_BUILTIN | M_T_PREFERRED, + M_T_BUILTIN, + M_T_USERDEF | M_T_PREFERRED, + M_T_USERDEF, + M_T_DRIVER | M_T_PREFERRED, + M_T_DRIVER, + 0 + }; + const int ntypes = sizeof(types) / sizeof(int); + + strategy &= ~(LOOKUP_CLKDIV2 | LOOKUP_OPTIONAL_TOLERANCES); + + /* Some sanity checking */ + if (scrp == NULL || scrp->modePool == NULL || + (!scrp->progClock && scrp->numClocks == 0)) { + ErrorF("xf86LookupMode: called with invalid scrnInfoRec\n"); + return MODE_ERROR; + } + if (modep == NULL || modep->name == NULL) { + ErrorF("xf86LookupMode: called with invalid modep\n"); + return MODE_ERROR; + } + for (cp = clockRanges; cp != NULL; cp = cp->next) { + /* DivFactor and MulFactor must be > 0 */ + cp->ClockDivFactor = max(1, cp->ClockDivFactor); + cp->ClockMulFactor = max(1, cp->ClockMulFactor); + } + + /* Scan the mode pool for matching names */ + for (n = 0; n < ntypes; n++) { + int type = types[n]; + for (p = scrp->modePool; p != NULL; p = p->next) { + + /* scan through the modes in the sort order above */ + if ((p->type & type) != type) + continue; + + if (strcmp(p->name, modep->name) == 0) { + + /* Skip over previously rejected modes */ + if (p->status != MODE_OK) { + if (!found) + status = p->status; + continue; + } + + /* Skip over previously considered modes */ + if (p->prev) + continue; + + if (p->type & M_T_BUILTIN) { + return xf86HandleBuiltinMode(scrp, p,modep, clockRanges, + allowDiv2); + } + + /* Check clock is in range */ + cp = xf86FindClockRangeForMode(clockRanges, p); + if (cp == NULL) { + /* + * XXX Could do more here to provide a more detailed + * reason for not finding a mode. + */ + p->status = MODE_CLOCK_RANGE; + if (!found) + status = MODE_CLOCK_RANGE; + continue; + } + + /* + * If programmable clock and strategy is not + * LOOKUP_BEST_REFRESH, the required mode has been found, + * otherwise record the refresh and continue looking. + */ + if (scrp->progClock) { + found = TRUE; + if (strategy != LOOKUP_BEST_REFRESH) { + bestMode = p; + DivFactor = cp->ClockDivFactor; + MulFactor = cp->ClockMulFactor; + ModePrivFlags = cp->PrivFlags; + break; + } + refresh = xf86ModeVRefresh(p); + if (p->Flags & V_INTERLACE) + refresh /= INTERLACE_REFRESH_WEIGHT; + if (refresh > bestRefresh) { + bestMode = p; + DivFactor = cp->ClockDivFactor; + MulFactor = cp->ClockMulFactor; + ModePrivFlags = cp->PrivFlags; + bestRefresh = refresh; + } + continue; + } + + /* + * Clock is in range, so if it is not a programmable clock, find + * a matching clock. + */ + + i = xf86GetNearestClock(scrp, p->Clock, allowDiv2, + cp->ClockDivFactor, cp->ClockMulFactor, &k); + /* + * If the clock is too far from the requested clock, this + * mode is no good. + */ + if (k & V_CLKDIV2) + gap = abs((p->Clock * 2) - + ((scrp->clock[i] * cp->ClockDivFactor) / + cp->ClockMulFactor)); + else + gap = abs(p->Clock - + ((scrp->clock[i] * cp->ClockDivFactor) / + cp->ClockMulFactor)); + if (gap > minimumGap) { + p->status = MODE_NOCLOCK; + if (!found) + status = MODE_NOCLOCK; + continue; + } + found = TRUE; + + if (strategy == LOOKUP_BEST_REFRESH) { + refresh = xf86ModeVRefresh(p); + if (p->Flags & V_INTERLACE) + refresh /= INTERLACE_REFRESH_WEIGHT; + if (refresh > bestRefresh) { + bestMode = p; + DivFactor = cp->ClockDivFactor; + MulFactor = cp->ClockMulFactor; + ModePrivFlags = cp->PrivFlags; + extraFlags = k; + clockIndex = i; + bestRefresh = refresh; + } + continue; + } + if (strategy == LOOKUP_CLOSEST_CLOCK) { + if (gap < minimumGap) { + bestMode = p; + DivFactor = cp->ClockDivFactor; + MulFactor = cp->ClockMulFactor; + ModePrivFlags = cp->PrivFlags; + extraFlags = k; + clockIndex = i; + minimumGap = gap; + } + continue; + } + /* + * If strategy is neither LOOKUP_BEST_REFRESH or + * LOOKUP_CLOSEST_CLOCK the required mode has been found. + */ + bestMode = p; + DivFactor = cp->ClockDivFactor; + MulFactor = cp->ClockMulFactor; + ModePrivFlags = cp->PrivFlags; + extraFlags = k; + clockIndex = i; + break; + } + } + if (found) break; + } + if (!found || bestMode == NULL) + return status; + + /* Fill in the mode parameters */ + if (scrp->progClock) { + modep->Clock = bestMode->Clock; + modep->ClockIndex = -1; + modep->SynthClock = (modep->Clock * MulFactor) / DivFactor; + } else { + modep->Clock = (scrp->clock[clockIndex] * DivFactor) / + MulFactor; + modep->ClockIndex = clockIndex; + modep->SynthClock = scrp->clock[clockIndex]; + if (extraFlags & V_CLKDIV2) { + modep->Clock /= 2; + modep->SynthClock /= 2; + } + } + modep->type = bestMode->type; + modep->PrivFlags = ModePrivFlags; + modep->HDisplay = bestMode->HDisplay; + modep->HSyncStart = bestMode->HSyncStart; + modep->HSyncEnd = bestMode->HSyncEnd; + modep->HTotal = bestMode->HTotal; + modep->HSkew = bestMode->HSkew; + modep->VDisplay = bestMode->VDisplay; + modep->VSyncStart = bestMode->VSyncStart; + modep->VSyncEnd = bestMode->VSyncEnd; + modep->VTotal = bestMode->VTotal; + modep->VScan = bestMode->VScan; + modep->Flags = bestMode->Flags | extraFlags; + modep->CrtcHDisplay = bestMode->CrtcHDisplay; + modep->CrtcHBlankStart = bestMode->CrtcHBlankStart; + modep->CrtcHSyncStart = bestMode->CrtcHSyncStart; + modep->CrtcHSyncEnd = bestMode->CrtcHSyncEnd; + modep->CrtcHBlankEnd = bestMode->CrtcHBlankEnd; + modep->CrtcHTotal = bestMode->CrtcHTotal; + modep->CrtcHSkew = bestMode->CrtcHSkew; + modep->CrtcVDisplay = bestMode->CrtcVDisplay; + modep->CrtcVBlankStart = bestMode->CrtcVBlankStart; + modep->CrtcVSyncStart = bestMode->CrtcVSyncStart; + modep->CrtcVSyncEnd = bestMode->CrtcVSyncEnd; + modep->CrtcVBlankEnd = bestMode->CrtcVBlankEnd; + modep->CrtcVTotal = bestMode->CrtcVTotal; + modep->CrtcHAdjusted = bestMode->CrtcHAdjusted; + modep->CrtcVAdjusted = bestMode->CrtcVAdjusted; + modep->HSync = bestMode->HSync; + modep->VRefresh = bestMode->VRefresh; + modep->Private = bestMode->Private; + modep->PrivSize = bestMode->PrivSize; + + bestMode->prev = modep; + + return MODE_OK; +} + +/* + * xf86CheckModeForMonitor + * + * This function takes a mode and monitor description, and determines + * if the mode is valid for the monitor. + */ +ModeStatus +xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor) +{ + int i; + + /* Sanity checks */ + if (mode == NULL || monitor == NULL) { + ErrorF("xf86CheckModeForMonitor: called with invalid parameters\n"); + return MODE_ERROR; + } + + DebugF("xf86CheckModeForMonitor(%p %s, %p %s)\n", + mode, mode->name, monitor, monitor->id); + + /* Some basic mode validity checks */ + if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart || + mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal) + return MODE_H_ILLEGAL; + + if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart || + mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal) + return MODE_V_ILLEGAL; + + if (monitor->nHsync > 0) { + /* Check hsync against the allowed ranges */ + float hsync = xf86ModeHSync(mode); + for (i = 0; i < monitor->nHsync; i++) + if ((hsync > monitor->hsync[i].lo * (1.0 - SYNC_TOLERANCE)) && + (hsync < monitor->hsync[i].hi * (1.0 + SYNC_TOLERANCE))) + break; + + /* Now see whether we ran out of sync ranges without finding a match */ + if (i == monitor->nHsync) + return MODE_HSYNC; + } + + if (monitor->nVrefresh > 0) { + /* Check vrefresh against the allowed ranges */ + float vrefrsh = xf86ModeVRefresh(mode); + for (i = 0; i < monitor->nVrefresh; i++) + if ((vrefrsh > monitor->vrefresh[i].lo * (1.0 - SYNC_TOLERANCE)) && + (vrefrsh < monitor->vrefresh[i].hi * (1.0 + SYNC_TOLERANCE))) + break; + + /* Now see whether we ran out of refresh ranges without finding a match */ + if (i == monitor->nVrefresh) + return MODE_VSYNC; + } + + /* Force interlaced modes to have an odd VTotal */ + if (mode->Flags & V_INTERLACE) + mode->CrtcVTotal = mode->VTotal |= 1; + + /* + * This code stops cvt -r modes, and only cvt -r modes, from hitting 15y+ + * old CRTs which might, when there is a lot of solar flare activity and + * when the celestial bodies are unfavourably aligned, implode trying to + * sync to it. It's called "Protecting the user from doing anything stupid". + * -- libv + */ + + if (xf86ModeIsReduced(mode)) { + if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER)) + return MODE_NO_REDUCED; + } + + if ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock)) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + +/* + * xf86CheckModeSize + * + * An internal routine to check if a mode fits in video memory. This tries to + * avoid overflows that would otherwise occur when video memory size is greater + * than 256MB. + */ +static Bool +xf86CheckModeSize(ScrnInfoPtr scrp, int w, int x, int y) +{ + int bpp = scrp->fbFormat.bitsPerPixel, + pad = scrp->fbFormat.scanlinePad; + int lineWidth, lastWidth; + + if (scrp->depth == 4) + pad *= 4; /* 4 planes */ + + /* Sanity check */ + if ((w < 0) || (x < 0) || (y <= 0)) + return FALSE; + + lineWidth = (((w * bpp) + pad - 1) / pad) * pad; + lastWidth = x * bpp; + + /* + * At this point, we need to compare + * + * (lineWidth * (y - 1)) + lastWidth + * + * against + * + * scrp->videoRam * (1024 * 8) + * + * These are bit quantities. To avoid overflows, do the comparison in + * terms of BITMAP_SCANLINE_PAD units. This assumes BITMAP_SCANLINE_PAD + * is a power of 2. We currently use 32, which limits us to a video + * memory size of 8GB. + */ + + lineWidth = (lineWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD; + lastWidth = (lastWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD; + + if ((lineWidth * (y - 1) + lastWidth) > + (scrp->videoRam * ((1024 * 8) / BITMAP_SCANLINE_PAD))) + return FALSE; + + return TRUE; +} + +/* + * xf86InitialCheckModeForDriver + * + * This function checks if a mode satisfies a driver's initial requirements: + * - mode size fits within the available pixel area (memory) + * - width lies within the range of supported line pitches + * - mode size fits within virtual size (if fixed) + * - horizontal timings are in range + * + * This function takes the following parameters: + * scrp ScrnInfoPtr + * mode mode to check + * maxPitch (optional) maximum line pitch + * virtualX (optional) virtual width requested + * virtualY (optional) virtual height requested + * + * In addition, the following fields from the ScrnInfoRec are used: + * monitor pointer to structure for monitor section + * fbFormat pixel format for the framebuffer + * videoRam video memory size (in kB) + * maxHValue maximum horizontal timing value + * maxVValue maximum vertical timing value + */ + +ModeStatus +xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, + ClockRangePtr clockRanges, + LookupModeFlags strategy, + int maxPitch, int virtualX, int virtualY) +{ + ClockRangePtr cp; + ModeStatus status; + Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0; + int i, needDiv2; + + /* Sanity checks */ + if (!scrp || !mode || !clockRanges) { + ErrorF("xf86InitialCheckModeForDriver: " + "called with invalid parameters\n"); + return MODE_ERROR; + } + + DebugF("xf86InitialCheckModeForDriver(%p, %p %s, %p, 0x%x, %d, %d, %d)\n", + scrp, mode, mode->name , clockRanges, strategy, maxPitch, virtualX, virtualY); + + /* Some basic mode validity checks */ + if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart || + mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal) + return MODE_H_ILLEGAL; + + if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart || + mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal) + return MODE_V_ILLEGAL; + + if (!xf86CheckModeSize(scrp, mode->HDisplay, mode->HDisplay, + mode->VDisplay)) + return MODE_MEM; + + if (maxPitch > 0 && mode->HDisplay > maxPitch) + return MODE_BAD_WIDTH; + + if (virtualX > 0 && mode->HDisplay > virtualX) + return MODE_VIRTUAL_X; + + if (virtualY > 0 && mode->VDisplay > virtualY) + return MODE_VIRTUAL_Y; + + if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue) + return MODE_BAD_HVALUE; + + if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue) + return MODE_BAD_VVALUE; + + /* + * The use of the DisplayModeRec's Crtc* and SynthClock elements below is + * provisional, in that they are later reused by the driver at mode-set + * time. Here, they are temporarily enlisted to contain the mode timings + * as seen by the CRT or panel (rather than the CRTC). The driver's + * ValidMode() is allowed to modify these so it can deal with such things + * as mode stretching and/or centering. The driver should >NOT< modify the + * user-supplied values as these are reported back when mode validation is + * said and done. + */ + /* + * NOTE: We (ab)use the mode->Crtc* values here to store timing + * information for the calculation of Hsync and Vrefresh. Before + * these values are calculated the driver is given the opportunity + * to either set these HSync and VRefresh itself or modify the timing + * values. + * The difference to the final calculation is small but imortand: + * here we pass the flag INTERLACE_HALVE_V regardless if the driver + * sets it or not. This way our calculation of VRefresh has the same + * effect as if we do if (flags & V_INTERLACE) refresh *= 2.0 + * This dual use of the mode->Crtc* values will certainly create + * confusion and is bad software design. However since it's part of + * the driver API it's hard to change. + */ + + if (scrp->ValidMode) { + + xf86SetModeCrtc(mode, INTERLACE_HALVE_V); + + cp = xf86FindClockRangeForMode(clockRanges, mode); + if (!cp) + return MODE_CLOCK_RANGE; + + if (cp->ClockMulFactor < 1) + cp->ClockMulFactor = 1; + if (cp->ClockDivFactor < 1) + cp->ClockDivFactor = 1; + + /* + * XXX The effect of clock dividers and multipliers on the monitor's + * pixel clock needs to be verified. + */ + if (scrp->progClock) { + mode->SynthClock = mode->Clock; + } else { + i = xf86GetNearestClock(scrp, mode->Clock, allowDiv2, + cp->ClockDivFactor, cp->ClockMulFactor, + &needDiv2); + mode->SynthClock = (scrp->clock[i] * cp->ClockDivFactor) / + cp->ClockMulFactor; + if (needDiv2 & V_CLKDIV2) + mode->SynthClock /= 2; + } + + status = (*scrp->ValidMode)(scrp->scrnIndex, mode, FALSE, + MODECHECK_INITIAL); + if (status != MODE_OK) + return status; + + if (mode->HSync <= 0.0) + mode->HSync = (float)mode->SynthClock / (float)mode->CrtcHTotal; + if (mode->VRefresh <= 0.0) + mode->VRefresh = (mode->SynthClock * 1000.0) + / (mode->CrtcHTotal * mode->CrtcVTotal); + } + + mode->HSync = xf86ModeHSync(mode); + mode->VRefresh = xf86ModeVRefresh(mode); + + /* Assume it is OK */ + return MODE_OK; +} + +/* + * xf86CheckModeForDriver + * + * This function is for checking modes while the server is running (for + * use mainly by the VidMode extension). + * + * This function checks if a mode satisfies a driver's requirements: + * - width lies within the line pitch + * - mode size fits within virtual size + * - horizontal/vertical timings are in range + * + * This function takes the following parameters: + * scrp ScrnInfoPtr + * mode mode to check + * flags not (currently) used + * + * In addition, the following fields from the ScrnInfoRec are used: + * maxHValue maximum horizontal timing value + * maxVValue maximum vertical timing value + * virtualX virtual width + * virtualY virtual height + * clockRanges allowable clock ranges + */ + +ModeStatus +xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, int flags) +{ + ClockRangePtr cp; + int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1; + int extraFlags = 0; + int clockIndex = -1; + int MulFactor = 1; + int DivFactor = 1; + int ModePrivFlags = 0; + ModeStatus status = MODE_NOMODE; + + /* Some sanity checking */ + if (scrp == NULL || (!scrp->progClock && scrp->numClocks == 0)) { + ErrorF("xf86CheckModeForDriver: called with invalid scrnInfoRec\n"); + return MODE_ERROR; + } + if (mode == NULL) { + ErrorF("xf86CheckModeForDriver: called with invalid modep\n"); + return MODE_ERROR; + } + + /* Check the mode size */ + if (mode->HDisplay > scrp->virtualX) + return MODE_VIRTUAL_X; + + if (mode->VDisplay > scrp->virtualY) + return MODE_VIRTUAL_Y; + + if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue) + return MODE_BAD_HVALUE; + + if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue) + return MODE_BAD_VVALUE; + + for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) { + /* DivFactor and MulFactor must be > 0 */ + cp->ClockDivFactor = max(1, cp->ClockDivFactor); + cp->ClockMulFactor = max(1, cp->ClockMulFactor); + } + + if (scrp->progClock) { + /* Check clock is in range */ + for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) { + if (modeInClockRange(cp, mode)) + break; + } + if (cp == NULL) { + return MODE_CLOCK_RANGE; + } + /* + * If programmable clock the required mode has been found + */ + DivFactor = cp->ClockDivFactor; + MulFactor = cp->ClockMulFactor; + ModePrivFlags = cp->PrivFlags; + } else { + status = MODE_CLOCK_RANGE; + /* Check clock is in range */ + for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) { + if (modeInClockRange(cp, mode)) { + /* + * Clock is in range, so if it is not a programmable clock, + * find a matching clock. + */ + + i = xf86GetNearestClock(scrp, mode->Clock, 0, + cp->ClockDivFactor, cp->ClockMulFactor, &k); + /* + * If the clock is too far from the requested clock, this + * mode is no good. + */ + if (k & V_CLKDIV2) + gap = abs((mode->Clock * 2) - + ((scrp->clock[i] * cp->ClockDivFactor) / + cp->ClockMulFactor)); + else + gap = abs(mode->Clock - + ((scrp->clock[i] * cp->ClockDivFactor) / + cp->ClockMulFactor)); + if (gap > minimumGap) { + status = MODE_NOCLOCK; + continue; + } + + DivFactor = cp->ClockDivFactor; + MulFactor = cp->ClockMulFactor; + ModePrivFlags = cp->PrivFlags; + extraFlags = k; + clockIndex = i; + break; + } + } + if (cp == NULL) + return status; + } + + /* Fill in the mode parameters */ + if (scrp->progClock) { + mode->ClockIndex = -1; + mode->SynthClock = (mode->Clock * MulFactor) / DivFactor; + } else { + mode->Clock = (scrp->clock[clockIndex] * DivFactor) / MulFactor; + mode->ClockIndex = clockIndex; + mode->SynthClock = scrp->clock[clockIndex]; + if (extraFlags & V_CLKDIV2) { + mode->Clock /= 2; + mode->SynthClock /= 2; + } + } + mode->PrivFlags = ModePrivFlags; + + return MODE_OK; +} + +static int +inferVirtualSize(ScrnInfoPtr scrp, DisplayModePtr modes, int *vx, int *vy) +{ + float aspect = 0.0; + MonPtr mon = scrp->monitor; + xf86MonPtr DDC; + int x = 0, y = 0; + DisplayModePtr mode; + + if (!mon) return 0; + DDC = mon->DDC; + + if (DDC && DDC->ver.revision >= 4) { + /* For 1.4, we might actually get native pixel format. How novel. */ + if (PREFERRED_TIMING_MODE(DDC->features.msc)) { + for (mode = modes; mode; mode = mode->next) { + if (mode->type & (M_T_DRIVER | M_T_PREFERRED)) { + x = mode->HDisplay; + y = mode->VDisplay; + goto found; + } + } + } + /* + * Even if we don't, we might get aspect ratio from extra CVT info + * or from the monitor size fields. TODO. + */ + } + + /* + * Technically this triggers if either is zero. That wasn't legal + * before EDID 1.4, but right now we'll get that wrong. TODO. + */ + if (!aspect) { + if (!mon->widthmm || !mon->heightmm) + aspect = 4.0/3.0; + else + aspect = (float)mon->widthmm / (float)mon->heightmm; + } + + /* find the largest M_T_DRIVER mode with that aspect ratio */ + for (mode = modes; mode; mode = mode->next) { + float mode_aspect, metaspect; + if (!(mode->type & (M_T_DRIVER|M_T_USERDEF))) + continue; + mode_aspect = (float)mode->HDisplay / (float)mode->VDisplay; + metaspect = aspect / mode_aspect; + /* 5% slop or so, since we only get size in centimeters */ + if (fabs(1.0 - metaspect) < 0.05) { + if ((mode->HDisplay > x) && (mode->VDisplay > y)) { + x = mode->HDisplay; + y = mode->VDisplay; + } + } + } + + if (!x || !y) { + xf86DrvMsg(scrp->scrnIndex, X_WARNING, + "Unable to estimate virtual size\n"); + return 0; + } + +found: + *vx = x; + *vy = y; + + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "Estimated virtual size for aspect ratio %.4f is %dx%d\n", + aspect, *vx, *vy); + + return 1; +} + +/* Least common multiple */ +static unsigned int +LCM(unsigned int x, unsigned int y) +{ + unsigned int m = x, n = y, o; + + while ((o = m % n)) + { + m = n; + n = o; + } + + return (x / n) * y; +} + +/* + * Given various screen attributes, determine the minimum scanline width such + * that each scanline is server and DDX padded and any pixels with imbedded + * bank boundaries are off-screen. This function returns -1 if such a width + * cannot exist. + */ +static int +scanLineWidth( + unsigned int xsize, /* pixels */ + unsigned int ysize, /* pixels */ + unsigned int width, /* pixels */ + unsigned long BankSize, /* char's */ + PixmapFormatRec *pBankFormat, + unsigned int nWidthUnit /* bits */ +) +{ + unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit; + unsigned long minBitsPerScanline, maxBitsPerScanline; + + /* Sanity checks */ + + if (!nWidthUnit || !pBankFormat) + return -1; + + nBitsPerBank = BankSize * 8; + if (nBitsPerBank % pBankFormat->scanlinePad) + return -1; + + if (xsize > width) + width = xsize; + nBitsPerScanlinePadUnit = LCM(pBankFormat->scanlinePad, nWidthUnit); + nBitsPerScanline = + (((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) / + nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit; + width = nBitsPerScanline / pBankFormat->bitsPerPixel; + + if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel)) + return (int)width; + + /* + * Scanlines will be server-pad aligned at this point. They will also be + * a multiple of nWidthUnit bits long. Ensure that pixels with imbedded + * bank boundaries are off-screen. + * + * It seems reasonable to limit total frame buffer size to 1/16 of the + * theoretical maximum address space size. On a machine with 32-bit + * addresses (to 8-bit quantities) this turns out to be 256MB. Not only + * does this provide a simple limiting condition for the loops below, but + * it also prevents unsigned long wraparounds. + */ + if (!ysize) + return -1; + + minBitsPerScanline = xsize * pBankFormat->bitsPerPixel; + if (minBitsPerScanline > nBitsPerBank) + return -1; + + if (ysize == 1) + return (int)width; + + maxBitsPerScanline = + (((unsigned long)(-1) >> 1) - minBitsPerScanline) / (ysize - 1); + while (nBitsPerScanline <= maxBitsPerScanline) + { + unsigned long BankBase, BankUnit; + + BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) * + nBitsPerBank; + if (!(BankUnit % nBitsPerScanline)) + return (int)width; + + for (BankBase = BankUnit; ; BankBase += nBitsPerBank) + { + unsigned long x, y; + + y = BankBase / nBitsPerScanline; + if (y >= ysize) + return (int)width; + + x = BankBase % nBitsPerScanline; + if (!(x % pBankFormat->bitsPerPixel)) + continue; + + if (x < minBitsPerScanline) + { + /* + * Skip ahead certain widths by dividing the excess scanline + * amongst the y's. + */ + y *= nBitsPerScanlinePadUnit; + nBitsPerScanline += + ((x + y - 1) / y) * nBitsPerScanlinePadUnit; + width = nBitsPerScanline / pBankFormat->bitsPerPixel; + break; + } + + if (BankBase != BankUnit) + continue; + + if (!(nBitsPerScanline % x)) + return (int)width; + + BankBase = ((nBitsPerScanline - minBitsPerScanline) / + (nBitsPerScanline - x)) * BankUnit; + } + } + + return -1; +} + +/* + * xf86ValidateModes + * + * This function takes a set of mode names, modes and limiting conditions, + * and selects a set of modes and parameters based on those conditions. + * + * This function takes the following parameters: + * scrp ScrnInfoPtr + * availModes the list of modes available for the monitor + * modeNames (optional) list of mode names that the screen is requesting + * clockRanges a list of clock ranges + * linePitches (optional) a list of line pitches + * minPitch (optional) minimum line pitch (in pixels) + * maxPitch (optional) maximum line pitch (in pixels) + * pitchInc (mandatory) pitch increment (in bits) + * minHeight (optional) minimum virtual height (in pixels) + * maxHeight (optional) maximum virtual height (in pixels) + * virtualX (optional) virtual width requested (in pixels) + * virtualY (optional) virtual height requested (in pixels) + * apertureSize size of video aperture (in bytes) + * strategy how to decide which mode to use from multiple modes with + * the same name + * + * In addition, the following fields from the ScrnInfoRec are used: + * clocks a list of discrete clocks + * numClocks number of discrete clocks + * progClock clock is programmable + * monitor pointer to structure for monitor section + * fbFormat format of the framebuffer + * videoRam video memory size + * maxHValue maximum horizontal timing value + * maxVValue maximum vertical timing value + * xInc horizontal timing increment (defaults to 8 pixels) + * + * The function fills in the following ScrnInfoRec fields: + * modePool A subset of the modes available to the monitor which + * are compatible with the driver. + * modes one mode entry for each of the requested modes, with the + * status field filled in to indicate if the mode has been + * accepted or not. + * virtualX the resulting virtual width + * virtualY the resulting virtual height + * displayWidth the resulting line pitch + * + * The function's return value is the number of matching modes found, or -1 + * if an unrecoverable error was encountered. + */ + +int +xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, + char **modeNames, ClockRangePtr clockRanges, + int *linePitches, int minPitch, int maxPitch, int pitchInc, + int minHeight, int maxHeight, int virtualX, int virtualY, + int apertureSize, LookupModeFlags strategy) +{ + DisplayModePtr p, q, r, new, last, *endp; + int i, numModes = 0; + ModeStatus status; + int linePitch = -1, virtX = 0, virtY = 0; + int newLinePitch, newVirtX, newVirtY; + int modeSize; /* in pixels */ + Bool validateAllDefaultModes = FALSE; + Bool userModes = FALSE; + int saveType; + PixmapFormatRec *BankFormat; + ClockRangePtr cp; + ClockRangePtr storeClockRanges; + int numTimings = 0; + range hsync[MAX_HSYNC]; + range vrefresh[MAX_VREFRESH]; + Bool inferred_virtual = FALSE; + + DebugF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n", + scrp, availModes, modeNames, clockRanges, + linePitches, minPitch, maxPitch, pitchInc, + minHeight, maxHeight, virtualX, virtualY, + apertureSize, strategy + ); + + /* Some sanity checking */ + if (scrp == NULL || scrp->name == NULL || !scrp->monitor || + (!scrp->progClock && scrp->numClocks == 0)) { + ErrorF("xf86ValidateModes: called with invalid scrnInfoRec\n"); + return -1; + } + if (linePitches != NULL && linePitches[0] <= 0) { + ErrorF("xf86ValidateModes: called with invalid linePitches\n"); + return -1; + } + if (pitchInc <= 0) { + ErrorF("xf86ValidateModes: called with invalid pitchInc\n"); + return -1; + } + if ((virtualX > 0) != (virtualY > 0)) { + ErrorF("xf86ValidateModes: called with invalid virtual resolution\n"); + return -1; + } + + /* + * If requested by the driver, allow missing hsync and/or vrefresh ranges + * in the monitor section. + */ + if (strategy & LOOKUP_OPTIONAL_TOLERANCES) { + strategy &= ~LOOKUP_OPTIONAL_TOLERANCES; + } else { + const char *type = ""; + Bool specified = FALSE; + + if (scrp->monitor->nHsync <= 0) { + if (numTimings > 0) { + scrp->monitor->nHsync = numTimings; + for (i = 0; i < numTimings; i++) { + scrp->monitor->hsync[i].lo = hsync[i].lo; + scrp->monitor->hsync[i].hi = hsync[i].hi; + } + } else { + scrp->monitor->hsync[0].lo = 31.5; + scrp->monitor->hsync[0].hi = 48.0; + scrp->monitor->nHsync = 1; + } + type = "default "; + } else { + specified = TRUE; + } + for (i = 0; i < scrp->monitor->nHsync; i++) { + if (scrp->monitor->hsync[i].lo == scrp->monitor->hsync[i].hi) + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "%s: Using %shsync value of %.2f kHz\n", + scrp->monitor->id, type, + scrp->monitor->hsync[i].lo); + else + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "%s: Using %shsync range of %.2f-%.2f kHz\n", + scrp->monitor->id, type, + scrp->monitor->hsync[i].lo, + scrp->monitor->hsync[i].hi); + } + + type = ""; + if (scrp->monitor->nVrefresh <= 0) { + if (numTimings > 0) { + scrp->monitor->nVrefresh = numTimings; + for (i = 0; i < numTimings; i++) { + scrp->monitor->vrefresh[i].lo = vrefresh[i].lo; + scrp->monitor->vrefresh[i].hi = vrefresh[i].hi; + } + } else { + scrp->monitor->vrefresh[0].lo = 50; + scrp->monitor->vrefresh[0].hi = 70; + scrp->monitor->nVrefresh = 1; + } + type = "default "; + } else { + specified = TRUE; + } + for (i = 0; i < scrp->monitor->nVrefresh; i++) { + if (scrp->monitor->vrefresh[i].lo == scrp->monitor->vrefresh[i].hi) + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "%s: Using %svrefresh value of %.2f Hz\n", + scrp->monitor->id, type, + scrp->monitor->vrefresh[i].lo); + else + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "%s: Using %svrefresh range of %.2f-%.2f Hz\n", + scrp->monitor->id, type, + scrp->monitor->vrefresh[i].lo, + scrp->monitor->vrefresh[i].hi); + } + + type = ""; + if (!scrp->monitor->maxPixClock && !specified) { + type = "default "; + scrp->monitor->maxPixClock = 65000.0; + } + if (scrp->monitor->maxPixClock) { + xf86DrvMsg(scrp->scrnIndex, X_INFO, + "%s: Using %smaximum pixel clock of %.2f MHz\n", + scrp->monitor->id, type, + (float)scrp->monitor->maxPixClock / 1000.0); + } + } + + /* + * Store the clockRanges for later use by the VidMode extension. + */ + storeClockRanges = scrp->clockRanges; + while (storeClockRanges != NULL) { + storeClockRanges = storeClockRanges->next; + } + for (cp = clockRanges; cp != NULL; cp = cp->next, + storeClockRanges = storeClockRanges->next) { + storeClockRanges = xnfalloc(sizeof(ClockRange)); + if (scrp->clockRanges == NULL) + scrp->clockRanges = storeClockRanges; + memcpy(storeClockRanges, cp, sizeof(ClockRange)); + } + + /* Determine which pixmap format to pass to scanLineWidth() */ + if (scrp->depth > 4) + BankFormat = &scrp->fbFormat; + else + BankFormat = xf86GetPixFormat(scrp, 1); /* >not< scrp->depth! */ + + if (scrp->xInc <= 0) + scrp->xInc = 8; /* Suitable for VGA and others */ + +#define _VIRTUALX(x) ((((x) + scrp->xInc - 1) / scrp->xInc) * scrp->xInc) + + /* + * Determine maxPitch if it wasn't given explicitly. Note linePitches + * always takes precedence if is non-NULL. In that case the minPitch and + * maxPitch values passed are ignored. + */ + if (linePitches) { + minPitch = maxPitch = linePitches[0]; + for (i = 1; linePitches[i] > 0; i++) { + if (linePitches[i] > maxPitch) + maxPitch = linePitches[i]; + if (linePitches[i] < minPitch) + minPitch = linePitches[i]; + } + } + + /* Initial check of virtual size against other constraints */ + scrp->virtualFrom = X_PROBED; + /* + * Initialise virtX and virtY if the values are fixed. + */ + if (virtualY > 0) { + if (maxHeight > 0 && virtualY > maxHeight) { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Virtual height (%d) is too large for the hardware " + "(max %d)\n", virtualY, maxHeight); + return -1; + } + + if (minHeight > 0 && virtualY < minHeight) { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Virtual height (%d) is too small for the hardware " + "(min %d)\n", virtualY, minHeight); + return -1; + } + + virtualX = _VIRTUALX(virtualX); + if (linePitches != NULL) { + for (i = 0; linePitches[i] != 0; i++) { + if ((linePitches[i] >= virtualX) && + (linePitches[i] == + scanLineWidth(virtualX, virtualY, linePitches[i], + apertureSize, BankFormat, pitchInc))) { + linePitch = linePitches[i]; + break; + } + } + } else { + linePitch = scanLineWidth(virtualX, virtualY, minPitch, + apertureSize, BankFormat, pitchInc); + } + + if ((linePitch < minPitch) || (linePitch > maxPitch)) { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Virtual width (%d) is too large for the hardware " + "(max %d)\n", virtualX, maxPitch); + return -1; + } + + if (!xf86CheckModeSize(scrp, linePitch, virtualX, virtualY)) { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Virtual size (%dx%d) (pitch %d) exceeds video memory\n", + virtualX, virtualY, linePitch); + return -1; + } + + virtX = virtualX; + virtY = virtualY; + scrp->virtualFrom = X_CONFIG; + } else if (!modeNames || !*modeNames) { + /* No virtual size given in the config, try to infer */ + /* XXX this doesn't take m{in,ax}Pitch into account; oh well */ + inferred_virtual = inferVirtualSize(scrp, availModes, &virtX, &virtY); + if (inferred_virtual) + linePitch = scanLineWidth(virtX, virtY, minPitch, apertureSize, + BankFormat, pitchInc); + } + + /* Print clock ranges and scaled clocks */ + xf86ShowClockRanges(scrp, clockRanges); + + /* + * If scrp->modePool hasn't been setup yet, set it up now. This allows the + * modes that the driver definitely can't use to be weeded out early. Note + * that a modePool mode's prev field is used to hold a pointer to the + * member of the scrp->modes list for which a match was considered. + */ + if (scrp->modePool == NULL) { + q = NULL; + for (p = availModes; p != NULL; p = p->next) { + status = xf86InitialCheckModeForDriver(scrp, p, clockRanges, + strategy, maxPitch, + virtX, virtY); + + if (status == MODE_OK) { + status = xf86CheckModeForMonitor(p, scrp->monitor); + } + + if (status == MODE_OK) { + new = xnfalloc(sizeof(DisplayModeRec)); + *new = *p; + new->next = NULL; + if (!q) { + scrp->modePool = new; + } else { + q->next = new; + } + new->prev = NULL; + q = new; + q->name = xnfstrdup(p->name); + q->status = MODE_OK; + } else { + printModeRejectMessage(scrp->scrnIndex, p, status); + } + } + + if (scrp->modePool == NULL) { + xf86DrvMsg(scrp->scrnIndex, X_WARNING, "Mode pool is empty\n"); + return 0; + } + } else { + for (p = scrp->modePool; p != NULL; p = p->next) { + p->prev = NULL; + p->status = MODE_OK; + } + } + + /* + * Allocate one entry in scrp->modes for each named mode. + */ + while (scrp->modes) + xf86DeleteMode(&scrp->modes, scrp->modes); + endp = &scrp->modes; + last = NULL; + if (modeNames != NULL) { + for (i = 0; modeNames[i] != NULL; i++) { + userModes = TRUE; + new = xnfcalloc(1, sizeof(DisplayModeRec)); + new->prev = last; + new->type = M_T_USERDEF; + new->name = xnfstrdup(modeNames[i]); + if (new->prev) + new->prev->next = new; + *endp = last = new; + endp = &new->next; + } + } + + /* Lookup each mode */ +#ifdef RANDR + if (!xf86Info.disableRandR +#ifdef PANORAMIX + && noPanoramiXExtension +#endif + ) + validateAllDefaultModes = TRUE; +#endif + + for (p = scrp->modes; ; p = p->next) { + Bool repeat; + + /* + * If the supplied mode names don't produce a valid mode, scan through + * unconsidered modePool members until one survives validation. This + * is done in decreasing order by mode pixel area. + */ + + if (p == NULL) { + if ((numModes > 0) && !validateAllDefaultModes) + break; + + validateAllDefaultModes = TRUE; + r = NULL; + modeSize = 0; + for (q = scrp->modePool; q != NULL; q = q->next) { + if ((q->prev == NULL) && (q->status == MODE_OK)) { + /* + * Deal with the case where this mode wasn't considered + * because of a builtin mode of the same name. + */ + for (p = scrp->modes; p != NULL; p = p->next) { + if ((p->status != MODE_OK) && + !strcmp(p->name, q->name)) + break; + } + + if (p != NULL) + q->prev = p; + else { + /* + * A quick check to not allow default modes with + * horizontal timing parameters that CRTs may have + * problems with. + */ + if (!scrp->monitor->reducedblanking && + (q->type & M_T_DEFAULT) && + ((double)q->HTotal / (double)q->HDisplay) < 1.15) + continue; + + if (modeSize < (q->HDisplay * q->VDisplay)) { + r = q; + modeSize = q->HDisplay * q->VDisplay; + } + } + } + } + + if (r == NULL) + break; + + p = xnfcalloc(1, sizeof(DisplayModeRec)); + p->prev = last; + p->name = xnfstrdup(r->name); + if (!userModes) + p->type = M_T_USERDEF; + if (p->prev) + p->prev->next = p; + *endp = last = p; + endp = &p->next; + } + + repeat = FALSE; + lookupNext: + if (repeat && ((status = p->status) != MODE_OK)) + printModeRejectMessage(scrp->scrnIndex, p, status); + saveType = p->type; + status = xf86LookupMode(scrp, p, clockRanges, strategy); + if (repeat && status == MODE_NOMODE) + continue; + if (status != MODE_OK) + printModeRejectMessage(scrp->scrnIndex, p, status); + if (status == MODE_ERROR) { + ErrorF("xf86ValidateModes: " + "unexpected result from xf86LookupMode()\n"); + return -1; + } + if (status != MODE_OK) { + if (p->status == MODE_OK) + p->status = status; + continue; + } + p->type |= saveType; + repeat = TRUE; + + newLinePitch = linePitch; + newVirtX = virtX; + newVirtY = virtY; + + /* + * Don't let non-user defined modes increase the virtual size + */ + if (!(p->type & M_T_USERDEF) && (numModes > 0)) { + if (p->HDisplay > virtX) { + p->status = MODE_VIRTUAL_X; + goto lookupNext; + } + if (p->VDisplay > virtY) { + p->status = MODE_VIRTUAL_Y; + goto lookupNext; + } + } + /* + * Adjust virtual width and height if the mode is too large for the + * current values and if they are not fixed. + */ + if (virtualX <= 0 && p->HDisplay > newVirtX) + newVirtX = _VIRTUALX(p->HDisplay); + if (virtualY <= 0 && p->VDisplay > newVirtY) { + if (maxHeight > 0 && p->VDisplay > maxHeight) { + p->status = MODE_VIRTUAL_Y; /* ? */ + goto lookupNext; + } + newVirtY = p->VDisplay; + } + + /* + * If virtual resolution is to be increased, revalidate it. + */ + if ((virtX != newVirtX) || (virtY != newVirtY)) { + if (linePitches != NULL) { + newLinePitch = -1; + for (i = 0; linePitches[i] != 0; i++) { + if ((linePitches[i] >= newVirtX) && + (linePitches[i] >= linePitch) && + (linePitches[i] == + scanLineWidth(newVirtX, newVirtY, linePitches[i], + apertureSize, BankFormat, pitchInc))) { + newLinePitch = linePitches[i]; + break; + } + } + } else { + if (linePitch < minPitch) + linePitch = minPitch; + newLinePitch = scanLineWidth(newVirtX, newVirtY, linePitch, + apertureSize, BankFormat, + pitchInc); + } + if ((newLinePitch < minPitch) || (newLinePitch > maxPitch)) { + p->status = MODE_BAD_WIDTH; + goto lookupNext; + } + + /* + * Check that the pixel area required by the new virtual height + * and line pitch isn't too large. + */ + if (!xf86CheckModeSize(scrp, newLinePitch, newVirtX, newVirtY)) { + p->status = MODE_MEM_VIRT; + goto lookupNext; + } + } + + if (scrp->ValidMode) { + /* + * Give the driver a final say, passing it the proposed virtual + * geometry. + */ + scrp->virtualX = newVirtX; + scrp->virtualY = newVirtY; + scrp->displayWidth = newLinePitch; + p->status = (scrp->ValidMode)(scrp->scrnIndex, p, FALSE, + MODECHECK_FINAL); + + if (p->status != MODE_OK) { + goto lookupNext; + } + } + + /* Mode has passed all the tests */ + virtX = newVirtX; + virtY = newVirtY; + linePitch = newLinePitch; + p->status = MODE_OK; + numModes++; + } + + /* + * If we estimated the virtual size above, we may have filtered away all + * the modes that maximally match that size; scan again to find out and + * fix up if so. + */ + if (inferred_virtual) { + int vx = 0, vy = 0; + for (p = scrp->modes; p; p = p->next) { + if (p->HDisplay > vx && p->VDisplay > vy) { + vx = p->HDisplay; + vy = p->VDisplay; + } + } + if (vx < virtX || vy < virtY) { + const int types[] = { + M_T_BUILTIN | M_T_PREFERRED, + M_T_BUILTIN, + M_T_DRIVER | M_T_PREFERRED, + M_T_DRIVER, + 0 + }; + const int ntypes = sizeof(types) / sizeof(int); + int n; + + /* + * We did not find the estimated virtual size. So now we want to + * find the largest mode available, but we want to search in the + * modes in the order of "types" listed above. + */ + for (n = 0; n < ntypes; n++) { + int type = types[n]; + + vx = 0; vy = 0; + for (p = scrp->modes; p; p = p->next) { + /* scan through the modes in the sort order above */ + if ((p->type & type) != type) + continue; + if (p->HDisplay > vx && p->VDisplay > vy) { + vx = p->HDisplay; + vy = p->VDisplay; + } + } + if (vx && vy) + /* Found one */ + break; + } + xf86DrvMsg(scrp->scrnIndex, X_WARNING, + "Shrinking virtual size estimate from %dx%d to %dx%d\n", + virtX, virtY, vx, vy); + virtX = _VIRTUALX(vx); + virtY = vy; + for (p = scrp->modes; p; p = p->next) { + if (numModes > 0) { + if (p->HDisplay > virtX) + p->status = MODE_VIRTUAL_X; + if (p->VDisplay > virtY) + p->status = MODE_VIRTUAL_Y; + if (p->status != MODE_OK) { + numModes--; + printModeRejectMessage(scrp->scrnIndex, p, p->status); + } + } + } + if (linePitches != NULL) { + for (i = 0; linePitches[i] != 0; i++) { + if ((linePitches[i] >= virtX) && + (linePitches[i] == + scanLineWidth(virtX, virtY, linePitches[i], + apertureSize, BankFormat, pitchInc))) { + linePitch = linePitches[i]; + break; + } + } + } else { + linePitch = scanLineWidth(virtX, virtY, minPitch, + apertureSize, BankFormat, pitchInc); + } + } + } + + /* Update the ScrnInfoRec parameters */ + + scrp->virtualX = virtX; + scrp->virtualY = virtY; + scrp->displayWidth = linePitch; + + if (numModes <= 0) + return 0; + + /* Make the mode list into a circular list by joining up the ends */ + p = scrp->modes; + while (p->next != NULL) + p = p->next; + /* p is now the last mode on the list */ + p->next = scrp->modes; + scrp->modes->prev = p; + + if (minHeight > 0 && virtY < minHeight) { + xf86DrvMsg(scrp->scrnIndex, X_ERROR, + "Virtual height (%d) is too small for the hardware " + "(min %d)\n", virtY, minHeight); + return -1; + } + + return numModes; +} + +/* + * xf86DeleteMode + * + * This function removes a mode from a list of modes. + * + * There are different types of mode lists: + * + * - singly linked linear lists, ending in NULL + * - doubly linked linear lists, starting and ending in NULL + * - doubly linked circular lists + * + */ + +void +xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode) +{ + /* Catch the easy/insane cases */ + if (modeList == NULL || *modeList == NULL || mode == NULL) + return; + + /* If the mode is at the start of the list, move the start of the list */ + if (*modeList == mode) + *modeList = mode->next; + + /* If mode is the only one on the list, set the list to NULL */ + if ((mode == mode->prev) && (mode == mode->next)) { + *modeList = NULL; + } else { + if ((mode->prev != NULL) && (mode->prev->next == mode)) + mode->prev->next = mode->next; + if ((mode->next != NULL) && (mode->next->prev == mode)) + mode->next->prev = mode->prev; + } + + free(mode->name); + free(mode); +} + +/* + * xf86PruneDriverModes + * + * Remove modes from the driver's mode list which have been marked as + * invalid. + */ + +void +xf86PruneDriverModes(ScrnInfoPtr scrp) +{ + DisplayModePtr first, p, n; + + p = scrp->modes; + if (p == NULL) + return; + + do { + if (!(first = scrp->modes)) + return; + n = p->next; + if (p->status != MODE_OK) { + xf86DeleteMode(&(scrp->modes), p); + } + p = n; + } while (p != NULL && p != first); + + /* modePool is no longer needed, turf it */ + while (scrp->modePool) { + /* + * A modePool mode's prev field is used to hold a pointer to the + * member of the scrp->modes list for which a match was considered. + * Clear that pointer first, otherwise xf86DeleteMode might get + * confused + */ + scrp->modePool->prev = NULL; + xf86DeleteMode(&scrp->modePool, scrp->modePool); + } +} + + +/* + * xf86SetCrtcForModes + * + * Goes through the screen's mode list, and initialises the Crtc + * parameters for each mode. The initialisation includes adjustments + * for interlaced and double scan modes. + */ +void +xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags) +{ + DisplayModePtr p; + + /* + * Store adjustFlags for use with the VidMode extension. There is an + * implicit assumption here that SetCrtcForModes is called once. + */ + scrp->adjustFlags = adjustFlags; + + p = scrp->modes; + if (p == NULL) + return; + + do { + xf86SetModeCrtc(p, adjustFlags); + DebugF("%sMode %s: %d (%d) %d %d (%d) %d %d (%d) %d %d (%d) %d\n", + (p->type & M_T_DEFAULT) ? "Default " : "", + p->name, p->CrtcHDisplay, p->CrtcHBlankStart, + p->CrtcHSyncStart, p->CrtcHSyncEnd, p->CrtcHBlankEnd, + p->CrtcHTotal, p->CrtcVDisplay, p->CrtcVBlankStart, + p->CrtcVSyncStart, p->CrtcVSyncEnd, p->CrtcVBlankEnd, + p->CrtcVTotal); + p = p->next; + } while (p != NULL && p != scrp->modes); +} + +void +xf86PrintModes(ScrnInfoPtr scrp) +{ + DisplayModePtr p; + float hsync, refresh = 0; + const char *desc, *desc2, *prefix, *uprefix; + + if (scrp == NULL) + return; + + xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d " + "(pitch %d)\n", scrp->virtualX, scrp->virtualY, + scrp->displayWidth); + + p = scrp->modes; + if (p == NULL) + return; + + do { + desc = desc2 = ""; + hsync = xf86ModeHSync(p); + refresh = xf86ModeVRefresh(p); + if (p->Flags & V_INTERLACE) { + desc = " (I)"; + } + if (p->Flags & V_DBLSCAN) { + desc = " (D)"; + } + if (p->VScan > 1) { + desc2 = " (VScan)"; + } + if (p->type & M_T_BUILTIN) + prefix = "Built-in mode"; + else if (p->type & M_T_DEFAULT) + prefix = "Default mode"; + else if (p->type & M_T_DRIVER) + prefix = "Driver mode"; + else + prefix = "Mode"; + if (p->type & M_T_USERDEF) + uprefix = "*"; + else + uprefix = " "; + if (hsync == 0 || refresh == 0) { + if (p->name) + xf86DrvMsg(scrp->scrnIndex, X_CONFIG, + "%s%s \"%s\"\n", uprefix, prefix, p->name); + else + xf86DrvMsg(scrp->scrnIndex, X_PROBED, + "%s%s %dx%d (unnamed)\n", + uprefix, prefix, p->HDisplay, p->VDisplay); + } else if (p->Clock == p->SynthClock) { + xf86DrvMsg(scrp->scrnIndex, X_CONFIG, + "%s%s \"%s\": %.1f MHz, %.1f kHz, %.1f Hz%s%s\n", + uprefix, prefix, p->name, p->Clock / 1000.0, + hsync, refresh, desc, desc2); + } else { + xf86DrvMsg(scrp->scrnIndex, X_CONFIG, + "%s%s \"%s\": %.1f MHz (scaled from %.1f MHz), " + "%.1f kHz, %.1f Hz%s%s\n", + uprefix, prefix, p->name, p->Clock / 1000.0, + p->SynthClock / 1000.0, hsync, refresh, desc, desc2); + } + if (hsync != 0 && refresh != 0) + xf86PrintModeline(scrp->scrnIndex,p); + p = p->next; + } while (p != NULL && p != scrp->modes); +} diff --git a/xorg-server/hw/xfree86/common/xf86Opt.h b/xorg-server/hw/xfree86/common/xf86Opt.h index 88392dc6d..b0fdaa6b6 100644 --- a/xorg-server/hw/xfree86/common/xf86Opt.h +++ b/xorg-server/hw/xfree86/common/xf86Opt.h @@ -72,7 +72,7 @@ typedef struct { extern _X_EXPORT int xf86SetIntOption(XF86OptionPtr optlist, const char *name, int deflt); extern _X_EXPORT double xf86SetRealOption(XF86OptionPtr optlist, const char *name, double deflt); -extern _X_EXPORT char *xf86SetStrOption(XF86OptionPtr optlist, const char *name, char *deflt); +extern _X_EXPORT char *xf86SetStrOption(XF86OptionPtr optlist, const char *name, const char *deflt); extern _X_EXPORT int xf86SetBoolOption(XF86OptionPtr list, const char *name, int deflt ); extern _X_EXPORT double xf86SetPercentOption(XF86OptionPtr list, const char *name, double deflt ); extern _X_EXPORT int xf86CheckIntOption(XF86OptionPtr optlist, const char *name, int deflt); @@ -91,7 +91,7 @@ extern _X_EXPORT char *xf86OptionName(XF86OptionPtr opt); extern _X_EXPORT char *xf86OptionValue(XF86OptionPtr opt); extern _X_EXPORT void xf86OptionListReport(XF86OptionPtr parm); extern _X_EXPORT XF86OptionPtr xf86FindOption(XF86OptionPtr options, const char *name); -extern _X_EXPORT char *xf86FindOptionValue(XF86OptionPtr options, const char *name); +extern _X_EXPORT const char *xf86FindOptionValue(XF86OptionPtr options, const char *name); extern _X_EXPORT void xf86MarkOptionUsed(XF86OptionPtr option); extern _X_EXPORT void xf86MarkOptionUsedByName(XF86OptionPtr options, const char *name); extern _X_EXPORT Bool xf86CheckIfOptionUsed(XF86OptionPtr option); diff --git a/xorg-server/hw/xfree86/common/xf86Option.c b/xorg-server/hw/xfree86/common/xf86Option.c index 9c528782f..dc0a01899 100644 --- a/xorg-server/hw/xfree86/common/xf86Option.c +++ b/xorg-server/hw/xfree86/common/xf86Option.c @@ -187,7 +187,7 @@ LookupRealOption(XF86OptionPtr optlist, const char *name, double deflt, static char * -LookupStrOption(XF86OptionPtr optlist, const char *name, char *deflt, Bool markUsed) +LookupStrOption(XF86OptionPtr optlist, const char *name, const char *deflt, Bool markUsed) { OptionInfoRec o; @@ -243,7 +243,7 @@ xf86SetRealOption(XF86OptionPtr optlist, const char *name, double deflt) char * -xf86SetStrOption(XF86OptionPtr optlist, const char *name, char *deflt) +xf86SetStrOption(XF86OptionPtr optlist, const char *name, const char *deflt) { return LookupStrOption(optlist, name, deflt, TRUE); } @@ -306,7 +306,7 @@ XF86OptionPtr xf86ReplaceIntOption(XF86OptionPtr optlist, const char *name, const int val) { char tmp[16]; - sprintf(tmp,"%i",val); + snprintf(tmp,sizeof(tmp),"%i",val); return xf86AddNewOption(optlist,name,tmp); } @@ -314,7 +314,7 @@ XF86OptionPtr xf86ReplaceRealOption(XF86OptionPtr optlist, const char *name, const double val) { char tmp[32]; - snprintf(tmp,32,"%f",val); + snprintf(tmp,sizeof(tmp),"%f",val); return xf86AddNewOption(optlist,name,tmp); } @@ -328,7 +328,7 @@ XF86OptionPtr xf86ReplacePercentOption(XF86OptionPtr optlist, const char *name, const double val) { char tmp[16]; - sprintf(tmp, "%lf%%", val); + snprintf(tmp, sizeof(tmp), "%lf%%", val); return xf86AddNewOption(optlist,name,tmp); } @@ -416,7 +416,7 @@ xf86FindOption(XF86OptionPtr options, const char *name) } -char * +const char * xf86FindOptionValue(XF86OptionPtr options, const char *name) { return xf86findOptionValue(options, name); diff --git a/xorg-server/hw/xfree86/common/xf86PM.c b/xorg-server/hw/xfree86/common/xf86PM.c index 16b6bdc4a..47e0297d6 100644 --- a/xorg-server/hw/xfree86/common/xf86PM.c +++ b/xorg-server/hw/xfree86/common/xf86PM.c @@ -41,7 +41,7 @@ pmWait (*xf86PMConfirmEventToOs)(int fd,pmEvent event) = NULL; static Bool suspended = FALSE; static int -eventName(pmEvent event, char **str) +eventName(pmEvent event, const char **str) { switch(event) { case XF86_APM_SYS_STANDBY: *str="System Standby Request"; return 0; @@ -179,7 +179,7 @@ xf86HandlePMEvents(int fd, pointer data) if ((n = xf86PMGetEventFromOs(fd,events,MAX_NO_EVENTS))) { do { for (i = 0; i < n; i++) { - char *str = NULL; + const char *str = NULL; int verb = eventName(events[i],&str); xf86MsgVerb(X_INFO,verb,"PM Event received: %s\n",str); diff --git a/xorg-server/hw/xfree86/common/xf86Priv.h b/xorg-server/hw/xfree86/common/xf86Priv.h index 1fe3d7e0d..8c698591e 100644 --- a/xorg-server/hw/xfree86/common/xf86Priv.h +++ b/xorg-server/hw/xfree86/common/xf86Priv.h @@ -69,7 +69,7 @@ extern _X_EXPORT Pix24Flags xf86Pix24; extern _X_EXPORT rgb xf86Weight; extern _X_EXPORT Bool xf86FlipPixels; extern _X_EXPORT Gamma xf86Gamma; -extern _X_EXPORT char *xf86ServerName; +extern _X_EXPORT const char *xf86ServerName; /* Other parameters */ diff --git a/xorg-server/hw/xfree86/common/xf86ShowOpts.c b/xorg-server/hw/xfree86/common/xf86ShowOpts.c deleted file mode 100644 index a8059168d..000000000 --- a/xorg-server/hw/xfree86/common/xf86ShowOpts.c +++ /dev/null @@ -1,130 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86ShopwOpts.c,v 3.80 2003/10/08 14:58:27 dawes Exp $ */ -/* - * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales. - * - * 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 Alan Hourihane not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations - * about the suitability of this software for any purpose. It is provided - * "as is" without express or implied warranty. - * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE 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: Marcus Schaefer, ms@suse.de - * - */ - -#include <ctype.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <X11/X.h> -#include <X11/Xmd.h> -#include "os.h" -#ifdef XFree86LOADER -#include "loaderProcs.h" -#endif -#include "xf86.h" -#include "xf86Config.h" -#include "xf86_OSlib.h" -#include "xf86Priv.h" -/* #include "xf86PciData.h" */ -#define IN_XSERVER -#include "xf86Parser.h" -#include "xf86tokens.h" -#include "Configint.h" -#include "xf86DDC.h" -#if defined(__sparc__) && !defined(__OpenBSD__) -#include "xf86Bus.h" -#include "xf86Sbus.h" -#endif -#include "globals.h" - -static const char* -optionTypeToSting(OptionValueType type) -{ - switch (type) { - case OPTV_NONE: - return ""; - case OPTV_INTEGER: - return "<int>"; - case OPTV_STRING: - return "<str>"; - case OPTV_ANYSTR: - return "<str>"; - case OPTV_REAL: - return "<real>"; - case OPTV_BOOLEAN: - return "<bool>"; - case OPTV_FREQ: - return "<freq>"; - case OPTV_PERCENT: - return "<percent>"; - default: - return "<undef>"; - } -} - -void DoShowOptions (void) { - int i = 0; - char **vlist = 0; - char *pSymbol = 0; - XF86ModuleData *initData = 0; - if (! (vlist = xf86DriverlistFromCompile())) { - ErrorF("Missing output drivers\n"); - goto bail; - } - xf86LoadModules (vlist,0); - free(vlist); - for (i = 0; i < xf86NumDrivers; i++) { - if (xf86DriverList[i]->AvailableOptions) { - OptionInfoPtr pOption = (OptionInfoPtr)(*xf86DriverList[i]->AvailableOptions)(0,0); - if (! pOption) { - ErrorF ("(EE) Couldn't read option table for %s driver\n", - xf86DriverList[i]->driverName - ); - continue; - } - XNFasprintf(&pSymbol, "%sModuleData", - xf86DriverList[i]->driverName); - initData = LoaderSymbol (pSymbol); - if (initData) { - XF86ModuleVersionInfo *vers = initData->vers; - OptionInfoPtr p; - ErrorF ("Driver[%d]:%s[%s] {\n", - i,xf86DriverList[i]->driverName,vers->vendor - ); - for (p = pOption; p->name != NULL; p++) { - const char *opttype = optionTypeToSting(p->type); - /* XXX: Why overallocate by 2 bytes? - * Otherwise, this would be strdup() - */ - char *optname = malloc(strlen(p->name) + 2 + 1); - if (!optname) { - continue; - } - sprintf(optname, "%s", p->name); - ErrorF ("\t%s:%s\n", optname,opttype); - } - ErrorF ("}\n"); - } - } - } - bail: - OsCleanup (TRUE); - AbortDDX (EXIT_ERR_DRIVERS); - fflush (stderr); - exit (0); -} diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c index 7feb48c1e..b9753f01d 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.c +++ b/xorg-server/hw/xfree86/common/xf86Xinput.c @@ -460,10 +460,9 @@ HostOS(void) if (*host_os == '\0') { if (uname(&name) >= 0) - strcpy(host_os, name.sysname); + strlcpy(host_os, name.sysname, sizeof(host_os)); else { - strncpy(host_os, "unknown", sizeof(host_os)); - host_os[sizeof(host_os)-1] = '\0'; + strlcpy(host_os, "unknown", sizeof(host_os)); } } return host_os; diff --git a/xorg-server/hw/xfree86/common/xf86pciBus.c b/xorg-server/hw/xfree86/common/xf86pciBus.c index 87dc02512..b95b25359 100644 --- a/xorg-server/hw/xfree86/common/xf86pciBus.c +++ b/xorg-server/hw/xfree86/common/xf86pciBus.c @@ -82,16 +82,6 @@ static struct pci_slot_match xf86IsolateDevice = { PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0 }; -void -xf86FormatPciBusNumber(int busnum, char *buffer) -{ - /* 'buffer' should be at least 8 characters long */ - if (busnum < 256) - sprintf(buffer, "%d", busnum); - else - sprintf(buffer, "%d@%d", busnum & 0x00ff, busnum >> 8); -} - /* * xf86Bus.c interface */ @@ -1072,7 +1062,7 @@ videoPtrToDriverList(struct pci_device *dev, int i; /* Add more entries here if we ever return more than 4 drivers for any device */ - char *driverList[5] = { NULL, NULL, NULL, NULL, NULL }; + const char *driverList[5] = { NULL, NULL, NULL, NULL, NULL }; switch (dev->vendor_id) { @@ -1219,9 +1209,8 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip /* A tiny bit of sanity checking. We should probably do better */ if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) { /* We need the full path name to open the file */ - strncpy(path_name, PCI_TXT_IDS_PATH, 256); - strncat(path_name, "/", 1); - strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1)); + snprintf(path_name, sizeof(path_name), "%s/%s", + PCI_TXT_IDS_PATH, direntry->d_name); fp = fopen(path_name, "r"); if (fp == NULL) { xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name); @@ -1235,8 +1224,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip #endif /* __GLIBC __ */ xchomp(line); if (isdigit(line[0])) { - strncpy(vendor_str, line, 4); - vendor_str[4] = '\0'; + strlcpy(vendor_str, line, sizeof(vendor_str)); vendor = (int)strtol(vendor_str, NULL, 16); if ((strlen(&line[4])) == 0) { chip_str[0] = '\0'; @@ -1248,8 +1236,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip chip = -1; } else { /* Ok, it's a real ID */ - strncpy(chip_str, &line[4], 4); - chip_str[4] = '\0'; + strlcpy(chip_str, &line[4], sizeof(chip_str)); chip = (int)strtol(chip_str, NULL, 16); } } @@ -1349,7 +1336,12 @@ xf86PciConfigureNewDev(void *busData, struct pci_device *pVideo, pVideo = (struct pci_device *) busData; - xf86FormatPciBusNumber(pVideo->bus, busnum); + if (pVideo->bus < 256) + snprintf(busnum, sizeof(busnum), "%d", pVideo->bus); + else + snprintf(busnum, sizeof(busnum), "%d@%d", + pVideo->bus & 0x00ff, pVideo->bus >> 8); + XNFasprintf(&GDev->busID, "PCI:%s:%d:%d", busnum, pVideo->dev, pVideo->func); diff --git a/xorg-server/hw/xfree86/common/xf86sbusBus.c b/xorg-server/hw/xfree86/common/xf86sbusBus.c index 181c6ab00..b7bb913fe 100644 --- a/xorg-server/hw/xfree86/common/xf86sbusBus.c +++ b/xorg-server/hw/xfree86/common/xf86sbusBus.c @@ -88,7 +88,7 @@ xf86SbusProbe(void) xf86SbusInfo = malloc(sizeof(psdp)); *xf86SbusInfo = NULL; for (i = 0; i < 32; i++) { - sprintf(fbDevName, "/dev/fb%d", i); + snprintf(fbDevName, sizeof(fbDevName), "/dev/fb%d", i); CheckSbusDevice(fbDevName, i); } if (sparcPromInit() >= 0) { diff --git a/xorg-server/hw/xfree86/ddc/xf86DDC.h b/xorg-server/hw/xfree86/ddc/xf86DDC.h index af3ba06a5..16a8641c6 100644 --- a/xorg-server/hw/xfree86/ddc/xf86DDC.h +++ b/xorg-server/hw/xfree86/ddc/xf86DDC.h @@ -100,11 +100,6 @@ typedef enum { DDC_QUIRK_DVI_SINGLE_LINK = 1 << 8, } ddc_quirk_t; -DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); - -extern Bool -xf86MonitorIsHDMI(xf86MonPtr mon); - typedef void (* handle_detailed_fn)(struct detailed_monitor_section *,void *); void xf86ForEachDetailedBlock(xf86MonPtr mon, diff --git a/xorg-server/hw/xfree86/doc/ddxDesign.xml b/xorg-server/hw/xfree86/doc/ddxDesign.xml index c406cd744..ca5efc9be 100644 --- a/xorg-server/hw/xfree86/doc/ddxDesign.xml +++ b/xorg-server/hw/xfree86/doc/ddxDesign.xml @@ -34,7 +34,7 @@ <pubdate>&xserver.reldate;</pubdate> <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> - <releaseinfo>Xorg server version &xserver.version;</releaseinfo> + <releaseinfo>X Server Version &xserver.version;</releaseinfo> </articleinfo> @@ -3187,7 +3187,7 @@ would not need to use these directly. <blockquote><para> <programlisting> - char *xf86FindOptionValue(XF86OptionPtr options, const char *name); + const char *xf86FindOptionValue(XF86OptionPtr options, const char *name); </programlisting> <blockquote><para> Takes a list of options and an option name, and returns the value diff --git a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c index 30a2a9133..d7b4d3c20 100644 --- a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c +++ b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c @@ -265,20 +265,20 @@ fbdev_open_pci(struct pci_device * pPci, char **namep) int fd, i; for (i = 0; i < 8; i++) { - sprintf(filename, + snprintf(filename, sizeof(filename), "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d", pPci->domain, pPci->bus, pPci->dev, pPci->func, i); fd = open(filename, O_RDONLY, 0); if (fd < 0) { - sprintf(filename, + snprintf(filename, sizeof(filename), "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d", pPci->domain, pPci->bus, pPci->dev, pPci->func, i); fd = open(filename, O_RDONLY, 0); } if (fd >= 0) { close(fd); - sprintf(filename, "/dev/fb%d", i); + snprintf(filename, sizeof(filename), "/dev/fb%d", i); fd = open(filename, O_RDWR, 0); if (fd != -1) { diff --git a/xorg-server/hw/xfree86/i2c/msp3430.c b/xorg-server/hw/xfree86/i2c/msp3430.c index b58c3f09c..df8adc435 100644 --- a/xorg-server/hw/xfree86/i2c/msp3430.c +++ b/xorg-server/hw/xfree86/i2c/msp3430.c @@ -1,726 +1,727 @@ -#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-#include <unistd.h>
-
-#include "xf86.h"
-#include "xf86i2c.h"
-#include "msp3430.h"
-#include "i2c_def.h"
-
-#define CONTROL 0x00
-#define WR_DEM 0x10
-#define RD_DEM 0x11
-#define WR_DSP 0x12
-#define RD_DSP 0x13
-
-
-void InitMSP34xxG(MSP3430Ptr m);
-void InitMSP34x5D(MSP3430Ptr m);
-void CheckModeMSP34x5D(MSP3430Ptr m);
-char *MSP_getProductName (CARD16 product_id);
-void mpause(int milliseconds);
-
-#define __MSPDEBUG__ 0
-
-#if __MSPDEBUG__ > 3
-
-void MSPBeep(MSP3430Ptr m, CARD8 freq);
-#define __MSPBEEP MSPBeep(m,0x14);
-
-#else
-
-#define __MSPBEEP
-#endif
-
-static void SetMSP3430Control(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegValueHigh, CARD8 RegValueLow)
-{
- I2CByte data[3];
-
- data[0]=RegAddress;
- data[1]=RegValueHigh;
- data[2]=RegValueLow;
-
- I2C_WriteRead(&(m->d),data,3,NULL,0);
-}
-
-static void SetMSP3430Data(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegSubAddressHigh, CARD8 RegSubAddressLow,
- CARD8 RegValueHigh, CARD8 RegValueLow)
-{
- I2CByte data[5];
-#ifdef MSP_DEBUG
- if(!m->registers_present[RegSubAddressLow]){
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_ERROR, "Attempt to access non-existent register in MSP34xxX: 0x%02x 0x%02x 0x%02x <- 0x%02x 0x%02x\n",
- RegAddress, RegSubAddressHigh, RegSubAddressLow, RegValueHigh, RegValueLow);
- }
-#endif
-
- data[0] = RegAddress;
- data[1] = RegSubAddressHigh;
- data[2] = RegSubAddressLow;
- data[3] = RegValueHigh;
- data[4] = RegValueLow;
-
- I2C_WriteRead(&(m->d),data,5,NULL,0);
-}
-
-static void GetMSP3430Data(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegSubAddressHigh, CARD8 RegSubAddressLow,
- CARD8 *RegValueHigh, CARD8 *RegValueLow)
-{
- I2CByte send[3];
- I2CByte receive[2];
-
- send[0] = RegAddress;
- send[1] = RegSubAddressHigh;
- send[2] = RegSubAddressLow;
-
- I2C_WriteRead(&(m->d), send, 3, receive, 2);
-
- *RegValueHigh = receive[0];
- *RegValueLow = receive[1];
-}
-
-#if __MSPDEBUG__ > 2
-static void MSP3430DumpStatus(MSP3430Ptr m)
-{
-CARD8 status_hi, status_lo;
-CARD8 subaddr, data[2];
-
-GetMSP3430Data(m, RD_DEM, 0x02, 0x00, &status_hi, &status_lo);
-xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: SAP(8)=%d mono/NICAM(7)=%d stereo=%d %s O_1=%d O_0=%d 2nd car=%d 1st car=%d\n",
- status_hi & 1, (status_lo>>7) & 1, (status_lo>>6)&1,
- (status_lo>>5)? ( (status_hi>>1)&1? "bad NICAM reception" : "NICAM" ) :
- ((status_hi>>1)&1 ? "bogus" : "ANALOG FM/AM") ,
- (status_lo>>4)&1, (status_lo>>3)&1,!( (status_lo>>2)&1), !((status_lo>>1)&1));
-
-GetMSP3430Data(m, RD_DEM, 0x00, 0x7E, &status_hi, &status_lo);
-xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: standard result=0x%02x%02x\n",
- status_hi, status_lo);
-subaddr=0x0;
-I2C_WriteRead(&(m->d), &subaddr, 1, data, 2);
-xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: control=0x%02x%02x\n",
- data[1], data[0]);
-}
-#endif
-
-/* wrapper */
-void InitMSP3430(MSP3430Ptr m)
-{
- #if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"InitMSP3430(m->connector=%d, m->standard=%d, m->chip_family=%d)\n",
- m->connector, m->standard, m->chip_family);
- #endif
- switch (m->chip_family) {
- case MSPFAMILY_34x0G:
- InitMSP34xxG(m);
- break;
- case MSPFAMILY_34x5G:
- InitMSP34xxG(m);
- break;
- case MSPFAMILY_34x5D:
- InitMSP34x5D(m);
- break;
- }
-}
-
-/*-----------------------------------------------------------------
-| common functions for all MSP34xx chips
-|----------------------------------------------------------------*/
-
-MSP3430Ptr DetectMSP3430(I2CBusPtr b, I2CSlaveAddr addr)
-{
- MSP3430Ptr m;
- I2CByte a;
- CARD8 hardware_version, major_revision, product_code, rom_version;
- Bool supported;
-
- m = calloc(1,sizeof(MSP3430Rec));
- if(m == NULL)return NULL;
- m->d.DevName = strdup("MSP34xx");
- m->d.SlaveAddr = addr;
- m->d.pI2CBus = b;
- m->d.NextDev = NULL;
- m->d.StartTimeout = b->StartTimeout;
- m->d.BitTimeout = b->BitTimeout;
- m->d.AcknTimeout = b->AcknTimeout;
- m->d.ByteTimeout = b->ByteTimeout;
-
- if(!I2C_WriteRead(&(m->d), NULL, 0, &a, 1))
- {
- free(m->d.DevName);
- free(m);
- return NULL;
- }
-
-
- m->standard=MSP3430_NTSC;
- m->connector=MSP3430_CONNECTOR_1;
- m->mode=MSPMODE_STEREO_A; /*stereo or chanel A if avail. */
- m->c_format=MSPFORMAT_UNKNOWN;
- m->c_standard=MSPSTANDARD_UNKNOWN;
- m->c_matrix=m->c_fmmatrix=m->c_source=0;
- m->volume=0;
- m->recheck=FALSE;
-
- GetMSP3430Data(m, RD_DSP, 0x00, 0x1E, &hardware_version, &major_revision);
- GetMSP3430Data(m, RD_DSP, 0x00, 0x1F, &product_code, &rom_version);
- m->hardware_version=hardware_version;
- m->major_revision=major_revision;
- m->product_code=product_code;
- m->rom_version=rom_version;
-
- m->chip_id=((major_revision << 8) | product_code);
-
- supported=FALSE;
- switch (major_revision) {
- case 4: /* 34xxD */
- switch (product_code) {
- case 0x05: /* 3405D */
- case 0x0A: /* 3410D */
- case 0x0F: /* 3415D */
- m->chip_family=MSPFAMILY_34x5D;
- m->recheck=TRUE;
- supported=TRUE;
- break;
- default:
- m->chip_family=MSPFAMILY_34x0D;
- }
- break;
- case 7: /* 34xxG */
- switch(product_code){
- case 0x00:
- case 0x0A:
- case 0x1E:
- case 0x28:
- case 0x32:
- m->chip_family=MSPFAMILY_34x0G;
- supported=TRUE;
- break;
- case 0x0f:
- case 0x19:
- case 0x2d:
- case 0x37:
- case 0x41:
- m->chip_family=MSPFAMILY_34x5G;
- supported=TRUE;
- #ifdef MSP_DEBUG
- memset(m->registers_present, 0, 256);
- #define A(num) m->registers_present[(num)]=1;
- #define B(num1, num2) memset(&(m->registers_present[num1]), 1, num2-num1);
- A(0x20)
- A(0x30)
- A(0x40)
- A(0x00)
- B(0x01, 0x08)
- B(0x0B, 0x0E)
- A(0x10)
- B(0x12,0x14)
- A(0x16)
- A(0x29)
- #undef B
- #undef A
- #endif
- break;
- default:
- m->chip_family=MSPFAMILY_UNKNOWN;
- }
- break;
- default:
- m->chip_family=MSPFAMILY_UNKNOWN;
- }
-
- xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "Found %s%s, rom version 0x%02x, chip_id=0x%04x\n",
- MSP_getProductName(m->chip_id), supported?"":" (unsupported)", rom_version, m->chip_id);
-
- if (!supported) {
- free(m->d.DevName);
- free(m);
- return NULL;
- }
- if(!I2CDevInit(&(m->d)))
- {
- free(m->d.DevName);
- free(m);
- return NULL;
- }
-
- return m;
-}
-
-void ResetMSP3430(MSP3430Ptr m)
-{
- /* Reset the MSP3430 */
- SetMSP3430Control(m, 0x00, 0x80, 0x00);
- /* Set it back to normal operation */
- SetMSP3430Control(m, 0x00, 0x00, 0x00);
-
- m->c_format=MSPFORMAT_UNKNOWN;
- m->c_standard=MSPSTANDARD_UNKNOWN;
- m->c_matrix=m->c_fmmatrix=m->c_source=0;
- m->volume=0;
-}
-
-void MSP3430SetVolume (MSP3430Ptr m, CARD8 value)
-{
- CARD8 result;
-#if 0
- CARD8 old_volume;
- GetMSP3430Data(m, RD_DSP, 0x00, 0x00, &old_volume, &result);
- xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP3430 result 0x%02x\n", result);
-#endif
- /* save an extra Get call */
- result=0;
-
- SetMSP3430Data(m, WR_DSP, 0x00, 0x00, value, result);
-
- SetMSP3430Data(m, WR_DSP, 0x00, 0x07, value, 0);
- m->volume=value;
-
-#if __MSPDEBUG__ > 2
- MSP3430DumpStatus(m);
- __MSPBEEP
- GetMSP3430Data(m, RD_DSP, 0x00, 0x00, &old_volume, &result);
- xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP3430 volume 0x%02x\n",value);
-#endif
-}
-
-
-void MSP3430SetSAP (MSP3430Ptr m, int mode)
-{
- xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "Put actual code to change SAP here\n");
-
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, mode & 0xff, 0x20);
-}
-
-
-#if 0
-void MSP3430SetSource(MSP3430Ptr m, CARD8 value)
-{
- /* Write to DSP, register 0x0008, (loudspeaker channel source/matrix) */
- /* This sets the source to the TV tuner, for stereo operation */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, value, 0x20);
-}
-#endif
-
-
-char *MSP_getProductName (CARD16 product_id)
-{
- switch (product_id) {
- case 0x0400: return "MSP3400D";
- case 0x040a: return "MSP3410D";
- case 0x0405: return "MSP3405D";
- case 0x040f: return "MSP3415D";
- case 0x0700: return "MSP3400G";
- case 0x070a: return "MSP3410G";
- case 0x071e: return "MSP3430G";
- case 0x0728: return "MSP3440G";
- case 0x0732: return "MSP3450G";
- case 0x070f: return "MSP3415G";
- case 0x0719: return "MSP3425G";
- case 0x072d: return "MSP3445G";
- case 0x0737: return "MSP3455G";
- case 0x0741: return "MSP3465G";
- }
- return "MSP - unknown type";
-}
-
-#if __MSPDEBUG__ > 2
-/*puts beep in MSP output
- freq = 0x01 - 16Hz ... 0x40 - 1kHz ... 0xff - 4kHz
-*/
-void MSPBeep(MSP3430Ptr m, CARD8 freq) {
- SetMSP3430Data (m, WR_DSP, 0x00, freq, 0x7f, 0x40);
- mpause(100);
- SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, 0x00);
-}
-#endif
-
-void mpause(int milliseconds) {
- int i,m;
- m=milliseconds/20;
- for (i=0;i<m;i++) usleep(20000);
-}
-
-/*-----------------------------------------------------------------
-| specific functions for all MSP34xxG chips
-|----------------------------------------------------------------*/
-
-void InitMSP34xxG(MSP3430Ptr m)
-{
-
- #if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"InitMSP34xxG(m->connector=%d, m->standard=%d, m->chip_family=%d)\n",
- m->connector, m->standard, m->chip_family);
- #endif
- /* Reset MSP3430 */
- SetMSP3430Control(m, 0x00, 0x80, 0x00);
- /* Set it back to normal operation */
- SetMSP3430Control(m, 0x00, 0x00, 0x00);
-
- /*set MODUS register */
- /* bits: 0 - automatic sound detection */
- /* 1 - enable STATUS change */
- /* 12 - detect 6.5 Mhz carrier as D/K1, D/K2 or D/K NICAM (does not seem to work ) */
- /* 13 - detect 4.5 Mhz carrier as BTSC */
- if ( (m->standard & 0xff) == MSP3430_PAL )
- {
- SetMSP3430Data(m, WR_DEM, 0x00, 0x30, 0x30, 0x03|0x08); /* make O_ pins tristate */
- /* PAL standard */
- SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x01); /* possibly wrong */
- } else {
- SetMSP3430Data(m, WR_DEM, 0x00, 0x30, 0x20, 0x03|0x08);
- /* standard selection is M-BTSC-Stereo */
- SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x20);
- }
-
- switch(m->connector){
- case MSP3430_CONNECTOR_1:
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x03, 0x20);
- break;
- case MSP3430_CONNECTOR_2:
- /* this has not been checked yet.. could be bogus */
- /* SCART Input Prescale: 0 dB gain */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0d, 0x19, 0x00);
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x02, 0x20);
- break;
- case MSP3430_CONNECTOR_3:
- default:
- /* SCART Input Prescale: 0 dB gain */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0d, 0x19, 0x00);
-
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x02, 0x20);
- break;
- }
-
- switch(m->standard){
- case MSP3430_PAL:
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03);
- SetMSP3430Data(m, WR_DSP, 0x00, 0x10, 0x00, 0x5a);
- SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x03);
- /* Set volume to FAST_MUTE. */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);
- break;
- case MSP3430_PAL_DK1:
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03);
- SetMSP3430Data(m, WR_DSP, 0x00, 0x10, 0x00, 0x5a);
- SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x04);
- /* Set volume to FAST_MUTE. */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);
- break;
- case MSP3430_SECAM: /* is this right ? */
- case MSP3430_NTSC:
- /* Write to DSP, register 0x000E, (prescale FM/FM matrix) */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03);
-
- /* Set volume to FAST_MUTE. */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);
- break;
- }
-
-}
-
-/*-----------------------------------------------------------------
-| specific functions for all MSP34x5D chips
-|----------------------------------------------------------------*/
-
-void InitMSP34x5D(MSP3430Ptr m)
-{
-int count;
-CARD8 high,low;
-CARD16 result,standard;
-CARD16 peak;
-
-
-if (m->c_format==MSPFORMAT_UNKNOWN) ResetMSP3430(m);
-else {
- /*mute volume*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x00, 0x00, 0x00);
-}
-
-
-
- switch(m->connector){
- case MSP3430_CONNECTOR_2:
- case MSP3430_CONNECTOR_3:
- if (m->c_format!=MSPFORMAT_SCART) {
- /* SCART Input Prescale: 0 dB gain */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0d, 0x19, 0x00);
- /* this has not been checked yet.. could be bogus */
- m->c_format=MSPFORMAT_SCART; /*stereo*/
- }
- break;
- case MSP3430_CONNECTOR_1:
- default:
-
- switch ( m->standard & 0x00ff ) {
- case MSP3430_PAL:
- switch( m->standard ) {
- case MSP3430_PAL_DK1:
- standard=MSPSTANDARD_FM_DK1;
- break;
-/* case MSP3430_PAL_DK2:
- standard=MSPSTANDARD_FM_DK2;
- break;
- case MSP3430_PAL_BG:
- may be FM stereo (Germany) or FM NICAM (Scandinavia,spain)
- standard=MSPSTANDARD_AUTO;
- break;
-*/
- default:
- standard=MSPSTANDARD_AUTO;
- }
- break;
- case MSP3430_SECAM:
- standard=MSPSTANDARD_AUTO;
- case MSP3430_NTSC:
- /* Only MSP34x5 supported format - Korean NTSC-M*/
- standard=MSPSTANDARD_FM_M;
- default:
- standard=MSPSTANDARD_AUTO;
- }
-
- /*no NICAM support in MSP3410D - force to autodetect*/
- if ((m->chip_id==0x405) && (standard>=MSPSTANDARD_NICAM_BG))
- standard=MSPSTANDARD_AUTO;
-
- if (m->c_standard != standard) {
-
- SetMSP3430Data (m, WR_DEM, 0x00, 0x20, standard>>8, standard & 0xFF);
- if (standard==MSPSTANDARD_AUTO) {
- count = 50; /* time shouldn't exceed 1s, just in case */
- do {
- usleep(20000);
- GetMSP3430Data (m, RD_DEM, 0x00, 0x7e, &high, &low);
- result = ( high << 8 ) | low;
- --count;
- } while( result > 0x07ff && count > 0 );
-
- if ((result > MSPSTANDARD_AUTO))
- standard=result;
- else standard=MSPSTANDARD_UNKNOWN;
-#if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Detected audio standard: %d\n",result);
-#endif
- /* result = MSPSTANDARD_NICAM_L can be one of:
- SECAM_L - MSPSTANDARD_NICAM_L
- D/K1 - MSPSTANDARD_FM_DK1
- D/K2 - MSPSTANDARD_FM_DK2
- D/K-NICAM - MSPSTANDARD_NICAM_DK*/
- if( standard == MSPSTANDARD_NICAM_L ) {
- if ((m->standard & 0x00ff)==MSP3430_PAL) {
- /* force PAL D/K */
- standard=MSPSTANDARD_FM_DK1;
- SetMSP3430Data (m, WR_DEM, 0x00, 0x20, standard>>8, standard & 0xFF);
-#if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO, "Detected 6.5MHz carrier - forced to D/K1 !!!\n" );
-#endif
- }
- }
- }
- m->c_standard=standard;
- } /*end - standard changed*/
- else {
- if (standard<MSPSTANDARD_NICAM_BG) {
- /* get old value of ident. mode register*/
- GetMSP3430Data (m, RD_DSP, 0x00, 0x15, &high, &low);
- /* reset Ident-Filter */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, 0x3F);
- /* put back old value to ident. mode register*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, low);
- }
- }
-
- if (standard<=MSPSTANDARD_AUTO) {
- m->c_format=MSPFORMAT_1xFM;
- }
- else if (standard<MSPSTANDARD_NICAM_BG) {
- /* set FM prescale */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x30, 0);
- /* set FM deemphasis*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0f, ((standard==MSPSTANDARD_FM_M)?0:1), 0);
-
- /* check if FM2 carrier is present */
- /*turn off FM DC Notch*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x17, 0x00, 0x3f);
- /*matrix source for Quasi-Peak Detector - stereo: ch2->L ch1->R*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0c, 0x00, 0x20);
-
- mpause(250);
- GetMSP3430Data (m, RD_DSP, 0x00, 0x1A, &high, &low);
- peak = (high << 8) | low;
-#if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Second carrier Quasi-Peak detection: %d\n",peak);
-#endif
- /*turn on FM DC Notch*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x17, 0x00, 0x00);
-
- if (peak<5) {
- /* if second carrier not detected - only mono from first carrier*/
- m->c_format=MSPFORMAT_1xFM;
- }
- else {
- m->c_format=MSPFORMAT_2xFM;
- /*start of FM identification process - FM_WAIT
- wait at least 0.5s - used 1s - gives beter resolution*/
- mpause(1000);
- }
- }
- else {
- if (standard==MSPSTANDARD_NICAM_L) {
- m->c_format=MSPFORMAT_NICAM_AM;
- /* set AM prescale */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x7C, 0);
- }
- else {
- m->c_format=MSPFORMAT_NICAM_FM;
- /* set FM prescale */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x30, 0);
- }
- /* set FM deemphasis*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0f, 0x00, 0);
- /* set NICAM prescale to 0dB */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x10, 0x20, 0);
- }
-
- break;
- } /*end - case conector*/
-
- CheckModeMSP34x5D(m);
-
- /* Set volume to FAST_MUTE. */
- /*SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);*/
- /*set volume*/
- MSP3430SetVolume(m,m->volume);
-
- __MSPBEEP
-
-
-} /* EnableMSP34x5D ()... */
-
-
-
-
-void CheckModeMSP34x5D(MSP3430Ptr m) {
- const char stereo_on=25;
- const char stereo_off=20;
- const char dual_on=-stereo_on;
- const char dual_off=-stereo_off;
- char detect;
- CARD8 matrix, fmmatrix, source, high, low;
-
- fmmatrix=0; /*no matrix*/
- source=0; /*FM*/
- switch (m->c_format) {
- case MSPFORMAT_NICAM_FM:
- case MSPFORMAT_NICAM_AM:
- case MSPFORMAT_SCART:
- source=( (m->c_format == MSPFORMAT_SCART)?2:1 );
- switch (m->mode) {
- case MSPMODE_MONO:
- matrix=0x30; /*MONO*/
- break;
- case MSPMODE_A:
- matrix=0x00; /*A*/
- break;
- case MSPMODE_B:
- matrix=0x10; /*B*/
- break;
- default:
- matrix=0x20; /*STEREO*/
- break;
- }
- break;
- default:
- case MSPFORMAT_1xFM:
- matrix=0x00; /*A*/
- break;
- case MSPFORMAT_2xFM:
- switch (m->mode) {
- case MSPMODE_MONO:
- matrix=0x30; /*MONO*/
- break;
- case MSPMODE_STEREO:
- matrix=0x20; /*STEREO*/
- fmmatrix=((m->c_standard==MSPSTANDARD_FM_M)?2:1);
- break;
- case MSPMODE_AB:
- matrix=0x20; /*STEREO*/
- break;
- case MSPMODE_A:
- matrix=0x00; /*A*/
- break;
- case MSPMODE_B:
- matrix=0x10; /*B*/
- break;
- default:
- /*FM_IDENT_CHECK*/
- GetMSP3430Data (m, RD_DSP, 0x00, 0x18, &high, &low);
- detect=(char)high;
-#if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Stereo Detection Register: %d\n",detect);
-#endif
- if (detect>=((m->c_mode==MSPMODE_STEREO)?stereo_off:stereo_on)) {
- m->c_mode=MSPMODE_STEREO;
- matrix=0x20; /*STEREO*/
- fmmatrix=((m->c_standard==MSPSTANDARD_FM_M)?2:1);
- }
- else if (detect<=((m->c_mode==MSPMODE_AB)?dual_off:dual_on)) {
- m->c_mode=MSPMODE_AB;
- switch (m->mode) {
- case MSPMODE_STEREO_AB: matrix=0x20; break;
- case MSPMODE_STEREO_B: matrix=0x10; break;
- default:
- case MSPMODE_A: matrix=0x00; break;
- }
- }
- else {
- m->c_mode=MSPMODE_MONO;
- matrix=0x30; /*MONO*/
- }
- break;
- } /* end - case mode*/
- break;
- }
-
- if (m->c_fmmatrix != fmmatrix) {
- GetMSP3430Data (m, RD_DSP, 0x00, 0x0e, &high, &low);
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, high, fmmatrix);
- m->c_fmmatrix = fmmatrix;
- }
-
- if ((m->c_matrix != matrix) || (m->c_source != source)) {
- /*set chanel source and matrix for loudspeaker*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x08, source, matrix);
-
- m->c_matrix = matrix;
- m->c_source = source;
- }
-
- if ( ((m->c_format) & 0xF0) == MSPFORMAT_NICAM)
- SetMSP3430Data (m, WR_DEM, 0x00, 0x21, 0, 1);
-
-#if __MSPDEBUG__ > 0
- char *msg;
- switch (matrix) {
- case 0x30: /*MONO*/
- msg="MONO";
- break;
- case 0x00: /*LEFT*/
- msg="MONO/CHANNEL_1";
- break;
- case 0x10: /*RIGHT*/
- msg="MONO/CHANNEL_2";
- break;
- case 0x20: /*LEFT*/
- msg="STEREO";
- break;
- default:
- msg="unknown";
- break;
- }
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Audio mode set to: %s\n",msg);
-#endif
-}
-
+#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <string.h> +#include <unistd.h> + +#include "xf86.h" +#include "xf86i2c.h" +#include "msp3430.h" +#include "i2c_def.h" + +#define CONTROL 0x00 +#define WR_DEM 0x10 +#define RD_DEM 0x11 +#define WR_DSP 0x12 +#define RD_DSP 0x13 + + +void InitMSP34xxG(MSP3430Ptr m); +void InitMSP34x5D(MSP3430Ptr m); +void CheckModeMSP34x5D(MSP3430Ptr m); +static const char *MSP_getProductName (CARD16 product_id); +void mpause(int milliseconds); + +#define __MSPDEBUG__ 0 + +#if __MSPDEBUG__ > 3 + +void MSPBeep(MSP3430Ptr m, CARD8 freq); +#define __MSPBEEP MSPBeep(m,0x14); + +#else + +#define __MSPBEEP +#endif + +static void SetMSP3430Control(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegValueHigh, CARD8 RegValueLow) +{ + I2CByte data[3]; + + data[0]=RegAddress; + data[1]=RegValueHigh; + data[2]=RegValueLow; + + I2C_WriteRead(&(m->d),data,3,NULL,0); +} + +static void SetMSP3430Data(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegSubAddressHigh, CARD8 RegSubAddressLow, + CARD8 RegValueHigh, CARD8 RegValueLow) +{ + I2CByte data[5]; +#ifdef MSP_DEBUG + if(!m->registers_present[RegSubAddressLow]){ + xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_ERROR, "Attempt to access non-existent register in MSP34xxX: 0x%02x 0x%02x 0x%02x <- 0x%02x 0x%02x\n", + RegAddress, RegSubAddressHigh, RegSubAddressLow, RegValueHigh, RegValueLow); + } +#endif + + data[0] = RegAddress; + data[1] = RegSubAddressHigh; + data[2] = RegSubAddressLow; + data[3] = RegValueHigh; + data[4] = RegValueLow; + + I2C_WriteRead(&(m->d),data,5,NULL,0); +} + +static void GetMSP3430Data(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegSubAddressHigh, CARD8 RegSubAddressLow, + CARD8 *RegValueHigh, CARD8 *RegValueLow) +{ + I2CByte send[3]; + I2CByte receive[2]; + + send[0] = RegAddress; + send[1] = RegSubAddressHigh; + send[2] = RegSubAddressLow; + + I2C_WriteRead(&(m->d), send, 3, receive, 2); + + *RegValueHigh = receive[0]; + *RegValueLow = receive[1]; +} + +#if __MSPDEBUG__ > 2 +static void MSP3430DumpStatus(MSP3430Ptr m) +{ +CARD8 status_hi, status_lo; +CARD8 subaddr, data[2]; + +GetMSP3430Data(m, RD_DEM, 0x02, 0x00, &status_hi, &status_lo); +xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: SAP(8)=%d mono/NICAM(7)=%d stereo=%d %s O_1=%d O_0=%d 2nd car=%d 1st car=%d\n", + status_hi & 1, (status_lo>>7) & 1, (status_lo>>6)&1, + (status_lo>>5)? ( (status_hi>>1)&1? "bad NICAM reception" : "NICAM" ) : + ((status_hi>>1)&1 ? "bogus" : "ANALOG FM/AM") , + (status_lo>>4)&1, (status_lo>>3)&1,!( (status_lo>>2)&1), !((status_lo>>1)&1)); + +GetMSP3430Data(m, RD_DEM, 0x00, 0x7E, &status_hi, &status_lo); +xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: standard result=0x%02x%02x\n", + status_hi, status_lo); +subaddr=0x0; +I2C_WriteRead(&(m->d), &subaddr, 1, data, 2); +xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: control=0x%02x%02x\n", + data[1], data[0]); +} +#endif + +/* wrapper */ +void InitMSP3430(MSP3430Ptr m) +{ + #if __MSPDEBUG__ > 1 + xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"InitMSP3430(m->connector=%d, m->standard=%d, m->chip_family=%d)\n", + m->connector, m->standard, m->chip_family); + #endif + switch (m->chip_family) { + case MSPFAMILY_34x0G: + InitMSP34xxG(m); + break; + case MSPFAMILY_34x5G: + InitMSP34xxG(m); + break; + case MSPFAMILY_34x5D: + InitMSP34x5D(m); + break; + } +} + +/*----------------------------------------------------------------- +| common functions for all MSP34xx chips +|----------------------------------------------------------------*/ + +MSP3430Ptr DetectMSP3430(I2CBusPtr b, I2CSlaveAddr addr) +{ + MSP3430Ptr m; + I2CByte a; + CARD8 hardware_version, major_revision, product_code, rom_version; + Bool supported; + + m = calloc(1,sizeof(MSP3430Rec)); + if(m == NULL)return NULL; + m->d.DevName = strdup("MSP34xx"); + m->d.SlaveAddr = addr; + m->d.pI2CBus = b; + m->d.NextDev = NULL; + m->d.StartTimeout = b->StartTimeout; + m->d.BitTimeout = b->BitTimeout; + m->d.AcknTimeout = b->AcknTimeout; + m->d.ByteTimeout = b->ByteTimeout; + + if(!I2C_WriteRead(&(m->d), NULL, 0, &a, 1)) + { + free(m->d.DevName); + free(m); + return NULL; + } + + + m->standard=MSP3430_NTSC; + m->connector=MSP3430_CONNECTOR_1; + m->mode=MSPMODE_STEREO_A; /*stereo or chanel A if avail. */ + m->c_format=MSPFORMAT_UNKNOWN; + m->c_standard=MSPSTANDARD_UNKNOWN; + m->c_matrix=m->c_fmmatrix=m->c_source=0; + m->volume=0; + m->recheck=FALSE; + + GetMSP3430Data(m, RD_DSP, 0x00, 0x1E, &hardware_version, &major_revision); + GetMSP3430Data(m, RD_DSP, 0x00, 0x1F, &product_code, &rom_version); + m->hardware_version=hardware_version; + m->major_revision=major_revision; + m->product_code=product_code; + m->rom_version=rom_version; + + m->chip_id=((major_revision << 8) | product_code); + + supported=FALSE; + switch (major_revision) { + case 4: /* 34xxD */ + switch (product_code) { + case 0x05: /* 3405D */ + case 0x0A: /* 3410D */ + case 0x0F: /* 3415D */ + m->chip_family=MSPFAMILY_34x5D; + m->recheck=TRUE; + supported=TRUE; + break; + default: + m->chip_family=MSPFAMILY_34x0D; + } + break; + case 7: /* 34xxG */ + switch(product_code){ + case 0x00: + case 0x0A: + case 0x1E: + case 0x28: + case 0x32: + m->chip_family=MSPFAMILY_34x0G; + supported=TRUE; + break; + case 0x0f: + case 0x19: + case 0x2d: + case 0x37: + case 0x41: + m->chip_family=MSPFAMILY_34x5G; + supported=TRUE; + #ifdef MSP_DEBUG + memset(m->registers_present, 0, 256); + #define A(num) m->registers_present[(num)]=1; + #define B(num1, num2) memset(&(m->registers_present[num1]), 1, num2-num1); + A(0x20) + A(0x30) + A(0x40) + A(0x00) + B(0x01, 0x08) + B(0x0B, 0x0E) + A(0x10) + B(0x12,0x14) + A(0x16) + A(0x29) + #undef B + #undef A + #endif + break; + default: + m->chip_family=MSPFAMILY_UNKNOWN; + } + break; + default: + m->chip_family=MSPFAMILY_UNKNOWN; + } + + xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "Found %s%s, rom version 0x%02x, chip_id=0x%04x\n", + MSP_getProductName(m->chip_id), supported?"":" (unsupported)", rom_version, m->chip_id); + + if (!supported) { + free(m->d.DevName); + free(m); + return NULL; + } + if(!I2CDevInit(&(m->d))) + { + free(m->d.DevName); + free(m); + return NULL; + } + + return m; +} + +void ResetMSP3430(MSP3430Ptr m) +{ + /* Reset the MSP3430 */ + SetMSP3430Control(m, 0x00, 0x80, 0x00); + /* Set it back to normal operation */ + SetMSP3430Control(m, 0x00, 0x00, 0x00); + + m->c_format=MSPFORMAT_UNKNOWN; + m->c_standard=MSPSTANDARD_UNKNOWN; + m->c_matrix=m->c_fmmatrix=m->c_source=0; + m->volume=0; +} + +void MSP3430SetVolume (MSP3430Ptr m, CARD8 value) +{ + CARD8 result; +#if 0 + CARD8 old_volume; + GetMSP3430Data(m, RD_DSP, 0x00, 0x00, &old_volume, &result); + xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP3430 result 0x%02x\n", result); +#endif + /* save an extra Get call */ + result=0; + + SetMSP3430Data(m, WR_DSP, 0x00, 0x00, value, result); + + SetMSP3430Data(m, WR_DSP, 0x00, 0x07, value, 0); + m->volume=value; + +#if __MSPDEBUG__ > 2 + MSP3430DumpStatus(m); + __MSPBEEP + GetMSP3430Data(m, RD_DSP, 0x00, 0x00, &old_volume, &result); + xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP3430 volume 0x%02x\n",value); +#endif +} + + +void MSP3430SetSAP (MSP3430Ptr m, int mode) +{ + xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "Put actual code to change SAP here\n"); + + SetMSP3430Data(m, WR_DSP, 0x00, 0x08, mode & 0xff, 0x20); +} + + +#if 0 +void MSP3430SetSource(MSP3430Ptr m, CARD8 value) +{ + /* Write to DSP, register 0x0008, (loudspeaker channel source/matrix) */ + /* This sets the source to the TV tuner, for stereo operation */ + SetMSP3430Data(m, WR_DSP, 0x00, 0x08, value, 0x20); +} +#endif + + +static const char * +MSP_getProductName (CARD16 product_id) +{ + switch (product_id) { + case 0x0400: return "MSP3400D"; + case 0x040a: return "MSP3410D"; + case 0x0405: return "MSP3405D"; + case 0x040f: return "MSP3415D"; + case 0x0700: return "MSP3400G"; + case 0x070a: return "MSP3410G"; + case 0x071e: return "MSP3430G"; + case 0x0728: return "MSP3440G"; + case 0x0732: return "MSP3450G"; + case 0x070f: return "MSP3415G"; + case 0x0719: return "MSP3425G"; + case 0x072d: return "MSP3445G"; + case 0x0737: return "MSP3455G"; + case 0x0741: return "MSP3465G"; + } + return "MSP - unknown type"; +} + +#if __MSPDEBUG__ > 2 +/*puts beep in MSP output + freq = 0x01 - 16Hz ... 0x40 - 1kHz ... 0xff - 4kHz +*/ +void MSPBeep(MSP3430Ptr m, CARD8 freq) { + SetMSP3430Data (m, WR_DSP, 0x00, freq, 0x7f, 0x40); + mpause(100); + SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, 0x00); +} +#endif + +void mpause(int milliseconds) { + int i,m; + m=milliseconds/20; + for (i=0;i<m;i++) usleep(20000); +} + +/*----------------------------------------------------------------- +| specific functions for all MSP34xxG chips +|----------------------------------------------------------------*/ + +void InitMSP34xxG(MSP3430Ptr m) +{ + + #if __MSPDEBUG__ > 1 + xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"InitMSP34xxG(m->connector=%d, m->standard=%d, m->chip_family=%d)\n", + m->connector, m->standard, m->chip_family); + #endif + /* Reset MSP3430 */ + SetMSP3430Control(m, 0x00, 0x80, 0x00); + /* Set it back to normal operation */ + SetMSP3430Control(m, 0x00, 0x00, 0x00); + + /*set MODUS register */ + /* bits: 0 - automatic sound detection */ + /* 1 - enable STATUS change */ + /* 12 - detect 6.5 Mhz carrier as D/K1, D/K2 or D/K NICAM (does not seem to work ) */ + /* 13 - detect 4.5 Mhz carrier as BTSC */ + if ( (m->standard & 0xff) == MSP3430_PAL ) + { + SetMSP3430Data(m, WR_DEM, 0x00, 0x30, 0x30, 0x03|0x08); /* make O_ pins tristate */ + /* PAL standard */ + SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x01); /* possibly wrong */ + } else { + SetMSP3430Data(m, WR_DEM, 0x00, 0x30, 0x20, 0x03|0x08); + /* standard selection is M-BTSC-Stereo */ + SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x20); + } + + switch(m->connector){ + case MSP3430_CONNECTOR_1: + SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x03, 0x20); + break; + case MSP3430_CONNECTOR_2: + /* this has not been checked yet.. could be bogus */ + /* SCART Input Prescale: 0 dB gain */ + SetMSP3430Data(m, WR_DSP, 0x00, 0x0d, 0x19, 0x00); + SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x02, 0x20); + break; + case MSP3430_CONNECTOR_3: + default: + /* SCART Input Prescale: 0 dB gain */ + SetMSP3430Data(m, WR_DSP, 0x00, 0x0d, 0x19, 0x00); + + SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x02, 0x20); + break; + } + + switch(m->standard){ + case MSP3430_PAL: + SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03); + SetMSP3430Data(m, WR_DSP, 0x00, 0x10, 0x00, 0x5a); + SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x03); + /* Set volume to FAST_MUTE. */ + SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00); + break; + case MSP3430_PAL_DK1: + SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03); + SetMSP3430Data(m, WR_DSP, 0x00, 0x10, 0x00, 0x5a); + SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x04); + /* Set volume to FAST_MUTE. */ + SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00); + break; + case MSP3430_SECAM: /* is this right ? */ + case MSP3430_NTSC: + /* Write to DSP, register 0x000E, (prescale FM/FM matrix) */ + SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03); + + /* Set volume to FAST_MUTE. */ + SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00); + break; + } + +} + +/*----------------------------------------------------------------- +| specific functions for all MSP34x5D chips +|----------------------------------------------------------------*/ + +void InitMSP34x5D(MSP3430Ptr m) +{ +int count; +CARD8 high,low; +CARD16 result,standard; +CARD16 peak; + + +if (m->c_format==MSPFORMAT_UNKNOWN) ResetMSP3430(m); +else { + /*mute volume*/ + SetMSP3430Data (m, WR_DSP, 0x00, 0x00, 0x00, 0x00); +} + + + + switch(m->connector){ + case MSP3430_CONNECTOR_2: + case MSP3430_CONNECTOR_3: + if (m->c_format!=MSPFORMAT_SCART) { + /* SCART Input Prescale: 0 dB gain */ + SetMSP3430Data (m, WR_DSP, 0x00, 0x0d, 0x19, 0x00); + /* this has not been checked yet.. could be bogus */ + m->c_format=MSPFORMAT_SCART; /*stereo*/ + } + break; + case MSP3430_CONNECTOR_1: + default: + + switch ( m->standard & 0x00ff ) { + case MSP3430_PAL: + switch( m->standard ) { + case MSP3430_PAL_DK1: + standard=MSPSTANDARD_FM_DK1; + break; +/* case MSP3430_PAL_DK2: + standard=MSPSTANDARD_FM_DK2; + break; + case MSP3430_PAL_BG: + may be FM stereo (Germany) or FM NICAM (Scandinavia,spain) + standard=MSPSTANDARD_AUTO; + break; +*/ + default: + standard=MSPSTANDARD_AUTO; + } + break; + case MSP3430_SECAM: + standard=MSPSTANDARD_AUTO; + case MSP3430_NTSC: + /* Only MSP34x5 supported format - Korean NTSC-M*/ + standard=MSPSTANDARD_FM_M; + default: + standard=MSPSTANDARD_AUTO; + } + + /*no NICAM support in MSP3410D - force to autodetect*/ + if ((m->chip_id==0x405) && (standard>=MSPSTANDARD_NICAM_BG)) + standard=MSPSTANDARD_AUTO; + + if (m->c_standard != standard) { + + SetMSP3430Data (m, WR_DEM, 0x00, 0x20, standard>>8, standard & 0xFF); + if (standard==MSPSTANDARD_AUTO) { + count = 50; /* time shouldn't exceed 1s, just in case */ + do { + usleep(20000); + GetMSP3430Data (m, RD_DEM, 0x00, 0x7e, &high, &low); + result = ( high << 8 ) | low; + --count; + } while( result > 0x07ff && count > 0 ); + + if ((result > MSPSTANDARD_AUTO)) + standard=result; + else standard=MSPSTANDARD_UNKNOWN; +#if __MSPDEBUG__ > 1 + xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Detected audio standard: %d\n",result); +#endif + /* result = MSPSTANDARD_NICAM_L can be one of: + SECAM_L - MSPSTANDARD_NICAM_L + D/K1 - MSPSTANDARD_FM_DK1 + D/K2 - MSPSTANDARD_FM_DK2 + D/K-NICAM - MSPSTANDARD_NICAM_DK*/ + if( standard == MSPSTANDARD_NICAM_L ) { + if ((m->standard & 0x00ff)==MSP3430_PAL) { + /* force PAL D/K */ + standard=MSPSTANDARD_FM_DK1; + SetMSP3430Data (m, WR_DEM, 0x00, 0x20, standard>>8, standard & 0xFF); +#if __MSPDEBUG__ > 1 + xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO, "Detected 6.5MHz carrier - forced to D/K1 !!!\n" ); +#endif + } + } + } + m->c_standard=standard; + } /*end - standard changed*/ + else { + if (standard<MSPSTANDARD_NICAM_BG) { + /* get old value of ident. mode register*/ + GetMSP3430Data (m, RD_DSP, 0x00, 0x15, &high, &low); + /* reset Ident-Filter */ + SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, 0x3F); + /* put back old value to ident. mode register*/ + SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, low); + } + } + + if (standard<=MSPSTANDARD_AUTO) { + m->c_format=MSPFORMAT_1xFM; + } + else if (standard<MSPSTANDARD_NICAM_BG) { + /* set FM prescale */ + SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x30, 0); + /* set FM deemphasis*/ + SetMSP3430Data (m, WR_DSP, 0x00, 0x0f, ((standard==MSPSTANDARD_FM_M)?0:1), 0); + + /* check if FM2 carrier is present */ + /*turn off FM DC Notch*/ + SetMSP3430Data (m, WR_DSP, 0x00, 0x17, 0x00, 0x3f); + /*matrix source for Quasi-Peak Detector - stereo: ch2->L ch1->R*/ + SetMSP3430Data (m, WR_DSP, 0x00, 0x0c, 0x00, 0x20); + + mpause(250); + GetMSP3430Data (m, RD_DSP, 0x00, 0x1A, &high, &low); + peak = (high << 8) | low; +#if __MSPDEBUG__ > 1 + xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Second carrier Quasi-Peak detection: %d\n",peak); +#endif + /*turn on FM DC Notch*/ + SetMSP3430Data (m, WR_DSP, 0x00, 0x17, 0x00, 0x00); + + if (peak<5) { + /* if second carrier not detected - only mono from first carrier*/ + m->c_format=MSPFORMAT_1xFM; + } + else { + m->c_format=MSPFORMAT_2xFM; + /*start of FM identification process - FM_WAIT + wait at least 0.5s - used 1s - gives beter resolution*/ + mpause(1000); + } + } + else { + if (standard==MSPSTANDARD_NICAM_L) { + m->c_format=MSPFORMAT_NICAM_AM; + /* set AM prescale */ + SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x7C, 0); + } + else { + m->c_format=MSPFORMAT_NICAM_FM; + /* set FM prescale */ + SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x30, 0); + } + /* set FM deemphasis*/ + SetMSP3430Data (m, WR_DSP, 0x00, 0x0f, 0x00, 0); + /* set NICAM prescale to 0dB */ + SetMSP3430Data (m, WR_DSP, 0x00, 0x10, 0x20, 0); + } + + break; + } /*end - case conector*/ + + CheckModeMSP34x5D(m); + + /* Set volume to FAST_MUTE. */ + /*SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);*/ + /*set volume*/ + MSP3430SetVolume(m,m->volume); + + __MSPBEEP + + +} /* EnableMSP34x5D ()... */ + + + + +void CheckModeMSP34x5D(MSP3430Ptr m) { + const char stereo_on=25; + const char stereo_off=20; + const char dual_on=-stereo_on; + const char dual_off=-stereo_off; + char detect; + CARD8 matrix, fmmatrix, source, high, low; + + fmmatrix=0; /*no matrix*/ + source=0; /*FM*/ + switch (m->c_format) { + case MSPFORMAT_NICAM_FM: + case MSPFORMAT_NICAM_AM: + case MSPFORMAT_SCART: + source=( (m->c_format == MSPFORMAT_SCART)?2:1 ); + switch (m->mode) { + case MSPMODE_MONO: + matrix=0x30; /*MONO*/ + break; + case MSPMODE_A: + matrix=0x00; /*A*/ + break; + case MSPMODE_B: + matrix=0x10; /*B*/ + break; + default: + matrix=0x20; /*STEREO*/ + break; + } + break; + default: + case MSPFORMAT_1xFM: + matrix=0x00; /*A*/ + break; + case MSPFORMAT_2xFM: + switch (m->mode) { + case MSPMODE_MONO: + matrix=0x30; /*MONO*/ + break; + case MSPMODE_STEREO: + matrix=0x20; /*STEREO*/ + fmmatrix=((m->c_standard==MSPSTANDARD_FM_M)?2:1); + break; + case MSPMODE_AB: + matrix=0x20; /*STEREO*/ + break; + case MSPMODE_A: + matrix=0x00; /*A*/ + break; + case MSPMODE_B: + matrix=0x10; /*B*/ + break; + default: + /*FM_IDENT_CHECK*/ + GetMSP3430Data (m, RD_DSP, 0x00, 0x18, &high, &low); + detect=(char)high; +#if __MSPDEBUG__ > 1 + xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Stereo Detection Register: %d\n",detect); +#endif + if (detect>=((m->c_mode==MSPMODE_STEREO)?stereo_off:stereo_on)) { + m->c_mode=MSPMODE_STEREO; + matrix=0x20; /*STEREO*/ + fmmatrix=((m->c_standard==MSPSTANDARD_FM_M)?2:1); + } + else if (detect<=((m->c_mode==MSPMODE_AB)?dual_off:dual_on)) { + m->c_mode=MSPMODE_AB; + switch (m->mode) { + case MSPMODE_STEREO_AB: matrix=0x20; break; + case MSPMODE_STEREO_B: matrix=0x10; break; + default: + case MSPMODE_A: matrix=0x00; break; + } + } + else { + m->c_mode=MSPMODE_MONO; + matrix=0x30; /*MONO*/ + } + break; + } /* end - case mode*/ + break; + } + + if (m->c_fmmatrix != fmmatrix) { + GetMSP3430Data (m, RD_DSP, 0x00, 0x0e, &high, &low); + SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, high, fmmatrix); + m->c_fmmatrix = fmmatrix; + } + + if ((m->c_matrix != matrix) || (m->c_source != source)) { + /*set chanel source and matrix for loudspeaker*/ + SetMSP3430Data (m, WR_DSP, 0x00, 0x08, source, matrix); + + m->c_matrix = matrix; + m->c_source = source; + } + + if ( ((m->c_format) & 0xF0) == MSPFORMAT_NICAM) + SetMSP3430Data (m, WR_DEM, 0x00, 0x21, 0, 1); + +#if __MSPDEBUG__ > 0 + char *msg; + switch (matrix) { + case 0x30: /*MONO*/ + msg="MONO"; + break; + case 0x00: /*LEFT*/ + msg="MONO/CHANNEL_1"; + break; + case 0x10: /*RIGHT*/ + msg="MONO/CHANNEL_2"; + break; + case 0x20: /*LEFT*/ + msg="STEREO"; + break; + default: + msg="unknown"; + break; + } + xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Audio mode set to: %s\n",msg); +#endif +} + diff --git a/xorg-server/hw/xfree86/loader/loadmod.c b/xorg-server/hw/xfree86/loader/loadmod.c index a21f43d63..c697d74ed 100644 --- a/xorg-server/hw/xfree86/loader/loadmod.c +++ b/xorg-server/hw/xfree86/loader/loadmod.c @@ -437,14 +437,11 @@ FindModule(const char *module, const char *dirname, const char **subdirlist, PatternPtr patterns) { char buf[PATH_MAX + 1]; - char *dirpath = NULL; char *name = NULL; - int dirlen; const char **subdirs = NULL; const char **s; - dirpath = (char *)dirname; - if (strlen(dirpath) > PATH_MAX) + if (strlen(dirname) > PATH_MAX) return NULL; subdirs = InitSubdirs(subdirlist); @@ -452,17 +449,15 @@ FindModule(const char *module, const char *dirname, const char **subdirlist, return NULL; for (s = subdirs; *s; s++) { - if ((dirlen = strlen(dirpath) + strlen(*s)) > PATH_MAX) + if ((strlen(dirname) + strlen(*s)) > PATH_MAX) continue; - strcpy(buf, dirpath); + strcpy(buf, dirname); strcat(buf, *s); if ((name = FindModuleInSubdir(buf, module))) break; } FreeSubdirs(subdirs); - if (dirpath != dirname) - free(dirpath); return name; } diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c index 953215196..da9db3460 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.c +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c @@ -481,7 +481,7 @@ static void xf86OutputSetMonitor (xf86OutputPtr output) { char *option_name; - char *monitor; + const char *monitor; if (!output->name) return; @@ -561,7 +561,7 @@ xf86OutputIgnored (xf86OutputPtr output) return xf86ReturnOptValBool (output->options, OPTION_IGNORE, FALSE); } -static char *direction[4] = { +static const char *direction[4] = { "normal", "left", "inverted", @@ -3063,13 +3063,13 @@ xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) return mon; } -static char *_xf86ConnectorNames[] = { +static const char *_xf86ConnectorNames[] = { "None", "VGA", "DVI-I", "DVI-D", "DVI-A", "Composite", "S-Video", "Component", "LFP", "Proprietary", "HDMI", "DisplayPort", }; -char * +const char * xf86ConnectorGetName(xf86ConnectorType connector) { return _xf86ConnectorNames[connector]; diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.h b/xorg-server/hw/xfree86/modes/xf86Crtc.h index 716499f8d..8d4a08938 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.h +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.h @@ -900,7 +900,7 @@ xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen); /* * Get a standard string name for a connector type */ -extern _X_EXPORT char * +extern _X_EXPORT const char * xf86ConnectorGetName(xf86ConnectorType connector); /* diff --git a/xorg-server/hw/xfree86/modes/xf86EdidModes.c b/xorg-server/hw/xfree86/modes/xf86EdidModes.c index 86065f869..0100d2a59 100644 --- a/xorg-server/hw/xfree86/modes/xf86EdidModes.c +++ b/xorg-server/hw/xfree86/modes/xf86EdidModes.c @@ -230,7 +230,7 @@ static Bool quirk_dvi_single_link(int scrnIndex, xf86MonPtr DDC) typedef struct { Bool (*detect) (int scrnIndex, xf86MonPtr DDC); ddc_quirk_t quirk; - char *description; + const char *description; } ddc_quirk_map_t; static const ddc_quirk_map_t ddc_quirks[] = { diff --git a/xorg-server/hw/xfree86/modes/xf86Modes.c b/xorg-server/hw/xfree86/modes/xf86Modes.c index dcd3a2805..49cc14992 100644 --- a/xorg-server/hw/xfree86/modes/xf86Modes.c +++ b/xorg-server/hw/xfree86/modes/xf86Modes.c @@ -272,7 +272,7 @@ xf86ModesEqual(const DisplayModeRec *pMode1, const DisplayModeRec *pMode2) } static void -add(char **p, char *new) +add(char **p, const char *new) { *p = xnfrealloc(*p, strlen(*p) + strlen(new) + 2); strcat(*p, " "); @@ -599,7 +599,7 @@ xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, if (mode->status != MODE_OK) { if (verbose) { - char *type = ""; + const char *type = ""; if (mode->type & M_T_BUILTIN) type = "built-in "; else if (mode->type & M_T_DEFAULT) diff --git a/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c b/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c index b58d6a790..7079d62b4 100644 --- a/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c +++ b/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c @@ -446,7 +446,7 @@ xf86OpenSyscons() } close(fd); - sprintf(vtname, "/dev/ttyv%01x", xf86Info.vtno - 1); + snprintf(vtname, sizeof(vtname), "/dev/ttyv%01x", xf86Info.vtno - 1); if ((fd = open(vtname, SYSCONS_CONSOLE_MODE, 0)) < 0) { FatalError("xf86OpenSyscons: Cannot open %s (%s)", @@ -550,13 +550,13 @@ xf86OpenPcvt() } close(fd); - sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1); + snprintf(vtname, sizeof(vtname), "%s%01x", vtprefix, xf86Info.vtno - 1); if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) { ErrorF("xf86OpenPcvt: Cannot open %s (%s)", vtname, strerror(errno)); xf86Info.vtno = initialVT; - sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1); + snprintf(vtname, sizeof(vtname), "%s%01x", vtprefix, xf86Info.vtno - 1); if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) { FatalError("xf86OpenPcvt: Cannot open %s (%s)", vtname, strerror(errno)); @@ -602,9 +602,9 @@ xf86OpenWScons() /* XXX Is this ok? */ for (i = 0; i < 8; i++) { #if defined(__NetBSD__) - sprintf(ttyname, "/dev/ttyE%d", i); + snprintf(ttyname, sizeof(ttyname), "/dev/ttyE%d", i); #elif defined(__OpenBSD__) - sprintf(ttyname, "/dev/ttyC%x", i); + snprintf(ttyname, sizeof(ttyname), "/dev/ttyC%x", i); #endif if ((fd = open(ttyname, 2)) != -1) break; diff --git a/xorg-server/hw/xfree86/os-support/bus/Sbus.c b/xorg-server/hw/xfree86/os-support/bus/Sbus.c index 7c4888126..c02d2cd55 100644 --- a/xorg-server/hw/xfree86/os-support/bus/Sbus.c +++ b/xorg-server/hw/xfree86/os-support/bus/Sbus.c @@ -1,688 +1,688 @@ -/*
- * SBUS and OpenPROM access functions.
- *
- * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#ifdef sun
-#include <sys/utsname.h>
-#endif
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-
-#include "xf86sbusBus.h"
-#include "xf86Sbus.h"
-
-int promRootNode;
-
-static int promFd = -1;
-static int promCurrentNode;
-static int promOpenCount = 0;
-static int promP1275 = -1;
-#define MAX_PROP 128
-#define MAX_VAL (4096-128-4)
-static struct openpromio *promOpio;
-
-sbusDevicePtr *xf86SbusInfo = NULL;
-
-struct sbus_devtable sbusDeviceTable[] = {
- { SBUS_DEVICE_BW2, FBTYPE_SUN2BW, "bwtwo", "sunbw2", "Sun Monochrome (bwtwo)" },
- { SBUS_DEVICE_CG2, FBTYPE_SUN2COLOR, "cgtwo", NULL, "Sun Color2 (cgtwo)" },
- { SBUS_DEVICE_CG3, FBTYPE_SUN3COLOR, "cgthree", "suncg3", "Sun Color3 (cgthree)" },
- { SBUS_DEVICE_CG4, FBTYPE_SUN4COLOR, "cgfour", NULL, "Sun Color4 (cgfour)" },
- { SBUS_DEVICE_CG6, FBTYPE_SUNFAST_COLOR, "cgsix", "suncg6", "Sun GX" },
- { SBUS_DEVICE_CG8, FBTYPE_MEMCOLOR, "cgeight", NULL, "Sun CG8/RasterOps" },
- { SBUS_DEVICE_CG12, FBTYPE_SUNGP3, "cgtwelve", NULL, "Sun GS (cgtwelve)" },
- { SBUS_DEVICE_CG14, FBTYPE_MDICOLOR, "cgfourteen", "suncg14", "Sun SX" },
- { SBUS_DEVICE_GT, FBTYPE_SUNGT, "gt", NULL, "Sun Graphics Tower" },
- { SBUS_DEVICE_MGX, -1, "mgx", NULL, "Quantum 3D MGXplus" },
- { SBUS_DEVICE_LEO, FBTYPE_SUNLEO, "leo", "sunleo", "Sun ZX or Turbo ZX" },
- { SBUS_DEVICE_TCX, FBTYPE_TCXCOLOR, "tcx", "suntcx", "Sun TCX" },
- { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "ffb", "sunffb", "Sun FFB" },
- { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "afb", "sunffb", "Sun Elite3D" },
- { 0, 0, NULL }
-};
-
-int
-promGetSibling(int node)
-{
- promOpio->oprom_size = sizeof(int);
-
- if (node == -1) return 0;
- *(int *)promOpio->oprom_array = node;
- if (ioctl(promFd, OPROMNEXT, promOpio) < 0)
- return 0;
- promCurrentNode = *(int *)promOpio->oprom_array;
- return *(int *)promOpio->oprom_array;
-}
-
-int
-promGetChild(int node)
-{
- promOpio->oprom_size = sizeof(int);
-
- if (!node || node == -1) return 0;
- *(int *)promOpio->oprom_array = node;
- if (ioctl(promFd, OPROMCHILD, promOpio) < 0)
- return 0;
- promCurrentNode = *(int *)promOpio->oprom_array;
- return *(int *)promOpio->oprom_array;
-}
-
-char *
-promGetProperty(const char *prop, int *lenp)
-{
- promOpio->oprom_size = MAX_VAL;
-
- strcpy(promOpio->oprom_array, prop);
- if (ioctl(promFd, OPROMGETPROP, promOpio) < 0)
- return 0;
- if (lenp) *lenp = promOpio->oprom_size;
- return promOpio->oprom_array;
-}
-
-int
-promGetBool(const char *prop)
-{
- promOpio->oprom_size = 0;
-
- *(int *)promOpio->oprom_array = 0;
- for (;;) {
- promOpio->oprom_size = MAX_PROP;
- if (ioctl(promFd, OPROMNXTPROP, promOpio) < 0)
- return 0;
- if (!promOpio->oprom_size)
- return 0;
- if (!strcmp(promOpio->oprom_array, prop))
- return 1;
- }
-}
-
-#define PROM_NODE_SIBLING 0x01
-#define PROM_NODE_PREF 0x02
-#define PROM_NODE_SBUS 0x04
-#define PROM_NODE_EBUS 0x08
-#define PROM_NODE_PCI 0x10
-
-static int
-promSetNode(sbusPromNodePtr pnode)
-{
- int node;
-
- if (!pnode->node || pnode->node == -1)
- return -1;
- if (pnode->cookie[0] & PROM_NODE_SIBLING)
- node = promGetSibling(pnode->cookie[1]);
- else
- node = promGetChild(pnode->cookie[1]);
- if (pnode->node != node)
- return -1;
- return 0;
-}
-
-static void
-promIsP1275(void)
-{
-#ifdef linux
- FILE *f;
- char buffer[1024];
-
- if (promP1275 != -1)
- return;
- promP1275 = 0;
- f = fopen("/proc/cpuinfo","r");
- if (!f) return;
- while (fgets(buffer, 1024, f) != NULL)
- if (!strncmp (buffer, "type", 4) && strstr (buffer, "sun4u")) {
- promP1275 = 1;
- break;
- }
- fclose(f);
-#elif defined(sun)
- struct utsname buffer;
-
- if ((uname(&buffer) >= 0) && !strcmp(buffer.machine, "sun4u"))
- promP1275 = TRUE;
- else
- promP1275 = FALSE;
-#elif defined(__FreeBSD__)
- promP1275 = TRUE;
-#else
-#error Missing promIsP1275() function for this OS
-#endif
-}
-
-void
-sparcPromClose(void)
-{
- if (promOpenCount > 1) {
- promOpenCount--;
- return;
- }
- if (promFd != -1) {
- close(promFd);
- promFd = -1;
- }
- free(promOpio);
- promOpio = NULL;
- promOpenCount = 0;
-}
-
-int
-sparcPromInit(void)
-{
- if (promOpenCount) {
- promOpenCount++;
- return 0;
- }
- promFd = open("/dev/openprom", O_RDONLY, 0);
- if (promFd == -1)
- return -1;
- promOpio = (struct openpromio *)malloc(4096);
- if (!promOpio) {
- sparcPromClose();
- return -1;
- }
- promRootNode = promGetSibling(0);
- if (!promRootNode) {
- sparcPromClose();
- return -1;
- }
- promIsP1275();
- promOpenCount++;
-
- return 0;
-}
-
-char *
-sparcPromGetProperty(sbusPromNodePtr pnode, const char *prop, int *lenp)
-{
- if (promSetNode(pnode))
- return NULL;
- return promGetProperty(prop, lenp);
-}
-
-int
-sparcPromGetBool(sbusPromNodePtr pnode, const char *prop)
-{
- if (promSetNode(pnode))
- return 0;
- return promGetBool(prop);
-}
-
-static char *
-promWalkGetDriverName(int node, int oldnode)
-{
- int nextnode;
- int len;
- char *prop;
- int devId, i;
-
- prop = promGetProperty("device_type", &len);
- if (prop && (len > 0)) do {
- if (!strcmp(prop, "display")) {
- prop = promGetProperty("name", &len);
- if (!prop || len <= 0)
- break;
- while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',')
- prop++;
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (!strcmp(prop, sbusDeviceTable[i].promName))
- break;
- devId = sbusDeviceTable[i].devId;
- if (!devId)
- break;
- if (sbusDeviceTable[i].driverName)
- return sbusDeviceTable[i].driverName;
- }
- } while (0);
-
- nextnode = promGetChild(node);
- if (nextnode) {
- char *name;
- name = promWalkGetDriverName(nextnode, node);
- if (name)
- return name;
- }
-
- nextnode = promGetSibling(node);
- if (nextnode)
- return promWalkGetDriverName(nextnode, node);
- return NULL;
-}
-
-char *
-sparcDriverName(void)
-{
- char *name;
-
- if (sparcPromInit() < 0)
- return NULL;
- promGetSibling(0);
- name = promWalkGetDriverName(promRootNode, 0);
- sparcPromClose();
- return name;
-}
-
-static void
-promWalkAssignNodes(int node, int oldnode, int flags, sbusDevicePtr *devicePtrs)
-{
- int nextnode;
- int len, sbus = flags & PROM_NODE_SBUS;
- char *prop;
- int devId, i, j;
- sbusPromNode pNode, pNode2;
-
- prop = promGetProperty("device_type", &len);
- if (prop && (len > 0)) do {
- if (!strcmp(prop, "display")) {
- prop = promGetProperty("name", &len);
- if (!prop || len <= 0)
- break;
- while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',')
- prop++;
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (!strcmp(prop, sbusDeviceTable[i].promName))
- break;
- devId = sbusDeviceTable[i].devId;
- if (!devId)
- break;
- if (!sbus) {
- if (devId == SBUS_DEVICE_FFB) {
- /*
- * All /SUNW,ffb outside of SBUS tree come before all
- * /SUNW,afb outside of SBUS tree in Linux.
- */
- if (!strcmp(prop, "afb"))
- flags |= PROM_NODE_PREF;
- } else if (devId != SBUS_DEVICE_CG14)
- break;
- }
- for (i = 0; i < 32; i++) {
- if (!devicePtrs[i] || devicePtrs[i]->devId != devId)
- continue;
- if (devicePtrs[i]->node.node) {
- if ((devicePtrs[i]->node.cookie[0] & ~PROM_NODE_SIBLING) <=
- (flags & ~PROM_NODE_SIBLING))
- continue;
- for (j = i + 1, pNode = devicePtrs[i]->node; j < 32; j++) {
- if (!devicePtrs[j] || devicePtrs[j]->devId != devId)
- continue;
- pNode2 = devicePtrs[j]->node;
- devicePtrs[j]->node = pNode;
- pNode = pNode2;
- }
- }
- devicePtrs[i]->node.node = node;
- devicePtrs[i]->node.cookie[0] = flags;
- devicePtrs[i]->node.cookie[1] = oldnode;
- break;
- }
- break;
- }
- } while (0);
-
- prop = promGetProperty("name", &len);
- if (prop && len > 0) {
- if (!strcmp(prop, "sbus") || !strcmp(prop, "sbi"))
- sbus = PROM_NODE_SBUS;
- }
-
- nextnode = promGetChild(node);
- if (nextnode)
- promWalkAssignNodes(nextnode, node, sbus, devicePtrs);
-
- nextnode = promGetSibling(node);
- if (nextnode)
- promWalkAssignNodes(nextnode, node, PROM_NODE_SIBLING | sbus, devicePtrs);
-}
-
-void
-sparcPromAssignNodes(void)
-{
- sbusDevicePtr psdp, *psdpp;
- int n, holes = 0, i, j;
- FILE *f;
- sbusDevicePtr devicePtrs[32];
-
- memset(devicePtrs, 0, sizeof(devicePtrs));
- for (psdpp = xf86SbusInfo, n = 0; (psdp = *psdpp); psdpp++, n++) {
- if (psdp->fbNum != n)
- holes = 1;
- devicePtrs[psdp->fbNum] = psdp;
- }
- if (holes && (f = fopen("/proc/fb", "r")) != NULL) {
- /* We could not open one of fb devices, check /proc/fb to see what
- * were the types of the cards missed. */
- char buffer[64];
- int fbNum, devId;
- static struct {
- int devId;
- char *prefix;
- } procFbPrefixes[] = {
- { SBUS_DEVICE_BW2, "BWtwo" },
- { SBUS_DEVICE_CG14, "CGfourteen" },
- { SBUS_DEVICE_CG6, "CGsix" },
- { SBUS_DEVICE_CG3, "CGthree" },
- { SBUS_DEVICE_FFB, "Creator" },
- { SBUS_DEVICE_FFB, "Elite 3D" },
- { SBUS_DEVICE_LEO, "Leo" },
- { SBUS_DEVICE_TCX, "TCX" },
- { 0, NULL },
- };
-
- while (fscanf(f, "%d %63s\n", &fbNum, buffer) == 2) {
- for (i = 0; procFbPrefixes[i].devId; i++)
- if (! strncmp(procFbPrefixes[i].prefix, buffer,
- strlen(procFbPrefixes[i].prefix)))
- break;
- devId = procFbPrefixes[i].devId;
- if (! devId) continue;
- if (devicePtrs[fbNum]) {
- if (devicePtrs[fbNum]->devId != devId)
- xf86ErrorF("Inconsistent /proc/fb with FBIOGATTR\n");
- } else if (!devicePtrs[fbNum]) {
- devicePtrs[fbNum] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
- psdp->devId = devId;
- psdp->fbNum = fbNum;
- psdp->fd = -2;
- }
- }
- fclose(f);
- }
- promGetSibling(0);
- promWalkAssignNodes(promRootNode, 0, PROM_NODE_PREF, devicePtrs);
- for (i = 0, j = 0; i < 32; i++)
- if (devicePtrs[i] && devicePtrs[i]->fbNum == -1)
- j++;
- xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (n + j + 1));
- for (i = 0, psdpp = xf86SbusInfo; i < 32; i++)
- if (devicePtrs[i]) {
- if (devicePtrs[i]->fbNum == -1) {
- memmove(psdpp + 1, psdpp, sizeof(psdpp) * (n + 1));
- *psdpp = devicePtrs[i];
- } else
- n--;
- }
-}
-
-static char *
-promGetReg(int type)
-{
- char *prop;
- int len;
- static char regstr[40];
-
- regstr[0] = 0;
- prop = promGetProperty("reg", &len);
- if (prop && len >= 4) {
- unsigned int *reg = (unsigned int *)prop;
- if (!promP1275 || (type == PROM_NODE_SBUS) || (type == PROM_NODE_EBUS))
- sprintf (regstr, "@%x,%x", reg[0], reg[1]);
- else if (type == PROM_NODE_PCI) {
- if ((reg[0] >> 8) & 7)
- sprintf (regstr, "@%x,%x", (reg[0] >> 11) & 0x1f, (reg[0] >> 8) & 7);
- else
- sprintf (regstr, "@%x", (reg[0] >> 11) & 0x1f);
- } else if (len == 4)
- sprintf (regstr, "@%x", reg[0]);
- else {
- unsigned int regs[2];
-
- /* Things get more complicated on UPA. If upa-portid exists,
- then address is @upa-portid,second-int-in-reg, otherwise
- it is @first-int-in-reg/16,second-int-in-reg (well, probably
- upa-portid always exists, but just to be safe). */
- memcpy (regs, reg, sizeof(regs));
- prop = promGetProperty("upa-portid", &len);
- if (prop && len == 4) {
- reg = (unsigned int *)prop;
- sprintf (regstr, "@%x,%x", reg[0], regs[1]);
- } else
- sprintf (regstr, "@%x,%x", regs[0] >> 4, regs[1]);
- }
- }
- return regstr;
-}
-
-static int
-promWalkNode2Pathname(char *path, int parent, int node, int searchNode, int type)
-{
- int nextnode;
- int len, ntype = type;
- char *prop, *p;
-
- prop = promGetProperty("name", &len);
- *path = '/';
- if (!prop || len <= 0)
- return 0;
- if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
- ntype = PROM_NODE_SBUS;
- else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI)
- ntype = PROM_NODE_EBUS;
- else if (!strcmp(prop, "pci") && !type)
- ntype = PROM_NODE_PCI;
- strcpy (path + 1, prop);
- p = promGetReg(type);
- if (*p)
- strcat (path, p);
- if (node == searchNode)
- return 1;
- nextnode = promGetChild(node);
- if (nextnode &&
- promWalkNode2Pathname(strchr(path, 0), node, nextnode, searchNode, ntype))
- return 1;
- nextnode = promGetSibling(node);
- if (nextnode &&
- promWalkNode2Pathname(path, parent, nextnode, searchNode, type))
- return 1;
- return 0;
-}
-
-char *
-sparcPromNode2Pathname(sbusPromNodePtr pnode)
-{
- char *ret;
-
- if (!pnode->node) return NULL;
- ret = malloc(4096);
- if (!ret) return NULL;
- if (promWalkNode2Pathname(ret, promRootNode, promGetChild(promRootNode), pnode->node, 0))
- return ret;
- free(ret);
- return NULL;
-}
-
-static int
-promWalkPathname2Node(char *name, char *regstr, int parent, int type)
-{
- int len, node, ret;
- char *prop, *p;
-
- for (;;) {
- prop = promGetProperty("name", &len);
- if (!prop || len <= 0)
- return 0;
- if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
- type = PROM_NODE_SBUS;
- else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI)
- type = PROM_NODE_EBUS;
- else if (!strcmp(prop, "pci") && !type)
- type = PROM_NODE_PCI;
- for (node = promGetChild(parent); node; node = promGetSibling(node)) {
- prop = promGetProperty("name", &len);
- if (!prop || len <= 0)
- continue;
- if (*name && strcmp(name, prop))
- continue;
- if (*regstr) {
- p = promGetReg(type);
- if (! *p || strcmp(p + 1, regstr))
- continue;
- }
- break;
- }
- if (!node) {
- for (node = promGetChild(parent); node; node = promGetSibling(node)) {
- ret = promWalkPathname2Node(name, regstr, node, type);
- if (ret) return ret;
- }
- return 0;
- }
- name = strchr(regstr, 0) + 1;
- if (! *name)
- return node;
- p = strchr(name, '/');
- if (p)
- *p = 0;
- else
- p = strchr(name, 0);
- regstr = strchr(name, '@');
- if (regstr)
- *regstr++ = 0;
- else
- regstr = p;
- if (name == regstr)
- return 0;
- parent = node;
- }
-}
-
-int
-sparcPromPathname2Node(const char *pathName)
-{
- int i;
- char *name, *regstr, *p;
-
- i = strlen(pathName);
- name = malloc(i + 2);
- if (! name) return 0;
- strcpy (name, pathName);
- name [i + 1] = 0;
- if (name[0] != '/')
- return 0;
- p = strchr(name + 1, '/');
- if (p)
- *p = 0;
- else
- p = strchr(name, 0);
- regstr = strchr(name, '@');
- if (regstr)
- *regstr++ = 0;
- else
- regstr = p;
- if (name + 1 == regstr)
- return 0;
- promGetSibling(0);
- i = promWalkPathname2Node(name + 1, regstr, promRootNode, 0);
- free(name);
- return i;
-}
-
-pointer
-xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size)
-{
- pointer ret;
- unsigned long pagemask = getpagesize() - 1;
- unsigned long off = offset & ~pagemask;
- unsigned long len = ((offset + size + pagemask) & ~pagemask) - off;
-
- if (psdp->fd == -1) {
- psdp->fd = open(psdp->device, O_RDWR);
- if (psdp->fd == -1)
- return NULL;
- } else if (psdp->fd < 0)
- return NULL;
-
- ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
- psdp->fd, off);
- if (ret == (pointer) -1) {
- ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
- psdp->fd, off);
- }
- if (ret == (pointer) -1)
- return NULL;
-
- return (char *)ret + (offset - off);
-}
-
-void
-xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr, unsigned long size)
-{
- unsigned long mask = getpagesize() - 1;
- unsigned long base = (unsigned long)addr & ~mask;
- unsigned long len = (((unsigned long)addr + size + mask) & ~mask) - base;
-
- munmap ((pointer)base, len);
-}
-
-/* Tell OS that we are driving the HW cursor ourselves. */
-void
-xf86SbusHideOsHwCursor(sbusDevicePtr psdp)
-{
- struct fbcursor fbcursor;
- unsigned char zeros[8];
-
- memset(&fbcursor, 0, sizeof(fbcursor));
- memset(&zeros, 0, sizeof(zeros));
- fbcursor.cmap.count = 2;
- fbcursor.cmap.red = zeros;
- fbcursor.cmap.green = zeros;
- fbcursor.cmap.blue = zeros;
- fbcursor.image = (char *)zeros;
- fbcursor.mask = (char *)zeros;
- fbcursor.size.x = 32;
- fbcursor.size.y = 1;
- fbcursor.set = FB_CUR_SETALL;
- ioctl(psdp->fd, FBIOSCURSOR, &fbcursor);
-}
-
-/* Set HW cursor colormap. */
-void
-xf86SbusSetOsHwCursorCmap(sbusDevicePtr psdp, int bg, int fg)
-{
- struct fbcursor fbcursor;
- unsigned char red[2], green[2], blue[2];
-
- memset(&fbcursor, 0, sizeof(fbcursor));
- red[0] = bg >> 16;
- green[0] = bg >> 8;
- blue[0] = bg;
- red[1] = fg >> 16;
- green[1] = fg >> 8;
- blue[1] = fg;
- fbcursor.cmap.count = 2;
- fbcursor.cmap.red = red;
- fbcursor.cmap.green = green;
- fbcursor.cmap.blue = blue;
- fbcursor.set = FB_CUR_SETCMAP;
- ioctl(psdp->fd, FBIOSCURSOR, &fbcursor);
-}
+/* + * SBUS and OpenPROM access functions. + * + * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#ifdef sun +#include <sys/utsname.h> +#endif +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include "xf86sbusBus.h" +#include "xf86Sbus.h" + +int promRootNode; + +static int promFd = -1; +static int promCurrentNode; +static int promOpenCount = 0; +static int promP1275 = -1; +#define MAX_PROP 128 +#define MAX_VAL (4096-128-4) +static struct openpromio *promOpio; + +sbusDevicePtr *xf86SbusInfo = NULL; + +struct sbus_devtable sbusDeviceTable[] = { + { SBUS_DEVICE_BW2, FBTYPE_SUN2BW, "bwtwo", "sunbw2", "Sun Monochrome (bwtwo)" }, + { SBUS_DEVICE_CG2, FBTYPE_SUN2COLOR, "cgtwo", NULL, "Sun Color2 (cgtwo)" }, + { SBUS_DEVICE_CG3, FBTYPE_SUN3COLOR, "cgthree", "suncg3", "Sun Color3 (cgthree)" }, + { SBUS_DEVICE_CG4, FBTYPE_SUN4COLOR, "cgfour", NULL, "Sun Color4 (cgfour)" }, + { SBUS_DEVICE_CG6, FBTYPE_SUNFAST_COLOR, "cgsix", "suncg6", "Sun GX" }, + { SBUS_DEVICE_CG8, FBTYPE_MEMCOLOR, "cgeight", NULL, "Sun CG8/RasterOps" }, + { SBUS_DEVICE_CG12, FBTYPE_SUNGP3, "cgtwelve", NULL, "Sun GS (cgtwelve)" }, + { SBUS_DEVICE_CG14, FBTYPE_MDICOLOR, "cgfourteen", "suncg14", "Sun SX" }, + { SBUS_DEVICE_GT, FBTYPE_SUNGT, "gt", NULL, "Sun Graphics Tower" }, + { SBUS_DEVICE_MGX, -1, "mgx", NULL, "Quantum 3D MGXplus" }, + { SBUS_DEVICE_LEO, FBTYPE_SUNLEO, "leo", "sunleo", "Sun ZX or Turbo ZX" }, + { SBUS_DEVICE_TCX, FBTYPE_TCXCOLOR, "tcx", "suntcx", "Sun TCX" }, + { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "ffb", "sunffb", "Sun FFB" }, + { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "afb", "sunffb", "Sun Elite3D" }, + { 0, 0, NULL } +}; + +int +promGetSibling(int node) +{ + promOpio->oprom_size = sizeof(int); + + if (node == -1) return 0; + *(int *)promOpio->oprom_array = node; + if (ioctl(promFd, OPROMNEXT, promOpio) < 0) + return 0; + promCurrentNode = *(int *)promOpio->oprom_array; + return *(int *)promOpio->oprom_array; +} + +int +promGetChild(int node) +{ + promOpio->oprom_size = sizeof(int); + + if (!node || node == -1) return 0; + *(int *)promOpio->oprom_array = node; + if (ioctl(promFd, OPROMCHILD, promOpio) < 0) + return 0; + promCurrentNode = *(int *)promOpio->oprom_array; + return *(int *)promOpio->oprom_array; +} + +char * +promGetProperty(const char *prop, int *lenp) +{ + promOpio->oprom_size = MAX_VAL; + + strcpy(promOpio->oprom_array, prop); + if (ioctl(promFd, OPROMGETPROP, promOpio) < 0) + return 0; + if (lenp) *lenp = promOpio->oprom_size; + return promOpio->oprom_array; +} + +int +promGetBool(const char *prop) +{ + promOpio->oprom_size = 0; + + *(int *)promOpio->oprom_array = 0; + for (;;) { + promOpio->oprom_size = MAX_PROP; + if (ioctl(promFd, OPROMNXTPROP, promOpio) < 0) + return 0; + if (!promOpio->oprom_size) + return 0; + if (!strcmp(promOpio->oprom_array, prop)) + return 1; + } +} + +#define PROM_NODE_SIBLING 0x01 +#define PROM_NODE_PREF 0x02 +#define PROM_NODE_SBUS 0x04 +#define PROM_NODE_EBUS 0x08 +#define PROM_NODE_PCI 0x10 + +static int +promSetNode(sbusPromNodePtr pnode) +{ + int node; + + if (!pnode->node || pnode->node == -1) + return -1; + if (pnode->cookie[0] & PROM_NODE_SIBLING) + node = promGetSibling(pnode->cookie[1]); + else + node = promGetChild(pnode->cookie[1]); + if (pnode->node != node) + return -1; + return 0; +} + +static void +promIsP1275(void) +{ +#ifdef linux + FILE *f; + char buffer[1024]; + + if (promP1275 != -1) + return; + promP1275 = 0; + f = fopen("/proc/cpuinfo","r"); + if (!f) return; + while (fgets(buffer, 1024, f) != NULL) + if (!strncmp (buffer, "type", 4) && strstr (buffer, "sun4u")) { + promP1275 = 1; + break; + } + fclose(f); +#elif defined(sun) + struct utsname buffer; + + if ((uname(&buffer) >= 0) && !strcmp(buffer.machine, "sun4u")) + promP1275 = TRUE; + else + promP1275 = FALSE; +#elif defined(__FreeBSD__) + promP1275 = TRUE; +#else +#error Missing promIsP1275() function for this OS +#endif +} + +void +sparcPromClose(void) +{ + if (promOpenCount > 1) { + promOpenCount--; + return; + } + if (promFd != -1) { + close(promFd); + promFd = -1; + } + free(promOpio); + promOpio = NULL; + promOpenCount = 0; +} + +int +sparcPromInit(void) +{ + if (promOpenCount) { + promOpenCount++; + return 0; + } + promFd = open("/dev/openprom", O_RDONLY, 0); + if (promFd == -1) + return -1; + promOpio = (struct openpromio *)malloc(4096); + if (!promOpio) { + sparcPromClose(); + return -1; + } + promRootNode = promGetSibling(0); + if (!promRootNode) { + sparcPromClose(); + return -1; + } + promIsP1275(); + promOpenCount++; + + return 0; +} + +char * +sparcPromGetProperty(sbusPromNodePtr pnode, const char *prop, int *lenp) +{ + if (promSetNode(pnode)) + return NULL; + return promGetProperty(prop, lenp); +} + +int +sparcPromGetBool(sbusPromNodePtr pnode, const char *prop) +{ + if (promSetNode(pnode)) + return 0; + return promGetBool(prop); +} + +static char * +promWalkGetDriverName(int node, int oldnode) +{ + int nextnode; + int len; + char *prop; + int devId, i; + + prop = promGetProperty("device_type", &len); + if (prop && (len > 0)) do { + if (!strcmp(prop, "display")) { + prop = promGetProperty("name", &len); + if (!prop || len <= 0) + break; + while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',') + prop++; + for (i = 0; sbusDeviceTable[i].devId; i++) + if (!strcmp(prop, sbusDeviceTable[i].promName)) + break; + devId = sbusDeviceTable[i].devId; + if (!devId) + break; + if (sbusDeviceTable[i].driverName) + return sbusDeviceTable[i].driverName; + } + } while (0); + + nextnode = promGetChild(node); + if (nextnode) { + char *name; + name = promWalkGetDriverName(nextnode, node); + if (name) + return name; + } + + nextnode = promGetSibling(node); + if (nextnode) + return promWalkGetDriverName(nextnode, node); + return NULL; +} + +char * +sparcDriverName(void) +{ + char *name; + + if (sparcPromInit() < 0) + return NULL; + promGetSibling(0); + name = promWalkGetDriverName(promRootNode, 0); + sparcPromClose(); + return name; +} + +static void +promWalkAssignNodes(int node, int oldnode, int flags, sbusDevicePtr *devicePtrs) +{ + int nextnode; + int len, sbus = flags & PROM_NODE_SBUS; + char *prop; + int devId, i, j; + sbusPromNode pNode, pNode2; + + prop = promGetProperty("device_type", &len); + if (prop && (len > 0)) do { + if (!strcmp(prop, "display")) { + prop = promGetProperty("name", &len); + if (!prop || len <= 0) + break; + while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',') + prop++; + for (i = 0; sbusDeviceTable[i].devId; i++) + if (!strcmp(prop, sbusDeviceTable[i].promName)) + break; + devId = sbusDeviceTable[i].devId; + if (!devId) + break; + if (!sbus) { + if (devId == SBUS_DEVICE_FFB) { + /* + * All /SUNW,ffb outside of SBUS tree come before all + * /SUNW,afb outside of SBUS tree in Linux. + */ + if (!strcmp(prop, "afb")) + flags |= PROM_NODE_PREF; + } else if (devId != SBUS_DEVICE_CG14) + break; + } + for (i = 0; i < 32; i++) { + if (!devicePtrs[i] || devicePtrs[i]->devId != devId) + continue; + if (devicePtrs[i]->node.node) { + if ((devicePtrs[i]->node.cookie[0] & ~PROM_NODE_SIBLING) <= + (flags & ~PROM_NODE_SIBLING)) + continue; + for (j = i + 1, pNode = devicePtrs[i]->node; j < 32; j++) { + if (!devicePtrs[j] || devicePtrs[j]->devId != devId) + continue; + pNode2 = devicePtrs[j]->node; + devicePtrs[j]->node = pNode; + pNode = pNode2; + } + } + devicePtrs[i]->node.node = node; + devicePtrs[i]->node.cookie[0] = flags; + devicePtrs[i]->node.cookie[1] = oldnode; + break; + } + break; + } + } while (0); + + prop = promGetProperty("name", &len); + if (prop && len > 0) { + if (!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) + sbus = PROM_NODE_SBUS; + } + + nextnode = promGetChild(node); + if (nextnode) + promWalkAssignNodes(nextnode, node, sbus, devicePtrs); + + nextnode = promGetSibling(node); + if (nextnode) + promWalkAssignNodes(nextnode, node, PROM_NODE_SIBLING | sbus, devicePtrs); +} + +void +sparcPromAssignNodes(void) +{ + sbusDevicePtr psdp, *psdpp; + int n, holes = 0, i, j; + FILE *f; + sbusDevicePtr devicePtrs[32]; + + memset(devicePtrs, 0, sizeof(devicePtrs)); + for (psdpp = xf86SbusInfo, n = 0; (psdp = *psdpp); psdpp++, n++) { + if (psdp->fbNum != n) + holes = 1; + devicePtrs[psdp->fbNum] = psdp; + } + if (holes && (f = fopen("/proc/fb", "r")) != NULL) { + /* We could not open one of fb devices, check /proc/fb to see what + * were the types of the cards missed. */ + char buffer[64]; + int fbNum, devId; + static struct { + int devId; + char *prefix; + } procFbPrefixes[] = { + { SBUS_DEVICE_BW2, "BWtwo" }, + { SBUS_DEVICE_CG14, "CGfourteen" }, + { SBUS_DEVICE_CG6, "CGsix" }, + { SBUS_DEVICE_CG3, "CGthree" }, + { SBUS_DEVICE_FFB, "Creator" }, + { SBUS_DEVICE_FFB, "Elite 3D" }, + { SBUS_DEVICE_LEO, "Leo" }, + { SBUS_DEVICE_TCX, "TCX" }, + { 0, NULL }, + }; + + while (fscanf(f, "%d %63s\n", &fbNum, buffer) == 2) { + for (i = 0; procFbPrefixes[i].devId; i++) + if (! strncmp(procFbPrefixes[i].prefix, buffer, + strlen(procFbPrefixes[i].prefix))) + break; + devId = procFbPrefixes[i].devId; + if (! devId) continue; + if (devicePtrs[fbNum]) { + if (devicePtrs[fbNum]->devId != devId) + xf86ErrorF("Inconsistent /proc/fb with FBIOGATTR\n"); + } else if (!devicePtrs[fbNum]) { + devicePtrs[fbNum] = psdp = xnfcalloc(sizeof (sbusDevice), 1); + psdp->devId = devId; + psdp->fbNum = fbNum; + psdp->fd = -2; + } + } + fclose(f); + } + promGetSibling(0); + promWalkAssignNodes(promRootNode, 0, PROM_NODE_PREF, devicePtrs); + for (i = 0, j = 0; i < 32; i++) + if (devicePtrs[i] && devicePtrs[i]->fbNum == -1) + j++; + xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (n + j + 1)); + for (i = 0, psdpp = xf86SbusInfo; i < 32; i++) + if (devicePtrs[i]) { + if (devicePtrs[i]->fbNum == -1) { + memmove(psdpp + 1, psdpp, sizeof(psdpp) * (n + 1)); + *psdpp = devicePtrs[i]; + } else + n--; + } +} + +static char * +promGetReg(int type) +{ + char *prop; + int len; + static char regstr[40]; + + regstr[0] = 0; + prop = promGetProperty("reg", &len); + if (prop && len >= 4) { + unsigned int *reg = (unsigned int *)prop; + if (!promP1275 || (type == PROM_NODE_SBUS) || (type == PROM_NODE_EBUS)) + snprintf (regstr, sizeof(regstr), "@%x,%x", reg[0], reg[1]); + else if (type == PROM_NODE_PCI) { + if ((reg[0] >> 8) & 7) + snprintf (regstr, sizeof(regstr), "@%x,%x", (reg[0] >> 11) & 0x1f, (reg[0] >> 8) & 7); + else + snprintf (regstr, sizeof(regstr), "@%x", (reg[0] >> 11) & 0x1f); + } else if (len == 4) + snprintf (regstr, sizeof(regstr), "@%x", reg[0]); + else { + unsigned int regs[2]; + + /* Things get more complicated on UPA. If upa-portid exists, + then address is @upa-portid,second-int-in-reg, otherwise + it is @first-int-in-reg/16,second-int-in-reg (well, probably + upa-portid always exists, but just to be safe). */ + memcpy (regs, reg, sizeof(regs)); + prop = promGetProperty("upa-portid", &len); + if (prop && len == 4) { + reg = (unsigned int *)prop; + snprintf (regstr, sizeof(regstr), "@%x,%x", reg[0], regs[1]); + } else + snprintf (regstr, sizeof(regstr), "@%x,%x", regs[0] >> 4, regs[1]); + } + } + return regstr; +} + +static int +promWalkNode2Pathname(char *path, int parent, int node, int searchNode, int type) +{ + int nextnode; + int len, ntype = type; + char *prop, *p; + + prop = promGetProperty("name", &len); + *path = '/'; + if (!prop || len <= 0) + return 0; + if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type) + ntype = PROM_NODE_SBUS; + else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI) + ntype = PROM_NODE_EBUS; + else if (!strcmp(prop, "pci") && !type) + ntype = PROM_NODE_PCI; + strcpy (path + 1, prop); + p = promGetReg(type); + if (*p) + strcat (path, p); + if (node == searchNode) + return 1; + nextnode = promGetChild(node); + if (nextnode && + promWalkNode2Pathname(strchr(path, 0), node, nextnode, searchNode, ntype)) + return 1; + nextnode = promGetSibling(node); + if (nextnode && + promWalkNode2Pathname(path, parent, nextnode, searchNode, type)) + return 1; + return 0; +} + +char * +sparcPromNode2Pathname(sbusPromNodePtr pnode) +{ + char *ret; + + if (!pnode->node) return NULL; + ret = malloc(4096); + if (!ret) return NULL; + if (promWalkNode2Pathname(ret, promRootNode, promGetChild(promRootNode), pnode->node, 0)) + return ret; + free(ret); + return NULL; +} + +static int +promWalkPathname2Node(char *name, char *regstr, int parent, int type) +{ + int len, node, ret; + char *prop, *p; + + for (;;) { + prop = promGetProperty("name", &len); + if (!prop || len <= 0) + return 0; + if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type) + type = PROM_NODE_SBUS; + else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI) + type = PROM_NODE_EBUS; + else if (!strcmp(prop, "pci") && !type) + type = PROM_NODE_PCI; + for (node = promGetChild(parent); node; node = promGetSibling(node)) { + prop = promGetProperty("name", &len); + if (!prop || len <= 0) + continue; + if (*name && strcmp(name, prop)) + continue; + if (*regstr) { + p = promGetReg(type); + if (! *p || strcmp(p + 1, regstr)) + continue; + } + break; + } + if (!node) { + for (node = promGetChild(parent); node; node = promGetSibling(node)) { + ret = promWalkPathname2Node(name, regstr, node, type); + if (ret) return ret; + } + return 0; + } + name = strchr(regstr, 0) + 1; + if (! *name) + return node; + p = strchr(name, '/'); + if (p) + *p = 0; + else + p = strchr(name, 0); + regstr = strchr(name, '@'); + if (regstr) + *regstr++ = 0; + else + regstr = p; + if (name == regstr) + return 0; + parent = node; + } +} + +int +sparcPromPathname2Node(const char *pathName) +{ + int i; + char *name, *regstr, *p; + + i = strlen(pathName); + name = malloc(i + 2); + if (! name) return 0; + strcpy (name, pathName); + name [i + 1] = 0; + if (name[0] != '/') + return 0; + p = strchr(name + 1, '/'); + if (p) + *p = 0; + else + p = strchr(name, 0); + regstr = strchr(name, '@'); + if (regstr) + *regstr++ = 0; + else + regstr = p; + if (name + 1 == regstr) + return 0; + promGetSibling(0); + i = promWalkPathname2Node(name + 1, regstr, promRootNode, 0); + free(name); + return i; +} + +pointer +xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size) +{ + pointer ret; + unsigned long pagemask = getpagesize() - 1; + unsigned long off = offset & ~pagemask; + unsigned long len = ((offset + size + pagemask) & ~pagemask) - off; + + if (psdp->fd == -1) { + psdp->fd = open(psdp->device, O_RDWR); + if (psdp->fd == -1) + return NULL; + } else if (psdp->fd < 0) + return NULL; + + ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, + psdp->fd, off); + if (ret == (pointer) -1) { + ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, + psdp->fd, off); + } + if (ret == (pointer) -1) + return NULL; + + return (char *)ret + (offset - off); +} + +void +xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr, unsigned long size) +{ + unsigned long mask = getpagesize() - 1; + unsigned long base = (unsigned long)addr & ~mask; + unsigned long len = (((unsigned long)addr + size + mask) & ~mask) - base; + + munmap ((pointer)base, len); +} + +/* Tell OS that we are driving the HW cursor ourselves. */ +void +xf86SbusHideOsHwCursor(sbusDevicePtr psdp) +{ + struct fbcursor fbcursor; + unsigned char zeros[8]; + + memset(&fbcursor, 0, sizeof(fbcursor)); + memset(&zeros, 0, sizeof(zeros)); + fbcursor.cmap.count = 2; + fbcursor.cmap.red = zeros; + fbcursor.cmap.green = zeros; + fbcursor.cmap.blue = zeros; + fbcursor.image = (char *)zeros; + fbcursor.mask = (char *)zeros; + fbcursor.size.x = 32; + fbcursor.size.y = 1; + fbcursor.set = FB_CUR_SETALL; + ioctl(psdp->fd, FBIOSCURSOR, &fbcursor); +} + +/* Set HW cursor colormap. */ +void +xf86SbusSetOsHwCursorCmap(sbusDevicePtr psdp, int bg, int fg) +{ + struct fbcursor fbcursor; + unsigned char red[2], green[2], blue[2]; + + memset(&fbcursor, 0, sizeof(fbcursor)); + red[0] = bg >> 16; + green[0] = bg >> 8; + blue[0] = bg; + red[1] = fg >> 16; + green[1] = fg >> 8; + blue[1] = fg; + fbcursor.cmap.count = 2; + fbcursor.cmap.red = red; + fbcursor.cmap.green = green; + fbcursor.cmap.blue = blue; + fbcursor.set = FB_CUR_SETCMAP; + ioctl(psdp->fd, FBIOSCURSOR, &fbcursor); +} diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_init.c b/xorg-server/hw/xfree86/os-support/linux/lnx_init.c index f18271f38..5f3e3a9fb 100644 --- a/xorg-server/hw/xfree86/os-support/linux/lnx_init.c +++ b/xorg-server/hw/xfree86/os-support/linux/lnx_init.c @@ -146,7 +146,7 @@ xf86OpenConsole(void) i=0; while (vcs[i] != NULL) { - sprintf(vtname, vcs[i], xf86Info.vtno); /* /dev/tty1-64 */ + snprintf(vtname, sizeof(vtname), vcs[i], xf86Info.vtno); /* /dev/tty1-64 */ if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) >= 0) break; i++; diff --git a/xorg-server/hw/xfree86/os-support/solaris/sun_agp.c b/xorg-server/hw/xfree86/os-support/solaris/sun_agp.c index 0331ac1c5..8c4e9f5c1 100644 --- a/xorg-server/hw/xfree86/os-support/solaris/sun_agp.c +++ b/xorg-server/hw/xfree86/os-support/solaris/sun_agp.c @@ -233,7 +233,7 @@ xf86DeallocateGARTMemory(int screenNum, int key) if (!GARTInit(screenNum) || (acquiredScreen != screenNum)) return FALSE; - if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)key) != 0) { + if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)(uintptr_t)key) != 0) { xf86DrvMsg(screenNum, X_WARNING, "xf86DeAllocateGARTMemory: " "deallocation of gart memory with key %d failed\n" "\t(%s)\n", key, strerror(errno)); diff --git a/xorg-server/hw/xfree86/parser/Flags.c b/xorg-server/hw/xfree86/parser/Flags.c index f0a61707b..87fd3edf6 100644 --- a/xorg-server/hw/xfree86/parser/Flags.c +++ b/xorg-server/hw/xfree86/parser/Flags.c @@ -330,7 +330,7 @@ xf86findOption (XF86OptionPtr list, const char *name) * returned. If the option is not found, a NULL is returned. */ -char * +const char * xf86findOptionValue (XF86OptionPtr list, const char *name) { XF86OptionPtr p = xf86findOption (list, name); diff --git a/xorg-server/hw/xfree86/parser/InputClass.c b/xorg-server/hw/xfree86/parser/InputClass.c index 3f801700e..2cdc9125a 100644 --- a/xorg-server/hw/xfree86/parser/InputClass.c +++ b/xorg-server/hw/xfree86/parser/InputClass.c @@ -128,60 +128,70 @@ xf86parseInputClassSection(void) Error(QUOTE_MSG, "MatchProduct"); add_group_entry(&ptr->match_product, xstrtokenize(val.str, TOKEN_SEP)); + free(val.str); break; case MATCH_VENDOR: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchVendor"); add_group_entry(&ptr->match_vendor, xstrtokenize(val.str, TOKEN_SEP)); + free(val.str); break; case MATCH_DEVICE_PATH: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchDevicePath"); add_group_entry(&ptr->match_device, xstrtokenize(val.str, TOKEN_SEP)); + free(val.str); break; case MATCH_OS: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchOS"); add_group_entry(&ptr->match_os, xstrtokenize(val.str, TOKEN_SEP)); + free(val.str); break; case MATCH_PNPID: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchPnPID"); add_group_entry(&ptr->match_pnpid, xstrtokenize(val.str, TOKEN_SEP)); + free(val.str); break; case MATCH_USBID: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchUSBID"); add_group_entry(&ptr->match_usbid, xstrtokenize(val.str, TOKEN_SEP)); + free(val.str); break; case MATCH_DRIVER: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchDriver"); add_group_entry(&ptr->match_driver, xstrtokenize(val.str, TOKEN_SEP)); + free(val.str); break; case MATCH_TAG: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchTag"); add_group_entry(&ptr->match_tag, xstrtokenize(val.str, TOKEN_SEP)); + free(val.str); break; case MATCH_LAYOUT: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchLayout"); add_group_entry(&ptr->match_layout, xstrtokenize(val.str, TOKEN_SEP)); + free(val.str); break; case MATCH_IS_KEYBOARD: if (xf86getSubToken(&(ptr->comment)) != STRING) Error(QUOTE_MSG, "MatchIsKeyboard"); ptr->is_keyboard.set = xf86getBoolValue(&ptr->is_keyboard.val, val.str); + free(val.str); if (!ptr->is_keyboard.set) Error(BOOL_MSG, "MatchIsKeyboard"); break; @@ -190,6 +200,7 @@ xf86parseInputClassSection(void) Error(QUOTE_MSG, "MatchIsPointer"); ptr->is_pointer.set = xf86getBoolValue(&ptr->is_pointer.val, val.str); + free(val.str); if (!ptr->is_pointer.set) Error(BOOL_MSG, "MatchIsPointer"); break; @@ -198,6 +209,7 @@ xf86parseInputClassSection(void) Error(QUOTE_MSG, "MatchIsJoystick"); ptr->is_joystick.set = xf86getBoolValue(&ptr->is_joystick.val, val.str); + free(val.str); if (!ptr->is_joystick.set) Error(BOOL_MSG, "MatchIsJoystick"); break; @@ -206,6 +218,7 @@ xf86parseInputClassSection(void) Error(QUOTE_MSG, "MatchIsTablet"); ptr->is_tablet.set = xf86getBoolValue(&ptr->is_tablet.val, val.str); + free(val.str); if (!ptr->is_tablet.set) Error(BOOL_MSG, "MatchIsTablet"); break; @@ -214,6 +227,7 @@ xf86parseInputClassSection(void) Error(QUOTE_MSG, "MatchIsTouchpad"); ptr->is_touchpad.set = xf86getBoolValue(&ptr->is_touchpad.val, val.str); + free(val.str); if (!ptr->is_touchpad.set) Error(BOOL_MSG, "MatchIsTouchpad"); break; @@ -222,6 +236,7 @@ xf86parseInputClassSection(void) Error(QUOTE_MSG, "MatchIsTouchscreen"); ptr->is_touchscreen.set = xf86getBoolValue(&ptr->is_touchscreen.val, val.str); + free(val.str); if (!ptr->is_touchscreen.set) Error(BOOL_MSG, "MatchIsTouchscreen"); break; diff --git a/xorg-server/hw/xfree86/parser/configProcs.h b/xorg-server/hw/xfree86/parser/configProcs.h index 7d8a8e53a..114cdfe33 100644 --- a/xorg-server/hw/xfree86/parser/configProcs.h +++ b/xorg-server/hw/xfree86/parser/configProcs.h @@ -95,9 +95,9 @@ int xf86getSubToken(char **comment); int xf86getSubTokenWithTab(char **comment, xf86ConfigSymTabRec *tab); void xf86unGetToken(int token); char *xf86tokenString(void); -void xf86parseError(char *format, ...); -void xf86validationError(char *format, ...); -void xf86setSection(char *section); +void xf86parseError(const char *format, ...); +void xf86validationError(const char *format, ...); +void xf86setSection(const char *section); int xf86getStringToken(xf86ConfigSymTabRec *tab); /* write.c */ /* DRI.c */ diff --git a/xorg-server/hw/xfree86/parser/scan.c b/xorg-server/hw/xfree86/parser/scan.c index 99b325717..9099227bb 100644 --- a/xorg-server/hw/xfree86/parser/scan.c +++ b/xorg-server/hw/xfree86/parser/scan.c @@ -90,7 +90,7 @@ #define CONFIG_BUF_LEN 1024 #define CONFIG_MAX_FILES 64 -static int StringToToken (char *, xf86ConfigSymTabRec *); +static int StringToToken (const char *, xf86ConfigSymTabRec *); static struct { FILE *file; @@ -101,8 +101,6 @@ static int builtinIndex = 0; static int configPos = 0; /* current readers position */ static int configLineNo = 0; /* linenumber */ static char *configBuf, *configRBuf; /* buffer for lines */ -static char *configPath; /* path to config file */ -static char *configDirPath; /* path to config dir */ static char *configSection = NULL; /* name of current section being parsed */ static int numFiles = 0; /* number of config files */ static int curFileIndex = 0; /* index of current config file */ @@ -281,8 +279,10 @@ again: if (builtinConfig[builtinIndex] == NULL) ret = NULL; else { - ret = strncpy(configBuf, builtinConfig[builtinIndex], - CONFIG_BUF_LEN); + strlcpy(configBuf, + builtinConfig[builtinIndex], + CONFIG_BUF_LEN); + ret = configBuf; builtinIndex++; } } @@ -800,14 +800,12 @@ AddConfigDirFiles(const char *dirpath, struct dirent **list, int num) "files opened\n"); warnOnce = TRUE; } - free(list[i]); continue; } path = malloc(PATH_MAX + 1); snprintf(path, PATH_MAX + 1, "%s/%s", dirpath, list[i]->d_name); - free(list[i]); file = fopen(path, "r"); if (!file) { free(path); @@ -858,8 +856,10 @@ OpenConfigDir(const char *path, const char *cmdline, const char *projroot, if (!found) { free(dirpath); dirpath = NULL; - free(list); } + while (num--) + free(list[num]); + free(list); } free(pathcopy); @@ -892,7 +892,8 @@ xf86initConfigFiles(void) * of the located files. * * The return value is a pointer to the actual name of the file that was - * opened. When no file is found, the return value is NULL. + * opened. When no file is found, the return value is NULL. The caller should + * free() the returned value. * * The escape sequences allowed in the search path are defined above. * @@ -914,7 +915,7 @@ xf86initConfigFiles(void) "%P/lib/X11/%X" #endif -const char * +char * xf86openConfigFile(const char *path, const char *cmdline, const char *projroot) { if (!path || !path[0]) @@ -923,8 +924,7 @@ xf86openConfigFile(const char *path, const char *cmdline, const char *projroot) projroot = PROJECTROOT; /* Search for a config file */ - configPath = OpenConfigFile(path, cmdline, projroot, XCONFIGFILE); - return configPath; + return OpenConfigFile(path, cmdline, projroot, XCONFIGFILE); } /* @@ -937,12 +937,13 @@ xf86openConfigFile(const char *path, const char *cmdline, const char *projroot) * fails if it is not found. * * The return value is a pointer to the actual name of the direcoty that was - * opened. When no directory is found, the return value is NULL. + * opened. When no directory is found, the return value is NULL. The caller + * should free() the returned value. * * The escape sequences allowed in the search path are defined above. * */ -const char * +char * xf86openConfigDirFiles(const char *path, const char *cmdline, const char *projroot) { @@ -952,8 +953,7 @@ xf86openConfigDirFiles(const char *path, const char *cmdline, projroot = PROJECTROOT; /* Search for the multiconf directory */ - configDirPath = OpenConfigDir(path, cmdline, projroot, XCONFIGDIR); - return configDirPath; + return OpenConfigDir(path, cmdline, projroot, XCONFIGDIR); } void @@ -961,10 +961,6 @@ xf86closeConfigFile (void) { int i; - free (configPath); - configPath = NULL; - free (configDirPath); - configDirPath = NULL; free (configRBuf); configRBuf = NULL; free (configBuf); @@ -990,11 +986,11 @@ xf86setBuiltinConfig(const char *config[]) } void -xf86parseError (char *format,...) +xf86parseError (const char *format,...) { va_list ap; - char *filename = numFiles ? configFiles[curFileIndex].path : - "<builtin configuration>"; + const char *filename = numFiles ? configFiles[curFileIndex].path + : "<builtin configuration>"; ErrorF ("Parse error on line %d of section %s in file %s\n\t", configLineNo, configSection, filename); @@ -1006,11 +1002,11 @@ xf86parseError (char *format,...) } void -xf86validationError (char *format,...) +xf86validationError (const char *format,...) { va_list ap; - char *filename = numFiles ? configFiles[curFileIndex].path : - "<builtin configuration>"; + const char *filename = numFiles ? configFiles[curFileIndex].path + : "<builtin configuration>"; ErrorF ("Data incomplete in file %s\n\t", filename); va_start (ap, format); @@ -1021,7 +1017,7 @@ xf86validationError (char *format,...) } void -xf86setSection (char *section) +xf86setSection (const char *section) { free(configSection); configSection = strdup(section); @@ -1038,7 +1034,7 @@ xf86getStringToken (xf86ConfigSymTabRec * tab) } static int -StringToToken (char *str, xf86ConfigSymTabRec * tab) +StringToToken (const char *str, xf86ConfigSymTabRec * tab) { int i; diff --git a/xorg-server/hw/xfree86/parser/xf86Optrec.h b/xorg-server/hw/xfree86/parser/xf86Optrec.h index 61a8c5ff5..b8e9d6192 100644 --- a/xorg-server/hw/xfree86/parser/xf86Optrec.h +++ b/xorg-server/hw/xfree86/parser/xf86Optrec.h @@ -77,7 +77,7 @@ extern _X_EXPORT char *xf86optionValue(XF86OptionPtr opt); extern _X_EXPORT XF86OptionPtr xf86newOption(char *name, char *value); extern _X_EXPORT XF86OptionPtr xf86nextOption(XF86OptionPtr list); extern _X_EXPORT XF86OptionPtr xf86findOption(XF86OptionPtr list, const char *name); -extern _X_EXPORT char *xf86findOptionValue(XF86OptionPtr list, const char *name); +extern _X_EXPORT const char *xf86findOptionValue(XF86OptionPtr list, const char *name); extern _X_EXPORT XF86OptionPtr xf86optionListCreate(const char **options, int count, int used); extern _X_EXPORT XF86OptionPtr xf86optionListMerge(XF86OptionPtr head, XF86OptionPtr tail); extern _X_EXPORT int xf86nameCompare (const char *s1, const char *s2); diff --git a/xorg-server/hw/xfree86/parser/xf86Parser.h b/xorg-server/hw/xfree86/parser/xf86Parser.h index a8785c5fa..7d4662b98 100644 --- a/xorg-server/hw/xfree86/parser/xf86Parser.h +++ b/xorg-server/hw/xfree86/parser/xf86Parser.h @@ -479,7 +479,7 @@ XF86ConfigRec, *XF86ConfigPtr; typedef struct { int token; /* id of the token */ - char *name; /* pointer to the LOWERCASED name */ + const char *name; /* pointer to the LOWERCASED name */ } xf86ConfigSymTabRec, *xf86ConfigSymTabPtr; @@ -487,10 +487,10 @@ xf86ConfigSymTabRec, *xf86ConfigSymTabPtr; * prototypes for public functions */ extern void xf86initConfigFiles(void); -extern const char *xf86openConfigFile(const char *path, const char *cmdline, - const char *projroot); -extern const char *xf86openConfigDirFiles(const char *path, const char *cmdline, - const char *projroot); +extern char *xf86openConfigFile(const char *path, const char *cmdline, + const char *projroot); +extern char *xf86openConfigDirFiles(const char *path, const char *cmdline, + const char *projroot); extern void xf86setBuiltinConfig(const char *config[]); extern XF86ConfigPtr xf86readConfigFile(void); extern void xf86closeConfigFile(void); diff --git a/xorg-server/hw/xfree86/ramdac/BTPriv.h b/xorg-server/hw/xfree86/ramdac/BTPriv.h index 184b4811c..52737768f 100644 --- a/xorg-server/hw/xfree86/ramdac/BTPriv.h +++ b/xorg-server/hw/xfree86/ramdac/BTPriv.h @@ -6,7 +6,7 @@ #include "BT.h" typedef struct { - char *DeviceName; + const char *DeviceName; } xf86BTramdacInfo; extern xf86BTramdacInfo BTramdacDeviceInfo[]; diff --git a/xorg-server/hw/xfree86/ramdac/IBMPriv.h b/xorg-server/hw/xfree86/ramdac/IBMPriv.h index a33da9106..309a193ad 100644 --- a/xorg-server/hw/xfree86/ramdac/IBMPriv.h +++ b/xorg-server/hw/xfree86/ramdac/IBMPriv.h @@ -6,7 +6,7 @@ #include "IBM.h" typedef struct { - char *DeviceName; + const char *DeviceName; } xf86IBMramdacInfo; extern xf86IBMramdacInfo IBMramdacDeviceInfo[]; diff --git a/xorg-server/hw/xfree86/ramdac/TIPriv.h b/xorg-server/hw/xfree86/ramdac/TIPriv.h index 191c9b5ce..20e07f5cc 100644 --- a/xorg-server/hw/xfree86/ramdac/TIPriv.h +++ b/xorg-server/hw/xfree86/ramdac/TIPriv.h @@ -6,7 +6,7 @@ #include "TI.h" typedef struct { - char *DeviceName; + const char *DeviceName; } xf86TIramdacInfo; extern xf86TIramdacInfo TIramdacDeviceInfo[]; diff --git a/xorg-server/hw/xfree86/utils/gtf/gtf.c b/xorg-server/hw/xfree86/utils/gtf/gtf.c index 840626c66..87fcb3f0e 100644 --- a/xorg-server/hw/xfree86/utils/gtf/gtf.c +++ b/xorg-server/hw/xfree86/utils/gtf/gtf.c @@ -1,741 +1,741 @@ -/* gtf.c Generate mode timings using the GTF Timing Standard
- *
- * gcc gtf.c -o gtf -lm -Wall
- *
- * Copyright (c) 2001, Andy Ritger aritger@nvidia.com
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * o Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * o Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * o Neither the name of NVIDIA nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- *
- *
- * This program is based on the Generalized Timing Formula(GTF TM)
- * Standard Version: 1.0, Revision: 1.0
- *
- * The GTF Document contains the following Copyright information:
- *
- * Copyright (c) 1994, 1995, 1996 - Video Electronics Standards
- * Association. Duplication of this document within VESA member
- * companies for review purposes is permitted. All other rights
- * reserved.
- *
- * While every precaution has been taken in the preparation
- * of this standard, the Video Electronics Standards Association and
- * its contributors assume no responsibility for errors or omissions,
- * and make no warranties, expressed or implied, of functionality
- * of suitability for any purpose. The sample code contained within
- * this standard may be used without restriction.
- *
- *
- *
- * The GTF EXCEL(TM) SPREADSHEET, a sample (and the definitive)
- * implementation of the GTF Timing Standard, is available at:
- *
- * ftp://ftp.vesa.org/pub/GTF/GTF_V1R1.xls
- *
- *
- *
- * This program takes a desired resolution and vertical refresh rate,
- * and computes mode timings according to the GTF Timing Standard.
- * These mode timings can then be formatted as an XServer modeline
- * or a mode description for use by fbset(8).
- *
- *
- *
- * NOTES:
- *
- * The GTF allows for computation of "margins" (the visible border
- * surrounding the addressable video); on most non-overscan type
- * systems, the margin period is zero. I've implemented the margin
- * computations but not enabled it because 1) I don't really have
- * any experience with this, and 2) neither XServer modelines nor
- * fbset fb.modes provide an obvious way for margin timings to be
- * included in their mode descriptions (needs more investigation).
- *
- * The GTF provides for computation of interlaced mode timings;
- * I've implemented the computations but not enabled them, yet.
- * I should probably enable and test this at some point.
- *
- *
- *
- * TODO:
- *
- * o Add support for interlaced modes.
- *
- * o Implement the other portions of the GTF: compute mode timings
- * given either the desired pixel clock or the desired horizontal
- * frequency.
- *
- * o It would be nice if this were more general purpose to do things
- * outside the scope of the GTF: like generate double scan mode
- * timings, for example.
- *
- * o Printing digits to the right of the decimal point when the
- * digits are 0 annoys me.
- *
- * o Error checking.
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-# include <xorg-config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#define MARGIN_PERCENT 1.8 /* % of active vertical image */
-#define CELL_GRAN 8.0 /* assumed character cell granularity */
-#define MIN_PORCH 1 /* minimum front porch */
-#define V_SYNC_RQD 3 /* width of vsync in lines */
-#define H_SYNC_PERCENT 8.0 /* width of hsync as % of total line */
-#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */
-#define M 600.0 /* blanking formula gradient */
-#define C 40.0 /* blanking formula offset */
-#define K 128.0 /* blanking formula scaling factor */
-#define J 20.0 /* blanking formula scaling factor */
-
-/* C' and M' are part of the Blanking Duty Cycle computation */
-
-#define C_PRIME (((C - J) * K/256.0) + J)
-#define M_PRIME (K/256.0 * M)
-
-
-/* struct definitions */
-
-typedef struct __mode
-{
- int hr, hss, hse, hfl;
- int vr, vss, vse, vfl;
- float pclk, h_freq, v_freq;
-} mode;
-
-
-typedef struct __options
-{
- int x, y;
- int xorgmode, fbmode;
- float v_freq;
-} options;
-
-
-
-
-/* prototypes */
-
-void print_value(int n, char *name, float val);
-void print_xf86_mode (mode *m);
-void print_fb_mode (mode *m);
-mode *vert_refresh (int h_pixels, int v_lines, float freq,
- int interlaced, int margins);
-options *parse_command_line (int argc, char *argv[]);
-
-
-
-
-/*
- * print_value() - print the result of the named computation; this is
- * useful when comparing against the GTF EXCEL spreadsheet.
- */
-
-int global_verbose = 0;
-
-void print_value(int n, char *name, float val)
-{
- if (global_verbose) {
- printf("%2d: %-27s: %15f\n", n, name, val);
- }
-}
-
-
-
-/* print_xf86_mode() - print the XServer modeline, given mode timings. */
-
-void print_xf86_mode (mode *m)
-{
- printf ("\n");
- printf (" # %dx%d @ %.2f Hz (GTF) hsync: %.2f kHz; pclk: %.2f MHz\n",
- m->hr, m->vr, m->v_freq, m->h_freq, m->pclk);
-
- printf (" Modeline \"%dx%d_%.2f\" %.2f"
- " %d %d %d %d"
- " %d %d %d %d"
- " -HSync +Vsync\n\n",
- m->hr, m->vr, m->v_freq, m->pclk,
- m->hr, m->hss, m->hse, m->hfl,
- m->vr, m->vss, m->vse, m->vfl);
-
-}
-
-
-
-/*
- * print_fb_mode() - print a mode description in fbset(8) format;
- * see the fb.modes(8) manpage. The timing description used in
- * this is rather odd; they use "left and right margin" to refer
- * to the portion of the hblank before and after the sync pulse
- * by conceptually wrapping the portion of the blank after the pulse
- * to infront of the visible region; ie:
- *
- *
- * Timing description I'm accustomed to:
- *
- *
- *
- * <--------1--------> <--2--> <--3--> <--4-->
- * _________
- * |-------------------|_______| |_______
- *
- * R SS SE FL
- *
- * 1: visible image
- * 2: blank before sync (aka front porch)
- * 3: sync pulse
- * 4: blank after sync (aka back porch)
- * R: Resolution
- * SS: Sync Start
- * SE: Sync End
- * FL: Frame Length
- *
- *
- * But the fb.modes format is:
- *
- *
- * <--4--> <--------1--------> <--2--> <--3-->
- * _________
- * _______|-------------------|_______| |
- *
- * The fb.modes(8) manpage refers to <4> and <2> as the left and
- * right "margin" (as well as upper and lower margin in the vertical
- * direction) -- note that this has nothing to do with the term
- * "margin" used in the GTF Timing Standard.
- *
- * XXX always prints the 32 bit mode -- should I provide a command
- * line option to specify the bpp? It's simple enough for a user
- * to edit the mode description after it's generated.
- */
-
-void print_fb_mode (mode *m)
-{
- printf ("\n");
- printf ("mode \"%dx%d %.2fHz 32bit (GTF)\"\n",
- m->hr, m->vr, m->v_freq);
- printf (" # PCLK: %.2f MHz, H: %.2f kHz, V: %.2f Hz\n",
- m->pclk, m->h_freq, m->v_freq);
- printf (" geometry %d %d %d %d 32\n",
- m->hr, m->vr, m->hr, m->vr);
- printf (" timings %d %d %d %d %d %d %d\n",
- (int) rint(1000000.0/m->pclk),/* pixclock in picoseconds */
- m->hfl - m->hse, /* left margin (in pixels) */
- m->hss - m->hr, /* right margin (in pixels) */
- m->vfl - m->vse, /* upper margin (in pixel lines) */
- m->vss - m->vr, /* lower margin (in pixel lines) */
- m->hse - m->hss, /* horizontal sync length (pixels) */
- m->vse - m->vss); /* vert sync length (pixel lines) */
- printf (" hsync low\n");
- printf (" vsync high\n");
- printf ("endmode\n\n");
-
-}
-
-
-
-
-/*
- * vert_refresh() - as defined by the GTF Timing Standard, compute the
- * Stage 1 Parameters using the vertical refresh frequency. In other
- * words: input a desired resolution and desired refresh rate, and
- * output the GTF mode timings.
- *
- * XXX All the code is in place to compute interlaced modes, but I don't
- * feel like testing it right now.
- *
- * XXX margin computations are implemented but not tested (nor used by
- * XServer of fbset mode descriptions, from what I can tell).
- */
-
-mode *vert_refresh (int h_pixels, int v_lines, float freq,
- int interlaced, int margins)
-{
- float h_pixels_rnd;
- float v_lines_rnd;
- float v_field_rate_rqd;
- float top_margin;
- float bottom_margin;
- float interlace;
- float h_period_est;
- float vsync_plus_bp;
- float v_back_porch;
- float total_v_lines;
- float v_field_rate_est;
- float h_period;
- float v_field_rate;
- float v_frame_rate;
- float left_margin;
- float right_margin;
- float total_active_pixels;
- float ideal_duty_cycle;
- float h_blank;
- float total_pixels;
- float pixel_freq;
- float h_freq;
-
- float h_sync;
- float h_front_porch;
- float v_odd_front_porch_lines;
-
- mode *m = (mode*) malloc (sizeof (mode));
-
-
- /* 1. In order to give correct results, the number of horizontal
- * pixels requested is first processed to ensure that it is divisible
- * by the character size, by rounding it to the nearest character
- * cell boundary:
- *
- * [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND])
- */
-
- h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN;
-
- print_value(1, "[H PIXELS RND]", h_pixels_rnd);
-
-
- /* 2. If interlace is requested, the number of vertical lines assumed
- * by the calculation must be halved, as the computation calculates
- * the number of vertical lines per field. In either case, the
- * number of lines is rounded to the nearest integer.
- *
- * [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0),
- * ROUND([V LINES],0))
- */
-
- v_lines_rnd = interlaced ?
- rint((float) v_lines) / 2.0 :
- rint((float) v_lines);
-
- print_value(2, "[V LINES RND]", v_lines_rnd);
-
-
- /* 3. Find the frame rate required:
- *
- * [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2,
- * [I/P FREQ RQD])
- */
-
- v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq);
-
- print_value(3, "[V FIELD RATE RQD]", v_field_rate_rqd);
-
-
- /* 4. Find number of lines in Top margin:
- *
- * [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
- * ROUND(([MARGIN%]/100*[V LINES RND]),0),
- * 0)
- */
-
- top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0);
-
- print_value(4, "[TOP MARGIN (LINES)]", top_margin);
-
-
- /* 5. Find number of lines in Bottom margin:
- *
- * [BOT MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
- * ROUND(([MARGIN%]/100*[V LINES RND]),0),
- * 0)
- */
-
- bottom_margin = margins ? rint(MARGIN_PERCENT/100.0 * v_lines_rnd) : (0.0);
-
- print_value(5, "[BOT MARGIN (LINES)]", bottom_margin);
-
-
- /* 6. If interlace is required, then set variable [INTERLACE]=0.5:
- *
- * [INTERLACE]=(IF([INT RQD?]="y",0.5,0))
- */
-
- interlace = interlaced ? 0.5 : 0.0;
-
- print_value(6, "[INTERLACE]", interlace);
-
-
- /* 7. Estimate the Horizontal period
- *
- * [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) /
- * ([V LINES RND] + (2*[TOP MARGIN (LINES)]) +
- * [MIN PORCH RND]+[INTERLACE]) * 1000000
- */
-
- h_period_est = (((1.0/v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP/1000000.0))
- / (v_lines_rnd + (2*top_margin) + MIN_PORCH + interlace)
- * 1000000.0);
-
- print_value(7, "[H PERIOD EST]", h_period_est);
-
-
- /* 8. Find the number of lines in V sync + back porch:
- *
- * [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0)
- */
-
- vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP/h_period_est);
-
- print_value(8, "[V SYNC+BP]", vsync_plus_bp);
-
-
- /* 9. Find the number of lines in V back porch alone:
- *
- * [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND]
- *
- * XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]?
- */
-
- v_back_porch = vsync_plus_bp - V_SYNC_RQD;
-
- print_value(9, "[V BACK PORCH]", v_back_porch);
-
-
- /* 10. Find the total number of lines in Vertical field period:
- *
- * [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] +
- * [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] +
- * [MIN PORCH RND]
- */
-
- total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp +
- interlace + MIN_PORCH;
-
- print_value(10, "[TOTAL V LINES]", total_v_lines);
-
-
- /* 11. Estimate the Vertical field frequency:
- *
- * [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000
- */
-
- v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0;
-
- print_value(11, "[V FIELD RATE EST]", v_field_rate_est);
-
-
- /* 12. Find the actual horizontal period:
- *
- * [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST])
- */
-
- h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est);
-
- print_value(12, "[H PERIOD]", h_period);
-
-
- /* 13. Find the actual Vertical field frequency:
- *
- * [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000
- */
-
- v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0;
-
- print_value(13, "[V FIELD RATE]", v_field_rate);
-
-
- /* 14. Find the Vertical frame frequency:
- *
- * [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE]))
- */
-
- v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate;
-
- print_value(14, "[V FRAME RATE]", v_frame_rate);
-
-
- /* 15. Find number of pixels in left margin:
- *
- * [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
- * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
- * [CELL GRAN RND]),0)) * [CELL GRAN RND],
- * 0))
- */
-
- left_margin = margins ?
- rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
- 0.0;
-
- print_value(15, "[LEFT MARGIN (PIXELS)]", left_margin);
-
-
- /* 16. Find number of pixels in right margin:
- *
- * [RIGHT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
- * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
- * [CELL GRAN RND]),0)) * [CELL GRAN RND],
- * 0))
- */
-
- right_margin = margins ?
- rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
- 0.0;
-
- print_value(16, "[RIGHT MARGIN (PIXELS)]", right_margin);
-
-
- /* 17. Find total number of active pixels in image and left and right
- * margins:
- *
- * [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] +
- * [RIGHT MARGIN (PIXELS)]
- */
-
- total_active_pixels = h_pixels_rnd + left_margin + right_margin;
-
- print_value(17, "[TOTAL ACTIVE PIXELS]", total_active_pixels);
-
-
- /* 18. Find the ideal blanking duty cycle from the blanking duty cycle
- * equation:
- *
- * [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000)
- */
-
- ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0);
-
- print_value(18, "[IDEAL DUTY CYCLE]", ideal_duty_cycle);
-
-
- /* 19. Find the number of pixels in the blanking time to the nearest
- * double character cell:
- *
- * [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] *
- * [IDEAL DUTY CYCLE] /
- * (100-[IDEAL DUTY CYCLE]) /
- * (2*[CELL GRAN RND])), 0))
- * * (2*[CELL GRAN RND])
- */
-
- h_blank = rint(total_active_pixels *
- ideal_duty_cycle /
- (100.0 - ideal_duty_cycle) /
- (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN);
-
- print_value(19, "[H BLANK (PIXELS)]", h_blank);
-
-
- /* 20. Find total number of pixels:
- *
- * [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)]
- */
-
- total_pixels = total_active_pixels + h_blank;
-
- print_value(20, "[TOTAL PIXELS]", total_pixels);
-
-
- /* 21. Find pixel clock frequency:
- *
- * [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD]
- */
-
- pixel_freq = total_pixels / h_period;
-
- print_value(21, "[PIXEL FREQ]", pixel_freq);
-
-
- /* 22. Find horizontal frequency:
- *
- * [H FREQ] = 1000 / [H PERIOD]
- */
-
- h_freq = 1000.0 / h_period;
-
- print_value(22, "[H FREQ]", h_freq);
-
-
-
- /* Stage 1 computations are now complete; I should really pass
- the results to another function and do the Stage 2
- computations, but I only need a few more values so I'll just
- append the computations here for now */
-
-
-
- /* 17. Find the number of pixels in the horizontal sync period:
- *
- * [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] /
- * [CELL GRAN RND]),0))*[CELL GRAN RND]
- */
-
- h_sync = rint(H_SYNC_PERCENT/100.0 * total_pixels / CELL_GRAN) * CELL_GRAN;
-
- print_value(17, "[H SYNC (PIXELS)]", h_sync);
-
-
- /* 18. Find the number of pixels in the horizontal front porch period:
- *
- * [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)]
- */
-
- h_front_porch = (h_blank / 2.0) - h_sync;
-
- print_value(18, "[H FRONT PORCH (PIXELS)]", h_front_porch);
-
-
- /* 36. Find the number of lines in the odd front porch period:
- *
- * [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE])
- */
-
- v_odd_front_porch_lines = MIN_PORCH + interlace;
-
- print_value(36, "[V ODD FRONT PORCH(LINES)]", v_odd_front_porch_lines);
-
-
- /* finally, pack the results in the mode struct */
-
- m->hr = (int) (h_pixels_rnd);
- m->hss = (int) (h_pixels_rnd + h_front_porch);
- m->hse = (int) (h_pixels_rnd + h_front_porch + h_sync);
- m->hfl = (int) (total_pixels);
-
- m->vr = (int) (v_lines_rnd);
- m->vss = (int) (v_lines_rnd + v_odd_front_porch_lines);
- m->vse = (int) (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD);
- m->vfl = (int) (total_v_lines);
-
- m->pclk = pixel_freq;
- m->h_freq = h_freq;
- m->v_freq = freq;
-
- return m;
-
-}
-
-
-
-
-/*
- * parse_command_line() - parse the command line and return an
- * alloced structure containing the results. On error print usage
- * and return NULL.
- */
-
-options *parse_command_line (int argc, char *argv[])
-{
- int n;
-
- options *o = (options *) calloc (1, sizeof (options));
-
- if (argc < 4) goto bad_option;
-
- o->x = atoi (argv[1]);
- o->y = atoi (argv[2]);
- o->v_freq = atof (argv[3]);
-
- /* XXX should check for errors in the above */
-
- n = 4;
-
- while (n < argc) {
- if ((strcmp (argv[n], "-v") == 0) ||
- (strcmp (argv[n], "--verbose") == 0)) {
- global_verbose = 1;
- } else if ((strcmp (argv[n], "-f") == 0) ||
- (strcmp (argv[n], "--fbmode") == 0)) {
- o->fbmode = 1;
- } else if ((strcmp (argv[n], "-x") == 0) ||
- (strcmp (argv[n], "--xorgmode") == 0) ||
- (strcmp (argv[n], "--xf86mode") == 0)) {
- o->xorgmode = 1;
- } else {
- goto bad_option;
- }
-
- n++;
- }
-
- /* if neither xorgmode nor fbmode were requested, default to
- xorgmode */
-
- if (!o->fbmode && !o->xorgmode) o->xorgmode = 1;
-
- return o;
-
- bad_option:
-
- fprintf (stderr, "\n");
- fprintf (stderr, "usage: %s x y refresh [-v|--verbose] "
- "[-f|--fbmode] [-x|--xorgmode]\n", argv[0]);
-
- fprintf (stderr, "\n");
-
- fprintf (stderr, " x : the desired horizontal "
- "resolution (required)\n");
- fprintf (stderr, " y : the desired vertical "
- "resolution (required)\n");
- fprintf (stderr, " refresh : the desired refresh "
- "rate (required)\n");
- fprintf (stderr, " -v|--verbose : enable verbose printouts "
- "(traces each step of the computation)\n");
- fprintf (stderr, " -f|--fbmode : output an fbset(8)-style mode "
- "description\n");
- fprintf (stderr, " -x|--xorgmode : output an "__XSERVERNAME__"-style mode "
- "description (this is the default\n"
- " if no mode description is requested)\n");
-
- fprintf (stderr, "\n");
-
- free (o);
- return NULL;
-
-}
-
-
-
-int main (int argc, char *argv[])
-{
- mode *m;
- options *o;
-
- o = parse_command_line (argc, argv);
- if (!o) exit (1);
-
- m = vert_refresh (o->x, o->y, o->v_freq, 0, 0);
- if (!m) exit (1);
-
- if (o->xorgmode)
- print_xf86_mode(m);
-
- if (o->fbmode)
- print_fb_mode(m);
-
- return 0;
-
-}
+/* gtf.c Generate mode timings using the GTF Timing Standard + * + * gcc gtf.c -o gtf -lm -Wall + * + * Copyright (c) 2001, Andy Ritger aritger@nvidia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * o Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * o Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * o Neither the name of NVIDIA nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * + * This program is based on the Generalized Timing Formula(GTF TM) + * Standard Version: 1.0, Revision: 1.0 + * + * The GTF Document contains the following Copyright information: + * + * Copyright (c) 1994, 1995, 1996 - Video Electronics Standards + * Association. Duplication of this document within VESA member + * companies for review purposes is permitted. All other rights + * reserved. + * + * While every precaution has been taken in the preparation + * of this standard, the Video Electronics Standards Association and + * its contributors assume no responsibility for errors or omissions, + * and make no warranties, expressed or implied, of functionality + * of suitability for any purpose. The sample code contained within + * this standard may be used without restriction. + * + * + * + * The GTF EXCEL(TM) SPREADSHEET, a sample (and the definitive) + * implementation of the GTF Timing Standard, is available at: + * + * ftp://ftp.vesa.org/pub/GTF/GTF_V1R1.xls + * + * + * + * This program takes a desired resolution and vertical refresh rate, + * and computes mode timings according to the GTF Timing Standard. + * These mode timings can then be formatted as an XServer modeline + * or a mode description for use by fbset(8). + * + * + * + * NOTES: + * + * The GTF allows for computation of "margins" (the visible border + * surrounding the addressable video); on most non-overscan type + * systems, the margin period is zero. I've implemented the margin + * computations but not enabled it because 1) I don't really have + * any experience with this, and 2) neither XServer modelines nor + * fbset fb.modes provide an obvious way for margin timings to be + * included in their mode descriptions (needs more investigation). + * + * The GTF provides for computation of interlaced mode timings; + * I've implemented the computations but not enabled them, yet. + * I should probably enable and test this at some point. + * + * + * + * TODO: + * + * o Add support for interlaced modes. + * + * o Implement the other portions of the GTF: compute mode timings + * given either the desired pixel clock or the desired horizontal + * frequency. + * + * o It would be nice if this were more general purpose to do things + * outside the scope of the GTF: like generate double scan mode + * timings, for example. + * + * o Printing digits to the right of the decimal point when the + * digits are 0 annoys me. + * + * o Error checking. + * + */ + +#ifdef HAVE_XORG_CONFIG_H +# include <xorg-config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#define MARGIN_PERCENT 1.8 /* % of active vertical image */ +#define CELL_GRAN 8.0 /* assumed character cell granularity */ +#define MIN_PORCH 1 /* minimum front porch */ +#define V_SYNC_RQD 3 /* width of vsync in lines */ +#define H_SYNC_PERCENT 8.0 /* width of hsync as % of total line */ +#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */ +#define M 600.0 /* blanking formula gradient */ +#define C 40.0 /* blanking formula offset */ +#define K 128.0 /* blanking formula scaling factor */ +#define J 20.0 /* blanking formula scaling factor */ + +/* C' and M' are part of the Blanking Duty Cycle computation */ + +#define C_PRIME (((C - J) * K/256.0) + J) +#define M_PRIME (K/256.0 * M) + + +/* struct definitions */ + +typedef struct __mode +{ + int hr, hss, hse, hfl; + int vr, vss, vse, vfl; + float pclk, h_freq, v_freq; +} mode; + + +typedef struct __options +{ + int x, y; + int xorgmode, fbmode; + float v_freq; +} options; + + + + +/* prototypes */ + +void print_value(int n, const char *name, float val); +void print_xf86_mode (mode *m); +void print_fb_mode (mode *m); +mode *vert_refresh (int h_pixels, int v_lines, float freq, + int interlaced, int margins); +options *parse_command_line (int argc, char *argv[]); + + + + +/* + * print_value() - print the result of the named computation; this is + * useful when comparing against the GTF EXCEL spreadsheet. + */ + +int global_verbose = 0; + +void print_value(int n, const char *name, float val) +{ + if (global_verbose) { + printf("%2d: %-27s: %15f\n", n, name, val); + } +} + + + +/* print_xf86_mode() - print the XServer modeline, given mode timings. */ + +void print_xf86_mode (mode *m) +{ + printf ("\n"); + printf (" # %dx%d @ %.2f Hz (GTF) hsync: %.2f kHz; pclk: %.2f MHz\n", + m->hr, m->vr, m->v_freq, m->h_freq, m->pclk); + + printf (" Modeline \"%dx%d_%.2f\" %.2f" + " %d %d %d %d" + " %d %d %d %d" + " -HSync +Vsync\n\n", + m->hr, m->vr, m->v_freq, m->pclk, + m->hr, m->hss, m->hse, m->hfl, + m->vr, m->vss, m->vse, m->vfl); + +} + + + +/* + * print_fb_mode() - print a mode description in fbset(8) format; + * see the fb.modes(8) manpage. The timing description used in + * this is rather odd; they use "left and right margin" to refer + * to the portion of the hblank before and after the sync pulse + * by conceptually wrapping the portion of the blank after the pulse + * to infront of the visible region; ie: + * + * + * Timing description I'm accustomed to: + * + * + * + * <--------1--------> <--2--> <--3--> <--4--> + * _________ + * |-------------------|_______| |_______ + * + * R SS SE FL + * + * 1: visible image + * 2: blank before sync (aka front porch) + * 3: sync pulse + * 4: blank after sync (aka back porch) + * R: Resolution + * SS: Sync Start + * SE: Sync End + * FL: Frame Length + * + * + * But the fb.modes format is: + * + * + * <--4--> <--------1--------> <--2--> <--3--> + * _________ + * _______|-------------------|_______| | + * + * The fb.modes(8) manpage refers to <4> and <2> as the left and + * right "margin" (as well as upper and lower margin in the vertical + * direction) -- note that this has nothing to do with the term + * "margin" used in the GTF Timing Standard. + * + * XXX always prints the 32 bit mode -- should I provide a command + * line option to specify the bpp? It's simple enough for a user + * to edit the mode description after it's generated. + */ + +void print_fb_mode (mode *m) +{ + printf ("\n"); + printf ("mode \"%dx%d %.2fHz 32bit (GTF)\"\n", + m->hr, m->vr, m->v_freq); + printf (" # PCLK: %.2f MHz, H: %.2f kHz, V: %.2f Hz\n", + m->pclk, m->h_freq, m->v_freq); + printf (" geometry %d %d %d %d 32\n", + m->hr, m->vr, m->hr, m->vr); + printf (" timings %d %d %d %d %d %d %d\n", + (int) rint(1000000.0/m->pclk),/* pixclock in picoseconds */ + m->hfl - m->hse, /* left margin (in pixels) */ + m->hss - m->hr, /* right margin (in pixels) */ + m->vfl - m->vse, /* upper margin (in pixel lines) */ + m->vss - m->vr, /* lower margin (in pixel lines) */ + m->hse - m->hss, /* horizontal sync length (pixels) */ + m->vse - m->vss); /* vert sync length (pixel lines) */ + printf (" hsync low\n"); + printf (" vsync high\n"); + printf ("endmode\n\n"); + +} + + + + +/* + * vert_refresh() - as defined by the GTF Timing Standard, compute the + * Stage 1 Parameters using the vertical refresh frequency. In other + * words: input a desired resolution and desired refresh rate, and + * output the GTF mode timings. + * + * XXX All the code is in place to compute interlaced modes, but I don't + * feel like testing it right now. + * + * XXX margin computations are implemented but not tested (nor used by + * XServer of fbset mode descriptions, from what I can tell). + */ + +mode *vert_refresh (int h_pixels, int v_lines, float freq, + int interlaced, int margins) +{ + float h_pixels_rnd; + float v_lines_rnd; + float v_field_rate_rqd; + float top_margin; + float bottom_margin; + float interlace; + float h_period_est; + float vsync_plus_bp; + float v_back_porch; + float total_v_lines; + float v_field_rate_est; + float h_period; + float v_field_rate; + float v_frame_rate; + float left_margin; + float right_margin; + float total_active_pixels; + float ideal_duty_cycle; + float h_blank; + float total_pixels; + float pixel_freq; + float h_freq; + + float h_sync; + float h_front_porch; + float v_odd_front_porch_lines; + + mode *m = (mode*) malloc (sizeof (mode)); + + + /* 1. In order to give correct results, the number of horizontal + * pixels requested is first processed to ensure that it is divisible + * by the character size, by rounding it to the nearest character + * cell boundary: + * + * [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND]) + */ + + h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN; + + print_value(1, "[H PIXELS RND]", h_pixels_rnd); + + + /* 2. If interlace is requested, the number of vertical lines assumed + * by the calculation must be halved, as the computation calculates + * the number of vertical lines per field. In either case, the + * number of lines is rounded to the nearest integer. + * + * [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0), + * ROUND([V LINES],0)) + */ + + v_lines_rnd = interlaced ? + rint((float) v_lines) / 2.0 : + rint((float) v_lines); + + print_value(2, "[V LINES RND]", v_lines_rnd); + + + /* 3. Find the frame rate required: + * + * [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2, + * [I/P FREQ RQD]) + */ + + v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq); + + print_value(3, "[V FIELD RATE RQD]", v_field_rate_rqd); + + + /* 4. Find number of lines in Top margin: + * + * [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y", + * ROUND(([MARGIN%]/100*[V LINES RND]),0), + * 0) + */ + + top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0); + + print_value(4, "[TOP MARGIN (LINES)]", top_margin); + + + /* 5. Find number of lines in Bottom margin: + * + * [BOT MARGIN (LINES)] = IF([MARGINS RQD?]="Y", + * ROUND(([MARGIN%]/100*[V LINES RND]),0), + * 0) + */ + + bottom_margin = margins ? rint(MARGIN_PERCENT/100.0 * v_lines_rnd) : (0.0); + + print_value(5, "[BOT MARGIN (LINES)]", bottom_margin); + + + /* 6. If interlace is required, then set variable [INTERLACE]=0.5: + * + * [INTERLACE]=(IF([INT RQD?]="y",0.5,0)) + */ + + interlace = interlaced ? 0.5 : 0.0; + + print_value(6, "[INTERLACE]", interlace); + + + /* 7. Estimate the Horizontal period + * + * [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) / + * ([V LINES RND] + (2*[TOP MARGIN (LINES)]) + + * [MIN PORCH RND]+[INTERLACE]) * 1000000 + */ + + h_period_est = (((1.0/v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP/1000000.0)) + / (v_lines_rnd + (2*top_margin) + MIN_PORCH + interlace) + * 1000000.0); + + print_value(7, "[H PERIOD EST]", h_period_est); + + + /* 8. Find the number of lines in V sync + back porch: + * + * [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0) + */ + + vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP/h_period_est); + + print_value(8, "[V SYNC+BP]", vsync_plus_bp); + + + /* 9. Find the number of lines in V back porch alone: + * + * [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND] + * + * XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]? + */ + + v_back_porch = vsync_plus_bp - V_SYNC_RQD; + + print_value(9, "[V BACK PORCH]", v_back_porch); + + + /* 10. Find the total number of lines in Vertical field period: + * + * [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] + + * [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] + + * [MIN PORCH RND] + */ + + total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp + + interlace + MIN_PORCH; + + print_value(10, "[TOTAL V LINES]", total_v_lines); + + + /* 11. Estimate the Vertical field frequency: + * + * [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000 + */ + + v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0; + + print_value(11, "[V FIELD RATE EST]", v_field_rate_est); + + + /* 12. Find the actual horizontal period: + * + * [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST]) + */ + + h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est); + + print_value(12, "[H PERIOD]", h_period); + + + /* 13. Find the actual Vertical field frequency: + * + * [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000 + */ + + v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0; + + print_value(13, "[V FIELD RATE]", v_field_rate); + + + /* 14. Find the Vertical frame frequency: + * + * [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE])) + */ + + v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate; + + print_value(14, "[V FRAME RATE]", v_frame_rate); + + + /* 15. Find number of pixels in left margin: + * + * [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y", + * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 / + * [CELL GRAN RND]),0)) * [CELL GRAN RND], + * 0)) + */ + + left_margin = margins ? + rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : + 0.0; + + print_value(15, "[LEFT MARGIN (PIXELS)]", left_margin); + + + /* 16. Find number of pixels in right margin: + * + * [RIGHT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y", + * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 / + * [CELL GRAN RND]),0)) * [CELL GRAN RND], + * 0)) + */ + + right_margin = margins ? + rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : + 0.0; + + print_value(16, "[RIGHT MARGIN (PIXELS)]", right_margin); + + + /* 17. Find total number of active pixels in image and left and right + * margins: + * + * [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] + + * [RIGHT MARGIN (PIXELS)] + */ + + total_active_pixels = h_pixels_rnd + left_margin + right_margin; + + print_value(17, "[TOTAL ACTIVE PIXELS]", total_active_pixels); + + + /* 18. Find the ideal blanking duty cycle from the blanking duty cycle + * equation: + * + * [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000) + */ + + ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0); + + print_value(18, "[IDEAL DUTY CYCLE]", ideal_duty_cycle); + + + /* 19. Find the number of pixels in the blanking time to the nearest + * double character cell: + * + * [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] * + * [IDEAL DUTY CYCLE] / + * (100-[IDEAL DUTY CYCLE]) / + * (2*[CELL GRAN RND])), 0)) + * * (2*[CELL GRAN RND]) + */ + + h_blank = rint(total_active_pixels * + ideal_duty_cycle / + (100.0 - ideal_duty_cycle) / + (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN); + + print_value(19, "[H BLANK (PIXELS)]", h_blank); + + + /* 20. Find total number of pixels: + * + * [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)] + */ + + total_pixels = total_active_pixels + h_blank; + + print_value(20, "[TOTAL PIXELS]", total_pixels); + + + /* 21. Find pixel clock frequency: + * + * [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD] + */ + + pixel_freq = total_pixels / h_period; + + print_value(21, "[PIXEL FREQ]", pixel_freq); + + + /* 22. Find horizontal frequency: + * + * [H FREQ] = 1000 / [H PERIOD] + */ + + h_freq = 1000.0 / h_period; + + print_value(22, "[H FREQ]", h_freq); + + + + /* Stage 1 computations are now complete; I should really pass + the results to another function and do the Stage 2 + computations, but I only need a few more values so I'll just + append the computations here for now */ + + + + /* 17. Find the number of pixels in the horizontal sync period: + * + * [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] / + * [CELL GRAN RND]),0))*[CELL GRAN RND] + */ + + h_sync = rint(H_SYNC_PERCENT/100.0 * total_pixels / CELL_GRAN) * CELL_GRAN; + + print_value(17, "[H SYNC (PIXELS)]", h_sync); + + + /* 18. Find the number of pixels in the horizontal front porch period: + * + * [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)] + */ + + h_front_porch = (h_blank / 2.0) - h_sync; + + print_value(18, "[H FRONT PORCH (PIXELS)]", h_front_porch); + + + /* 36. Find the number of lines in the odd front porch period: + * + * [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE]) + */ + + v_odd_front_porch_lines = MIN_PORCH + interlace; + + print_value(36, "[V ODD FRONT PORCH(LINES)]", v_odd_front_porch_lines); + + + /* finally, pack the results in the mode struct */ + + m->hr = (int) (h_pixels_rnd); + m->hss = (int) (h_pixels_rnd + h_front_porch); + m->hse = (int) (h_pixels_rnd + h_front_porch + h_sync); + m->hfl = (int) (total_pixels); + + m->vr = (int) (v_lines_rnd); + m->vss = (int) (v_lines_rnd + v_odd_front_porch_lines); + m->vse = (int) (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD); + m->vfl = (int) (total_v_lines); + + m->pclk = pixel_freq; + m->h_freq = h_freq; + m->v_freq = freq; + + return m; + +} + + + + +/* + * parse_command_line() - parse the command line and return an + * alloced structure containing the results. On error print usage + * and return NULL. + */ + +options *parse_command_line (int argc, char *argv[]) +{ + int n; + + options *o = (options *) calloc (1, sizeof (options)); + + if (argc < 4) goto bad_option; + + o->x = atoi (argv[1]); + o->y = atoi (argv[2]); + o->v_freq = atof (argv[3]); + + /* XXX should check for errors in the above */ + + n = 4; + + while (n < argc) { + if ((strcmp (argv[n], "-v") == 0) || + (strcmp (argv[n], "--verbose") == 0)) { + global_verbose = 1; + } else if ((strcmp (argv[n], "-f") == 0) || + (strcmp (argv[n], "--fbmode") == 0)) { + o->fbmode = 1; + } else if ((strcmp (argv[n], "-x") == 0) || + (strcmp (argv[n], "--xorgmode") == 0) || + (strcmp (argv[n], "--xf86mode") == 0)) { + o->xorgmode = 1; + } else { + goto bad_option; + } + + n++; + } + + /* if neither xorgmode nor fbmode were requested, default to + xorgmode */ + + if (!o->fbmode && !o->xorgmode) o->xorgmode = 1; + + return o; + + bad_option: + + fprintf (stderr, "\n"); + fprintf (stderr, "usage: %s x y refresh [-v|--verbose] " + "[-f|--fbmode] [-x|--xorgmode]\n", argv[0]); + + fprintf (stderr, "\n"); + + fprintf (stderr, " x : the desired horizontal " + "resolution (required)\n"); + fprintf (stderr, " y : the desired vertical " + "resolution (required)\n"); + fprintf (stderr, " refresh : the desired refresh " + "rate (required)\n"); + fprintf (stderr, " -v|--verbose : enable verbose printouts " + "(traces each step of the computation)\n"); + fprintf (stderr, " -f|--fbmode : output an fbset(8)-style mode " + "description\n"); + fprintf (stderr, " -x|--xorgmode : output an "__XSERVERNAME__"-style mode " + "description (this is the default\n" + " if no mode description is requested)\n"); + + fprintf (stderr, "\n"); + + free (o); + return NULL; + +} + + + +int main (int argc, char *argv[]) +{ + mode *m; + options *o; + + o = parse_command_line (argc, argv); + if (!o) exit (1); + + m = vert_refresh (o->x, o->y, o->v_freq, 0, 0); + if (!m) exit (1); + + if (o->xorgmode) + print_xf86_mode(m); + + if (o->fbmode) + print_fb_mode(m); + + return 0; + +} diff --git a/xorg-server/hw/xfree86/vbe/vbe.c b/xorg-server/hw/xfree86/vbe/vbe.c index 06a628457..6ecca6858 100644 --- a/xorg-server/hw/xfree86/vbe/vbe.c +++ b/xorg-server/hw/xfree86/vbe/vbe.c @@ -170,7 +170,7 @@ vbeFree(vbeInfoPtr pVbe) static Bool vbeProbeDDC(vbeInfoPtr pVbe) { - char *ddc_level; + const char *ddc_level; int screen = pVbe->pInt10->scrnIndex; if (pVbe->ddc == DDC_NONE) diff --git a/xorg-server/hw/xfree86/x86emu/debug.c b/xorg-server/hw/xfree86/x86emu/debug.c index 5eda90805..04d0741e0 100644 --- a/xorg-server/hw/xfree86/x86emu/debug.c +++ b/xorg-server/hw/xfree86/x86emu/debug.c @@ -172,7 +172,7 @@ void x86emu_decode_printf (char *x) void x86emu_decode_printf2 (char *x, int y) { char temp[100]; - sprintf(temp,x,y); + snprintf(temp,sizeof(temp),x,y); sprintf(M.x86.decoded_buf+M.x86.enc_str_pos,"%s",temp); M.x86.enc_str_pos += strlen(temp); } diff --git a/xorg-server/hw/xquartz/xpr/dri.c b/xorg-server/hw/xquartz/xpr/dri.c index 8bae6b009..a58f2c76d 100644 --- a/xorg-server/hw/xquartz/xpr/dri.c +++ b/xorg-server/hw/xquartz/xpr/dri.c @@ -813,8 +813,7 @@ Bool DRICreatePixmap(ScreenPtr pScreen, Drawable id, return FALSE; } - strncpy(path, shared->shmPath, pathmax); - path[pathmax - 1] = '\0'; + strlcpy(path, shared->shmPath, pathmax); dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, shared); diff --git a/xorg-server/hw/xwin/winconfig.c b/xorg-server/hw/xwin/winconfig.c index 1325e77a6..71850d0a4 100644 --- a/xorg-server/hw/xwin/winconfig.c +++ b/xorg-server/hw/xwin/winconfig.c @@ -1,1101 +1,1103 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *
- *Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- *"Software"), to deal in the Software without restriction, including
- *without limitation the rights to use, copy, modify, merge, publish,
- *distribute, sublicense, and/or sell copies of the Software, and to
- *permit persons to whom the Software is furnished to do so, subject to
- *the following conditions:
- *
- *The above copyright notice and this permission notice shall be
- *included in all copies or substantial portions of the Software.
- *
- *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
- *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *Except as contained in this notice, the name of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors: Alexander Gottwald
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include "winconfig.h"
-#include "winmsg.h"
-#include "globals.h"
-
-#include "xkbsrv.h"
-
-#ifdef XWIN_XF86CONFIG
-#ifndef CONFIGPATH
-#define CONFIGPATH "%A," "%R," \
- "/etc/X11/%R," "%P/etc/X11/%R," \
- "%E," "%F," \
- "/etc/X11/%F," "%P/etc/X11/%F," \
- "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
- "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
- "%P/etc/X11/%X," \
- "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
- "%P/lib/X11/%X"
-#endif
-#ifndef CONFIGDIRPATH
-#define CONFIGDIRPATH "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
- "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
- "%P/etc/X11/%X," \
- "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
- "%P/lib/X11/%X"
-#endif
-
-XF86ConfigPtr g_xf86configptr = NULL;
-#endif
-
-WinCmdlineRec g_cmdline = {
-#ifdef XWIN_XF86CONFIG
- NULL, /* configFile */
- NULL, /* configDir */
-#endif
- NULL, /* fontPath */
-#ifdef XWIN_XF86CONFIG
- NULL, /* keyboard */
-#endif
- NULL, /* xkbRules */
- NULL, /* xkbModel */
- NULL, /* xkbLayout */
- NULL, /* xkbVariant */
- NULL, /* xkbOptions */
- NULL, /* screenname */
- NULL, /* mousename */
- FALSE, /* emulate3Buttons */
- 0 /* emulate3Timeout */
-};
-
-winInfoRec g_winInfo = {
- { /* keyboard */
- 0, /* leds */
- 500, /* delay */
- 30 /* rate */
- }
- ,
- { /* xkb */
- NULL, /* rules */
- NULL, /* model */
- NULL, /* layout */
- NULL, /* variant */
- NULL, /* options */
- }
- ,
- {
- FALSE,
- 50}
-};
-
-#define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL)
-
-#ifdef XWIN_XF86CONFIG
-serverLayoutRec g_winConfigLayout;
-
-static Bool ParseOptionValue (int scrnIndex, pointer options,
- OptionInfoPtr p);
-static Bool configLayout (serverLayoutPtr, XF86ConfLayoutPtr, char *);
-static Bool configImpliedLayout (serverLayoutPtr, XF86ConfScreenPtr);
-static Bool GetBoolValue (OptionInfoPtr p, const char *s);
-
-
-Bool
-winReadConfigfile ()
-{
- Bool retval = TRUE;
- const char *filename, *dirname;
- MessageType filefrom = X_DEFAULT;
- MessageType dirfrom = X_DEFAULT;
- char *xf86ConfigFile = NULL;
- char *xf86ConfigDir = NULL;
-
- if (g_cmdline.configFile)
- {
- filefrom = X_CMDLINE;
- xf86ConfigFile = g_cmdline.configFile;
- }
- if (g_cmdline.configDir)
- {
- dirfrom = X_CMDLINE;
- xf86ConfigDir = g_cmdline.configDir;
- }
-
- /* Parse config file into data structure */
- xf86initConfigFiles();
- dirname = xf86openConfigDirFiles (CONFIGDIRPATH, xf86ConfigDir, PROJECTROOT);
- filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT);
-
- /* Hack for backward compatibility */
- if (!filename && from == X_DEFAULT)
- filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT);
-
- if (filename)
- {
- winDebug ("Using config file: \"%s\"\n", filename);
- }
- else
- {
- ErrorF ("Unable to locate/open config file");
- if (xf86ConfigFile)
- ErrorF (": \"%s\"", xf86ConfigFile);
- ErrorF ("\n");
- }
- if (dirname)
- {
- winMsg (from, "Using config directory: \"%s\"\n", dirname);
- }
- else
- {
- winMsg (X_ERROR, "Unable to locate/open config directory");
- if (xf86ConfigDir)
- ErrorF (": \"%s\"", xf86ConfigDir);
- ErrorF ("\n");
- }
- if (!filename && !dirname)
- {
- return FALSE;
- }
- if ((g_xf86configptr = xf86readConfigFile ()) == NULL)
- {
- ErrorF ("Problem parsing the config file\n");
- return FALSE;
- }
- xf86closeConfigFile ();
-
- LogPrintMarkers();
-
- /* set options from data structure */
-
- if (g_xf86configptr->conf_layout_lst == NULL || g_cmdline.screenname != NULL)
- {
- if (g_cmdline.screenname == NULL)
- {
- winDebug ("No Layout section. Using the first Screen section.\n");
- }
- if (!configImpliedLayout (&g_winConfigLayout,
- g_xf86configptr->conf_screen_lst))
- {
- ErrorF ("Unable to determine the screen layout\n");
- return FALSE;
- }
- }
- else
- {
- /* Check if layout is given in the config file */
- if (g_xf86configptr->conf_flags != NULL)
- {
- char *dfltlayout = NULL;
- pointer optlist = g_xf86configptr->conf_flags->flg_option_lst;
-
- if (optlist && winFindOption (optlist, "defaultserverlayout"))
- dfltlayout =
- winSetStrOption (optlist, "defaultserverlayout", NULL);
-
- if (!configLayout (&g_winConfigLayout,
- g_xf86configptr->conf_layout_lst,
- dfltlayout))
- {
- ErrorF ("Unable to determine the screen layout\n");
- return FALSE;
- }
- }
- else
- {
- if (!configLayout (&g_winConfigLayout,
- g_xf86configptr->conf_layout_lst,
- NULL))
- {
- ErrorF ("Unable to determine the screen layout\n");
- return FALSE;
- }
- }
- }
-
- /* setup special config files */
- winConfigFiles ();
- return retval;
-}
-#endif
-
-/* load layout definitions */
-#include "winlayouts.h"
-
-/* Set the keyboard configuration */
-Bool
-winConfigKeyboard (DeviceIntPtr pDevice)
-{
- char layoutName[KL_NAMELENGTH];
- unsigned char layoutFriendlyName[256];
- static unsigned int layoutNum = 0;
- int keyboardType;
-#ifdef XWIN_XF86CONFIG
- XF86ConfInputPtr kbd = NULL;
- XF86ConfInputPtr input_list = NULL;
- MessageType kbdfrom = X_CONFIG;
-#endif
- MessageType from = X_DEFAULT;
- char *s = NULL;
-
- /* Setup defaults */
- XkbGetRulesDflts(&g_winInfo.xkb);
-
- /*
- * Query the windows autorepeat settings and change the xserver defaults.
- */
- {
- int kbd_delay;
- DWORD kbd_speed;
- if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) &&
- SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0))
- {
- switch (kbd_delay)
- {
- case 0: g_winInfo.keyboard.delay = 250; break;
- case 1: g_winInfo.keyboard.delay = 500; break;
- case 2: g_winInfo.keyboard.delay = 750; break;
- default:
- case 3: g_winInfo.keyboard.delay = 1000; break;
- }
- g_winInfo.keyboard.rate = (kbd_speed>0)?kbd_speed:1;
- winDebug("Setting autorepeat to delay=%d, rate=%d\n",
- g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
- }
- }
-
-
- keyboardType = GetKeyboardType (0);
- if (keyboardType > 0 && GetKeyboardLayoutName (layoutName))
- {
- WinKBLayoutPtr pLayout;
- Bool bfound = FALSE;
-
- if (! layoutNum)
- layoutNum = strtoul (layoutName, (char **)NULL, 16);
- if ((layoutNum & 0xffff) == 0x411) {
- /* The japanese layouts know a lot of different IMEs which all have
- different layout numbers set. Map them to a single entry.
- Same might apply for chinese, korean and other symbol languages
- too */
- layoutNum = (layoutNum & 0xffff);
- if (keyboardType == 7)
- {
- /* Japanese layouts have problems with key event messages
- such as the lack of WM_KEYUP for Caps Lock key.
- Loading US layout fixes this problem. */
- if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL)
- winDebug("Loading US keyboard layout.\n");
- else
- ErrorF ("LoadKeyboardLayout failed.\n");
- }
- }
-
- /* Discover the friendly name of the current layout */
- {
- HKEY regkey = NULL;
- const char regtempl[] = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
- char *regpath;
- DWORD namesize = sizeof(layoutFriendlyName);
-
- regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
- strcpy(regpath, regtempl);
- strcat(regpath, layoutName);
-
- if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key))
- RegQueryValueEx(regkey, "Layout Text", 0, NULL, layoutFriendlyName, &namesize);
-
- /* Close registry key */
- if (regkey)
- RegCloseKey (regkey);
- free(regpath);
- }
-
- winDebug ("Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n",
- layoutName, layoutNum, layoutFriendlyName, keyboardType);
-
- for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++)
- {
- if (pLayout->winlayout != layoutNum)
- continue;
- if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
- continue;
-
- bfound = TRUE;
- winDebug (
- "Found matching XKB configuration \"%s\"\n",
- pLayout->layoutname);
-
- winDebug(
- "Model = \"%s\" Layout = \"%s\""
- " Variant = \"%s\" Options = \"%s\"\n",
- pLayout->xkbmodel ? pLayout->xkbmodel : "none",
- pLayout->xkblayout ? pLayout->xkblayout : "none",
- pLayout->xkbvariant ? pLayout->xkbvariant : "none",
- pLayout->xkboptions ? pLayout->xkboptions : "none");
-
- g_winInfo.xkb.model = pLayout->xkbmodel;
- g_winInfo.xkb.layout = pLayout->xkblayout;
- g_winInfo.xkb.variant = pLayout->xkbvariant;
- g_winInfo.xkb.options = pLayout->xkboptions;
-
-
- break;
- }
-
- if (!bfound)
- {
- ErrorF ("Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n", layoutFriendlyName, layoutName);
- }
- }
-
- /* parse the configuration */
-#ifdef XWIN_XF86CONFIG
- if (g_cmdline.keyboard)
- kbdfrom = X_CMDLINE;
-
- /*
- * Until the layout code is finished, I search for the keyboard
- * device and configure the server with it.
- */
-
- if (g_xf86configptr != NULL)
- input_list = g_xf86configptr->conf_input_lst;
-
- while (input_list != NULL)
- {
- if (winNameCompare (input_list->inp_driver, "keyboard") == 0)
- {
- /* Check if device name matches requested name */
- if (g_cmdline.keyboard && winNameCompare (input_list->inp_identifier,
- g_cmdline.keyboard))
- continue;
- kbd = input_list;
- }
- input_list = input_list->list.next;
- }
-
- if (kbd != NULL)
- {
-
- if (kbd->inp_identifier)
- winDebug ("Using keyboard \"%s\" as primary keyboard\n",
- kbd->inp_identifier);
-
- if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL)))
- {
- if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay,
- &g_winInfo.keyboard.rate) != 2) ||
- (g_winInfo.keyboard.delay < 1) ||
- (g_winInfo.keyboard.rate == 0) ||
- (1000 / g_winInfo.keyboard.rate) < 1)
- {
- ErrorF ("\"%s\" is not a valid AutoRepeat value", s);
- free(s);
- return FALSE;
- }
- free(s);
- winDebug ("AutoRepeat: %ld %ld\n",
- g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
- }
-#endif
-
- s = NULL;
- if (g_cmdline.xkbRules)
- {
- s = g_cmdline.xkbRules;
- from = X_CMDLINE;
- }
-#ifdef XWIN_XF86CONFIG
- else
- {
- s = winSetStrOption (kbd->inp_option_lst, "XkbRules", NULL);
- from = X_CONFIG;
- }
-#endif
- if (s)
- {
- g_winInfo.xkb.rules = NULL_IF_EMPTY (s);
- winDebug ("XKB: rules: \"%s\"\n", s);
- }
-
- s = NULL;
- if (g_cmdline.xkbModel)
- {
- s = g_cmdline.xkbModel;
- from = X_CMDLINE;
- }
-#ifdef XWIN_XF86CONFIG
- else
- {
- s = winSetStrOption (kbd->inp_option_lst, "XkbModel", NULL);
- from = X_CONFIG;
- }
-#endif
- if (s)
- {
- g_winInfo.xkb.model = NULL_IF_EMPTY (s);
- winDebug ("XKB: model: \"%s\"\n", s);
- }
-
- s = NULL;
- if (g_cmdline.xkbLayout)
- {
- s = g_cmdline.xkbLayout;
- from = X_CMDLINE;
- }
-#ifdef XWIN_XF86CONFIG
- else
- {
- s = winSetStrOption (kbd->inp_option_lst, "XkbLayout", NULL);
- from = X_CONFIG;
- }
-#endif
- if (s)
- {
- g_winInfo.xkb.layout = NULL_IF_EMPTY (s);
- winDebug ("XKB: layout: \"%s\"\n", s);
- }
-
- s = NULL;
- if (g_cmdline.xkbVariant)
- {
- s = g_cmdline.xkbVariant;
- from = X_CMDLINE;
- }
-#ifdef XWIN_XF86CONFIG
- else
- {
- s = winSetStrOption (kbd->inp_option_lst, "XkbVariant", NULL);
- from = X_CONFIG;
- }
-#endif
- if (s)
- {
- g_winInfo.xkb.variant = NULL_IF_EMPTY (s);
- winDebug ("XKB: variant: \"%s\"\n", s);
- }
-
- s = NULL;
- if (g_cmdline.xkbOptions)
- {
- s = g_cmdline.xkbOptions;
- from = X_CMDLINE;
- }
-#ifdef XWIN_XF86CONFIG
- else
- {
- s = winSetStrOption (kbd->inp_option_lst, "XkbOptions", NULL);
- from = X_CONFIG;
- }
-#endif
- if (s)
- {
- g_winInfo.xkb.options = NULL_IF_EMPTY (s);
- winDebug ("XKB: options: \"%s\"\n", s);
- }
-
-#ifdef XWIN_XF86CONFIG
- }
-#endif
-
- return TRUE;
-}
-
-
-#ifdef XWIN_XF86CONFIG
-Bool
-winConfigMouse (DeviceIntPtr pDevice)
-{
- MessageType mousefrom = X_CONFIG;
-
- XF86ConfInputPtr mouse = NULL;
- XF86ConfInputPtr input_list = NULL;
-
- if (g_cmdline.mouse)
- mousefrom = X_CMDLINE;
-
- if (g_xf86configptr != NULL)
- input_list = g_xf86configptr->conf_input_lst;
-
- while (input_list != NULL)
- {
- if (winNameCompare (input_list->inp_driver, "mouse") == 0)
- {
- /* Check if device name matches requested name */
- if (g_cmdline.mouse && winNameCompare (input_list->inp_identifier,
- g_cmdline.mouse))
- continue;
- mouse = input_list;
- }
- input_list = input_list->list.next;
- }
-
- if (mouse != NULL)
- {
- if (mouse->inp_identifier)
- winDebug ("Using pointer \"%s\" as primary pointer\n",
- mouse->inp_identifier);
-
- g_winInfo.pointer.emulate3Buttons =
- winSetBoolOption (mouse->inp_option_lst, "Emulate3Buttons", FALSE);
- if (g_cmdline.emulate3buttons)
- g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons;
-
- g_winInfo.pointer.emulate3Timeout =
- winSetIntOption (mouse->inp_option_lst, "Emulate3Timeout", 50);
- if (g_cmdline.emulate3timeout)
- g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout;
- }
- else
- {
- winDebug ("No primary pointer configured\n");
- winDebug ("Using compiletime defaults for pointer\n");
- }
-
- return TRUE;
-}
-
-
-Bool
-winConfigFiles ()
-{
- MessageType from;
- XF86ConfFilesPtr filesptr = NULL;
-
- /* set some shortcuts */
- if (g_xf86configptr != NULL)
- {
- filesptr = g_xf86configptr->conf_files;
- }
-
-
- /* Fontpath */
- from = X_DEFAULT;
-
- if (g_cmdline.fontPath)
- {
- from = X_CMDLINE;
- defaultFontPath = g_cmdline.fontPath;
- }
- else if (filesptr != NULL && filesptr->file_fontpath)
- {
- from = X_CONFIG;
- defaultFontPath = strdup (filesptr->file_fontpath);
- }
- winDebug ("FontPath set to \"%s\"\n", defaultFontPath);
-
- return TRUE;
-}
-#else
-Bool
-winConfigFiles (void)
-{
- /* Fontpath */
- if (g_cmdline.fontPath)
- {
- defaultFontPath = g_cmdline.fontPath;
- winDebug("FontPath set to \"%s\"\n", defaultFontPath);
- }
-
- return TRUE;
-}
-#endif
-
-
-Bool
-winConfigOptions (void)
-{
- return TRUE;
-}
-
-
-Bool
-winConfigScreens (void)
-{
- return TRUE;
-}
-
-
-#ifdef XWIN_XF86CONFIG
-char *
-winSetStrOption (pointer optlist, const char *name, char *deflt)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_STRING;
- if (ParseOptionValue (-1, optlist, &o))
- deflt = o.value.str;
- if (deflt)
- return strdup (deflt);
- else
- return NULL;
-}
-
-
-int
-winSetBoolOption (pointer optlist, const char *name, int deflt)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_BOOLEAN;
- if (ParseOptionValue (-1, optlist, &o))
- deflt = o.value.bool;
- return deflt;
-}
-
-
-int
-winSetIntOption (pointer optlist, const char *name, int deflt)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_INTEGER;
- if (ParseOptionValue (-1, optlist, &o))
- deflt = o.value.num;
- return deflt;
-}
-
-
-double
-winSetRealOption (pointer optlist, const char *name, double deflt)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_REAL;
- if (ParseOptionValue (-1, optlist, &o))
- deflt = o.value.realnum;
- return deflt;
-}
-
-double
-winSetPercentOption (pointer optlist, const char *name, double deflt)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_PERCENT;
- if (ParseOptionValue (-1, optlist, &o))
- deflt = o.value.realnum;
- return deflt;
-}
-#endif
-
-
-/*
- * Compare two strings for equality. This is caseinsensitive and
- * The characters '_', ' ' (space) and '\t' (tab) are treated as
- * not existing.
- */
-
-int
-winNameCompare (const char *s1, const char *s2)
-{
- char c1, c2;
-
- if (!s1 || *s1 == 0)
- {
- if (!s2 || *s2 == 0)
- return 0;
- else
- return 1;
- }
-
- while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
- s1++;
- while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
- s2++;
-
- c1 = (isupper ((int)*s1) ? tolower ((int)*s1) : *s1);
- c2 = (isupper ((int)*s2) ? tolower ((int)*s2) : *s2);
-
- while (c1 == c2)
- {
- if (c1 == 0)
- return 0;
- s1++;
- s2++;
-
- while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
- s1++;
- while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
- s2++;
-
- c1 = (isupper ((int)*s1) ? tolower ((int)*s1) : *s1);
- c2 = (isupper ((int)*s2) ? tolower ((int)*s2) : *s2);
- }
- return c1 - c2;
-}
-
-
-#ifdef XWIN_XF86CONFIG
-/*
- * Find the named option in the list.
- * @return the pointer to the option record, or NULL if not found.
- */
-
-XF86OptionPtr
-winFindOption (XF86OptionPtr list, const char *name)
-{
- while (list)
- {
- if (winNameCompare (list->opt_name, name) == 0)
- return list;
- list = list->list.next;
- }
- return NULL;
-}
-
-
-/*
- * Find the Value of an named option.
- * @return The option value or NULL if not found.
- */
-
-char *
-winFindOptionValue (XF86OptionPtr list, const char *name)
-{
- list = winFindOption (list, name);
- if (list)
- {
- if (list->opt_val)
- return list->opt_val;
- else
- return "";
- }
- return NULL;
-}
-
-
-/*
- * Parse the option.
- */
-
-static Bool
-ParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p)
-{
- char *s, *end;
-
- if ((s = winFindOptionValue (options, p->name)) != NULL)
- {
- switch (p->type)
- {
- case OPTV_INTEGER:
- if (*s == '\0')
- {
- winDebug ( "Option \"%s\" requires an integer value\n",
- p->name);
- p->found = FALSE;
- }
- else
- {
- p->value.num = strtoul (s, &end, 0);
- if (*end == '\0')
- {
- p->found = TRUE;
- }
- else
- {
- winDebug ( "Option \"%s\" requires an integer value\n",
- p->name);
- p->found = FALSE;
- }
- }
- break;
- case OPTV_STRING:
- if (*s == '\0')
- {
- winDebug ( "Option \"%s\" requires an string value\n", p->name);
- p->found = FALSE;
- }
- else
- {
- p->value.str = s;
- p->found = TRUE;
- }
- break;
- case OPTV_ANYSTR:
- p->value.str = s;
- p->found = TRUE;
- break;
- case OPTV_REAL:
- if (*s == '\0')
- {
- winDebug ( "Option \"%s\" requires a floating point value\n",
- p->name);
- p->found = FALSE;
- }
- else
- {
- p->value.realnum = strtod (s, &end);
- if (*end == '\0')
- {
- p->found = TRUE;
- }
- else
- {
- winDebug ( "Option \"%s\" requires a floating point value\n",
- p->name);
- p->found = FALSE;
- }
- }
- break;
- case OPTV_BOOLEAN:
- if (GetBoolValue (p, s))
- {
- p->found = TRUE;
- }
- else
- {
- winDebug ( "Option \"%s\" requires a boolean value\n", p->name);
- p->found = FALSE;
- }
- break;
- case OPTV_PERCENT:
- if (*s == '\0')
- {
- winDrvMsg (scrnIndex, X_WARNING,
- "Option \"%s\" requires a percent value\n",
- p->name);
- p->found = FALSE;
- }
- else
- {
- double percent = strtod (s, &end);
-
- if (end != s && winNameCompare (end, "%"))
- {
- p->found = TRUE;
- p->value.realnum = percent;
- }
- else
- {
- winDrvMsg (scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- }
- }
- case OPTV_FREQ:
- if (*s == '\0')
- {
- winDebug ( "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- }
- else
- {
- double freq = strtod (s, &end);
- int units = 0;
-
- if (end != s)
- {
- p->found = TRUE;
- if (!winNameCompare (end, "Hz"))
- units = 1;
- else if (!winNameCompare (end, "kHz") ||
- !winNameCompare (end, "k"))
- units = 1000;
- else if (!winNameCompare (end, "MHz") ||
- !winNameCompare (end, "M"))
- units = 1000000;
- else
- {
- winDebug ( "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- }
- if (p->found)
- freq *= (double) units;
- }
- else
- {
- winDebug ( "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- }
- if (p->found)
- {
- p->value.freq.freq = freq;
- p->value.freq.units = units;
- }
- }
- break;
- case OPTV_NONE:
- /* Should never get here */
- p->found = FALSE;
- break;
- }
- if (p->found)
- {
- winDebug ("Option \"%s\"", p->name);
- if (!(p->type == OPTV_BOOLEAN && *s == 0))
- {
- winDebug (" \"%s\"", s);
- }
- winDebug ("\n");
- }
- }
- else if (p->type == OPTV_BOOLEAN)
- {
- /* Look for matches with options with or without a "No" prefix. */
- char *n, *newn;
- OptionInfoRec opt;
-
- n = winNormalizeName (p->name);
- if (!n)
- {
- p->found = FALSE;
- return FALSE;
- }
- if (strncmp (n, "no", 2) == 0)
- {
- newn = n + 2;
- }
- else
- {
- free (n);
- n = malloc (strlen (p->name) + 2 + 1);
- if (!n)
- {
- p->found = FALSE;
- return FALSE;
- }
- strcpy (n, "No");
- strcat (n, p->name);
- newn = n;
- }
- if ((s = winFindOptionValue (options, newn)) != NULL)
- {
- if (GetBoolValue (&opt, s))
- {
- p->value.bool = !opt.value.bool;
- p->found = TRUE;
- }
- else
- {
- winDebug ( "Option \"%s\" requires a boolean value\n", newn);
- p->found = FALSE;
- }
- }
- else
- {
- p->found = FALSE;
- }
- if (p->found)
- {
- winDebug ("Option \"%s\"", newn);
- if (*s != 0)
- {
- winDebug (" \"%s\"", s);
- }
- winDebug ("\n");
- }
- free (n);
- }
- else
- {
- p->found = FALSE;
- }
- return p->found;
-}
-
-
-static Bool
-configLayout (serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
- char *default_layout)
-{
-#if 0
-#pragma warn UNIMPLEMENTED
-#endif
- return TRUE;
-}
-
-
-static Bool
-configImpliedLayout (serverLayoutPtr servlayoutp,
- XF86ConfScreenPtr conf_screen)
-{
-#if 0
-#pragma warn UNIMPLEMENTED
-#endif
- return TRUE;
-}
-
-
-static Bool
-GetBoolValue (OptionInfoPtr p, const char *s)
-{
- if (*s == 0)
- {
- p->value.bool = TRUE;
- }
- else
- {
- if (winNameCompare (s, "1") == 0)
- p->value.bool = TRUE;
- else if (winNameCompare (s, "on") == 0)
- p->value.bool = TRUE;
- else if (winNameCompare (s, "true") == 0)
- p->value.bool = TRUE;
- else if (winNameCompare (s, "yes") == 0)
- p->value.bool = TRUE;
- else if (winNameCompare (s, "0") == 0)
- p->value.bool = FALSE;
- else if (winNameCompare (s, "off") == 0)
- p->value.bool = FALSE;
- else if (winNameCompare (s, "false") == 0)
- p->value.bool = FALSE;
- else if (winNameCompare (s, "no") == 0)
- p->value.bool = FALSE;
- }
- return TRUE;
-}
-#endif
-
-
-char *
-winNormalizeName (const char *s)
-{
- char *ret, *q;
- const char *p;
-
- if (s == NULL)
- return NULL;
-
- ret = malloc (strlen (s) + 1);
- for (p = s, q = ret; *p != 0; p++)
- {
- switch (*p)
- {
- case '_':
- case ' ':
- case '\t':
- continue;
- default:
- if (isupper ((int)*p))
- *q++ = tolower ((int)*p);
- else
- *q++ = *p;
- }
- }
- *q = '\0';
- return ret;
-}
-
+/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Alexander Gottwald + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "winconfig.h" +#include "winmsg.h" +#include "globals.h" + +#include "xkbsrv.h" + +#ifdef XWIN_XF86CONFIG +#ifndef CONFIGPATH +#define CONFIGPATH "%A," "%R," \ + "/etc/X11/%R," "%P/etc/X11/%R," \ + "%E," "%F," \ + "/etc/X11/%F," "%P/etc/X11/%F," \ + "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ + "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ + "%P/etc/X11/%X," \ + "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ + "%P/lib/X11/%X" +#endif +#ifndef CONFIGDIRPATH +#define CONFIGDIRPATH "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ + "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ + "%P/etc/X11/%X," \ + "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ + "%P/lib/X11/%X" +#endif + +XF86ConfigPtr g_xf86configptr = NULL; +#endif + +WinCmdlineRec g_cmdline = { +#ifdef XWIN_XF86CONFIG + NULL, /* configFile */ + NULL, /* configDir */ +#endif + NULL, /* fontPath */ +#ifdef XWIN_XF86CONFIG + NULL, /* keyboard */ +#endif + NULL, /* xkbRules */ + NULL, /* xkbModel */ + NULL, /* xkbLayout */ + NULL, /* xkbVariant */ + NULL, /* xkbOptions */ + NULL, /* screenname */ + NULL, /* mousename */ + FALSE, /* emulate3Buttons */ + 0 /* emulate3Timeout */ +}; + +winInfoRec g_winInfo = { + { /* keyboard */ + 0, /* leds */ + 500, /* delay */ + 30 /* rate */ + } + , + { /* xkb */ + NULL, /* rules */ + NULL, /* model */ + NULL, /* layout */ + NULL, /* variant */ + NULL, /* options */ + } + , + { + FALSE, + 50} +}; + +#define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL) + +#ifdef XWIN_XF86CONFIG +serverLayoutRec g_winConfigLayout; + +static Bool ParseOptionValue (int scrnIndex, pointer options, + OptionInfoPtr p); +static Bool configLayout (serverLayoutPtr, XF86ConfLayoutPtr, char *); +static Bool configImpliedLayout (serverLayoutPtr, XF86ConfScreenPtr); +static Bool GetBoolValue (OptionInfoPtr p, const char *s); + + +Bool +winReadConfigfile () +{ + Bool retval = TRUE; + char *filename, *dirname; + MessageType filefrom = X_DEFAULT; + MessageType dirfrom = X_DEFAULT; + char *xf86ConfigFile = NULL; + char *xf86ConfigDir = NULL; + + if (g_cmdline.configFile) + { + filefrom = X_CMDLINE; + xf86ConfigFile = g_cmdline.configFile; + } + if (g_cmdline.configDir) + { + dirfrom = X_CMDLINE; + xf86ConfigDir = g_cmdline.configDir; + } + + /* Parse config file into data structure */ + xf86initConfigFiles(); + dirname = xf86openConfigDirFiles (CONFIGDIRPATH, xf86ConfigDir, PROJECTROOT); + filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT); + + /* Hack for backward compatibility */ + if (!filename && from == X_DEFAULT) + filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT); + + if (filename) + { + winDebug ("Using config file: \"%s\"\n", filename); + } + else + { + ErrorF ("Unable to locate/open config file"); + if (xf86ConfigFile) + ErrorF (": \"%s\"", xf86ConfigFile); + ErrorF ("\n"); + } + if (dirname) + { + winMsg (from, "Using config directory: \"%s\"\n", dirname); + } + else + { + winMsg (X_ERROR, "Unable to locate/open config directory"); + if (xf86ConfigDir) + ErrorF (": \"%s\"", xf86ConfigDir); + ErrorF ("\n"); + } + if (!filename && !dirname) + { + return FALSE; + } + free(filename); + free(dirname); + if ((g_xf86configptr = xf86readConfigFile ()) == NULL) + { + ErrorF ("Problem parsing the config file\n"); + return FALSE; + } + xf86closeConfigFile (); + + LogPrintMarkers(); + + /* set options from data structure */ + + if (g_xf86configptr->conf_layout_lst == NULL || g_cmdline.screenname != NULL) + { + if (g_cmdline.screenname == NULL) + { + winDebug ("No Layout section. Using the first Screen section.\n"); + } + if (!configImpliedLayout (&g_winConfigLayout, + g_xf86configptr->conf_screen_lst)) + { + ErrorF ("Unable to determine the screen layout\n"); + return FALSE; + } + } + else + { + /* Check if layout is given in the config file */ + if (g_xf86configptr->conf_flags != NULL) + { + char *dfltlayout = NULL; + pointer optlist = g_xf86configptr->conf_flags->flg_option_lst; + + if (optlist && winFindOption (optlist, "defaultserverlayout")) + dfltlayout = + winSetStrOption (optlist, "defaultserverlayout", NULL); + + if (!configLayout (&g_winConfigLayout, + g_xf86configptr->conf_layout_lst, + dfltlayout)) + { + ErrorF ("Unable to determine the screen layout\n"); + return FALSE; + } + } + else + { + if (!configLayout (&g_winConfigLayout, + g_xf86configptr->conf_layout_lst, + NULL)) + { + ErrorF ("Unable to determine the screen layout\n"); + return FALSE; + } + } + } + + /* setup special config files */ + winConfigFiles (); + return retval; +} +#endif + +/* load layout definitions */ +#include "winlayouts.h" + +/* Set the keyboard configuration */ +Bool +winConfigKeyboard (DeviceIntPtr pDevice) +{ + char layoutName[KL_NAMELENGTH]; + unsigned char layoutFriendlyName[256]; + static unsigned int layoutNum = 0; + int keyboardType; +#ifdef XWIN_XF86CONFIG + XF86ConfInputPtr kbd = NULL; + XF86ConfInputPtr input_list = NULL; + MessageType kbdfrom = X_CONFIG; +#endif + MessageType from = X_DEFAULT; + char *s = NULL; + + /* Setup defaults */ + XkbGetRulesDflts(&g_winInfo.xkb); + + /* + * Query the windows autorepeat settings and change the xserver defaults. + */ + { + int kbd_delay; + DWORD kbd_speed; + if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) && + SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0)) + { + switch (kbd_delay) + { + case 0: g_winInfo.keyboard.delay = 250; break; + case 1: g_winInfo.keyboard.delay = 500; break; + case 2: g_winInfo.keyboard.delay = 750; break; + default: + case 3: g_winInfo.keyboard.delay = 1000; break; + } + g_winInfo.keyboard.rate = (kbd_speed>0)?kbd_speed:1; + winDebug("Setting autorepeat to delay=%d, rate=%d\n", + g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); + } + } + + + keyboardType = GetKeyboardType (0); + if (keyboardType > 0 && GetKeyboardLayoutName (layoutName)) + { + WinKBLayoutPtr pLayout; + Bool bfound = FALSE; + + if (! layoutNum) + layoutNum = strtoul (layoutName, (char **)NULL, 16); + if ((layoutNum & 0xffff) == 0x411) { + /* The japanese layouts know a lot of different IMEs which all have + different layout numbers set. Map them to a single entry. + Same might apply for chinese, korean and other symbol languages + too */ + layoutNum = (layoutNum & 0xffff); + if (keyboardType == 7) + { + /* Japanese layouts have problems with key event messages + such as the lack of WM_KEYUP for Caps Lock key. + Loading US layout fixes this problem. */ + if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL) + winDebug("Loading US keyboard layout.\n"); + else + ErrorF ("LoadKeyboardLayout failed.\n"); + } + } + + /* Discover the friendly name of the current layout */ + { + HKEY regkey = NULL; + const char regtempl[] = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"; + char *regpath; + DWORD namesize = sizeof(layoutFriendlyName); + + regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1); + strcpy(regpath, regtempl); + strcat(regpath, layoutName); + + if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key)) + RegQueryValueEx(regkey, "Layout Text", 0, NULL, layoutFriendlyName, &namesize); + + /* Close registry key */ + if (regkey) + RegCloseKey (regkey); + free(regpath); + } + + winDebug ("Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n", + layoutName, layoutNum, layoutFriendlyName, keyboardType); + + for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) + { + if (pLayout->winlayout != layoutNum) + continue; + if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType) + continue; + + bfound = TRUE; + winDebug ( + "Found matching XKB configuration \"%s\"\n", + pLayout->layoutname); + + winDebug( + "Model = \"%s\" Layout = \"%s\"" + " Variant = \"%s\" Options = \"%s\"\n", + pLayout->xkbmodel ? pLayout->xkbmodel : "none", + pLayout->xkblayout ? pLayout->xkblayout : "none", + pLayout->xkbvariant ? pLayout->xkbvariant : "none", + pLayout->xkboptions ? pLayout->xkboptions : "none"); + + g_winInfo.xkb.model = pLayout->xkbmodel; + g_winInfo.xkb.layout = pLayout->xkblayout; + g_winInfo.xkb.variant = pLayout->xkbvariant; + g_winInfo.xkb.options = pLayout->xkboptions; + + + break; + } + + if (!bfound) + { + ErrorF ("Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n", layoutFriendlyName, layoutName); + } + } + + /* parse the configuration */ +#ifdef XWIN_XF86CONFIG + if (g_cmdline.keyboard) + kbdfrom = X_CMDLINE; + + /* + * Until the layout code is finished, I search for the keyboard + * device and configure the server with it. + */ + + if (g_xf86configptr != NULL) + input_list = g_xf86configptr->conf_input_lst; + + while (input_list != NULL) + { + if (winNameCompare (input_list->inp_driver, "keyboard") == 0) + { + /* Check if device name matches requested name */ + if (g_cmdline.keyboard && winNameCompare (input_list->inp_identifier, + g_cmdline.keyboard)) + continue; + kbd = input_list; + } + input_list = input_list->list.next; + } + + if (kbd != NULL) + { + + if (kbd->inp_identifier) + winDebug ("Using keyboard \"%s\" as primary keyboard\n", + kbd->inp_identifier); + + if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL))) + { + if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay, + &g_winInfo.keyboard.rate) != 2) || + (g_winInfo.keyboard.delay < 1) || + (g_winInfo.keyboard.rate == 0) || + (1000 / g_winInfo.keyboard.rate) < 1) + { + ErrorF ("\"%s\" is not a valid AutoRepeat value", s); + free(s); + return FALSE; + } + free(s); + winDebug ("AutoRepeat: %ld %ld\n", + g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); + } +#endif + + s = NULL; + if (g_cmdline.xkbRules) + { + s = g_cmdline.xkbRules; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbRules", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.rules = NULL_IF_EMPTY (s); + winDebug ("XKB: rules: \"%s\"\n", s); + } + + s = NULL; + if (g_cmdline.xkbModel) + { + s = g_cmdline.xkbModel; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbModel", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.model = NULL_IF_EMPTY (s); + winDebug ("XKB: model: \"%s\"\n", s); + } + + s = NULL; + if (g_cmdline.xkbLayout) + { + s = g_cmdline.xkbLayout; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbLayout", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.layout = NULL_IF_EMPTY (s); + winDebug ("XKB: layout: \"%s\"\n", s); + } + + s = NULL; + if (g_cmdline.xkbVariant) + { + s = g_cmdline.xkbVariant; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbVariant", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.variant = NULL_IF_EMPTY (s); + winDebug ("XKB: variant: \"%s\"\n", s); + } + + s = NULL; + if (g_cmdline.xkbOptions) + { + s = g_cmdline.xkbOptions; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbOptions", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.options = NULL_IF_EMPTY (s); + winDebug ("XKB: options: \"%s\"\n", s); + } + +#ifdef XWIN_XF86CONFIG + } +#endif + + return TRUE; +} + + +#ifdef XWIN_XF86CONFIG +Bool +winConfigMouse (DeviceIntPtr pDevice) +{ + MessageType mousefrom = X_CONFIG; + + XF86ConfInputPtr mouse = NULL; + XF86ConfInputPtr input_list = NULL; + + if (g_cmdline.mouse) + mousefrom = X_CMDLINE; + + if (g_xf86configptr != NULL) + input_list = g_xf86configptr->conf_input_lst; + + while (input_list != NULL) + { + if (winNameCompare (input_list->inp_driver, "mouse") == 0) + { + /* Check if device name matches requested name */ + if (g_cmdline.mouse && winNameCompare (input_list->inp_identifier, + g_cmdline.mouse)) + continue; + mouse = input_list; + } + input_list = input_list->list.next; + } + + if (mouse != NULL) + { + if (mouse->inp_identifier) + winDebug ("Using pointer \"%s\" as primary pointer\n", + mouse->inp_identifier); + + g_winInfo.pointer.emulate3Buttons = + winSetBoolOption (mouse->inp_option_lst, "Emulate3Buttons", FALSE); + if (g_cmdline.emulate3buttons) + g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons; + + g_winInfo.pointer.emulate3Timeout = + winSetIntOption (mouse->inp_option_lst, "Emulate3Timeout", 50); + if (g_cmdline.emulate3timeout) + g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout; + } + else + { + winDebug ("No primary pointer configured\n"); + winDebug ("Using compiletime defaults for pointer\n"); + } + + return TRUE; +} + + +Bool +winConfigFiles () +{ + MessageType from; + XF86ConfFilesPtr filesptr = NULL; + + /* set some shortcuts */ + if (g_xf86configptr != NULL) + { + filesptr = g_xf86configptr->conf_files; + } + + + /* Fontpath */ + from = X_DEFAULT; + + if (g_cmdline.fontPath) + { + from = X_CMDLINE; + defaultFontPath = g_cmdline.fontPath; + } + else if (filesptr != NULL && filesptr->file_fontpath) + { + from = X_CONFIG; + defaultFontPath = strdup (filesptr->file_fontpath); + } + winDebug ("FontPath set to \"%s\"\n", defaultFontPath); + + return TRUE; +} +#else +Bool +winConfigFiles (void) +{ + /* Fontpath */ + if (g_cmdline.fontPath) + { + defaultFontPath = g_cmdline.fontPath; + winDebug("FontPath set to \"%s\"\n", defaultFontPath); + } + + return TRUE; +} +#endif + + +Bool +winConfigOptions (void) +{ + return TRUE; +} + + +Bool +winConfigScreens (void) +{ + return TRUE; +} + + +#ifdef XWIN_XF86CONFIG +char * +winSetStrOption (pointer optlist, const char *name, char *deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_STRING; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.str; + if (deflt) + return strdup (deflt); + else + return NULL; +} + + +int +winSetBoolOption (pointer optlist, const char *name, int deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_BOOLEAN; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.bool; + return deflt; +} + + +int +winSetIntOption (pointer optlist, const char *name, int deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_INTEGER; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.num; + return deflt; +} + + +double +winSetRealOption (pointer optlist, const char *name, double deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_REAL; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.realnum; + return deflt; +} + +double +winSetPercentOption (pointer optlist, const char *name, double deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_PERCENT; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.realnum; + return deflt; +} +#endif + + +/* + * Compare two strings for equality. This is caseinsensitive and + * The characters '_', ' ' (space) and '\t' (tab) are treated as + * not existing. + */ + +int +winNameCompare (const char *s1, const char *s2) +{ + char c1, c2; + + if (!s1 || *s1 == 0) + { + if (!s2 || *s2 == 0) + return 0; + else + return 1; + } + + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + + c1 = (isupper ((int)*s1) ? tolower ((int)*s1) : *s1); + c2 = (isupper ((int)*s2) ? tolower ((int)*s2) : *s2); + + while (c1 == c2) + { + if (c1 == 0) + return 0; + s1++; + s2++; + + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + + c1 = (isupper ((int)*s1) ? tolower ((int)*s1) : *s1); + c2 = (isupper ((int)*s2) ? tolower ((int)*s2) : *s2); + } + return c1 - c2; +} + + +#ifdef XWIN_XF86CONFIG +/* + * Find the named option in the list. + * @return the pointer to the option record, or NULL if not found. + */ + +XF86OptionPtr +winFindOption (XF86OptionPtr list, const char *name) +{ + while (list) + { + if (winNameCompare (list->opt_name, name) == 0) + return list; + list = list->list.next; + } + return NULL; +} + + +/* + * Find the Value of an named option. + * @return The option value or NULL if not found. + */ + +char * +winFindOptionValue (XF86OptionPtr list, const char *name) +{ + list = winFindOption (list, name); + if (list) + { + if (list->opt_val) + return list->opt_val; + else + return ""; + } + return NULL; +} + + +/* + * Parse the option. + */ + +static Bool +ParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p) +{ + char *s, *end; + + if ((s = winFindOptionValue (options, p->name)) != NULL) + { + switch (p->type) + { + case OPTV_INTEGER: + if (*s == '\0') + { + winDebug ( "Option \"%s\" requires an integer value\n", + p->name); + p->found = FALSE; + } + else + { + p->value.num = strtoul (s, &end, 0); + if (*end == '\0') + { + p->found = TRUE; + } + else + { + winDebug ( "Option \"%s\" requires an integer value\n", + p->name); + p->found = FALSE; + } + } + break; + case OPTV_STRING: + if (*s == '\0') + { + winDebug ( "Option \"%s\" requires an string value\n", p->name); + p->found = FALSE; + } + else + { + p->value.str = s; + p->found = TRUE; + } + break; + case OPTV_ANYSTR: + p->value.str = s; + p->found = TRUE; + break; + case OPTV_REAL: + if (*s == '\0') + { + winDebug ( "Option \"%s\" requires a floating point value\n", + p->name); + p->found = FALSE; + } + else + { + p->value.realnum = strtod (s, &end); + if (*end == '\0') + { + p->found = TRUE; + } + else + { + winDebug ( "Option \"%s\" requires a floating point value\n", + p->name); + p->found = FALSE; + } + } + break; + case OPTV_BOOLEAN: + if (GetBoolValue (p, s)) + { + p->found = TRUE; + } + else + { + winDebug ( "Option \"%s\" requires a boolean value\n", p->name); + p->found = FALSE; + } + break; + case OPTV_PERCENT: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a percent value\n", + p->name); + p->found = FALSE; + } + else + { + double percent = strtod (s, &end); + + if (end != s && winNameCompare (end, "%")) + { + p->found = TRUE; + p->value.realnum = percent; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + } + case OPTV_FREQ: + if (*s == '\0') + { + winDebug ( "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + else + { + double freq = strtod (s, &end); + int units = 0; + + if (end != s) + { + p->found = TRUE; + if (!winNameCompare (end, "Hz")) + units = 1; + else if (!winNameCompare (end, "kHz") || + !winNameCompare (end, "k")) + units = 1000; + else if (!winNameCompare (end, "MHz") || + !winNameCompare (end, "M")) + units = 1000000; + else + { + winDebug ( "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + if (p->found) + freq *= (double) units; + } + else + { + winDebug ( "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + if (p->found) + { + p->value.freq.freq = freq; + p->value.freq.units = units; + } + } + break; + case OPTV_NONE: + /* Should never get here */ + p->found = FALSE; + break; + } + if (p->found) + { + winDebug ("Option \"%s\"", p->name); + if (!(p->type == OPTV_BOOLEAN && *s == 0)) + { + winDebug (" \"%s\"", s); + } + winDebug ("\n"); + } + } + else if (p->type == OPTV_BOOLEAN) + { + /* Look for matches with options with or without a "No" prefix. */ + char *n, *newn; + OptionInfoRec opt; + + n = winNormalizeName (p->name); + if (!n) + { + p->found = FALSE; + return FALSE; + } + if (strncmp (n, "no", 2) == 0) + { + newn = n + 2; + } + else + { + free (n); + n = malloc (strlen (p->name) + 2 + 1); + if (!n) + { + p->found = FALSE; + return FALSE; + } + strcpy (n, "No"); + strcat (n, p->name); + newn = n; + } + if ((s = winFindOptionValue (options, newn)) != NULL) + { + if (GetBoolValue (&opt, s)) + { + p->value.bool = !opt.value.bool; + p->found = TRUE; + } + else + { + winDebug ( "Option \"%s\" requires a boolean value\n", newn); + p->found = FALSE; + } + } + else + { + p->found = FALSE; + } + if (p->found) + { + winDebug ("Option \"%s\"", newn); + if (*s != 0) + { + winDebug (" \"%s\"", s); + } + winDebug ("\n"); + } + free (n); + } + else + { + p->found = FALSE; + } + return p->found; +} + + +static Bool +configLayout (serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, + char *default_layout) +{ +#if 0 +#pragma warn UNIMPLEMENTED +#endif + return TRUE; +} + + +static Bool +configImpliedLayout (serverLayoutPtr servlayoutp, + XF86ConfScreenPtr conf_screen) +{ +#if 0 +#pragma warn UNIMPLEMENTED +#endif + return TRUE; +} + + +static Bool +GetBoolValue (OptionInfoPtr p, const char *s) +{ + if (*s == 0) + { + p->value.bool = TRUE; + } + else + { + if (winNameCompare (s, "1") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "on") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "true") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "yes") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "0") == 0) + p->value.bool = FALSE; + else if (winNameCompare (s, "off") == 0) + p->value.bool = FALSE; + else if (winNameCompare (s, "false") == 0) + p->value.bool = FALSE; + else if (winNameCompare (s, "no") == 0) + p->value.bool = FALSE; + } + return TRUE; +} +#endif + + +char * +winNormalizeName (const char *s) +{ + char *ret, *q; + const char *p; + + if (s == NULL) + return NULL; + + ret = malloc (strlen (s) + 1); + for (p = s, q = ret; *p != 0; p++) + { + switch (*p) + { + case '_': + case ' ': + case '\t': + continue; + default: + if (isupper ((int)*p)) + *q++ = tolower ((int)*p); + else + *q++ = *p; + } + } + *q = '\0'; + return ret; +} + |