Revision f008ad71
Added by Amos Benari about 11 years ago
- ID f008ad716bf31d022c1135238a18497b03a04c07
app/views/hosts/console/spice.html.erb | ||
---|---|---|
<%= javascript 'spice/setup', 'spice' %>
|
||
<%= javascript 'spice-html5', 'spice' %>
|
||
<% title "#{@console[:name]}" %>
|
||
<%= title_actions(
|
||
button_group(link_to("Ctrl-Alt-Del", "#", :id => "sendCtrlAltDelButton", :onclick => 'sendCtrlAltDel()', :class => "btn"),
|
||
... | ... | |
end
|
||
)) %>
|
||
|
||
<%# TODO: when rails 3.2 merge is done uncomment the following %>
|
||
<%# tag(:div id =>'spice-area' data => spice_data_attributes(@console) %>
|
||
<div id='spice-area' <%= spice_data_attributes(@console).map {|k,v| "data-#{k}=#{v}"}.join(' ') %>>
|
||
<%= content_tag(:div, :id =>'spice-area', :data => spice_data_attributes(@console)) do %>
|
||
<div class="console-status">
|
||
<div id="spice-status" class="span7 label"><%= "Connecting (unencrypted) to: #{@console[:name]}" %></div>
|
||
</div>
|
||
<div id="spice-screen" class="console-screen"> </div>
|
||
</div>
|
||
<% end %>
|
bundler.d/assets.rb | ||
---|---|---|
gem 'jquery-ui-rails'
|
||
gem "therubyracer", '0.11.3'
|
||
gem "twitter-bootstrap-rails"
|
||
gem "spice-html5-rails"
|
||
end
|
config/environments/production.rb | ||
---|---|---|
noVNC/webutil
|
||
noVNC
|
||
reports
|
||
spice/setup
|
||
spice
|
||
trends
|
||
charts
|
vendor/assets/javascripts/spice/atKeynames.js | ||
---|---|---|
"use strict";
|
||
/*
|
||
Copyright (C) 2012 by Aric Stewart <aric@codeweavers.com>
|
||
|
||
This file is part of spice-html5.
|
||
|
||
spice-html5 is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
spice-html5 is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
/*
|
||
* Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
|
||
*
|
||
* 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, and that the name of Thomas Roell not be used in
|
||
* advertising or publicity pertaining to distribution of the software without
|
||
* specific, written prior permission. Thomas Roell makes no representations
|
||
* about the suitability of this software for any purpose. It is provided
|
||
* "as is" without express or implied warranty.
|
||
*
|
||
* THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||
* EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||
* PERFORMANCE OF THIS SOFTWARE.
|
||
*
|
||
*/
|
||
/*
|
||
* Copyright (c) 1994-2003 by The XFree86 Project, Inc.
|
||
*
|
||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||
* copy of this software and associated documentation files (the "Software"),
|
||
* to deal in the Software without restriction, including without limitation
|
||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
* and/or sell copies of the Software, and to permit persons to whom the
|
||
* Software is furnished to do so, subject to the following conditions:
|
||
*
|
||
* The above copyright notice and this permission notice shall be included in
|
||
* all copies or substantial portions of the Software.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
* OTHER DEALINGS IN THE SOFTWARE.
|
||
*
|
||
* Except as contained in this notice, the name of the copyright holder(s)
|
||
* and author(s) shall not be used in advertising or otherwise to promote
|
||
* the sale, use or other dealings in this Software without prior written
|
||
* authorization from the copyright holder(s) and author(s).
|
||
*/
|
||
|
||
/*
|
||
* NOTE: The AT/MF keyboards can generate (via the 8042) two (MF: three)
|
||
* sets of scancodes. Set3 can only be generated by a MF keyboard.
|
||
* Set2 sends a makecode for keypress, and the same code prefixed by a
|
||
* F0 for keyrelease. This is a little bit ugly to handle. Thus we use
|
||
* here for X386 the PC/XT compatible Set1. This set uses 8bit scancodes.
|
||
* Bit 7 ist set if the key is released. The code E0 switches to a
|
||
* different meaning to add the new MF cursorkeys, while not breaking old
|
||
* applications. E1 is another special prefix. Since I assume that there
|
||
* will be further versions of PC/XT scancode compatible keyboards, we
|
||
* may be in trouble one day.
|
||
*
|
||
* IDEA: 1) Use Set2 on AT84 keyboards and translate it to MF Set3.
|
||
* 2) Use the keyboards native set and translate it to common keysyms.
|
||
*/
|
||
|
||
/*
|
||
* definition of the AT84/MF101/MF102 Keyboard:
|
||
* ============================================================
|
||
* Defined Key Cap Glyphs Pressed value
|
||
* Key Name Main Also (hex) (dec)
|
||
* ---------------- ---------- ------- ------ ------
|
||
*/
|
||
|
||
var KEY_Escape =/* Escape 0x01 */ 1
|
||
var KEY_1 =/* 1 ! 0x02 */ 2
|
||
var KEY_2 =/* 2 @ 0x03 */ 3
|
||
var KEY_3 =/* 3 # 0x04 */ 4
|
||
var KEY_4 =/* 4 $ 0x05 */ 5
|
||
var KEY_5 =/* 5 % 0x06 */ 6
|
||
var KEY_6 =/* 6 ^ 0x07 */ 7
|
||
var KEY_7 =/* 7 & 0x08 */ 8
|
||
var KEY_8 =/* 8 * 0x09 */ 9
|
||
var KEY_9 =/* 9 ( 0x0a */ 10
|
||
var KEY_0 =/* 0 ) 0x0b */ 11
|
||
var KEY_Minus =/* - (Minus) _ (Under) 0x0c */ 12
|
||
var KEY_Equal =/* = (Equal) + 0x0d */ 13
|
||
var KEY_BackSpace =/* Back Space 0x0e */ 14
|
||
var KEY_Tab =/* Tab 0x0f */ 15
|
||
var KEY_Q =/* Q 0x10 */ 16
|
||
var KEY_W =/* W 0x11 */ 17
|
||
var KEY_E =/* E 0x12 */ 18
|
||
var KEY_R =/* R 0x13 */ 19
|
||
var KEY_T =/* T 0x14 */ 20
|
||
var KEY_Y =/* Y 0x15 */ 21
|
||
var KEY_U =/* U 0x16 */ 22
|
||
var KEY_I =/* I 0x17 */ 23
|
||
var KEY_O =/* O 0x18 */ 24
|
||
var KEY_P =/* P 0x19 */ 25
|
||
var KEY_LBrace =/* [ { 0x1a */ 26
|
||
var KEY_RBrace =/* ] } 0x1b */ 27
|
||
var KEY_Enter =/* Enter 0x1c */ 28
|
||
var KEY_LCtrl =/* Ctrl(left) 0x1d */ 29
|
||
var KEY_A =/* A 0x1e */ 30
|
||
var KEY_S =/* S 0x1f */ 31
|
||
var KEY_D =/* D 0x20 */ 32
|
||
var KEY_F =/* F 0x21 */ 33
|
||
var KEY_G =/* G 0x22 */ 34
|
||
var KEY_H =/* H 0x23 */ 35
|
||
var KEY_J =/* J 0x24 */ 36
|
||
var KEY_K =/* K 0x25 */ 37
|
||
var KEY_L =/* L 0x26 */ 38
|
||
var KEY_SemiColon =/* ;(SemiColon) :(Colon) 0x27 */ 39
|
||
var KEY_Quote =/* ' (Apostr) " (Quote) 0x28 */ 40
|
||
var KEY_Tilde =/* ` (Accent) ~ (Tilde) 0x29 */ 41
|
||
var KEY_ShiftL =/* Shift(left) 0x2a */ 42
|
||
var KEY_BSlash =/* \(BckSlash) |(VertBar)0x2b */ 43
|
||
var KEY_Z =/* Z 0x2c */ 44
|
||
var KEY_X =/* X 0x2d */ 45
|
||
var KEY_C =/* C 0x2e */ 46
|
||
var KEY_V =/* V 0x2f */ 47
|
||
var KEY_B =/* B 0x30 */ 48
|
||
var KEY_N =/* N 0x31 */ 49
|
||
var KEY_M =/* M 0x32 */ 50
|
||
var KEY_Comma =/* , (Comma) < (Less) 0x33 */ 51
|
||
var KEY_Period =/* . (Period) >(Greater)0x34 */ 52
|
||
var KEY_Slash =/* / (Slash) ? 0x35 */ 53
|
||
var KEY_ShiftR =/* Shift(right) 0x36 */ 54
|
||
var KEY_KP_Multiply =/* * 0x37 */ 55
|
||
var KEY_Alt =/* Alt(left) 0x38 */ 56
|
||
var KEY_Space =/* (SpaceBar) 0x39 */ 57
|
||
var KEY_CapsLock =/* CapsLock 0x3a */ 58
|
||
var KEY_F1 =/* F1 0x3b */ 59
|
||
var KEY_F2 =/* F2 0x3c */ 60
|
||
var KEY_F3 =/* F3 0x3d */ 61
|
||
var KEY_F4 =/* F4 0x3e */ 62
|
||
var KEY_F5 =/* F5 0x3f */ 63
|
||
var KEY_F6 =/* F6 0x40 */ 64
|
||
var KEY_F7 =/* F7 0x41 */ 65
|
||
var KEY_F8 =/* F8 0x42 */ 66
|
||
var KEY_F9 =/* F9 0x43 */ 67
|
||
var KEY_F10 =/* F10 0x44 */ 68
|
||
var KEY_NumLock =/* NumLock 0x45 */ 69
|
||
var KEY_ScrollLock =/* ScrollLock 0x46 */ 70
|
||
var KEY_KP_7 =/* 7 Home 0x47 */ 71
|
||
var KEY_KP_8 =/* 8 Up 0x48 */ 72
|
||
var KEY_KP_9 =/* 9 PgUp 0x49 */ 73
|
||
var KEY_KP_Minus =/* - (Minus) 0x4a */ 74
|
||
var KEY_KP_4 =/* 4 Left 0x4b */ 75
|
||
var KEY_KP_5 =/* 5 0x4c */ 76
|
||
var KEY_KP_6 =/* 6 Right 0x4d */ 77
|
||
var KEY_KP_Plus =/* + (Plus) 0x4e */ 78
|
||
var KEY_KP_1 =/* 1 End 0x4f */ 79
|
||
var KEY_KP_2 =/* 2 Down 0x50 */ 80
|
||
var KEY_KP_3 =/* 3 PgDown 0x51 */ 81
|
||
var KEY_KP_0 =/* 0 Insert 0x52 */ 82
|
||
var KEY_KP_Decimal =/* . (Decimal) Delete 0x53 */ 83
|
||
var KEY_SysReqest =/* SysReqest 0x54 */ 84
|
||
/* NOTUSED 0x55 */
|
||
var KEY_Less =/* < (Less) >(Greater) 0x56 */ 86
|
||
var KEY_F11 =/* F11 0x57 */ 87
|
||
var KEY_F12 =/* F12 0x58 */ 88
|
||
|
||
var KEY_Prefix0 =/* special 0x60 */ 96
|
||
var KEY_Prefix1 =/* specail 0x61 */ 97
|
vendor/assets/javascripts/spice/bitmap.js | ||
---|---|---|
"use strict";
|
||
/*
|
||
Copyright (C) 2012 by Jeremy P. White <jwhite@codeweavers.com>
|
||
|
||
This file is part of spice-html5.
|
||
|
||
spice-html5 is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
spice-html5 is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
|
||
/*----------------------------------------------------------------------------
|
||
** bitmap.js
|
||
** Handle SPICE_IMAGE_TYPE_BITMAP
|
||
**--------------------------------------------------------------------------*/
|
||
function convert_spice_bitmap_to_web(context, spice_bitmap)
|
||
{
|
||
var ret;
|
||
var offset, x;
|
||
var u8 = new Uint8Array(spice_bitmap.data);
|
||
if (spice_bitmap.format != SPICE_BITMAP_FMT_32BIT &&
|
||
spice_bitmap.format != SPICE_BITMAP_FMT_RGBA)
|
||
return undefined;
|
||
|
||
ret = context.createImageData(spice_bitmap.x, spice_bitmap.y);
|
||
for (offset = 0; offset < (spice_bitmap.y * spice_bitmap.stride); )
|
||
for (x = 0; x < spice_bitmap.x; x++, offset += 4)
|
||
{
|
||
ret.data[offset + 0 ] = u8[offset + 2];
|
||
ret.data[offset + 1 ] = u8[offset + 1];
|
||
ret.data[offset + 2 ] = u8[offset + 0];
|
||
|
||
// FIXME - We effectively treat all images as having SPICE_IMAGE_FLAGS_HIGH_BITS_SET
|
||
if (spice_bitmap.format == SPICE_BITMAP_FMT_32BIT)
|
||
ret.data[offset + 3] = 255;
|
||
else
|
||
ret.data[offset + 3] = u8[offset];
|
||
}
|
||
|
||
return ret;
|
||
}
|
vendor/assets/javascripts/spice/cursor.js | ||
---|---|---|
"use strict";
|
||
/*
|
||
Copyright (C) 2012 by Jeremy P. White <jwhite@codeweavers.com>
|
||
|
||
This file is part of spice-html5.
|
||
|
||
spice-html5 is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
spice-html5 is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
|
||
/*----------------------------------------------------------------------------
|
||
** SpiceCursorConn
|
||
** Drive the Spice Cursor Channel
|
||
**--------------------------------------------------------------------------*/
|
||
function SpiceCursorConn()
|
||
{
|
||
SpiceConn.apply(this, arguments);
|
||
}
|
||
|
||
SpiceCursorConn.prototype = Object.create(SpiceConn.prototype);
|
||
SpiceCursorConn.prototype.process_channel_message = function(msg)
|
||
{
|
||
if (msg.type == SPICE_MSG_CURSOR_INIT)
|
||
{
|
||
var cursor_init = new SpiceMsgCursorInit(msg.data);
|
||
DEBUG > 1 && console.log("SpiceMsgCursorInit");
|
||
if (this.parent && this.parent.inputs &&
|
||
this.parent.inputs.mouse_mode == SPICE_MOUSE_MODE_SERVER)
|
||
{
|
||
// FIXME - this imagines that the server actually
|
||
// provides the current cursor position,
|
||
// instead of 0,0. As of May 11, 2012,
|
||
// that assumption was false :-(.
|
||
this.parent.inputs.mousex = cursor_init.position.x;
|
||
this.parent.inputs.mousey = cursor_init.position.y;
|
||
}
|
||
// FIXME - We don't handle most of the parameters here...
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_CURSOR_SET)
|
||
{
|
||
var cursor_set = new SpiceMsgCursorSet(msg.data);
|
||
DEBUG > 1 && console.log("SpiceMsgCursorSet");
|
||
if (cursor_set.flags & SPICE_CURSOR_FLAGS_NONE)
|
||
{
|
||
document.getElementById(this.parent.screen_id).style.cursor = "none";
|
||
return true;
|
||
}
|
||
|
||
if (cursor_set.flags > 0)
|
||
this.log_warn("FIXME: No support for cursor flags " + cursor_set.flags);
|
||
|
||
if (cursor_set.cursor.header.type != SPICE_CURSOR_TYPE_ALPHA)
|
||
{
|
||
this.log_warn("FIXME: No support for cursor type " + cursor_set.cursor.header.type);
|
||
return false;
|
||
}
|
||
|
||
this.set_cursor(cursor_set.cursor);
|
||
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_CURSOR_HIDE)
|
||
{
|
||
DEBUG > 1 && console.log("SpiceMsgCursorHide");
|
||
document.getElementById(this.parent.screen_id).style.cursor = "none";
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
SpiceCursorConn.prototype.set_cursor = function(cursor)
|
||
{
|
||
var pngstr = create_rgba_png(cursor.header.height, cursor.header.width, cursor.data);
|
||
var curstr = 'url(data:image/png,' + pngstr + ') ' +
|
||
cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ", default";
|
||
document.getElementById(this.parent.screen_id).style.cursor = curstr;
|
||
}
|
vendor/assets/javascripts/spice/display.js | ||
---|---|---|
"use strict";
|
||
/*
|
||
Copyright (C) 2012 by Jeremy P. White <jwhite@codeweavers.com>
|
||
|
||
This file is part of spice-html5.
|
||
|
||
spice-html5 is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
spice-html5 is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
|
||
/*----------------------------------------------------------------------------
|
||
** FIXME: putImageData does not support Alpha blending
|
||
** or compositing. So if we have data in an ImageData
|
||
** format, we have to draw it onto a context,
|
||
** and then use drawImage to put it onto the target,
|
||
** as drawImage does alpha.
|
||
**--------------------------------------------------------------------------*/
|
||
function putImageDataWithAlpha(context, d, x, y)
|
||
{
|
||
var c = document.createElement("canvas");
|
||
var t = c.getContext("2d");
|
||
c.setAttribute('width', d.width);
|
||
c.setAttribute('height', d.height);
|
||
t.putImageData(d, 0, 0);
|
||
context.drawImage(c, x, y, d.width, d.height);
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------
|
||
** FIXME: Spice will send an image with '0' alpha when it is intended to
|
||
** go on a surface w/no alpha. So in that case, we have to strip
|
||
** out the alpha. The test case for this was flux box; in a Xspice
|
||
** server, right click on the desktop to get the menu; the top bar
|
||
** doesn't paint/highlight correctly w/out this change.
|
||
**--------------------------------------------------------------------------*/
|
||
function stripAlpha(d)
|
||
{
|
||
var i;
|
||
for (i = 0; i < (d.width * d.height * 4); i += 4)
|
||
d.data[i + 3] = 255;
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------
|
||
** SpiceDisplayConn
|
||
** Drive the Spice Display Channel
|
||
**--------------------------------------------------------------------------*/
|
||
function SpiceDisplayConn()
|
||
{
|
||
SpiceConn.apply(this, arguments);
|
||
}
|
||
|
||
SpiceDisplayConn.prototype = Object.create(SpiceConn.prototype);
|
||
SpiceDisplayConn.prototype.process_channel_message = function(msg)
|
||
{
|
||
if (msg.type == SPICE_MSG_DISPLAY_MARK)
|
||
{
|
||
// FIXME - DISPLAY_MARK not implemented (may be hard or impossible)
|
||
this.known_unimplemented(msg.type, "Display Mark");
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_RESET)
|
||
{
|
||
DEBUG > 2 && console.log("Display reset");
|
||
this.surfaces[this.primary_surface].canvas.context.restore();
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_DRAW_COPY)
|
||
{
|
||
var draw_copy = new SpiceMsgDisplayDrawCopy(msg.data);
|
||
|
||
DEBUG > 1 && this.log_draw("DrawCopy", draw_copy);
|
||
|
||
if (! draw_copy.base.box.is_same_size(draw_copy.data.src_area))
|
||
this.log_warn("FIXME: DrawCopy src_area is a different size than base.box; we do not handle that yet.");
|
||
if (draw_copy.base.clip.type != SPICE_CLIP_TYPE_NONE)
|
||
this.log_warn("FIXME: DrawCopy we don't handle clipping yet");
|
||
if (draw_copy.data.rop_descriptor != SPICE_ROPD_OP_PUT)
|
||
this.log_warn("FIXME: DrawCopy we don't handle ropd type: " + draw_copy.data.rop_descriptor);
|
||
if (draw_copy.data.mask.flags)
|
||
this.log_warn("FIXME: DrawCopy we don't handle mask flag: " + draw_copy.data.mask.flags);
|
||
if (draw_copy.data.mask.bitmap)
|
||
this.log_warn("FIXME: DrawCopy we don't handle mask");
|
||
|
||
if (draw_copy.data && draw_copy.data.src_bitmap)
|
||
{
|
||
if (draw_copy.data.src_bitmap.descriptor.flags &&
|
||
draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_CACHE_ME &&
|
||
draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_HIGH_BITS_SET)
|
||
{
|
||
this.log_warn("FIXME: DrawCopy unhandled image flags: " + draw_copy.data.src_bitmap.descriptor.flags);
|
||
DEBUG <= 1 && this.log_draw("DrawCopy", draw_copy);
|
||
}
|
||
|
||
if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
|
||
{
|
||
var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
|
||
if (! draw_copy.data.src_bitmap.quic)
|
||
{
|
||
this.log_warn("FIXME: DrawCopy could not handle this QUIC file.");
|
||
return false;
|
||
}
|
||
var source_img = convert_spice_quic_to_web(canvas.context,
|
||
draw_copy.data.src_bitmap.quic);
|
||
|
||
return this.draw_copy_helper(
|
||
{ base: draw_copy.base,
|
||
src_area: draw_copy.data.src_area,
|
||
image_data: source_img,
|
||
tag: "copyquic." + draw_copy.data.src_bitmap.quic.type,
|
||
has_alpha: (draw_copy.data.src_bitmap.quic.type == QUIC_IMAGE_TYPE_RGBA ? true : false) ,
|
||
descriptor : draw_copy.data.src_bitmap.descriptor
|
||
});
|
||
}
|
||
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE ||
|
||
draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS)
|
||
{
|
||
if (! this.cache || ! this.cache[draw_copy.data.src_bitmap.descriptor.id])
|
||
{
|
||
this.log_warn("FIXME: DrawCopy did not find image id " + draw_copy.data.src_bitmap.descriptor.id + " in cache.");
|
||
return false;
|
||
}
|
||
|
||
return this.draw_copy_helper(
|
||
{ base: draw_copy.base,
|
||
src_area: draw_copy.data.src_area,
|
||
image_data: this.cache[draw_copy.data.src_bitmap.descriptor.id],
|
||
tag: "copycache." + draw_copy.data.src_bitmap.descriptor.id,
|
||
has_alpha: true, /* FIXME - may want this to be false... */
|
||
descriptor : draw_copy.data.src_bitmap.descriptor
|
||
});
|
||
|
||
/* FIXME - LOSSLESS CACHE ramifications not understood or handled */
|
||
}
|
||
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
|
||
{
|
||
var source_context = this.surfaces[draw_copy.data.src_bitmap.surface_id].canvas.context;
|
||
var target_context = this.surfaces[draw_copy.base.surface_id].canvas.context;
|
||
|
||
var source_img = source_context.getImageData(
|
||
draw_copy.data.src_area.left, draw_copy.data.src_area.top,
|
||
draw_copy.data.src_area.right - draw_copy.data.src_area.left,
|
||
draw_copy.data.src_area.bottom - draw_copy.data.src_area.top);
|
||
var computed_src_area = new SpiceRect;
|
||
computed_src_area.top = computed_src_area.left = 0;
|
||
computed_src_area.right = source_img.width;
|
||
computed_src_area.bottom = source_img.height;
|
||
|
||
/* FIXME - there is a potential optimization here.
|
||
That is, if the surface is from 0,0, and
|
||
both surfaces are alpha surfaces, you should
|
||
be able to just do a drawImage, which should
|
||
save time. */
|
||
|
||
return this.draw_copy_helper(
|
||
{ base: draw_copy.base,
|
||
src_area: computed_src_area,
|
||
image_data: source_img,
|
||
tag: "copysurf." + draw_copy.data.src_bitmap.surface_id,
|
||
has_alpha: this.surfaces[draw_copy.data.src_bitmap.surface_id].format == SPICE_SURFACE_FMT_32_xRGB ? false : true,
|
||
descriptor : draw_copy.data.src_bitmap.descriptor
|
||
});
|
||
|
||
return true;
|
||
}
|
||
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
|
||
{
|
||
if (! draw_copy.data.src_bitmap.jpeg)
|
||
{
|
||
this.log_warn("FIXME: DrawCopy could not handle this JPEG file.");
|
||
return false;
|
||
}
|
||
|
||
// FIXME - how lame is this. Be have it in binary format, and we have
|
||
// to put it into string to get it back into jpeg. Blech.
|
||
var tmpstr = "data:image/jpeg,";
|
||
var img = new Image;
|
||
var i;
|
||
var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg.data);
|
||
for (i = 0; i < qdv.length; i++)
|
||
{
|
||
tmpstr += '%';
|
||
if (qdv[i] < 16)
|
||
tmpstr += '0';
|
||
tmpstr += qdv[i].toString(16);
|
||
}
|
||
|
||
img.o =
|
||
{ base: draw_copy.base,
|
||
tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
|
||
descriptor : draw_copy.data.src_bitmap.descriptor,
|
||
sc : this,
|
||
};
|
||
img.onload = handle_draw_jpeg_onload;
|
||
img.src = tmpstr;
|
||
|
||
return true;
|
||
}
|
||
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA)
|
||
{
|
||
if (! draw_copy.data.src_bitmap.jpeg_alpha)
|
||
{
|
||
this.log_warn("FIXME: DrawCopy could not handle this JPEG ALPHA file.");
|
||
return false;
|
||
}
|
||
|
||
// FIXME - how lame is this. Be have it in binary format, and we have
|
||
// to put it into string to get it back into jpeg. Blech.
|
||
var tmpstr = "data:image/jpeg,";
|
||
var img = new Image;
|
||
var i;
|
||
var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg_alpha.data);
|
||
for (i = 0; i < qdv.length; i++)
|
||
{
|
||
tmpstr += '%';
|
||
if (qdv[i] < 16)
|
||
tmpstr += '0';
|
||
tmpstr += qdv[i].toString(16);
|
||
}
|
||
|
||
img.o =
|
||
{ base: draw_copy.base,
|
||
tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
|
||
descriptor : draw_copy.data.src_bitmap.descriptor,
|
||
sc : this,
|
||
};
|
||
|
||
if (this.surfaces[draw_copy.base.surface_id].format == SPICE_SURFACE_FMT_32_ARGB)
|
||
{
|
||
|
||
var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
|
||
img.alpha_img = convert_spice_lz_to_web(canvas.context,
|
||
draw_copy.data.src_bitmap.jpeg_alpha.alpha);
|
||
}
|
||
img.onload = handle_draw_jpeg_onload;
|
||
img.src = tmpstr;
|
||
|
||
return true;
|
||
}
|
||
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_BITMAP)
|
||
{
|
||
var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
|
||
if (! draw_copy.data.src_bitmap.bitmap)
|
||
{
|
||
this.log_err("null bitmap");
|
||
return false;
|
||
}
|
||
|
||
var source_img = convert_spice_bitmap_to_web(canvas.context,
|
||
draw_copy.data.src_bitmap.bitmap);
|
||
if (! source_img)
|
||
{
|
||
this.log_warn("FIXME: Unable to interpret bitmap of format: " +
|
||
draw_copy.data.src_bitmap.bitmap.format);
|
||
return false;
|
||
}
|
||
|
||
return this.draw_copy_helper(
|
||
{ base: draw_copy.base,
|
||
src_area: draw_copy.data.src_area,
|
||
image_data: source_img,
|
||
tag: "bitmap." + draw_copy.data.src_bitmap.bitmap.format,
|
||
has_alpha: draw_copy.data.src_bitmap.bitmap == SPICE_BITMAP_FMT_32BIT ? false : true,
|
||
descriptor : draw_copy.data.src_bitmap.descriptor
|
||
});
|
||
}
|
||
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB)
|
||
{
|
||
var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
|
||
if (! draw_copy.data.src_bitmap.lz_rgb)
|
||
{
|
||
this.log_err("null lz_rgb ");
|
||
return false;
|
||
}
|
||
|
||
if (draw_copy.data.src_bitmap.lz_rgb.top_down != 1)
|
||
this.log_warn("FIXME: Implement non top down support for lz_rgb");
|
||
|
||
var source_img = convert_spice_lz_to_web(canvas.context,
|
||
draw_copy.data.src_bitmap.lz_rgb);
|
||
if (! source_img)
|
||
{
|
||
this.log_warn("FIXME: Unable to interpret bitmap of type: " +
|
||
draw_copy.data.src_bitmap.lz_rgb.type);
|
||
return false;
|
||
}
|
||
|
||
return this.draw_copy_helper(
|
||
{ base: draw_copy.base,
|
||
src_area: draw_copy.data.src_area,
|
||
image_data: source_img,
|
||
tag: "lz_rgb." + draw_copy.data.src_bitmap.lz_rgb.type,
|
||
has_alpha: draw_copy.data.src_bitmap.lz_rgb.type == LZ_IMAGE_TYPE_RGBA ? true : false ,
|
||
descriptor : draw_copy.data.src_bitmap.descriptor
|
||
});
|
||
}
|
||
else
|
||
{
|
||
this.log_warn("FIXME: DrawCopy unhandled image type: " + draw_copy.data.src_bitmap.descriptor.type);
|
||
this.log_draw("DrawCopy", draw_copy);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
this.log_warn("FIXME: DrawCopy no src_bitmap.");
|
||
return false;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_DRAW_FILL)
|
||
{
|
||
var draw_fill = new SpiceMsgDisplayDrawFill(msg.data);
|
||
|
||
DEBUG > 1 && this.log_draw("DrawFill", draw_fill);
|
||
|
||
if (draw_fill.data.rop_descriptor != SPICE_ROPD_OP_PUT)
|
||
this.log_warn("FIXME: DrawFill we don't handle ropd type: " + draw_fill.data.rop_descriptor);
|
||
if (draw_fill.data.mask.flags)
|
||
this.log_warn("FIXME: DrawFill we don't handle mask flag: " + draw_fill.data.mask.flags);
|
||
if (draw_fill.data.mask.bitmap)
|
||
this.log_warn("FIXME: DrawFill we don't handle mask");
|
||
|
||
if (draw_fill.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
|
||
{
|
||
// FIXME - do brushes ever have alpha?
|
||
var color = draw_fill.data.brush.color & 0xffffff;
|
||
var color_str = "rgb(" + (color >> 16) + ", " + ((color >> 8) & 0xff) + ", " + (color & 0xff) + ")";
|
||
this.surfaces[draw_fill.base.surface_id].canvas.context.fillStyle = color_str;
|
||
|
||
this.surfaces[draw_fill.base.surface_id].canvas.context.fillRect(
|
||
draw_fill.base.box.left, draw_fill.base.box.top,
|
||
draw_fill.base.box.right - draw_fill.base.box.left,
|
||
draw_fill.base.box.bottom - draw_fill.base.box.top);
|
||
|
||
if (DUMP_DRAWS && this.parent.dump_id)
|
||
{
|
||
var debug_canvas = document.createElement("canvas");
|
||
debug_canvas.setAttribute('width', this.surfaces[draw_fill.base.surface_id].canvas.width);
|
||
debug_canvas.setAttribute('height', this.surfaces[draw_fill.base.surface_id].canvas.height);
|
||
debug_canvas.setAttribute('id', "fillbrush." + draw_fill.base.surface_id + "." + this.surfaces[draw_fill.base.surface_id].draw_count);
|
||
debug_canvas.getContext("2d").fillStyle = color_str;
|
||
debug_canvas.getContext("2d").fillRect(
|
||
draw_fill.base.box.left, draw_fill.base.box.top,
|
||
draw_fill.base.box.right - draw_fill.base.box.left,
|
||
draw_fill.base.box.bottom - draw_fill.base.box.top);
|
||
document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
|
||
}
|
||
|
||
this.surfaces[draw_fill.base.surface_id].draw_count++;
|
||
|
||
}
|
||
else
|
||
{
|
||
this.log_warn("FIXME: DrawFill can't handle brush type: " + draw_fill.data.brush.type);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_COPY_BITS)
|
||
{
|
||
var copy_bits = new SpiceMsgDisplayCopyBits(msg.data);
|
||
|
||
DEBUG > 1 && this.log_draw("CopyBits", copy_bits);
|
||
|
||
var source_canvas = this.surfaces[copy_bits.base.surface_id].canvas;
|
||
var source_context = source_canvas.context;
|
||
|
||
var width = source_canvas.width - copy_bits.src_pos.x;
|
||
var height = source_canvas.height - copy_bits.src_pos.y;
|
||
if (width > (copy_bits.base.box.right - copy_bits.base.box.left))
|
||
width = copy_bits.base.box.right - copy_bits.base.box.left;
|
||
if (height > (copy_bits.base.box.bottom - copy_bits.base.box.top))
|
||
height = copy_bits.base.box.bottom - copy_bits.base.box.top;
|
||
|
||
var source_img = source_context.getImageData(
|
||
copy_bits.src_pos.x, copy_bits.src_pos.y, width, height);
|
||
//source_context.putImageData(source_img, copy_bits.base.box.left, copy_bits.base.box.top);
|
||
putImageDataWithAlpha(source_context, source_img, copy_bits.base.box.left, copy_bits.base.box.top);
|
||
|
||
if (DUMP_DRAWS && this.parent.dump_id)
|
||
{
|
||
var debug_canvas = document.createElement("canvas");
|
||
debug_canvas.setAttribute('width', width);
|
||
debug_canvas.setAttribute('height', height);
|
||
debug_canvas.setAttribute('id', "copybits" + copy_bits.base.surface_id + "." + this.surfaces[copy_bits.base.surface_id].draw_count);
|
||
debug_canvas.getContext("2d").putImageData(source_img, 0, 0);
|
||
document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
|
||
}
|
||
|
||
|
||
this.surfaces[copy_bits.base.surface_id].draw_count++;
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES)
|
||
{
|
||
this.known_unimplemented(msg.type, "Inval All Palettes");
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_SURFACE_CREATE)
|
||
{
|
||
if (! ("surfaces" in this))
|
||
this.surfaces = [];
|
||
|
||
var m = new SpiceMsgSurfaceCreate(msg.data);
|
||
DEBUG > 1 && console.log(this.type + ": MsgSurfaceCreate id " + m.surface.surface_id
|
||
+ "; " + m.surface.width + "x" + m.surface.height
|
||
+ "; format " + m.surface.format
|
||
+ "; flags " + m.surface.flags);
|
||
if (m.surface.format != SPICE_SURFACE_FMT_32_xRGB &&
|
||
m.surface.format != SPICE_SURFACE_FMT_32_ARGB)
|
||
{
|
||
this.log_warn("FIXME: cannot handle surface format " + m.surface.format + " yet.");
|
||
return false;
|
||
}
|
||
|
||
var canvas = document.createElement("canvas");
|
||
canvas.setAttribute('width', m.surface.width);
|
||
canvas.setAttribute('height', m.surface.height);
|
||
canvas.setAttribute('id', "spice_surface_" + m.surface.surface_id);
|
||
canvas.setAttribute('tabindex', m.surface.surface_id);
|
||
canvas.context = canvas.getContext("2d");
|
||
|
||
if (DUMP_CANVASES && this.parent.dump_id)
|
||
document.getElementById(this.parent.dump_id).appendChild(canvas);
|
||
|
||
m.surface.canvas = canvas;
|
||
m.surface.draw_count = 0;
|
||
this.surfaces[m.surface.surface_id] = m.surface;
|
||
|
||
if (m.surface.flags & SPICE_SURFACE_FLAGS_PRIMARY)
|
||
{
|
||
this.primary_surface = m.surface.surface_id;
|
||
|
||
/* This .save() is done entirely to enable SPICE_MSG_DISPLAY_RESET */
|
||
canvas.context.save();
|
||
document.getElementById(this.parent.screen_id).appendChild(canvas);
|
||
document.getElementById(this.parent.screen_id).setAttribute('width', m.surface.width);
|
||
document.getElementById(this.parent.screen_id).setAttribute('height', m.surface.height);
|
||
this.hook_events();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_SURFACE_DESTROY)
|
||
{
|
||
var m = new SpiceMsgSurfaceDestroy(msg.data);
|
||
DEBUG > 1 && console.log(this.type + ": MsgSurfaceDestroy id " + m.surface_id);
|
||
this.delete_surface(m.surface_id);
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_STREAM_CREATE)
|
||
{
|
||
var m = new SpiceMsgDisplayStreamCreate(msg.data);
|
||
DEBUG > 1 && console.log(this.type + ": MsgStreamCreate id" + m.id);
|
||
if (!this.streams)
|
||
this.streams = new Array();
|
||
if (this.streams[m.id])
|
||
console.log("Stream already exists");
|
||
else
|
||
this.streams[m.id] = m;
|
||
if (m.codec_type != SPICE_VIDEO_CODEC_TYPE_MJPEG)
|
||
console.log("Unhandled stream codec: "+m.codec_type);
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA)
|
||
{
|
||
var m = new SpiceMsgDisplayStreamData(msg.data);
|
||
if (!this.streams[m.base.id])
|
||
{
|
||
console.log("no stream for data");
|
||
return false;
|
||
}
|
||
if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_MJPEG)
|
||
{
|
||
var tmpstr = "data:image/jpeg,";
|
||
var img = new Image;
|
||
var i;
|
||
for (i = 0; i < m.data.length; i++)
|
||
{
|
||
tmpstr += '%';
|
||
if (m.data[i] < 16)
|
||
tmpstr += '0';
|
||
tmpstr += m.data[i].toString(16);
|
||
}
|
||
var strm_base = new SpiceMsgDisplayBase();
|
||
strm_base.surface_id = this.streams[m.base.id].surface_id;
|
||
strm_base.box = this.streams[m.base.id].dest;
|
||
strm_base.clip = this.streams[m.base.id].clip;
|
||
img.o =
|
||
{ base: strm_base,
|
||
tag: "mjpeg." + m.base.id,
|
||
descriptor: null,
|
||
sc : this,
|
||
};
|
||
img.onload = handle_draw_jpeg_onload;
|
||
img.src = tmpstr;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_STREAM_CLIP)
|
||
{
|
||
var m = new SpiceMsgDisplayStreamClip(msg.data);
|
||
DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" + m.id);
|
||
this.streams[m.id].clip = m.clip;
|
||
return true;
|
||
}
|
||
|
||
if (msg.type == SPICE_MSG_DISPLAY_STREAM_DESTROY)
|
||
{
|
||
var m = new SpiceMsgDisplayStreamDestroy(msg.data);
|
||
DEBUG > 1 && console.log(this.type + ": MsgStreamDestroy id" + m.id);
|
||
this.streams[m.id] = undefined;
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
SpiceDisplayConn.prototype.delete_surface = function(surface_id)
|
||
{
|
||
var canvas = document.getElementById("spice_surface_" + surface_id);
|
||
if (DUMP_CANVASES && this.parent.dump_id)
|
||
document.getElementById(this.parent.dump_id).removeChild(canvas);
|
||
if (this.primary_surface == surface_id)
|
||
{
|
||
this.unhook_events();
|
||
this.primary_surface = undefined;
|
||
document.getElementById(this.parent.screen_id).removeChild(canvas);
|
||
}
|
||
|
||
delete this.surfaces[surface_id];
|
||
}
|
||
|
||
|
||
SpiceDisplayConn.prototype.draw_copy_helper = function(o)
|
||
{
|
||
|
||
var canvas = this.surfaces[o.base.surface_id].canvas;
|
||
if (o.has_alpha)
|
||
{
|
||
/* FIXME - This is based on trial + error, not a serious thoughtful
|
||
analysis of what Spice requires. See display.js for more. */
|
||
if (this.surfaces[o.base.surface_id].format == SPICE_SURFACE_FMT_32_xRGB)
|
||
{
|
||
stripAlpha(o.image_data);
|
||
canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
|
||
}
|
||
else
|
||
putImageDataWithAlpha(canvas.context, o.image_data,
|
||
o.base.box.left, o.base.box.top);
|
||
}
|
||
else
|
||
canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
|
||
|
||
if (o.src_area.left > 0 || o.src_area.top > 0)
|
||
{
|
||
this.log_warn("FIXME: DrawCopy not shifting draw copies just yet...");
|
||
}
|
||
|
||
if (o.descriptor && (o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
|
||
{
|
||
if (! ("cache" in this))
|
||
this.cache = [];
|
||
this.cache[o.descriptor.id] = o.image_data;
|
||
}
|
||
|
||
if (DUMP_DRAWS && this.parent.dump_id)
|
||
{
|
||
var debug_canvas = document.createElement("canvas");
|
||
debug_canvas.setAttribute('width', o.image_data.width);
|
||
debug_canvas.setAttribute('height', o.image_data.height);
|
||
debug_canvas.setAttribute('id', o.tag + "." +
|
||
this.surfaces[o.base.surface_id].draw_count + "." +
|
||
o.base.surface_id + "@" + o.base.box.left + "x" + o.base.box.top);
|
||
debug_canvas.getContext("2d").putImageData(o.image_data, 0, 0);
|
||
document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
|
||
}
|
||
|
||
this.surfaces[o.base.surface_id].draw_count++;
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
SpiceDisplayConn.prototype.log_draw = function(prefix, draw)
|
||
{
|
||
var str = prefix + "." + draw.base.surface_id + "." + this.surfaces[draw.base.surface_id].draw_count + ": ";
|
||
str += "base.box " + draw.base.box.left + ", " + draw.base.box.top + " to " +
|
||
draw.base.box.right + ", " + draw.base.box.bottom;
|
||
str += "; clip.type " + draw.base.clip.type;
|
||
|
||
if (draw.data)
|
||
{
|
||
if (draw.data.src_area)
|
||
str += "; src_area " + draw.data.src_area.left + ", " + draw.data.src_area.top + " to "
|
||
+ draw.data.src_area.right + ", " + draw.data.src_area.bottom;
|
||
|
||
if (draw.data.src_bitmap && draw.data.src_bitmap != null)
|
||
{
|
||
str += "; src_bitmap id: " + draw.data.src_bitmap.descriptor.id;
|
||
str += "; src_bitmap width " + draw.data.src_bitmap.descriptor.width + ", height " + draw.data.src_bitmap.descriptor.height;
|
||
str += "; src_bitmap type " + draw.data.src_bitmap.descriptor.type + ", flags " + draw.data.src_bitmap.descriptor.flags;
|
||
if (draw.data.src_bitmap.surface_id !== undefined)
|
||
str += "; src_bitmap surface_id " + draw.data.src_bitmap.surface_id;
|
||
if (draw.data.src_bitmap.quic)
|
||
str += "; QUIC type " + draw.data.src_bitmap.quic.type +
|
||
"; width " + draw.data.src_bitmap.quic.width +
|
||
"; height " + draw.data.src_bitmap.quic.height ;
|
||
if (draw.data.src_bitmap.lz_rgb)
|
||
str += "; LZ_RGB length " + draw.data.src_bitmap.lz_rgb.length +
|
||
"; magic " + draw.data.src_bitmap.lz_rgb.magic +
|
||
"; version 0x" + draw.data.src_bitmap.lz_rgb.version.toString(16) +
|
||
"; type " + draw.data.src_bitmap.lz_rgb.type +
|
||
"; width " + draw.data.src_bitmap.lz_rgb.width +
|
||
"; height " + draw.data.src_bitmap.lz_rgb.height +
|
||
"; stride " + draw.data.src_bitmap.lz_rgb.stride +
|
||
"; top down " + draw.data.src_bitmap.lz_rgb.top_down;
|
||
}
|
||
else
|
||
str += "; src_bitmap is null";
|
||
|
||
if (draw.data.brush)
|
||
{
|
||
if (draw.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
|
||
str += "; brush.color 0x" + draw.data.brush.color.toString(16);
|
||
if (draw.data.brush.type == SPICE_BRUSH_TYPE_PATTERN)
|
||
{
|
||
str += "; brush.pat ";
|
||
if (draw.data.brush.pattern.pat != null)
|
||
str += "[SpiceImage]";
|
||
else
|
||
str += "[null]";
|
||
str += " at " + draw.data.brush.pattern.pos.x + ", " + draw.data.brush.pattern.pos.y;
|
||
}
|
||
}
|
||
|
||
str += "; rop_descriptor " + draw.data.rop_descriptor;
|
||
if (draw.data.scale_mode !== undefined)
|
||
str += "; scale_mode " + draw.data.scale_mode;
|
||
str += "; mask.flags " + draw.data.mask.flags;
|
||
str += "; mask.pos " + draw.data.mask.pos.x + ", " + draw.data.mask.pos.y;
|
||
if (draw.data.mask.bitmap != null)
|
||
{
|
||
str += "; mask.bitmap width " + draw.data.mask.bitmap.descriptor.width + ", height " + draw.data.mask.bitmap.descriptor.height;
|
||
str += "; mask.bitmap type " + draw.data.mask.bitmap.descriptor.type + ", flags " + draw.data.mask.bitmap.descriptor.flags;
|
||
}
|
||
else
|
||
str += "; mask.bitmap is null";
|
||
}
|
||
|
||
console.log(str);
|
||
}
|
||
|
||
SpiceDisplayConn.prototype.hook_events = function()
|
||
{
|
||
if (this.primary_surface !== undefined)
|
||
{
|
||
var canvas = this.surfaces[this.primary_surface].canvas;
|
||
canvas.sc = this.parent;
|
||
canvas.addEventListener('mousemove', handle_mousemove);
|
||
canvas.addEventListener('mousedown', handle_mousedown);
|
||
canvas.addEventListener('contextmenu', handle_contextmenu);
|
||
canvas.addEventListener('mouseup', handle_mouseup);
|
||
canvas.addEventListener('keydown', handle_keydown);
|
||
canvas.addEventListener('keyup', handle_keyup);
|
||
canvas.addEventListener('mouseout', handle_mouseout);
|
||
canvas.addEventListener('mouseover', handle_mouseover);
|
||
canvas.addEventListener('mousewheel', handle_mousewheel);
|
||
canvas.focus();
|
||
}
|
||
}
|
||
|
||
SpiceDisplayConn.prototype.unhook_events = function()
|
||
{
|
||
if (this.primary_surface !== undefined)
|
||
{
|
||
var canvas = this.surfaces[this.primary_surface].canvas;
|
||
canvas.removeEventListener('mousemove', handle_mousemove);
|
||
canvas.removeEventListener('mousedown', handle_mousedown);
|
||
canvas.removeEventListener('contextmenu', handle_contextmenu);
|
||
canvas.removeEventListener('mouseup', handle_mouseup);
|
||
canvas.removeEventListener('keydown', handle_keydown);
|
||
canvas.removeEventListener('keyup', handle_keyup);
|
||
canvas.removeEventListener('mouseout', handle_mouseout);
|
||
canvas.removeEventListener('mouseover', handle_mouseover);
|
||
canvas.removeEventListener('mousewheel', handle_mousewheel);
|
||
}
|
||
}
|
||
|
||
|
||
SpiceDisplayConn.prototype.destroy_surfaces = function()
|
||
{
|
||
for (var s in this.surfaces)
|
||
{
|
||
this.delete_surface(this.surfaces[s].surface_id);
|
||
}
|
||
|
||
this.surfaces = undefined;
|
||
}
|
||
|
||
|
||
function handle_mouseover(e)
|
||
{
|
||
this.focus();
|
||
}
|
||
|
||
function handle_mouseout(e)
|
||
{
|
||
this.blur();
|
||
}
|
||
|
||
function handle_draw_jpeg_onload()
|
||
{
|
||
var temp_canvas = null;
|
||
var context;
|
||
|
||
/*------------------------------------------------------------
|
||
** FIXME:
|
||
** The helper should be extended to be able to handle actual HtmlImageElements
|
||
** ...and the cache should be modified to do so as well
|
||
**----------------------------------------------------------*/
|
||
if (this.o.sc.surfaces[this.o.base.surface_id] === undefined)
|
||
{
|
||
// This can happen; if the jpeg image loads after our surface
|
||
// has been destroyed (e.g. open a menu, close it quickly),
|
||
// we'll find we have no surface.
|
||
DEBUG > 2 && this.o.sc.log_info("Discarding jpeg; presumed lost surface " + this.o.base.surface_id);
|
||
temp_canvas = document.createElement("canvas");
|
||
temp_canvas.setAttribute('width', this.o.base.box.right);
|
||
temp_canvas.setAttribute('height', this.o.base.box.bottom);
|
||
context = temp_canvas.getContext("2d");
|
||
}
|
||
else
|
||
context = this.o.sc.surfaces[this.o.base.surface_id].canvas.context;
|
||
|
||
if (this.alpha_img)
|
||
{
|
||
var c = document.createElement("canvas");
|
||
var t = c.getContext("2d");
|
||
c.setAttribute('width', this.alpha_img.width);
|
||
c.setAttribute('height', this.alpha_img.height);
|
||
t.putImageData(this.alpha_img, 0, 0);
|
||
t.globalCompositeOperation = 'source-in';
|
||
t.drawImage(this, 0, 0);
|
||
|
||
context.drawImage(c, this.o.base.box.left, this.o.base.box.top);
|
||
|
||
if (this.o.descriptor &&
|
||
(this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
|
||
{
|
||
if (! ("cache" in this.o.sc))
|
||
this.o.sc.cache = [];
|
||
|
||
this.o.sc.cache[this.o.descriptor.id] =
|
||
t.getImageData(0, 0,
|
||
this.alpha_img.width,
|
||
this.alpha_img.height);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
context.drawImage(this, this.o.base.box.left, this.o.base.box.top);
|
||
|
||
if (this.o.descriptor &&
|
||
(this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
|
||
{
|
||
if (! ("cache" in this.o.sc))
|
||
this.o.sc.cache = [];
|
||
|
||
this.o.sc.cache[this.o.descriptor.id] =
|
||
context.getImageData(this.o.base.box.left, this.o.base.box.top,
|
||
this.o.base.box.right - this.o.base.box.left,
|
||
this.o.base.box.bottom - this.o.base.box.top);
|
||
}
|
||
}
|
||
|
||
if (temp_canvas == null)
|
||
{
|
||
if (DUMP_DRAWS && this.o.sc.parent.dump_id)
|
||
{
|
||
var debug_canvas = document.createElement("canvas");
|
||
debug_canvas.setAttribute('id', this.o.tag + "." +
|
||
this.o.sc.surfaces[this.o.base.surface_id].draw_count + "." +
|
||
this.o.base.surface_id + "@" + this.o.base.box.left + "x" + this.o.base.box.top);
|
||
debug_canvas.getContext("2d").drawImage(this, 0, 0);
|
||
document.getElementById(this.o.sc.parent.dump_id).appendChild(debug_canvas);
|
||
}
|
||
|
||
this.o.sc.surfaces[this.o.base.surface_id].draw_count++;
|
||
}
|
||
}
|
vendor/assets/javascripts/spice/enums.js | ||
---|---|---|
"use strict";
|
||
/*
|
||
Copyright (C) 2012 by Jeremy P. White <jwhite@codeweavers.com>
|
||
|
||
This file is part of spice-html5.
|
||
|
||
spice-html5 is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
spice-html5 is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
|
||
/*----------------------------------------------------------------------------
|
||
** enums.js
|
||
** 'constants' for Spice
|
||
**--------------------------------------------------------------------------*/
|
||
var SPICE_MAGIC = "REDQ";
|
||
var SPICE_VERSION_MAJOR = 2;
|
||
var SPICE_VERSION_MINOR = 2;
|
||
|
||
var SPICE_CONNECT_TIMEOUT = (30 * 1000);
|
||
|
||
var SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION = 0;
|
||
var SPICE_COMMON_CAP_AUTH_SPICE = 1;
|
||
var SPICE_COMMON_CAP_AUTH_SASL = 2;
|
||
var SPICE_COMMON_CAP_MINI_HEADER = 3;
|
||
|
||
var SPICE_TICKET_KEY_PAIR_LENGTH = 1024;
|
||
var SPICE_TICKET_PUBKEY_BYTES = (SPICE_TICKET_KEY_PAIR_LENGTH / 8 + 34);
|
||
|
||
var SPICE_LINK_ERR_OK = 0,
|
||
SPICE_LINK_ERR_ERROR = 1,
|
||
SPICE_LINK_ERR_INVALID_MAGIC = 2,
|
||
SPICE_LINK_ERR_INVALID_DATA = 3,
|
||
SPICE_LINK_ERR_VERSION_MISMATCH = 4,
|
||
SPICE_LINK_ERR_NEED_SECURED = 5,
|
||
SPICE_LINK_ERR_NEED_UNSECURED = 6,
|
||
SPICE_LINK_ERR_PERMISSION_DENIED = 7,
|
||
SPICE_LINK_ERR_BAD_CONNECTION_ID = 8,
|
||
SPICE_LINK_ERR_CHANNEL_NOT_AVAILABLE = 9;
|
||
|
||
var SPICE_MSG_MIGRATE = 1;
|
||
var SPICE_MSG_MIGRATE_DATA = 2;
|
||
var SPICE_MSG_SET_ACK = 3;
|
||
var SPICE_MSG_PING = 4;
|
||
var SPICE_MSG_WAIT_FOR_CHANNELS = 5;
|
||
var SPICE_MSG_DISCONNECTING = 6;
|
||
var SPICE_MSG_NOTIFY = 7;
|
||
var SPICE_MSG_LIST = 8;
|
||
|
||
var SPICE_MSG_MAIN_MIGRATE_BEGIN = 101;
|
||
var SPICE_MSG_MAIN_MIGRATE_CANCEL = 102;
|
||
var SPICE_MSG_MAIN_INIT = 103;
|
||
var SPICE_MSG_MAIN_CHANNELS_LIST = 104;
|
||
var SPICE_MSG_MAIN_MOUSE_MODE = 105;
|
||
var SPICE_MSG_MAIN_MULTI_MEDIA_TIME = 106;
|
||
var SPICE_MSG_MAIN_AGENT_CONNECTED = 107;
|
||
var SPICE_MSG_MAIN_AGENT_DISCONNECTED = 108;
|
||
var SPICE_MSG_MAIN_AGENT_DATA = 109;
|
||
var SPICE_MSG_MAIN_AGENT_TOKEN = 110;
|
||
var SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST = 111;
|
||
var SPICE_MSG_MAIN_MIGRATE_END = 112;
|
||
var SPICE_MSG_MAIN_NAME = 113;
|
||
var SPICE_MSG_MAIN_UUID = 114;
|
||
var SPICE_MSG_END_MAIN = 115;
|
||
|
||
|
||
var SPICE_MSGC_ACK_SYNC = 1;
|
||
var SPICE_MSGC_ACK = 2;
|
||
var SPICE_MSGC_PONG = 3;
|
||
var SPICE_MSGC_MIGRATE_FLUSH_MARK = 4;
|
||
var SPICE_MSGC_MIGRATE_DATA = 5;
|
||
var SPICE_MSGC_DISCONNECTING = 6;
|
||
|
||
|
||
var SPICE_MSGC_MAIN_CLIENT_INFO = 101;
|
||
var SPICE_MSGC_MAIN_MIGRATE_CONNECTED = 102;
|
||
var SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR = 103;
|
||
var SPICE_MSGC_MAIN_ATTACH_CHANNELS = 104;
|
||
var SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST = 105;
|
||
var SPICE_MSGC_MAIN_AGENT_START = 106;
|
||
var SPICE_MSGC_MAIN_AGENT_DATA = 107;
|
||
var SPICE_MSGC_MAIN_AGENT_TOKEN = 108;
|
||
var SPICE_MSGC_MAIN_MIGRATE_END = 109;
|
||
var SPICE_MSGC_END_MAIN = 110;
|
||
|
||
var SPICE_MSG_DISPLAY_MODE = 101;
|
||
var SPICE_MSG_DISPLAY_MARK = 102;
|
||
var SPICE_MSG_DISPLAY_RESET = 103;
|
||
var SPICE_MSG_DISPLAY_COPY_BITS = 104;
|
||
var SPICE_MSG_DISPLAY_INVAL_LIST = 105;
|
||
var SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS = 106;
|
||
var SPICE_MSG_DISPLAY_INVAL_PALETTE = 107;
|
||
var SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES= 108;
|
||
|
||
var SPICE_MSG_DISPLAY_STREAM_CREATE = 122;
|
||
var SPICE_MSG_DISPLAY_STREAM_DATA = 123;
|
||
var SPICE_MSG_DISPLAY_STREAM_CLIP = 124;
|
||
var SPICE_MSG_DISPLAY_STREAM_DESTROY = 125;
|
||
var SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL= 126;
|
||
|
||
var SPICE_MSG_DISPLAY_DRAW_FILL = 302;
|
||
var SPICE_MSG_DISPLAY_DRAW_OPAQUE = 303;
|
||
var SPICE_MSG_DISPLAY_DRAW_COPY = 304;
|
||
var SPICE_MSG_DISPLAY_DRAW_BLEND = 305;
|
||
var SPICE_MSG_DISPLAY_DRAW_BLACKNESS = 306;
|
||
var SPICE_MSG_DISPLAY_DRAW_WHITENESS = 307;
|
||
var SPICE_MSG_DISPLAY_DRAW_INVERS = 308;
|
||
var SPICE_MSG_DISPLAY_DRAW_ROP3 = 309;
|
||
var SPICE_MSG_DISPLAY_DRAW_STROKE = 310;
|
||
var SPICE_MSG_DISPLAY_DRAW_TEXT = 311;
|
||
var SPICE_MSG_DISPLAY_DRAW_TRANSPARENT = 312;
|
||
var SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND = 313;
|
||
var SPICE_MSG_DISPLAY_SURFACE_CREATE = 314;
|
||
var SPICE_MSG_DISPLAY_SURFACE_DESTROY = 315;
|
||
|
||
var SPICE_MSGC_DISPLAY_INIT = 101;
|
||
|
||
var SPICE_MSG_INPUTS_INIT = 101;
|
||
var SPICE_MSG_INPUTS_KEY_MODIFIERS = 102;
|
||
|
||
var SPICE_MSG_INPUTS_MOUSE_MOTION_ACK = 111;
|
||
|
||
var SPICE_MSGC_INPUTS_KEY_DOWN = 101;
|
||
var SPICE_MSGC_INPUTS_KEY_UP = 102;
|
||
var SPICE_MSGC_INPUTS_KEY_MODIFIERS = 103;
|
||
|
||
var SPICE_MSGC_INPUTS_MOUSE_MOTION = 111;
|
||
var SPICE_MSGC_INPUTS_MOUSE_POSITION = 112;
|
||
var SPICE_MSGC_INPUTS_MOUSE_PRESS = 113;
|
||
var SPICE_MSGC_INPUTS_MOUSE_RELEASE = 114;
|
||
|
||
var SPICE_MSG_CURSOR_INIT = 101;
|
||
var SPICE_MSG_CURSOR_RESET = 102;
|
||
var SPICE_MSG_CURSOR_SET = 103;
|
||
var SPICE_MSG_CURSOR_MOVE = 104;
|
||
var SPICE_MSG_CURSOR_HIDE = 105;
|
||
var SPICE_MSG_CURSOR_TRAIL = 106;
|
||
var SPICE_MSG_CURSOR_INVAL_ONE = 107;
|
||
var SPICE_MSG_CURSOR_INVAL_ALL = 108;
|
||
|
||
|
||
var SPICE_CHANNEL_MAIN = 1;
|
||
var SPICE_CHANNEL_DISPLAY = 2;
|
||
var SPICE_CHANNEL_INPUTS = 3;
|
||
var SPICE_CHANNEL_CURSOR = 4;
|
||
var SPICE_CHANNEL_PLAYBACK = 5;
|
||
var SPICE_CHANNEL_RECORD = 6;
|
||
var SPICE_CHANNEL_TUNNEL = 7;
|
||
var SPICE_CHANNEL_SMARTCARD = 8;
|
||
var SPICE_CHANNEL_USBREDIR = 9;
|
||
|
||
var SPICE_SURFACE_FLAGS_PRIMARY = (1 << 0);
|
||
|
||
var SPICE_NOTIFY_SEVERITY_INFO = 0;
|
||
var SPICE_NOTIFY_SEVERITY_WARN = 1;
|
||
var SPICE_NOTIFY_SEVERITY_ERROR = 2;
|
||
|
||
var SPICE_MOUSE_MODE_SERVER = (1 << 0),
|
||
SPICE_MOUSE_MODE_CLIENT = (1 << 1),
|
||
SPICE_MOUSE_MODE_MASK = 0x3;
|
||
|
||
var SPICE_CLIP_TYPE_NONE = 0;
|
||
var SPICE_CLIP_TYPE_RECTS = 1;
|
||
|
||
var SPICE_IMAGE_TYPE_BITMAP = 0;
|
||
var SPICE_IMAGE_TYPE_QUIC = 1;
|
||
var SPICE_IMAGE_TYPE_RESERVED = 2;
|
||
var SPICE_IMAGE_TYPE_LZ_PLT = 100;
|
||
var SPICE_IMAGE_TYPE_LZ_RGB = 101;
|
||
var SPICE_IMAGE_TYPE_GLZ_RGB = 102;
|
||
var SPICE_IMAGE_TYPE_FROM_CACHE = 103;
|
||
var SPICE_IMAGE_TYPE_SURFACE = 104;
|
||
var SPICE_IMAGE_TYPE_JPEG = 105;
|
||
var SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS = 106;
|
||
var SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB = 107;
|
||
var SPICE_IMAGE_TYPE_JPEG_ALPHA = 108;
|
||
|
||
var SPICE_IMAGE_FLAGS_CACHE_ME = (1 << 0),
|
||
SPICE_IMAGE_FLAGS_HIGH_BITS_SET = (1 << 1),
|
||
SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME = (1 << 2);
|
||
|
||
var SPICE_BITMAP_FLAGS_PAL_CACHE_ME = (1 << 0),
|
||
SPICE_BITMAP_FLAGS_PAL_FROM_CACHE = (1 << 1),
|
||
SPICE_BITMAP_FLAGS_TOP_DOWN = (1 << 2),
|
||
SPICE_BITMAP_FLAGS_MASK = 0x7;
|
||
|
||
var SPICE_BITMAP_FMT_INVALID = 0,
|
||
SPICE_BITMAP_FMT_1BIT_LE = 1,
|
||
SPICE_BITMAP_FMT_1BIT_BE = 2,
|
||
SPICE_BITMAP_FMT_4BIT_LE = 3,
|
||
SPICE_BITMAP_FMT_4BIT_BE = 4,
|
||
SPICE_BITMAP_FMT_8BIT = 5,
|
||
SPICE_BITMAP_FMT_16BIT = 6,
|
||
SPICE_BITMAP_FMT_24BIT = 7,
|
||
SPICE_BITMAP_FMT_32BIT = 8,
|
||
SPICE_BITMAP_FMT_RGBA = 9;
|
||
|
||
|
||
var SPICE_CURSOR_FLAGS_NONE = (1 << 0),
|
||
SPICE_CURSOR_FLAGS_CACHE_ME = (1 << 1),
|
||
SPICE_CURSOR_FLAGS_FROM_CACHE = (1 << 2),
|
||
SPICE_CURSOR_FLAGS_MASK = 0x7;
|
||
|
||
var SPICE_MOUSE_BUTTON_MASK_LEFT = (1 << 0),
|
||
SPICE_MOUSE_BUTTON_MASK_MIDDLE = (1 << 1),
|
||
SPICE_MOUSE_BUTTON_MASK_RIGHT = (1 << 2),
|
||
SPICE_MOUSE_BUTTON_MASK_MASK = 0x7;
|
||
|
||
var SPICE_MOUSE_BUTTON_INVALID = 0;
|
||
var SPICE_MOUSE_BUTTON_LEFT = 1;
|
||
var SPICE_MOUSE_BUTTON_MIDDLE = 2;
|
||
var SPICE_MOUSE_BUTTON_RIGHT = 3;
|
||
var SPICE_MOUSE_BUTTON_UP = 4;
|
||
var SPICE_MOUSE_BUTTON_DOWN = 5;
|
||
|
||
var SPICE_BRUSH_TYPE_NONE = 0,
|
||
SPICE_BRUSH_TYPE_SOLID = 1,
|
||
SPICE_BRUSH_TYPE_PATTERN = 2;
|
||
|
||
var SPICE_SURFACE_FMT_INVALID = 0,
|
||
SPICE_SURFACE_FMT_1_A = 1,
|
||
SPICE_SURFACE_FMT_8_A = 8,
|
||
SPICE_SURFACE_FMT_16_555 = 16,
|
||
SPICE_SURFACE_FMT_32_xRGB = 32,
|
||
SPICE_SURFACE_FMT_16_565 = 80,
|
||
SPICE_SURFACE_FMT_32_ARGB = 96;
|
||
|
||
var SPICE_ROPD_INVERS_SRC = (1 << 0),
|
||
SPICE_ROPD_INVERS_BRUSH = (1 << 1),
|
||
SPICE_ROPD_INVERS_DEST = (1 << 2),
|
||
SPICE_ROPD_OP_PUT = (1 << 3),
|
||
SPICE_ROPD_OP_OR = (1 << 4),
|
||
SPICE_ROPD_OP_AND = (1 << 5),
|
||
SPICE_ROPD_OP_XOR = (1 << 6),
|
||
SPICE_ROPD_OP_BLACKNESS = (1 << 7),
|
||
SPICE_ROPD_OP_WHITENESS = (1 << 8),
|
||
SPICE_ROPD_OP_INVERS = (1 << 9),
|
||
SPICE_ROPD_INVERS_RES = (1 << 10),
|
||
SPICE_ROPD_MASK = 0x7ff;
|
||
|
||
var LZ_IMAGE_TYPE_INVALID = 0,
|
||
LZ_IMAGE_TYPE_PLT1_LE = 1,
|
||
LZ_IMAGE_TYPE_PLT1_BE = 2, // PLT stands for palette
|
||
LZ_IMAGE_TYPE_PLT4_LE = 3,
|
||
LZ_IMAGE_TYPE_PLT4_BE = 4,
|
||
LZ_IMAGE_TYPE_PLT8 = 5,
|
||
LZ_IMAGE_TYPE_RGB16 = 6,
|
||
LZ_IMAGE_TYPE_RGB24 = 7,
|
||
LZ_IMAGE_TYPE_RGB32 = 8,
|
||
LZ_IMAGE_TYPE_RGBA = 9,
|
||
LZ_IMAGE_TYPE_XXXA = 10;
|
||
|
||
|
||
var QUIC_IMAGE_TYPE_INVALID = 0,
|
||
QUIC_IMAGE_TYPE_GRAY = 1,
|
||
QUIC_IMAGE_TYPE_RGB16 = 2,
|
||
QUIC_IMAGE_TYPE_RGB24 = 3,
|
||
QUIC_IMAGE_TYPE_RGB32 = 4,
|
||
QUIC_IMAGE_TYPE_RGBA = 5;
|
||
|
||
var SPICE_INPUT_MOTION_ACK_BUNCH = 4;
|
||
|
||
|
||
var SPICE_CURSOR_TYPE_ALPHA = 0,
|
||
SPICE_CURSOR_TYPE_MONO = 1,
|
||
SPICE_CURSOR_TYPE_COLOR4 = 2,
|
||
SPICE_CURSOR_TYPE_COLOR8 = 3,
|
||
SPICE_CURSOR_TYPE_COLOR16 = 4,
|
||
SPICE_CURSOR_TYPE_COLOR24 = 5,
|
||
SPICE_CURSOR_TYPE_COLOR32 = 6;
|
||
|
||
var SPICE_VIDEO_CODEC_TYPE_MJPEG = 1;
|
Also available in: Unified diff
moved spice console to spice-html5-rails gem