diff options
Diffstat (limited to 'specs/shm.xml')
-rw-r--r-- | specs/shm.xml | 476 |
1 files changed, 476 insertions, 0 deletions
diff --git a/specs/shm.xml b/specs/shm.xml new file mode 100644 index 0000000..f6ad347 --- /dev/null +++ b/specs/shm.xml @@ -0,0 +1,476 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" +[ +<!ENTITY % defs SYSTEM "defs.ent"> %defs; +]> + + +<!-- lifted from troff+ms+XMan by doclifter --> +<book id="shm"> + +<bookinfo> + <title>MIT-SHM(The MIT Shared Memory Extension)</title> + <subtitle>How the shared memory extension works</subtitle> + <authorgroup> + <author> + <firstname>Jonathan</firstname><surname>Corbet</surname> + <affiliation> + <orgname>National Center for Atmospheric Research</orgname> + <orgdiv>Atmospheric Technology Division</orgdiv> + </affiliation> + <email>corbet@ncar.ucar.edu</email> + </author> + <editor> + <firstname>Keith</firstname><surname>Packard</surname> + <affiliation><orgname>MIT X Consortium</orgname></affiliation> + </editor> + </authorgroup> + <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> + <releaseinfo>Version 1.0</releaseinfo> + <copyright><year>1991</year><holder>X Consortium</holder></copyright> + +<legalnotice> +<para> +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: +</para> +<para> +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. +</para> +<para> +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 +X CONSORTIUM 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. +</para> +<para> +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. +</para> +<para>X Window System is a trademark of The OpenGroup.</para> +</legalnotice> + +<abstract> +<para> +This document briefly describes how to use the MIT-SHM shared memory +extension. I have tried to make it accurate, but it would not surprise me +if some errors remained. If you find anything wrong, do let me know and I +will incorporate the corrections. Meanwhile, please take this document "as +is" (eman improvement over what was there before, but certainly not the +definitive word.) +</para> +</abstract> + +</bookinfo> + +<chapter id="REQUIREMENTS"> +<title>REQUIREMENTS</title> +<para> +The shared memory extension is provided only by some X servers. To find out +if your server supports the extension, use xdpyinfo(1). In particular, to +be able to use this extension, your system must provide the SYSV shared +memory primitives. There is not an mmap-based version of this extension. +To use shared memory on Sun systems, you must have built your kernel with +SYSV shared memory enabled -- which is not the default configuration. +Additionally, the shared memeory maximum size will need to be increased on +both Sun and Digital systems; the defaults are far too small for any useful +work. +</para> +</chapter> + +<chapter id="WHAT_IS_PROVIDED"> +<title>WHAT IS PROVIDED</title> + +<para> +The basic capability provided is that of shared memory XImages. This is +essentially a version of the ximage interface where the actual image data +is stored in a shared memory segment, and thus need not be moved through +the Xlib interprocess communication channel. For large images, use of this +facility can result in some real performance increases. +</para> + +<para> +Additionally, some implementations provided shared memory pixmaps. These +are 2 dimensional arrays of pixels in a format specified by the X server, +where the image data is stored in the shared memory segment. Through use of +shared memory pixmaps, it is possible to change the contents of these +pixmaps without using any Xlib routines at all. Shared memory pixmaps can +only be supported when the X server can use regular virtual memory for +pixmap data; if the pixmaps are stored in some magic graphics hardware, your +application will not be able to share them with the server. Xdpyinfo(1) +doesn't print this particular nugget of information. +</para> +</chapter> + +<chapter id="HOW_TO_USE_THE_SHARED_MEMORY_EXTENSION"> +<title>HOW TO USE THE SHARED MEMORY EXTENSION</title> +<para> +Code which uses the shared memory extension must include a number of header +files: +</para> + +<literallayout class="monospaced"> +#include <X11/Xlib.h> /* of course */ +#include <sys/ipc.h> +#include <sys/shm.h> +#include <X11/extensions/XShm.h> +</literallayout> + +<para> +Of course, if the system you are building on does not support shared +memory, the file XShm.h may not be present. You may want to make +liberal use of #ifdefs. +</para> + +<para> +Any code which uses the shared memory extension should first check to see +that the server provides the extension. You could always be running over +the net, or in some other environment where the extension will not work. +To perform this check, call either +</para> + +<funcsynopsis id='XShmQueryExtension'> +<funcprototype> + <funcdef>Status <function>XShmQueryExtension</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<para> +or +</para> + +<funcsynopsis id='XShmQueryVersion'> +<funcprototype> + <funcdef>Status <function>XShmQueryVersion</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>int <parameter>*major</parameter></paramdef> + <paramdef>int <parameter>*minor</parameter></paramdef> + <paramdef>Bool <parameter>*pixmaps</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<para> +Where "display" is, of course, the display on which you are running. If +the shared memory extension may be used, the return value from either +function will be True; otherwise your program should operate using +conventional Xlib calls. When the extension is available, +\fCXShmQueryVersion\fP also returns "major" and "minor" which are the +version numbers of the extension implementation, and "pixmaps" which is +True iff shared memory pixmaps are supported. +</para> +</chapter> + +<chapter id="USE_OF_SHARED_MEMORY_XIMAGES"> +<title>USE OF SHARED MEMORY XIMAGES</title> +<para> +The basic sequence of operations for shared memory XImages is as follows: +</para> + +<orderedlist> + <listitem> + <para> +Create the shared memory XImage structure + </para> + </listitem> + <listitem> + <para> +Create a shared memory segment to store the image data + </para> + </listitem> + <listitem> + <para> +Inform the server about the shared memory segment + </para> + </listitem> + <listitem> + <para> +Use the shared memory XImage, much like a normal one. + </para> + </listitem> +</orderedlist> + +<para> +To create a shared memory XImage, use: +</para> + +<funcsynopsis id='XShmCreateImage'> +<funcprototype> + <funcdef>XImage <function>*XShmCreateImage</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>Visual <parameter>*visual</parameter></paramdef> + <paramdef>unsigned int <parameter>depth</parameter></paramdef> + <paramdef>int <parameter>format</parameter></paramdef> + <paramdef>char <parameter>*data</parameter></paramdef> + <paramdef>XShmSegmentInfo <parameter>*shminfo</parameter></paramdef> + <paramdef>unsigned int <parameter>width</parameter></paramdef> + <paramdef>unsigned int <parameter>height</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<para> +Most of the arguments are the same as for XCreateImage; I will not go +through them here. Note, however, that there are no "offset", "bitmap_pad", +or "bytes_per_line" arguments. These quantities will be defined by the +server itself, and your code needs to abide by them. Unless you have already +allocated the shared memory segment (see below), you should pass in NULL for +the "data" pointer. +</para> + +<para> +There is one additional argument: "shminfo", which is a pointer to a +structure of type XShmSegmentInfo. You must allocate one of these +structures such that it will have a lifetime at least as long as that of +the shared memory XImage. There is no need to initialize this structure +before the call to XShmCreateImage. +</para> + +<para> +The return value, if all goes well, will be an XImage structure, which you +can use for the subsequent steps. +</para> + +<para> +The next step is to create the shared memory segment. This is +best done after the creation of the XImage, since you need to make use of +the information in that XImage to know how much memory to allocate. To +create the segment, you need a call like: +</para> + + +<literallayout class="monospaced"> +shminfo.shmid = shmget (IPC_PRIVATE, + image->bytes_per_line * image->height, IPC_CREAT|0777); +</literallayout> + +<para> +(assuming that you have called your shared memory XImage "image"). You +should, of course, follow the Rules and do error checking on all of these +system calls. Also, be sure to use the bytes_per_line field, not the width +you used to create the XImage as they may well be different. +</para> + +<para> +Note that the shared memory ID returned by the system is stored in the +shminfo structure. The server will need that ID to attach itself to the +segment. +</para> + +<para> +Also note that, on many systems for security reasons, the X server +will only accept to attach to the shared memory segment if it's +readable and writeable by "other". On systems where the X server is +able to determine the uid of the X client over a local transport, the +shared memory segment can be readable and writeable only by the uid of +the client. +</para> + +<para> +Next, attach this shared memory segment to your process: +</para> + +<para> +shminfo.shmaddr = image->data = shmat (shminfo.shmid, 0, 0); +</para> + +<para> +The address returned by shmat should be stored in *both* the XImage +structure and the shminfo structure. +</para> + +<para> +To finish filling in the shminfo structure, you need to decide how you want +the server to attach to the shared memory segment, and set the "readOnly" +field as follows. Normally, you would code: +</para> +<para> +shminfo.readOnly = False; +</para> + +<para> +If you set it to True, the server will not be able to write to this +segment, and thus XShmGetImage calls will fail. +</para> + +<para> +Finally, tell the server to attach to your shared memory segment with: +</para> + +<literallayout class="monospaced"> +Status XShmAttach (display, shminfo); +</literallayout> + +<para> +If all goes well, you will get a non-zero status back, and your XImage is +ready for use. +</para> + +<para> +To write a shared memory XImage into an X drawable, use XShmPutImage: +</para> + +<funcsynopsis id='XShmPutImage'> +<funcprototype> + <funcdef>Status <function>XShmPutImage </function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>Drawable <parameter>d</parameter></paramdef> + <paramdef>GC <parameter>gc</parameter></paramdef> + <paramdef>XImage <parameter>*image</parameter></paramdef> + <paramdef>int <parameter>src_x</parameter></paramdef> + <paramdef>int <parameter>src_y</parameter></paramdef> + <paramdef>int <parameter>dest_x</parameter></paramdef> + <paramdef>int <parameter>dest_y</parameter></paramdef> + <paramdef>unsigned int <parameter>width</parameter></paramdef> + <paramdef>unsigned int <parameter>height</parameter></paramdef> + <paramdef>bool <parameter>send_event</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<para> +The interface is identical to that of XPutImage, so I will spare my fingers +and not repeat that documentation here. There is one additional parameter, +however, called "send_event". If this parameter is passed as True, the +server will generate a "completion" event when the image write is complete; +thus your program can know when it is safe to begin manipulating the shared +memory segment again. +</para> + +<para> +The completion event has type XShmCompletionEvent, which is defined as the +following: +</para> + +<literallayout class="monospaced"> +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed */ + Bool send_event; /* true if came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Drawable drawable; /* drawable of request */ + int major_code; /* ShmReqCode */ + int minor_code; /* X_ShmPutImage */ + ShmSeg shmseg; /* the ShmSeg used in the request */ + unsigned long offset; /* the offset into ShmSeg used */ +} XShmCompletionEvent; +</literallayout> + +<para> +The event type value that will be used can be determined at run time with a +line of the form: +</para> + +<para> +int CompletionType = XShmGetEventBase (display) + ShmCompletion; +</para> + +<para> +If you modify the shared memory segment before the arrival of the +completion event, the results you see on the screen may be inconsistent. +</para> + +<para> +To read image data into a shared memory XImage, use the following: +</para> + +<funcsynopsis id='XShmGetImage'> +<funcprototype> + <funcdef>Status <function>XShmGetImage </function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>Drawable <parameter>d</parameter></paramdef> + <paramdef>XImage <parameter>*image</parameter></paramdef> + <paramdef>int <parameter>x</parameter></paramdef> + <paramdef>int <parameter>y</parameter></paramdef> + <paramdef>unsigned long <parameter>plane_mask</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<para> +Where "display" is the display of interest, "d" is the source drawable, +"image" is the destination XImage, "x" and "y" are the offsets within +"d", and "plane_mask" defines which planes are to be read. +</para> + +<para> +To destroy a shared memory XImage, you should first instruct the server to +detach from it, then destroy the segment itself, as follows: +</para> + +<literallayout class="monospaced"> +XShmDetach (display, shminfo); +XDestroyImage (image); +shmdt (shminfo.shmaddr); +shmctl (shminfo.shmid, IPC_RMID, 0); +</literallayout> + +</chapter> + +<chapter id="USE_OF_SHARED_MEMORY_PIXMAPS"> +<title>USE OF SHARED MEMORY PIXMAPS</title> +<para> +Unlike X images, for which any image format is usable, the shared memory +extension supports only a single format (i.e. XYPixmap or ZPixmap) for the +data stored in a shared memory pixmap. This format is independent of the +depth of the image (for 1-bit pixmaps it doesn't really matter what this +format is) and independent of the screen. Use XShmPixmapFormat to get the +format for the server: +</para> + +<funcsynopsis id='XShmPixmapFormat'> +<funcprototype> + <funcdef>int <function>XShmPixmapFormat</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<para> +If your application can deal with the server pixmap data format (including +bits-per-pixel et al.), create a shared memory segment and "shminfo" +structure in exactly the same way as is listed above for shared memory +XImages. While it is, not strictly necessary to create an XImage first, +doing so incurs little overhead and will give you an appropriate +bytes_per_line value to use. +</para> + +<para> +Once you have your shminfo structure filled in, simply call: +</para> + +<funcsynopsis id='XShmCreatePixmap'> +<funcprototype> + <funcdef>Pixmap <function>XShmCreatePixmap</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>Drawable <parameter>d</parameter></paramdef> + <paramdef>char <parameter>*data</parameter></paramdef> + <paramdef>XShmSegmentInfo <parameter>*shminfo</parameter></paramdef> + <paramdef>unsigned int <parameter>width</parameter></paramdef> + <paramdef>unsigned int <parameter>height</parameter></paramdef> + <paramdef>unsigned int <parameter>depth</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<para> +The arguments are all the same as for XCreatePixmap, with two additions: +"data" and "shminfo". The second of the two is the same old shminfo +structure that has been used before. The first is the pointer to the shared +memory segment, and should be the same as the shminfo.shmaddr field. I am +not sure why this is a separate parameter. +</para> + +<para> +If everything works, you will get back a pixmap, which you can manipulate in +all of the usual ways, with the added bonus of being able to tweak its +contents directly through the shared memory segment. Shared memory pixmaps +are destroyed in the usual manner with XFreePixmap, though you should detach +and destroy the shared memory segment itself as shown above. +</para> +</chapter> +</book> |