From: andrey mirtchovski <andrey@lanl.gov>
To: 9fans@cse.psu.edu
Subject: Re: [9fans] draw() question
Date: Sat, 17 Aug 2002 02:45:13 -0600 [thread overview]
Message-ID: <20020817023223.K47692-400000@fbsd.acl.lanl.gov> (raw)
In-Reply-To: <bbbee9131f29845d1c92436460ce9c53@plan9.bell-labs.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 699 bytes --]
it's not hard, i'm just (to quote george carlin) minimally exceptional.
XCopyArea, whose behaviour i tried to emulate, had it the other way
around and i was tricked by it :)
included is the end result following your help. getscr contains some
help routines which grab a screenshot and squeeze it into the current
window, decayscreen is another xscreensaver hack, which just mangles
the screen in interesting ways...
8c -FVw decayscreen.c getscr.c; 8l decayscreen.8 getscr.8
andrey
On Fri, 16 Aug 2002, rob pike, esq. wrote:
> Isn't it just
>
> draw(dst, Rect(x, y, x+(x2-x1), y+(y2-y1)), src, nil, Pt(x1, y1)) ?
>
> Why is this hard? Or what have I missed?
>
> -rob
>
[-- Attachment #2: Type: TEXT/PLAIN, Size: 1947 bytes --]
#include <u.h>
#include <libc.h>
#include <draw.h>
#include "getscr.h"
/*
* allocates temporary storage for and reads
* /dev/screen... modified from of lens.c
*/
uchar *
getscr(void)
{
char buf[5*12];
ulong chan;
uchar *screenbuf;
int d, screenfd;
screenfd = open("/dev/screen", OREAD);
if(screenfd < 0)
sysfatal("can't open /dev/screen: %r");
if(read(screenfd, buf, sizeof buf) != sizeof buf)
sysfatal("can't read /dev/screen: %r");
chan = strtochan(buf);
d = chantodepth(chan);
if(d < 8)
sysfatal("can't handle screen format %11.11s", buf);
bypp = d/8;
screenr.min.x = atoi(buf+1*12);
screenr.min.y = atoi(buf+2*12);
screenr.max.x = atoi(buf+3*12);
screenr.max.y = atoi(buf+4*12);
screenbuf = malloc(bypp*Dx(screenr)*Dy(screenr));
if(screenbuf == nil)
sysfatal("screen buffer malloc failed: %r");
if(readn(screenfd, screenbuf, bypp*Dx(screenr)*Dy(screenr)) != bypp*Dx(screenr)*Dy(screenr))
sysfatal("can't read screen: %r");
return screenbuf;
}
/*
* squeeze the screenshot to fit in the current
* window
*/
Image *
squeeze(uchar *buf)
{
int x, y, xx, yy, i;
float dx, dy;
Image *tmp;
uchar *out;
if(buf == nil)
return nil;
tmp = allocimage(display, screen->r, screen->chan, 0, DBlack);
if(tmp == nil)
sysfatal("can't allocate temp image");
dx = (float)Dx(screenr)/Dx(tmp->r);
dy = (float)Dy(screenr)/Dy(tmp->r);
out = (uchar *)malloc(bypp*Dx(tmp->r)*Dy(tmp->r));
if(out == nil)
sysfatal("can't allocate temp memory");
for(y=0; y<Dy(tmp->r); y++){
for(x=0; x<Dx(tmp->r); x++){
for(i=0; i<bypp; i++) {
yy = (int)(dy*y);
xx = (int)(dx*x);
out[bypp*(y*Dx(tmp->r)+x) + i] = buf[bypp*(yy*Dx(screenr)+xx)+i];
}
}
}
if(loadimage(tmp, tmp->r, out, bypp*Dx(tmp->r)*Dy(tmp->r)) != bypp*Dx(tmp->r)*Dy(tmp->r)){
sysfatal("loadimage");
}
return(tmp);
}
[-- Attachment #3: Type: TEXT/PLAIN, Size: 85 bytes --]
uchar* getscr(void);
Image* squeeze(uchar *);
Rectangle screenr;
int bypp;
[-- Attachment #4: Type: TEXT/PLAIN, Size: 8537 bytes --]
/* xscreensaver, Copyright (c) 1992, 1993, 1994, 1996, 1997
* Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation. No representations are made about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*/
/* decayscreen
*
* Based on slidescreen program from the xscreensaver application and the
* decay program for Sun framebuffers. This is the comment from the decay.c
* file:
* decay.c
* find the screen bitmap for the console and make it "decay" by
* randomly shifting random rectangles by one pixelwidth at a time.
*
* by David Wald, 1988
* rewritten by Natuerlich!
* based on a similar "utility" on the Apollo ring at Yale.
* X version by
*
* Vivek Khera <khera@cs.duke.edu>
* 5-AUG-1993
*
* Hacked by jwz, 28-Nov-97 (sped up and added new motion directions)
* R. Schultz
* Added "melt" & "stretch" modes 28-Mar-1999
*
*/
/*
* ported to Plan 9 by andrey@lanl.gov, 08/02
*/
/* plan9-related stuff */
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
/* screenshot-related stuff */
#include "getscr.h"
static uchar *scrbuf;
static Image *scrimg;
/* other defines */
#define NULL nil
#define XPoint Point
#define NRAND nrand
#define LRAND lrand
#define random rand
#define MAXRAND ((2<<31)-1)
#define MAX(a, b) (((a) > (b))?(a):(b))
#define MIN(a, b) (((a) < (b))?(a):(b))
#define RAND_MAX MAXRAND
#define ABS abs
Image *colors[256];
#define M_PI PI
#define Bool int
#define True 1
#define False 0
char *buttons[] =
{
"exit",
0
};
Menu menu =
{
buttons
};
Mouse m;
/* end of plan9-related defines */
static int sizex, sizey;
static int delay = 1000;
static int mode;
static int iterations=1;
#define SHUFFLE 0
#define UP 1
#define LEFT 2
#define RIGHT 3
#define DOWN 4
#define UPLEFT 5
#define DOWNLEFT 6
#define UPRIGHT 7
#define DOWNRIGHT 8
#define IN 9
#define OUT 10
#define MELT 11
#define STRETCH 12
#define FUZZ 13
static void
init_decay (void)
{
mode = random() % (FUZZ+1);
delay = 10;
sizex = Dx(screen->r);
sizey = Dy(screen->r);
if (mode == MELT || mode == STRETCH) {
/* make sure screen eventually turns background color */
line(screen, addpt(screen->r.min, Pt(0, 0)),
addpt(screen->r.min, Pt(sizex, 1)),
Endsquare, Endsquare, 0, display->black, ZP);
/* slow down for smoother melting*/
iterations = 1;
}
}
/*
* perform one iteration of decay
*/
static void
decay1 (void)
{
int left, top, width, height, toleft, totop;
Rectangle r; Point p, p2;
#define L 101
#define R 102
#define U 103
#define D 104
static int no_bias[] = { L,L,L,L, R,R,R,R, U,U,U,U, D,D,D,D };
static int up_bias[] = { L,L,L,L, R,R,R,R, U,U,U,U, U,U,D,D };
static int down_bias[] = { L,L,L,L, R,R,R,R, U,U,D,D, D,D,D,D };
static int left_bias[] = { L,L,L,L, L,L,R,R, U,U,U,U, D,D,D,D };
static int right_bias[] = { L,L,R,R, R,R,R,R, U,U,U,U, D,D,D,D };
static int upleft_bias[] = { L,L,L,L, L,R,R,R, U,U,U,U, U,D,D,D };
static int downleft_bias[] = { L,L,L,L, L,R,R,R, U,U,U,D, D,D,D,D };
static int upright_bias[] = { L,L,L,R, R,R,R,R, U,U,U,U, U,D,D,D };
static int downright_bias[] = { L,L,L,R, R,R,R,R, U,U,U,D, D,D,D,D };
static int *bias;
switch (mode) {
case SHUFFLE: bias = no_bias; break;
case UP: bias = up_bias; break;
case LEFT: bias = left_bias; break;
case RIGHT: bias = right_bias; break;
case DOWN: bias = down_bias; break;
case UPLEFT: bias = upleft_bias; break;
case DOWNLEFT: bias = downleft_bias; break;
case UPRIGHT: bias = upright_bias; break;
case DOWNRIGHT: bias = downright_bias; break;
case IN: bias = no_bias; break;
case OUT: bias = no_bias; break;
case MELT: bias = no_bias; break;
case STRETCH: bias = no_bias; break;
case FUZZ: bias = no_bias; break;
default: abort();
}
#define nrnd(x) (random() % (x))
if (mode == MELT || mode == STRETCH) {
left = nrnd(sizex/2);
top = nrnd(sizey);
width = nrnd( sizex/2 ) + sizex/2 - left;
height = nrnd(sizey - top);
toleft = left;
totop = top+1;
} else if (mode == FUZZ) { /* By Vince Levey <vincel@vincel.org>;
inspired by the "melt" mode of the
"scrhack" IrisGL program by Paul Haeberli
circa 1991. */
static int toggle = 0;
left = nrnd(sizex - 1);
top = nrnd(sizey - 1);
toggle = !toggle;
if (toggle)
{
totop = top;
height = 1;
toleft = nrnd(sizex - 1);
if (toleft > left)
{
width = toleft-left;
toleft = left;
left++;
}
else
{
width = left-toleft;
left = toleft;
toleft++;
}
}
else
{
toleft = left;
width = 1;
totop = nrnd(sizey - 1);
if (totop > top)
{
height = totop-top;
totop = top;
top++;
}
else
{
height = top-totop;
top = totop;
totop++;
}
}
} else {
left = nrnd(sizex - 1);
top = nrnd(sizey);
width = nrnd(sizex - left);
height = nrnd(sizey - top);
toleft = left;
totop = top;
if (mode == IN || mode == OUT) {
int x = left+(width/2);
int y = top+(height/2);
int cx = sizex/2;
int cy = sizey/2;
if (mode == IN) {
if (x > cx && y > cy) bias = upleft_bias;
else if (x < cx && y > cy) bias = upright_bias;
else if (x < cx && y < cy) bias = downright_bias;
else /* (x > cx && y < cy)*/ bias = downleft_bias;
} else {
if (x > cx && y > cy) bias = downright_bias;
else if (x < cx && y > cy) bias = downleft_bias;
else if (x < cx && y < cy) bias = upleft_bias;
else /* (x > cx && y < cy)*/ bias = upright_bias;
}
}
switch (bias[random() % (sizeof(no_bias)/sizeof(*no_bias))]) {
case L: toleft = left-1; break;
case R: toleft = left+1; break;
case U: totop = top-1; break;
case D: totop = top+1; break;
default: abort(); break;
}
}
r = screen->r;
if (mode == STRETCH) {
p = addpt(r.min, Pt(0, sizey-top-1));
p2 = addpt(r.min, Pt(0, sizey-top-2));
r = Rpt(p, addpt(Pt(sizex, top+1), p));
// XCopyArea (dpy, window, window, gc, 0, sizey-top-2, sizex, top+1,
// 0, sizey-top-1);
} else {
p = addpt(r.min, Pt(toleft, totop));
p2 = addpt(r.min, Pt(left, top));
r = Rpt(p, addpt(Pt(width, height), p));
// XCopyArea (dpy, window, window, gc, left, top, width, height,
// toleft, totop);
}
draw(screen, r, screen, nil, p2);
#undef nrnd
}
void
screenhack (void)
{
init_decay ();
while (1) {
int i;
for (i = 0; i < iterations; i++)
decay1 ();
flushimage(display, 1);
if(ecanmouse()) {
m = emouse();
if(m.buttons&4) {
if(emenuhit(3, &m, &menu) == 0)
exits(0);
}
}
if (delay) sleep (delay);
}
}
void
eresized(int new)
{
if(new && getwindow(display, Refnone) < 0) {
sysfatal("can't reattach to window: %r");
}
if(scrimg != nil)
freeimage(scrimg);
scrimg = squeeze(scrbuf);
if(scrimg == nil)
sysfatal("unable to fit screenshot to window: %r");
init_decay();
draw(screen, screen->r, scrimg, nil, scrimg->r.min);
}
void
main(int argc, char **argv)
{
USED(argc, argv);
srand(time(0));
scrbuf = getscr();
if(scrbuf == nil)
sysfatal("could not obtain screenshot: %r");
if(initdraw(nil, nil, "decayscreen") < 0)
sysfatal("initdraw failed: %r");
einit(Emouse);
eresized(0);
screenhack();
}
next prev parent reply other threads:[~2002-08-17 8:45 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-08-16 12:14 rob pike, esq.
2002-08-17 8:45 ` andrey mirtchovski [this message]
-- strict thread matches above, loose matches on Subject: below --
2002-08-16 7:59 andrey mirtchovski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020817023223.K47692-400000@fbsd.acl.lanl.gov \
--to=andrey@lanl.gov \
--cc=9fans@cse.psu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).