[as-devel] Re: Re: [julian@catchen.org: Zharf Patch]

Sasha Vasko/OSCA/Courts/Judicial(sashav@sprintmail.com)
Tue, 20 Mar 2001 16:27:06 -0600


> Sasha,
> 
> So, after I finish cleaning up Zharf I will try to understand the 
> new drawing code in order to convert wharf over.  Do you have some
> examples that use the new code that I sould use as a model for wharf?

> Thanks,

> julian


I'm glad you asked.

Examples you may find in libasGadget/wmdecor.c and libasGadget/wmicon.c
There is also somewhat older example in src/test. You can use src/test 
as a simple test bed for different ideas, by the way - just create your own 

function. 

The plan I had was to either use wmdecor code directly since Wharf buttons 
can be considered somewhat similar to regular window decorations, except 
for 
the fact that you cannot have frame nor handlebar and titlebar can only 
have label, 
or create similar gadget in libasGadget specifically for Wharf 
buttons/folders. 

Below is exerpt from my older mail - it does gives some abstructs on how 
drawing is done nowdays :

Ok, let me outline the direction in which AfterStep is moving as well as 
describe existing infrastructure and what still needs to be done.

The direction in which AS is moving is not much different from what E and 
WM,
and which is logical: delegate all the drawing code and all the 
configuration 
read/write code out of the core window manager and into the libs, as well 
as wrap 
most used protocol calls into higher level interfaces. The reason for that 
can be
seen in AS 1.8.* series - if you compare different modules - you'd see that 
large 
portion of those is same from module to module. It makes perfect sense from 
the 
p[oint of view of extensibility and maintainability to move it all out into 
the lib,
shared by all the modules.

Respectively AfterSTep 1.9.* (CVS) series now have the following libraries 
:

libafterstep  - core library - includes applcation initialization,
memory management/audit, inter-module communications, generic container 
data structure 
management - hashes and vectors, string manipulation, regexp, parsing, 
and several higher level data structures such as aggregated hints, database 
entries, 
Feel, etc., It also includes most of the Xlib wrapers that are not related 
to 
image processing.

libasGUI - graphics library - includes image loading and manipulation code, 
gradients,
balloons, and higher level image management functionality, such as 
MyTexture, MyStyle,
MyLook. This also includes low level widget drawing/layouting code for 
MyWidgets.

libasGadget - higher level drawing library - it is based on MyLook and 
MyWidget and provides
for high level meaningfull widgets/gadgets, such as Titlebar, Frame window, 
Icon, etc.

libasConfig - configuration reading/writing library - This library is based 
on parser 
module from the core library and allows for reading text configuration into 
high level
module-specific data structures, as well as writing it back out into the 
text file.

Now let me stop a little bit on the way AS is performing actuall 
drawing/image maagement.
We utilize several levels of abstruction : 
1)On the lowest level we have actuall image files that we load into pixmaps
2)Pixmaps gets aggregated into ASIcon structure, that holds actuall pixmap, 

its mask, and size
3)ASIcon is aggregated into MyTexture structure: MyTexture provides for 
unified interface
to any drawing method, regardless of low level data used - It allows for 
scaling/tiling/rotating/shading/tinting of pixmaps, pixmap masks, gradients 
and transparency.
4)MyTexture is aggregated into MyStyle together with some other attributes, 
such as font,
back and fore colors, text style
5)MyStyles are named and gathered together into hash tablethat is part of 
MyLook structure.
There is also gloabl hash table like that that should be used only by 
modules.

The actuall process of drawing consists of several steps : 
1) get MyStyle by name from MyLook.
2) use high level mystyle_* API to obtain pixmap of desired size with 
needed drawing on it.
3) copy this pixmap to window, or set window's background to this pixmap. 
You can actually draw directly to the window with MyStyles but it is deemed 
inefficient, 
since you need to regenerate your drawing each time window is Exposed. Its 
always better 
to cache drawing in pixmap.

There are 2 approaches to drawing text.
1) traditional: we use Xlib calls XDrawText and the likes to perform text 
drawing
2) AS special: we draw text on 1bit mask using Xlib calls, then create 
another pixmap
with foreground texture and then simply using mask while copying fore 
pixmap to the window.

1st approach is usefull for the dynamic text and has drawbacks of not being 
able to 
rotate and texturize text.
2nd approach allows for texturized and rotated text and often is faster 
then first approach,
it has the drawback that you need to regenerate the mask each time your 
text changes, thus
potentially increasing amount of resources used.

All is fine so far, but the best thing is still not covered: MyWidgets.
MyWidgets is the next level abstruction that allows for building interfaces 
without 
worreing about actuall drawing at all. MyWidgets are different from 
traditional 
widget libraries in the way that it concentrates on drawing, leaving 
interface semantics
out. It provides very limited number of essential building blocks: 
Empty, Icon, Label, Widget; and allows for layouting of this blocks similar 
to HTML tables.
Out of this elements only Widget has its own window and allows for nested 
layouts with 
more widgets in it. Widget could be container or simple. Container's window 
is provided 
from outside, and widget does not do any drawing in it - it only 
resizes/moves it when 
needed. Simple widget has complete control over its window. Widget has 
member layout that 
represents 2 dimentional table of subparts. For ech part row and column of 
its 
topleft corner has to be specifyed, as well as number of rows/columns 
spanned. This allows
for overlapping layout. Each part may have fixed or variable size. If the 
size is variable
it will be automagocally recalculated based on the widget size. Each part 
is distinguished 
by its context id. MyWidgets provides event handling functionality for 
simple events 
allowing for fast retrival of affected context id and window, as well as 
handling Exposes 
and button presses. Balloons are also displayed when we move from widget to 
widget. 
lots of convinience functionality is provided as well for 
enabling/disabling,
shading/unshading and so on based on context id.

We use  MyWidgets then to build bigger blocks such as titlebars, window 
manager 
frame decorations and such. All this high level code is located in 
libasGadget.

Now going back to overall AfterStep structure, I'd like to point out that 
all of the above
is in the libraries, and therefore can be used in modules as well. In fact 
all the 
modules has to be rewritten to use it. Even if it may sound like alot of 
work it really 
is not, and I'd expect reduction in code in average module by as much as 
60-70%%.

Another revolutionary development in AS is new hints management. Basically 
there are 
so many different window configuring hints out there: ICCCM, Motif, Old 
Gnome, 
Extended WM, transient owner's, group owner's, afterstep database. They all 
exist in 
parallel and quite often overlap. What we do is we read them all and then 
merge 
together into 2 non-overlapping structures : ASHints and ASStatusHints. 
later on we
using those structures throughtout the entire scope of AS, without ever 
worreying 
where those came from.

Basically both afterstep proper and modules should be no more then simple 
state 
machines from now on. Example can be seen in afterstep proper as I already 
rewrote it - 
it is now about 55% of its size as it was in 1.8, despite the fact that it 
is capable of
about twice as much as it used to. There are several items that still needs 
to be 
implemented, like window movement, but that would not bring size up too 
much.