1
|
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js'
|
2
|
--- src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js 2015-07-20 21:45:43 +0000
|
3
|
+++ src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js 2015-08-07 15:56:12 +0000
|
4
|
@@ -18,8 +18,9 @@
|
5
|
** 007 GES 20150324 Moved this class to a common resource base and made it generic (so that it
|
6
|
** can be used for both ChUI and GUI web clients.
|
7
|
** 008 SBI 20150731 Applied "use strict" directive, fixed undeclared variables.
|
8
|
-** 009 GES 20170709 Added support for MSG_READ_CLIPBOARD (server-driven clipboard request) and
|
9
|
+** 009 GES 20150709 Added support for MSG_READ_CLIPBOARD (server-driven clipboard request) and
|
10
|
** MSG_WRITE_CLIPBOARD.
|
11
|
+** 010 SBI 20150807 Fixed a network order for reading int32 from binaries message
|
12
|
*/
|
13
|
|
14
|
"use strict";
|
15
|
@@ -131,7 +132,7 @@
|
16
|
|
17
|
for (var i = 0; i < 4; i++)
|
18
|
{
|
19
|
- num |= message[offset + i] << (8 * i);
|
20
|
+ num |= message[offset + i] << (8 * (3-i));
|
21
|
}
|
22
|
|
23
|
return num;
|
24
|
|
25
|
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/web/DrawImageOp.java'
|
26
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/DrawImageOp.java 1970-01-01 00:00:00 +0000
|
27
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/DrawImageOp.java 2015-08-07 15:25:53 +0000
|
28
|
@@ -0,0 +1,122 @@
|
29
|
+/*
|
30
|
+** Module : DrawImageOp.java
|
31
|
+** Abstract : Defines a draw image command.
|
32
|
+**
|
33
|
+** Copyright (c) 2015, Golden Code Development Corporation.
|
34
|
+** ALL RIGHTS RESERVED. Use is subject to license terms.
|
35
|
+**
|
36
|
+** Golden Code Development Corporation
|
37
|
+** CONFIDENTIAL
|
38
|
+**
|
39
|
+** -#- -I- --Date-- --------------------------------Description----------------------------------
|
40
|
+** 001 SBI 20150807 First version which is a draw image command.
|
41
|
+**
|
42
|
+**
|
43
|
+*/
|
44
|
+
|
45
|
+package com.goldencode.p2j.ui.client.gui.driver.web;
|
46
|
+
|
47
|
+import java.awt.Image;
|
48
|
+import java.util.HashSet;
|
49
|
+
|
50
|
+import com.goldencode.p2j.ui.client.gui.driver.PaintPrimitives;
|
51
|
+import com.goldencode.p2j.ui.client.gui.driver.PaintStructure;
|
52
|
+
|
53
|
+/**
|
54
|
+ *
|
55
|
+ * DrawImageOp performs a draw image on a virtual screen and prepares
|
56
|
+ * a draw message to transfer via networks, holds a hash map of loaded images.
|
57
|
+ *
|
58
|
+ */
|
59
|
+public class DrawImageOp
|
60
|
+{
|
61
|
+
|
62
|
+ private final VirtualScreen virtualScreen;
|
63
|
+
|
64
|
+ private final HashSet<String> loadedImages;
|
65
|
+ /**
|
66
|
+ *
|
67
|
+ * @param virtualScreen
|
68
|
+ */
|
69
|
+ public DrawImageOp(VirtualScreen virtualScreen)
|
70
|
+ {
|
71
|
+ this.virtualScreen = virtualScreen;
|
72
|
+ this.loadedImages = new HashSet<String>();
|
73
|
+ }
|
74
|
+
|
75
|
+ private static String md5HashToString(byte[] md5Hash) {
|
76
|
+ StringBuilder builder = new StringBuilder(8);
|
77
|
+ for (int i = 0; i < 16; i++) {
|
78
|
+ builder.append(Integer.toHexString(md5Hash[i]));
|
79
|
+ }
|
80
|
+ return builder.toString();
|
81
|
+ }
|
82
|
+
|
83
|
+ /**
|
84
|
+ * Write a 32-bit integer value into a binary message at a given offset.
|
85
|
+ *
|
86
|
+ * @param message
|
87
|
+ * Message content as an byte array.
|
88
|
+ * @param offset
|
89
|
+ * Offset into the message at which the integer should be written.
|
90
|
+ * @param value
|
91
|
+ * The 32-bit value to write.
|
92
|
+ */
|
93
|
+ private void writeMessageInt32(byte[] message, int offset, int value)
|
94
|
+ {
|
95
|
+ message[offset] = (byte)((value >> 24) & 0x00FF);
|
96
|
+ message[offset + 1] = (byte)((value >> 16) & 0x00FF);
|
97
|
+ message[offset + 2] = (byte)((value >> 8) & 0x00FF);
|
98
|
+ message[offset + 3] = (byte)( value & 0x00FF);
|
99
|
+ }
|
100
|
+
|
101
|
+ /**
|
102
|
+ * Perform a draw image on a virtual screen, the image parameters provided
|
103
|
+ * in PaintStructure. A binary message format is defined as
|
104
|
+ * DRAW_IMAGE, 1 byte, operation id
|
105
|
+ * x, 4 bytes, an image x-offset
|
106
|
+ * y, 4 bytes, an image y-offset
|
107
|
+ * width, 4 bytes, an image width
|
108
|
+ * height, 4 bytes, an image width
|
109
|
+ * encoding, 4 bytes, an image encoding schema, Raw or MD5 hash
|
110
|
+ * imageMd5Hash, 16 bytes, an image MD5 hash
|
111
|
+ * image binaries, 4*width*height bytes, an encoded image, it is omitted
|
112
|
+ * if an encoding is MD5 hash.
|
113
|
+ * @param ps PaintStructure parameters for an image drawing
|
114
|
+ * @return byte[] a drawing image prepared to transfer via network.
|
115
|
+ */
|
116
|
+ public byte[] execute(PaintStructure ps) {
|
117
|
+ int x = ps.xOffset;//4
|
118
|
+ int y = ps.yOffset;//4
|
119
|
+ Image image = (Image) ps.img.getImage();
|
120
|
+ int width = image.getWidth(null);//4
|
121
|
+ int height = image.getHeight(null);//4
|
122
|
+ final byte[] md5ImageHash = virtualScreen.drawImage(image, x, y);
|
123
|
+ final String md5ImageKey = md5HashToString(md5ImageHash);
|
124
|
+ ImageEncoding encoding;
|
125
|
+ if (!loadedImages.contains(md5ImageKey)) {
|
126
|
+ loadedImages.add(md5ImageKey);
|
127
|
+ encoding = ImageEncoding.Raw;
|
128
|
+ } else {
|
129
|
+ encoding = ImageEncoding.Md5Hash;
|
130
|
+ }
|
131
|
+ final byte[] encodedImage = new RawEncoder().packToBinaries(virtualScreen, x, y, width, height);
|
132
|
+ int msgLen = 37;
|
133
|
+ if (encoding == ImageEncoding.Raw) {
|
134
|
+ msgLen += encodedImage.length;
|
135
|
+ }
|
136
|
+ byte[] drawImageMsg = new byte[msgLen];
|
137
|
+ drawImageMsg[0] = (byte) (PaintPrimitives.DRAW_IMAGE.ordinal());
|
138
|
+ writeMessageInt32(drawImageMsg, 1, x);
|
139
|
+ writeMessageInt32(drawImageMsg, 5, y);
|
140
|
+ writeMessageInt32(drawImageMsg, 9, width);
|
141
|
+ writeMessageInt32(drawImageMsg, 13, height);
|
142
|
+ writeMessageInt32(drawImageMsg, 17, encoding.getValue());
|
143
|
+ System.arraycopy(md5ImageHash, 0, drawImageMsg, 21, 16);
|
144
|
+ if (encoding == ImageEncoding.Raw) {
|
145
|
+ System.arraycopy(encodedImage, 0, drawImageMsg, 37, encodedImage.length);
|
146
|
+ }
|
147
|
+
|
148
|
+ return drawImageMsg;
|
149
|
+ }
|
150
|
+}
|
151
|
|
152
|
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java'
|
153
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java 2015-07-30 23:09:31 +0000
|
154
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java 2015-08-07 15:18:59 +0000
|
155
|
@@ -13,6 +13,7 @@
|
156
|
** 002 HC 20150612 Compatibility changes related to support of paragraph layout.
|
157
|
** 003 HC 20150702 Improved positioning of top-level windows on systems with multiple displays.
|
158
|
** 004 GES 20150701 Added GUI implementation for previously stubbed-out methods.
|
159
|
+** 005 SBI 20150807 Added an images drawing operation.
|
160
|
*/
|
161
|
|
162
|
package com.goldencode.p2j.ui.client.gui.driver.web;
|
163
|
@@ -378,6 +379,7 @@
|
164
|
websock.drawRoundRect(ps.x, ps.y, ps.width, ps.height, ps.arcDiameter);
|
165
|
break;
|
166
|
case DRAW_IMAGE:
|
167
|
+ websock.drawImage(ps);
|
168
|
break;
|
169
|
case FILL_RECT:
|
170
|
websock.fillRect(ps.x, ps.y, ps.width, ps.height);
|
171
|
|
172
|
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java'
|
173
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java 2015-07-30 23:09:31 +0000
|
174
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java 2015-08-07 15:25:55 +0000
|
175
|
@@ -10,16 +10,19 @@
|
176
|
**
|
177
|
** -#- -I- --Date-- --------------------------------Description----------------------------------
|
178
|
** 001 GES 20150331 First version which is a placeholder using the common parent code as ChUI.
|
179
|
-** 002 GES 20150701 Added messages for a first pass at GUI support.
|
180
|
+** 002 GES 20150701 Added messages for a first pass at GUI support.
|
181
|
+** 003 SBI 20150807 Added an images drawing operation.
|
182
|
*/
|
183
|
|
184
|
package com.goldencode.p2j.ui.client.gui.driver.web;
|
185
|
|
186
|
+import java.awt.color.ColorSpace;
|
187
|
+import java.awt.image.DataBuffer;
|
188
|
+import java.awt.image.DirectColorModel;
|
189
|
import java.util.*;
|
190
|
|
191
|
import com.goldencode.p2j.ui.client.driver.web.*;
|
192
|
import com.goldencode.p2j.ui.client.*;
|
193
|
-import com.goldencode.p2j.ui.client.widget.*;
|
194
|
import com.goldencode.p2j.ui.client.gui.driver.*;
|
195
|
|
196
|
/**
|
197
|
@@ -49,6 +52,21 @@
|
198
|
private int pendingBytes = 0;
|
199
|
|
200
|
/**
|
201
|
+ * Defines a pixels model as sRGB 32bits per a pixel
|
202
|
+ */
|
203
|
+ private final DirectColorModel colorModel = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
204
|
+ 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000, true, DataBuffer.TYPE_INT);
|
205
|
+ /**
|
206
|
+ * TODO to get client screen width and height.
|
207
|
+ */
|
208
|
+ private final VirtualScreen virtualScreen = new VirtualScreenImpl(colorModel, 800, 600);
|
209
|
+
|
210
|
+ /**
|
211
|
+ * Image drawing manager holds a hash map of loaded images
|
212
|
+ */
|
213
|
+ private final DrawImageOp drawImageOp = new DrawImageOp(virtualScreen);
|
214
|
+
|
215
|
+ /**
|
216
|
* Create a new GUI web socket instance.
|
217
|
*
|
218
|
* @param lock
|
219
|
@@ -257,7 +275,17 @@
|
220
|
{
|
221
|
allocateAndSend(PaintPrimitives.FILL_3D_RECT, x, y, width, height, raised);
|
222
|
}
|
223
|
-
|
224
|
+
|
225
|
+ /**
|
226
|
+ * Draw a given image on the virtual screen and prepare it to transfer.
|
227
|
+ * @param imageParameters PaintStructure
|
228
|
+ */
|
229
|
+ public void drawImage(PaintStructure imageParameters) {
|
230
|
+ byte[] message = drawImageOp.execute(imageParameters);
|
231
|
+ drawingOps.add(message);
|
232
|
+ pendingBytes += message.length;
|
233
|
+ }
|
234
|
+
|
235
|
/**
|
236
|
* Draw a filled, closed polygon in the current color/stroke.
|
237
|
*
|
238
|
@@ -719,6 +747,15 @@
|
239
|
}
|
240
|
|
241
|
/**
|
242
|
+ * Add a prepared drawing to the pending operations list
|
243
|
+ * @param message byte[] prepared drawing to transfer
|
244
|
+ */
|
245
|
+ private void addDrawingOp(byte[] message) {
|
246
|
+ drawingOps.add(message);
|
247
|
+ pendingBytes += message.length;
|
248
|
+ }
|
249
|
+
|
250
|
+ /**
|
251
|
* Defines the possible ways that the clipboard contents can be requested.
|
252
|
*/
|
253
|
private enum ClipboardRequest
|
254
|
|
255
|
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/web/ImageEncoding.java'
|
256
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/ImageEncoding.java 1970-01-01 00:00:00 +0000
|
257
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/ImageEncoding.java 2015-08-07 14:49:54 +0000
|
258
|
@@ -0,0 +1,44 @@
|
259
|
+/*
|
260
|
+** Module : ImageEncoding.java
|
261
|
+** Abstract : Enumerates encoding schemas to transfer screens images via network.
|
262
|
+**
|
263
|
+** Copyright (c) 2015, Golden Code Development Corporation.
|
264
|
+** ALL RIGHTS RESERVED. Use is subject to license terms.
|
265
|
+**
|
266
|
+** Golden Code Development Corporation
|
267
|
+** CONFIDENTIAL
|
268
|
+**
|
269
|
+** -#- -I- --Date-- --------------------------------Description----------------------------------
|
270
|
+** 001 SBI 20150807 First version which describes a schema for Raw encoding and MD5 hash encoding
|
271
|
+** that is used to transfer images md5 hashes via networks.
|
272
|
+**
|
273
|
+*/
|
274
|
+
|
275
|
+package com.goldencode.p2j.ui.client.gui.driver.web;
|
276
|
+
|
277
|
+/**
|
278
|
+ *
|
279
|
+ * ImageEncoding defines Raw encoding and MD5 hash encoding
|
280
|
+ * that is used to transfer images md5 hashes via networks.
|
281
|
+ *
|
282
|
+ */
|
283
|
+public enum ImageEncoding
|
284
|
+{
|
285
|
+ Raw(0), Md5Hash(1);
|
286
|
+
|
287
|
+ private final int value;
|
288
|
+
|
289
|
+ private ImageEncoding(int value)
|
290
|
+ {
|
291
|
+ this.value = value;
|
292
|
+ }
|
293
|
+
|
294
|
+ /**
|
295
|
+ * Returns an encoding well-known id.
|
296
|
+ * @return int an encoding id
|
297
|
+ */
|
298
|
+ public int getValue()
|
299
|
+ {
|
300
|
+ return value;
|
301
|
+ }
|
302
|
+}
|
303
|
|
304
|
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/web/PixelsEncoder.java'
|
305
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/PixelsEncoder.java 1970-01-01 00:00:00 +0000
|
306
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/PixelsEncoder.java 2015-08-07 14:49:54 +0000
|
307
|
@@ -0,0 +1,35 @@
|
308
|
+/*
|
309
|
+** Module : PixelsEncoder.java
|
310
|
+** Abstract : Describes a functionality to encode screens rectangles to transfer via networks.
|
311
|
+**
|
312
|
+** Copyright (c) 2015, Golden Code Development Corporation.
|
313
|
+** ALL RIGHTS RESERVED. Use is subject to license terms.
|
314
|
+**
|
315
|
+** Golden Code Development Corporation
|
316
|
+** CONFIDENTIAL
|
317
|
+**
|
318
|
+** -#- -I- --Date-- --------------------------------Description----------------------------------
|
319
|
+** 001 SBI 20150807 First version which describes a schema for encoding of a rectangle
|
320
|
+** on a provided virtual screen.
|
321
|
+*/
|
322
|
+
|
323
|
+package com.goldencode.p2j.ui.client.gui.driver.web;
|
324
|
+
|
325
|
+/**
|
326
|
+ *
|
327
|
+ * PixelsEncoder
|
328
|
+ *
|
329
|
+ */
|
330
|
+public interface PixelsEncoder
|
331
|
+{
|
332
|
+ /**
|
333
|
+ * Encode the rectangular area on the screen to transfer.
|
334
|
+ * @param screen virtual screen with the defined color model
|
335
|
+ * @param x int a position of the left side of the target rectangle along the screen horizon
|
336
|
+ * @param y int a position of the upper side of the target rectangle along the screen's vertical
|
337
|
+ * @param w int a width of the target rectangular area
|
338
|
+ * @param h int a height of the target rectangular area
|
339
|
+ * @return
|
340
|
+ */
|
341
|
+ byte[] packToBinaries(VirtualScreen screen, int x, int y, int w, int h);
|
342
|
+}
|
343
|
|
344
|
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/web/RawEncoder.java'
|
345
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/RawEncoder.java 1970-01-01 00:00:00 +0000
|
346
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/RawEncoder.java 2015-08-07 14:49:54 +0000
|
347
|
@@ -0,0 +1,70 @@
|
348
|
+/*
|
349
|
+** Module : RawEncoder.java
|
350
|
+** Abstract : Implements Raw encoding.
|
351
|
+**
|
352
|
+** Copyright (c) 2015, Golden Code Development Corporation.
|
353
|
+** ALL RIGHTS RESERVED. Use is subject to license terms.
|
354
|
+**
|
355
|
+** Golden Code Development Corporation
|
356
|
+** CONFIDENTIAL
|
357
|
+**
|
358
|
+** -#- -I- --Date-- --------------------------------Description----------------------------------
|
359
|
+** 001 SBI 20150807 First version which describes a raw encoding of a rectangle
|
360
|
+** on a provided virtual screen based on sRGB model.
|
361
|
+*/
|
362
|
+
|
363
|
+
|
364
|
+package com.goldencode.p2j.ui.client.gui.driver.web;
|
365
|
+
|
366
|
+import java.awt.image.DirectColorModel;
|
367
|
+
|
368
|
+/**
|
369
|
+ *
|
370
|
+ * RawEncoder implements Raw encoding based on RFB specification documents:
|
371
|
+ * https://www.realvnc.com/docs/rfbproto.pdf
|
372
|
+ * https://tools.ietf.org/html/rfc6143
|
373
|
+ * This implementation supports only sRGB pixels models with 32 bits per a pixel.
|
374
|
+ */
|
375
|
+class RawEncoder implements PixelsEncoder
|
376
|
+{
|
377
|
+
|
378
|
+ private final static int TRUE_COLOR_BITS_PER_PIXEL = 32;
|
379
|
+
|
380
|
+ @Override
|
381
|
+ public byte[] packToBinaries(VirtualScreen screen, int x, int y,
|
382
|
+ int w, int h)
|
383
|
+ {
|
384
|
+ byte[] encodedRectangle = null;
|
385
|
+ int b = 0;
|
386
|
+ int i = 0;
|
387
|
+ int s = 0;
|
388
|
+ int pixel;
|
389
|
+ int numberOfPixels = w * h;
|
390
|
+ int scanline = screen.getScreenWidth();
|
391
|
+ int jump = scanline - w;
|
392
|
+ int p = y * scanline + x;
|
393
|
+ int[] pixels = screen.getPixels();
|
394
|
+ DirectColorModel colorModel = screen.getColorModel();
|
395
|
+ if (colorModel.getPixelSize() == TRUE_COLOR_BITS_PER_PIXEL) {
|
396
|
+ encodedRectangle = new byte[ numberOfPixels << 2 ];
|
397
|
+ for( ; i < numberOfPixels; i++, s++, p++ )
|
398
|
+ {
|
399
|
+ if( s == w )
|
400
|
+ {
|
401
|
+ s = 0;
|
402
|
+ p += jump;
|
403
|
+ }
|
404
|
+ pixel = pixels[p];
|
405
|
+ encodedRectangle[b++] = (byte) colorModel.getRed(pixel);
|
406
|
+ encodedRectangle[b++] = (byte) colorModel.getGreen(pixel);
|
407
|
+ encodedRectangle[b++] = (byte) colorModel.getBlue(pixel);
|
408
|
+ encodedRectangle[b++] = (byte) colorModel.getAlpha(pixel);
|
409
|
+ }
|
410
|
+ } else {
|
411
|
+ throw new UnsupportedOperationException("Supported only 32 bits per a pixel");
|
412
|
+ }
|
413
|
+
|
414
|
+ return encodedRectangle;
|
415
|
+ }
|
416
|
+
|
417
|
+}
|
418
|
|
419
|
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreen.java'
|
420
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreen.java 1970-01-01 00:00:00 +0000
|
421
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreen.java 2015-08-07 15:16:33 +0000
|
422
|
@@ -0,0 +1,52 @@
|
423
|
+/*
|
424
|
+** Module : VirtualScreen.java
|
425
|
+** Abstract : Define methods to work with screen
|
426
|
+**
|
427
|
+** Copyright (c) 2015, Golden Code Development Corporation.
|
428
|
+** ALL RIGHTS RESERVED. Use is subject to license terms.
|
429
|
+**
|
430
|
+** Golden Code Development Corporation
|
431
|
+** CONFIDENTIAL
|
432
|
+**
|
433
|
+** -#- -I- --Date-- --------------------------------Description----------------------------------
|
434
|
+** 001 SBI 20150807 First version which describes a virtual screen based on sRGB model.
|
435
|
+*/
|
436
|
+
|
437
|
+package com.goldencode.p2j.ui.client.gui.driver.web;
|
438
|
+
|
439
|
+import java.awt.Image;
|
440
|
+import java.awt.image.DirectColorModel;
|
441
|
+
|
442
|
+/**
|
443
|
+ * VirtualScreen describes a virtual screen based on sRGB model. It provides
|
444
|
+ * an access to a screen pixel model and perform drawing operations.
|
445
|
+ */
|
446
|
+public interface VirtualScreen
|
447
|
+{
|
448
|
+ /**
|
449
|
+ *
|
450
|
+ * @return pixels int[] RGBA model via pixels
|
451
|
+ */
|
452
|
+ int[] getPixels();
|
453
|
+ /**
|
454
|
+ * Gets a screen width.
|
455
|
+ * @return int a screen width
|
456
|
+ */
|
457
|
+ int getScreenWidth();
|
458
|
+ /**
|
459
|
+ * Gets a screen height.
|
460
|
+ * @return height a screen height
|
461
|
+ */
|
462
|
+ int getScreenHeight();
|
463
|
+ /**
|
464
|
+ * Describes a pixel format used for drawing.
|
465
|
+ * @return DirectColorModel color model
|
466
|
+ */
|
467
|
+ DirectColorModel getColorModel();
|
468
|
+ /**
|
469
|
+ * Draw an image at the given point on the screen
|
470
|
+ * @param image Image
|
471
|
+ * @return unique bytes as unique image identification
|
472
|
+ */
|
473
|
+ byte[] drawImage(Image image, int x, int y);
|
474
|
+}
|
475
|
|
476
|
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreenImpl.java'
|
477
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreenImpl.java 1970-01-01 00:00:00 +0000
|
478
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreenImpl.java 2015-08-07 14:53:22 +0000
|
479
|
@@ -0,0 +1,123 @@
|
480
|
+/*
|
481
|
+** Module : VirtualScreenImpl.java
|
482
|
+** Abstract : Implements virtual screen functionalities.
|
483
|
+**
|
484
|
+** Copyright (c) 2015, Golden Code Development Corporation.
|
485
|
+** ALL RIGHTS RESERVED. Use is subject to license terms.
|
486
|
+**
|
487
|
+** Golden Code Development Corporation
|
488
|
+** CONFIDENTIAL
|
489
|
+**
|
490
|
+** -#- -I- --Date-- --------------------------------Description----------------------------------
|
491
|
+** 001 SBI 20150807 First version which implements a virtual screen based on sRGB model.
|
492
|
+*/
|
493
|
+
|
494
|
+package com.goldencode.p2j.ui.client.gui.driver.web;
|
495
|
+
|
496
|
+import java.awt.Color;
|
497
|
+import java.awt.Graphics2D;
|
498
|
+import java.awt.Image;
|
499
|
+import java.awt.image.BufferedImage;
|
500
|
+import java.awt.image.DataBuffer;
|
501
|
+import java.awt.image.DataBufferInt;
|
502
|
+import java.awt.image.DirectColorModel;
|
503
|
+import java.awt.image.Raster;
|
504
|
+import java.awt.image.SampleModel;
|
505
|
+import java.awt.image.SinglePixelPackedSampleModel;
|
506
|
+import java.awt.image.WritableRaster;
|
507
|
+import java.nio.ByteBuffer;
|
508
|
+import java.nio.IntBuffer;
|
509
|
+import java.security.MessageDigest;
|
510
|
+import java.security.NoSuchAlgorithmException;
|
511
|
+
|
512
|
+
|
513
|
+/**
|
514
|
+ *
|
515
|
+ * VirtualScreenImpl is an implementation of VirtualScreen drawings operations.
|
516
|
+ *
|
517
|
+ */
|
518
|
+class VirtualScreenImpl implements VirtualScreen
|
519
|
+{
|
520
|
+
|
521
|
+ private final DirectColorModel colorModel;
|
522
|
+ private final int width;
|
523
|
+ private final int height;
|
524
|
+ private final int[] pixels;
|
525
|
+ private final BufferedImage screen;
|
526
|
+
|
527
|
+ /**
|
528
|
+ * Constructs a virtual screen of the given width and height
|
529
|
+ * based on the given pixels model.
|
530
|
+ *
|
531
|
+ * @param colorModel DirectColorModel pixels model based on sRGB
|
532
|
+ * @param width int a screen width
|
533
|
+ * @param height int a screen height
|
534
|
+ */
|
535
|
+ public VirtualScreenImpl(DirectColorModel colorModel, int width, int height)
|
536
|
+ {
|
537
|
+ this.colorModel = colorModel;
|
538
|
+ this.width = width;
|
539
|
+ this.height = height;
|
540
|
+ this.pixels = new int[width*height];
|
541
|
+ final DataBuffer data = new DataBufferInt(pixels, pixels.length);
|
542
|
+ final SampleModel sampleModel = new SinglePixelPackedSampleModel(
|
543
|
+ DataBuffer.TYPE_INT, width, height, colorModel.getMasks());
|
544
|
+ final WritableRaster raster = Raster.createWritableRaster(sampleModel, data, null);
|
545
|
+ this.screen = new BufferedImage(colorModel, raster, true, null);
|
546
|
+ }
|
547
|
+
|
548
|
+ @Override
|
549
|
+ public int[] getPixels()
|
550
|
+ {
|
551
|
+ return pixels;
|
552
|
+ }
|
553
|
+
|
554
|
+ @Override
|
555
|
+ public int getScreenWidth()
|
556
|
+ {
|
557
|
+ return width;
|
558
|
+ }
|
559
|
+
|
560
|
+ @Override
|
561
|
+ public int getScreenHeight()
|
562
|
+ {
|
563
|
+ return height;
|
564
|
+ }
|
565
|
+
|
566
|
+ @Override
|
567
|
+ public DirectColorModel getColorModel()
|
568
|
+ {
|
569
|
+ return colorModel;
|
570
|
+ }
|
571
|
+
|
572
|
+ private byte[] digest(int scanline, int imagePixelsSize, int x, int y)
|
573
|
+ {
|
574
|
+ byte[] md5ImageHash = null;
|
575
|
+ try
|
576
|
+ {
|
577
|
+ MessageDigest md = MessageDigest.getInstance("MD5");
|
578
|
+ ByteBuffer byteBuffer = ByteBuffer.allocate(imagePixelsSize * 4);
|
579
|
+ IntBuffer intBuffer = byteBuffer.asIntBuffer();
|
580
|
+ intBuffer.put(pixels, x + y * scanline, imagePixelsSize);
|
581
|
+ md.update(byteBuffer);
|
582
|
+ md5ImageHash = md.digest();
|
583
|
+ }
|
584
|
+ catch (NoSuchAlgorithmException e)
|
585
|
+ {
|
586
|
+ e.printStackTrace();
|
587
|
+ }
|
588
|
+ return md5ImageHash;
|
589
|
+ }
|
590
|
+
|
591
|
+ @Override
|
592
|
+ public byte[] drawImage(Image image, int x, int y)
|
593
|
+ {
|
594
|
+ Graphics2D g2 = screen.createGraphics();
|
595
|
+ g2.setColor(new Color(0,0,0));
|
596
|
+ g2.fillRect(0, 0, getScreenWidth(), getScreenHeight());
|
597
|
+ g2.drawImage(image, x, y, null);
|
598
|
+ g2.dispose();
|
599
|
+ return digest(getScreenWidth(), image.getWidth(null)*image.getHeight(null), x, y);
|
600
|
+ }
|
601
|
+
|
602
|
+}
|
603
|
|
604
|
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js'
|
605
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2015-07-30 23:09:31 +0000
|
606
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2015-08-07 15:52:02 +0000
|
607
|
@@ -14,6 +14,7 @@
|
608
|
** ChUI). Moved some logic to common code locations.
|
609
|
** 002 SBI 20150731 Applied "use strict" directive, fixed undeclared variables.
|
610
|
** 003 GES 20150720 Total rewrite to implement a first pass at GUI support.
|
611
|
+** 004 SBI 20150807 Added a drawing image operation
|
612
|
*/
|
613
|
|
614
|
"use strict";
|
615
|
@@ -32,6 +33,11 @@
|
616
|
/** List of active windows. */
|
617
|
var winlist = new Array();
|
618
|
|
619
|
+ /**
|
620
|
+ * Loaded images map
|
621
|
+ */
|
622
|
+ var loadedImages = new Map();
|
623
|
+
|
624
|
/** Normal canvas font. */
|
625
|
var font;
|
626
|
|
627
|
@@ -352,6 +358,38 @@
|
628
|
drawRoundRect(ctx, x, y, width, height, diameter, this.rawColor, false);
|
629
|
break;
|
630
|
case ops.DRAW_IMAGE:
|
631
|
+ console.debug("drawing type: " + message[idx]);
|
632
|
+ x = p2j.socket.readInt32BinaryMessage(message, idx + 1);
|
633
|
+ y = p2j.socket.readInt32BinaryMessage(message, idx + 5);
|
634
|
+ width = p2j.socket.readInt32BinaryMessage(message, idx + 9);
|
635
|
+ height = p2j.socket.readInt32BinaryMessage(message, idx + 13);
|
636
|
+ console.debug(x + "x" + y + ", " + width + "x" + height);
|
637
|
+ var encoding = p2j.socket.readInt32BinaryMessage(message, idx + 17);
|
638
|
+ console.debug("encoding type: " + encoding);
|
639
|
+ var md5ImageHash = message.subarray(idx + 21, idx + 37);
|
640
|
+ var key = md5ImageHash.join('');
|
641
|
+ console.debug("hash: " + key);
|
642
|
+ var img = ctx.createImageData(width, height);
|
643
|
+ var data = img.data;
|
644
|
+ var pixelsInBytes = width * height * 4;
|
645
|
+ var imgData;
|
646
|
+ var imgDataOffset;
|
647
|
+ if(loadedImages.has(key)) {
|
648
|
+ imgData = loadedImages.get(key);
|
649
|
+ imgDataOffset = 0;
|
650
|
+ } else {
|
651
|
+ imgData = message;
|
652
|
+ imgDataOffset = idx + 37;
|
653
|
+ loadedImages.set(key, message.subarray(imgDataOffset, imgDataOffset + pixelsInBytes));
|
654
|
+ }
|
655
|
+ for (var i = 0, j = imgDataOffset; i < pixelsInBytes; i += 4, j += 4) {
|
656
|
+ data[i] = imgData[j];
|
657
|
+ data[i + 1] = imgData[j + 1];
|
658
|
+ data[i + 2] = imgData[j + 2];
|
659
|
+ data[i + 3] = imgData[j + 3];
|
660
|
+ }
|
661
|
+ ctx.putImageData(img, x, y);
|
662
|
+
|
663
|
break;
|
664
|
case ops.FILL_RECT:
|
665
|
x = p2j.socket.readInt32BinaryMessage(message, idx + 1);
|
666
|
|