@ -48,7 +48,7 @@ typedef struct {
/* X modifiers */
# define XK_ANY_MOD UINT_MAX
# define XK_NO_MOD 0
# define XK_SWITCH_MOD (1<<13 )
# define XK_SWITCH_MOD (1<<13 |1<<14 )
/* function definitions used in config.h */
static void clipcopy ( const Arg * ) ;
@ -81,6 +81,7 @@ typedef XftGlyphFontSpec GlyphFontSpec;
typedef struct {
int tw , th ; /* tty width and height */
int w , h ; /* window width and height */
int hborderpx , vborderpx ;
int ch ; /* char height */
int cw ; /* char width */
int mode ; /* window state/mode flags */
@ -93,7 +94,7 @@ typedef struct {
Window win ;
Drawable buf ;
GlyphFontSpec * specbuf ; /* font spec buffer used for rendering */
Atom xembed , wmdeletewin , netwmname , netwm pid;
Atom xembed , wmdeletewin , netwmname , netwm iconname, netwm pid;
struct {
XIM xim ;
XIC xic ;
@ -103,6 +104,11 @@ typedef struct {
Draw draw ;
Visual * vis ;
XSetWindowAttributes attrs ;
/* Here, we use the term *pointer* to differentiate the cursor
* one sees when hovering the mouse over the terminal from , e . g . ,
* a green rectangle where text would be entered . */
Cursor vpointer , bpointer ; /* visible and hidden pointers */
int pointerisvisible ;
int scr ;
int isfixed ; /* is fixed geometry? */
int l , t ; /* left and top offset */
@ -156,7 +162,7 @@ static void xresize(int, int);
static void xhints ( void ) ;
static int xloadcolor ( int , const char * , Color * ) ;
static int xloadfont ( Font * , FcPattern * ) ;
static void xloadfonts ( char * , double ) ;
static void xloadfonts ( const char * , double ) ;
static void xunloadfont ( Font * ) ;
static void xunloadfonts ( void ) ;
static void xsetenv ( void ) ;
@ -331,7 +337,7 @@ ttysend(const Arg *arg)
int
evcol ( XEvent * e )
{
int x = e - > xbutton . x - borderpx;
int x = e - > xbutton . x - win. h borderpx;
LIMIT ( x , 0 , win . tw - 1 ) ;
return x / win . cw ;
}
@ -339,7 +345,7 @@ evcol(XEvent *e)
int
evrow ( XEvent * e )
{
int y = e - > xbutton . y - borderpx;
int y = e - > xbutton . y - win. v borderpx;
LIMIT ( y , 0 , win . th - 1 ) ;
return y / win . ch ;
}
@ -387,7 +393,9 @@ mousereport(XEvent *e)
button = 3 ;
} else {
button - = Button1 ;
if ( button > = 3 )
if ( button > = 7 )
button + = 128 - 7 ;
else if ( button > = 3 )
button + = 64 - 3 ;
}
if ( e - > xbutton . type = = ButtonPress ) {
@ -698,6 +706,13 @@ brelease(XEvent *e)
void
bmotion ( XEvent * e )
{
if ( ! xw . pointerisvisible ) {
XDefineCursor ( xw . dpy , xw . win , xw . vpointer ) ;
xw . pointerisvisible = 1 ;
if ( ! IS_SET ( MODE_MOUSEMANY ) )
xsetpointermotion ( 0 ) ;
}
if ( IS_SET ( MODE_MOUSE ) & & ! ( e - > xbutton . state & forcemousemod ) ) {
mousereport ( e ) ;
return ;
@ -721,6 +736,9 @@ cresize(int width, int height)
col = MAX ( 1 , col ) ;
row = MAX ( 1 , row ) ;
win . hborderpx = ( win . w - col * win . cw ) / 2 ;
win . vborderpx = ( win . h - row * win . ch ) / 2 ;
tresize ( col , row ) ;
xresize ( col , row ) ;
ttyresize ( win . tw , win . th ) ;
@ -838,8 +856,8 @@ xhints(void)
sizeh - > flags = PSize | PResizeInc | PBaseSize | PMinSize ;
sizeh - > height = win . h ;
sizeh - > width = win . w ;
sizeh - > height_inc = win . ch ;
sizeh - > width_inc = win . cw ;
sizeh - > height_inc = 1 ;
sizeh - > width_inc = 1 ;
sizeh - > base_height = 2 * borderpx ;
sizeh - > base_width = 2 * borderpx ;
sizeh - > min_height = win . ch + 2 * borderpx ;
@ -950,7 +968,7 @@ xloadfont(Font *f, FcPattern *pattern)
}
void
xloadfonts ( char * fontstr , double fontsize )
xloadfonts ( const char * fontstr , double fontsize )
{
FcPattern * pattern ;
double fontval ;
@ -958,7 +976,7 @@ xloadfonts(char *fontstr, double fontsize)
if ( fontstr [ 0 ] = = ' - ' )
pattern = XftXlfdParse ( fontstr , False , False ) ;
else
pattern = FcNameParse ( ( FcChar8 * ) fontstr ) ;
pattern = FcNameParse ( ( const FcChar8 * ) fontstr ) ;
if ( ! pattern )
die ( " can't open font %s \n " , fontstr ) ;
@ -1099,10 +1117,10 @@ void
xinit ( int cols , int rows )
{
XGCValues gcvalues ;
Cursor cursor ;
Window parent ;
pid_t thispid = getpid ( ) ;
XColor xmousefg , xmousebg ;
Pixmap blankpm ;
if ( ! ( xw . dpy = XOpenDisplay ( NULL ) ) )
die ( " can't open display \n " ) ;
@ -1121,8 +1139,8 @@ xinit(int cols, int rows)
xloadcols ( ) ;
/* adjust fixed window geometry */
win . w = 2 * borderpx + cols * win . cw ;
win . h = 2 * borderpx + rows * win . ch ;
win . w = 2 * win. h borderpx + cols * win . cw ;
win . h = 2 * win. v borderpx + rows * win . ch ;
if ( xw . gm & XNegative )
xw . l + = DisplayWidth ( xw . dpy , xw . scr ) - win . w - 2 ;
if ( xw . gm & YNegative )
@ -1166,8 +1184,9 @@ xinit(int cols, int rows)
}
/* white cursor, black outline */
cursor = XCreateFontCursor ( xw . dpy , mouseshape ) ;
XDefineCursor ( xw . dpy , xw . win , cursor ) ;
xw . pointerisvisible = 1 ;
xw . vpointer = XCreateFontCursor ( xw . dpy , mouseshape ) ;
XDefineCursor ( xw . dpy , xw . win , xw . vpointer ) ;
if ( XParseColor ( xw . dpy , xw . cmap , colorname [ mousefg ] , & xmousefg ) = = 0 ) {
xmousefg . red = 0xffff ;
@ -1181,11 +1200,15 @@ xinit(int cols, int rows)
xmousebg . blue = 0x0000 ;
}
XRecolorCursor ( xw . dpy , cursor , & xmousefg , & xmousebg ) ;
XRecolorCursor ( xw . dpy , xw . vpointer , & xmousefg , & xmousebg ) ;
blankpm = XCreateBitmapFromData ( xw . dpy , xw . win , & ( char ) { 0 } , 1 , 1 ) ;
xw . bpointer = XCreatePixmapCursor ( xw . dpy , blankpm , blankpm ,
& xmousefg , & xmousebg , 0 , 0 ) ;
xw . xembed = XInternAtom ( xw . dpy , " _XEMBED " , False ) ;
xw . wmdeletewin = XInternAtom ( xw . dpy , " WM_DELETE_WINDOW " , False ) ;
xw . netwmname = XInternAtom ( xw . dpy , " _NET_WM_NAME " , False ) ;
xw . netwmiconname = XInternAtom ( xw . dpy , " _NET_WM_ICON_NAME " , False ) ;
XSetWMProtocols ( xw . dpy , xw . win , & xw . wmdeletewin , 1 ) ;
xw . netwmpid = XInternAtom ( xw . dpy , " _NET_WM_PID " , False ) ;
@ -1210,7 +1233,7 @@ xinit(int cols, int rows)
int
xmakeglyphfontspecs ( XftGlyphFontSpec * specs , const Glyph * glyphs , int len , int x , int y )
{
float winx = borderpx + x * win . cw , winy = borderpx + y * win . ch , xp , yp ;
float winx = win. h borderpx + x * win . cw , winy = win. v borderpx + y * win . ch , xp , yp ;
ushort mode , prevmode = USHRT_MAX ;
Font * font = & dc . font ;
int frcflags = FRC_NORMAL ;
@ -1343,7 +1366,7 @@ void
xdrawglyphfontspecs ( const XftGlyphFontSpec * specs , Glyph base , int len , int x , int y )
{
int charlen = len * ( ( base . mode & ATTR_WIDE ) ? 2 : 1 ) ;
int winx = borderpx + x * win . cw , winy = borderpx + y * win . ch ,
int winx = win. h borderpx + x * win . cw , winy = win. v borderpx + y * win . ch ,
width = charlen * win . cw ;
Color * fg , * bg , * temp , revfg , revbg , truefg , truebg ;
XRenderColor colfg , colbg ;
@ -1433,17 +1456,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
/* Intelligent cleaning up of the borders. */
if ( x = = 0 ) {
xclear ( 0 , ( y = = 0 ) ? 0 : winy , borderpx,
xclear ( 0 , ( y = = 0 ) ? 0 : winy , win. v borderpx,
winy + win . ch +
( ( winy + win . ch > = borderpx + win . th ) ? win . h : 0 ) ) ;
( ( winy + win . ch > = win. v borderpx + win . th ) ? win . h : 0 ) ) ;
}
if ( winx + width > = borderpx + win . tw ) {
if ( winx + width > = win. h borderpx + win . tw ) {
xclear ( winx + width , ( y = = 0 ) ? 0 : winy , win . w ,
( ( winy + win . ch > = borderpx + win . th ) ? win . h : ( winy + win . ch ) ) ) ;
( ( winy + win . ch > = win. v borderpx + win . th ) ? win . h : ( winy + win . ch ) ) ) ;
}
if ( y = = 0 )
xclear ( winx , 0 , winx + width , borderpx) ;
if ( winy + win . ch > = borderpx + win . th )
xclear ( winx , 0 , winx + width , win. h borderpx) ;
if ( winy + win . ch > = win. v borderpx + win . th )
xclear ( winx , winy + win . ch , winx + width , win . h ) ;
/* Clean up the region we want to draw to. */
@ -1537,35 +1560,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
case 3 : /* Blinking Underline */
case 4 : /* Steady Underline */
XftDrawRect ( xw . draw , & drawcol ,
borderpx + cx * win . cw ,
borderpx + ( cy + 1 ) * win . ch - \
win. h borderpx + cx * win . cw ,
win. v borderpx + ( cy + 1 ) * win . ch - \
cursorthickness ,
win . cw , cursorthickness ) ;
break ;
case 5 : /* Blinking bar */
case 6 : /* Steady bar */
XftDrawRect ( xw . draw , & drawcol ,
borderpx + cx * win . cw ,
borderpx + cy * win . ch ,
win. h borderpx + cx * win . cw ,
win. v borderpx + cy * win . ch ,
cursorthickness , win . ch ) ;
break ;
}
} else {
XftDrawRect ( xw . draw , & drawcol ,
borderpx + cx * win . cw ,
borderpx + cy * win . ch ,
win. h borderpx + cx * win . cw ,
win. v borderpx + cy * win . ch ,
win . cw - 1 , 1 ) ;
XftDrawRect ( xw . draw , & drawcol ,
borderpx + cx * win . cw ,
borderpx + cy * win . ch ,
win. h borderpx + cx * win . cw ,
win. v borderpx + cy * win . ch ,
1 , win . ch - 1 ) ;
XftDrawRect ( xw . draw , & drawcol ,
borderpx + ( cx + 1 ) * win . cw - 1 ,
borderpx + cy * win . ch ,
win. h borderpx + ( cx + 1 ) * win . cw - 1 ,
win. v borderpx + cy * win . ch ,
1 , win . ch - 1 ) ;
XftDrawRect ( xw . draw , & drawcol ,
borderpx + cx * win . cw ,
borderpx + ( cy + 1 ) * win . ch - 1 ,
win. h borderpx + cx * win . cw ,
win. v borderpx + ( cy + 1 ) * win . ch - 1 ,
win . cw , 1 ) ;
}
}
@ -1579,14 +1602,29 @@ xsetenv(void)
setenv ( " WINDOWID " , buf , 1 ) ;
}
void
xseticontitle ( char * p )
{
XTextProperty prop ;
DEFAULT ( p , opt_title ) ;
if ( Xutf8TextListToTextProperty ( xw . dpy , & p , 1 , XUTF8StringStyle ,
& prop ) ! = Success )
return ;
XSetWMIconName ( xw . dpy , xw . win , & prop ) ;
XSetTextProperty ( xw . dpy , xw . win , & prop , xw . netwmiconname ) ;
XFree ( prop . value ) ;
}
void
xsettitle ( char * p )
{
XTextProperty prop ;
DEFAULT ( p , opt_title ) ;
Xutf8TextListToTextProperty ( xw . dpy , & p , 1 , XUTF8StringStyle ,
& prop ) ;
if ( Xutf8TextListToTextProperty ( xw . dpy , & p , 1 , XUTF8StringStyle ,
& prop ) ! = Success )
return ;
XSetWMName ( xw . dpy , xw . win , & prop ) ;
XSetTextProperty ( xw . dpy , xw . win , & prop , xw . netwmname ) ;
XFree ( prop . value ) ;
@ -1674,6 +1712,8 @@ unmap(XEvent *ev)
void
xsetpointermotion ( int set )
{
if ( ! set & & ! xw . pointerisvisible )
return ;
MODBIT ( xw . attrs . event_mask , set , PointerMotionMask ) ;
XChangeWindowAttributes ( xw . dpy , xw . win , CWEventMask , & xw . attrs ) ;
}
@ -1793,6 +1833,12 @@ kpress(XEvent *ev)
Status status ;
Shortcut * bp ;
if ( xw . pointerisvisible ) {
XDefineCursor ( xw . dpy , xw . win , xw . bpointer ) ;
xsetpointermotion ( 1 ) ;
xw . pointerisvisible = 0 ;
}
if ( IS_SET ( MODE_KBDLOCK ) )
return ;