Compare commits
	
		
			No commits in common. "d7b0b447b7e254d4af37f09acfa258956d24a7e0" and "1639235a48dbed75c2563c9a497b41c31a2a1bae" have entirely different histories.
		
	
	
		
			d7b0b447b7
			...
			1639235a48
		
	
		
							
								
								
									
										19
									
								
								README.adoc
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								README.adoc
									
									
									
									
									
								
							| @ -23,16 +23,15 @@ command aliases, SOCKS proxying, SASL EXTERNAL authentication using TLS client | |||||||
| certificates, a remote relay interface, or basic support for Lua scripting. | certificates, a remote relay interface, or basic support for Lua scripting. | ||||||
| As a unique bonus, you can launch a full text editor from within. | As a unique bonus, you can launch a full text editor from within. | ||||||
| 
 | 
 | ||||||
| xP |  | ||||||
| -- |  | ||||||
| The web frontend for 'xC', making use of its networked relay interface. |  | ||||||
| So far it's quite basic, yet usable.  Build it using `make` in its directory, |  | ||||||
| and run it from within the _public_ subdirectory. |  | ||||||
| 
 |  | ||||||
| xF | xF | ||||||
| -- | -- | ||||||
| The X11 frontend for 'xC', making use of its networked relay interface. | The X11 frontend for 'xC', making use of its networked relay interface. | ||||||
| It's currently in development, and hidden behind a CMake option. | It's currently in development, and is hidden behind a CMake option. | ||||||
|  | 
 | ||||||
|  | xP | ||||||
|  | -- | ||||||
|  | The web frontend for 'xC', making use of its networked relay interface. | ||||||
|  | It's currently rather elementary, and can be built from within its directory. | ||||||
| 
 | 
 | ||||||
| xD | xD | ||||||
| -- | -- | ||||||
| @ -73,15 +72,15 @@ Building | |||||||
| Build-only dependencies: | Build-only dependencies: | ||||||
|  CMake, pkg-config, asciidoctor or asciidoc, awk, liberty (included) + |  CMake, pkg-config, asciidoctor or asciidoc, awk, liberty (included) + | ||||||
| Common runtime dependencies: openssl + | Common runtime dependencies: openssl + | ||||||
| Additionally for 'xC': curses, libffi, readline >= 6.0 or libedit >= 2013-07-12, | Additionally for 'xC': curses, libffi, + | ||||||
|  lua >= 5.3 (optional) + |  readline >= 6.0 or libedit >= 2013-07-12, lua >= 5.3 (optional) + | ||||||
| Additionally for 'xF': x11, xft | Additionally for 'xF': x11, xft | ||||||
| 
 | 
 | ||||||
|  $ git clone --recursive https://git.janouch.name/p/xK.git |  $ git clone --recursive https://git.janouch.name/p/xK.git | ||||||
|  $ mkdir xK/build |  $ mkdir xK/build | ||||||
|  $ cd xK/build |  $ cd xK/build | ||||||
|  $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RelWithDebInfo \ |  $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RelWithDebInfo \ | ||||||
|             -DWANT_READLINE=ON -DWANT_LIBEDIT=OFF -DWITH_LUA=ON |             -DWANT_READLINE=ON -DWANT_LIBEDIT=OFF -DWANT_LUA=ON | ||||||
|  $ make |  $ make | ||||||
| 
 | 
 | ||||||
| To install the application, you can do either the usual: | To install the application, you can do either the usual: | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								xC-proto
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								xC-proto
									
									
									
									
									
								
							| @ -69,7 +69,6 @@ struct EventMessage { | |||||||
| 			ERROR, | 			ERROR, | ||||||
| 			JOIN, | 			JOIN, | ||||||
| 			PART, | 			PART, | ||||||
| 			ACTION, |  | ||||||
| 		} rendition; | 		} rendition; | ||||||
| 		// Unix timestamp in seconds. | 		// Unix timestamp in seconds. | ||||||
| 		u64 when; | 		u64 when; | ||||||
|  | |||||||
							
								
								
									
										22
									
								
								xC.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								xC.c
									
									
									
									
									
								
							| @ -1480,7 +1480,7 @@ struct formatter_item | |||||||
| { | { | ||||||
| 	enum formatter_item_type type : 16; ///< Type of this item
 | 	enum formatter_item_type type : 16; ///< Type of this item
 | ||||||
| 	int attribute                 : 16; ///< Attribute ID or a TEXT_* mask
 | 	int attribute                 : 16; ///< Attribute ID or a TEXT_* mask
 | ||||||
| 	int color;                          ///< Colour ([256 << 16] | 16)
 | 	int color;                          ///< Colour
 | ||||||
| 	char *text;                         ///< String
 | 	char *text;                         ///< String
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -1536,7 +1536,6 @@ enum buffer_line_rendition | |||||||
| 	BUFFER_LINE_ERROR,                  ///< Error message
 | 	BUFFER_LINE_ERROR,                  ///< Error message
 | ||||||
| 	BUFFER_LINE_JOIN,                   ///< Join arrow
 | 	BUFFER_LINE_JOIN,                   ///< Join arrow
 | ||||||
| 	BUFFER_LINE_PART,                   ///< Part arrow
 | 	BUFFER_LINE_PART,                   ///< Part arrow
 | ||||||
| 	BUFFER_LINE_ACTION,                 ///< Highlighted asterisk
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct buffer_line | struct buffer_line | ||||||
| @ -3115,9 +3114,6 @@ relay_prepare_buffer_line (struct app_context *ctx, struct buffer *buffer, | |||||||
| 	union relay_item_data *p = e->items = xcalloc (len * 6, sizeof *e->items); | 	union relay_item_data *p = e->items = xcalloc (len * 6, sizeof *e->items); | ||||||
| 	for (struct formatter_item *i = line->items; len--; i++) | 	for (struct formatter_item *i = line->items; len--; i++) | ||||||
| 	{ | 	{ | ||||||
| 		// XXX: See attr_printer_decode_color(), this is a footgun.
 |  | ||||||
| 		int16_t c16  = i->color; |  | ||||||
| 		int16_t c256 = i->color >> 16; |  | ||||||
| 		switch (i->type) | 		switch (i->type) | ||||||
| 		{ | 		{ | ||||||
| 		case FORMATTER_ITEM_TEXT: | 		case FORMATTER_ITEM_TEXT: | ||||||
| @ -3129,11 +3125,11 @@ relay_prepare_buffer_line (struct app_context *ctx, struct buffer *buffer, | |||||||
| 			(p++)->kind = RELAY_ITEM_RESET; | 			(p++)->kind = RELAY_ITEM_RESET; | ||||||
| 			break; | 			break; | ||||||
| 		case FORMATTER_ITEM_FG_COLOR: | 		case FORMATTER_ITEM_FG_COLOR: | ||||||
| 			p->fg_color.color = c256 <= 0 ? c16 : c256; | 			p->fg_color.color = i->color; | ||||||
| 			(p++)->kind = RELAY_ITEM_FG_COLOR; | 			(p++)->kind = RELAY_ITEM_FG_COLOR; | ||||||
| 			break; | 			break; | ||||||
| 		case FORMATTER_ITEM_BG_COLOR: | 		case FORMATTER_ITEM_BG_COLOR: | ||||||
| 			p->bg_color.color = c256 <= 0 ? c16 : c256; | 			p->bg_color.color = i->color; | ||||||
| 			(p++)->kind = RELAY_ITEM_BG_COLOR; | 			(p++)->kind = RELAY_ITEM_BG_COLOR; | ||||||
| 			break; | 			break; | ||||||
| 		case FORMATTER_ITEM_SIMPLE: | 		case FORMATTER_ITEM_SIMPLE: | ||||||
| @ -4479,7 +4475,6 @@ buffer_line_flush (struct buffer_line *line, struct formatter *f, FILE *output, | |||||||
| 	case BUFFER_LINE_ERROR:   formatter_add (f, "#a=!=#r ", ATTR_ERROR); break; | 	case BUFFER_LINE_ERROR:   formatter_add (f, "#a=!=#r ", ATTR_ERROR); break; | ||||||
| 	case BUFFER_LINE_JOIN:    formatter_add (f, "#a-->#r ", ATTR_JOIN);  break; | 	case BUFFER_LINE_JOIN:    formatter_add (f, "#a-->#r ", ATTR_JOIN);  break; | ||||||
| 	case BUFFER_LINE_PART:    formatter_add (f, "#a<--#r ", ATTR_PART);  break; | 	case BUFFER_LINE_PART:    formatter_add (f, "#a<--#r ", ATTR_PART);  break; | ||||||
| 	case BUFFER_LINE_ACTION:  formatter_add (f, " #a*#r  ", ATTR_ACTION); break; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for (struct formatter_item *iter = line->items; iter->type; iter++) | 	for (struct formatter_item *iter = line->items; iter->type; iter++) | ||||||
| @ -4696,16 +4691,16 @@ log_full (struct app_context *ctx, struct server *s, struct buffer *buffer, | |||||||
| #define log_outcoming_privmsg(s, buffer, prefixes, who, text)                  \ | #define log_outcoming_privmsg(s, buffer, prefixes, who, text)                  \ | ||||||
| 	log_server ((s), (buffer), 0, 0, "<#s#n> #m", (prefixes), (who), (text)) | 	log_server ((s), (buffer), 0, 0, "<#s#n> #m", (prefixes), (who), (text)) | ||||||
| #define log_outcoming_action(s, buffer, who, text)                             \ | #define log_outcoming_action(s, buffer, who, text)                             \ | ||||||
| 	log_server ((s), (buffer), 0, BUFFER_LINE_ACTION, "#n #m", (who), (text)) | 	log_server ((s), (buffer), 0, 0, " #a*#r  #n #m", \ | ||||||
|  | 		ATTR_ACTION, (who), (text)) | ||||||
| 
 | 
 | ||||||
| #define log_outcoming_orphan_notice(s, target, text)                           \ | #define log_outcoming_orphan_notice(s, target, text)                           \ | ||||||
| 	log_server_status ((s), (s)->buffer, "Notice -> #n: #m", (target), (text)) | 	log_server_status ((s), (s)->buffer, "Notice -> #n: #m", (target), (text)) | ||||||
| #define log_outcoming_orphan_privmsg(s, target, text)                          \ | #define log_outcoming_orphan_privmsg(s, target, text)                          \ | ||||||
| 	log_server ((s), (s)->buffer, 0, BUFFER_LINE_STATUS,                       \ | 	log_server_status ((s), (s)->buffer, "MSG(#n): #m", (target), (text)) | ||||||
| 		"MSG(#n): #m", (target), (text)) |  | ||||||
| #define log_outcoming_orphan_action(s, target, text)                           \ | #define log_outcoming_orphan_action(s, target, text)                           \ | ||||||
| 	log_server ((s), (s)->buffer, 0, BUFFER_LINE_ACTION,                       \ | 	log_server_status ((s), (s)->buffer, "MSG(#n):  #a*#r  #m", (target),      \ | ||||||
| 		"MSG(#n): #m", (target), (text)) | 		ATTR_ACTION, (text)) | ||||||
| 
 | 
 | ||||||
| #define log_ctcp_query(s, target, tag)                                         \ | #define log_ctcp_query(s, target, tag)                                         \ | ||||||
| 	log_server_status ((s), (s)->buffer, "CTCP query to #S: #S", target, tag) | 	log_server_status ((s), (s)->buffer, "CTCP query to #S: #S", target, tag) | ||||||
| @ -8768,7 +8763,6 @@ irc_process_numeric (struct server *s, | |||||||
| 		if (msg->params.len == 2) | 		if (msg->params.len == 2) | ||||||
| 			irc_try_parse_welcome_for_userhost (s, msg->params.vector[1]); | 			irc_try_parse_welcome_for_userhost (s, msg->params.vector[1]); | ||||||
| 		break; | 		break; | ||||||
| 	case IRC_RPL_MOTDSTART: |  | ||||||
| 	case IRC_RPL_MOTD: | 	case IRC_RPL_MOTD: | ||||||
| 		if (copy.len) | 		if (copy.len) | ||||||
| 			irc_adjust_motd (©.vector[0]); | 			irc_adjust_motd (©.vector[0]); | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| module janouch.name/xK/xP | module janouch.name/xK | ||||||
| 
 | 
 | ||||||
| go 1.18 | go 1.18 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -79,9 +79,6 @@ body { | |||||||
| .mark.part { | .mark.part { | ||||||
| 	color: red; | 	color: red; | ||||||
| } | } | ||||||
| .mark.action { |  | ||||||
| 	color: darkred; |  | ||||||
| } |  | ||||||
| .content { | .content { | ||||||
| 	padding: .1rem .3rem; | 	padding: .1rem .3rem; | ||||||
| 	white-space: pre-wrap; | 	white-space: pre-wrap; | ||||||
|  | |||||||
| @ -1,40 +1,3 @@ | |||||||
| // Copyright (c) 2022, Přemysl Eric Janouch <p@janouch.name>
 |  | ||||||
| // SPDX-License-Identifier: 0BSD
 |  | ||||||
| 
 |  | ||||||
| // --- Colours -----------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| let palette = [ |  | ||||||
| 	'#000', '#800', '#080', '#880', '#008', '#808', '#088', '#ccc', |  | ||||||
| 	'#888', '#f00', '#0f0', '#ff0', '#00f', '#f0f', '#0ff', '#fff', |  | ||||||
| ] |  | ||||||
| palette.length = 256 |  | ||||||
| for (let i = 0; i < 216; i++) { |  | ||||||
| 	let r = i / 36 >> 0, g = (i / 6 >> 0) % 6, b = i % 6 |  | ||||||
| 	r = !r ? '00' : (55 + 40 * r).toString(16) |  | ||||||
| 	g = !g ? '00' : (55 + 40 * g).toString(16) |  | ||||||
| 	b = !b ? '00' : (55 + 40 * b).toString(16) |  | ||||||
| 	palette[16 + i] = `#${r}${g}${b}` |  | ||||||
| } |  | ||||||
| for (let i = 0; i < 24; i++) { |  | ||||||
| 	let g = ('0' + (8 + i * 10).toString(16)).slice(-2) |  | ||||||
| 	palette[232 + i] = `#${g}${g}${g}` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function applyColor(fg, bg, inverse) { |  | ||||||
| 	if (inverse) |  | ||||||
| 		[fg, bg] = [bg >= 0 ? bg : 15, fg >= 0 ? fg : 0] |  | ||||||
| 
 |  | ||||||
| 	let style = '' |  | ||||||
| 	if (fg >= 0) |  | ||||||
| 		style += `color: ${palette[fg]};` |  | ||||||
| 	if (bg >= 0) |  | ||||||
| 		style += `background-color: ${palette[bg]};` |  | ||||||
| 	if (style) |  | ||||||
| 		return style |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ---- Event processing -------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| // TODO: Probably reset state on disconnect, and indicate to user.
 | // TODO: Probably reset state on disconnect, and indicate to user.
 | ||||||
| let socket = new WebSocket(proxy) | let socket = new WebSocket(proxy) | ||||||
| 
 | 
 | ||||||
| @ -96,8 +59,6 @@ socket.onmessage = function(event) { | |||||||
| 	m.redraw() | 	m.redraw() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ---- UI ---------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| let BufferList = { | let BufferList = { | ||||||
| 	view: vnode => { | 	view: vnode => { | ||||||
| 		let items = [] | 		let items = [] | ||||||
| @ -125,7 +86,6 @@ let Content = { | |||||||
| 		case 'Error':  content.push(m('span.mark.error', {}, '⚠')); break | 		case 'Error':  content.push(m('span.mark.error', {}, '⚠')); break | ||||||
| 		case 'Join':   content.push(m('span.mark.join',  {}, '→')); break | 		case 'Join':   content.push(m('span.mark.join',  {}, '→')); break | ||||||
| 		case 'Part':   content.push(m('span.mark.part',  {}, '←')); break | 		case 'Part':   content.push(m('span.mark.part',  {}, '←')); break | ||||||
| 		case 'Action': content.push(m('span.mark.action', {}, '✶')); break |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		let classes = new Set() | 		let classes = new Set() | ||||||
| @ -135,33 +95,22 @@ let Content = { | |||||||
| 			else | 			else | ||||||
| 				classes.add(c) | 				classes.add(c) | ||||||
| 		} | 		} | ||||||
| 		let fg = -1, bg = -1, inverse = false |  | ||||||
| 		line.items.forEach(item => { | 		line.items.forEach(item => { | ||||||
|  | 			// TODO: Colours.
 | ||||||
| 			switch (item.kind) { | 			switch (item.kind) { | ||||||
| 			case 'Text': | 			case 'Text': | ||||||
| 				// TODO: Detect and transform links.
 | 				// TODO: Detect and transform links.
 | ||||||
| 				content.push(m('span', { | 				content.push(m('span', { | ||||||
| 					class: Array.from(classes.keys()).join(' '), | 					class: Array.from(classes.keys()).join(' '), | ||||||
| 					style: applyColor(fg, bg, inverse), |  | ||||||
| 				}, item.text)) | 				}, item.text)) | ||||||
| 				break | 				break | ||||||
| 			case 'Reset': | 			case 'Reset': | ||||||
| 				classes.clear() | 				classes.clear() | ||||||
| 				fg = bg = -1 |  | ||||||
| 				inverse = false |  | ||||||
| 				break |  | ||||||
| 			case 'FgColor': |  | ||||||
| 				fg = item.color |  | ||||||
| 				break |  | ||||||
| 			case 'BgColor': |  | ||||||
| 				bg = item.color |  | ||||||
| 				break |  | ||||||
| 			case 'FlipInverse': |  | ||||||
| 				inverse = !inverse |  | ||||||
| 				break | 				break | ||||||
| 			case 'FlipBold':       flip('b'); break | 			case 'FlipBold':       flip('b'); break | ||||||
| 			case 'FlipItalic':     flip('i'); break | 			case 'FlipItalic':     flip('i'); break | ||||||
| 			case 'FlipUnderline':  flip('u'); break | 			case 'FlipUnderline':  flip('u'); break | ||||||
|  | 			case 'FlipInverse':    flip('i'); break | ||||||
| 			case 'FlipCrossedOut': flip('s'); break | 			case 'FlipCrossedOut': flip('s'); break | ||||||
| 			case 'FlipMonospace':  flip('m'); break | 			case 'FlipMonospace':  flip('m'); break | ||||||
| 			} | 			} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user