gnu.x11
Class Request

java.lang.Object
  extended by gnu.x11.Data
      extended by 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:

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

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.


Nested Class Summary
static class Request.Poly
          Aggregate poly drawing requests.
static class Request.ValueList
          Aggregate value list requests.
 
Field Summary
 int length
           
 
Fields inherited from class gnu.x11.Data
data, index, offset
 
Constructor Summary
Request()
           
Request(Display display, int opcode, boolean b, int unit)
           
Request(Display display, int opcode, int unit)
           
Request(Display display, int opcode, int i, int unit)
           
 
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
 

Field Detail

length

public int length
Constructor Detail

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)
Method Detail

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