ftp.nice.ch/Attic/openStep/implementation/gnustep/sources/objcX-0.87.tgz#/objcX-0.87/dpsclient

CGTMatrix.h
[View CGTMatrix.h] 
CGTMatrix.m
[View CGTMatrix.m] 
DrawContext.h
[View DrawContext.h] 
DrawContext.m
[View DrawContext.m] 
DrawContextWraps.h
[View DrawContextWraps.h] 
DrawContextWraps.m
[View DrawContextWraps.m] 
Makefile.in
 
README
 
XtDrawContext.h
[View XtDrawContext.h] 
XtDrawContext.m
[View XtDrawContext.m] 
XtDrawContextWraps.m
[View XtDrawContextWraps.m] 
XtDrawObject.h
[View XtDrawObject.h] 
XtDrawObject.m
[View XtDrawObject.m] 
XtDrawPrivate.h
[View XtDrawPrivate.h] 
XtGState.h
[View XtGState.h] 
XtGState.m
[View XtGState.m] 
XtGStateOps.h
[View XtGStateOps.h] 
cgt.c
[View cgt.c] 
cgt.h
[View cgt.h] 
dpsGNU.h
[View dpsGNU.h] 
dpsNeXT.h
[View dpsNeXT.h] 
dpsclient.h
[View dpsclient.h] 
dpsfriends.h
[View dpsfriends.h] 
event.h
[View event.h] 
psops.h
[View psops.h] 
wraps.h
[View wraps.h] 
xtcontext.m
[View xtcontext.m] 
xtgstate.h
[View xtgstate.h] 
xtpsops.m
[View xtpsops.m] 
xttools.c
[View xttools.c] 
xttools.h
[View xttools.h] 
xtwraps.m
[View xtwraps.m] 
xwfriends.h
[View xwfriends.h] 

README

Introduction:
------------

This directory contains implementations of interfaces to various
drawing models. The main interface is the DrawContext class, which is
an abstract class that basically defines the interface methods (which
correspond to DPS function calls). From here one can create a concrete
subclass (e.g. XtDrawContext), which maps these DPS calls to a specific
drawing model, such as the Xlib library. Basically, the intent is
to concentrate all the window/graphic/event specific code in a
DrawContext subclass, so that the appkit can be built independent of
the drawing model.  I think this is a good idea, because:

1 - one can switch contexts on the fly simply by instantiating a 
different subclass of DrawContext. For instance, one could instantiate a 
StreamContext to print Postscript to a stream.

2 - Whenever a good DPS implementation comes along, it can simply be 
dropped into objcX without changing multiple appkit classes - no code 
changes to either the appkit or any program based on the appkit!

3 - It provides a consistent, simple and fast interface for handling
graphics and events for X-Windows until someone wants a more
powerful system. 

4 - It may allow an easier transition from the current objcX focus on 
NeXTStep compatability to OpenStep compatability.

Getting Started
---------------

Using the Display PostScript interface is almost the same as
programming in PostScript.  If you already know PostScript, use of the
psops functions (specified in "psops.h") should be
transparent. For instance, drawing a grey, filled rectangle is as
simple as:

PSsetgray(0.5);
PSrectfill(10, 10, 200, 300);

or the slower way:

PSsetgray(0.5);
PSmoveto(10, 10);
PSlineto(200, 10);
PSlineto(200, 300);
PSlineto(10, 300);
PSclosepath();
PSfill();

Certain window system specific functions are not defined in Display
PostScript, but must be specified by the particular implementation.
In this case, the interface used by NeXT is closely followed.  These
window specific calls are defined in "wraps.h" and "dpsGNU.h", and
documented in the NeXTStep Reference Manual. As a minimum, you must
first create a Context, create/order a window, and tell the current
graphic state which window to draw in:

int number;
DPSContext context = DPSCreateContext(NULL, NULL, NULL, NULL);

PSwindow(10, 10, 200, 300, NX_RETAINED, &number);
PSorderwindow(NX_ABOVE, 0, number);

PSwindowdeviceround(number);

Once you create a context, it automatically becomes the current
context. Thus you can use any of the "PS" calls, and they will refer
to the most recently created context.

Implementation details (XtDrawContext):
---------------------------------------

The current XtDrawContext isn't intended to be even close to a
complete Postscript implementation.  However, it should be enough to
base a widget set on and do simple drawing. 

NOTE: Not all psops/wrap functions are implemented and there is NO
indication when you call a method that is not implemented. You need to
check if a function is implemented (in XtDrawContext AND XtGState (if
applicable)) before you call it, otherwise you will not get good
results (e.g. the stack might get messed up).

All files starting with xt or Xt are intended to be Xlib specific
implmentations of the DrawContext drawing model. The fact that the
files have the prefix "Xt" is probable a misnomer.  The only Xt
library call currently used is "XtWindow" as well as the "Widget"
structure, so that it can work with the current Motif implementation
of objcX. In the future, XtDrawContext will only use Xlib calls.

Drawing with XtDrawContext
--------------------------

If you plan on avoiding the psops functions, or you want to implement
more of the psops functions, here are some things to know about:

- Backing Store:

Backing store is probably one of the most fundamental aspects of a
windowing system.  Unfortunately, the X-Windows backing store protocol
leaves something to be desired.  This library, however, does implement
backing store in a somewhat non-intrusive way.  In a style similar to
NeXT's DPS, graphics written to buffered or retained windows is first
written to a backing pixmap, and then transfered to the window after
the drawing is complete.  When a window is exposed, the data from the
pixmap is automatically transfered to the window to refresh the parts
of the window that were previously covered.
    
What do you have to do?  

If you use psops calls, as with DPS, you need not worry about how
backing store or graphics is implemented. If you need to draw directly
using Xlib routines (not recommended - think about just implementing
the corresponding psops routine if it isn't already), you'll need to
know which drawable (from the current gstate) to draw to. You can
get the current gstate (XtGState object) using PSgstateobject.

- XWContext:

The X-Windows/objcX widget set has a sort-of context which holds
information about the X application, including the display, the
application colormap and the current gstate. Use PSxwcontext(&context)
to get the context for the application. The definitions for XWContext
are in dpsclient/xwfriends.h.
        
- XtGState:
    
Every view, when lockFocus'ed, has it's own gState, which you can
access through context->gstate.  The gstate is a XtGstate object which
incudes the following information:
    
    Coordinate transform matrix: Contains information about the current
    offset (origin), scale and rotation of the view.
    It's important that you use this offset when 
    you are drawing, so that buffering will work correctly.
    
    xgcntxt:  This is a standard X Graphic Context that you can modify and use 
    for your drawing (for example, to change the foreground color, etc).
    
    draw:  This is the drawable that you should send all drawing too (see 
    backing store).


After doing any drawing, you should also call setNeedsDisplay:, so that
the data is transfered from the pixmap to the window.  This is to
avoid unecessary transfering when no drawing was done.

- Coordinate system:
    
Note that the X-windows coordinate system places the origin in the
upper-left-hand corner, and y increases downward.  You should keep
track of this (of course, you do not need to worry about this when
using psops/wraps calls).

TODO list:
----------
2 - If NSInvocation ever gets working, we could support true
procedures and executable/use paths as well as error procedures (as 
in PostScript).

3 - Should make use of Dictionaries for font info and window devices -
this is slower and more work, but it may be more robust. At the
least, it follows the same model as PostScript.

4 - Implement arcs. I've already got the code, just need to integrate it.

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.