% Copyright Barbara Liskov 1985 x_display = cluster is init, root, width, height, device, protocol, planes, cells, grab, ungrab, alloc_color, alloc_cell, alloc_cells, free_color, free_colors, store_color, store_colors, query_color, lookup_color, black, white rep = null own base: x_window own rwidth: int own rheight: int own devid: int own numproto: int own numplanes: int own numcells: int own haveblack: bool own blackp: x_pixmap own havewhite: bool own whitep: x_pixmap own colbuf: _bytevec init = proc (display: string) signals (error(string)) qw = sequence[_wordvec] if string$empty(display) then display := _environ("DISPLAY") except when not_found: end end num: int := string$indexc(':', display) if num ~= 0 then display, num := string$substr(display, 1, num - 1), int$parse(string$rest(display, num + 1)) end addrs: qw := qw$new() if string$empty(display) cor display = "unix" then addrs := qw$addh(addrs, _cvt[string, _wordvec]("\001\000/dev/X" || int$unparse(num))) end if string$empty(display) cor display ~= "unix" then if string$empty(display) then display := _host_name() end l, r: int := host_address(display) except when not_found, bad_address: signal error("bad host") end addr: _wordvec := _wordvec$create(4) _wordvec$wstore(addr, 1, 2) num := num + 5800 _wordvec$bstore(addr, 3, num / 2**8) _wordvec$bstore(addr, 4, num) _wordvec$wstore(addr, 5, r) _wordvec$wstore(addr, 7, l) addrs := qw$addh(addrs, addr) end err: string := "" for addr: _wordvec in qw$elements(addrs) do x_buf$init(addr) except when error (why: string): err := why continue end err := "" break end if ~string$empty(err) then signal error(err) end or: oreq, er: ereq := x_buf$get() er.code := x_setup x_buf$receive() base := _cvt[int, x_window](x_buf$get_lp0()) rwidth := 0 rheight := 0 numproto := x_buf$get_sp2() devid := x_buf$get_sp3() numplanes := x_buf$get_sp4() numcells := x_buf$get_sp5() // 2**16 haveblack := false havewhite := false colbuf := _bytevec$create(8) x_input$init() end init root = proc () returns (x_window) return(base) end root width = proc () returns (int) if rwidth = 0 then x, y, w, h, b, s, k: int, i: x_window := x_window$query(base) rwidth := w rheight := h end return(rwidth) end width height = proc () returns (int) if rheight = 0 then x, y, w, h, b, s, k: int, i: x_window := x_window$query(base) rwidth := w rheight := h end return(rheight) end height device = proc () returns (int) return(devid) end device protocol = proc () returns (int) return(numproto) end protocol planes = proc () returns (int) return(numplanes) end planes cells = proc () returns (int) return(numcells) end cells grab = proc () or: oreq, er: ereq := x_buf$get() er.code := x_grabserver end grab ungrab = proc () or: oreq, er: ereq := x_buf$get() er.code := x_ungrabserver end ungrab alloc_color = proc (red, green, blue: int) returns (int) signals (error(string)) or: oreq, er: ereq := x_buf$get() er.code := x_getcolor er.s0 := red or.s1 := green er.s2 := blue x_buf$receive() resignal error return(x_buf$get_sp0() // 2**16) end alloc_color alloc_cell = proc () returns (int) signals (error(string)) or: oreq, er: ereq := x_buf$get() er.code := x_getcolorcells er.s0 := 1 or.s1 := 0 x_buf$receive() resignal error b: _bytevec := _bytevec$create(2) x_buf$receive_data(b) return(_wordvec$wfetch(b2w(b), 1)) end alloc_cell alloc_cells = proc (ncolors, nplanes: int, contig: bool) returns (pixellist, int) signals (error(string)) or: oreq, er: ereq := x_buf$get() if contig then er.code := x_getcolorcells + (1 * 2**8) else er.code := x_getcolorcells end er.s0 := ncolors or.s1 := nplanes x_buf$receive() resignal error mask: int := x_buf$get_sp0() // 2**16 pixels: pixellist := pixellist$fill(1, ncolors, 0) if ncolors > 0 then b: _bytevec := _bytevec$create(ncolors * 2) x_buf$receive_data(b) for i: int in int$from_to_by(ncolors, 1, -1) do pixels[i] := _wordvec$wfetch(b2w(b), i * 2 - 1) end end return(pixels, mask) end alloc_cells free_color = proc (pixel: int) or: oreq, er: ereq := x_buf$get() er.code := x_freecolors or.mask := 0 er.s0 := 1 b: _bytevec := _bytevec$create(2) _wordvec$wstore(b2w(b), 1, pixel) x_buf$send_data(b, 1, 2) end free_color free_colors = proc (pixels: pixellist, mask: int) or: oreq, er: ereq := x_buf$get() er.code := x_freecolors or.mask := mask er.s0 := pixellist$size(pixels) b: _bytevec := _bytevec$create(pixellist$size(pixels) * 2) i: int := 1 for pixel: int in pixellist$elements(pixels) do _wordvec$wstore(b2w(b), i, pixel) i := i + 2 end x_buf$send_data(b, 1, _bytevec$size(b)) end free_colors store_color = proc (pixel, red, green, blue: int) or: oreq, er: ereq := x_buf$get() er.code := x_storecolors er.s0 := 1 _wordvec$wstore(b2w(colbuf), 1, pixel) _wordvec$wstore(b2w(colbuf), 3, red) _wordvec$wstore(b2w(colbuf), 5, green) _wordvec$wstore(b2w(colbuf), 7, blue) x_buf$send_data(colbuf, 1, 8) end store_color store_colors = proc (defs: colordeflist) or: oreq, er: ereq := x_buf$get() er.code := x_storecolors er.s0 := colordeflist$size(defs) z: int := colordeflist$size(defs) * 8 if _bytevec$size(colbuf) < z then colbuf := _bytevec$create(z) end i: int := 1 for def: colordef in colordeflist$elements(defs) do _wordvec$wstore(b2w(colbuf), i, def.pixel) _wordvec$wstore(b2w(colbuf), i + 2, def.red) _wordvec$wstore(b2w(colbuf), i + 4, def.green) _wordvec$wstore(b2w(colbuf), i + 6, def.blue) i := i + 8 end x_buf$send_data(colbuf, 1, z) end store_colors query_color = proc (pixel: int) returns (int, int, int) signals (error(string)) or: oreq, er: ereq := x_buf$get() er.code := x_querycolor er.s0 := pixel x_buf$receive() resignal error return(x_buf$get_sp0() // 2**16, x_buf$get_sp1() // 2**16, x_buf$get_sp2() // 2**16) end query_color lookup_color = proc (name: string) returns (int, int, int, int, int, int) signals (error(string)) or: oreq, er: ereq := x_buf$get() er.code := x_lookupcolor er.s0 := string$size(name) x_buf$send_data(s2b(name), 1, string$size(name)) x_buf$receive() resignal error return(x_buf$get_sp0() // 2**16, x_buf$get_sp1() // 2**16, x_buf$get_sp2() // 2**16, x_buf$get_sp3() // 2**16, x_buf$get_sp4() // 2**16, x_buf$get_sp5() // 2**16) end lookup_color black = proc () returns (x_pixmap) if ~haveblack then blackp := x_pixmap$tile(BlackPixel) haveblack := true end return(blackp) end black white = proc () returns (x_pixmap) if ~havewhite then whitep := x_pixmap$tile(WhitePixel) havewhite := true end return(whitep) end white end x_display