gnu.x11
Class Request
java.lang.Object
gnu.x11.Data
gnu.x11.Request
- Direct Known Subclasses:
- Request.Poly, Request.ValueList
public class Request
- extends Data
Request to X server.
Aggregate Requests
In C xlib, "similar requests" will be aggregated into one if possible.
For example, setting foreground followed by setting background of a gc
can be aggregated into one ChangeGC
request (as suggested
in Section 1.4.1 "Client Library Implementation" on page 36 of X
Protocol Reference Manual by Adrian Nye).
Details on how C xlib implements this feature is unclear (missing?)
because of arcane C macros. Without a documented reference
implementation, an early attempt to implement such a feature into this
library was a failure. We did not have a clear mind of the exact
conditions of when a request can be aggregated into previous requests in
the queue.
There are two kinds of requests that can be aggregated:
- value list requests
ChangeGC
ChangeKeyboardControl
ChangeWindowAttributes
ConfigureWindow
)
- poly drawing requests
FillPoly
Poly/Fill Arc
PolyLine
PolyPoint
Poly/Fill Rectangle
PolySegment
Note that PolyText
cannot be aggregated easily in general
because of the presence of x
and y
parameter.
Besides of being the same protocol opcode, two requests to be aggregated
have to be acting on the same drawable and using the same gc. Special
care must be taken for different coordinate_mode
. Moreover,
the gc must not have been changed since the last poly request. That is,
we need to keep track of gc modification requests
(ChangeGC
, SetDashes
, and
SetClipRectangles
) to mark the respective gc "dirty".
However, there is one more critical condition that makes aggregating
poly drawing requests almost worthless: drawing order. For example,
given there are PolyRectangleRequest r1
and
PolyArcRequest r2
, even when a PolyRectangleRequest
r3
comes in and r1
and r3
are "similar"
(same opcode, same "clean" gc, same drawable), they cannot be aggregated
because of the drawing order. If aggregated, drawing r2
would overwrite r3
, producing an unintended result.
For value list requests, the conditions are less restrictive. Two
requests to be aggregated have to be of the same opcode code and acting
on the same object. However, there is also one critical condition: state
dependency. For example, two requests for setting a gc cannot be
aggregated if there is a drawing request in between. If aggregated, the
second background would be used instead of the first one. The same
applies to changing window attributes when in between there are other
requests that depends on the states of the window.
In conclusion, to aggregate poly drawing requests at maximum level,
we must identify all drawing requests in core and extension requests to
preserve the drawing order. The same applies to value list requests but
with more cases to be handled. At a lesser level (current implementation
of this library), we can aggregate a new request with only the last one
in the queue such that there are no order or dependency conditions. This
way convenience methods of
ChangeGC
ChangeKeyboardControl
ChangeWindowAttributes
ConfigureWindow
)
FillPoly
Poly/Fill Arc
PolyLine
PolyPoint
Poly/Fill Rectangle
PolySegment
such as GC.set_foreground(gnu.x11.Color)
can be used extensively
without generating extra requests. However, it fails to aggregate at
maximum level. For example, two requests for setting a gc will never be
aggregated (while it is safe to do so) if there is a request for
querying font in between.
[Sep 07, 00] Finally, in xlib.ps, I have found a note of xlib's
implementation of this feature, which is called "batching". A discussion
can be found in section C.4 "Graphics Batching" of Appendix C "Writing
Extensions to X" of the postscript document, or you can view it from
here. Basically xlib implements batching using the same technique
described above but with specialized buffers and less OOP.
Method Summary |
void |
init(Display display,
int opcode,
int second_field,
int unit)
|
void |
write(java.io.OutputStream out)
|
Methods inherited from class gnu.x11.Data |
byte_to_string, len, len, n, np, p, pad, read_boolean, read_double, read_float, read_string, read1, read2, read4_boolean, read4, read8, to_string, toString, unit, unit, unit, write_string16, write_string16, write_unused, write1_unused, write1, write1, write1, write1, write1, write1, write1, write1, write1, write1, write1, write1, write1, write1, write2_unused, write2, write2, write2, write2, write2, write2, write2, write2, write2, write2, write2, write2, write2, write2, write3_unused, write4_unused, write4, write4, write4, write4, write4, write4, write4, write4, write4, write4, write4, write4, write4, write4, write4, write8, write8, write8, write8, write8, write8, write8, write8 |
Methods inherited from class java.lang.Object |
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait |
length
public int length
Request
public Request()
Request
public Request(Display display,
int opcode,
int i,
int unit)
Request
public Request(Display display,
int opcode,
boolean b,
int unit)
Request
public Request(Display display,
int opcode,
int unit)
init
public void init(Display display,
int opcode,
int second_field,
int unit)
write
public void write(java.io.OutputStream out)
throws java.io.IOException
- Throws:
java.io.IOException