# 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