This commit is contained in:
rustdesk 2021-07-25 21:04:11 +08:00
parent bebe136834
commit 879c300563
2 changed files with 54 additions and 29 deletions

View File

@ -139,12 +139,13 @@ pub fn get_cursor_data(hcursor: u64) -> ResultType<CursorData> {
width, width,
height, height,
bm_mask.bmWidthBytes, bm_mask.bmWidthBytes,
bm_mask.bmHeight,
) > 0; ) > 0;
} }
if do_outline { if do_outline {
let mut outline = Vec::new(); let mut outline = Vec::new();
outline.resize(((width + 2) * (height + 2) * 4) as _, 0); outline.resize(((width + 2) * (height + 2) * 4) as _, 0);
drawOutline(outline.as_mut_ptr(), cbits.as_ptr(), width, height); drawOutline(outline.as_mut_ptr(), cbits.as_ptr(), width, height, outline.len() as _);
cbits = outline; cbits = outline;
width += 2; width += 2;
height += 2; height += 2;
@ -285,7 +286,7 @@ fn fix_cursor_mask(
cbits: &mut Vec<u8>, cbits: &mut Vec<u8>,
width: usize, width: usize,
height: usize, height: usize,
width_bytes: usize, bm_width_bytes: usize,
) -> bool { ) -> bool {
let mut pix_idx = 0; let mut pix_idx = 0;
for _ in 0..height { for _ in 0..height {
@ -298,12 +299,18 @@ fn fix_cursor_mask(
} }
let packed_width_bytes = (width + 7) >> 3; let packed_width_bytes = (width + 7) >> 3;
let bm_size = mbits.len();
let c_size = cbits.len();
// Pack and invert bitmap data (mbits) // Pack and invert bitmap data (mbits)
// borrow from tigervnc // borrow from tigervnc
for y in 0..height { for y in 0..height {
for x in 0..packed_width_bytes { for x in 0..packed_width_bytes {
mbits[y * packed_width_bytes + x] = !mbits[y * width_bytes + x]; let a = y * packed_width_bytes + x;
let b = y * bm_width_bytes + x;
if a < bm_size && b < bm_size {
mbits[a] = !mbits[b];
}
} }
} }
@ -315,15 +322,23 @@ fn fix_cursor_mask(
let mut bitmask: u8 = 0x80; let mut bitmask: u8 = 0x80;
for x in 0..width { for x in 0..width {
let mask_idx = y * packed_width_bytes + (x >> 3); let mask_idx = y * packed_width_bytes + (x >> 3);
let pix_idx = y * bytes_row + (x << 2); if mask_idx < bm_size {
if (mbits[mask_idx] & bitmask) == 0 { let pix_idx = y * bytes_row + (x << 2);
for b1 in 0..4 { if (mbits[mask_idx] & bitmask) == 0 {
if cbits[pix_idx + b1] != 0 { for b1 in 0..4 {
mbits[mask_idx] ^= bitmask; let a = pix_idx + b1;
for b2 in b1..4 { if a < c_size {
cbits[pix_idx + b2] = 0x00; if cbits[a] != 0 {
mbits[mask_idx] ^= bitmask;
for b2 in b1..4 {
let b = pix_idx + b2;
if b < c_size {
cbits[b] = 0x00;
}
}
break;
}
} }
break;
} }
} }
} }
@ -339,11 +354,12 @@ fn fix_cursor_mask(
for y in 0..height { for y in 0..height {
for x in 0..width { for x in 0..width {
let mask_idx = y * packed_width_bytes + (x >> 3); let mask_idx = y * packed_width_bytes + (x >> 3);
let alpha = if (mbits[mask_idx] << (x & 0x7)) & 0x80 == 0 { let mut alpha = 255;
0 if mask_idx < bm_size {
} else { if (mbits[mask_idx] << (x & 0x7)) & 0x80 == 0 {
255 alpha = 0;
}; }
}
let a = cbits[pix_idx + 2]; let a = cbits[pix_idx + 2];
let b = cbits[pix_idx + 1]; let b = cbits[pix_idx + 1];
let c = cbits[pix_idx]; let c = cbits[pix_idx];
@ -377,9 +393,9 @@ extern "C" {
fn LaunchProcessWin(cmd: *const u16, session_id: DWORD, as_user: BOOL) -> HANDLE; fn LaunchProcessWin(cmd: *const u16, session_id: DWORD, as_user: BOOL) -> HANDLE;
fn selectInputDesktop() -> BOOL; fn selectInputDesktop() -> BOOL;
fn inputDesktopSelected() -> BOOL; fn inputDesktopSelected() -> BOOL;
fn handleMask(out: *mut u8, mask: *const u8, width: i32, height: i32, bmWidthBytes: i32) fn handleMask(out: *mut u8, mask: *const u8, width: i32, height: i32, bmWidthBytes: i32, bmHeight: i32)
-> i32; -> i32;
fn drawOutline(out: *mut u8, in_: *const u8, width: i32, height: i32); fn drawOutline(out: *mut u8, in_: *const u8, width: i32, height: i32, out_size: i32);
fn get_di_bits(out: *mut u8, dc: HDC, hbmColor: HBITMAP, width: i32, height: i32) -> i32; fn get_di_bits(out: *mut u8, dc: HDC, hbmColor: HBITMAP, width: i32, height: i32) -> i32;
fn blank_screen(v: BOOL); fn blank_screen(v: BOOL);
fn BlockInput(v: BOOL) -> BOOL; fn BlockInput(v: BOOL) -> BOOL;

View File

@ -192,10 +192,13 @@ extern "C"
return true; return true;
} }
int handleMask(uint8_t *rwbuffer, const uint8_t *mask, int width, int height, int bmWidthBytes) int handleMask(uint8_t *rwbuffer, const uint8_t *mask, int width, int height, int bmWidthBytes, int bmHeight)
{ {
auto andMask = mask; auto andMask = mask;
auto xorMask = mask + height * bmWidthBytes; auto andMaskSize = bmWidthBytes * bmHeight;
auto offset = height * bmWidthBytes;
auto xorMask = mask + offset;
auto xorMaskSize = andMaskSize - offset;
int doOutline = 0; int doOutline = 0;
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
@ -204,7 +207,7 @@ extern "C"
int byte = y * bmWidthBytes + x / 8; int byte = y * bmWidthBytes + x / 8;
int bit = 7 - x % 8; int bit = 7 - x % 8;
if (!(andMask[byte] & (1 << bit))) if (byte < andMaskSize && !(andMask[byte] & (1 << bit)))
{ {
// Valid pixel, so make it opaque // Valid pixel, so make it opaque
rwbuffer[3] = 0xff; rwbuffer[3] = 0xff;
@ -215,7 +218,7 @@ extern "C"
else else
rwbuffer[0] = rwbuffer[1] = rwbuffer[2] = 0; rwbuffer[0] = rwbuffer[1] = rwbuffer[2] = 0;
} }
else if (xorMask[byte] & (1 << bit)) else if (byte < xorMaskSize && xorMask[byte] & (1 << bit))
{ {
// Replace any XORed pixels with black, because RFB doesn't support // Replace any XORed pixels with black, because RFB doesn't support
// XORing of cursors. XORing is used for the I-beam cursor, which is most // XORing of cursors. XORing is used for the I-beam cursor, which is most
@ -240,10 +243,12 @@ extern "C"
return doOutline; return doOutline;
} }
void drawOutline(uint8_t *out0, const uint8_t *in0, int width, int height) void drawOutline(uint8_t *out0, const uint8_t *in0, int width, int height, int out0_size)
{ {
auto in = in0; auto in = in0;
auto out = out0 + width * 4 + 4; auto out0_end = out0 + out0_size;
auto offset = width * 4 + 4;
auto out = out0 + offset;
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
@ -251,12 +256,16 @@ extern "C"
// Visible pixel? // Visible pixel?
if (in[3] > 0) if (in[3] > 0)
{ {
auto n = 4 * 3;
auto p = out - (width + 2) * 4 - 4;
// Outline above... // Outline above...
memset(out - (width + 2) * 4 - 4, 0xff, 4 * 3); if (p >= out0 && p + n <= out0_end) memset(p, 0xff, n);
// ...besides... // ...besides...
memset(out - 4, 0xff, 4 * 3); p = out - 4;
if (p + n <= out0_end) memset(p, 0xff, n);
// ...and above // ...and above
memset(out + (width + 2) * 4 - 4, 0xff, 4 * 3); p = out + (width + 2) * 4 - 4;
if (p + n <= out0_end) memset(p, 0xff, n);
} }
in += 4; in += 4;
out += 4; out += 4;
@ -267,12 +276,12 @@ extern "C"
// Pass 2, overwrite with actual cursor // Pass 2, overwrite with actual cursor
in = in0; in = in0;
out = out0 + width * 4 + 4; out = out0 + offset;
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
{ {
if (in[3] > 0) if (in[3] > 0 && out + 4 <= out0_end)
memcpy(out, in, 4); memcpy(out, in, 4);
in += 4; in += 4;
out += 4; out += 4;