Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 2014ss
  • 2015ss
  • 2016ss
  • 2017ss
  • 2018ss
  • 2019ss
  • 2020ss
  • 2021ss
  • 2022ss
  • 2023ss
  • 2024ss
  • 2025ss
12 results

Target

Select target project
  • pgerwinski/bs
  • cloepke/bs
  • khaleeliyeh/bs
3 results
Select Git revision
  • 2014ss
  • 2015ss
  • 2016ss
  • 2017ss
  • 2018ss
  • 2019ss
  • 2020ss
  • 2021ss
  • 2022ss
  • 2023ss
10 results
Show changes

Commits on Source 105

5 additional commits have been omitted to prevent performance issues.
Showing
with 0 additions and 1426 deletions
\documentclass{article}
\input tmp.inputs
\pagestyle{empty}
\begin{document}
\begin{pspicture}(6,2)
\put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}}
\put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}}
\psline[arrows=<->](3,0.4)(3.2,1.125)(2.8,0.875)(3,1.6)
\end{pspicture}
\end{document}
\documentclass{article}
\input tmp.inputs
\pagestyle{empty}
\begin{document}
\begin{pspicture}(6,2)
\put(3,2){\makebox(0,0)[t]{Harte Echtzeitanforderungen}}
\put(3,0){\makebox(0,0)[b]{Ressourcen optimal nutzen}}
\psline[arrows=<->](3,0.4)(3.2,1.125)(2.8,0.875)(3,1.6)
\end{pspicture}
\end{document}
File deleted
../common/logo-hochschule-bochum-cvh-text.pdf
\ No newline at end of file
../common/logo-hochschule-bochum.pdf
\ No newline at end of file
echo "Fiese Dinge" >> /etc/passwd
/bin/ls "$@"
cassini/home/peter/bo/2021ss/bs/20210409> t="ls -lrt"
cassini/home/peter/bo/2021ss/bs/20210409> $t
insgesamt 3012
lrwxrwxrwx 1 peter peter 32 Apr 17 2016 philosophenproblem.jpg -> ../common/philosophenproblem.jpg
lrwxrwxrwx 1 peter peter 24 Apr 17 2016 pathfinder.jpg -> ../common/pathfinder.jpg
lrwxrwxrwx 1 peter peter 43 Apr 17 2016 Operating_system_placement-de.pdf -> ../common/Operating_system_placement-de.pdf
lrwxrwxrwx 1 peter peter 36 Apr 17 2016 logo-hochschule-bochum.pdf -> ../common/logo-hochschule-bochum.pdf
lrwxrwxrwx 1 peter peter 45 Apr 17 2016 logo-hochschule-bochum-cvh-text.pdf -> ../common/logo-hochschule-bochum-cvh-text.pdf
lrwxrwxrwx 1 peter peter 22 Apr 13 2018 pgslides.sty -> ../common/pgslides.sty
-rw-r--r-- 1 peter peter 49866 Feb 15 16:38 yesvnc-wc-6.html
-rw-r--r-- 1 peter peter 19082 Apr 9 11:14 unix-20210409.tex
-rw-r--r-- 1 peter peter 149551 Apr 9 11:14 unix-20210409.pdf
-rw-r--r-- 1 peter peter 41934 Apr 9 12:08 bs-20210409.tex
-rw-r--r-- 1 peter peter 196 Apr 9 12:08 tmp.inputs
-rw-r--r-- 1 peter peter 340 Apr 9 12:08 bs-20210409-fig1.tex
-rw-r--r-- 1 peter peter 340 Apr 9 12:08 bs-20210409-fig2.tex
-rw-r--r-- 1 peter peter 5374 Apr 9 12:08 bs-20210409.vrb
-rw-r--r-- 1 peter peter 722 Apr 9 12:08 bs-20210409.toc
-rw-r--r-- 1 peter peter 0 Apr 9 12:08 bs-20210409.snm
-rw-r--r-- 1 peter peter 704 Apr 9 12:08 bs-20210409.out
-rw-r--r-- 1 peter peter 4733 Apr 9 12:08 bs-20210409.nav
-rw-r--r-- 1 peter peter 7882 Apr 9 12:08 bs-20210409.aux
-rw-r--r-- 1 peter peter 2691461 Apr 9 12:08 bs-20210409.pdf
-rw-r--r-- 1 peter peter 69148 Apr 9 12:08 bs-20210409.log
-rw-r--r-- 1 peter peter 939 Apr 9 13:11 projekte.txt
cassini/home/peter/bo/2021ss/bs/20210409> echo $PATH
/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
cassini/home/peter/bo/2021ss/bs/20210409> which ls
/bin/ls
cassini/home/peter/bo/2021ss/bs/20210409> ls
bs-20210409.aux bs-20210409.toc philosophenproblem.jpg
bs-20210409-fig1.tex bs-20210409.vrb projekte.txt
bs-20210409-fig2.tex hello shell-variables-1.txt
bs-20210409.log hello.c tmp.inputs
bs-20210409.nav logo-hochschule-bochum-cvh-text.pdf unix-20210409.pdf
bs-20210409.out logo-hochschule-bochum.pdf unix-20210409.tex
bs-20210409.pdf Operating_system_placement-de.pdf yesvnc-wc-6.html
bs-20210409.snm pathfinder.jpg
bs-20210409.tex pgslides.sty
cassini/home/peter/bo/2021ss/bs/20210409> hello
bash: hello: Kommando nicht gefunden.
cassini/home/peter/bo/2021ss/bs/20210409> ./hello
Hello, world!
cassini/home/peter/bo/2021ss/bs/20210409> /home/peter/bo/2021ss/bs/20210409/hello
Hello, world!
cassini/home/peter/bo/2021ss/bs/20210409> PATH=".:$PATH"
cassini/home/peter/bo/2021ss/bs/20210409> echo $PATH
.:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/usr/bin:/home/peter/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
cassini/home/peter/bo/2021ss/bs/20210409> hello
Hello, world!
cassini/home/peter/bo/2021ss/bs/20210409>
cassini/home/peter/bo/2021ss/bs/20210409> ls
./ls: Zeile 1: /etc/passwd: Keine Berechtigung
bs-20210409.aux bs-20210409.toc pgslides.sty
bs-20210409-fig1.tex bs-20210409.vrb philosophenproblem.jpg
bs-20210409-fig2.tex hello projekte.txt
bs-20210409.log hello.c shell-variables-1.txt
bs-20210409.nav logo-hochschule-bochum-cvh-text.pdf shell-variables-2.txt
bs-20210409.out logo-hochschule-bochum.pdf tmp.inputs
bs-20210409.pdf ls unix-20210409.pdf
bs-20210409.snm Operating_system_placement-de.pdf unix-20210409.tex
bs-20210409.tex pathfinder.jpg yesvnc-wc-6.html
cassini/home/peter/bo/2021ss/bs/20210409> cat ls
echo "Fiese Dinge" >> /etc/passwd
/bin/ls "$@"
File deleted
<!doctype html public "-//W3C//DTD HTML 4.0 Strict//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<title>yesVNC Web Connector</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8">
<link rel="stylesheet" href="stylesheets/yesvnc-wc.css" type="text/css">
</head>
<body>
<main class="main">
<header class="main__header">
<h2 class="main__header-title">yesVNC Web Connector</h2>
<h3 id="room-indicator" class="main__header-subtitle">
Channel&nbsp;6
</h3>
</header>
<hr class="main__seperator" />
<div id="preview-section" class="hidden">
<div id="preview-container">
<video id="video" style="display: none;" autoplay></video>
<canvas id="canvas0" style="display:none;"></canvas>
<canvas class="preview" id="canvas1"></canvas>
</div>
<hr class="main__seperator" />
</div>
<div class="main__controls">
<button id="start">Start</button>
<button id="stop" disabled>Stop</button>
</div>
</main>
<script>
const debugging = 0;
const combine_rects_x_min_distance = 24;
const combine_rects_y_min_distance = 4;
const scroll_detection_x_min = -64;
const scroll_detection_x_max = 64;
const scroll_detection_y_min = -64;
const scroll_detection_y_max = 64;
const scroll_detection_r_max = 16;
const scroll_detection_min_width = 256;
const scroll_detection_min_height = 256;
const scroll_detection_min_stripe_width = 16;
const scroll_detection_min_stripe_height = 16;
const scroll_detection_point_divisor = 1024;
const scroll_detection_length_divisor = 8;
const scroll_detection_same_color_threshold = 0.995;
const scroll_detection_hit_threshold = 0.995;
let video = document.getElementById ("video");
const canvas0 = document.getElementById ("canvas0");
const canvas1 = document.getElementById ("canvas1");
let ctx0 = undefined;
let ctx1 = undefined;
function hideElement (el)
{
el.classList.add ('hidden');
}
function showElement (el)
{
el.classList.remove ('hidden');
}
const displayMediaOptions = { video: { cursor: "always" }, audio: false };
async function startCapture ()
{
video.srcObject = await navigator.mediaDevices.getDisplayMedia (displayMediaOptions);
showElement (document.getElementById ('preview-section'));
}
function stopCapture (evt)
{
hideElement (document.getElementById ('preview-section'));
let tracks = video.srcObject.getTracks ();
tracks.forEach (
function (track)
{
track.stop ();
});
video.srcObject = null;
}
const startButton = document.getElementById ("start");
const stopButton = document.getElementById ("stop");
startButton.addEventListener ("click",
function (evt)
{
startCapture ();
startButton.setAttribute ('disabled', '');
stopButton.removeAttribute ('disabled');
},
false);
stopButton.addEventListener ("click",
function (evt)
{
stopCapture ();
start.removeAttribute ('disabled');
stopButton.setAttribute ('disabled', '');
window.location.reload();
},
false);
let socket = undefined;
function buf2hex (buffer)
{
const b = new Uint8Array (buffer);
const hexdump = Array.prototype.map.call (b,
function (x)
{
return ("00" + x.toString (16)).slice (-2);
}).join (" ");
return hexdump + " (" + buffer.byteLength.toString ()
+ (buffer.byteLength == 1 ? " byte)" : " bytes)");
}
let wScreen = 0;
let hScreen = 0;
const rfb_padding = 0;
const rfb_encoding_raw = 0;
const rfb_encoding_copyrect = 1;
const rfb_encoding_rre = 2;
const rfb_encoding_tight = 7;
const rfb_name = "wc:6";
const rfb_name_length = rfb_name.length;
class Rect
{
constructor (x, y, w, h, encoding)
{
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.encoding = encoding;
}
send ()
{
const buffer = new ArrayBuffer (12);
const b = new Uint8Array (buffer);
b[0] = this.x >>> 8;
b[1] = this.x & 0xff;
b[2] = this.y >>> 8;
b[3] = this.y & 0xff;
b[4] = this.w >>> 8;
b[5] = this.w & 0xff;
b[6] = this.h >>> 8;
b[7] = this.h & 0xff;
b[8] = this.encoding >>> 24
b[9] = (this.encoding >>> 16) & 0xff;
b[10] = (this.encoding >>> 8) & 0xff;
b[11] = this.encoding & 0xff;
if (debugging)
console.log ("sending Rect object: " + buf2hex (buffer));
socket.send (buffer);
}
}
class RawRect extends Rect
{
constructor (x, y, w, h, data)
{
super (x, y, w, h, rfb_encoding_raw);
this.data = data;
}
send ()
{
super.send ();
if (debugging)
console.log ("sending RawRect object data (" + this.data.byteLength.toString () + " pixel bytes)");
socket.send (this.data);
}
}
class ScrollRect extends Rect
{
constructor (x, y, w, h, dx, dy)
{
super (x, y, w, h, rfb_encoding_copyrect);
this.dx = dx;
this.dy = dy;
}
send ()
{
super.send ();
const buffer = new ArrayBuffer (4);
const b = new Uint8Array (buffer);
b[0] = this.dx >>> 8;
b[1] = this.dx & 0xff;
b[2] = this.dy >>> 8;
b[3] = this.dy & 0xff;
if (debugging)
console.log ("sending ScrollRect object: " + buf2hex (buffer));
socket.send (buffer);
}
}
class SolidRect extends Rect
{
constructor (x, y, w, h, color)
{
super (x, y, w, h, rfb_encoding_rre);
this.color = color;
}
send ()
{
super.send ();
const buffer = new ArrayBuffer (8);
const b = new Uint8Array (buffer);
b[0] = 0; // number of sub-rectangles
b[1] = 0;
b[2] = 0;
b[3] = 0;
b[4] = this.color >>> 16;
b[5] = (this.color >>> 8) & 0xff;
b[6] = this.color & 0xff;
b[7] = rfb_padding;
if (debugging)
console.log ("sending SolidRect object: " + buf2hex (buffer));
socket.send (buffer);
}
}
class TightRect extends Rect
{
constructor (x, y, w, h, data)
{
super (x, y, w, h, rfb_encoding_tight);
this.data = data;
}
send ()
{
super.send ();
const data_length = this.data.byteLength;
let data_length_length = undefined;
if (data_length <= 0x7f)
data_length_length = 1;
else if (data_length <= 0x3fff)
data_length_length = 2;
else
data_length_length = 3;
const buffer = new ArrayBuffer (1 + data_length_length);
const b = new Uint8Array (buffer);
b[0] = 0x90; // Tight-JPEG
if (data_length <= 0x7f)
b[1] = data_length & 0x7f;
else if (data_length <= 0x3fff)
{
b[1] = (data_length & 0x7f) | 0x80;
b[2] = (data_length & 0x3f80) >>> 7;
}
else
{
b[1] = (data_length & 0x7f) | 0x80;
b[2] = ((data_length & 0x3f80) >>> 7) | 0x80;
b[3] = (data_length & 0x3fc000) >>> 14;
}
if (debugging)
console.log ("sending TightRect object header: " + buf2hex (buffer));
socket.send (buffer);
if (debugging)
console.log ("sending TightRect object data (" + data_length.toString () + " pixel bytes)");
socket.send (this.data);
}
}
let rects = new Array ();
class ScrollParams
{
constructor (x, y, w, h, dx, dy)
{
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.dx = dx;
this.dy = dy;
}
}
let scrollRects = new Array ();
let rfb_bits_per_pixel = 32;
let rfb_depth = 24;
let rfb_big_endian_flag = 0;
let rfb_true_color_flag = 1;
let rfb_red_maximum = 255;
let rfb_green_maximum = 255;
let rfb_blue_maximum = 255;
let rfb_red_shift = 24;
let rfb_green_shift = 16;
let rfb_blue_shift = 8;
let isFirstFrame = 1;
let processing = 0;
const rfb_aborted = 42;
function fillRectBuffer (px, x, y, w, h, color)
{
for (let yy = 0; yy < h; yy++)
{
let o = (y + yy) * wScreen + x;
for (let xx = 0; xx < w; xx++)
px[o++] = color;
}
}
function scrollRectBuffer (px, x, y, w, h, dx, dy)
{
const ww = w - Math.abs (dx);
const hh = h - Math.abs (dy);
const do0 = dy > 0 ? -wScreen : wScreen;
let o10 = (dy > 0 ? y + h - 1 : y) * wScreen + (dx > 0 ? x + w - 1 : x);
let o00 = ((dy > 0 ? y + h - 1 : y) - dy) * wScreen + (dx > 0 ? x + w - 1 : x) - dx;
for (let i = 0; i < hh; i++)
{
o1 = o10;
o0 = o00;
if (dx > 0)
for (let j = 0; j < ww; j++)
px[o1--] = px[o0--];
else
for (let j = 0; j < ww; j++)
px[o1++] = px[o0++];
o10 += do0;
o00 += do0;
}
}
function sleep (delay)
{
return new Promise (
function (resolve)
{
setTimeout (resolve, delay)
});
}
function canvasToBlob (canvas, type, options)
{
return new Promise (
function (resolve)
{
canvas.toBlob (resolve, type, options);
});
}
function pushRectRaw (x, y, w, h)
{
const data_length = w * h * 4;
const buffer = new ArrayBuffer (data_length);
const b = new Uint8Array (buffer);
const id1 = ctx1.getImageData (x, y, w, h);
const px1 = new Uint8Array (id1.data.buffer);
let bo = 0;
let po = 0;
for (let yy = 0; yy < h; yy++)
for (let xx = 0; xx < w; xx++)
{
b[bo + 0] = px1[po + 2];
b[bo + 1] = px1[po + 1];
b[bo + 2] = px1[po + 0];
b[bo + 3] = rfb_padding;
bo += 4;
po += 4;
}
if (debugging)
console.log ("storing RawRect (" + data_length.toString () + " pixel bytes)");
rects.push (new RawRect (x, y, w, h, buffer));
}
function pushRectScroll (x, y, w, h, dx, dy)
{
if (debugging)
console.log ("storing ScrollRect");
rects.push (new ScrollRect (x, y, w, h, dx, dy));
}
function pushRectSolid (x, y, w, h, color)
{
if (debugging)
console.log ("storing SolidRect");
rects.push (new SolidRect (x, y, w, h, color));
}
async function pushRectTight (x, y, w, h)
{
if (debugging)
console.log ("pushRectTight: x = " + x.toString () + ", y = " + y.toString () + ", w = " + w.toString () + ", h = " + h.toString ());
let canvas = undefined;
if (x == 0 && y == 0 && w == wScreen && h == hScreen)
canvas = canvas1;
else
{
canvas = document.createElement ('canvas');
canvas.width = w;
canvas.height = h;
canvas.getContext ('2d').drawImage (canvas1, -x, -y);
}
// if (debugging)
// console.log ("calling canvasToBlob()");
const blob = await canvasToBlob (canvas, "image/jpeg");
// if (debugging)
// console.log ("calling blob.arrayBuffer()");
const jpeg_buffer = await blob.arrayBuffer ();
// if (debugging)
// console.log ("storing TightRect (" + jpeg_buffer.byteLength.toString () + " instead of " + (w * h * 4).toString () + " pixel bytes)");
rects.push (new TightRect (x, y, w, h, jpeg_buffer));
}
function detectScrolling (px0, px1, x, y, w, h)
{
if (debugging)
console.log ("scrolling: detection started");
const pixels = w * h;
const points = Math.floor (pixels / scroll_detection_point_divisor);
const qxBuffer = new ArrayBuffer (2 * points);
const qx = new Uint16Array (qxBuffer);
const qyBuffer = new ArrayBuffer (2 * points);
const qy = new Uint16Array (qyBuffer);
const qc1Buffer = new ArrayBuffer (4 * points);
const qc1 = new Uint32Array (qc1Buffer);
const qc0Buffer = new ArrayBuffer (4 * points);
const qc0 = new Uint32Array (qc0Buffer);
for (let i = 0; i < points; i++)
{
const p = Math.floor (Math.random () * pixels);
// I lost a whole day to find out that p / w is a floating point division,
// which causes crazy things to happen when we use yy as an array index.
// I hate JavaScript. -- PG 20201222
const yy = Math.floor (p / w);
const xx = p % w;
const o = (y + yy) * wScreen + x + xx;
qy[i] = yy;
qx[i] = xx;
qc1[i] = px1[o];
qc0[i] = px0[o];
}
const xDensityBuffer = new ArrayBuffer (2 * w);
const xDensity = new Uint16Array (xDensityBuffer);
const yDensityBuffer = new ArrayBuffer (2 * h);
const yDensity = new Uint16Array (yDensityBuffer);
for (let xx = 0; xx < w; xx++)
{
xDensity[xx] = 0;
for (let i = 0; i < points; i++)
if (qx[i] < xx && qc1[i] != qc0[i])
xDensity[xx]++;
}
const lx = Math.floor (w / scroll_detection_length_divisor);
const halflx = Math.floor (lx / 2);
const averageDensity = Math.floor (xDensity[w - 1] / scroll_detection_length_divisor);
if (debugging)
console.log ("scrolling: averageDensity =", averageDensity);
let x0 = 0;
while (x0 + lx < w)
{
while (x0 + lx < w && xDensity[x0 + lx] - xDensity[x0] < averageDensity)
x0++;
let x1 = x0;
while (x1 + lx < w && xDensity[x1 + lx] - xDensity[x1] >= averageDensity)
x1++;
if (x1 - x0 >= scroll_detection_min_stripe_width)
{
if (debugging)
console.log ("scrolling: vertical stripe:", x0 + halflx, x1 - x0);
for (let yy = 0; yy < h; yy++)
{
yDensity[yy] = 0;
for (let i = 0; i < points; i++)
if (qy[i] < yy && qc1[i] != qc0[i] && qx[i] >= x0 && qx[i] < x1)
yDensity[yy]++;
}
const ly = Math.floor (h / scroll_detection_length_divisor);
const halfly = Math.floor (ly / 2);
const averageDensity = Math.floor (yDensity[h - 1] / scroll_detection_length_divisor);
if (debugging)
console.log ("scrolling: averageDensity =", averageDensity);
let y0 = 0;
while (y0 + ly < h)
{
while (y0 + ly < h && yDensity[y0 + ly] - yDensity[y0] < averageDensity)
y0++;
let y1 = y0;
while (y1 + ly < h && yDensity[y1 + ly] - yDensity[y1] >= averageDensity)
y1++;
if (y1 - y0 >= scroll_detection_min_stripe_height)
{
if (debugging)
console.log ("scrolling: horizontal stripe:", y0 + halfly, y1 - y0);
let sx = x0 + halflx;
let sy = y0 + halfly;
let sw = x1 - x0;
let sh = y1 - y0;
if (debugging)
{
console.log ("scrolling: checking area:", sx, sy, sw, sh);
console.log ("scrolling: " + scrollRects.length.toString () + " rects");
}
const redundant = scrollRects.find (
function (r)
{
if (debugging)
console.log ("scrolling: checking rect", sx, sy, sw, sh, "against", r.x, r.y, r.w, r.h, r.dx, r.dy);
if (sx + sw <= r.x || sx >= r.x + r.w)
return 0;
else if (sy + sh <= r.y || sy >= r.y + r.h)
return 0;
else
{
if (debugging)
console.log ("scrolling: new rect", sx, sy, sw, sh, "is redundant with", r.x, r.y, r.w, r.h, r.dx, r.dy);
return 1;
}
});
if (!redundant)
{
const color = new Array;
for (let i = 0; i < points; i++)
if (qx[i] >= sx && qx[i] < sx + sw && qy[i] >= sy && qy[i] < sy + sh)
color.push (qc1[i]);
const points_inside = color.length;
color.sort (
function (a, b)
{
return a - b;
});
let color_abundance = 1;
let i0 = 0;
let i1 = 1;
while (i1 < points_inside)
{
if (color[i1] != color[i0])
{
const a = i1 - i0;
if (a > color_abundance)
{
color_abundance = a;
i0 = i1;
}
}
i1++
}
const a = i1 - i0;
if (a > color_abundance)
color_abundance = a;
if (debugging)
console.log ("scrolling: color_abundance = " + color_abundance.toString () + ", points_inside = " + points_inside.toString ()
+ ", threshold = " + (points_inside * scroll_detection_same_color_threshold).toString ());
if (color_abundance < points_inside * scroll_detection_same_color_threshold)
{
let min_mishits = points_inside;
let sdx = 0;
let sdy = 0;
// We intentionally include the case dx == dy == 0.
// Without this, we get false positives where unchanged content
// is scrolled by 1 pixel because the "repair" after the scrolling
// is minimal.
for (let dy = scroll_detection_y_max; dy >= scroll_detection_y_min && min_mishits > 0; dy--)
for (let dx = scroll_detection_x_max; dx >= scroll_detection_x_min && min_mishits > 0; dx--)
if ((dx == 0 || dy == 0 || dx * dx + dy * dy < scroll_detection_r_max * scroll_detection_r_max))
{
let i = 0;
let mishits = 0;
while (i < points && mishits < min_mishits)
{
if (qx[i] >= sx && qx[i] < sx + sw && qy[i] >= sy && qy[i] < sy + sh)
{
const o0 = (y + qy[i] - dy) * wScreen + x + qx[i] - dx;
if (o0 >= 0 && o0 < pixels && qc1[i] != px0[o0])
mishits++;
// if (i < 10)
// console.log ("scrolling: point:", qx[i], qy[i], "rect:", sx, sx + sw, sy, sy + sh,
// "o0, px:", o0, qc1[i], px0[o0]);
}
i++;
}
if (mishits < min_mishits)
{
min_mishits = mishits;
sdx = dx;
sdy = dy;
}
if (debugging)
console.log ("scrolling: dx = " + dx.toString () + ", dy = " + dy.toString ()
+ ", mishits = " + mishits.toString () + ", points_inside = " + points_inside.toString ());
}
if (debugging)
console.log ("scrolling: sdx = " + sdx.toString () + ", sdy = " + sdy.toString ()
+ ", min_mishits = " + min_mishits.toString () + ", points_inside = " + points_inside.toString ());
if (min_mishits < points_inside * (1 - scroll_detection_hit_threshold))
{
if (debugging)
console.log ("scrolling: expanding rect:", sx, sy, sw, sh, sdx, sdy);
let xx = sx - 1;
let scrollable = 1;
while (xx > 0 && scrollable)
{
let yy = sy;
let scrollable_points = 0;
let o1 = (y + yy) * wScreen + x + xx;
let o0 = (y + yy - sdy) * wScreen + x + xx - sdx;
while (yy < sy + sh)
{
if (px1[o1] == px0[o0])
scrollable_points++;
yy++;
o1 += wScreen;
o0 += wScreen;
}
if (scrollable_points < sh * scroll_detection_hit_threshold)
scrollable = 0;
xx--;
}
if (!scrollable)
sx = xx + 1;
else
sx = xx;
xx = sx + sw;
scrollable = 1;
while (xx < w && scrollable)
{
let yy = sy;
let scrollable_points = 0;
let o1 = (y + yy) * wScreen + x + xx;
let o0 = (y + yy - sdy) * wScreen + x + xx - sdx;
while (yy < sy + sh)
{
if (px1[o1] == px0[o0])
scrollable_points++;
yy++;
o1 += wScreen;
o0 += wScreen;
}
if (scrollable_points < sh * scroll_detection_hit_threshold)
scrollable = 0;
xx++;
}
if (!scrollable)
sw = xx - sx - 1;
else
sw = xx - sx;
let yy = sy - 1;
scrollable = 1;
while (yy > 0 && scrollable)
{
let xx = sx;
let scrollable_points = 0;
let o1 = (y + yy) * wScreen + x + xx;
let o0 = (y + yy - sdy) * wScreen + x + xx - sdx;
while (xx < sx + sw)
{
if (px1[o1] == px0[o0])
scrollable_points++;
xx++;
o1++;
o0++;
}
if (scrollable_points < sw * scroll_detection_hit_threshold)
scrollable = 0;
yy--;
}
if (!scrollable)
sy = yy + 1;
else
sy = yy;
yy = sy + sh;
scrollable = 1;
while (yy < h && scrollable)
{
let xx = sx;
let scrollable_points = 0;
let o1 = (y + yy) * wScreen + x + xx;
let o0 = (y + yy - sdy) * wScreen + x + xx - sdx;
while (xx < sx + sw)
{
if (px1[o1] == px0[o0])
scrollable_points++;
xx++;
o1++;
o0++;
}
if (scrollable_points < sw * scroll_detection_hit_threshold)
scrollable = 0;
yy++;
}
if (!scrollable)
sh = yy - sy - 1;
else
sh = yy - sy;
// if (debugging)
console.log ("scrolling: pushing rect:", sx, sy, sw, sh, sdx, sdy);
scrollRects.forEach (
function (r)
{
if (!(sx + sw <= r.x || sx >= r.x + r.w || sy + sh <= r.y || sy >= r.y + r.h))
{
if (debugging)
console.log ("scrolling: neutralizing redundant rect:", r.x, r.y, r.w, r.h, r.dx, r.dy);
r.dx = 0;
r.dy = 0;
}
});
scrollRects.push (new ScrollParams (sx, sy, sw, sh, sdx, sdy));
}
}
}
}
y0 = y1;
}
}
x0 = x1;
}
scrollRects.forEach (
function (r)
{
if (r.dx != 0 || r.dy != 0)
{
const adx = Math.abs (r.dx);
const ady = Math.abs (r.dy);
if (r.w > adx && r.h > ady)
{
// pushRectSolid (r.x, r.y, r.w, r.h, 0xff0000);
// fillRectBuffer (px0, r.x, r.y, r.w, r.h, 0xffff0000);
const xx = r.dx > 0 ? r.x + r.dx : r.x;
const yy = r.dy > 0 ? r.y + r.dy : r.y;
pushRectScroll (xx, yy, r.w - adx, r.h - ady, xx - r.dx, yy - r.dy);
scrollRectBuffer (px0, r.x, r.y, r.w, r.h, r.dx, r.dy);
}
}
});
if (debugging)
console.log ("scrolling: " + scrollRects.length.toString ()
+ " rectangle" + (scrollRects.length == 1 ? "" : "s") + " detected");
scrollRects.length = 0;
}
function determineBackgroundColor (px, x, y, w, h)
{
const pixels = w * h;
const max_points = Math.floor (pixels / 16);
const points = max_points > 256 ? 256 : max_points;
const color = new Array (points);
for (let i = 0; i < points; i++)
{
const p = Math.floor (Math.random () * pixels);
const yy = Math.floor (p / w);
const xx = p % w;
const o = yy * wScreen + x;
color[i] = px[o];
}
color.sort (
function (a, b)
{
return a - b;
});
let background_index = 0;
let background_abundance = 1;
let i0 = 0;
let i1 = 1;
while (i1 < points)
{
if (color[i1] != color[i0])
{
const a = i1 - i0;
if (a > background_abundance)
{
background_index = i0;
background_abundance = a;
i0 = i1;
}
}
i1++
}
const a = i1 - i0;
if (a > background_abundance)
background_index = i0;
return color[background_index];
}
async function updateFullRectangle (x, y, w, h)
{
if (w * h * 4 > 1024)
await pushRectTight (x, y, w, h);
else
pushRectRaw (x, y, w, h);
}
async function updateInnerStructureHorizontal (px0, px1, x, y, w, h, final)
{
// if (debugging)
// console.log ("updateInnerStructureHorizontal: x = " + x.toString () + ", y = " + y.toString ()
// + ", w = " + w.toString () + ", h = " + h.toString () + ", final = ", final.toString ());
const empty = new Array (w);
const pixel_unchanged = 0x01000000;
const same_color = 0x2000000;
let xx = 0;
while (xx < w)
{
let yy = 0;
let o = y * wScreen + x + xx;
const start_color = px1[o];
empty[xx] = (start_color & 0x00ffffff) | (pixel_unchanged | same_color);
while (yy < h && empty[xx] & (pixel_unchanged | same_color))
{
if (px1[o] != px0[o])
empty[xx] &= ~pixel_unchanged;
if (px1[o] != start_color)
empty[xx] &= ~same_color;
o += wScreen;
yy++;
}
xx++;
}
let x0 = 0;
while (x0 < w && empty[x0] & (pixel_unchanged | same_color))
x0++;
while (x0 < w)
{
while (x0 < w && !(empty[x0] & (pixel_unchanged | same_color)))
x0++;
let x1 = x0;
while (x1 < w && empty[x1] & (pixel_unchanged | same_color))
x1++;
if (x1 < w && x1 - x0 < combine_rects_x_min_distance)
for (let xx = x0; xx < x1; xx++)
empty[xx] &= ~(pixel_unchanged | same_color);
x0 = x1;
}
let nothing_empty = 1;
for (let xx = 0; xx < w; xx++)
if (empty[xx] & (pixel_unchanged | same_color))
nothing_empty = 0;
// if (debugging)
// console.log ("nothing_empty = " + nothing_empty.toString () + ", empty =", empty);
x0 = 0;
while (x0 < w)
{
let x1 = x0;
if (empty[x0] & pixel_unchanged)
{
while (x1 < w && empty[x1] & pixel_unchanged)
x1++;
}
else if (empty[x0] & same_color)
{
while (x1 < w && empty[x1] & same_color && (empty[x1] & 0x00ffffff) == (empty[x0] & 0x00ffffff))
x1++;
x1--;
while (x1 > x0 && empty[x1] & pixel_unchanged)
x1--;
x1++;
const start_color = empty[x0] | 0xff000000;
pushRectSolid (x + x0, y, x1 - x0, h, debugging ? start_color | 0x00ffff : start_color);
fillRectBuffer (px0, x + x0, y, x1 - x0, h, start_color);
}
else
{
while (x1 < w && !(empty[x1] & (pixel_unchanged | same_color)))
x1++;
if (final)
await updateFullRectangle (x + x0, y, x1 - x0, h);
else
await updateInnerStructureVertical (px0, px1, x + x0, y, x1 - x0, h, nothing_empty);
}
x0 = x1;
}
}
async function updateInnerStructureVertical (px0, px1, x, y, w, h, final)
{
// if (debugging)
// console.log ("updateInnerStructureVertical: x = " + x.toString () + ", y = " + y.toString ()
// + ", w = " + w.toString () + ", h = " + h.toString () + ", final = ", final.toString ());
const empty = new Array (h);
const pixel_unchanged = 1;
const same_color = 2;
let yy = 0;
while (yy < h)
{
let xx = 0;
let o = (y + yy) * wScreen + x;
const start_color = px1[o];
empty[yy] = (start_color & 0x00ffffff) | (pixel_unchanged | same_color);
while (xx < w && empty[yy] & (pixel_unchanged | same_color))
{
if (px1[o] != px0[o])
empty[yy] &= ~pixel_unchanged;
if (px1[o] != start_color)
empty[yy] &= ~same_color;
o++;
xx++;
}
yy++;
}
let y0 = 0;
while (y0 < h && empty[y0] & (pixel_unchanged | same_color))
y0++;
while (y0 < h)
{
while (y0 < h && !(empty[y0] & (pixel_unchanged | same_color)))
y0++;
let y1 = y0;
while (y1 < h && empty[y1] & (pixel_unchanged | same_color))
y1++;
if (y1 < h && y1 - y0 < combine_rects_y_min_distance)
for (let yy = y0; yy < y1; yy++)
empty[yy] &= ~(pixel_unchanged | same_color);
y0 = y1;
}
let nothing_empty = 1;
for (let yy = 0; yy < h; yy++)
if (empty[yy] & (pixel_unchanged | same_color))
nothing_empty = 0;
// if (debugging)
// console.log ("nothing_empty = " + nothing_empty.toString () + ", empty =", empty);
y0 = 0;
while (y0 < h)
{
let y1 = y0;
if (empty[y0] & pixel_unchanged)
{
while (y1 < h && empty[y1] & pixel_unchanged)
y1++;
}
else if (empty[y0] & same_color)
{
while (y1 < h && empty[y1] & same_color && (empty[y1] & 0x00ffffff) == (empty[y0] & 0x00ffffff))
y1++;
y1--;
while (y1 > y0 && empty[y1] & pixel_unchanged)
y1--;
y1++;
const start_color = empty[y0] | 0xff000000;
pushRectSolid (x, y + y0, w, y1 - y0, debugging ? start_color | 0xffff00 : start_color);
fillRectBuffer (px0, x, y + y0, w, y1 - y0, start_color);
}
else
{
while (y1 < h && !(empty[y1] & (pixel_unchanged | same_color)))
y1++;
if (final)
await updateFullRectangle (x, y + y0, w, y1 - y0);
else
await updateInnerStructureHorizontal (px0, px1, x, y + y0, w, y1 - y0, nothing_empty);
}
y0 = y1;
}
}
async function decomposeRect (px0, px1, x, y, w, h)
{
await updateInnerStructureVertical (px0, px1, x, y, w, h, 0);
}
async function rfbFramebufferUpdate (isIncremental, x, y, w, h)
{
if (debugging)
console.log ("rfbFramebufferUpdate: isIncremental = " + isIncremental.toString ()
+ ", x = " + x.toString () + ", y = " + h.toString ()
+ ", w = " + w.toString () + ", h = " + h.toString ());
let id1 = ctx1.getImageData (x, y, w, h);
ctx0.putImageData (id1, x, y, x, y, w, h);
const id0 = ctx0.getImageData (0, 0, wScreen, hScreen);
const px0 = new Uint32Array (id0.data.buffer);
ctx1.drawImage (video, 0, 0, wScreen, hScreen);
id1 = ctx1.getImageData (0, 0, wScreen, hScreen);
let px1 = new Uint32Array (id1.data.buffer);
if (!isIncremental)
{
const color = determineBackgroundColor (px1, x, y, w, h);
if (debugging)
console.log ("background color = " + color.toString ());
pushRectSolid (x, y, w, h, debugging ? color | 0x7f00ff : color);
fillRectBuffer (px0, x, y, w, h, color);
}
do
{
const length = px0.length;
let o = 0;
while (o < length && px0[o] == px1[o])
o++;
if (o < length)
{
// if (isIncremental && w >= scroll_detection_min_width && h >= scroll_detection_min_height)
// detectScrolling (px0, px1, x, y, w, h);
await decomposeRect (px0, px1, x, y, w, h);
}
if (rects.length == 0)
{
await sleep (100);
ctx1.drawImage (video, 0, 0, wScreen, hScreen);
id1 = ctx1.getImageData (x, y, w, h);
px1 = new Uint32Array (id1.data.buffer);
}
}
while (rects.length == 0);
}
function rfbReceivePixelFormat (buffer, offset)
{
if (debugging)
console.log ("received: SetPixelFormat");
const b = new Uint8Array (buffer);
rfb_bits_per_pixel = b[4];
rfb_depth = b[5];
rfb_big_endian_flag = b[6];
rfb_true_color_flag = b[7];
rfb_red_maximum = b[8] << 8 + b[9];
rfb_green_maximum = b[10] << 8 + b[11];
rfb_blue_maximum = b[12] << 8 + b[13];
rfb_red_shift = b[14];
rfb_green_shift = b[15];
rfb_blue_shift = b[16];
return 20;
}
function rfbReceiveEncodings (buffer, offset)
{
if (debugging)
console.log ("received: SetEncodings");
const b = new Uint8Array (buffer);
const encodings = b[offset + 2] << 8 + b[offset + 3];
return 4 + 4 * encodings;
}
function rfbAbort ()
{
if (debugging)
console.log ("Aborting RFB transmission ...");
processing += rfb_aborted;
}
async function rfbFramebufferUpdateRequest (buffer, offset)
{
if (debugging)
console.log ("received: FramebufferUpdateRequest");
if (processing)
{
// if (debugging)
if (processing >= rfb_aborted)
console.log ("aborted");
else
console.log ("already being processed");
}
else
{
processing++;
let b = new Uint8Array (buffer);
let isIncremental = b[1];
const x = b[2] * 256 + b[3];
const y = b[4] * 256 + b[5];
const w = b[6] * 256 + b[7];
const h = b[8] * 256 + b[9];
if (debugging)
{
console.log ("FramebufferUpdateRequest: Initiating processing ...");
console.log ("wScreen = ", wScreen, ", hScreen = ", hScreen + ", w = ", w, ", h = ", h);
}
rects.length = 0;
if (processing < rfb_aborted)
{
if (isFirstFrame)
{
await rfbFramebufferUpdate (0, 0, 0, wScreen, hScreen);
isFirstFrame = 0;
}
else if (isIncremental)
await rfbFramebufferUpdate (1, x, y, w, h);
else
await rfbFramebufferUpdate (0, x, y, w, h);
if (debugging)
console.log ("FramebufferUpdateRequest: Processing completed. Sending data ... ("
+ rects.length.toString ()
+ " rectangle" + (rects.length != 1 ? "s" : "") + ")");
const header_buffer = new ArrayBuffer (4);
b = new Uint8Array (header_buffer);
const num_rects = rects.length;
b[0] = 0;
b[1] = rfb_padding;
b[2] = num_rects >>> 8;
b[3] = num_rects & 0xff;
if (debugging)
console.log ("sending rfbFramebufferUpdate header: " + buf2hex (header_buffer));
socket.send (header_buffer);
rects.forEach (
function sendIt (r)
{
r.send ();
});
}
processing--;
}
return 10;
}
function rfbReceiveKeyEvent (buffer, offset)
{
if (debugging)
console.log ("received: KeyEvent");
return 8;
}
function rfbReceivePointerEvent (buffer, offset)
{
if (debugging)
console.log ("received: PointerEvent");
return 6;
}
function rfbReceiveCutText (buffer, offset)
{
if (debugging)
console.log ("received: ClientCutText");
const b = new Uint8Array (buffer);
const length = b[offset + 4] << 24 + b[offset + 5] << 16 + b[offset + 6] << 8 + b[offset + 7];
return 8 + length;
}
function rfbServer (event)
{
if (debugging)
console.log ("received: " + buf2hex (event.data));
const b = new Uint8Array (event.data);
let offset = 0;
while (offset < event.data.byteLength)
{
if (debugging)
console.log ("received RFB packet type " + b[offset].toString ());
if (b[offset] == 0)
offset += rfbReceivePixelFormat (event.data, offset);
else if (b[offset] == 2)
offset += rfbReceiveEncodings (event.data, offset);
else if (b[offset] == 3)
offset += rfbFramebufferUpdateRequest (event.data, offset);
else if (b[offset] == 4)
offset += rfbReceiveKeyEvent (event.data, offset);
else if (b[offset] == 5)
offset += rfbReceivePointerEvent (event.data, offset);
else if (b[offset] == 6)
offset += rfbReceiveCutText (event.data, offset);
else
{
if (debugging)
console.log ("unknown RFB packet");
offset = event.data.byteLength;
}
}
}
function rfbFramebufferHandshake (event)
{
if (debugging)
console.log ("received: " + buf2hex (event.data));
socket.removeEventListener ("message", rfbFramebufferHandshake);
socket.addEventListener ("message", rfbServer);
const buffer = new ArrayBuffer (24 + rfb_name_length);
const b = new Uint8Array (buffer);
b[0] = wScreen >>> 8;
b[1] = wScreen & 0xff;
b[2] = hScreen >>> 8;
b[3] = hScreen & 0xff;
b[4] = rfb_bits_per_pixel;
b[5] = rfb_depth;
b[6] = rfb_big_endian_flag;
b[7] = rfb_true_color_flag;
b[8] = rfb_red_maximum >>> 8;
b[9] = rfb_red_maximum & 0xff;
b[10] = rfb_green_maximum >>> 8;
b[11] = rfb_green_maximum & 0xff;
b[12] = rfb_blue_maximum >>> 8;
b[13] = rfb_blue_maximum & 0xff;
b[14] = rfb_red_shift;
b[15] = rfb_green_shift;
b[16] = rfb_blue_shift;
b[17] = rfb_padding;
b[18] = rfb_padding;
b[19] = rfb_padding;
b[20] = rfb_name_length >>> 24;
b[21] = rfb_name_length >>> 16;
b[22] = rfb_name_length >>> 8;
b[23] = rfb_name_length & 0xff;
for (let i = 0; i < rfb_name_length; i++)
b[24 + i] = rfb_name[i];
if (debugging)
console.log ("sending framebuffer parameters: " + buf2hex (buffer));
socket.send (buffer);
}
function rfbAuthenticate (event)
{
if (debugging)
console.log ("received: " + buf2hex (event.data));
socket.removeEventListener ("message", rfbAuthenticate);
socket.addEventListener ("message", rfbFramebufferHandshake);
if (debugging)
console.log ("sending: 00 00 00 00");
const buffer = new ArrayBuffer (4);
const b = new Uint8Array (buffer);
b[0] = 0;
b[1] = 0;
b[2] = 0;
b[3] = 0;
socket.send (buffer);
}
function rfbSecurityHandshake (event)
{
if (debugging)
console.log ("received: " + buf2hex (event.data));
socket.removeEventListener ("message", rfbSecurityHandshake);
socket.addEventListener ("message", rfbAuthenticate);
if (debugging)
console.log ("sending: 01 01");
const buffer = new ArrayBuffer (2);
const b = new Uint8Array (buffer);
b[0] = 1;
b[1] = 1;
socket.send (buffer);
}
function rfbConnect (event)
{
socket.addEventListener ("message", rfbSecurityHandshake);
if (debugging)
console.log ("sending: RFB 003.008\\n");
socket.send ("RFB 003.008\n");
}
document.addEventListener ("DOMContentLoaded",
function ()
{
video.addEventListener ("play",
function ()
{
wScreen = video.videoWidth;
hScreen = video.videoHeight;
canvas1.width = wScreen;
canvas1.height = hScreen;
ctx1 = canvas1.getContext ("2d");
canvas0.width = wScreen;
canvas0.height = hScreen;
ctx0 = canvas0.getContext ("2d");
ctx0.beginPath ();
ctx0.rect (0, 0, wScreen, hScreen);
ctx0.fillStyle = "black";
ctx0.fill ();
if (debugging)
console.log ("Opening WebSocket ...");
socket = new WebSocket ("wss://streaming.cvh-server.de/websock/wc-6/", ['binary', 'base64']);
socket.binaryType = "arraybuffer";
socket.addEventListener ("open", rfbConnect);
},
false);
video.addEventListener ("abort", rfbAbort, false);
video.addEventListener ("emptied", rfbAbort, false);
video.addEventListener ("ended", rfbAbort, false);
video.addEventListener ("error", rfbAbort, false);
video.addEventListener ("pause", rfbAbort, false);
video.addEventListener ("stalled", rfbAbort, false);
// video.addEventListener ("suspend", rfbAbort, false);
});
</script>
</body>
</html>
Punkt-Test
../20210409/bs-20210409.pdf
\ No newline at end of file
../20210409/bs-20210409.tex
\ No newline at end of file
#!/usr/bin/bc -q
2 ^ 50 / 10 / 1000 / 1000 / 1000000
quit
#pwd
cd ..
#pwd
-rwxr-xr-x 1 peter peter 16 Apr 16 14:20 cd..
cassini/home/peter/bo/2021ss/bs/20210416> chmod 750 cd..
cassini/home/peter/bo/2021ss/bs/20210416> ls -l cd..
-rwxr-x--- 1 peter peter 16 Apr 16 14:20 cd..
cassini/home/peter/bo/2021ss/bs/20210416> chmod 644 cd..
cassini/home/peter/bo/2021ss/bs/20210416> ls -l cd..
-rw-r--r-- 1 peter peter 16 Apr 16 14:20 cd..
cassini/home/peter/bo/2021ss/bs/20210416> chmod 660 cd..
cassini/home/peter/bo/2021ss/bs/20210416> ls -l cd..
-rw-rw---- 1 peter peter 16 Apr 16 14:20 cd..
cassini/home/peter/bo/2021ss/bs/20210416>
cassini/home/peter/bo/2021ss/bs/20210416> find . -name "*.txt"
./shell-scripts-4.txt
./shell-scripts-2.txt
./test-3.txt
./shell-scripts-3.txt
./symlinks-3.txt
./wildcards-1.txt
./wildcards-3.txt
./shell-scripts-5.txt
./shell-scripts-6.txt
./hardlinks-1.txt
./.test.txt
./test/hello.txt
./chmod-1.txt
./wildcards-2.txt
./hardlinks-2.txt
./shell-scripts-1.txt
./symlinks-4.txt
./mount-1.txt
./test-1.txt
./grep-3.txt
./grep-1.txt
./symlinks-1.txt
./symlinks-2.txt
./grep-2.txt
cassini/home/peter/bo/2021ss/bs/20210416> find . -name *.txt
find: paths must precede expression: `find-1.txt'
find: possible unquoted pattern after predicate `-name'?
cassini/home/peter/bo/2021ss/bs/20210416> echo find . -name *.txt
find . -name chmod-1.txt find-1.txt find-2.txt grep-1.txt grep-2.txt grep-3.txt hardlinks-1.txt hardlinks-2.txt mount-1.txt shell-scripts-1.txt shell-scripts-2.txt shell-scripts-3.txt shell-scripts-4.txt shell-scripts-5.txt shell-scripts-6.txt symlinks-1.txt symlinks-2.txt symlinks-3.txt symlinks-4.txt test-1.txt test-3.txt wildcards-1.txt wildcards-2.txt wildcards-3.txt
cassini/home/peter/bo/2021ss/bs/20210416>