# some primitives for moving the cursor without making assumptions about # raster order fn move-cursor-left screen: (addr screen) { var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-x, 0 { break-if-> return } cursor-x <- decrement set-cursor-position screen, cursor-x, cursor-y } fn move-cursor-right screen: (addr screen) { var _width/eax: int <- copy 0 var dummy/ecx: int <- copy 0 _width, dummy <- screen-size screen var limit/edx: int <- copy _width limit <- decrement var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-x, limit { break-if-< return } cursor-x <- increment set-cursor-position screen, cursor-x, cursor-y } fn move-cursor-up screen: (addr screen) { var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-y, 0 { break-if-> return } cursor-y <- decrement set-cursor-position screen, cursor-x, cursor-y } fn move-cursor-down screen: (addr screen) { var dummy/eax: int <- copy 0 var _height/ecx: int <- copy 0 dummy, _height <- screen-size screen var limit/edx: int <- copy _height limit <- decrement var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-y, limit { break-if-< return } cursor-y <- increment set-cursor-position screen, cursor-x, cursor-y } fn move-cursor-to-left-margin-of-next-line screen: (addr screen) { var dummy/eax: int <- copy 0 var _height/ecx: int <- copy 0 dummy, _height <- screen-size screen var limit/edx: int <- copy _height limit <- decrement var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-y, limit { break-if-< return } cursor-y <- increment cursor-x <- copy 0 set-cursor-position screen, cursor-x, cursor-y } fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int, background-color: int { var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen draw-grapheme screen, g, cursor-x, cursor-y, color, background-color } # we can't really render non-ASCII yet, but when we do we'll be ready fn draw-code-point-at-cursor screen: (addr screen), c: code-point, color: int, background-color: int { var g/eax: grapheme <- copy c draw-grapheme-at-cursor screen, g, color, background-color } # draw a single line of text from x, y to xmax # return the next 'x' coordinate # if there isn't enough space, truncate fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int { var stream-storage: (stream byte 0x100) var stream/esi: (addr stream byte) <- address stream-storage write stream, text var xcurr/eax: int <- draw-stream-rightward screen, stream, x, xmax, y, color, background-color return xcurr } # draw a single-line stream from x, y to xmax # return the next 'x' coordinate # if there isn't enough space, truncate fn draw-stream-rightward screen: (addr screen), stream: (addr stream byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int { var xcurr/ecx: int <- copy x { var g/eax: grapheme <- read-grapheme stream compare g, 0xffffffff/end-of-file break-if-= draw-grapheme screen, g, xcurr, y, color, background-color xcurr <- increment loop } set-cursor-position screen, xcurr, y return xcurr } fn draw-text-rightward-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int { var width/eax: int <- copy 0 var height/ecx: int <- copy 0 width, height <- screen-size screen var result/eax: int <- draw-text-rightward screen, text, x, width, y, color, background-color return result } fn draw-text-rightward-from-cursor screen: (addr screen), text: (addr array byte), xmax: int, color: int, background-color: int { var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen cursor-x <- draw-text-rightward screen, text, cursor-x, xmax, cursor-y, color, background-color set-cursor-position screen, cursor-x, cursor-y } fn render-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { compare g, 0xa/newline var x/eax: int <- copy x { break-if-!= # minimum effort to clear cursor draw-code-point screen, 0x20/space, x, y, color, background-color x <- copy xmin increment y return x, y } draw-grapheme screen, g, x, y, color, background-color x <- increment compare x, xmax { break-if-< x <- copy xmin increment y } return x, y } # draw text in the rectangle from (xmin, ymin) to (xmax, ymax), starting from (x, y), wrapping as necessary # return the next (x, y) coordinate in raster order where drawing stopped # that way the caller can draw more if given the same min and max bounding-box. # if there isn't enough space, truncate fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { var stream-storage: (stream byte 0x100) var stream/esi: (addr stream byte) <- address stream-storage write stream, text var x/eax: int <- copy _x var y/ecx: int <- copy _y x, y <- draw-stream-wrapping-right-then-down screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color return x, y } # draw a stream in the rectangle from (xmin, ymin) to (xmax, ymax), starting from (x, y), wrapping as necessary # return the next (x, y) coordinate in raster order where drawing stopped # that way the caller can draw more if given the same min and max bounding-box. # if there isn't enough space, truncate fn draw-stream-wrapping-right-then-down screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { var xcurr/eax: int <- copy x var ycurr/ecx: int <- copy y var g/ebx: grapheme <- copy 0 { { var _g/eax: grapheme <- read-grapheme stream g <- copy _g } compare g, 0xffffffff/end-of-file break-if-= xcurr, ycurr <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color loop } set-cursor-position screen, xcurr, ycurr return xcurr, ycurr } fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: int { var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen c
<html>
	<head>
		<title>dwm - dynamic window manager</title>
		<meta name="author" content="Anselm R. Garbe">
		<meta name="generator" content="ed">
		<meta name="copyright" content="(C)opyright 2006 by Anselm R. Garbe">
		<link rel="dwm icon" href="favicon.ico" type="image/x-icon" />
		<style type="text/css">
			body {
				color: #000000;
				font-family: sans-serif;
				margin: 20px 20px 20px 20px;
			}
		</style>
	</head>
	<body>
		<center>
			<img src="dwm.png"/><br />
			<h3>dynamic window manager</h3>
		</center>
		<h3>Description</h3>
		<p>
		dwm is a dynamic window manager for X11.
		</p>
		<h4>Background</h4>
		<p>
		As founder and main developer of wmii I came to the conclusion that
		wmii is too clunky for my needs. I don't need so many funky features
		and all this hype about remote control through a 9P service, I only
		want to manage my windows in a simple, but dynamic way. wmii never got
		finished because I listened to users, who proposed arbitrary ideas I
		considered useful. This resulted in an extreme <a
		href="http://www.jwz.org/doc/cadt.html">CADT</a> development model,
		which was a mistake. Thus the philosophy of dwm is simply <i>to fit my
		needs</i> (maybe yours as well). That's it.
		</p>
		<h4>Differences to ion, larswm, and wmii</h4>
		<p