Compare commits

...
This repository has been archived on 2021-04-22. You can view files and clone it, but cannot push or open issues/pull-requests.

11 Commits

19 changed files with 3978 additions and 3656 deletions

149
.clang-format 100644
View File

@ -0,0 +1,149 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignConsecutiveBitFields: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 79
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
...

View File

@ -0,0 +1,3 @@
#!/usr/bin/env sh
make clean

View File

@ -0,0 +1,3 @@
#!/usr/bin/env sh
make format

36
CHANGELOG.md 100644
View File

@ -0,0 +1,36 @@
# Upcoming
## v1.0
* Switched build to CMake
* Completely overhauled code structure
* Separate code into logical blocks
* Purge global variables as much as possible
* Add a desktop entry when installing
based on [desktopentry](https://st.suckless.org/patches/desktopentry/)
## v1.1
* Configurable transparency (focused and unfocused)
based on [alpha](https://st.suckless.org/patches/alpha/) and
[alpha focus highlight](https://st.suckless.org/patches/alpha_focus_highlight/)
* Proper resizing (aka don't snap to nearest character size)
based on [anysize](https://st.suckless.org/patches/anysize/)
* Copy to clipboard on selection
based on [one clipboard](https://st.suckless.org/patches/clipboard/)
## v1.2
* Add better/gapless rendering of lines/blocks
based on [boxdraw](https://st.suckless.org/patches/boxdraw/)
* Add support for multiple fonts
based on [font2](https://st.suckless.org/patches/font2/)
* Hide cursor when working in the terminal
based on [hidecursor](https://st.suckless.org/patches/hidecursor/)
## v2.0
* Add ligature support
based on [ligature support](https://st.suckless.org/patches/ligatures/)
* Support for multiple color pallets
* Paste on right click
* Scrollback support
* Center lines smaller than max height
based on [vertcenter](https://st.suckless.org/patches/vertcenter/)
* Visual bell
based on [visualbell](https://st.suckless.org/patches/visualbell/)

109
Makefile
View File

@ -1,67 +1,42 @@
# =====CONFIG=====
SRC_DIR := src SRC_DIR := src
BUILD_DIR := build BUILD_DIR := build
RELEASE_DIR := $(BUILD_DIR)/release RELEASE_DIR := $(BUILD_DIR)/release
DEBUG_DIR := $(BUILD_DIR)/debug DEBUG_DIR := $(BUILD_DIR)/debug
MINSIZEREL_DIR := $(BUILD_DIR)/min_size_rel
BINARY := stj BINARY := stj
CORES := $(shell nproc --all) CORES := $(shell nproc --all)
PREFIX := /usr/local PREFIX := /usr/local
MANPREFIX := $(PREFIX)/share/man MANPREFIX := $(PREFIX)/share/man
SHELL := $(shell which sh)
all: debug all: debug
.PHONY: all .PHONY: all
# Installation & removal # =====INSTALL & UNINSTALL=====
install: release install: release
mkdir -p $(DESTDIR)$(PREFIX)/bin @ mkdir -p '$(DESTDIR)$(PREFIX)/bin'
cp -f build/release/stj $(DESTDIR)$(PREFIX)/bin @ cp -f '$(RELEASE_DIR)/$(BINARY)' '$(DESTDIR)$(PREFIX)/bin'
chmod 755 $(DESTDIR)$(PREFIX)/bin/stj @ chmod 755 '$(DESTDIR)$(PREFIX)/bin/$(BINARY)'
mkdir -p $(DESTDIR)$(MANPREFIX)/man1 @ mkdir -p '$(DESTDIR)$(MANPREFIX)/man1'
sed "s/VERSION/$(VERSION)/g" < data/stj.1 > $(DESTDIR)$(MANPREFIX)/man1/stj.1 @ sed "s/VERSION/$(VERSION)/g" < 'data/stj.1' > '$(DESTDIR)$(MANPREFIX)/man1/$(BINARY).1'
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stj.1 @ chmod 644 '$(DESTDIR)$(MANPREFIX)/man1/$(BINARY).1'
tic -sx data/stj.info @ tic -sx 'data/stj.info'
cp -f data/stj.desktop $(DESTDIR)$(PREFIX)/share/applications @ cp -f 'data/$(BINARY).desktop' '$(DESTDIR)$(PREFIX)/share/applications'
.PHONY: install
uninstall: uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/stj @ rm -f '$(DESTDIR)$(PREFIX)/bin/$(BINARY)'
rm -f $(DESTDIR)$(MANPREFIX)/man1/stj.1 @ rm -f '$(DESTDIR)$(MANPREFIX)/man1/$(BINARY).1'
rm -f $(DESTDIR)$(PREFIX)/share/applications/stj.desktop @ rm -f '$(DESTDIR)$(PREFIX)/share/applications/$(BINARY).desktop'
.PHONY: uninstall
# Full clean # =====DEBUG=====
clean:
@ [ ! -e '$(BINARY)' ] || rm '$(BINARY)'
@ rm -rf '$(BUILD_DIR)'
.PHONY: clean
# Release
run-release: release
@ ./'$(RELEASE_DIR)/$(BINARY)'
.PHONY: run-release
release: $(RELEASE_DIR)/Makefile
@ make -C '$(RELEASE_DIR)' -j'$(CORES)' && \
ln -sf '$(RELEASE_DIR)'/'$(BINARY)' ./'$(BINARY)'
.PHONY: release
$(RELEASE_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
@ cmake \
-H'$(SRC_DIR)' \
-B'$(RELEASE_DIR)' \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
clean-release:
@ rm -rf '$(RELEASE_DIR)'
.PHONY: clean-release
# Debug
run-debug: debug
@ ./'$(DEBUG_DIR)/$(BINARY)'
.PHONY: run-debug
debug: $(DEBUG_DIR)/Makefile debug: $(DEBUG_DIR)/Makefile
@ make -C '$(DEBUG_DIR)' -j'$(CORES)' && \ @ make -C '$(DEBUG_DIR)' -j'$(CORES)' && \
ln -sf '$(DEBUG_DIR)/$(BINARY)' ./'$(BINARY)' ln -sf '$(DEBUG_DIR)/$(BINARY)' ./'$(BINARY)'
@ -74,6 +49,48 @@ $(DEBUG_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
-DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# =====RELEASE=====
release: $(RELEASE_DIR)/Makefile
@ make -C '$(RELEASE_DIR)' -j'$(CORES)' && \
ln -sf '$(RELEASE_DIR)'/'$(BINARY)' ./'$(BINARY)'
.PHONY: release
$(RELEASE_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
@ cmake \
-H'$(SRC_DIR)' \
-B'$(RELEASE_DIR)' \
-DCMAKE_BUILD_TYPE=Release \
# =====MINIMUM SIZE RELEASE=====
minsizerel: $(MINSIZEREL_DIR)/Makefile
@ make -C '$(MINSIZEREL_DIR)' -j'$(CORES)' && \
ln -sf '$(MINSIZEREL_DIR)'/'$(BINARY)' ./'$(BINARY)'
.PHONY: minsizerel
$(MINSIZEREL_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
@ cmake \
-H'$(SRC_DIR)' \
-B'$(MINSIZEREL_DIR)' \
-DCMAKE_BUILD_TYPE=MinSizeRel \
# =====CLEANING=====
clean:
@ [ ! -e '$(BINARY)' ] || rm '$(BINARY)'
@ rm -rf '$(BUILD_DIR)'
.PHONY: clean
clean-release:
@ rm -rf '$(RELEASE_DIR)'
.PHONY: clean-release
clean-debug: clean-debug:
@ rm -rf '$(DEBUG_DIR)' @ rm -rf '$(DEBUG_DIR)'
.PHONY: clean-debug .PHONY: clean-debug
# =====FORMAT CODE=====
format:
@ clang-format -i --style=file src/**/*.c src/**/*.h src/*.c src/*.h

View File

@ -5,27 +5,31 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif() endif()
set(SYSTEM_TYPE x64)
# =====COMPILER=====
# =====COMMON SETTINGS=====
set(CMAKE_C_COMPILER "clang-11") set(CMAKE_C_COMPILER "clang-11")
set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD 11)
project(stj VERSION 0.1) project(stj VERSION 0.1)
# =====COMPILE FLAGS=====
add_definitions(-DVERSION="${CMAKE_PROJECT_VERSION}" -D_XOPEN_SOURCE=600) add_definitions(-DVERSION="${CMAKE_PROJECT_VERSION}" -D_XOPEN_SOURCE=600)
# Debug flags
# -g flag gets auto-added by CMake for the debug build
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -O0 -march=native")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address -pedantic")
# Release flags # =====BUILD TYPES=====
# -O3 gets added automatically by CMake # Debug
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Werror -march=native -pedantic-errors") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -O0 -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address -pedantic")
# Arch doesn't use static libraries
if(NOT EXISTS "/etc/arch-release")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -static-libasan")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -static-libasan")
endif()
# Release
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -Werror -pedantic-errors")
# =====EXECUTABLE===== # =====EXECUTABLE=====
@ -40,16 +44,20 @@ find_package(Freetype 2 REQUIRED)
target_include_directories(stj PRIVATE "${FREETYPE_INCLUDE_DIRS}") target_include_directories(stj PRIVATE "${FREETYPE_INCLUDE_DIRS}")
target_link_libraries(stj PRIVATE "${FREETYPE_LIBRARIES}") target_link_libraries(stj PRIVATE "${FREETYPE_LIBRARIES}")
find_package(Fontconfig REQUIRED) find_package(Fontconfig 2 REQUIRED)
target_include_directories(stj PRIVATE "${Fontconfig_INCLUDE_DIRS}") target_include_directories(stj PRIVATE "${Fontconfig_INCLUDE_DIRS}")
target_link_libraries(stj PRIVATE "${Fontconfig_LIBRARIES}") target_link_libraries(stj PRIVATE "${Fontconfig_LIBRARIES}")
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
target_include_directories(stj PRIVATE "${X11_INCLUDE_DIR}") target_include_directories(stj PRIVATE "${X11_INCLUDE_DIR}")
target_link_libraries(stj PRIVATE "${X11_LIBRARIES}") target_link_libraries(stj PRIVATE "${X11_LIBRARIES}")
# TODO Find out if these are included in the above statement or not
# target_link_libraries(stj PRIVATE Xft)
# target_link_libraries(stj PRIVATE Xrender)
# Normally provided with clang
target_link_libraries(stj PRIVATE m) target_link_libraries(stj PRIVATE m)
target_link_libraries(stj PRIVATE rt) # I'm not sure if I actually need this, so keeping it here for reference
# target_link_libraries(stj PRIVATE rt)
target_link_libraries(stj PRIVATE util) target_link_libraries(stj PRIVATE util)
target_link_libraries(stj PRIVATE Xft)
target_link_libraries(stj PRIVATE Xrender)

View File

@ -6,14 +6,14 @@
#ifndef ARG_H #ifndef ARG_H
#define ARG_H #define ARG_H
extern char *argv0; extern char* argv0;
/* use main(int argc, char *argv[]) */ /* use main(int argc, char *argv[]) */
#define ARGBEGIN \ #define ARGBEGIN \
for (argv0 = *argv, argv++, argc--; \ for (argv0 = *argv, argv++, argc--; \
argv[0] && argv[0][0] == '-' && argv[0][1]; argc--, argv++) { \ argv[0] && argv[0][0] == '-' && argv[0][1]; argc--, argv++) { \
char argc_; \ char argc_; \
char **argv_; \ char** argv_; \
int brk_; \ int brk_; \
if (argv[0][1] == '-' && argv[0][2] == '\0') { \ if (argv[0][1] == '-' && argv[0][2] == '\0') { \
argv++; \ argv++; \
@ -35,13 +35,13 @@ extern char *argv0;
#define EARGF(x) \ #define EARGF(x) \
((argv[0][i_ + 1] == '\0' && argv[1] == NULL) \ ((argv[0][i_ + 1] == '\0' && argv[1] == NULL) \
? ((x), abort(), (char *)0) \ ? ((x), abort(), (char*)0) \
: (brk_ = 1, (argv[0][i_ + 1] != '\0') ? (&argv[0][i_ + 1]) \ : (brk_ = 1, (argv[0][i_ + 1] != '\0') ? (&argv[0][i_ + 1]) \
: (argc--, argv++, argv[0]))) : (argc--, argv++, argv[0])))
#define ARGF() \ #define ARGF() \
((argv[0][i_ + 1] == '\0' && argv[1] == NULL) \ ((argv[0][i_ + 1] == '\0' && argv[1] == NULL) \
? (char *)0 \ ? (char*)0 \
: (brk_ = 1, (argv[0][i_ + 1] != '\0') ? (&argv[0][i_ + 1]) \ : (brk_ = 1, (argv[0][i_ + 1] != '\0') ? (&argv[0][i_ + 1]) \
: (argc--, argv++, argv[0]))) : (argc--, argv++, argv[0])))

View File

@ -5,7 +5,8 @@
* *
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/ */
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; static char* font =
"Liberation Mono:pixelsize=12:antialias=true:autohint=true";
static int borderpx = 2; static int borderpx = 2;
/* /*
@ -16,14 +17,14 @@ static int borderpx = 2;
* 4: value of shell in /etc/passwd * 4: value of shell in /etc/passwd
* 5: value of shell in config.h * 5: value of shell in config.h
*/ */
static char *shell = "/bin/sh"; static char* shell = "/bin/sh";
char *utmp = NULL; char* utmp = NULL;
/* scroll program: to enable use a string like "scroll" */ /* scroll program: to enable use a string like "scroll" */
char *scroll = NULL; char* scroll = NULL;
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; char* stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
/* identification sequence returned in DA and DECID */ /* identification sequence returned in DA and DECID */
char *vtiden = "\033[?6c"; char* vtiden = "\033[?6c";
/* Kerning / character bounding-box multipliers */ /* Kerning / character bounding-box multipliers */
static float cwscale = 1.0; static float cwscale = 1.0;
@ -34,7 +35,7 @@ static float chscale = 1.0;
* *
* More advanced example: L" `'\"()[]{}" * More advanced example: L" `'\"()[]{}"
*/ */
wchar_t *worddelimiters = L" "; wchar_t* worddelimiters = L" ";
/* selection timeouts (in milliseconds) */ /* selection timeouts (in milliseconds) */
static unsigned int doubleclicktimeout = 300; static unsigned int doubleclicktimeout = 300;
@ -74,7 +75,7 @@ static unsigned int cursorthickness = 2;
static int bellvolume = 0; static int bellvolume = 0;
/* default TERM value */ /* default TERM value */
char *termname = "st-256color"; char* termname = "st-256color";
/* /*
* spaces per tab * spaces per tab
@ -94,7 +95,7 @@ char *termname = "st-256color";
unsigned int tabspaces = 8; unsigned int tabspaces = 8;
/* Terminal colors (16 first used in escape sequence) */ /* Terminal colors (16 first used in escape sequence) */
static const char *colorname[] = { static const char* colorname[] = {
/* 8 normal colors */ /* 8 normal colors */
"black", "black",
"red3", "red3",

View File

@ -5,7 +5,8 @@
* *
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/ */
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; static char* font =
"Liberation Mono:pixelsize=12:antialias=true:autohint=true";
static int borderpx = 2; static int borderpx = 2;
/* /*
@ -16,14 +17,14 @@ static int borderpx = 2;
* 4: value of shell in /etc/passwd * 4: value of shell in /etc/passwd
* 5: value of shell in config.h * 5: value of shell in config.h
*/ */
static char *shell = "/bin/sh"; static char* shell = "/bin/sh";
char *utmp = NULL; char* utmp = NULL;
/* scroll program: to enable use a string like "scroll" */ /* scroll program: to enable use a string like "scroll" */
char *scroll = NULL; char* scroll = NULL;
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; char* stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
/* identification sequence returned in DA and DECID */ /* identification sequence returned in DA and DECID */
char *vtiden = "\033[?6c"; char* vtiden = "\033[?6c";
/* Kerning / character bounding-box multipliers */ /* Kerning / character bounding-box multipliers */
static float cwscale = 1.0; static float cwscale = 1.0;
@ -34,7 +35,7 @@ static float chscale = 1.0;
* *
* More advanced example: L" `'\"()[]{}" * More advanced example: L" `'\"()[]{}"
*/ */
wchar_t *worddelimiters = L" "; wchar_t* worddelimiters = L" ";
/* selection timeouts (in milliseconds) */ /* selection timeouts (in milliseconds) */
static unsigned int doubleclicktimeout = 300; static unsigned int doubleclicktimeout = 300;
@ -74,7 +75,7 @@ static unsigned int cursorthickness = 2;
static int bellvolume = 0; static int bellvolume = 0;
/* default TERM value */ /* default TERM value */
char *termname = "st-256color"; char* termname = "st-256color";
/* /*
* spaces per tab * spaces per tab
@ -94,7 +95,7 @@ char *termname = "st-256color";
unsigned int tabspaces = 8; unsigned int tabspaces = 8;
/* Terminal colors (16 first used in escape sequence) */ /* Terminal colors (16 first used in escape sequence) */
static const char *colorname[] = { static const char* colorname[] = {
/* 8 normal colors */ /* 8 normal colors */
"black", "black",
"red3", "red3",

68
src/st/selection.c 100644
View File

@ -0,0 +1,68 @@
#include "selection.h"
#include "macros.h"
void selnormalize() {
int i;
if (sel.type == SEL_REGULAR && sel.ob.y != sel.oe.y) {
sel.nb.x = sel.ob.y < sel.oe.y ? sel.ob.x : sel.oe.x;
sel.ne.x = sel.ob.y < sel.oe.y ? sel.oe.x : sel.ob.x;
} else {
sel.nb.x = MIN(sel.ob.x, sel.oe.x);
sel.ne.x = MAX(sel.ob.x, sel.oe.x);
}
sel.nb.y = MIN(sel.ob.y, sel.oe.y);
sel.ne.y = MAX(sel.ob.y, sel.oe.y);
selsnap(&sel.nb.x, &sel.nb.y, -1);
selsnap(&sel.ne.x, &sel.ne.y, +1);
/* expand selection over line breaks */
if (sel.type == SEL_RECTANGULAR)
return;
i = tlinelen(sel.nb.y);
if (i < sel.nb.x)
sel.nb.x = i;
if (tlinelen(sel.ne.y) <= sel.ne.x)
sel.ne.x = term.col - 1;
}
void selscroll(int orig, int n) {
if (sel.ob.x == -1)
return;
if (BETWEEN(sel.nb.y, orig, term.bot) !=
BETWEEN(sel.ne.y, orig, term.bot)) {
selclear();
} else if (BETWEEN(sel.nb.y, orig, term.bot)) {
sel.ob.y += n;
sel.oe.y += n;
if (sel.ob.y < term.top || sel.ob.y > term.bot ||
sel.oe.y < term.top || sel.oe.y > term.bot) {
selclear();
} else {
selnormalize();
}
}
}
void selclear(void) {
if (sel.ob.x == -1)
return;
sel.mode = SEL_IDLE;
sel.ob.x = -1;
tsetdirt(sel.nb.y, sel.ne.y);
}
void selinit(void) {
sel.mode = SEL_IDLE;
sel.snap = 0;
sel.ob.x = -1;
}

36
src/st/selection.h 100644
View File

@ -0,0 +1,36 @@
#ifndef SELECTION_H
#define SELECTION_H
enum selection_mode { SEL_IDLE = 0, SEL_EMPTY = 1, SEL_READY = 2 };
enum selection_type { SEL_REGULAR = 1, SEL_RECTANGULAR = 2 };
enum selection_snap { SNAP_WORD = 1, SNAP_LINE = 2 };
typedef struct {
int mode;
int type;
int snap;
/*
* Selection variables:
* nb normalized coordinates of the beginning of the selection
* ne normalized coordinates of the end of the selection
* ob original coordinates of the beginning of the selection
* oe original coordinates of the end of the selection
*/
struct {
int x, y;
} nb, ne, ob, oe;
int alt;
} Selection;
void selinit(void);
void selstart(int, int, int);
void selnormalize();
void selscroll(int, int);
void selsnap(int*, int*, int);
void selclear(void);
// Global variable for now
static Selection sel;
#endif

View File

@ -19,7 +19,9 @@
#include "../win.h" #include "../win.h"
#include "macros.h" #include "macros.h"
#include "selection.h"
#include "st.h" #include "st.h"
#include "utf8.h"
#if defined(__linux) #if defined(__linux)
#include <pty.h> #include <pty.h>
@ -30,8 +32,6 @@
#endif #endif
/* Arbitrary sizes */ /* Arbitrary sizes */
#define UTF_INVALID 0xFFFD
#define UTF_SIZE 4
#define ESC_BUF_SIZ (128 * UTF_SIZE) #define ESC_BUF_SIZ (128 * UTF_SIZE)
#define ESC_ARG_SIZ 16 #define ESC_ARG_SIZ 16
#define STR_BUF_SIZ ESC_BUF_SIZ #define STR_BUF_SIZ ESC_BUF_SIZ
@ -89,31 +89,13 @@ typedef struct {
char state; char state;
} TCursor; } TCursor;
typedef struct {
int mode;
int type;
int snap;
/*
* Selection variables:
* nb normalized coordinates of the beginning of the selection
* ne normalized coordinates of the end of the selection
* ob original coordinates of the beginning of the selection
* oe original coordinates of the end of the selection
*/
struct {
int x, y;
} nb, ne, ob, oe;
int alt;
} Selection;
/* Internal representation of the screen */ /* Internal representation of the screen */
typedef struct { typedef struct {
int row; /* nb row */ int row; /* nb row */
int col; /* nb col */ int col; /* nb col */
Line *line; /* screen */ Line* line; /* screen */
Line *alt; /* alternate screen */ Line* alt; /* alternate screen */
int *dirty; /* dirtyness of lines */ int* dirty; /* dirtyness of lines */
TCursor c; /* cursor */ TCursor c; /* cursor */
int ocx; /* old cursor col */ int ocx; /* old cursor col */
int ocy; /* old cursor row */ int ocy; /* old cursor row */
@ -124,7 +106,7 @@ typedef struct {
char trantbl[4]; /* charset table translation */ char trantbl[4]; /* charset table translation */
int charset; /* current charset */ int charset; /* current charset */
int icharset; /* selected charset for sequence */ int icharset; /* selected charset for sequence */
int *tabs; int* tabs;
Rune lastc; /* last printed char outside of sequence, 0 if control */ Rune lastc; /* last printed char outside of sequence, 0 if control */
} Term; } Term;
@ -143,17 +125,17 @@ typedef struct {
/* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */ /* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
typedef struct { typedef struct {
char type; /* ESC type ... */ char type; /* ESC type ... */
char *buf; /* allocated raw string */ char* buf; /* allocated raw string */
size_t siz; /* allocation size */ size_t siz; /* allocation size */
size_t len; /* raw string length */ size_t len; /* raw string length */
char *args[STR_ARG_SIZ]; char* args[STR_ARG_SIZ];
int narg; /* nb of args */ int narg; /* nb of args */
} STREscape; } STREscape;
static void execsh(char *, char **); static void execsh(char*, char**);
static void stty(char **); static void stty(char**);
static void sigchld(int); static void sigchld(int);
static void ttywriteraw(const char *, size_t); static void ttywriteraw(const char*, size_t);
static void csidump(void); static void csidump(void);
static void csihandle(void); static void csihandle(void);
@ -165,7 +147,7 @@ static void strhandle(void);
static void strparse(void); static void strparse(void);
static void strreset(void); static void strreset(void);
static void tprinter(char *, size_t); static void tprinter(char*, size_t);
static void tdumpsel(void); static void tdumpsel(void);
static void tdumpline(int); static void tdumpline(int);
static void tdump(void); static void tdump(void);
@ -184,154 +166,104 @@ static void tputc(Rune);
static void treset(void); static void treset(void);
static void tscrollup(int, int); static void tscrollup(int, int);
static void tscrolldown(int, int); static void tscrolldown(int, int);
static void tsetattr(int *, int); static void tsetattr(int*, int);
static void tsetchar(Rune, Glyph *, int, int); static void tsetchar(Rune, Glyph*, int, int);
static void tsetdirt(int, int); static void tsetdirt(int, int);
static void tsetscroll(int, int); static void tsetscroll(int, int);
static void tswapscreen(void); static void tswapscreen(void);
static void tsetmode(int, int, int *, int); static void tsetmode(int, int, int*, int);
static int twrite(const char *, int, int); static int twrite(const char*, int, int);
static void tfulldirt(void); static void tfulldirt(void);
static void tcontrolcode(uchar); static void tcontrolcode(uchar);
static void tdectest(char); static void tdectest(char);
static void tdefutf8(char); static void tdefutf8(char);
static int32_t tdefcolor(int *, int *, int); static int32_t tdefcolor(int*, int*, int);
static void tdeftran(char); static void tdeftran(char);
static void tstrsequence(uchar); static void tstrsequence(uchar);
static void drawregion(int, int, int, int); static void drawregion(int, int, int, int);
static void selnormalize(void); static char* base64dec(const char*);
static void selscroll(int, int); static char base64dec_getc(const char**);
static void selsnap(int *, int *, int);
static size_t utf8decode(const char *, Rune *, size_t); static ssize_t xwrite(int, const char*, size_t);
static Rune utf8decodebyte(char, size_t *);
static char utf8encodebyte(Rune, size_t);
static size_t utf8validate(Rune *, size_t);
static char *base64dec(const char *);
static char base64dec_getc(const char **);
static ssize_t xwrite(int, const char *, size_t);
/* Globals */ /* Globals */
static Term term; static Term term;
static Selection sel;
static CSIEscape csiescseq; static CSIEscape csiescseq;
static STREscape strescseq; static STREscape strescseq;
static int iofd = 1; static int iofd = 1;
static int cmdfd; static int cmdfd;
static pid_t pid; static pid_t pid;
static uchar utfbyte[UTF_SIZE + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; /**
static uchar utfmask[UTF_SIZE + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; * Same as write, but ensures that all bytes are written to the descriptor
static Rune utfmin[UTF_SIZE + 1] = {0, 0, 0x80, 0x800, 0x10000}; * (write sometimes isn't able to write all bytes)
static Rune utfmax[UTF_SIZE + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; *
* @param p_file_desc file descriptor to write to; same logic as write
ssize_t xwrite(int fd, const char *s, size_t len) { * @param p_str char array to write to the file descriptor
size_t aux = len; * @param p_nbytes amount of bytes to write
* @return p_nbytes if the write was successful, otherwise return negative
* error value of write
*/
ssize_t xwrite(int p_file_desc, const char* p_str, size_t p_nbytes) {
size_t aux = p_nbytes;
ssize_t result; ssize_t result;
while (len > 0) { while (p_nbytes > 0) {
result = write(fd, s, len); result = write(p_file_desc, p_str, p_nbytes);
// This means an error occured in write, so it passes the error along // This means an error occured in write, so it passes the error along
if (result < 0) if (result < 0)
return result; return result;
len -= result; p_nbytes -= (size_t)result;
s += result; p_str += result;
} }
return aux; return (ssize_t)aux;
} }
// Same as malloc, but stops entire program if malloc fails /**
void *safe_malloc(size_t len) { * same as malloc, but kill the program if it fails
void *ptr; *
* @param p_len bytes to allocate
* @return pointer to allocated memory
*/
void* safe_malloc(size_t p_len) {
void* ptr;
if (!(ptr = malloc(len))) if (!(ptr = malloc(p_len)))
die("malloc: %s\n", strerror(errno)); die("malloc: %s\n", strerror(errno));
return ptr; return ptr;
} }
// Same as realloc, but stops entire program if malloc fails /**
void *safe_realloc(void *ptr, size_t len) { * same as realloc, but kill the program if it fails
if ((ptr = realloc(ptr, len)) == NULL) *
* @param p_ptr pointer to re-allocate
* @param p_len bytes to re-allocate
* @return pointer to re-allocated memory
*/
void* safe_realloc(void* p_ptr, size_t p_len) {
if ((p_ptr = realloc(p_ptr, p_len)) == NULL)
die("realloc: %s\n", strerror(errno)); die("realloc: %s\n", strerror(errno));
return ptr; return p_ptr;
} }
char *safe_strdup(char *s) { /**
if ((s = strdup(s)) == NULL) * same as strdup, but kill the program if it fails
*
* @param p_str string to copy
* @return pointer to copy of original string
*/
char* safe_strdup(char* p_str) {
if ((p_str = strdup(p_str)) == NULL)
die("strdup: %s\n", strerror(errno)); die("strdup: %s\n", strerror(errno));
return s; return p_str;
}
size_t utf8decode(const char *chr, Rune *u, size_t chr_len) {
size_t i, j, len, type;
Rune udecoded;
*u = UTF_INVALID;
if (!chr_len) // chr_len is 0, so just return 0
return 0;
udecoded = utf8decodebyte(chr[0], &len);
if (!BETWEEN(len, 1, UTF_SIZE))
return 1;
for (i = 1, j = 1; i < chr_len && j < len; ++i, ++j) {
udecoded = (udecoded << 6) | utf8decodebyte(chr[i], &type);
if (type != 0)
return j;
}
if (j < len)
return 0;
*u = udecoded;
utf8validate(u, len);
return len;
}
Rune utf8decodebyte(char c, size_t *i) {
for (*i = 0; *i < LEN(utfmask); ++(*i))
if (((uchar)c & utfmask[*i]) == utfbyte[*i])
return (uchar)c & ~utfmask[*i];
return 0;
}
size_t utf8encode(Rune u, char *c) {
size_t len, i;
len = utf8validate(&u, 0);
if (len > UTF_SIZE)
return 0;
for (i = len - 1; i != 0; --i) {
c[i] = utf8encodebyte(u, 0);
u >>= 6;
}
c[0] = utf8encodebyte(u, len);
return len;
}
char utf8encodebyte(Rune u, size_t i) { return utfbyte[i] | (u & ~utfmask[i]); }
size_t utf8validate(Rune *u, size_t i) {
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
*u = UTF_INVALID;
for (i = 1; *u > utfmax[i]; ++i)
;
return i;
} }
static const char base64_digits[] = { static const char base64_digits[] = {
@ -350,15 +282,15 @@ static const char base64_digits[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0}; 0, 0, 0, 0, 0, 0, 0, 0};
char base64dec_getc(const char **src) { char base64dec_getc(const char** src) {
while (**src && !isprint(**src)) while (**src && !isprint(**src))
(*src)++; (*src)++;
return **src ? *((*src)++) : '='; /* emulate padding if string ends */ return **src ? *((*src)++) : '='; /* emulate padding if string ends */
} }
char *base64dec(const char *src) { char* base64dec(const char* src) {
size_t in_len = strlen(src); size_t in_len = strlen(src);
char *result, *dst; char * result, *dst;
if (in_len % 4) if (in_len % 4)
in_len += 4 - (in_len % 4); in_len += 4 - (in_len % 4);
@ -385,12 +317,6 @@ char *base64dec(const char *src) {
return result; return result;
} }
void selinit(void) {
sel.mode = SEL_IDLE;
sel.snap = 0;
sel.ob.x = -1;
}
int tlinelen(int y) { int tlinelen(int y) {
int i = term.col; int i = term.col;
@ -446,45 +372,21 @@ void selextend(int col, int row, int type, int done) {
sel.mode = done ? SEL_IDLE : SEL_READY; sel.mode = done ? SEL_IDLE : SEL_READY;
} }
void selnormalize(void) {
int i;
if (sel.type == SEL_REGULAR && sel.ob.y != sel.oe.y) {
sel.nb.x = sel.ob.y < sel.oe.y ? sel.ob.x : sel.oe.x;
sel.ne.x = sel.ob.y < sel.oe.y ? sel.oe.x : sel.ob.x;
} else {
sel.nb.x = MIN(sel.ob.x, sel.oe.x);
sel.ne.x = MAX(sel.ob.x, sel.oe.x);
}
sel.nb.y = MIN(sel.ob.y, sel.oe.y);
sel.ne.y = MAX(sel.ob.y, sel.oe.y);
selsnap(&sel.nb.x, &sel.nb.y, -1);
selsnap(&sel.ne.x, &sel.ne.y, +1);
/* expand selection over line breaks */
if (sel.type == SEL_RECTANGULAR)
return;
i = tlinelen(sel.nb.y);
if (i < sel.nb.x)
sel.nb.x = i;
if (tlinelen(sel.ne.y) <= sel.ne.x)
sel.ne.x = term.col - 1;
}
int selected(int x, int y) { int selected(int x, int y) {
if (sel.mode == SEL_EMPTY || sel.ob.x == -1 || if (sel.mode == SEL_EMPTY || sel.ob.x == -1 ||
sel.alt != IS_SET(MODE_ALTSCREEN)) sel.alt != IS_SET(MODE_ALTSCREEN))
return 0; return 0;
if (sel.type == SEL_RECTANGULAR) if (sel.type == SEL_RECTANGULAR)
return BETWEEN(y, sel.nb.y, sel.ne.y) && BETWEEN(x, sel.nb.x, sel.ne.x); return BETWEEN(y, sel.nb.y, sel.ne.y) &&
BETWEEN(x, sel.nb.x, sel.ne.x);
return BETWEEN(y, sel.nb.y, sel.ne.y) && (y != sel.nb.y || x >= sel.nb.x) && return BETWEEN(y, sel.nb.y, sel.ne.y) &&
(y != sel.nb.y || x >= sel.nb.x) &&
(y != sel.ne.y || x <= sel.ne.x); (y != sel.ne.y || x <= sel.ne.x);
} }
void selsnap(int *x, int *y, int direction) { void selsnap(int* x, int* y, int direction) {
int newx, newy, xt, yt; int newx, newy, xt, yt;
int delim, prevdelim; int delim, prevdelim;
Glyph *gp, *prevgp; Glyph *gp, *prevgp;
@ -553,8 +455,8 @@ void selsnap(int *x, int *y, int direction) {
} }
} }
char *getsel(void) { char* getsel(void) {
char *str, *ptr; char * str, *ptr;
int y, bufsize, lastx, linelen; int y, bufsize, lastx, linelen;
Glyph *gp, *last; Glyph *gp, *last;
@ -606,15 +508,7 @@ char *getsel(void) {
return str; return str;
} }
void selclear(void) { void die(const char* errstr, ...) {
if (sel.ob.x == -1)
return;
sel.mode = SEL_IDLE;
sel.ob.x = -1;
tsetdirt(sel.nb.y, sel.ne.y);
}
void die(const char *errstr, ...) {
va_list ap; va_list ap;
va_start(ap, errstr); va_start(ap, errstr);
@ -623,9 +517,9 @@ void die(const char *errstr, ...) {
exit(1); exit(1);
} }
void execsh(char *cmd, char **args) { void execsh(char* cmd, char** args) {
char *sh, *prog, *arg; char * sh, *prog, *arg;
const struct passwd *pw; const struct passwd* pw;
errno = 0; errno = 0;
if ((pw = getpwuid(getuid())) == NULL) { if ((pw = getpwuid(getuid())) == NULL) {
@ -651,7 +545,7 @@ void execsh(char *cmd, char **args) {
prog = sh; prog = sh;
arg = NULL; arg = NULL;
} }
DEFAULT(args, ((char *[]){prog, arg, NULL})); DEFAULT(args, ((char*[]){prog, arg, NULL}));
unsetenv("COLUMNS"); unsetenv("COLUMNS");
unsetenv("LINES"); unsetenv("LINES");
@ -690,7 +584,7 @@ void sigchld(int a) {
_exit(0); _exit(0);
} }
void stty(char **args) { void stty(char** args) {
char cmd[_POSIX_ARG_MAX], **p, *q, *s; char cmd[_POSIX_ARG_MAX], **p, *q, *s;
size_t n, siz; size_t n, siz;
@ -712,7 +606,7 @@ void stty(char **args) {
perror("Couldn't call stty"); perror("Couldn't call stty");
} }
int ttynew(char *line, char *cmd, char *out, char **args) { int ttynew(char* line, char* cmd, char* out, char** args) {
int m, s; int m, s;
if (out) { if (out) {
@ -792,8 +686,8 @@ size_t ttyread(void) {
} }
} }
void ttywrite(const char *s, size_t n, int may_echo) { void ttywrite(const char* s, size_t n, int may_echo) {
const char *next; const char* next;
if (may_echo && IS_SET(MODE_ECHO)) if (may_echo && IS_SET(MODE_ECHO))
twrite(s, n, 1); twrite(s, n, 1);
@ -818,7 +712,7 @@ void ttywrite(const char *s, size_t n, int may_echo) {
} }
} }
void ttywriteraw(const char *s, size_t n) { void ttywriteraw(const char* s, size_t n) {
fd_set wfd, rfd; fd_set wfd, rfd;
ssize_t r; ssize_t r;
size_t lim = 256; size_t lim = 256;
@ -971,7 +865,7 @@ void tnew(int col, int row) {
} }
void tswapscreen(void) { void tswapscreen(void) {
Line *tmp = term.line; Line* tmp = term.line;
term.line = term.alt; term.line = term.alt;
term.alt = tmp; term.alt = tmp;
@ -1015,24 +909,6 @@ void tscrollup(int orig, int n) {
selscroll(orig, -n); selscroll(orig, -n);
} }
void selscroll(int orig, int n) {
if (sel.ob.x == -1)
return;
if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) {
selclear();
} else if (BETWEEN(sel.nb.y, orig, term.bot)) {
sel.ob.y += n;
sel.oe.y += n;
if (sel.ob.y < term.top || sel.ob.y > term.bot || sel.oe.y < term.top ||
sel.oe.y > term.bot) {
selclear();
} else {
selnormalize();
}
}
}
void tnewline(int first_col) { void tnewline(int first_col) {
int y = term.c.y; int y = term.c.y;
@ -1045,7 +921,7 @@ void tnewline(int first_col) {
} }
void csiparse(void) { void csiparse(void) {
char *p = csiescseq.buf, *np; char * p = csiescseq.buf, *np;
long int v; long int v;
csiescseq.narg = 0; csiescseq.narg = 0;
@ -1092,8 +968,8 @@ void tmoveto(int x, int y) {
term.c.y = LIMIT(y, miny, maxy); term.c.y = LIMIT(y, miny, maxy);
} }
void tsetchar(Rune u, Glyph *attr, int x, int y) { void tsetchar(Rune u, Glyph* attr, int x, int y) {
static char *vt100_0[62] = { static char* vt100_0[62] = {
/* 0x41 - 0x7e */ /* 0x41 - 0x7e */
"", "", "", "", "", "", "", /* A - G */ "", "", "", "", "", "", "", /* A - G */
0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
@ -1129,7 +1005,7 @@ void tsetchar(Rune u, Glyph *attr, int x, int y) {
void tclearregion(int x1, int y1, int x2, int y2) { void tclearregion(int x1, int y1, int x2, int y2) {
int x, y, temp; int x, y, temp;
Glyph *gp; Glyph* gp;
if (x1 > x2) if (x1 > x2)
temp = x1, x1 = x2, x2 = temp; temp = x1, x1 = x2, x2 = temp;
@ -1157,7 +1033,7 @@ void tclearregion(int x1, int y1, int x2, int y2) {
void tdeletechar(int n) { void tdeletechar(int n) {
int dst, src, size; int dst, src, size;
Glyph *line; Glyph* line;
LIMIT(n, 0, term.col - term.c.x); LIMIT(n, 0, term.col - term.c.x);
@ -1172,7 +1048,7 @@ void tdeletechar(int n) {
void tinsertblank(int n) { void tinsertblank(int n) {
int dst, src, size; int dst, src, size;
Glyph *line; Glyph* line;
LIMIT(n, 0, term.col - term.c.x); LIMIT(n, 0, term.col - term.c.x);
@ -1195,14 +1071,15 @@ void tdeleteline(int n) {
tscrollup(term.c.y, n); tscrollup(term.c.y, n);
} }
int32_t tdefcolor(int *attr, int *npar, int l) { int32_t tdefcolor(int* attr, int* npar, int l) {
int32_t idx = -1; int32_t idx = -1;
uint r, g, b; uint r, g, b;
switch (attr[*npar + 1]) { switch (attr[*npar + 1]) {
case 2: /* direct color in RGB space */ case 2: /* direct color in RGB space */
if (*npar + 4 >= l) { if (*npar + 4 >= l) {
fprintf(stderr, "erresc(38): Incorrect number of parameters (%d)\n", fprintf(stderr,
"erresc(38): Incorrect number of parameters (%d)\n",
*npar); *npar);
break; break;
} }
@ -1217,7 +1094,8 @@ int32_t tdefcolor(int *attr, int *npar, int l) {
break; break;
case 5: /* indexed color */ case 5: /* indexed color */
if (*npar + 2 >= l) { if (*npar + 2 >= l) {
fprintf(stderr, "erresc(38): Incorrect number of parameters (%d)\n", fprintf(stderr,
"erresc(38): Incorrect number of parameters (%d)\n",
*npar); *npar);
break; break;
} }
@ -1239,7 +1117,7 @@ int32_t tdefcolor(int *attr, int *npar, int l) {
return idx; return idx;
} }
void tsetattr(int *attr, int l) { void tsetattr(int* attr, int l) {
int i; int i;
int32_t idx; int32_t idx;
@ -1247,8 +1125,8 @@ void tsetattr(int *attr, int l) {
switch (attr[i]) { switch (attr[i]) {
case 0: case 0:
term.c.attr.mode &= term.c.attr.mode &=
~(ATTR_BOLD | ATTR_FAINT | ATTR_ITALIC | ATTR_UNDERLINE | ATTR_BLINK | ~(ATTR_BOLD | ATTR_FAINT | ATTR_ITALIC | ATTR_UNDERLINE |
ATTR_REVERSE | ATTR_INVISIBLE | ATTR_STRUCK); ATTR_BLINK | ATTR_REVERSE | ATTR_INVISIBLE | ATTR_STRUCK);
term.c.attr.fg = defaultfg; term.c.attr.fg = defaultfg;
term.c.attr.bg = defaultbg; term.c.attr.bg = defaultbg;
break; break;
@ -1323,7 +1201,8 @@ void tsetattr(int *attr, int l) {
} else if (BETWEEN(attr[i], 100, 107)) { } else if (BETWEEN(attr[i], 100, 107)) {
term.c.attr.bg = attr[i] - 100 + 8; term.c.attr.bg = attr[i] - 100 + 8;
} else { } else {
fprintf(stderr, "erresc(default): gfx attr %d unknown\n", attr[i]); fprintf(stderr, "erresc(default): gfx attr %d unknown\n",
attr[i]);
csidump(); csidump();
} }
break; break;
@ -1345,7 +1224,7 @@ void tsetscroll(int t, int b) {
term.bot = b; term.bot = b;
} }
void tsetmode(int priv, int set, int *args, int narg) { void tsetmode(int priv, int set, int* args, int narg) {
int alt, *lim; int alt, *lim;
for (lim = args + narg; args < lim; ++args) { for (lim = args + narg; args < lim; ++args) {
@ -1441,7 +1320,8 @@ void tsetmode(int priv, int set, int *args, int narg) {
codes. */ codes. */
break; break;
default: default:
fprintf(stderr, "erresc: unknown private set/reset mode %d\n", *args); fprintf(stderr, "erresc: unknown private set/reset mode %d\n",
*args);
break; break;
} }
} else { } else {
@ -1619,7 +1499,8 @@ void csihandle(void) {
break; break;
case 'X': /* ECH -- Erase <n> char */ case 'X': /* ECH -- Erase <n> char */
DEFAULT(csiescseq.arg[0], 1); DEFAULT(csiescseq.arg[0], 1);
tclearregion(term.c.x, term.c.y, term.c.x + csiescseq.arg[0] - 1, term.c.y); tclearregion(term.c.x, term.c.y, term.c.x + csiescseq.arg[0] - 1,
term.c.y);
break; break;
case 'P': /* DCH -- Delete <n> char */ case 'P': /* DCH -- Delete <n> char */
DEFAULT(csiescseq.arg[0], 1); DEFAULT(csiescseq.arg[0], 1);
@ -1641,8 +1522,8 @@ void csihandle(void) {
break; break;
case 'n': /* DSR Device Status Report (cursor position) */ case 'n': /* DSR Device Status Report (cursor position) */
if (csiescseq.arg[0] == 6) { if (csiescseq.arg[0] == 6) {
len = len = snprintf(buf, sizeof(buf), "\033[%i;%iR", term.c.y + 1,
snprintf(buf, sizeof(buf), "\033[%i;%iR", term.c.y + 1, term.c.x + 1); term.c.x + 1);
ttywrite(buf, len, 0); ttywrite(buf, len, 0);
} }
break; break;
@ -1772,7 +1653,7 @@ void strhandle(void) {
void strparse(void) { void strparse(void) {
int c; int c;
char *p = strescseq.buf; char* p = strescseq.buf;
strescseq.narg = 0; strescseq.narg = 0;
strescseq.buf[strescseq.len] = '\0'; strescseq.buf[strescseq.len] = '\0';
@ -1822,12 +1703,12 @@ void strreset(void) {
}; };
} }
void sendbreak(const Arg *arg) { void sendbreak(const Arg* arg) {
if (tcsendbreak(cmdfd, 0)) if (tcsendbreak(cmdfd, 0))
perror("Error sending break"); perror("Error sending break");
} }
void tprinter(char *s, size_t len) { void tprinter(char* s, size_t len) {
if (iofd != -1 && xwrite(iofd, s, len) < 0) { if (iofd != -1 && xwrite(iofd, s, len) < 0) {
perror("Error writing to output file"); perror("Error writing to output file");
close(iofd); close(iofd);
@ -1835,14 +1716,14 @@ void tprinter(char *s, size_t len) {
} }
} }
void toggleprinter(const Arg *arg) { term.mode ^= MODE_PRINT; } void toggleprinter(const Arg* arg) { term.mode ^= MODE_PRINT; }
void printscreen(const Arg *arg) { tdump(); } void printscreen(const Arg* arg) { tdump(); }
void printsel(const Arg *arg) { tdumpsel(); } void printsel(const Arg* arg) { tdumpsel(); }
void tdumpsel(void) { void tdumpsel(void) {
char *ptr; char* ptr;
if ((ptr = getsel())) { if ((ptr = getsel())) {
tprinter(ptr, strlen(ptr)); tprinter(ptr, strlen(ptr));
@ -1895,7 +1776,7 @@ void tdefutf8(char ascii) {
void tdeftran(char ascii) { void tdeftran(char ascii) {
static char cs[] = "0B"; static char cs[] = "0B";
static int vcs[] = {CS_GRAPHIC0, CS_USA}; static int vcs[] = {CS_GRAPHIC0, CS_USA};
char *p; char* p;
if ((p = strchr(cs, ascii)) == NULL) { if ((p = strchr(cs, ascii)) == NULL) {
fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii); fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
@ -2108,8 +1989,8 @@ int eschandle(uchar ascii) {
strhandle(); strhandle();
break; break;
default: default:
fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n", (uchar)ascii, fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
isprint(ascii) ? ascii : '.'); (uchar)ascii, isprint(ascii) ? ascii : '.');
break; break;
} }
return 1; return 1;
@ -2119,7 +2000,7 @@ void tputc(Rune u) {
char c[UTF_SIZE]; char c[UTF_SIZE];
int control; int control;
int width, len; int width, len;
Glyph *gp; Glyph* gp;
control = ISCONTROL(u); control = ISCONTROL(u);
if (u < 127 || !IS_SET(MODE_UTF8)) { if (u < 127 || !IS_SET(MODE_UTF8)) {
@ -2249,7 +2130,7 @@ check_control_code:
} }
} }
int twrite(const char *buf, int buflen, int show_ctrl) { int twrite(const char* buf, int buflen, int show_ctrl) {
int charsize; int charsize;
Rune u; Rune u;
int n; int n;
@ -2283,7 +2164,7 @@ void tresize(int col, int row) {
int i; int i;
int minrow = MIN(row, term.row); int minrow = MIN(row, term.row);
int mincol = MIN(col, term.col); int mincol = MIN(col, term.col);
int *bp; int* bp;
TCursor c; TCursor c;
if (col < 1 || row < 1) { if (col < 1 || row < 1) {

View File

@ -3,9 +3,12 @@
#ifndef ST_H #ifndef ST_H
#define ST_H #define ST_H
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <stddef.h>
#include "types.h"
#include "utf8.h"
enum glyph_attribute { enum glyph_attribute {
ATTR_NULL = 0, ATTR_NULL = 0,
@ -23,29 +26,6 @@ enum glyph_attribute {
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
}; };
enum selection_mode {
SEL_IDLE = 0,
SEL_EMPTY = 1,
SEL_READY = 2
};
enum selection_type {
SEL_REGULAR = 1,
SEL_RECTANGULAR = 2
};
enum selection_snap {
SNAP_WORD = 1,
SNAP_LINE = 2
};
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned short ushort;
typedef uint_least32_t Rune;
#define Glyph Glyph_ #define Glyph Glyph_
typedef struct { typedef struct {
Rune u; /* character code */ Rune u; /* character code */
@ -54,34 +34,34 @@ typedef struct {
uint32_t bg; /* background */ uint32_t bg; /* background */
} Glyph; } Glyph;
typedef Glyph *Line; typedef Glyph* Line;
typedef union { typedef union {
int i; int i;
uint ui; uint ui;
float f; float f;
const void *v; const void* v;
const char *s; const char* s;
} Arg; } Arg;
void die(const char *, ...); void die(const char*, ...);
void redraw(void); void redraw(void);
void draw(void); void draw(void);
void printscreen(const Arg *); void printscreen(const Arg*);
void printsel(const Arg *); void printsel(const Arg*);
void sendbreak(const Arg *); void sendbreak(const Arg*);
void toggleprinter(const Arg *); void toggleprinter(const Arg*);
int tattrset(int); int tattrset(int);
void tnew(int, int); void tnew(int, int);
void tresize(int, int); void tresize(int, int);
void tsetdirtattr(int); void tsetdirtattr(int);
void ttyhangup(void); void ttyhangup(void);
int ttynew(char *, char *, char *, char **); int ttynew(char*, char*, char*, char**);
size_t ttyread(void); size_t ttyread(void);
void ttyresize(int, int); void ttyresize(int, int);
void ttywrite(const char *, size_t, int); void ttywrite(const char*, size_t, int);
void resettitle(void); void resettitle(void);
@ -90,23 +70,23 @@ void selinit(void);
void selstart(int, int, int); void selstart(int, int, int);
void selextend(int, int, int, int); void selextend(int, int, int, int);
int selected(int, int); int selected(int, int);
char *getsel(void); char* getsel(void);
size_t utf8encode(Rune, char *); size_t utf8encode(Rune, char*);
void *safe_malloc(size_t); void* safe_malloc(size_t);
void *safe_realloc(void *, size_t); void* safe_realloc(void*, size_t);
char *safe_strdup(char *); char* safe_strdup(char*);
/* config.h globals */ /* config.h globals */
extern char *utmp; extern char* utmp;
extern char *scroll; extern char* scroll;
extern char *stty_args; extern char* stty_args;
extern char *vtiden; extern char* vtiden;
extern wchar_t *worddelimiters; extern wchar_t* worddelimiters;
extern int allowaltscreen; extern int allowaltscreen;
extern int allowwindowops; extern int allowwindowops;
extern char *termname; extern char* termname;
extern unsigned int tabspaces; extern unsigned int tabspaces;
extern unsigned int defaultfg; extern unsigned int defaultfg;
extern unsigned int defaultbg; extern unsigned int defaultbg;

9
src/st/types.h 100644
View File

@ -0,0 +1,9 @@
#ifndef TYPES_H
#define TYPES_H
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned short ushort;
#endif

105
src/st/utf8.c 100644
View File

@ -0,0 +1,105 @@
#include "utf8.h"
#include "macros.h"
#include "types.h"
static uchar utfbyte[UTF_SIZE + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
static uchar utfmask[UTF_SIZE + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static Rune utfmin[UTF_SIZE + 1] = {0, 0, 0x80, 0x800, 0x10000};
static Rune utfmax[UTF_SIZE + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
/**
* Decode a given char array into a utf8 Rune
*
* @param p_char char array to decode
* @param p_rune rune pointer to decode to
* @param p_char_len length of the char array
* @return size of the decoded rune
*/
size_t utf8decode(const char* p_char, Rune* p_rune, size_t p_char_len) {
size_t decoded_len, type, i;
Rune decoded_rune;
*p_rune = UTF_INVALID;
if (!p_char_len) // p_char_len is 0, so just return 0
return 0;
decoded_rune = utf8decodebyte(p_char[0], &decoded_len);
if (!BETWEEN(decoded_len, 1, UTF_SIZE))
return 1;
for (i = 1; i < p_char_len && i < decoded_len; ++i) {
decoded_rune = (decoded_rune << 6) | utf8decodebyte(p_char[i], &type);
if (type != 0)
return i;
}
if (i < decoded_len)
return 0;
*p_rune = decoded_rune;
utf8validate(p_rune, decoded_len);
return decoded_len;
}
/**
* Decode a single byte to UTF-8
*
* @param p_char char to decode
* @param p_i counter used in internal for loop
* @return decoded rune
*/
Rune utf8decodebyte(char p_char, size_t* p_i) {
for (*p_i = 0; *p_i < LEN(utfmask); ++(*p_i)) {
if (((uchar)p_char & utfmask[*p_i]) == utfbyte[*p_i])
return (uchar)p_char & ~utfmask[*p_i];
}
return 0;
}
/**
* Encode a UTF-8 rune
*
* @param p_rune rune to encode
* @param p_char char array to encode to
* @return
*/
size_t utf8encode(Rune p_rune, char* p_char) {
size_t len, i;
len = utf8validate(&p_rune, 0);
if (len > UTF_SIZE)
return 0;
for (i = len - 1; i != 0; --i) {
p_char[i] = utf8encodebyte(p_rune, 0);
p_rune >>= 6;
}
p_char[0] = utf8encodebyte(p_rune, len);
return len;
}
char utf8encodebyte(Rune u, size_t i) {
return utfbyte[i] | (u & ~utfmask[i]);
}
/**
* Check if a given rune is a valid UTF-8 rune
*
* @param p_rune rune to validate
* @param i
*/
size_t utf8validate(Rune* p_rune, size_t i) {
if (!BETWEEN(*p_rune, utfmin[i], utfmax[i]) ||
BETWEEN(*p_rune, 0xD800, 0xDFFF))
*p_rune = UTF_INVALID;
// Count up i until you find a utfmax entry that's greater than *p_rune
for (i = 1; *p_rune > utfmax[i]; ++i)
;
return i;
}

17
src/st/utf8.h 100644
View File

@ -0,0 +1,17 @@
#ifndef UTF8_H
#define UTF8_H
#include <stdint.h>
#include <stdlib.h>
#define UTF_INVALID 0xFFFD
#define UTF_SIZE 4
typedef uint_least32_t Rune;
size_t utf8decode(const char*, Rune*, size_t);
Rune utf8decodebyte(char, size_t*);
char utf8encodebyte(Rune, size_t);
size_t utf8validate(Rune*, size_t);
#endif

View File

@ -34,13 +34,13 @@ void xdrawcursor(int, int, Glyph, int, int, Glyph);
void xdrawline(Line, int, int, int); void xdrawline(Line, int, int, int);
void xfinishdraw(void); void xfinishdraw(void);
void xloadcols(void); void xloadcols(void);
int xsetcolorname(int, const char *); int xsetcolorname(int, const char*);
void xseticontitle(char *); void xseticontitle(char*);
void xsettitle(char *); void xsettitle(char*);
int xsetcursor(int); int xsetcursor(int);
void xsetmode(int, unsigned int); void xsetmode(int, unsigned int);
void xsetpointermotion(int); void xsetpointermotion(int);
void xsetsel(char *); void xsetsel(char*);
int xstartdraw(void); int xstartdraw(void);
void xximspot(int, int); void xximspot(int, int);

332
src/x.c
View File

@ -15,7 +15,7 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
char *argv0; char* argv0;
#include "arg.h" #include "arg.h"
#include "st/macros.h" #include "st/macros.h"
#include "st/st.h" #include "st/st.h"
@ -25,14 +25,14 @@ char *argv0;
typedef struct { typedef struct {
uint mod; uint mod;
KeySym keysym; KeySym keysym;
void (*func)(const Arg *); void (*func)(const Arg*);
const Arg arg; const Arg arg;
} Shortcut; } Shortcut;
typedef struct { typedef struct {
uint mod; uint mod;
uint button; uint button;
void (*func)(const Arg *); void (*func)(const Arg*);
const Arg arg; const Arg arg;
uint release; uint release;
} MouseShortcut; } MouseShortcut;
@ -40,7 +40,7 @@ typedef struct {
typedef struct { typedef struct {
KeySym k; KeySym k;
uint mask; uint mask;
char *s; char* s;
/* three-valued logic variables: 0 indifferent, 1 on, -1 off */ /* three-valued logic variables: 0 indifferent, 1 on, -1 off */
signed char appkey; /* application keypad */ signed char appkey; /* application keypad */
signed char appcursor; /* application cursor */ signed char appcursor; /* application cursor */
@ -52,14 +52,14 @@ typedef struct {
#define XK_SWITCH_MOD (1 << 13) #define XK_SWITCH_MOD (1 << 13)
/* function definitions used in config.h */ /* function definitions used in config.h */
static void clipcopy(const Arg *); static void clipcopy(const Arg*);
static void clippaste(const Arg *); static void clippaste(const Arg*);
static void numlock(const Arg *); static void numlock(const Arg*);
static void selpaste(const Arg *); static void selpaste(const Arg*);
static void zoom(const Arg *); static void zoom(const Arg*);
static void zoomabs(const Arg *); static void zoomabs(const Arg*);
static void zoomreset(const Arg *); static void zoomreset(const Arg*);
static void ttysend(const Arg *); static void ttysend(const Arg*);
/* config.h for applying patches and the configuration. */ /* config.h for applying patches and the configuration. */
#include "config.h" #include "config.h"
@ -74,7 +74,7 @@ static void ttysend(const Arg *);
#define TRUEGREEN(x) (((x)&0xff00)) #define TRUEGREEN(x) (((x)&0xff00))
#define TRUEBLUE(x) (((x)&0xff) << 8) #define TRUEBLUE(x) (((x)&0xff) << 8)
typedef XftDraw *Draw; typedef XftDraw* Draw;
typedef XftColor Color; typedef XftColor Color;
typedef XftGlyphFontSpec GlyphFontSpec; typedef XftGlyphFontSpec GlyphFontSpec;
@ -89,11 +89,11 @@ typedef struct {
} TermWindow; } TermWindow;
typedef struct { typedef struct {
Display *dpy; Display* dpy;
Colormap cmap; Colormap cmap;
Window win; Window win;
Drawable buf; Drawable buf;
GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ GlyphFontSpec* specbuf; /* font spec buffer used for rendering */
Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid;
struct { struct {
XIM xim; XIM xim;
@ -102,7 +102,7 @@ typedef struct {
XVaNestedList spotlist; XVaNestedList spotlist;
} ime; } ime;
Draw draw; Draw draw;
Visual *vis; Visual* vis;
XSetWindowAttributes attrs; XSetWindowAttributes attrs;
int scr; int scr;
int isfixed; /* is fixed geometry? */ int isfixed; /* is fixed geometry? */
@ -112,7 +112,7 @@ typedef struct {
typedef struct { typedef struct {
Atom xtarget; Atom xtarget;
char *primary, *clipboard; char * primary, *clipboard;
struct timespec tclick1; struct timespec tclick1;
struct timespec tclick2; struct timespec tclick2;
} XSelection; } XSelection;
@ -128,70 +128,69 @@ typedef struct {
int badweight; int badweight;
short lbearing; short lbearing;
short rbearing; short rbearing;
XftFont *match; XftFont* match;
FcFontSet *set; FcFontSet* set;
FcPattern *pattern; FcPattern* pattern;
} Font; } Font;
/* Drawing Context */ /* Drawing Context */
typedef struct { typedef struct {
Color *col; Color* col;
size_t collen; size_t collen;
Font font, bfont, ifont, ibfont; Font font, bfont, ifont, ibfont;
GC gc; GC gc;
} DC; } DC;
static inline ushort sixd_to_16bit(int); static inline ushort sixd_to_16bit(int);
static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, static int xmakeglyphfontspecs(XftGlyphFontSpec*, const Glyph*, int, int, int);
int); static void xdrawglyphfontspecs(const XftGlyphFontSpec*, Glyph, int, int, int);
static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
static void xdrawglyph(Glyph, int, int); static void xdrawglyph(Glyph, int, int);
static void xclear(int, int, int, int); static void xclear(int, int, int, int);
static int xgeommasktogravity(int); static int xgeommasktogravity(int);
static int ximopen(Display *); static int ximopen(Display*);
static void ximinstantiate(Display *, XPointer, XPointer); static void ximinstantiate(Display*, XPointer, XPointer);
static void ximdestroy(XIM, XPointer, XPointer); static void ximdestroy(XIM, XPointer, XPointer);
static int xicdestroy(XIC, XPointer, XPointer); static int xicdestroy(XIC, XPointer, XPointer);
static void xinit(int, int); static void xinit(int, int);
static void cresize(int, int); static void cresize(int, int);
static void xresize(int, int); static void xresize(int, int);
static void xhints(void); static void xhints(void);
static int xloadcolor(int, const char *, Color *); static int xloadcolor(int, const char*, Color*);
static int xloadfont(Font *, FcPattern *); static int xloadfont(Font*, FcPattern*);
static void xloadfonts(char *, double); static void xloadfonts(char*, double);
static void xunloadfont(Font *); static void xunloadfont(Font*);
static void xunloadfonts(void); static void xunloadfonts(void);
static void xsetenv(void); static void xsetenv(void);
static void xseturgency(int); static void xseturgency(int);
static int evcol(XEvent *); static int evcol(XEvent*);
static int evrow(XEvent *); static int evrow(XEvent*);
static void expose(XEvent *); static void expose(XEvent*);
static void visibility(XEvent *); static void visibility(XEvent*);
static void unmap(XEvent *); static void unmap(XEvent*);
static void kpress(XEvent *); static void kpress(XEvent*);
static void cmessage(XEvent *); static void cmessage(XEvent*);
static void resize(XEvent *); static void resize(XEvent*);
static void focus(XEvent *); static void focus(XEvent*);
static uint buttonmask(uint); static uint buttonmask(uint);
static int mouseaction(XEvent *, uint); static int mouseaction(XEvent*, uint);
static void brelease(XEvent *); static void brelease(XEvent*);
static void bpress(XEvent *); static void bpress(XEvent*);
static void bmotion(XEvent *); static void bmotion(XEvent*);
static void propnotify(XEvent *); static void propnotify(XEvent*);
static void selnotify(XEvent *); static void selnotify(XEvent*);
static void selclear_(XEvent *); static void selclear_(XEvent*);
static void selrequest(XEvent *); static void selrequest(XEvent*);
static void setsel(char *, Time); static void setsel(char*, Time);
static void mousesel(XEvent *, int); static void mousesel(XEvent*, int);
static void mousereport(XEvent *); static void mousereport(XEvent*);
static char *kmap(KeySym, uint); static char* kmap(KeySym, uint);
static int match(uint, uint); static int match(uint, uint);
static void run(void); static void run(void);
static void usage(void); static void usage(void);
static void (*handler[LASTEvent])(XEvent *) = { static void (*handler[LASTEvent])(XEvent*) = {
[KeyPress] = kpress, [KeyPress] = kpress,
[ClientMessage] = cmessage, [ClientMessage] = cmessage,
[ConfigureNotify] = resize, [ConfigureNotify] = resize,
@ -227,31 +226,31 @@ static TermWindow win;
enum { FRC_NORMAL, FRC_ITALIC, FRC_BOLD, FRC_ITALICBOLD }; enum { FRC_NORMAL, FRC_ITALIC, FRC_BOLD, FRC_ITALICBOLD };
typedef struct { typedef struct {
XftFont *font; XftFont* font;
int flags; int flags;
Rune unicodep; Rune unicodep;
} Fontcache; } Fontcache;
/* Fontcache is an array now. A new font will be appended to the array. */ /* Fontcache is an array now. A new font will be appended to the array. */
static Fontcache *frc = NULL; static Fontcache* frc = NULL;
static int frclen = 0; static int frclen = 0;
static int frccap = 0; static int frccap = 0;
static char *usedfont = NULL; static char* usedfont = NULL;
static double usedfontsize = 0; static double usedfontsize = 0;
static double defaultfontsize = 0; static double defaultfontsize = 0;
static char *opt_class = NULL; static char* opt_class = NULL;
static char **opt_cmd = NULL; static char** opt_cmd = NULL;
static char *opt_embed = NULL; static char* opt_embed = NULL;
static char *opt_font = NULL; static char* opt_font = NULL;
static char *opt_io = NULL; static char* opt_io = NULL;
static char *opt_line = NULL; static char* opt_line = NULL;
static char *opt_name = NULL; static char* opt_name = NULL;
static char *opt_title = NULL; static char* opt_title = NULL;
static int oldbutton = 3; /* button event on startup: 3 = release */ static int oldbutton = 3; /* button event on startup: 3 = release */
void clipcopy(const Arg *dummy) { void clipcopy(const Arg* dummy) {
Atom clipboard; Atom clipboard;
free(xsel.clipboard); free(xsel.clipboard);
@ -264,7 +263,7 @@ void clipcopy(const Arg *dummy) {
} }
} }
void clippaste(const Arg *dummy) { void clippaste(const Arg* dummy) {
Atom clipboard; Atom clipboard;
clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
@ -272,21 +271,21 @@ void clippaste(const Arg *dummy) {
CurrentTime); CurrentTime);
} }
void selpaste(const Arg *dummy) { void selpaste(const Arg* dummy) {
XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY, xw.win, XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY, xw.win,
CurrentTime); CurrentTime);
} }
void numlock(const Arg *dummy) { win.mode ^= MODE_NUMLOCK; } void numlock(const Arg* dummy) { win.mode ^= MODE_NUMLOCK; }
void zoom(const Arg *arg) { void zoom(const Arg* arg) {
Arg larg; Arg larg;
larg.f = usedfontsize + arg->f; larg.f = usedfontsize + arg->f;
zoomabs(&larg); zoomabs(&larg);
} }
void zoomabs(const Arg *arg) { void zoomabs(const Arg* arg) {
xunloadfonts(); xunloadfonts();
xloadfonts(usedfont, arg->f); xloadfonts(usedfont, arg->f);
cresize(0, 0); cresize(0, 0);
@ -294,7 +293,7 @@ void zoomabs(const Arg *arg) {
xhints(); xhints();
} }
void zoomreset(const Arg *arg) { void zoomreset(const Arg* arg) {
Arg larg; Arg larg;
if (defaultfontsize > 0) { if (defaultfontsize > 0) {
@ -303,21 +302,21 @@ void zoomreset(const Arg *arg) {
} }
} }
void ttysend(const Arg *arg) { ttywrite(arg->s, strlen(arg->s), 1); } void ttysend(const Arg* arg) { ttywrite(arg->s, strlen(arg->s), 1); }
int evcol(XEvent *e) { int evcol(XEvent* e) {
int x = e->xbutton.x - borderpx; int x = e->xbutton.x - borderpx;
LIMIT(x, 0, win.tw - 1); LIMIT(x, 0, win.tw - 1);
return x / win.cw; return x / win.cw;
} }
int evrow(XEvent *e) { int evrow(XEvent* e) {
int y = e->xbutton.y - borderpx; int y = e->xbutton.y - borderpx;
LIMIT(y, 0, win.th - 1); LIMIT(y, 0, win.th - 1);
return y / win.ch; return y / win.ch;
} }
void mousesel(XEvent *e, int done) { void mousesel(XEvent* e, int done) {
int type, seltype = SEL_REGULAR; int type, seltype = SEL_REGULAR;
uint state = e->xbutton.state & ~(Button1Mask | forcemousemod); uint state = e->xbutton.state & ~(Button1Mask | forcemousemod);
@ -332,7 +331,7 @@ void mousesel(XEvent *e, int done) {
setsel(getsel(), e->xbutton.time); setsel(getsel(), e->xbutton.time);
} }
void mousereport(XEvent *e) { void mousereport(XEvent* e) {
int len, x = evcol(e), y = evrow(e), button = e->xbutton.button, int len, x = evcol(e), y = evrow(e), button = e->xbutton.button,
state = e->xbutton.state; state = e->xbutton.state;
char buf[40]; char buf[40];
@ -374,16 +373,17 @@ void mousereport(XEvent *e) {
} }
if (!IS_SET(MODE_MOUSEX10)) { if (!IS_SET(MODE_MOUSEX10)) {
button += ((state & ShiftMask) ? 4 : 0) + ((state & Mod4Mask) ? 8 : 0) + button += ((state & ShiftMask) ? 4 : 0) +
((state & Mod4Mask) ? 8 : 0) +
((state & ControlMask) ? 16 : 0); ((state & ControlMask) ? 16 : 0);
} }
if (IS_SET(MODE_MOUSESGR)) { if (IS_SET(MODE_MOUSESGR)) {
len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", button, x + 1, y + 1, len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", button, x + 1,
e->xbutton.type == ButtonRelease ? 'm' : 'M'); y + 1, e->xbutton.type == ButtonRelease ? 'm' : 'M');
} else if (x < 223 && y < 223) { } else if (x < 223 && y < 223) {
len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", 32 + button, 32 + x + 1, len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", 32 + button,
32 + y + 1); 32 + x + 1, 32 + y + 1);
} else { } else {
return; return;
} }
@ -400,8 +400,8 @@ uint buttonmask(uint button) {
: 0; : 0;
} }
int mouseaction(XEvent *e, uint release) { int mouseaction(XEvent* e, uint release) {
MouseShortcut *ms; MouseShortcut* ms;
/* ignore Button<N>mask for Button<N> - it's set on release */ /* ignore Button<N>mask for Button<N> - it's set on release */
uint state = e->xbutton.state & ~buttonmask(e->xbutton.button); uint state = e->xbutton.state & ~buttonmask(e->xbutton.button);
@ -418,7 +418,7 @@ int mouseaction(XEvent *e, uint release) {
return 0; return 0;
} }
void bpress(XEvent *e) { void bpress(XEvent* e) {
struct timespec now; struct timespec now;
int snap; int snap;
@ -450,8 +450,8 @@ void bpress(XEvent *e) {
} }
} }
void propnotify(XEvent *e) { void propnotify(XEvent* e) {
XPropertyEvent *xpev; XPropertyEvent* xpev;
Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
xpev = &e->xproperty; xpev = &e->xproperty;
@ -461,7 +461,7 @@ void propnotify(XEvent *e) {
} }
} }
void selnotify(XEvent *e) { void selnotify(XEvent* e) {
ulong nitems, ofs, rem; ulong nitems, ofs, rem;
int format; int format;
uchar *data, *last, *repl; uchar *data, *last, *repl;
@ -479,9 +479,9 @@ void selnotify(XEvent *e) {
return; return;
do { do {
if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, BUFSIZ / 4, False, if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, BUFSIZ / 4,
AnyPropertyType, &type, &format, &nitems, &rem, False, AnyPropertyType, &type, &format, &nitems,
&data)) { &rem, &data)) {
fprintf(stderr, "Clipboard allocation failed\n"); fprintf(stderr, "Clipboard allocation failed\n");
return; return;
} }
@ -528,7 +528,7 @@ void selnotify(XEvent *e) {
if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) if (IS_SET(MODE_BRCKTPASTE) && ofs == 0)
ttywrite("\033[200~", 6, 0); ttywrite("\033[200~", 6, 0);
ttywrite((char *)data, nitems * format / 8, 1); ttywrite((char*)data, nitems * format / 8, 1);
if (IS_SET(MODE_BRCKTPASTE) && rem == 0) if (IS_SET(MODE_BRCKTPASTE) && rem == 0)
ttywrite("\033[201~", 6, 0); ttywrite("\033[201~", 6, 0);
XFree(data); XFree(data);
@ -545,15 +545,15 @@ void selnotify(XEvent *e) {
void xclipcopy(void) { clipcopy(NULL); } void xclipcopy(void) { clipcopy(NULL); }
void selclear_(XEvent *e) { selclear(); } void selclear_(XEvent* e) { selclear(); }
void selrequest(XEvent *e) { void selrequest(XEvent* e) {
XSelectionRequestEvent *xsre; XSelectionRequestEvent* xsre;
XSelectionEvent xev; XSelectionEvent xev;
Atom xa_targets, string, clipboard; Atom xa_targets, string, clipboard;
char *seltext; char* seltext;
xsre = (XSelectionRequestEvent *)e; xsre = (XSelectionRequestEvent*)e;
xev.type = SelectionNotify; xev.type = SelectionNotify;
xev.requestor = xsre->requestor; xev.requestor = xsre->requestor;
xev.selection = xsre->selection; xev.selection = xsre->selection;
@ -569,8 +569,8 @@ void selrequest(XEvent *e) {
if (xsre->target == xa_targets) { if (xsre->target == xa_targets) {
/* respond with the supported type */ /* respond with the supported type */
string = xsel.xtarget; string = xsel.xtarget;
XChangeProperty(xsre->display, xsre->requestor, xsre->property, XA_ATOM, 32, XChangeProperty(xsre->display, xsre->requestor, xsre->property,
PropModeReplace, (uchar *)&string, 1); XA_ATOM, 32, PropModeReplace, (uchar*)&string, 1);
xev.property = xsre->property; xev.property = xsre->property;
} else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) { } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) {
/* /*
@ -583,23 +583,24 @@ void selrequest(XEvent *e) {
} else if (xsre->selection == clipboard) { } else if (xsre->selection == clipboard) {
seltext = xsel.clipboard; seltext = xsel.clipboard;
} else { } else {
fprintf(stderr, "Unhandled clipboard selection 0x%lx\n", xsre->selection); fprintf(stderr, "Unhandled clipboard selection 0x%lx\n",
xsre->selection);
return; return;
} }
if (seltext != NULL) { if (seltext != NULL) {
XChangeProperty(xsre->display, xsre->requestor, xsre->property, XChangeProperty(xsre->display, xsre->requestor, xsre->property,
xsre->target, 8, PropModeReplace, (uchar *)seltext, xsre->target, 8, PropModeReplace, (uchar*)seltext,
strlen(seltext)); strlen(seltext));
xev.property = xsre->property; xev.property = xsre->property;
} }
} }
/* all done, send a notification to the listener */ /* all done, send a notification to the listener */
if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *)&xev)) if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent*)&xev))
fprintf(stderr, "Error sending SelectionNotify event\n"); fprintf(stderr, "Error sending SelectionNotify event\n");
} }
void setsel(char *str, Time t) { void setsel(char* str, Time t) {
if (!str) if (!str)
return; return;
@ -611,9 +612,9 @@ void setsel(char *str, Time t) {
selclear(); selclear();
} }
void xsetsel(char *str) { setsel(str, CurrentTime); } void xsetsel(char* str) { setsel(str, CurrentTime); }
void brelease(XEvent *e) { void brelease(XEvent* e) {
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
mousereport(e); mousereport(e);
return; return;
@ -625,7 +626,7 @@ void brelease(XEvent *e) {
mousesel(e, 1); mousesel(e, 1);
} }
void bmotion(XEvent *e) { void bmotion(XEvent* e) {
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
mousereport(e); mousereport(e);
return; return;
@ -657,8 +658,8 @@ void xresize(int col, int row) {
win.th = row * win.ch; win.th = row * win.ch;
XFreePixmap(xw.dpy, xw.buf); XFreePixmap(xw.dpy, xw.buf);
xw.buf = xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
XCreatePixmap(xw.dpy, xw.win, win.w, win.h, DefaultDepth(xw.dpy, xw.scr)); DefaultDepth(xw.dpy, xw.scr));
XftDrawChange(xw.draw, xw.buf); XftDrawChange(xw.draw, xw.buf);
xclear(0, 0, win.w, win.h); xclear(0, 0, win.w, win.h);
@ -668,7 +669,7 @@ void xresize(int col, int row) {
ushort sixd_to_16bit(int x) { return x == 0 ? 0 : 0x3737 + 0x2828 * x; } ushort sixd_to_16bit(int x) { return x == 0 ? 0 : 0x3737 + 0x2828 * x; }
int xloadcolor(int i, const char *name, Color *ncolor) { int xloadcolor(int i, const char* name, Color* ncolor) {
XRenderColor color = {.alpha = 0xffff}; XRenderColor color = {.alpha = 0xffff};
if (!name) { if (!name) {
@ -692,7 +693,7 @@ int xloadcolor(int i, const char *name, Color *ncolor) {
void xloadcols(void) { void xloadcols(void) {
int i; int i;
static int loaded; static int loaded;
Color *cp; Color* cp;
if (loaded) { if (loaded) {
for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
@ -712,7 +713,7 @@ void xloadcols(void) {
loaded = 1; loaded = 1;
} }
int xsetcolorname(int x, const char *name) { int xsetcolorname(int x, const char* name) {
Color ncolor; Color ncolor;
if (!BETWEEN(x, 0, dc.collen)) if (!BETWEEN(x, 0, dc.collen))
@ -739,7 +740,7 @@ void xhints(void) {
XClassHint class = {opt_name ? opt_name : termname, XClassHint class = {opt_name ? opt_name : termname,
opt_class ? opt_class : termname}; opt_class ? opt_class : termname};
XWMHints wm = {.flags = InputHint, .input = 1}; XWMHints wm = {.flags = InputHint, .input = 1};
XSizeHints *sizeh; XSizeHints* sizeh;
sizeh = XAllocSizeHints(); sizeh = XAllocSizeHints();
@ -781,9 +782,9 @@ int xgeommasktogravity(int mask) {
return SouthEastGravity; return SouthEastGravity;
} }
int xloadfont(Font *f, FcPattern *pattern) { int xloadfont(Font* f, FcPattern* pattern) {
FcPattern *configured; FcPattern* configured;
FcPattern *match; FcPattern* match;
FcResult result; FcResult result;
XGlyphInfo extents; XGlyphInfo extents;
int wantattr, haveattr; int wantattr, haveattr;
@ -836,7 +837,7 @@ int xloadfont(Font *f, FcPattern *pattern) {
} }
} }
XftTextExtentsUtf8(xw.dpy, f->match, (const FcChar8 *)ascii_printable, XftTextExtentsUtf8(xw.dpy, f->match, (const FcChar8*)ascii_printable,
strlen(ascii_printable), &extents); strlen(ascii_printable), &extents);
f->set = NULL; f->set = NULL;
@ -853,14 +854,14 @@ int xloadfont(Font *f, FcPattern *pattern) {
return 0; return 0;
} }
void xloadfonts(char *fontstr, double fontsize) { void xloadfonts(char* fontstr, double fontsize) {
FcPattern *pattern; FcPattern* pattern;
double fontval; double fontval;
if (fontstr[0] == '-') if (fontstr[0] == '-')
pattern = XftXlfdParse(fontstr, False, False); pattern = XftXlfdParse(fontstr, False, False);
else else
pattern = FcNameParse((FcChar8 *)fontstr); pattern = FcNameParse((FcChar8*)fontstr);
if (!pattern) if (!pattern)
die("can't open font %s\n", fontstr); die("can't open font %s\n", fontstr);
@ -920,7 +921,7 @@ void xloadfonts(char *fontstr, double fontsize) {
FcPatternDestroy(pattern); FcPatternDestroy(pattern);
} }
void xunloadfont(Font *f) { void xunloadfont(Font* f) {
XftFontClose(xw.dpy, f->match); XftFontClose(xw.dpy, f->match);
FcPatternDestroy(f->pattern); FcPatternDestroy(f->pattern);
if (f->set) if (f->set)
@ -938,7 +939,7 @@ void xunloadfonts(void) {
xunloadfont(&dc.ibfont); xunloadfont(&dc.ibfont);
} }
int ximopen(Display *dpy) { int ximopen(Display* dpy) {
XIMCallback imdestroy = {.client_data = NULL, .callback = ximdestroy}; XIMCallback imdestroy = {.client_data = NULL, .callback = ximdestroy};
XICCallback icdestroy = {.client_data = NULL, .callback = xicdestroy}; XICCallback icdestroy = {.client_data = NULL, .callback = xicdestroy};
@ -950,12 +951,13 @@ int ximopen(Display *dpy) {
fprintf(stderr, "XSetIMValues: " fprintf(stderr, "XSetIMValues: "
"Could not set XNDestroyCallback.\n"); "Could not set XNDestroyCallback.\n");
xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot, NULL); xw.ime.spotlist =
XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot, NULL);
if (xw.ime.xic == NULL) { if (xw.ime.xic == NULL) {
xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle, xw.ime.xic = XCreateIC(
XIMPreeditNothing | XIMStatusNothing, XNClientWindow, xw.ime.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
xw.win, XNDestroyCallback, &icdestroy, NULL); XNClientWindow, xw.win, XNDestroyCallback, &icdestroy, NULL);
} }
if (xw.ime.xic == NULL) if (xw.ime.xic == NULL)
fprintf(stderr, "XCreateIC: Could not create input context.\n"); fprintf(stderr, "XCreateIC: Could not create input context.\n");
@ -963,10 +965,10 @@ int ximopen(Display *dpy) {
return 1; return 1;
} }
void ximinstantiate(Display *dpy, XPointer client, XPointer call) { void ximinstantiate(Display* dpy, XPointer client, XPointer call) {
if (ximopen(dpy)) if (ximopen(dpy))
XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, ximinstantiate, XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
NULL); ximinstantiate, NULL);
} }
void ximdestroy(XIM xim, XPointer client, XPointer call) { void ximdestroy(XIM xim, XPointer client, XPointer call) {
@ -1033,8 +1035,8 @@ void xinit(int cols, int rows) {
memset(&gcvalues, 0, sizeof(gcvalues)); memset(&gcvalues, 0, sizeof(gcvalues));
gcvalues.graphics_exposures = False; gcvalues.graphics_exposures = False;
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, &gcvalues); dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, &gcvalues);
xw.buf = xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
XCreatePixmap(xw.dpy, xw.win, win.w, win.h, DefaultDepth(xw.dpy, xw.scr)); DefaultDepth(xw.dpy, xw.scr));
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
@ -1046,8 +1048,8 @@ void xinit(int cols, int rows) {
/* input methods */ /* input methods */
if (!ximopen(xw.dpy)) { if (!ximopen(xw.dpy)) {
XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, ximinstantiate, XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
NULL); ximinstantiate, NULL);
} }
/* white cursor, black outline */ /* white cursor, black outline */
@ -1075,8 +1077,8 @@ void xinit(int cols, int rows) {
XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, PropModeReplace, XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32,
(uchar *)&thispid, 1); PropModeReplace, (uchar*)&thispid, 1);
win.mode = MODE_NUMLOCK; win.mode = MODE_NUMLOCK;
resettitle(); resettitle();
@ -1093,19 +1095,19 @@ void xinit(int cols, int rows) {
xsel.xtarget = XA_STRING; xsel.xtarget = XA_STRING;
} }
int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int xmakeglyphfontspecs(XftGlyphFontSpec* specs, const Glyph* glyphs, int len,
int x, int y) { int x, int y) {
float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
ushort mode, prevmode = USHRT_MAX; ushort mode, prevmode = USHRT_MAX;
Font *font = &dc.font; Font* font = &dc.font;
int frcflags = FRC_NORMAL; int frcflags = FRC_NORMAL;
float runewidth = win.cw; float runewidth = win.cw;
Rune rune; Rune rune;
FT_UInt glyphidx; FT_UInt glyphidx;
FcResult fcres; FcResult fcres;
FcPattern *fcpattern, *fontpattern; FcPattern *fcpattern, *fontpattern;
FcFontSet *fcsets[] = {NULL}; FcFontSet* fcsets[] = {NULL};
FcCharSet *fccharset; FcCharSet* fccharset;
int i, f, numspecs = 0; int i, f, numspecs = 0;
for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
@ -1155,7 +1157,8 @@ int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len,
if (glyphidx && frc[f].flags == frcflags) if (glyphidx && frc[f].flags == frcflags)
break; break;
/* We got a default font for a not found glyph. */ /* We got a default font for a not found glyph. */
if (!glyphidx && frc[f].flags == frcflags && frc[f].unicodep == rune) { if (!glyphidx && frc[f].flags == frcflags &&
frc[f].unicodep == rune) {
break; break;
} }
} }
@ -1218,12 +1221,12 @@ int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len,
return numspecs; return numspecs;
} }
void xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, void xdrawglyphfontspecs(const XftGlyphFontSpec* specs, Glyph base, int len,
int x, int y) { int x, int y) {
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
width = charlen * win.cw; width = charlen * win.cw;
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; Color * fg, *bg, *temp, revfg, revbg, truefg, truebg;
XRenderColor colfg, colbg; XRenderColor colfg, colbg;
XRectangle r; XRectangle r;
@ -1310,10 +1313,12 @@ void xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len,
/* Intelligent cleaning up of the borders. */ /* Intelligent cleaning up of the borders. */
if (x == 0) { if (x == 0) {
xclear(0, (y == 0) ? 0 : winy, borderpx, xclear(0, (y == 0) ? 0 : winy, borderpx,
winy + win.ch + ((winy + win.ch >= borderpx + win.th) ? win.h : 0)); winy + win.ch +
((winy + win.ch >= borderpx + win.th) ? win.h : 0));
} }
if (winx + width >= borderpx + win.tw) { if (winx + width >= borderpx + win.tw) {
xclear(winx + width, (y == 0) ? 0 : winy, win.w, xclear(
winx + width, (y == 0) ? 0 : winy, win.w,
((winy + win.ch >= borderpx + win.th) ? win.h : (winy + win.ch))); ((winy + win.ch >= borderpx + win.th) ? win.h : (winy + win.ch)));
} }
if (y == 0) if (y == 0)
@ -1340,7 +1345,8 @@ void xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len,
} }
if (base.mode & ATTR_STRUCK) { if (base.mode & ATTR_STRUCK) {
XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3, width, 1); XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3, width,
1);
} }
/* Reset clip to none. */ /* Reset clip to none. */
@ -1369,7 +1375,8 @@ void xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) {
/* /*
* Select the right color for the right mode. * Select the right color for the right mode.
*/ */
g.mode &= ATTR_BOLD | ATTR_ITALIC | ATTR_UNDERLINE | ATTR_STRUCK | ATTR_WIDE; g.mode &=
ATTR_BOLD | ATTR_ITALIC | ATTR_UNDERLINE | ATTR_STRUCK | ATTR_WIDE;
if (IS_SET(MODE_REVERSE)) { if (IS_SET(MODE_REVERSE)) {
g.mode |= ATTR_REVERSE; g.mode |= ATTR_REVERSE;
@ -1434,7 +1441,7 @@ void xsetenv(void) {
setenv("WINDOWID", buf, 1); setenv("WINDOWID", buf, 1);
} }
void xseticontitle(char *p) { void xseticontitle(char* p) {
XTextProperty prop; XTextProperty prop;
DEFAULT(p, opt_title); DEFAULT(p, opt_title);
@ -1444,7 +1451,7 @@ void xseticontitle(char *p) {
XFree(prop.value); XFree(prop.value);
} }
void xsettitle(char *p) { void xsettitle(char* p) {
XTextProperty prop; XTextProperty prop;
DEFAULT(p, opt_title); DEFAULT(p, opt_title);
@ -1459,7 +1466,7 @@ int xstartdraw(void) { return IS_SET(MODE_VISIBLE); }
void xdrawline(Line line, int x1, int y1, int x2) { void xdrawline(Line line, int x1, int y1, int x2) {
int i, x, ox, numspecs; int i, x, ox, numspecs;
Glyph base, new; Glyph base, new;
XftGlyphFontSpec *specs = xw.specbuf; XftGlyphFontSpec* specs = xw.specbuf;
numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1); numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
i = ox = 0; i = ox = 0;
@ -1501,15 +1508,15 @@ void xximspot(int x, int y) {
XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL); XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL);
} }
void expose(XEvent *ev) { redraw(); } void expose(XEvent* ev) { redraw(); }
void visibility(XEvent *ev) { void visibility(XEvent* ev) {
XVisibilityEvent *e = &ev->xvisibility; XVisibilityEvent* e = &ev->xvisibility;
MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE); MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE);
} }
void unmap(XEvent *ev) { win.mode &= ~MODE_VISIBLE; } void unmap(XEvent* ev) { win.mode &= ~MODE_VISIBLE; }
void xsetpointermotion(int set) { void xsetpointermotion(int set) {
MODBIT(xw.attrs.event_mask, set, PointerMotionMask); MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
@ -1531,7 +1538,7 @@ int xsetcursor(int cursor) {
} }
void xseturgency(int add) { void xseturgency(int add) {
XWMHints *h = XGetWMHints(xw.dpy, xw.win); XWMHints* h = XGetWMHints(xw.dpy, xw.win);
MODBIT(h->flags, add, XUrgencyHint); MODBIT(h->flags, add, XUrgencyHint);
XSetWMHints(xw.dpy, xw.win, h); XSetWMHints(xw.dpy, xw.win, h);
@ -1545,8 +1552,8 @@ void xbell(void) {
XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL);
} }
void focus(XEvent *ev) { void focus(XEvent* ev) {
XFocusChangeEvent *e = &ev->xfocus; XFocusChangeEvent* e = &ev->xfocus;
if (e->mode == NotifyGrab) if (e->mode == NotifyGrab)
return; return;
@ -1571,8 +1578,8 @@ int match(uint mask, uint state) {
return mask == XK_ANY_MOD || mask == (state & ~ignoremod); return mask == XK_ANY_MOD || mask == (state & ~ignoremod);
} }
char *kmap(KeySym k, uint state) { char* kmap(KeySym k, uint state) {
Key *kp; Key* kp;
int i; int i;
/* Check for mapped keys out of X11 function keys. */ /* Check for mapped keys out of X11 function keys. */
@ -1606,14 +1613,14 @@ char *kmap(KeySym k, uint state) {
return NULL; return NULL;
} }
void kpress(XEvent *ev) { void kpress(XEvent* ev) {
XKeyEvent *e = &ev->xkey; XKeyEvent* e = &ev->xkey;
KeySym ksym; KeySym ksym;
char buf[64], *customkey; char buf[64], *customkey;
int len; int len;
Rune c; Rune c;
Status status; Status status;
Shortcut *bp; Shortcut* bp;
if (IS_SET(MODE_KBDLOCK)) if (IS_SET(MODE_KBDLOCK))
return; return;
@ -1654,7 +1661,7 @@ void kpress(XEvent *ev) {
ttywrite(buf, len, 1); ttywrite(buf, len, 1);
} }
void cmessage(XEvent *e) { void cmessage(XEvent* e) {
/* /*
* See xembed specs * See xembed specs
* http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
@ -1672,7 +1679,7 @@ void cmessage(XEvent *e) {
} }
} }
void resize(XEvent *e) { void resize(XEvent* e) {
if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
return; return;
@ -1754,7 +1761,8 @@ void run(void) {
trigger = now; trigger = now;
drawing = 1; drawing = 1;
} }
timeout = (maxlatency - TIMEDIFF(now, trigger)) / maxlatency * minlatency; timeout = (maxlatency - TIMEDIFF(now, trigger)) / maxlatency *
minlatency;
if (timeout > 0) if (timeout > 0)
continue; /* we have time, try to find idle */ continue; /* we have time, try to find idle */
} }
@ -1791,7 +1799,7 @@ void usage(void) {
argv0, argv0); argv0, argv0);
} }
int main(int argc, char *argv[]) { int main(int argc, char* argv[]) {
xw.l = xw.t = 0; xw.l = xw.t = 0;
xw.isfixed = False; xw.isfixed = False;
xsetcursor(cursorshape); xsetcursor(cursorshape);