@ -155,6 +155,9 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
static void xdrawglyph ( Glyph , int , int ) ;
static void xclear ( int , int , int , int ) ;
static int xgeommasktogravity ( int ) ;
static void ximopen ( Display * ) ;
static void ximinstantiate ( Display * , XPointer , XPointer ) ;
static void ximdestroy ( XIM , XPointer , XPointer ) ;
static void xinit ( int , int ) ;
static void cresize ( int , int ) ;
static void xresize ( int , int ) ;
@ -239,12 +242,14 @@ typedef struct {
} Fontcache ;
/* Fontcache is an array now. A new font will be appended to the array. */
static Fontcache frc [ 16 ] ;
static Fontcache * frc = NULL ;
static int frclen = 0 ;
static int frccap = 0 ;
static char * usedfont = NULL ;
static double usedfontsize = 0 ;
static double defaultfontsize = 0 ;
static char * opt_alpha = NULL ;
static char * opt_class = NULL ;
static char * * opt_cmd = NULL ;
static char * opt_embed = NULL ;
@ -653,7 +658,7 @@ setsel(char *str, Time t)
if ( XGetSelectionOwner ( xw . dpy , XA_PRIMARY ) ! = xw . win )
selclear ( ) ;
x clipcopy( ) ;
clipcopy( NULL ) ;
}
void
@ -671,7 +676,7 @@ brelease(XEvent *e)
}
if ( e - > xbutton . button = = Button2 )
sel paste( NULL ) ;
clip paste( NULL ) ;
else if ( e - > xbutton . button = = Button1 )
mousesel ( e , 1 ) ;
}
@ -771,17 +776,17 @@ xloadcols(void)
for ( i = 0 ; i < dc . collen ; i + + )
if ( ! xloadcolor ( i , NULL , & dc . col [ i ] ) ) {
if ( colorname [ i ] )
die ( " C ould not allocate color '%s'\n " , colorname [ i ] ) ;
die ( " c ould not allocate color '%s'\n " , colorname [ i ] ) ;
else
die ( " C ould not allocate color %d\n " , i ) ;
die ( " c ould not allocate color %d\n " , i ) ;
}
/* set alpha value of bg color */
if ( USE_ARGB) {
dc. col [ defaultbg ] . color . alpha = ( 0xffff * alpha ) / OPAQUE ;
dc . col [ defaultbg ] . pixel & = 0x00111111 ;
dc . col [ defaultbg ] . pixel |= alpha < < 24 ;
}
if ( opt_alpha)
alpha = strtof ( opt_alpha , NULL ) ;
dc . col [ defaultbg ] . color. alpha = ( unsigned short ) ( 0xffff * alpha ) ;
dc . col [ defaultbg ] . pixel &= 0x00FFFFFF ;
dc . col [ defaultbg ] . pixel | = ( unsigned char ) ( 0xff * alpha ) < < 24 ;
loaded = 1 ;
}
@ -793,7 +798,6 @@ xsetcolorname(int x, const char *name)
if ( ! BETWEEN ( x , 0 , dc . collen ) )
return 1 ;
if ( ! xloadcolor ( x , name , & ncolor ) )
return 1 ;
@ -803,17 +807,6 @@ xsetcolorname(int x, const char *name)
return 0 ;
}
void
xtermclear ( int col1 , int row1 , int col2 , int row2 )
{
XftDrawRect ( xw . draw ,
& dc . col [ IS_SET ( MODE_REVERSE ) ? defaultfg : defaultbg ] ,
borderpx + col1 * win . cw ,
borderpx + row1 * win . ch ,
( col2 - col1 + 1 ) * win . cw ,
( row2 - row1 + 1 ) * win . ch ) ;
}
/*
* Absolute coordinates .
*/
@ -918,7 +911,7 @@ xloadfont(Font *f, FcPattern *pattern)
if ( ( XftPatternGetInteger ( f - > match - > pattern , " slant " , 0 ,
& haveattr ) ! = XftResultMatch ) | | haveattr < wantattr ) {
f - > badslant = 1 ;
fputs ( " st: font slant does not match\n " , stderr ) ;
fputs ( " font slant does not match\n " , stderr ) ;
}
}
@ -927,7 +920,7 @@ xloadfont(Font *f, FcPattern *pattern)
if ( ( XftPatternGetInteger ( f - > match - > pattern , " weight " , 0 ,
& haveattr ) ! = XftResultMatch ) | | haveattr ! = wantattr ) {
f - > badweight = 1 ;
fputs ( " st: font weight does not match\n " , stderr ) ;
fputs ( " font weight does not match\n " , stderr ) ;
}
}
@ -955,14 +948,13 @@ xloadfonts(char *fontstr, double fontsize)
FcPattern * pattern ;
double fontval ;
if ( fontstr [ 0 ] = = ' - ' ) {
if ( fontstr [ 0 ] = = ' - ' )
pattern = XftXlfdParse ( fontstr , False , False ) ;
} else {
else
pattern = FcNameParse ( ( FcChar8 * ) fontstr ) ;
}
if ( ! pattern )
die ( " st: can't open font %s\n " , fontstr ) ;
die ( " can't open font %s\n " , fontstr ) ;
if ( fontsize > 1 ) {
FcPatternDel ( pattern , FC_PIXEL_SIZE ) ;
@ -988,7 +980,7 @@ xloadfonts(char *fontstr, double fontsize)
}
if ( xloadfont ( & dc . font , pattern ) )
die ( " st: can't open font %s\n " , fontstr ) ;
die ( " can't open font %s\n " , fontstr ) ;
if ( usedfontsize < 0 ) {
FcPatternGetDouble ( dc . font . match - > pattern ,
@ -1006,17 +998,17 @@ xloadfonts(char *fontstr, double fontsize)
FcPatternDel ( pattern , FC_SLANT ) ;
FcPatternAddInteger ( pattern , FC_SLANT , FC_SLANT_ITALIC ) ;
if ( xloadfont ( & dc . ifont , pattern ) )
die ( " st: can't open font %s\n " , fontstr ) ;
die ( " can't open font %s\n " , fontstr ) ;
FcPatternDel ( pattern , FC_WEIGHT ) ;
FcPatternAddInteger ( pattern , FC_WEIGHT , FC_WEIGHT_BOLD ) ;
if ( xloadfont ( & dc . ibfont , pattern ) )
die ( " st: can't open font %s\n " , fontstr ) ;
die ( " can't open font %s\n " , fontstr ) ;
FcPatternDel ( pattern , FC_SLANT ) ;
FcPatternAddInteger ( pattern , FC_SLANT , FC_SLANT_ROMAN ) ;
if ( xloadfont ( & dc . bfont , pattern ) )
die ( " st: can't open font %s\n " , fontstr ) ;
die ( " can't open font %s\n " , fontstr ) ;
FcPatternDestroy ( pattern ) ;
}
@ -1043,6 +1035,43 @@ xunloadfonts(void)
xunloadfont ( & dc . ibfont ) ;
}
void
ximopen ( Display * dpy )
{
XIMCallback destroy = { . client_data = NULL , . callback = ximdestroy } ;
if ( ( xw . xim = XOpenIM ( xw . dpy , NULL , NULL , NULL ) ) = = NULL ) {
XSetLocaleModifiers ( " @im=local " ) ;
if ( ( xw . xim = XOpenIM ( xw . dpy , NULL , NULL , NULL ) ) = = NULL ) {
XSetLocaleModifiers ( " @im= " ) ;
if ( ( xw . xim = XOpenIM ( xw . dpy , NULL , NULL , NULL ) ) = = NULL )
die ( " XOpenIM failed. Could not open input device. \n " ) ;
}
}
if ( XSetIMValues ( xw . xim , XNDestroyCallback , & destroy , NULL ) ! = NULL )
die ( " XSetIMValues failed. Could not set input method value. \n " ) ;
xw . xic = XCreateIC ( xw . xim , XNInputStyle , XIMPreeditNothing | XIMStatusNothing ,
XNClientWindow , xw . win , XNFocusWindow , xw . win , NULL ) ;
if ( xw . xic = = NULL )
die ( " XCreateIC failed. Could not obtain input method. \n " ) ;
}
void
ximinstantiate ( Display * dpy , XPointer client , XPointer call )
{
ximopen ( dpy ) ;
XUnregisterIMInstantiateCallback ( xw . dpy , NULL , NULL , NULL ,
ximinstantiate , NULL ) ;
}
void
ximdestroy ( XIM xim , XPointer client , XPointer call )
{
xw . xim = NULL ;
XRegisterIMInstantiateCallback ( xw . dpy , NULL , NULL , NULL ,
ximinstantiate , NULL ) ;
}
void
xinit ( int cols , int rows )
{
@ -1051,56 +1080,31 @@ xinit(int cols, int rows)
Window parent ;
pid_t thispid = getpid ( ) ;
XColor xmousefg , xmousebg ;
XWindowAttributes attr ;
XVisualInfo vis ;
xw . scr = XDefaultScreen ( xw . dpy ) ;
xw . depth = ( USE_ARGB ) ? 32 : XDefaultDepth ( xw . dpy , xw . scr ) ;
if ( ! USE_ARGB )
xw . vis = XDefaultVisual ( xw . dpy , xw . scr ) ;
else {
XVisualInfo * vis ;
XRenderPictFormat * fmt ;
int nvi ;
int i ;
XVisualInfo tpl = {
. screen = xw . scr ,
. depth = 32 ,
. class = TrueColor
} ;
vis = XGetVisualInfo ( xw . dpy ,
VisualScreenMask | VisualDepthMask | VisualClassMask ,
& tpl , & nvi ) ;
xw . vis = NULL ;
for ( i = 0 ; i < nvi ; i + + ) {
fmt = XRenderFindVisualFormat ( xw . dpy , vis [ i ] . visual ) ;
if ( fmt - > type = = PictTypeDirect & & fmt - > direct . alphaMask ) {
xw . vis = vis [ i ] . visual ;
break ;
}
}
XFree ( vis ) ;
if ( ! xw . vis ) {
fprintf ( stderr , " Couldn't find ARGB visual. \n " ) ;
exit ( 1 ) ;
}
if ( ! ( opt_embed & & ( parent = strtol ( opt_embed , NULL , 0 ) ) ) ) {
parent = XRootWindow ( xw . dpy , xw . scr ) ;
xw . depth = 32 ;
} else {
XGetWindowAttributes ( xw . dpy , parent , & attr ) ;
xw . depth = attr . depth ;
}
XMatchVisualInfo ( xw . dpy , xw . scr , xw . depth , TrueColor , & vis ) ;
xw . vis = vis . visual ;
/* font */
if ( ! FcInit ( ) )
die ( " Could not init fontconfig. \n " ) ;
die ( " could not init fontconfig. \n " ) ;
usedfont = ( opt_font = = NULL ) ? font : opt_font ;
xloadfonts ( usedfont , 0 ) ;
/* colors */
if ( ! USE_ARGB )
xw . cmap = XDefaultColormap ( xw . dpy , xw . scr ) ;
else
xw . cmap = XCreateColormap ( xw . dpy , XRootWindow ( xw . dpy , xw . scr ) ,
xw . vis , None ) ;
xw . cmap = XCreateColormap ( xw . dpy , parent , xw . vis , None ) ;
xloadcols ( ) ;
/* adjust fixed window geometry */
@ -1115,13 +1119,11 @@ xinit(int cols, int rows)
xw . attrs . background_pixel = dc . col [ defaultbg ] . pixel ;
xw . attrs . border_pixel = dc . col [ defaultbg ] . pixel ;
xw . attrs . bit_gravity = NorthWestGravity ;
xw . attrs . event_mask = FocusChangeMask | KeyPressMask
xw . attrs . event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
| ExposureMask | VisibilityChangeMask | StructureNotifyMask
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask ;
xw . attrs . colormap = xw . cmap ;
if ( ! ( opt_embed & & ( parent = strtol ( opt_embed , NULL , 0 ) ) ) )
parent = XRootWindow ( xw . dpy , xw . scr ) ;
xw . win = XCreateWindow ( xw . dpy , parent , xw . l , xw . t ,
win . w , win . h , 0 , xw . depth , InputOutput ,
xw . vis , CWBackPixel | CWBorderPixel | CWBitGravity
@ -1130,8 +1132,7 @@ xinit(int cols, int rows)
memset ( & gcvalues , 0 , sizeof ( gcvalues ) ) ;
gcvalues . graphics_exposures = False ;
xw . buf = XCreatePixmap ( xw . dpy , xw . win , win . w , win . h , xw . depth ) ;
dc . gc = XCreateGC ( xw . dpy , ( USE_ARGB ) ? xw . buf : parent ,
GCGraphicsExposures , & gcvalues ) ;
dc . gc = XCreateGC ( xw . dpy , xw . buf , GCGraphicsExposures , & gcvalues ) ;
XSetForeground ( xw . dpy , dc . gc , dc . col [ defaultbg ] . pixel ) ;
XFillRectangle ( xw . dpy , xw . buf , dc . gc , 0 , 0 , win . w , win . h ) ;
@ -1142,22 +1143,7 @@ xinit(int cols, int rows)
xw . draw = XftDrawCreate ( xw . dpy , xw . buf , xw . vis , xw . cmap ) ;
/* input methods */
if ( ( xw . xim = XOpenIM ( xw . dpy , NULL , NULL , NULL ) ) = = NULL ) {
XSetLocaleModifiers ( " @im=local " ) ;
if ( ( xw . xim = XOpenIM ( xw . dpy , NULL , NULL , NULL ) ) = = NULL ) {
XSetLocaleModifiers ( " @im= " ) ;
if ( ( xw . xim = XOpenIM ( xw . dpy ,
NULL , NULL , NULL ) ) = = NULL ) {
die ( " XOpenIM failed. Could not open input "
" device. \n " ) ;
}
}
}
xw . xic = XCreateIC ( xw . xim , XNInputStyle , XIMPreeditNothing
| XIMStatusNothing , XNClientWindow , xw . win ,
XNFocusWindow , xw . win , NULL ) ;
if ( xw . xic = = NULL )
die ( " XCreateIC failed. Could not obtain input method. \n " ) ;
ximopen ( xw . dpy ) ;
/* white cursor, black outline */
cursor = XCreateFontCursor ( xw . dpy , mouseshape ) ;
@ -1299,13 +1285,10 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
fontpattern = FcFontSetMatch ( 0 , fcsets , 1 ,
fcpattern , & fcres ) ;
/*
* Overwrite or create the new cache entry .
*/
if ( frclen > = LEN ( frc ) ) {
frclen = LEN ( frc ) - 1 ;
XftFontClose ( xw . dpy , frc [ frclen ] . font ) ;
frc [ frclen ] . unicodep = 0 ;
/* Allocate memory for the new cache entry. */
if ( frclen > = frccap ) {
frccap + = 16 ;
frc = xrealloc ( frc , frccap * sizeof ( Fontcache ) ) ;
}
frc [ frclen ] . font = XftFontOpenPattern ( xw . dpy ,
@ -1377,10 +1360,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
bg = & dc . col [ base . bg ] ;
}
/* Change basic system colors [0-7] to bright system colors [8-15] */
if ( ( base . mode & ATTR_BOLD_FAINT ) = = ATTR_BOLD & & BETWEEN ( base . fg , 0 , 7 ) )
fg = & dc . col [ base . fg ] ;
if ( IS_SET ( MODE_REVERSE ) ) {
if ( fg = = & dc . col [ defaultfg ] ) {
fg = & dc . col [ defaultbg ] ;
@ -1635,6 +1614,16 @@ xfinishdraw(void)
defaultfg : defaultbg ] . pixel ) ;
}
void
xximspot ( int x , int y )
{
XPoint spot = { borderpx + x * win . cw , borderpx + ( y + 1 ) * win . ch } ;
XVaNestedList attr = XVaCreateNestedList ( 0 , XNSpotLocation , & spot , NULL ) ;
XSetICValues ( xw . xic , XNPreeditAttributes , attr , NULL ) ;
XFree ( attr ) ;
}
void
expose ( XEvent * ev )
{
@ -1812,7 +1801,6 @@ kpress(XEvent *ev)
ttywrite ( buf , len , 1 ) ;
}
void
cmessage ( XEvent * e )
{
@ -2028,6 +2016,9 @@ main(int argc, char *argv[])
case ' a ' :
allowaltscreen = 0 ;
break ;
case ' A ' :
opt_alpha = EARGF ( usage ( ) ) ;
break ;
case ' c ' :
opt_class = EARGF ( usage ( ) ) ;
break ;
@ -2062,7 +2053,7 @@ main(int argc, char *argv[])
opt_embed = EARGF ( usage ( ) ) ;
break ;
case ' v ' :
die ( " %s " VERSION " (c) 2010-2016 st engineers \n " , argv0 ) ;
die ( " %s " VERSION " \n " , argv0 ) ;
break ;
default :
usage ( ) ;