---
name: "asvisual"
section: "3x"
platform: "linux"
package: "libafterimage-dev"
version: "2.2.12-18"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/asvisual"
---

# asvisual(3x)

abstraction layer on top of X Visuals, focusing on color handling libAfterImage/asvisual.h

## NAME

**asvisual** - abstraction layer on top of X Visuals, focusing on color handling libAfterImage/asvisual.h

## NAMEasvisual

\- Defines abstraction layer on top of X Visuals, as well as several fundamental color datatypes.

## SEE ALSO

Structures:\
         ColorPair\
         ASVisual

Functions :\
   ASVisual initialization :\
         query\_screen\_visual(), setup\_truecolor\_visual(),\
         setup\_pseudo\_visual(), setup\_as\_colormap(),create\_asvisual(),\
         destroy\_asvisual()

  ASVisual encoding/decoding :\
         visual2visual\_prop(), visual\_prop2visual()

  ASVisual convenience functions :\
         create\_visual\_window(), create\_visual\_pixmap(),\
         create\_visual\_ximage()

Other libAfterImage modules :\
          ascmap.h asfont.h asimage.h asvisual.h blender.h export.h\
          import.h transform.h ximage.h

## AUTHOR

Sasha Vasko \<sasha at aftercode dot net\> libAfterImage/alpha

## FUNCTION

Alpha channel adds visibility parameter to color value. Alpha channel's value of 0xFF signifies complete visibility, while 0 makes pixel completely transparent.

## SOURCE

\#define ALPHA\_TRANSPARENT       0x00 #define ALPHA\_SEMI\_TRANSPARENT  0x7F #define ALPHA\_SOLID             0xFF

libAfterImage/ARGB32

## NAMEARGB32

\- main color datatype

## FUNCTION

ARGB32 is fundamental datatype that hold 32bit value corresponding to pixels color and transparency value (alpha channel) in ARGB colorspace. It is encoded as follows : Lowermost 8 bits - Blue channel bits 8 to 15     - Green channel bits 16 to 23    - Red channel bits 24 to 31    - Alpha channel

## EXAMPLE

ASTile.1

## SOURCE

typedef CARD32 ARGB32; #define ARGB32\_White            0xFFFFFFFF #define ARGB32\_Black            0xFF000000 /\* default background color is #FF000000 : \*/ #define ARGB32\_DEFAULT\_BACK\_COLOR   ARGB32\_Black

\#define ARGB32\_ALPHA\_CHAN       3 #define ARGB32\_RED\_CHAN         2 #define ARGB32\_GREEN\_CHAN       1 #define ARGB32\_BLUE\_CHAN        0 #define ARGB32\_CHANNELS         4

\#define MAKE\_ARGB32(a,r,g,b)    ((( (CARD32)a)        \<\<24)\| \\\
                                  ((((CARD32)r)&0x00FF)\<\<16)\| \\\
                                  ((((CARD32)g)&0x00FF)\<\<8 )\| \\\
                                  (( (CARD32)b)&0x00FF))

\#define MAKE\_ARGB32\_GREY8(a,l)  (((a)\<\<24)\|(((l)&0x00FF)\<\<16)\| \\\
                                  (((l)&0x00FF)\<\<8)\|((l)&0x00FF)) #define ARGB32\_ALPHA8(c)        (((c)\>\>24)&0x00FF) #define ARGB32\_RED8(c)          (((c)\>\>16)&0x00FF) #define ARGB32\_GREEN8(c)        (((c)\>\>8 )&0x00FF) #define ARGB32\_BLUE8(c)         ( (c)     &0x00FF) #define ARGB32\_CHAN8(c,i)       (((c)\>\>((i)\<\<3))&0x00FF) #define MAKE\_ARGB32\_CHAN8(v,i)  (((v)&0x0000FF)\<\<((i)\<\<3))

\#ifdef \_\_GNUC\_\_ #define ARGB32\_ALPHA16(c)       ({ CARD32 \_\_c = ARGB32\_ALPHA8(c); \_\_c \| (\_\_c\<\<8);}) #define ARGB32\_RED16(c)         ({ CARD32 \_\_c = ARGB32\_RED8(c); \_\_c \| (\_\_c\<\<8);}) #define ARGB32\_GREEN16(c)       ({ CARD32 \_\_c = ARGB32\_GREEN8(c); \_\_c \| (\_\_c\<\<8);}) #define ARGB32\_BLUE16(c)        ({ CARD32 \_\_c = ARGB32\_BLUE8(c); \_\_c \| (\_\_c\<\<8);}) #define ARGB32\_CHAN16(c,i)      ({ CARD32 \_\_c = ARGB32\_CHAN8(c,i); \_\_c \| (\_\_c\<\<8);}) #else #define ARGB32\_ALPHA16(c)       ((((c)\>\>16)&0x00FF00)\|(((c)\>\>24)&0x0000FF)) #define ARGB32\_RED16(c)         ((((c)\>\>8 )&0x00FF00)\|(((c)\>\>16)&0x0000FF)) #define ARGB32\_GREEN16(c)       (( (c)     &0x00FF00)\|(((c)\>\>8 )&0x0000FF)) #define ARGB32\_BLUE16(c)        ((((c)\<\<8) &0x00FF00)\|(((c)    )&0x0000FF)) #define ARGB32\_CHAN16(c,i)      ((ARGB32\_CHAN8(c,i)\<\<8)\|ARGB32\_CHAN8(c,i)) #endif

\#define MAKE\_ARGB32\_CHAN16(v,i) ((((v)&0x00FF00)\>\>8)\<\<((i)\<\<3))

libAfterImage/ARGB32\_manhattan\_distance()

## NAMEARGB32\_manhattan\_distance()

\- This function can be used to evaluate closeness of two colors.

## SYNOPSIS

long ARGB32\_manhattan\_distance (long a, long b);

## INPUTS

- a,

  b - ARGB32 color values to calculate Manhattan distance in between

## RETURN VALUE

returns calculated Manhattan distance. libAfterImage/ColorPart

## NAMEIC\_RED

\- red channel IC\_GREEN - green channel IC\_BLUE - blue channel IC\_ALPHA - alpha channel IC\_NUM\_CHANNELS - number of supported channels

## FUNCTION

Ids of the channels. These are basically synonyms to related ARGB32 channel numbers

## SOURCE

typedef enum {\
   IC\_BLUE   = ARGB32\_BLUE\_CHAN ,\
   IC\_GREEN  = ARGB32\_GREEN\_CHAN,\
   IC\_RED    = ARGB32\_RED\_CHAN  ,\
   IC\_ALPHA  = ARGB32\_ALPHA\_CHAN,\
   IC\_NUM\_CHANNELS = ARGB32\_CHANNELS } ColorPart;

libAfterImage/ColorPair

## NAMEColorPair

\- convenient structure to hold pair of colors.

## SOURCE

typedef struct ColorPair {\
   ARGB32 fore;\
   ARGB32 back; }ColorPair;

libAfterImage/ASVisual

## NAMEASVisual

\- an abstraction layer on top of X Server Visual.

## DESCRIPTION

This structure has been introduced in order to compensate for the fact that X may have so many different types of Visuals. It provides shortcuts to most Visual data, compensated for differences in Visuals. For PseudoColor visual it also contains preallocated set of colors. This colormap allows us to write XImages very fast and without exhausting available X colors. This colormap consist of 8, 64, or 4096 colors and constitutes fraction of colors available in particular colordepth. This colors are allocated to be evenly spread around RGB spectrum. Thus when converting from internal presentation - all we need to do is to discard unused bits, and use rest of them bits as an index in our colormap. Opposite conversion is much trickier and we engage into nasty business of having hash table mapping pixel values into colors, or straight table doing same in lower colordepths. Idea is that we do all internal processing in 32bit colordepth, and ASVisual provides us with means to convert it to actual X display format. Respectively ASVisual has methods to write out XImage lines and read XImage lines. ASVisual creation is a tricky process. Basically first we have to go through the list of available Visuals and choose the best suitable. Then based on the type of this Visual we have to setup our data members and method hooks. Several functions provided for that :\
  query\_screen\_visual()    - will lookup best suitable visual\
  setup\_truecolor\_visual() - will setup hooks if visual is TrueColor\
  setup\_pseudo\_visual()   - will setup hooks and data if Visual is\
                             PseudoColor.\
  setup\_as\_colormap()      - will preallocate colors for PseudoColor. Alternative to the above is :\
  create\_asvisual()        - it encapsulates all of the above\
                             functionality, and returns completely set\
                             up ASVisual object. Since Visual selected for ASVisual may differ from default ( we choose the best suitable ), all the window creation function must provide colormap and some other parameters, like border color for example. Thus we created some convenience functions. These should be used instead of standard Xlib calls :\
  create\_visual\_window() - to create window\
  create\_visual\_pixmap() - to create pixmap\
  create\_visual\_ximage() - to create XImage ASVisual could be dealolocated and its resources freed with :\
  destroy\_asvisual()

## EXAMPLE

asview.c: ASView

## SOURCE

typedef struct ASVisual {\
     Display      \*dpy;

    /\* This envvar will be used to determine what X Visual \
      \* (in hex) to use. If unset then best possible will \
      \* be selected automagically : \*/ #define ASVISUAL\_ID\_ENVVAR "AFTERIMAGE\_VISUAL\_ID"

    XVisualInfo   visual\_info;\
     /\* this things are calculated based on Visual : \*/\
     unsigned long rshift, gshift, bshift;\
     unsigned long rbits,  gbits,  bbits;\
     unsigned long true\_depth;   /\* could be 15 when X reports 16 \*/\
     Bool          BGR\_mode;\
     Bool          msb\_first;\
     /\* we must have colormap so that we can safely create windows\
      \* with different visuals even if we are in TrueColor mode : \*/\
     Colormap      colormap;\
     Bool          own\_colormap; /\* tells us to free colormap when we\
                                  \* done \*/\
     unsigned long black\_pixel, white\_pixel;\
     /\* for PseudoColor mode we need some more stuff : \*/\
     enum {\
         ACM\_None = 0,\
         ACM\_3BPP,\
         ACM\_6BPP,\
         ACM\_12BPP\
     } as\_colormap\_type ;    /\* there can only be 64 or 4096 entries\
                              \* so far ( 6 or 12 bpp) \*/\
     unsigned long \*as\_colormap; /\* array of preallocated colors for\
                                  \* PseudoColor mode \*/\
     union                       /\* reverse color lookup tables : \*/\
     {\
         ARGB32              \*xref;\
         struct ASHashTable  \*hash;\
     }as\_colormap\_reverse ;

    /\* different useful callbacks : \*/\
     CARD32 (\*color2pixel\_func)    ( struct ASVisual \*asv,\
                                     CARD32 encoded\_color,\
                                     unsigned long \*pixel);\
     void   (\*pixel2color\_func)    ( struct ASVisual \*asv,\
                                     unsigned long pixel,\
                                     CARD32 \*red, CARD32 \*green,\
                                     CARD32 \*blue);\
     void   (\*ximage2scanline\_func)( struct ASVisual \*asv, \
                                     XImage \*xim,\
                                     struct ASScanline \*sl, int y,\
                                     unsigned char \*xim\_data );\
     void   (\*scanline2ximage\_func)( struct ASVisual \*asv, \
                                     XImage \*xim,\
                                     struct ASScanline \*sl, int y,\
                                     unsigned char \*xim\_data );

\#define ASGLX\_Unavailable           0 #define ASGLX\_Available             (0x01\<\<0) #define ASGLX\_DoubleBuffer          (0x01\<\<1) #define ASGLX\_RGBA                  (0x01\<\<2) #define ASGLX\_UseForImageTx         (0x01\<\<3)   \
     ASFlagType glx\_support ;    /\* one of the above flags \*/

    void \*glx\_scratch\_gc\_indirect ; /\* (GLXContext) \*/\
     void \*glx\_scratch\_gc\_direct ;   /\* (GLXContext) \*/

    Window scratch\_window;

\#ifndef X\_DISPLAY\_MISSING #define ARGB2PIXEL(asv,argb,pixel)         \\\
     (asv)-\>color2pixel\_func((asv),(argb),(pixel)) #define GET\_SCANLINE(asv,xim,sl,y,xim\_data) \\\
     (asv)-\>ximage2scanline\_func((asv),(xim),(sl),(y),(xim\_data)) #define PUT\_SCANLINE(asv,xim,sl,y,xim\_data) \\\
     (asv)-\>scanline2ximage\_func((asv),(xim),(sl),(y),(xim\_data)) #else #define ARGB2PIXEL(asv,argb,pixel)         \\\
     do{ break; }while(0) #define GET\_SCANLINE(asv,xim,sl,y,xim\_data) \\\
     do{ break; }while(0) #define PUT\_SCANLINE(asv,xim,sl,y,xim\_data) \\\
     do{ break; }while(0) #endif }ASVisual;

libAfterImage/query\_screen\_visual()

## NAMEquery\_screen\_visual\_id()

query\_screen\_visual()

## SYNOPSIS

Bool query\_screen\_visual\_id( ASVisual \*asv, Display \*dpy, int screen,\
                           Window root, int default\_depth,\
                              VisualID visual\_id, Colormap cmap ); Bool query\_screen\_visual( ASVisual \*asv, Display \*dpy, int screen,\
                           Window root, int default\_depth );

## INPUTS

- asv

  \- preallocated ASVisual structure.

- dpy

  \- valid pointer to opened X display.

- screen

  \- screen number on which to query visuals.

- root

  \- root window on that screen.

- default\_depth-

  default colordepth of the screen.

- visual\_id

  \- optional ID of preferred Visual.

- cmap

  \- optional colormap to be used.

## RETURN VALUE

True on success, False on failure ASVisual structure pointed by asv will have the following data members set on success : dpy, visual\_info, colormap, own\_colormap, black\_pixel, white\_pixel.

## DESCRIPTION

query\_screen\_visual\_id() will go though prioritized list of possible Visuals and attempt to match those to what is available on the specified screen. If all items from list fail, then it goes about querying default visual. query\_screen\_visual is identical to query\_screen\_visual\_id with visual\_id and cmap set to 0. Once X Visual has been identified, we create X colormap and allocate white and black pixels from it. libAfterImage/setup\_truecolor\_visual()

## NAMEsetup\_truecolor\_visual()

## SYNOPSIS

Bool setup\_truecolor\_visual( ASVisual \*asv );

## INPUTS

- asv

  \- preallocated ASVisual structure.

## RETURN VALUE

True on success, False if visual is not TrueColor.

## DESCRIPTION

setup\_truecolor\_visual() checks if Visual is indeed TrueColor and if so it goes about querying color masks, deducing real XImage colordepth, and whether we work in BGR mode. It then goes about setting up correct hooks to X IO functions. libAfterImage/setup\_pseudo\_visual()

## NAMEsetup\_pseudo\_visual()

## SYNOPSIS

void setup\_pseudo\_visual( ASVisual \*asv  );

## INPUTS

- asv

  \- preallocated ASVisual structure.

## DESCRIPTION

setup\_pseudo\_visual() assumes that Visual is PseudoColor. It then tries to decide as to how many colors preallocate, and goes about setting up correct X IO hooks and possibly initialization of reverse colormap in case ASVisual already has colormap preallocated. libAfterImage/setup\_as\_colormap()

## NAMEsetup\_as\_colormap()

## SYNOPSIS

void setup\_as\_colormap( ASVisual \*asv );

## INPUTS

- asv

  \- preallocated ASVisual structure.

## DESCRIPTION

That has to be called in order to pre-allocate sufficient number of colors. It uses colormap size identification supplied in ASVisual structure. If colors where preallocated successfully - it will also create reverse lookup colormap. libAfterImage/create\_asvisual\_for\_id()

## NAMEcreate\_asvisual\_for\_id()

## SYNOPSIS

ASVisual \*create\_asvisual\_for\_id( Display \*dpy, int screen,\
                                   int default\_depth,\
                                   VisualID visual\_id, Colormap cmap,\
                                   ASVisual \*reusable\_memory );

## INPUTS

- dpy

  \- valid pointer to opened X display.

- screen

  \- screen number on which to query visuals.

- root

  \- root window on that screen.

- default\_depth-

  default colordepth of the screen.

- visual\_id

  \- ID of X visual to use.

- cmap

  \- optional ID of the colormap to be used.

- reusable\_memory

  \- pointer to preallocated ASVisual structure.

## RETURN VALUE

Pointer to ASVisual structure initialized with enough information to be able to deal with current X Visual.

## DESCRIPTION

This function calls all the needed functions in order to setup new ASVisual structure for the specified screen and visual. If reusable\_memory is not null - it will not allocate new ASVisual structure, but instead will use supplied one. Useful for allocating ASVisual on stack. This particular function will not do any autodetection and will use Visual ID supplied. That is useful when libAfterImage is used with an app that has its own approach to Visual handling, and since Visuals on all Windows, Pixmaps and colormaps must match, there is a need to synchronise visuals used by an app and libAfterImage. libAfterImage/create\_asvisual()

## NAMEcreate\_asvisual()

## SYNOPSIS

ASVisual \*create\_asvisual( Display \*dpy, int screen,\
                            int default\_depth,\
                            ASVisual \*reusable\_memory );

## INPUTS

- dpy

  \- valid pointer to opened X display.

- screen

  \- screen number on which to query visuals.

- root

  \- root window on that screen.

- default\_depth-

  default colordepth of the screen.

- reusable\_memory

  \- pointer to preallocated ASVisual structure.

## RETURN VALUE

Pointer to ASVisual structure initialized with enough information to be able to deal with current X Visual.

## DESCRIPTION

This function calls all the needed functions in order to setup new ASVisual structure for the specified screen. If reusable\_memory is not null - it will not allocate new ASVisual structure, but instead will use supplied one. Useful for allocating ASVisual on stack. It is different from create\_asvisualfor\_id() in that it will attempt to autodetect best possible visual for the screen. For example on some SUN Solaris X servers there will be both 8bpp pseudocolor and 24bpp truecolor, and default will be 8bpp. In this scenario libAfterImage will detect and use 24bpp true color visual, thus producing much better results. libAfterImage/destroy\_asvisual()

## NAMEdestroy\_asvisual()

## SYNOPSIS

void destroy\_asvisual( ASVisual \*asv, Bool reusable );

## INPUTS

- asv

  \- valid ASVisual structure.

- reusable

  \- if True it will cause function to not free object itself.

## DESCRIPTION

Cleanup function. Frees all the memory and deallocates all the resources. If reusable is False it will also free the object, pointed to by asv.

## EXAMPLE

asview.c: ASView.2 libAfterImage/visual2visual\_prop()

## NAMEvisual2visual\_prop()

## SYNOPSIS

Bool visual2visual\_prop( ASVisual \*asv, size\_t \*size,\
                          unsigned long \*version, unsigned long \*\*data );

## INPUTS

- asv

  \- valid ASVisual structure.

## RETURN VALUE

size         - size of the encoded memory block. version      - version of the encoding data         - actual encoded memory block True on success, False on failure

## DESCRIPTION

This function will encode ASVisual structure into memory block of 32 bit values, suitable for storing in X property. libAfterImage/visual\_prop2visual()

## NAMEvisual\_prop2visual()

## SYNOPSIS

Bool visual\_prop2visual( ASVisual \*asv, Display \*dpy, int screen,\
                          size\_t size,\
                          unsigned long version, unsigned long \*data );

## INPUTS

- asv

  \- valid ASVisual structure.

- dpy

  \- valid pointer to open X display.

- screen

  \- screen number.

- size

  \- encoded memory block's size.

- version

  \- version of encoding.

- data

  \- actual encoded memory block.

## RETURN VALUE

True on success, False on failure

## DESCRIPTION

visual\_prop2visual() will read ASVisual data from the memory block encoded by visual2visual\_prop(). It could be used to read data from X property and convert it into usable information - such as colormap, visual info, etc. Note: setup\_truecolor\_visual() or setup\_pseudo\_visual() has to be invoked in order to complete ASVisual setup. libAfterImage/create\_visual\_window()

## NAMEcreate\_visual\_window()

## SYNOPSIS

Window  create\_visual\_window( ASVisual \*asv, Window parent,\
                               int x, int y,\
                               unsigned int width, unsigned int height,\
                               unsigned int border\_width,\
                               unsigned int wclass,\
                               unsigned long mask,\
                               XSetWindowAttributes \*attributes );

## INPUTS

- asv

  \- pointer to the valid ASVisual structure.

- parent

  \- Window ID of the parent the window.

- x,

  y - initial position of the new window.

- width,

  height - initial size of the new window.

- border\_width

  \- initial border width of the new window.

- wclass

  \- Window class - InputOnly or InputOutput.

- mask

  \- defines what attributes are set.

- attributes

  \- different window attributes.

## RETURN VALUE

ID of the newly created window on success. None on failure.

## DESCRIPTION

create\_visual\_window() will do sanity checks on passed parameters, it will then add mandatory attributes if needed, and attempt to create window for the specified ASVisual. libAfterImage/create\_visual\_gc()

## NAMEcreate\_visual\_gc()

## SYNOPSIS

GC      create\_visual\_gc( ASVisual \*asv, Window root,\
                           unsigned long mask, XGCValues \*gcvalues );

## INPUTS

- asv

  \- pointer to the valid ASVisual structure.

- root

  \- Window ID of the root window of destination screen

- mask,

  gcvalues - values for creation of new GC - see XCreateGC() for details.

## RETURN VALUE

New GC created for regular window on success. NULL on failure.

## DESCRIPTION

create\_visual\_gc() will create temporary window for the ASVisual specific depth and Visual and it will then create GC for such window. Obtained GC should be good to be used for manipulation of windows and Pixmaps created for the same ASVisual. libAfterImage/create\_visual\_pixmap()

## NAMEcreate\_visual\_pixmap()

## SYNOPSIS

Pixmap  create\_visual\_pixmap( ASVisual \*asv, Window root,\
                               unsigned int width, unsigned int height,\
                               unsigned int depth );

## INPUTS

- asv

  \- pointer to the valid ASVisual structure.

- root

  \- Window ID of the root window of destination screen

- width,

  height - size of the pixmap to create.

- depth

  \- depth of the pixmap to create. If 0 asv-\>true\_depth will be used.

## RETURN VALUE

ID of the newly created pixmap on success. None on failure.

## DESCRIPTION

create\_visual\_pixmap() will perform sanity checks on passed parameters, and attempt to create pixmap for the specified ASVisual, root and depth. libAfterImage/create\_visual\_ximage()

## NAMEcreate\_visual\_ximage()

## SYNOPSIS

XImage\* create\_visual\_ximage( ASVisual \*asv,\
                               unsigned int width, unsigned int height,\
                               unsigned int depth );

## INPUTS

- asv

  \- pointer to the valid ASVisual structure.

- width,

  height - size of the XImage to create.

- depth

  \- depth of the XImage to create. If 0 asv-\>true\_depth will be used.

## RETURN VALUE

pointer to newly created XImage on success. NULL on failure.

## DESCRIPTION

create\_visual\_ximage() will perform sanity checks on passed parameters, and it will attempt to create XImage of sufficient size, and specified colordepth. It will also setup hooks for XImage deallocation to be handled by custom function.
