Libraryless. Click here for Pure Java version (4260L/32K/87K).
1 | !752 |
2 | |
3 | p { |
4 | serveHttp(7799); |
5 | } |
6 | |
7 | static int lastImageSize; |
8 | static RGBImage lastImage; |
9 | static S lastImageID; |
10 | static BufferedImage diff; |
11 | |
12 | // TODO: better auth check |
13 | static synchronized NanoHTTPD.Response serve(S uri, NanoHTTPD.Method method, |
14 | Map<S,S> header, Map<S,S> parms, Map<S,S> files) ctex { |
15 | |
16 | if (eq(uri, "/favicon.ico")) ret serveHTML(""); // who cares |
17 | |
18 | S pw = trim(loadSecretTextFile("vnc-pw")); |
19 | if (nempty(pw)) |
20 | assertEq(pw, parms.get("pw")); |
21 | |
22 | if (eq(uri, "/mouse")) { |
23 | int x = toInt(parms.get("x")); |
24 | int y = toInt(parms.get("y")); |
25 | S type = parms.get("type"); |
26 | print("Mouse event! " + type + " " + x + " " + y); |
27 | |
28 | new Robot robot; |
29 | robot.mouseMove(x, y); |
30 | if (eq(type, "down")) |
31 | robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); |
32 | else if (eq(type, "up")) { |
33 | sleepSeconds(0.1); |
34 | robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); |
35 | } |
36 | |
37 | ret serveHTML(""); |
38 | } |
39 | |
40 | if (eq(uri, "/diff.png")) { |
41 | byte[] data = convertToPNG(diff); |
42 | ret NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Status.OK, |
43 | "image/png", new ByteArrayInputStream(data), |
44 | l(data)); |
45 | } |
46 | |
47 | if (eq(uri, "/image.png")) { |
48 | BufferedImage img = shootScreen2(); |
49 | lastImage = new RGBImage(img); |
50 | lastImageID = randomID(10); |
51 | byte[] data = convertToPNG(img); |
52 | lastImageSize = l(data); |
53 | ret NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Status.OK, |
54 | "image/png", new ByteArrayInputStream(data), |
55 | l(data)); |
56 | } |
57 | |
58 | if (eq(uri, "/diff")) { |
59 | S lastID = parms.get("lastid"); |
60 | if (eq(lastID, lastImageID)) { |
61 | // todo: serve diff |
62 | BufferedImage img = shootScreen2(); |
63 | RGBImage image = new RGBImage(img); |
64 | Rectangle r = findDiffArea(lastImage, image); |
65 | if (r.width <= 0 && r.height <= 0) |
66 | ret serveHTML("no change"); |
67 | |
68 | diff = image.clip(r).getBufferedImage(); |
69 | lastImage = image; |
70 | lastImageID = randomID(10); |
71 | ret serveHTML(r.x + " " + r.y + " " + r.width + " " + r.height + lastImageID); |
72 | } |
73 | ret serveHTML("full"); |
74 | } |
75 | |
76 | print("Serving HTML."); |
77 | S html = htitle("Mini-VNC") + |
78 | hjavascript([[ |
79 | function httpGetAsync(theUrl, callback) { |
80 | var xmlHttp = new XMLHttpRequest(); |
81 | xmlHttp.onreadystatechange = function() { |
82 | if (xmlHttp.readyState == 4 && xmlHttp.status == 200) |
83 | if (callback != null) |
84 | callback(xmlHttp.responseText); |
85 | } |
86 | xmlHttp.open("GET", theUrl, true); // true for asynchronous |
87 | xmlHttp.send(null); |
88 | } |
89 | |
90 | function FindPosition(oElement) { |
91 | if (typeof(oElement.offsetParent) != "undefined") { |
92 | for(var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent) { |
93 | posX += oElement.offsetLeft; |
94 | posY += oElement.offsetTop; |
95 | } |
96 | return [ posX, posY ]; |
97 | } else { |
98 | return [ oElement.x, oElement.y ]; |
99 | } |
100 | } |
101 | |
102 | function sendMouse(e, type) { |
103 | var PosX = 0; |
104 | var PosY = 0; |
105 | var ImgPos; |
106 | ImgPos = FindPosition(myImg); |
107 | if (!e) var e = window.event; |
108 | if (e.pageX || e.pageY) { |
109 | PosX = e.pageX; |
110 | PosY = e.pageY; |
111 | } else if (e.clientX || e.clientY) { |
112 | PosX = e.clientX + document.body.scrollLeft |
113 | + document.documentElement.scrollLeft; |
114 | PosY = e.clientY + document.body.scrollTop |
115 | + document.documentElement.scrollTop; |
116 | } |
117 | PosX = PosX - ImgPos[0]; |
118 | PosY = PosY - ImgPos[1]; |
119 | |
120 | httpGetAsync("/mouse?pw=$PW$&type=" + type + "&x=" + PosX + "&y=" + PosY, null); |
121 | |
122 | if (type == "up") |
123 | setTimeout(function() { |
124 | thescreen.src = "image.png?pw=$PW$&_=" + new Date().getTime(); |
125 | }, 1000); |
126 | |
127 | //document.getElementById("y").innerHTML = PosY; |
128 | } |
129 | ]].replace("$PW$", urlencode(pw))) |
130 | + himg("image.png?pw=" + urlencode(pw), "id", "thescreen") |
131 | + hjavascript([[ |
132 | var myImg = document.getElementById("thescreen"); |
133 | myImg.ondragstart = function() { return false; }; |
134 | //myImg.onmouseover = GetCoordinates; |
135 | myImg.onmousemove = function(e) {}; |
136 | myImg.onmousedown = function(e) { sendMouse(e, "down"); }; |
137 | myImg.onmouseup = function(e) { sendMouse(e, "up"); }; |
138 | ]]) |
139 | + (lastImageSize == 0 ? "" : "<br><br>Last image size: " + toK(lastImageSize) + "K"); |
140 | ret serveHTML(html); |
141 | } |
142 | |
143 | static Rectangle findDiffArea(RGBImage a, RGBImage b) { |
144 | int w = a.getWidth(), h = a.getHeight(); |
145 | int x1 = 0, y1 = 0, x2 = w, y2 = h; |
146 | |
147 | // left side |
148 | |
149 | out0: while (x1 < x2) { |
150 | for (int y=y1; y < y2; y++) |
151 | if (different(a, b, x1, y)) break out0; |
152 | ++x1; |
153 | } |
154 | |
155 | // top side |
156 | |
157 | out1: while (y1 < y2) { |
158 | for (int x=x1; x < x2; x++) |
159 | if (different(a, b, x, y1)) break out1; |
160 | ++y1; |
161 | } |
162 | |
163 | // right side |
164 | |
165 | out2: while (x2 > x1) { |
166 | for (int y=y1; y < y2; y++) |
167 | if (different(a, b, x2-1, y)) break out2; |
168 | --x2; |
169 | } |
170 | |
171 | // bottom side |
172 | |
173 | out3: while (y2 > y1) { |
174 | for (int x=x1; x < x2; x++) |
175 | if (different(a, b, x, y2-1)) break out3; |
176 | --y2; |
177 | } |
178 | |
179 | ret new Rectangle(x1, y1, x2-x1, y2-y1); |
180 | } |
181 | |
182 | static bool different(RGBImage a, RGBImage b, int x, int y) { |
183 | ret a.getInt(x, y) != b.getInt(x, y); |
184 | } |
download show line numbers debug dex old transpilations
Travelled to 16 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, jtubtzbbkimh, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1003997 |
Snippet name: | Mini-VNC Server!! |
Eternal ID of this version: | #1003997/1 |
Text MD5: | e2c1c96ad6003dea3385fa61e32e5635 |
Transpilation MD5: | 844e708d8d02446d65b62bfee8d23929 |
Author: | stefan |
Category: | javax / networking |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-08-02 23:09:38 |
Source code size: | 5372 bytes / 184 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 599 / 932 |
Referenced in: | [show references] |