Update Xserver-spec for new devPrivates API

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Patrick E. Kane <pekane52@gmail.com>
This commit is contained in:
Alan Coopersmith 2010-07-22 23:57:57 -07:00
parent 40d598a4f8
commit a817271d46

View File

@ -92,6 +92,13 @@
<authorinitials>efw</authorinitials> <authorinitials>efw</authorinitials>
<revremark>Revised for devPrivates changes</revremark> <revremark>Revised for devPrivates changes</revremark>
</revision> </revision>
<revision>
<revnumber>3.5</revnumber>
<date>July 2010</date>
<authorinitials>ac</authorinitials>
<revremark>Revised for Xorg 1.9 devPrivates changes
and 1.8 CreateNewResourceType changes</revremark>
</revision>
</revhistory> </revhistory>
<legalnotice> <legalnotice>
<para>Copyright &#xA9; 1994 X Consortium, Inc., 2004 X.org Foundation, Inc.</para> <para>Copyright &#xA9; 1994 X Consortium, Inc., 2004 X.org Foundation, Inc.</para>
@ -4808,32 +4815,68 @@ Two new extensibility concepts have been developed for release 4, Wrappers
and devPrivates. These replace the R3 GCInterest queues, which were not a and devPrivates. These replace the R3 GCInterest queues, which were not a
general enough mechanism for many extensions and only provided hooks into a general enough mechanism for many extensions and only provided hooks into a
single data structure. devPrivates have been revised substantially for single data structure. devPrivates have been revised substantially for
X.org X server relase 1.5.</para> X.Org X server release 1.5, and updated again for the 1.9 release.</para>
<section> <section>
<title>devPrivates</title> <title>devPrivates</title>
<para> <para>
devPrivates provides a way to attach arbitrary private data to various server structures. devPrivates provides a way to attach arbitrary private data to various server structures.
Any structure which contains a <structfield>devPrivates</structfield> field of Any structure which contains a <structfield>devPrivates</structfield> field of
type <type>PrivateRec</type> supports this mechanism. Private data can be allocated at type <type>PrivateRec</type> supports this mechanism. Some structures allow
any time during an object's life cycle and callbacks are available to initialize and clean allocating space for private data after some objects have been created, others
up allocated space.</para> require all space allocations be registered before any objects of that type
are created. <filename class="headerfile">Xserver/include/privates.h</filename>
lists which of these cases applies to each structure containing
<structfield>devPrivates</structfield>.</para>
<para>
To request private space, use
<blockquote><programlisting>
Bool dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size);
</programlisting></blockquote>
The first argument is a pointer to a <type>DevPrivateKeyRec</type> which
will serve as the unique identifier for the private data. Typically this is
the address of a static <type>DevPrivateKeyRec</type> in your code.
The second argument is the class of objects for which this key will apply.
The third argument is the size of the space being requested, or
<constant>0</constant> to only allocate a pointer that the caller will manage.
If space is requested, this space will be automatically freed when the object
is destroyed. Note that a call to <function>dixSetPrivate</function>
that changes the pointer value may cause the space to be unreachable by the caller, however it will still be automatically freed.
The function returns <literal>TRUE</literal> unless memory allocation fails.
If the function is called more than once on the same key, all calls must use
the same value for <type>size</type> or the server will abort.</para>
<para>
To request private space and have the server manage the key, use
<blockquote><programlisting>
DevPrivateKey dixCreatePrivateKey(DevPrivateType type, unsigned size);
</programlisting></blockquote>
The <parameter>type</parameter> and <parameter>size</parameter> arguments are
the same as those to <function>dixRegisterPrivateKey</function> but this
function allocates a <type>DevPrivateKeyRec</type> and returns a pointer to it
instead of requiring the caller to pass a pointer to an existing structure.
The server will free it automatically when the privates system is restarted
at server reset time.</para>
<para> <para>
To attach a piece of private data to an object, use: To attach a piece of private data to an object, use:
<blockquote><programlisting> <blockquote><programlisting>
int dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val) void dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
</programlisting></blockquote> </programlisting></blockquote>
The first argument is the address of the <structfield>devPrivates</structfield> field The first argument is the address of the <structfield>devPrivates</structfield>
in the target structure. This field is managed privately by the DIX layer and field in the target structure. This field is managed privately by the DIX
should not be directly modified. The second argument is some address value which layer and should not be directly modified. The second argument is a pointer
will serve as the unique identifier for the private data. Typically this is the address to the <type>DevPrivateKeyRec</type> which you registered with
of some global variable in your code. Only one piece of data with a given key can be attached to an object. However, you <function>dixRegisterPrivateKey</function> or allocated with
can use the same key to store data in any object that supports the devPrivates mechanism. The third <function>dixCreatePrivateKey</function>. Only one
argument is the value to store.</para> piece of data with a given key can be attached to an object, and in most cases
each key is specific to the type of object it was registered for. (An
exception is the PRIVATE_XSELINUX class which applies to multiple object types.)
The third argument is the value to store.</para>
<para> <para>
If private data with the given key is already associated with the object, <function>dixSetPrivate</function> will If private data with the given key is already associated with the object,
overwrite the old value with the new one. Otherwise, new space will be allocated to hold the pointer value. <function>dixSetPrivate</function> will overwrite the old value with the
The function returns <literal>TRUE</literal> unless memory allocation fails, but note that since memory allocation only new one.</para>
occurs on the first reference to the private data, all subsequent calls are guaranteed to succeed.</para>
<para> <para>
To look up a piece of private data, use one of: To look up a piece of private data, use one of:
@ -4842,56 +4885,22 @@ To look up a piece of private data, use one of:
pointer *dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key) pointer *dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
</programlisting></blockquote> </programlisting></blockquote>
The first argument is the address of the <structfield>devPrivates</structfield> field The first argument is the address of the <structfield>devPrivates</structfield> field
in the target structure. The second argument is the key to look up. If private data with the given key is already associated in the target structure. The second argument is the key to look up.
with the object, <function>dixLookupPrivate</function> will return the stored pointer value while <function>dixLookupPrivateAddr</function> If a non-zero size was given when the key was registered, or if private data
will return the address of the stored pointer. Otherwise, new space will be first allocated to hold the pointer value with the given key is already associated with the object, then
and it will be initialized to NULL. Both functions return <literal>NULL</literal> if memory allocation fails, but note that <function>dixLookupPrivate</function> will return the pointer value
since memory allocation only occurs on the first reference to the private data, all subsequent calls are guaranteed to succeed.</para> while <function>dixLookupPrivateAddr</function>
will return the address of the pointer.</para>
<para> <para>
To request pre-allocated private space, use When implementing new server resource objects that support devPrivates, there
<blockquote><programlisting> are four steps to perform:
int dixRequestPrivate(const DevPrivateKey key, unsigned size) Add a type value to the <type>DevPrivateType</type> enum in
</programlisting></blockquote> <filename class="headerfile">Xserver/include/privates.h</filename>,
The first argument is the key for which space is being requested. The second argument is the size of the space being requested. declare a field of type <type>PrivateRec *</type> in your structure;
After this function has been called,
future calls to <function>dixLookupPrivate</function> or <function>dixLookupPrivateAddr</function> that cause the private pointer
to be initially allocated will also allocate <varname>size</varname> bytes of space cleared to zero and initialize the private pointer to point
to this space instead of <literal>NULL</literal>. This space will be automatically freed. Note that a call to <function>dixSetPrivate</function>
that changes the pointer value may cause the space to be unreachable by the caller, however it will still be automatically freed.
The function returns <literal>TRUE</literal> unless memory allocation fails. If the function is called more than once, the largest value
of <type>size</type> is used.</para>
<para>
To set callbacks for initializing and cleaning up private space, use
<blockquote><programlisting>
typedef struct {
DevPrivateKey key;
pointer *value;
} PrivateCallbackRec;
int dixRegisterPrivateInitFunc(const DevPrivateKey key,
CallbackProcPtr callback,
pointer userdata)
int dixRegisterPrivateDeleteFunc(const DevPrivateKey key,
CallbackProcPtr callback,
pointer userdata)
</programlisting></blockquote>
The first argument is the key for which the callbacks are being registered. The second argument is the callback function. The third argument
will be passed as the user data argument to the callback function when it is called. The call data argument to the callback is a pointer to
a structure of type <type>PrivateCallbackRec</type>.</para>
<para>
The init callback is called immediately after new private space has been allocated for the given key. The delete callback is called immediately
before the private space is freed when the object is being destroyed. The <type>PrivateCallbackRec</type> structure contains the devPrivate key
and the address of the private pointer. The init callback may be used to initialize any pre-allocated space requested by
<function>dixRequestPrivate</function>, while the delete callback may be used to free any data stored there. However the callbacks are called even
if no pre-allocated space was requested.</para>
<para>
When implementing new server resource objects that support devPrivates, there are three steps to perform:
Declare a field of type <type>PrivateRec *</type> in your structure;
initialize this field to <literal>NULL</literal> when creating any objects; and initialize this field to <literal>NULL</literal> when creating any objects; and
call the <function>dixFreePrivates</function> function, passing in the field value, when freeing any objects.</para> when freeing any objects call the <function>dixFreePrivates</function> or
<function>dixFreeObjectWithPrivates</function> function.</para>
</section> </section>
<section> <section>
<title>Wrappers</title> <title>Wrappers</title>