Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
libvncserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
rasky
libvncserver
Commits
1ce94186
Commit
1ce94186
authored
Mar 20, 2005
by
runge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
x11vnc: scale cursors, speed up some scaling, alt arrows, -norepeat N
parent
fba6f58a
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1963 additions
and
1145 deletions
+1963
-1145
ChangeLog
ChangeLog
+4
-0
ChangeLog
x11vnc/ChangeLog
+9
-0
README
x11vnc/README
+828
-654
tkx11vnc
x11vnc/tkx11vnc
+3
-2
tkx11vnc.h
x11vnc/tkx11vnc.h
+3
-2
x11vnc.1
x11vnc/x11vnc.1
+52
-24
x11vnc.c
x11vnc/x11vnc.c
+1064
-463
No files found.
ChangeLog
View file @
1ce94186
2005-03-19 Karl Runge <runge@karlrunge.com>
* x11vnc: scale cursors by default, -scale_cursor to tune,
-arrow n, -norepeat n, speed up integer magnification.
2005-03-12 Karl Runge <runge@karlrunge.com>
* x11vnc: X DAMAGE support, -clip WxH+X+Y, identd.
...
...
x11vnc/ChangeLog
View file @
1ce94186
2005-03-19 Karl Runge <runge@karlrunge.com>
* scale cursors along with display. Use -scale_cursor to change
or disable cursor scaling.
* speed up scaling in some cases, :nb and integer magnification.
* provide alternative arrow cursors (1-6) via -arrow n.
* reset no autorepeat a couple times if something turns it off,
set with -norepeat N.
* do not take a nap if DAMAGE seems to be doing its job.
2005-03-12 Karl Runge <runge@karlrunge.com>
* support for the X DAMAGE extension to receive damage
rectangle reports from the X server. On by default, disable
...
...
x11vnc/README
View file @
1ce94186
This source diff could not be displayed because it is too large. You can
view the blob
instead.
x11vnc/tkx11vnc
View file @
1ce94186
...
...
@@ -107,6 +107,7 @@ Screen
id:
sid:
=D scale:
scale_cursor:
--
overlay
overlay_nocursor
...
...
@@ -140,6 +141,7 @@ Keyboard
Pointer
=D-C:none,arrow,X,some,most cursor:
=-C:1,2,3,4,5,6 arrow:
--
cursorpos
=D nocursorshape
...
...
@@ -239,9 +241,8 @@ Tuning
snapfb
--
xdamage
xd_mem:
xd_area:
xd_
width
:
xd_
mem
:
--
threads
--
...
...
x11vnc/tkx11vnc.h
View file @
1ce94186
...
...
@@ -113,6 +113,7 @@
" id:
\n
"
" sid:
\n
"
" =D scale:
\n
"
" scale_cursor:
\n
"
" --
\n
"
" overlay
\n
"
" overlay_nocursor
\n
"
...
...
@@ -146,6 +147,7 @@
"
\n
"
"Pointer
\n
"
" =D-C:none,arrow,X,some,most cursor:
\n
"
" =-C:1,2,3,4,5,6 arrow:
\n
"
" --
\n
"
" cursorpos
\n
"
" =D nocursorshape
\n
"
...
...
@@ -245,9 +247,8 @@
" snapfb
\n
"
" --
\n
"
" xdamage
\n
"
" xd_mem:
\n
"
" xd_area:
\n
"
" xd_
width
:
\n
"
" xd_
mem
:
\n
"
" --
\n
"
" threads
\n
"
" --
\n
"
...
...
x11vnc/x11vnc.1
View file @
1ce94186
...
...
@@ -2,7 +2,7 @@
.TH X11VNC "1" "March 2005" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.7.2pre, lastmod: 2005-03-1
2
version: 0.7.2pre, lastmod: 2005-03-1
9
.SH SYNOPSIS
.B x11vnc
[OPTION]...
...
...
@@ -119,7 +119,7 @@ or 0x hex. Run
.IR xdpyinfo (1)
for the values. One may
also use "TrueColor", etc. see <X11/X.h> for a list.
If the string ends in ":m" the for better or for
If the string ends in ":m" the
n
for better or for
worse the visual depth is forced to be m.
.PP
\fB-overlay\fR
...
...
@@ -163,9 +163,8 @@ cursor shape using the overlay mechanism.
\fB-scale\fR \fIfraction\fR
.IP
Scale the framebuffer by factor \fIfraction\fR. Values
less than 1 shrink the fb, larger ones expand it.
Note: image may not be sharp and response may be
slower. Currently the cursor shape is not scaled.
less than 1 shrink the fb, larger ones expand it. Note:
image may not be sharp and response may be slower.
If \fIfraction\fR contains a decimal point "." it
is taken as a floating point number, alternatively
the notation "m/n" may be used to denote fractions
...
...
@@ -182,6 +181,17 @@ interpolation scheme even when shrinking, ":pad",
pad scaled width and height to be multiples of scaling
denominator (e.g. 3 for 2/3).
.PP
\fB-scale_cursor\fR \fIfrac\fR
.IP
By default if \fB-scale\fR is supplied the cursor shape is
scaled by the same factor. Depending on your usage,
you may want to scale the cursor independently of the
screen or not at all. If you specify \fB-scale_cursor\fR
the cursor will be scaled by that factor. When using
\fB-scale\fR mode to keep the cursor at its "natural" size
use "\fB-scale_cursor\fR \fI1\fR". Most of the ":" scaling
options apply here as well.
.PP
\fB-viewonly\fR
.IP
All VNC clients can only watch (default off).
...
...
@@ -686,6 +696,11 @@ either from large screen changes or high latency).
Note: your VNC viewer side will likely do autorepeating,
so this is no loss unless someone is simultaneously at
the real X display. Default: \fB-norepeat\fR
.IP
Use "\fB-norepeat\fR \fIN\fR" to set how many times norepeat will
be reset if something else (e.g. X session manager)
disables it. The default is 2. Use a negative value
for unlimited resets.
.PP
\fB-nofb\fR
.IP
...
...
@@ -780,6 +795,11 @@ unless the display has overlay visuals or XFIXES
extensions available. On Solaris and IRIX if XFIXES
is not available, \fB-overlay\fR mode will be attempted.
.PP
\fB-arrow\fR \fIn\fR
.IP
Choose an alternate "arrow" cursor from a set of
some common ones. n can be 1 to 6. Default is: 1
.PP
\fB-noxfixes\fR
.IP
Do not use the XFIXES extension to draw the exact cursor
...
...
@@ -1195,6 +1215,10 @@ id:windowid set \fB-id\fR window to "windowid". empty
.IP
sid:windowid set \fB-sid\fR window to "windowid"
.IP
waitmapped wait until subwin is mapped.
.IP
nowaitmapped do not wait until subwin is mapped.
.IP
clip:WxH+X+Y set \fB-clip\fR mode to "WxH+X+Y"
.IP
flashcmap enable \fB-flashcmap\fR mode.
...
...
@@ -1218,6 +1242,8 @@ visual:vis set \fB-visual\fR to "vis"
.IP
scale:frac set \fB-scale\fR to "frac"
.IP
scale_cursor:f set \fB-scale_cursor\fR to "f"
.IP
viewonly enable \fB-viewonly\fR mode.
.IP
noviewonly disable \fB-viewonly\fR mode.
...
...
@@ -1375,6 +1401,8 @@ show_cursor enable showing a cursor.
noshow_cursor disable showing a cursor. (same as
"nocursor")
.IP
arrow:n set \fB-arrow\fR to alternate n.
.IP
xfixes enable xfixes cursor shape mode.
.IP
noxfixes disable xfixes cursor shape mode.
...
...
@@ -1546,27 +1574,27 @@ remote command, we hope the name makes it obvious what
the returned value corresponds to (hint: the ext_*
variables correspond to the presence of X extensions):
.IP
ans= stop quit exit shutdown ping blacken zero
re
fresh reset close disconnect id sid clip
waitmapped
nowaitmapped
flashcmap noflashcmap truecolor notruecolor
ans= stop quit exit shutdown ping blacken zero
refresh
re
set close disconnect id sid waitmapped no
waitmapped
clip
flashcmap noflashcmap truecolor notruecolor
overlay nooverlay overlay_cursor overlay_yescursor
nooverlay_nocursor nooverlay_cursor nooverlay_yescursor
overlay_nocursor visual scale
viewonly no
viewonly
shared noshared forever noforever once timeout deny
lock nodeny unlock connect allowonce allow localhost
nolocalhost listen accept gone shm noshm flipbyteorder
noflipbyteorder onetile noonetile solid_color solid
no
solid blackout xinerama noxinerama xrandr noxrandr
xrandr_mode padgeom quiet q noquiet modtweak nomodtweak
xkb noxkb skip_keycodes add_keysyms noadd_keysym
s
clear_mods noclear_mods clear_keys noclear_key
s
remap repeat norepeat fb nofb bell nobell sel
nosel primary noprimary cursorshape no
cursorshape
cursorpos nocursorpos cursor show_cursor no
show_cursor
no
cursor xfixes noxfixes xdamage noxdamage xd_area
xd_mem alphacut alphafrac alpharemove no
alpharemove
alphablend noalphablend xwarp xwarppointer noxwarp
noxwarppointer buttonmap dragging nodragging
overlay_nocursor visual scale
scale_cursor
viewonly
noviewonly shared noshared forever noforever once
timeout deny lock nodeny unlock connect allowonce
allow localhost nolocalhost listen accept gone
shm noshm flipbyteorder noflipbyteorder onetile
no
onetile solid_color solid nosolid blackout xinerama
noxinerama xrandr noxrandr xrandr_mode padgeom quiet
q noquiet modtweak nomodtweak xkb noxkb skip_keycode
s
add_keysyms noadd_keysyms clear_mods noclear_mod
s
clear_keys noclear_keys remap repeat norepeat fb nofb
bell nobell sel nosel primary noprimary
cursorshape
nocursorshape cursorpos nocursorpos cursor
show_cursor
no
show_cursor nocursor arrow xfixes noxfixes xdamage
noxdamage xd_area xd_mem alphacut alphafrac
alpharemove
noalpharemove alphablend noalphablend xwarp xwarppointer
noxwarp
noxwarp
pointer buttonmap dragging nodragging
pointer_mode pm input_skip input client_input speeds
debug_pointer dp nodebug_pointer nodp debug_keyboard dk
nodebug_keyboard nodk deferupdate defer wait rfbwait
...
...
x11vnc/x11vnc.c
View file @
1ce94186
...
...
@@ -314,7 +314,6 @@ int overlay_present = 0;
static
int
xrandr_base_event_type
;
#endif
#define CURSOR_TRANSPARENCY 1
int
xfixes_present
=
0
;
int
use_xfixes
=
1
;
int
got_xfixes_cursor_notify
=
0
;
...
...
@@ -323,6 +322,8 @@ double alpha_frac = 0.33;
int
alpha_remove
=
0
;
int
alpha_blend
=
1
;
int
alt_arrow
=
1
;
#if LIBVNCSERVER_HAVE_LIBXFIXES
#include <X11/extensions/Xfixes.h>
static
int
xfixes_base_event_type
;
...
...
@@ -343,7 +344,7 @@ int xdamage_tile_count;
int
hack_val
=
0
;
/* date +'lastmod: %Y-%m-%d' */
char
lastmod
[]
=
"0.7.2pre lastmod: 2005-03-1
2
"
;
char
lastmod
[]
=
"0.7.2pre lastmod: 2005-03-1
9
"
;
/* X display info */
...
...
@@ -436,6 +437,15 @@ int scaling_interpolate = 0; /* use interpolation scheme when shrinking */
int
scaled_x
=
0
,
scaled_y
=
0
;
/* dimensions of scaled display */
int
scale_numer
=
0
,
scale_denom
=
0
;
/* n/m */
/* scale cursor */
char
*
scale_cursor_str
=
NULL
;
double
scale_cursor_fac
=
1
.
0
;
int
scaling_cursor
=
0
;
int
scaling_cursor_noblend
=
0
;
int
scaling_cursor_interpolate
=
0
;
int
scale_cursor_numer
=
0
,
scale_cursor_denom
=
0
;
/* size of the basic tile unit that is polled for changes: */
int
tile_x
=
32
;
int
tile_y
=
32
;
...
...
@@ -492,6 +502,7 @@ int scanlines[NSCAN] = {
int
all_clients_initialized
(
void
);
void
close_all_clients
(
void
);
void
close_clients
(
char
*
);
int
get_autorepeat_state
(
void
);
void
autorepeat
(
int
restore
);
char
*
bitprint
(
unsigned
int
,
int
);
void
blackout_tiles
(
void
);
...
...
@@ -576,6 +587,7 @@ void set_cursor(int, int, int);
void
setup_cursors
(
void
);
void
setup_cursors_and_push
(
void
);
void
first_cursor
(
void
);
rfbCursorPtr
pixels2curs
(
unsigned
long
*
,
int
,
int
,
int
,
int
,
int
);
void
set_no_cursor
(
void
);
void
set_cursor_was_changed
(
rfbScreenInfoPtr
);
void
set_cursor_was_moved
(
rfbScreenInfoPtr
);
...
...
@@ -611,6 +623,13 @@ char *get_local_host(int sock);
void
xcut_receive
(
char
*
text
,
int
len
,
rfbClientPtr
client
);
void
parse_scale_string
(
char
*
,
double
*
,
int
*
,
int
*
,
int
*
,
int
*
,
int
*
,
int
*
,
int
*
);
void
scale_rect
(
double
,
int
,
int
,
int
,
char
*
,
int
,
char
*
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
);
int
scale_round
(
int
,
double
);
void
zero_fb
(
int
,
int
,
int
,
int
);
void
push_black_screen
(
int
);
void
push_sleep
(
int
);
...
...
@@ -698,6 +717,7 @@ int cursor_shape_updates = 1; /* cursor shape updates -nocursorshape */
int
use_xwarppointer
=
0
;
/* use XWarpPointer instead of XTestFake... */
int
show_dragging
=
1
;
/* process mouse movement events */
int
no_autorepeat
=
1
;
/* turn off autorepeat with clients */
int
no_repeat_countdown
=
2
;
int
watch_bell
=
1
;
/* watch for the bell using XKEYBOARD */
int
sound_bell
=
1
;
/* actually send it */
int
xkbcompat
=
0
;
/* ignore XKEYBOARD extension */
...
...
@@ -2889,6 +2909,7 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) {
rfbLog
(
"running command:
\n
"
);
rfbLog
(
" %s
\n
"
,
cmd
);
/* XXX need to close port 5900, etc.. */
rc
=
system
(
cmd
);
if
(
rc
>=
256
)
{
...
...
@@ -4152,8 +4173,16 @@ void clear_keys(void) {
* keystroke autorepeating as well, it kind of makes sense to shut it
* off if no one is at the physical display...
*/
void
autorepeat
(
int
restore
)
{
int
get_autorepeat_state
(
void
)
{
XKeyboardState
kstate
;
X_LOCK
;
XGetKeyboardControl
(
dpy
,
&
kstate
);
X_UNLOCK
;
return
kstate
.
global_auto_repeat
;
}
void
autorepeat
(
int
restore
)
{
int
global_auto_repeat
;
XKeyboardControl
kctrl
;
static
int
save_auto_repeat
=
-
1
;
...
...
@@ -4161,10 +4190,10 @@ void autorepeat(int restore) {
if
(
save_auto_repeat
<
0
)
{
return
;
/* nothing to restore */
}
global_auto_repeat
=
get_autorepeat_state
();
X_LOCK
;
/* read state and skip restore if equal (e.g. no clients) */
XGetKeyboardControl
(
dpy
,
&
kstate
);
if
(
kstate
.
global_auto_repeat
==
save_auto_repeat
)
{
if
(
global_auto_repeat
==
save_auto_repeat
)
{
X_UNLOCK
;
return
;
}
...
...
@@ -4177,17 +4206,21 @@ void autorepeat(int restore) {
rfbLog
(
"Restored X server key autorepeat to: %d
\n
"
,
save_auto_repeat
);
}
else
{
X_LOCK
;
XGetKeyboardControl
(
dpy
,
&
kstate
);
save_auto_repeat
=
kstate
.
global_auto_repeat
;
global_auto_repeat
=
get_autorepeat_state
();
save_auto_repeat
=
global_auto_repeat
;
X_LOCK
;
kctrl
.
auto_repeat_mode
=
AutoRepeatModeOff
;
XChangeKeyboardControl
(
dpy
,
KBAutoRepeatMode
,
&
kctrl
);
XFlush
(
dpy
);
X_UNLOCK
;
rfbLog
(
"Disabled X server key autorepeat. (you can run the
\n
"
);
rfbLog
(
"command: 'xset r on' to force it back on)
\n
"
);
rfbLog
(
"Disabled X server key autorepeat.
\n
"
);
if
(
no_repeat_countdown
>=
0
)
{
rfbLog
(
" you can run the command: 'xset r on' (%d "
"times)
\n
"
,
no_repeat_countdown
+
1
);
rfbLog
(
" to force it back on.
\n
"
);
}
}
}
...
...
@@ -6884,6 +6917,30 @@ void check_xevents(void) {
}
}
if
(
no_autorepeat
&&
client_count
&&
no_repeat_countdown
)
{
static
time_t
last_check
=
0
;
if
(
now
>
last_check
+
1
)
{
last_check
=
now
;
X_UNLOCK
;
if
(
get_autorepeat_state
()
!=
0
)
{
int
n
=
no_repeat_countdown
-
1
;
if
(
n
>=
0
)
{
rfbLog
(
"Battling with something for "
"-norepeat!! (%d resets left)
\n
"
,
n
);
}
else
{
rfbLog
(
"Battling with something for "
"-norepeat!!
\n
"
);
}
if
(
no_repeat_countdown
>
0
)
{
no_repeat_countdown
--
;
}
autorepeat
(
1
);
autorepeat
(
0
);
}
X_LOCK
;
}
}
if
(
XCheckTypedEvent
(
dpy
,
MappingNotify
,
&
xev
))
{
XRefreshKeyboardMapping
((
XMappingEvent
*
)
&
xev
);
if
(
use_modifier_tweak
)
{
...
...
@@ -7658,20 +7715,6 @@ char *process_remote_cmd(char *cmd, int stringonly) {
do_new_fb
(
1
);
}
}
}
else
if
(
strstr
(
p
,
"clip"
)
==
p
)
{
COLON_CHECK
(
"clip:"
)
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s%s%s"
,
p
,
co
,
NONUL
(
clip_str
));
goto
qry
;
}
p
+=
strlen
(
"clip:"
);
if
(
clip_str
)
free
(
clip_str
);
clip_str
=
strdup
(
p
);
/* OK, this requires a new fb... */
do_new_fb
(
1
);
}
else
if
(
strstr
(
p
,
"waitmapped"
)
==
p
)
{
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s:%d"
,
p
,
...
...
@@ -7687,6 +7730,20 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
subwin_wait_mapped
=
0
;
}
else
if
(
strstr
(
p
,
"clip"
)
==
p
)
{
COLON_CHECK
(
"clip:"
)
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s%s%s"
,
p
,
co
,
NONUL
(
clip_str
));
goto
qry
;
}
p
+=
strlen
(
"clip:"
);
if
(
clip_str
)
free
(
clip_str
);
clip_str
=
strdup
(
p
);
/* OK, this requires a new fb... */
do_new_fb
(
1
);
}
else
if
(
!
strcmp
(
p
,
"flashcmap"
))
{
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s:%d"
,
p
,
flash_cmap
);
...
...
@@ -7831,6 +7888,23 @@ char *process_remote_cmd(char *cmd, int stringonly) {
check_black_fb
();
do_new_fb
(
0
);
}
else
if
(
!
strcmp
(
p
,
"scale_cursor"
)
||
strstr
(
p
,
"scale_cursor:"
)
==
p
)
{
/* skip-cmd-list */
COLON_CHECK
(
"scale_cursor:"
)
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s%s%s"
,
p
,
co
,
NONUL
(
scale_cursor_str
));
goto
qry
;
}
p
+=
strlen
(
"scale_cursor:"
);
if
(
scale_cursor_str
)
free
(
scale_cursor_str
);
if
(
*
p
==
'\0'
)
{
scale_cursor_str
=
NULL
;
}
else
{
scale_cursor_str
=
strdup
(
p
);
}
setup_cursors_and_push
();
}
else
if
(
!
strcmp
(
p
,
"viewonly"
))
{
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s:%d"
,
p
,
view_only
);
...
...
@@ -8657,6 +8731,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
rfbLog
(
"process_remote_cmd: enabling -norepeat mode.
\n
"
);
no_autorepeat
=
1
;
if
(
no_repeat_countdown
>=
0
)
{
no_repeat_countdown
=
2
;
}
if
(
client_count
)
{
autorepeat
(
0
);
/* disable if any clients */
}
...
...
@@ -8843,6 +8920,18 @@ char *process_remote_cmd(char *cmd, int stringonly) {
initialize_cursors_mode
();
first_cursor
();
}
else
if
(
strstr
(
p
,
"arrow"
)
==
p
)
{
COLON_CHECK
(
"arrow:"
)
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s%s%d"
,
p
,
co
,
alt_arrow
);
goto
qry
;
}
p
+=
strlen
(
"arrow:"
);
alt_arrow
=
atoi
(
p
);
rfbLog
(
"process_remote_cmd: setting alt_arrow: %d.
\n
"
,
alt_arrow
);
setup_cursors_and_push
();
}
else
if
(
!
strcmp
(
p
,
"xfixes"
))
{
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s:%d"
,
p
,
use_xfixes
);
...
...
@@ -9547,7 +9636,11 @@ char *process_remote_cmd(char *cmd, int stringonly) {
accept_remote_cmds
=
0
;
/* cannot be turned back on. */
}
else
if
(
strstr
(
p
,
"hack:"
)
==
p
)
{
/* skip-cmd-list */
NOTAPP
COLON_CHECK
(
"hack:"
)
if
(
query
)
{
snprintf
(
buf
,
bufn
,
"ans=%s%s%d"
,
p
,
co
,
hack_val
);
goto
qry
;
}
p
+=
strlen
(
"hack:"
);
hack_val
=
atoi
(
p
);
rfbLog
(
"set hack_val to: %d
\n
"
,
hack_val
);
...
...
@@ -9921,24 +10014,23 @@ void collect_xdamage(int scancnt) {
X_UNLOCK
;
now
=
time
(
0
);
if
(
!
last_rpt
)
{
if
(
!
last_rpt
)
{
last_rpt
=
now
;
}
if
(
now
>
last_rpt
+
15
)
{
}
if
(
now
>
last_rpt
+
15
)
{
double
rat
=
-
1
.
0
;
if
(
XD_tot
)
{
rat
=
((
double
)
XD_skip
)
/
XD_tot
;
}
if
(
0
)
fprintf
(
stderr
,
"skip/tot: %04d/%04d rat=%.3f rect_count: %d desired_rects: %d
\n
"
,
XD_skip
,
XD_tot
,
rat
,
rect_count
,
XD_des
);
if
(
0
)
fprintf
(
stderr
,
"skip/tot: %04d/%04d rat=%.3f rect_count: %d desired_rects: %d
\n
"
,
XD_skip
,
XD_tot
,
rat
,
rect_count
,
XD_des
);
XD_skip
=
0
;
XD_tot
=
0
;
XD_des
=
0
;
rect_count
=
0
;
last_rpt
=
now
;
}
}
#endif
}
...
...
@@ -10072,6 +10164,25 @@ typedef struct cursor_info {
rfbCursorPtr
rfb
;
}
cursor_info_t
;
void
curs_copy
(
cursor_info_t
*
dest
,
cursor_info_t
*
src
)
{
if
(
src
->
data
!=
NULL
)
{
dest
->
data
=
strdup
(
src
->
data
);
}
else
{
dest
->
data
=
NULL
;
}
if
(
src
->
mask
!=
NULL
)
{
dest
->
mask
=
strdup
(
src
->
mask
);
}
else
{
dest
->
mask
=
NULL
;
}
dest
->
wx
=
src
->
wx
;
dest
->
wy
=
src
->
wy
;
dest
->
sx
=
src
->
sx
;
dest
->
sy
=
src
->
sy
;
dest
->
reverse
=
src
->
reverse
;
dest
->
rfb
=
src
->
rfb
;
}
/* empty cursor */
static
char
*
curs_empty_data
=
" "
...
...
@@ -10092,6 +10203,7 @@ static char* curs_dot_mask =
" x"
;
static
cursor_info_t
cur_dot
=
{
NULL
,
NULL
,
2
,
2
,
0
,
0
,
0
,
NULL
};
/* main cursor */
static
char
*
curs_arrow_data
=
" "
...
...
@@ -10132,8 +10244,198 @@ static char* curs_arrow_mask =
" xx "
" "
" "
;
static
cursor_info_t
cur_arrow
=
{
NULL
,
NULL
,
18
,
18
,
0
,
0
,
0
,
NULL
};
static
cursor_info_t
cur_arrow
=
{
NULL
,
NULL
,
18
,
18
,
0
,
0
,
1
,
NULL
};
static
char
*
curs_arrow2_data
=
" "
" x "
" xx "
" xxx "
" xxxx "
" xxxxx "
" xxxxxx "
" xxxxxxx "
" xxxxxxxx "
" xxxxx "
" xx xx "
" x xx "
" xx "
" xx "
" xx "
" "
" "
" "
;
static
char
*
curs_arrow2_mask
=
"xx "
"xxx "
"xxxx "
"xxxxx "
"xxxxxx "
"xxxxxxx "
"xxxxxxxx "
"xxxxxxxxx "
"xxxxxxxxxx "
"xxxxxxxxxx "
"xxxxxxx "
"xxx xxxx "
"xx xxxx "
" xxxx "
" xxxx "
" xx "
" "
" "
;
static
cursor_info_t
cur_arrow2
=
{
NULL
,
NULL
,
18
,
18
,
0
,
0
,
0
,
NULL
};
static
char
*
curs_arrow3_data
=
" "
" xx "
" xxxx "
" xxxxx "
" xxxxxxx "
" xxxxxxxx "
" xxxxxxxxxx "
" xxxxx "
" xxxxx "
" xx x "
" xx x "
" x x "
" x x "
" x "
" x "
" "
;
static
char
*
curs_arrow3_mask
=
"xxx "
"xxxxx "
"xxxxxxx "
" xxxxxxxx "
" xxxxxxxxxx "
" xxxxxxxxxxxx "
" xxxxxxxxxxxx "
" xxxxxxxxxxx "
" xxxxxxx "
" xxxxxxx "
" xxxx xxx "
" xxx xxx "
" xxx xxx "
" xxx xxx "
" xxx"
" xx"
;
static
cursor_info_t
cur_arrow3
=
{
NULL
,
NULL
,
16
,
16
,
0
,
0
,
1
,
NULL
};
static
char
*
curs_arrow4_data
=
" "
" xx "
" xxxx "
" xxxxx "
" xxxxxxx "
" xxxxxxxx "
" xxxxxxxxxx "
" xxxxx "
" xxxxx "
" xx x "
" xx x "
" x x "
" x x "
" x "
" x "
" "
;
static
char
*
curs_arrow4_mask
=
"xxx "
"xxxxx "
"xxxxxxx "
" xxxxxxxx "
" xxxxxxxxxx "
" xxxxxxxxxxxx "
" xxxxxxxxxxxx "
" xxxxxxxxxxx "
" xxxxxxx "
" xxxxxxx "
" xxxx xxx "
" xxx xxx "
" xxx xxx "
" xxx xxx "
" xxx"
" xx"
;
static
cursor_info_t
cur_arrow4
=
{
NULL
,
NULL
,
16
,
16
,
0
,
0
,
0
,
NULL
};
static
char
*
curs_arrow5_data
=
"x "
" xx "
" xxxx "
" xxxxx "
" xxxxxxx "
" xxx "
" xx x "
" x x "
" x x "
" x "
" x "
" x "
" x "
" x "
" x"
;
static
char
*
curs_arrow5_mask
=
"xx "
"xxxx "
" xxxxx "
" xxxxxxx "
" xxxxxxxx "
" xxxxxxxx "
" xxxxx "
" xxxxxx "
" xx xxx "
" x xxx "
" xxx "
" xxx "
" xxx "
" xxx"
" xx"
;
static
cursor_info_t
cur_arrow5
=
{
NULL
,
NULL
,
15
,
15
,
0
,
0
,
1
,
NULL
};
static
char
*
curs_arrow6_data
=
"x "
" xx "
" xxxx "
" xxxxx "
" xxxxxxx "
" xxx "
" xx x "
" x x "
" x x "
" x "
" x "
" x "
" x "
" x "
" x"
;
static
char
*
curs_arrow6_mask
=
"xx "
"xxxx "
" xxxxx "
" xxxxxxx "
" xxxxxxxx "
" xxxxxxxx "
" xxxxx "
" xxxxxx "
" xx xxx "
" x xxx "
" xxx "
" xxx "
" xxx "
" xxx"
" xx"
;
static
cursor_info_t
cur_arrow6
=
{
NULL
,
NULL
,
15
,
15
,
0
,
0
,
0
,
NULL
};
int
alt_arrow_max
=
6
;
/*
* It turns out we can at least detect mouse is on the root window so
* show it (under -cursor X) with this familiar cursor...
...
...
@@ -10338,7 +10640,8 @@ void first_cursor(void) {
void
setup_cursors
(
void
)
{
rfbCursorPtr
rfb_curs
;
int
i
,
n
=
0
;
char
*
scale
=
NULL
;
int
i
,
j
,
n
=
0
;
static
int
first
=
1
;
rfbLog
(
"setting up %d cursors...
\n
"
,
CURS_MAX
);
...
...
@@ -10380,6 +10683,7 @@ void setup_cursors(void) {
if
(
ci
->
mask
)
{
free
(
ci
->
mask
);
}
free
(
ci
);
}
/* create new struct: */
...
...
@@ -10407,6 +10711,16 @@ void setup_cursors(void) {
cur_arrow
.
data
=
curs_arrow_data
;
cur_arrow
.
mask
=
curs_arrow_mask
;
cur_arrow2
.
data
=
curs_arrow2_data
;
cur_arrow2
.
mask
=
curs_arrow2_mask
;
cur_arrow3
.
data
=
curs_arrow3_data
;
cur_arrow3
.
mask
=
curs_arrow3_mask
;
cur_arrow4
.
data
=
curs_arrow4_data
;
cur_arrow4
.
mask
=
curs_arrow4_mask
;
cur_arrow5
.
data
=
curs_arrow5_data
;
cur_arrow5
.
mask
=
curs_arrow5_mask
;
cur_arrow6
.
data
=
curs_arrow6_data
;
cur_arrow6
.
mask
=
curs_arrow6_mask
;
cur_root
.
data
=
curs_root_data
;
cur_root
.
mask
=
curs_root_mask
;
...
...
@@ -10420,23 +10734,102 @@ void setup_cursors(void) {
cur_xterm
.
data
=
curs_xterm_data
;
cur_xterm
.
mask
=
curs_xterm_mask
;
cursors
[
CURS_EMPTY
]
=
&
cur_empty
;
n
++
;
cursors
[
CURS_DOT
]
=
&
cur_dot
;
n
++
;
cursors
[
CURS_ARROW
]
=
&
cur_arrow
;
n
++
;
cursors
[
CURS_ROOT
]
=
&
cur_root
;
n
++
;
cursors
[
CURS_WM
]
=
&
cur_fleur
;
n
++
;
cursors
[
CURS_TERM
]
=
&
cur_xterm
;
n
++
;
cursors
[
CURS_PLUS
]
=
&
cur_plus
;
n
++
;
curs_copy
(
cursors
[
CURS_EMPTY
],
&
cur_empty
);
n
++
;
curs_copy
(
cursors
[
CURS_DOT
],
&
cur_dot
);
n
++
;
if
(
alt_arrow
<
1
||
alt_arrow
>
alt_arrow_max
)
{
alt_arrow
=
1
;
}
if
(
alt_arrow
==
1
)
{
curs_copy
(
cursors
[
CURS_ARROW
],
&
cur_arrow
);
n
++
;
}
else
if
(
alt_arrow
==
2
)
{
curs_copy
(
cursors
[
CURS_ARROW
],
&
cur_arrow2
);
n
++
;
}
else
if
(
alt_arrow
==
3
)
{
curs_copy
(
cursors
[
CURS_ARROW
],
&
cur_arrow3
);
n
++
;
}
else
if
(
alt_arrow
==
4
)
{
curs_copy
(
cursors
[
CURS_ARROW
],
&
cur_arrow4
);
n
++
;
}
else
if
(
alt_arrow
==
5
)
{
curs_copy
(
cursors
[
CURS_ARROW
],
&
cur_arrow5
);
n
++
;
}
else
if
(
alt_arrow
==
6
)
{
curs_copy
(
cursors
[
CURS_ARROW
],
&
cur_arrow6
);
n
++
;
}
else
{
alt_arrow
=
1
;
curs_copy
(
cursors
[
CURS_ARROW
],
&
cur_arrow
);
n
++
;
}
curs_copy
(
cursors
[
CURS_ROOT
],
&
cur_root
);
n
++
;
curs_copy
(
cursors
[
CURS_WM
],
&
cur_fleur
);
n
++
;
curs_copy
(
cursors
[
CURS_TERM
],
&
cur_xterm
);
n
++
;
curs_copy
(
cursors
[
CURS_PLUS
],
&
cur_plus
);
n
++
;
if
(
scale_cursor_str
)
{
scale
=
scale_cursor_str
;
}
else
if
(
scaling
&&
scale_str
)
{
scale
=
scale_str
;
}
/* scale = NULL zeroes everything */
parse_scale_string
(
scale
,
&
scale_cursor_fac
,
&
scaling_cursor
,
&
scaling_cursor_noblend
,
&
j
,
&
j
,
&
scaling_cursor_interpolate
,
&
scale_cursor_numer
,
&
scale_cursor_denom
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
/* create rfbCursors for the special cursors: */
cursor_info_t
*
ci
=
cursors
[
i
];
ci
->
data
=
strdup
(
ci
->
data
);
ci
->
mask
=
strdup
(
ci
->
mask
);
if
(
scaling_cursor
&&
scale_cursor_fac
!=
1
.
0
)
{
int
w
,
h
,
x
,
y
,
i
;
unsigned
long
*
pixels
;
w
=
ci
->
wx
;
h
=
ci
->
wy
;
pixels
=
(
unsigned
long
*
)
malloc
(
4
*
w
*
h
);
i
=
0
;
for
(
y
=
0
;
y
<
h
;
y
++
)
{
for
(
x
=
0
;
x
<
w
;
x
++
)
{
char
d
=
ci
->
data
[
i
];
char
m
=
ci
->
mask
[
i
];
unsigned
long
*
p
;
p
=
pixels
+
i
;
/* set alpha on */
*
p
=
0xff000000
;
if
(
d
==
' '
&&
m
==
' '
)
{
/* alpha off */
*
p
=
0x00000000
;
}
else
if
(
d
!=
' '
)
{
/* body */
if
(
ci
->
reverse
)
{
*
p
|=
0x00000000
;
}
else
{
*
p
|=
0x00ffffff
;
}
}
else
if
(
m
!=
' '
)
{
/* edge */
if
(
ci
->
reverse
)
{
*
p
|=
0x00ffffff
;
}
else
{
*
p
|=
0x00000000
;
}
}
i
++
;
}
}
rfb_curs
=
pixels2curs
(
pixels
,
w
,
h
,
ci
->
sx
,
ci
->
sy
,
bpp
/
8
);
free
(
pixels
);
}
else
{
rfb_curs
=
rfbMakeXCursor
(
ci
->
wx
,
ci
->
wy
,
ci
->
data
,
ci
->
mask
);
/* standard X cursor */
rfb_curs
=
rfbMakeXCursor
(
ci
->
wx
,
ci
->
wy
,
ci
->
data
,
ci
->
mask
);
if
(
ci
->
reverse
)
{
rfb_curs
->
foreRed
=
0x0000
;
...
...
@@ -10485,11 +10878,13 @@ void setup_cursors(void) {
bw
=
black
;
}
}
*
(
rfb_curs
->
richSource
+
k
)
=
(
unsigned
char
)
bw
;
*
(
rfb_curs
->
richSource
+
k
)
=
(
unsigned
char
)
bw
;
k
++
;
}
}
}
}
ci
->
rfb
=
rfb_curs
;
}
if
(
screen
)
{
...
...
@@ -10622,134 +11017,49 @@ void initialize_xfixes(void) {
#endif
}
int
get_xfixes_cursor
(
int
init
)
{
static
unsigned
long
last_cursor
=
0
;
static
int
last_index
=
0
;
static
time_t
curs_times
[
CURS_MAX
];
static
unsigned
long
curs_index
[
CURS_MAX
];
int
which
=
CURS_ARROW
;
if
(
init
)
{
/* zero out our cache (cursors are not freed) */
int
i
;
for
(
i
=
0
;
i
<
CURS_MAX
;
i
++
)
{
curs_times
[
i
]
=
0
;
curs_index
[
i
]
=
0
;
}
last_cursor
=
0
;
last_index
=
0
;
return
-
1
;
}
if
(
xfixes_present
)
{
#if LIBVNCSERVER_HAVE_LIBXFIXES
int
use
,
oldest
,
i
,
x
,
y
,
w
,
h
,
len
;
int
Bpp
=
bpp
/
8
;
time_t
oldtime
,
now
;
char
*
bitmap
,
*
rich
,
*
alpha
;
unsigned
long
black
,
white
;
rfbCursorPtr
pixels2curs
(
unsigned
long
*
pixels
,
int
w
,
int
h
,
int
xhot
,
int
yhot
,
int
Bpp
)
{
rfbCursorPtr
c
;
int
thresh
,
n_opaque
,
n_trans
,
n_alpha
,
histo
[
256
];
int
send_alpha
=
0
,
alpha_shift
;
XFixesCursorImage
*
xfc
;
static
unsigned
long
black
,
white
;
static
int
first
=
1
;
char
*
bitmap
,
*
rich
,
*
alpha
;
char
*
new_pixels
=
NULL
;
int
n_opaque
,
n_trans
,
n_alpha
,
len
,
histo
[
256
];
int
send_alpha
=
0
,
alpha_shift
,
thresh
;
int
i
,
x
,
y
;
if
(
!
got_xfixes_cursor_notify
)
{
/* try again for XFixesCursorNotify event */
XEvent
xev
;
if
(
first
)
{
X_LOCK
;
if
(
XCheckTypedEvent
(
dpy
,
xfixes_base_event_type
+
XFixesCursorNotify
,
&
xev
))
{
got_xfixes_cursor_notify
++
;
}
black
=
BlackPixel
(
dpy
,
scr
);
white
=
WhitePixel
(
dpy
,
scr
);
X_UNLOCK
;
first
=
0
;
}
if
(
!
got_xfixes_cursor_notify
)
{
/* evidently no cursor change, just return last one */
if
(
last_index
)
{
return
last_index
;
}
else
{
return
CURS_ARROW
;
}
}
got_xfixes_cursor_notify
=
0
;
/* retrieve the cursor info + pixels from server: */
X_LOCK
;
xfc
=
XFixesGetCursorImage
(
dpy
);
X_UNLOCK
;
if
(
!
xfc
)
{
/* failure. */
return
(
which
);
}
if
(
scaling_cursor
&&
scale_cursor_fac
!=
1
.
0
)
{
int
W
,
H
;
if
(
xfc
->
cursor_serial
==
last_cursor
)
{
/* same serial index: no change */
X_LOCK
;
XFree
(
xfc
);
X_UNLOCK
;
if
(
last_index
)
{
return
last_index
;
}
else
{
return
CURS_ARROW
;
}
}
W
=
w
;
H
=
h
;
oldest
=
CURS_DYN_MIN
;
oldtime
=
curs_times
[
oldest
];
now
=
time
(
0
);
for
(
i
=
CURS_DYN_MIN
;
i
<=
CURS_DYN_MAX
;
i
++
)
{
if
(
curs_times
[
i
]
<
oldtime
)
{
/* watch for oldest one to overwrite */
oldest
=
i
;
oldtime
=
curs_times
[
i
];
}
if
(
xfc
->
cursor_serial
==
curs_index
[
i
])
{
/*
* got a hit with an existing cursor,
* use that one.
*/
last_cursor
=
curs_index
[
i
];
curs_times
[
i
]
=
now
;
last_index
=
i
;
X_LOCK
;
XFree
(
xfc
);
X_UNLOCK
;
return
last_index
;
}
}
w
=
scale_round
(
W
,
scale_cursor_fac
);
h
=
scale_round
(
H
,
scale_cursor_fac
);
RFBUNDRAWCURSOR
(
screen
);
new_pixels
=
(
char
*
)
malloc
(
4
*
w
*
h
);
/* we need to create the cursor and overwrite oldest */
use
=
oldest
;
if
(
cursors
[
use
]
->
rfb
)
{
/* clean up oldest if it exists */
if
(
cursors
[
use
]
->
rfb
->
richSource
)
{
free
(
cursors
[
use
]
->
rfb
->
richSource
);
}
#if !OLD_TREE && CURSOR_TRANSPARENCY
if
(
cursors
[
use
]
->
rfb
->
alphaSource
)
{
free
(
cursors
[
use
]
->
rfb
->
alphaSource
);
}
#endif
if
(
cursors
[
use
]
->
rfb
->
source
)
{
free
(
cursors
[
use
]
->
rfb
->
source
);
}
if
(
cursors
[
use
]
->
rfb
->
mask
)
{
free
(
cursors
[
use
]
->
rfb
->
mask
);
}
free
(
cursors
[
use
]
->
rfb
);
}
scale_rect
(
scale_cursor_fac
,
scaling_cursor_noblend
,
scaling_cursor_interpolate
,
4
,
(
char
*
)
pixels
,
4
*
W
,
new_pixels
,
4
*
w
,
W
,
H
,
w
,
h
,
0
,
0
,
W
,
H
,
0
);
X_LOCK
;
black
=
BlackPixel
(
dpy
,
scr
);
white
=
WhitePixel
(
dpy
,
scr
);
X_UNLOCK
;
pixels
=
(
unsigned
long
*
)
new_pixels
;
w
=
xfc
->
width
;
h
=
xfc
->
height
;
len
=
w
*
h
;
xhot
=
scale_round
(
xhot
,
scale_cursor_fac
)
;
yhot
=
scale_round
(
yhot
,
scale_cursor_fac
)
;
}
len
=
w
*
h
;
/* for bitmap data */
bitmap
=
(
char
*
)
malloc
(
len
+
1
);
bitmap
[
len
]
=
'\0'
;
...
...
@@ -10770,7 +11080,7 @@ int get_xfixes_cursor(int init) {
for
(
x
=
0
;
x
<
w
;
x
++
)
{
unsigned
long
a
;
a
=
0xff000000
&
(
*
(
xfc
->
pixels
+
i
));
a
=
0xff000000
&
(
*
(
pixels
+
i
));
a
=
a
>>
24
;
/* alpha channel */
if
(
a
>
0
)
{
n_alpha
++
;
...
...
@@ -10786,11 +11096,9 @@ int get_xfixes_cursor(int init) {
}
if
(
alpha_blend
)
{
send_alpha
=
0
;
#if CURSOR_TRANSPARENCY
if
(
Bpp
==
4
)
{
send_alpha
=
1
;
}
#endif
alpha_shift
=
24
;
if
(
main_red_shift
==
24
||
main_green_shift
==
24
||
main_blue_shift
==
24
)
{
...
...
@@ -10817,7 +11125,7 @@ int get_xfixes_cursor(int init) {
unsigned
int
ui
;
char
*
p
;
a
=
0xff000000
&
(
*
(
xfc
->
pixels
+
i
));
a
=
0xff000000
&
(
*
(
pixels
+
i
));
a
=
a
>>
24
;
/* alpha channel */
...
...
@@ -10827,9 +11135,9 @@ int get_xfixes_cursor(int init) {
bitmap
[
i
]
=
'x'
;
}
r
=
0x00ff0000
&
(
*
(
xfc
->
pixels
+
i
));
g
=
0x0000ff00
&
(
*
(
xfc
->
pixels
+
i
));
b
=
0x000000ff
&
(
*
(
xfc
->
pixels
+
i
));
r
=
0x00ff0000
&
(
*
(
pixels
+
i
));
g
=
0x0000ff00
&
(
*
(
pixels
+
i
));
b
=
0x000000ff
&
(
*
(
pixels
+
i
));
r
=
r
>>
16
;
/* red */
g
=
g
>>
8
;
/* green */
b
=
b
>>
0
;
/* blue */
...
...
@@ -10874,9 +11182,6 @@ int get_xfixes_cursor(int init) {
/* insert value into rich source: */
p
=
rich
+
Bpp
*
i
;
#if 0
memcpy(p, (char *)&ui, Bpp);
#else
if
(
Bpp
==
1
)
{
*
((
unsigned
char
*
)
p
)
=
(
unsigned
char
)
ui
;
...
...
@@ -10894,7 +11199,6 @@ int get_xfixes_cursor(int init) {
*
((
unsigned
int
*
)
p
)
=
(
unsigned
int
)
ui
;
}
#endif
/* insert alpha value into alpha source: */
p
=
alpha
+
i
;
...
...
@@ -10908,26 +11212,148 @@ int get_xfixes_cursor(int init) {
c
=
rfbMakeXCursor
(
w
,
h
,
bitmap
,
bitmap
);
free
(
bitmap
);
if
(
new_pixels
)
{
free
(
new_pixels
);
}
/* set up the cursor parameters: */
c
->
xhot
=
xfc
->
xhot
;
c
->
yhot
=
xfc
->
yhot
;
c
->
xhot
=
xhot
;
c
->
yhot
=
yhot
;
c
->
cleanup
=
FALSE
;
c
->
cleanupSource
=
FALSE
;
c
->
cleanupMask
=
FALSE
;
c
->
cleanupRichSource
=
FALSE
;
c
->
richSource
=
rich
;
#if !OLD_TREE
&& CURSOR_TRANSPARENCY
#if !OLD_TREE
if
(
alpha_blend
&&
!
indexed_color
)
{
c
->
alphaSource
=
alpha
;
c
->
alphaPreMultiplied
=
TRUE
;
}
else
{
free
(
alpha
);
c
->
alphaSource
=
NULL
;
}
#endif
return
c
;
}
int
get_xfixes_cursor
(
int
init
)
{
static
unsigned
long
last_cursor
=
0
;
static
int
last_index
=
0
;
static
time_t
curs_times
[
CURS_MAX
];
static
unsigned
long
curs_index
[
CURS_MAX
];
int
which
=
CURS_ARROW
;
if
(
init
)
{
/* zero out our cache (cursors are not freed) */
int
i
;
for
(
i
=
0
;
i
<
CURS_MAX
;
i
++
)
{
curs_times
[
i
]
=
0
;
curs_index
[
i
]
=
0
;
}
last_cursor
=
0
;
last_index
=
0
;
return
-
1
;
}
if
(
xfixes_present
)
{
#if LIBVNCSERVER_HAVE_LIBXFIXES
int
use
,
oldest
,
i
;
time_t
oldtime
,
now
;
XFixesCursorImage
*
xfc
;
if
(
!
got_xfixes_cursor_notify
)
{
/* try again for XFixesCursorNotify event */
XEvent
xev
;
X_LOCK
;
if
(
XCheckTypedEvent
(
dpy
,
xfixes_base_event_type
+
XFixesCursorNotify
,
&
xev
))
{
got_xfixes_cursor_notify
++
;
}
X_UNLOCK
;
}
if
(
!
got_xfixes_cursor_notify
)
{
/* evidently no cursor change, just return last one */
if
(
last_index
)
{
return
last_index
;
}
else
{
return
CURS_ARROW
;
}
}
got_xfixes_cursor_notify
=
0
;
/* retrieve the cursor info + pixels from server: */
X_LOCK
;
xfc
=
XFixesGetCursorImage
(
dpy
);
X_UNLOCK
;
if
(
!
xfc
)
{
/* failure. */
return
(
which
);
}
if
(
xfc
->
cursor_serial
==
last_cursor
)
{
/* same serial index: no change */
X_LOCK
;
XFree
(
xfc
);
X_UNLOCK
;
if
(
last_index
)
{
return
last_index
;
}
else
{
return
CURS_ARROW
;
}
}
oldest
=
CURS_DYN_MIN
;
oldtime
=
curs_times
[
oldest
];
now
=
time
(
0
);
for
(
i
=
CURS_DYN_MIN
;
i
<=
CURS_DYN_MAX
;
i
++
)
{
if
(
curs_times
[
i
]
<
oldtime
)
{
/* watch for oldest one to overwrite */
oldest
=
i
;
oldtime
=
curs_times
[
i
];
}
if
(
xfc
->
cursor_serial
==
curs_index
[
i
])
{
/*
* got a hit with an existing cursor,
* use that one.
*/
last_cursor
=
curs_index
[
i
];
curs_times
[
i
]
=
now
;
last_index
=
i
;
X_LOCK
;
XFree
(
xfc
);
X_UNLOCK
;
return
last_index
;
}
}
RFBUNDRAWCURSOR
(
screen
);
/* we need to create the cursor and overwrite oldest */
use
=
oldest
;
if
(
cursors
[
use
]
->
rfb
)
{
/* clean up oldest if it exists */
if
(
cursors
[
use
]
->
rfb
->
richSource
)
{
free
(
cursors
[
use
]
->
rfb
->
richSource
);
}
#if !OLD_TREE
if
(
cursors
[
use
]
->
rfb
->
alphaSource
)
{
free
(
cursors
[
use
]
->
rfb
->
alphaSource
);
}
#endif
if
(
cursors
[
use
]
->
rfb
->
source
)
{
free
(
cursors
[
use
]
->
rfb
->
source
);
}
if
(
cursors
[
use
]
->
rfb
->
mask
)
{
free
(
cursors
[
use
]
->
rfb
->
mask
);
}
free
(
cursors
[
use
]
->
rfb
);
}
/* place cursor into our collection */
cursors
[
use
]
->
rfb
=
c
;
cursors
[
use
]
->
rfb
=
pixels2curs
(
xfc
->
pixels
,
xfc
->
width
,
xfc
->
height
,
xfc
->
xhot
,
xfc
->
yhot
,
bpp
/
8
);
/* update time and serial index: */
curs_times
[
use
]
=
now
;
...
...
@@ -12116,19 +12542,20 @@ XImage *initialize_xdisplay_fb(void) {
return
fb
;
}
void
parse_scale_string
(
char
*
str
)
{
void
parse_scale_string
(
char
*
str
,
double
*
factor
,
int
*
scaling
,
int
*
noblend
,
int
*
nomult4
,
int
*
pad
,
int
*
interpolate
,
int
*
numer
,
int
*
denom
)
{
int
m
,
n
;
char
*
p
,
*
tstr
;
double
f
;
scale_fac
=
1
.
0
;
scaling
=
0
;
scaling_noblend
=
0
;
scaling_nomult4
=
0
;
scaling_pad
=
0
;
scaling_interpolate
=
0
;
scaled_x
=
0
,
scaled_y
=
0
;
scale_numer
=
0
,
scale_denom
=
0
;
*
factor
=
1
.
0
;
*
scaling
=
0
;
*
noblend
=
0
;
*
nomult4
=
0
;
*
pad
=
0
;
*
interpolate
=
0
;
*
numer
=
0
,
*
denom
=
0
;
if
(
str
==
NULL
||
str
[
0
]
==
'\0'
)
{
return
;
...
...
@@ -12138,16 +12565,16 @@ void parse_scale_string(char *str) {
if
(
(
p
=
strchr
(
tstr
,
':'
))
!=
NULL
)
{
/* options */
if
(
strstr
(
p
+
1
,
"nb"
)
!=
NULL
)
{
scaling_
noblend
=
1
;
*
noblend
=
1
;
}
if
(
strstr
(
p
+
1
,
"n4"
)
!=
NULL
)
{
scaling_
nomult4
=
1
;
*
nomult4
=
1
;
}
if
(
strstr
(
p
+
1
,
"in"
)
!=
NULL
)
{
scaling_
interpolate
=
1
;
*
interpolate
=
1
;
}
if
(
strstr
(
p
+
1
,
"pad"
)
!=
NULL
)
{
scaling_
pad
=
1
;
*
pad
=
1
;
}
*
p
=
'\0'
;
}
...
...
@@ -12157,24 +12584,24 @@ void parse_scale_string(char *str) {
rfbLog
(
"bad -scale arg: %s
\n
"
,
tstr
);
clean_up_exit
(
1
);
}
scale_fac
=
(
double
)
f
;
*
factor
=
(
double
)
f
;
/* look for common fractions from small ints: */
for
(
n
=
2
;
n
<=
10
;
n
++
)
{
for
(
m
=
1
;
m
<
n
;
m
++
)
{
test
=
((
double
)
m
)
/
n
;
diff
=
scale_fac
-
test
;
diff
=
*
factor
-
test
;
if
(
-
eps
<
diff
&&
diff
<
eps
)
{
scale_
numer
=
m
;
scale_
denom
=
n
;
*
numer
=
m
;
*
denom
=
n
;
break
;
}
}
if
(
scale_
denom
)
{
if
(
*
denom
)
{
break
;
}
}
if
(
scale_fac
<
0
.
01
)
{
if
(
*
factor
<
0
.
01
)
{
rfbLog
(
"-scale factor too small: %f
\n
"
,
scale_fac
);
clean_up_exit
(
1
);
}
...
...
@@ -12192,34 +12619,42 @@ void parse_scale_string(char *str) {
rfbLog
(
"bad -scale arg: %s
\n
"
,
tstr
);
clean_up_exit
(
1
);
}
scale_fac
=
((
double
)
m
)
/
n
;
if
(
scale_fac
<
0
.
01
)
{
rfbLog
(
"-scale factor too small: %f
\n
"
,
scale_fac
);
*
factor
=
((
double
)
m
)
/
n
;
if
(
*
factor
<
0
.
01
)
{
rfbLog
(
"-scale factor too small: %f
\n
"
,
*
factor
);
clean_up_exit
(
1
);
}
scale_
numer
=
m
;
scale_
denom
=
n
;
*
numer
=
m
;
*
denom
=
n
;
}
if
(
scale_fac
==
1
.
0
)
{
if
(
*
factor
==
1
.
0
)
{
if
(
!
quiet
)
{
rfbLog
(
"scaling disabled for factor %f
\n
"
,
scale_fac
);
rfbLog
(
"scaling disabled for factor %f
\n
"
,
*
factor
);
}
}
else
{
scaling
=
1
;
*
scaling
=
1
;
}
free
(
tstr
);
}
int
scale_round
(
int
len
,
double
fac
)
{
double
eps
=
0
.
000001
;
len
=
(
int
)
(
len
*
fac
+
eps
);
return
len
;
}
void
setup_scaling
(
int
*
width_in
,
int
*
height_in
)
{
int
width
=
*
width_in
;
int
height
=
*
height_in
;
parse_scale_string
(
scale_str
);
parse_scale_string
(
scale_str
,
&
scale_fac
,
&
scaling
,
&
scaling_noblend
,
&
scaling_nomult4
,
&
scaling_pad
,
&
scaling_interpolate
,
&
scale_numer
,
&
scale_denom
);
if
(
scaling
)
{
double
eps
=
0
.
000001
;
width
=
(
int
)
(
width
*
scale_fac
+
eps
);
height
=
(
int
)
(
height
*
scale_fac
+
eps
);
width
=
scale_round
(
width
,
scale_fac
);
height
=
scale_round
(
height
,
scale_fac
);
if
(
scale_denom
&&
scaling_pad
)
{
/* it is not clear this padding is useful anymore */
rfbLog
(
"width %% denom: %d %% %d = %d
\n
"
,
width
,
...
...
@@ -14304,7 +14739,9 @@ weights for this scaled pixel are:
* the loop over the 4 pixels.
*/
static
void
scale_and_mark_rect
(
int
X1
,
int
Y1
,
int
X2
,
int
Y2
)
{
void
scale_rect
(
double
factor
,
int
noblend
,
int
interpolate
,
int
Bpp
,
char
*
src_fb
,
int
src_bytes_per_line
,
char
*
dst_fb
,
int
dst_bytes_per_line
,
int
Nx
,
int
Ny
,
int
nx
,
int
ny
,
int
X1
,
int
Y1
,
int
X2
,
int
Y2
,
int
mark
)
{
/*
* Notation:
* "i" an x pixel index in the destination (scaled) framebuffer
...
...
@@ -14314,8 +14751,6 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
*
* Similarly for nx, ny, Nx, Ny, etc. Lowercase: dest, Uppercase: source.
*/
int
Nx
,
Ny
,
nx
,
ny
,
Bpp
,
b
;
int
i
,
j
,
i1
,
i2
,
j1
,
j2
;
/* indices for scaled fb (dest) */
int
I
,
J
,
I1
,
I2
,
J1
,
J2
;
/* indices for main fb (source) */
...
...
@@ -14323,73 +14758,108 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
double
x1
,
y1
,
x2
,
y2
;
/* x-y coords for destination pixels edges */
double
dx
,
dy
;
/* size of destination pixel */
double
ddx
,
ddy
;
/* for interpolation expansion */
char
*
src
,
*
dest
;
/* pointers to the two framebuffers */
double
pixave
[
4
];
/* for averaging pixel values */
unsigned
short
us
;
unsigned
char
uc
;
unsigned
int
ui
;
int
use_noblend_shortcut
=
1
;
int
shrink
;
/* whether shrinking or expanding */
static
int
constant_weights
=
-
1
,
cnt
=
0
;
static
int
constant_weights
=
-
1
,
mag_int
=
-
1
;
static
int
last_Nx
=
-
1
,
last_Ny
=
-
1
,
cnt
=
0
;
static
double
last_factor
=
-
1
.
0
;
int
b
,
k
;
double
pixave
[
4
];
/* for averaging pixel values */
if
(
scale_fac
<=
1
.
0
)
{
if
(
factor
<=
1
.
0
)
{
shrink
=
1
;
}
else
{
shrink
=
0
;
}
if
(
shrink
&&
scaling_interpolate
)
{
/*
* User asked for interpolation scheme, presumably for
* small shrink.
* N.B. width and height (real numbers) of a scaled pixel.
* both are > 1 (e.g. 1.333 for -scale 3/4)
* they should also be equal but we don't assume it.
*
* This new way is probably the best we can do, take the inverse
* of the scaling factor to double precision.
*/
shrink
=
0
;
}
if
(
!
screen
||
!
rfb_fb
||
!
main_fb
)
{
return
;
}
dx
=
1
.
0
/
factor
;
dy
=
1
.
0
/
factor
;
if
(
!
screen
->
serverFormat
.
trueColour
)
{
/*
* PseudoColor colormap... blending leads to random colors.
* There is some speedup if the pixel weights are constant, so
* let's special case these.
*
* If scale = 1/n and n divides Nx and Ny, the pixel weights
* are constant (e.g. 1/2 => equal on 2x2 square).
*/
scaling_noblend
=
1
;
if
(
factor
!=
last_factor
||
Nx
!=
last_Nx
||
Ny
!=
last_Ny
)
{
constant_weights
=
-
1
;
mag_int
=
-
1
;
last_Nx
=
Nx
;
last_Ny
=
Ny
;
last_factor
=
factor
;
}
Bpp
=
bpp
/
8
;
/* Bytes per pixel */
Nx
=
dpy_x
;
/* extent of source (the whole main fb) */
Ny
=
dpy_y
;
if
(
constant_weights
<
0
)
{
int
n
=
0
;
nx
=
scaled_x
;
/* extent of dest (the whole scaled rfb fb) */
ny
=
scaled_y
;
constant_weights
=
0
;
mag_int
=
0
;
/*
* width and height (real numbers) of a scaled pixel.
* both are > 1 (e.g. 1.333 for -scale 3/4)
* they should also be equal but we don't assume it.
*/
for
(
i
=
2
;
i
<=
128
;
i
++
)
{
double
test
=
((
double
)
1
)
/
i
;
double
diff
,
eps
=
1.0e-7
;
diff
=
factor
-
test
;
if
(
-
eps
<
diff
&&
diff
<
eps
)
{
n
=
i
;
break
;
}
}
if
(
noblend
||
!
shrink
||
interpolate
)
{
;
}
else
if
(
n
!=
0
)
{
if
(
Nx
%
n
==
0
&&
Ny
%
n
==
0
)
{
static
int
didmsg
=
0
;
if
(
mark
&&
!
didmsg
)
{
didmsg
=
1
;
rfbLog
(
"scale_and_mark_rect: using "
"constant pixel weight speedup "
"for 1/%d
\n
"
,
n
);
}
constant_weights
=
1
;
}
}
/*
* This original way is probably incorrect, giving rise to dx and
* dy that will not exactly line up with the grid for 2/3, etc.
* This gives rise to a whole spectrum of weights, leading to poor
* tightvnc (and other encoding) compression.
*/
#if 0
dx = (double) Nx / nx;
dy = (double) Ny / ny;
#else
n
=
0
;
for
(
i
=
2
;
i
<=
32
;
i
++
)
{
double
test
=
(
double
)
i
;
double
diff
,
eps
=
1.0e-7
;
diff
=
factor
-
test
;
if
(
-
eps
<
diff
&&
diff
<
eps
)
{
n
=
i
;
break
;
}
}
if
(
noblend
&&
factor
>
1
.
0
&&
n
)
{
mag_int
=
n
;
}
}
if
(
mark
&&
factor
>
1
.
0
&&
!
noblend
)
{
/*
* This new way is probably the best we can do, take the inverse
* of the scaling factor to double precision
.
* kludge: correct for interpolating blurring leaking
* up or left 1 destination pixel
.
*/
dx
=
1
.
0
/
scale_fac
;
dy
=
1
.
0
/
scale_fac
;
#endif
if
(
X1
>
0
)
X1
--
;
if
(
Y1
>
0
)
Y1
--
;
}
/*
* find the extent of the change the input rectangle induces in
...
...
@@ -14413,36 +14883,45 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
j1
=
nfix
(
j1
,
ny
);
j2
=
nfix
(
j2
,
ny
)
+
1
;
/*
* There is some speedup if the pixel weights are constant, so
* let's special case these.
*
* If scale = 1/n and n divides Nx and Ny, the pixel weights
* are constant (e.g. 1/2 => equal on 2x2 square).
*/
if
(
constant_weights
<
0
)
{
int
n
=
0
;
constant_weights
=
0
;
for
(
i
=
2
;
i
<=
128
;
i
++
)
{
double
test
=
((
double
)
1
)
/
i
;
double
diff
,
eps
=
1.0e-7
;
diff
=
scale_fac
-
test
;
if
(
-
eps
<
diff
&&
diff
<
eps
)
{
n
=
i
;
break
;
/* special case integer magnification with no blending */
if
(
mark
&&
noblend
&&
mag_int
&&
Bpp
!=
3
)
{
int
jmin
,
jmax
,
imin
,
imax
;
/* outer loop over *source* pixels */
for
(
J
=
Y1
;
J
<
Y2
;
J
++
)
{
jmin
=
J
*
mag_int
;
jmax
=
jmin
+
mag_int
;
for
(
I
=
X1
;
I
<
X2
;
I
++
)
{
/* extract value */
src
=
src_fb
+
J
*
src_bytes_per_line
+
I
*
Bpp
;
if
(
Bpp
==
4
)
{
ui
=
*
((
unsigned
int
*
)
src
);
}
else
if
(
Bpp
==
2
)
{
us
=
*
((
unsigned
short
*
)
src
);
}
else
if
(
Bpp
==
1
)
{
uc
=
*
((
unsigned
char
*
)
src
);
}
imin
=
I
*
mag_int
;
imax
=
imin
+
mag_int
;
/* inner loop over *dest* pixels */
for
(
j
=
jmin
;
j
<
jmax
;
j
++
)
{
dest
=
dst_fb
+
j
*
dst_bytes_per_line
+
imin
*
Bpp
;
for
(
i
=
imin
;
i
<
imax
;
i
++
)
{
if
(
Bpp
==
4
)
{
*
((
unsigned
int
*
)
dest
)
=
ui
;
}
else
if
(
Bpp
==
2
)
{
*
((
unsigned
short
*
)
dest
)
=
us
;
}
else
if
(
Bpp
==
1
)
{
*
((
unsigned
char
*
)
dest
)
=
uc
;
}
dest
+=
Bpp
;
}
}
if
(
scaling_noblend
||
!
shrink
)
{
;
}
else
if
(
n
!=
0
)
{
if
(
Nx
%
n
==
0
&&
Ny
%
n
==
0
)
{
rfbLog
(
"scale_and_mark_rect: using constant "
"pixel weight speedup for 1/%d
\n
"
,
n
);
constant_weights
=
1
;
}
}
goto
markit
;
}
/* set these all to 1.0 to begin with */
wx
=
1
.
0
;
wy
=
1
.
0
;
...
...
@@ -14463,7 +14942,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
J1
=
(
int
)
FLOOR
(
y1
);
J1
=
nfix
(
J1
,
Ny
);
if
(
shrink
)
{
if
(
shrink
&&
!
interpolate
)
{
J2
=
(
int
)
CEIL
(
y2
)
-
1
;
J2
=
nfix
(
J2
,
Ny
);
}
else
{
...
...
@@ -14472,9 +14951,10 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
}
/* destination char* pointer: */
dest
=
rfb_fb
+
j
*
rfb
_bytes_per_line
+
i1
*
Bpp
;
dest
=
dst_fb
+
j
*
dst
_bytes_per_line
+
i1
*
Bpp
;
for
(
i
=
i1
;
i
<
i2
;
i
++
)
{
x1
=
i
*
dx
;
/* left edge */
if
(
x1
>
Nx
-
1
)
{
/* can go over with dx = 1/scale_fac */
...
...
@@ -14488,7 +14968,32 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
I1
=
(
int
)
FLOOR
(
x1
);
if
(
I1
>=
Nx
)
I1
=
Nx
-
1
;
if
(
shrink
)
{
if
(
noblend
&&
use_noblend_shortcut
)
{
/*
* The noblend case involves no weights,
* and 1 pixel, so just copy the value
* directly.
*/
src
=
src_fb
+
J1
*
src_bytes_per_line
+
I1
*
Bpp
;
if
(
Bpp
==
4
)
{
*
((
unsigned
int
*
)
dest
)
=
*
((
unsigned
int
*
)
src
);
}
else
if
(
Bpp
==
2
)
{
*
((
unsigned
short
*
)
dest
)
=
*
((
unsigned
short
*
)
src
);
}
else
if
(
Bpp
==
1
)
{
*
(
dest
)
=
*
(
src
);
}
else
if
(
Bpp
==
3
)
{
/* rare case */
for
(
k
=
0
;
k
<=
2
;
k
++
)
{
*
(
dest
+
k
)
=
*
(
src
+
k
);
}
}
dest
+=
Bpp
;
continue
;
}
if
(
shrink
&&
!
interpolate
)
{
I2
=
(
int
)
CEIL
(
x2
)
-
1
;
if
(
I2
>=
Nx
)
I2
=
Nx
-
1
;
}
else
{
...
...
@@ -14517,19 +15022,22 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
* after the J > 0 data have been accessed and
* we are at j, i+1, J=0? The stride in J is
* main_bytes_per_line, and so ~4 KB.
*
* Typical case when shrinking are 2x2 loop, so
* just two lines to worry about.
*/
for
(
J
=
J1
;
J
<=
J2
;
J
++
)
{
/* see comments for I, x1, x2, etc. below */
if
(
constant_weights
)
{
;
}
else
if
(
scaling_
noblend
)
{
}
else
if
(
noblend
)
{
if
(
J
!=
J1
)
{
continue
;
}
wy
=
1
.
0
;
/* interpolation scheme: */
}
else
if
(
!
shrink
)
{
}
else
if
(
!
shrink
||
interpolate
)
{
if
(
J
>=
Ny
)
{
continue
;
}
else
if
(
J
==
J1
)
{
...
...
@@ -14547,7 +15055,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
wy
=
1
.
0
;
}
src
=
main_fb
+
J
*
main
_bytes_per_line
+
I1
*
Bpp
;
src
=
src_fb
+
J
*
src
_bytes_per_line
+
I1
*
Bpp
;
for
(
I
=
I1
;
I
<=
I2
;
I
++
)
{
...
...
@@ -14555,7 +15063,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
if
(
constant_weights
)
{
;
}
else
if
(
scaling_
noblend
)
{
}
else
if
(
noblend
)
{
/*
* Ugh, PseudoColor colormap is
* bad news, to avoid random
...
...
@@ -14569,7 +15077,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
wx
=
1
.
0
;
/* interpolation scheme: */
}
else
if
(
!
shrink
)
{
}
else
if
(
!
shrink
||
interpolate
)
{
if
(
I
>=
Nx
)
{
continue
;
/* off edge */
}
else
if
(
I
==
I1
)
{
...
...
@@ -14605,7 +15113,6 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
w
=
wx
*
wy
;
wtot
+=
w
;
/*
* We average the unsigned char value
* instead of char value: otherwise
...
...
@@ -14613,21 +15120,34 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
* to the maximum (char -1)! This way
* they are spread between 0 and 255.
*/
if
(
Bpp
!=
2
)
{
for
(
b
=
0
;
b
<
Bpp
;
b
++
)
{
pixave
[
b
]
+=
w
*
((
unsigned
char
)
*
(
src
+
b
));
}
}
else
{
if
(
Bpp
==
4
)
{
/* unroll the loops, can give 20% */
pixave
[
0
]
+=
w
*
((
unsigned
char
)
*
(
src
));
pixave
[
1
]
+=
w
*
((
unsigned
char
)
*
(
src
+
1
));
pixave
[
2
]
+=
w
*
((
unsigned
char
)
*
(
src
+
2
));
pixave
[
3
]
+=
w
*
((
unsigned
char
)
*
(
src
+
3
));
}
else
if
(
Bpp
==
2
)
{
/*
* 16bpp: trickier with green
* split over two bytes, so we
* use the masks:
*/
us
=
*
(
(
unsigned
short
*
)
src
);
us
=
*
(
(
unsigned
short
*
)
src
);
pixave
[
0
]
+=
w
*
(
us
&
main_red_mask
);
pixave
[
1
]
+=
w
*
(
us
&
main_green_mask
);
pixave
[
2
]
+=
w
*
(
us
&
main_blue_mask
);
}
else
if
(
Bpp
==
1
)
{
pixave
[
0
]
+=
w
*
((
unsigned
char
)
*
(
src
));
}
else
{
for
(
b
=
0
;
b
<
Bpp
;
b
++
)
{
pixave
[
b
]
+=
w
*
((
unsigned
char
)
*
(
src
+
b
));
}
}
src
+=
Bpp
;
}
...
...
@@ -14639,11 +15159,12 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
wtot
=
1
.
0
/
wtot
;
/* normalization factor */
/* place weighted average pixel in the scaled fb: */
if
(
Bpp
!=
2
)
{
for
(
b
=
0
;
b
<
Bpp
;
b
++
)
{
*
(
dest
+
b
)
=
(
char
)
(
wtot
*
pixave
[
b
]);
}
}
else
{
if
(
Bpp
==
4
)
{
*
(
dest
)
=
(
char
)
(
wtot
*
pixave
[
0
]);
*
(
dest
+
1
)
=
(
char
)
(
wtot
*
pixave
[
1
]);
*
(
dest
+
2
)
=
(
char
)
(
wtot
*
pixave
[
2
]);
*
(
dest
+
3
)
=
(
char
)
(
wtot
*
pixave
[
3
]);
}
else
if
(
Bpp
==
2
)
{
/* 16bpp / 565 case: */
pixave
[
0
]
*=
wtot
;
pixave
[
1
]
*=
wtot
;
...
...
@@ -14652,12 +15173,37 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
|
(
main_green_mask
&
(
int
)
pixave
[
1
])
|
(
main_blue_mask
&
(
int
)
pixave
[
2
]);
*
(
(
unsigned
short
*
)
dest
)
=
us
;
}
else
if
(
Bpp
==
1
)
{
*
(
dest
)
=
(
char
)
(
wtot
*
pixave
[
0
]);
}
else
{
for
(
b
=
0
;
b
<
Bpp
;
b
++
)
{
*
(
dest
+
b
)
=
(
char
)
(
wtot
*
pixave
[
b
]);
}
}
dest
+=
Bpp
;
}
}
markit:
if
(
mark
)
{
mark_rect_as_modified
(
i1
,
j1
,
i2
,
j2
,
1
);
}
}
static
void
scale_and_mark_rect
(
int
X1
,
int
Y1
,
int
X2
,
int
Y2
)
{
if
(
!
screen
||
!
rfb_fb
||
!
main_fb
)
{
return
;
}
if
(
!
screen
->
serverFormat
.
trueColour
)
{
/*
* PseudoColor colormap... blending leads to random colors.
*/
scaling_noblend
=
1
;
}
scale_rect
(
scale_fac
,
scaling_noblend
,
scaling_interpolate
,
bpp
/
8
,
main_fb
,
main_bytes_per_line
,
rfb_fb
,
rfb_bytes_per_line
,
dpy_x
,
dpy_y
,
scaled_x
,
scaled_y
,
X1
,
Y1
,
X2
,
Y2
,
1
);
}
void
mark_rect_as_modified
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
force
)
{
...
...
@@ -15449,6 +15995,7 @@ int copy_snap(void) {
* Utilities for managing the "naps" to cut down on amount of polling.
*/
static
void
nap_set
(
int
tile_cnt
)
{
int
nap_in
=
nap_ok
;
if
(
scan_count
==
0
)
{
/* roll up check for all NSCAN scans */
...
...
@@ -15459,6 +16006,12 @@ static void nap_set(int tile_cnt) {
}
nap_diff_count
=
0
;
}
if
(
nap_ok
&&
!
nap_in
&&
using_xdamage
)
{
if
(
XD_skip
>
0
.
8
*
XD_tot
)
{
/* X DAMAGE is keeping load low, so skip nap */
nap_ok
=
0
;
}
}
if
(
show_cursor
)
{
/* kludge for the up to 4 tiles the mouse patch could occupy */
...
...
@@ -17315,6 +17868,7 @@ static void print_help(int mode) {
" the full display). This also works for -id/-sid mode
\n
"
" where the offset is relative to the upper left corner
\n
"
" of the selected window.
\n
"
"
\n
"
"-flashcmap In 8bpp indexed color, let the installed colormap flash
\n
"
" as the pointer moves from window to window (slow).
\n
"
"-notruecolor For 8bpp displays, force indexed color (i.e. a colormap)
\n
"
...
...
@@ -17326,7 +17880,7 @@ static void print_help(int mode) {
" and for some workarounds. n may be a decimal number,
\n
"
" or 0x hex. Run xdpyinfo(1) for the values. One may
\n
"
" also use
\"
TrueColor
\"
, etc. see <X11/X.h> for a list.
\n
"
" If the string ends in
\"
:m
\"
the for better or for
\n
"
" If the string ends in
\"
:m
\"
the
n
for better or for
\n
"
" worse the visual depth is forced to be m.
\n
"
"-overlay Handle multiple depth visuals on one screen, e.g. 8+24
\n
"
" and 24+8 overlay visuals (the 32 bits per pixel are
\n
"
...
...
@@ -17360,9 +17914,8 @@ static void print_help(int mode) {
" cursor shape using the overlay mechanism.
\n
"
"
\n
"
"-scale fraction Scale the framebuffer by factor
\"
fraction
\"
. Values
\n
"
" less than 1 shrink the fb, larger ones expand it.
\n
"
" Note: image may not be sharp and response may be
\n
"
" slower. Currently the cursor shape is not scaled.
\n
"
" less than 1 shrink the fb, larger ones expand it. Note:
\n
"
" image may not be sharp and response may be slower.
\n
"
" If
\"
fraction
\"
contains a decimal point
\"
.
\"
it
\n
"
" is taken as a floating point number, alternatively
\n
"
" the notation
\"
m/n
\"
may be used to denote fractions
\n
"
...
...
@@ -17379,6 +17932,15 @@ static void print_help(int mode) {
" pad scaled width and height to be multiples of scaling
\n
"
" denominator (e.g. 3 for 2/3).
\n
"
"
\n
"
"-scale_cursor frac By default if -scale is supplied the cursor shape is
\n
"
" scaled by the same factor. Depending on your usage,
\n
"
" you may want to scale the cursor independently of the
\n
"
" screen or not at all. If you specify -scale_cursor
\n
"
" the cursor will be scaled by that factor. When using
\n
"
" -scale mode to keep the cursor at its
\"
natural
\"
size
\n
"
" use
\"
-scale_cursor 1
\"
. Most of the
\"
:
\"
scaling
\n
"
" options apply here as well.
\n
"
"
\n
"
"-viewonly All VNC clients can only watch (default %s).
\n
"
"-shared VNC display is shared (default %s).
\n
"
"-once Exit after the first successfully connected viewer
\n
"
...
...
@@ -17746,6 +18308,11 @@ static void print_help(int mode) {
" so this is no loss unless someone is simultaneously at
\n
"
" the real X display. Default: %s
\n
"
"
\n
"
" Use
\"
-norepeat N
\"
to set how many times norepeat will
\n
"
" be reset if something else (e.g. X session manager)
\n
"
" disables it. The default is 2. Use a negative value
\n
"
" for unlimited resets.
\n
"
"
\n
"
"-nofb Ignore video framebuffer: only process keyboard and
\n
"
" pointer. Intended for use with Win2VNC and x2vnc
\n
"
" dual-monitor setups.
\n
"
...
...
@@ -17826,6 +18393,9 @@ static void print_help(int mode) {
" extensions available. On Solaris and IRIX if XFIXES
\n
"
" is not available, -overlay mode will be attempted.
\n
"
"
\n
"
"-arrow n Choose an alternate
\"
arrow
\"
cursor from a set of
\n
"
" some common ones. n can be 1 to %d. Default is: %d
\n
"
"
\n
"
"-noxfixes Do not use the XFIXES extension to draw the exact cursor
\n
"
" shape even if it is available.
\n
"
"-alphacut n When using the XFIXES extension for the cursor shape,
\n
"
...
...
@@ -18144,6 +18714,8 @@ static void print_help(int mode) {
" id:windowid set -id window to
\"
windowid
\"
. empty
\n
"
" or
\"
root
\"
to go back to root window
\n
"
" sid:windowid set -sid window to
\"
windowid
\"\n
"
" waitmapped wait until subwin is mapped.
\n
"
" nowaitmapped do not wait until subwin is mapped.
\n
"
" clip:WxH+X+Y set -clip mode to
\"
WxH+X+Y
\"\n
"
" flashcmap enable -flashcmap mode.
\n
"
" noflashcmap disable -flashcmap mode.
\n
"
...
...
@@ -18156,6 +18728,7 @@ static void print_help(int mode) {
" nooverlay_cursor.
\n
"
" visual:vis set -visual to
\"
vis
\"\n
"
" scale:frac set -scale to
\"
frac
\"\n
"
" scale_cursor:f set -scale_cursor to
\"
f
\"\n
"
" viewonly enable -viewonly mode.
\n
"
/* access view,share,forever */
" noviewonly disable -viewonly mode.
\n
"
...
...
@@ -18257,6 +18830,7 @@ static void print_help(int mode) {
" show_cursor enable showing a cursor.
\n
"
" noshow_cursor disable showing a cursor. (same as
\n
"
"
\"
nocursor
\"
)
\n
"
" arrow:n set -arrow to alternate n.
\n
"
" xfixes enable xfixes cursor shape mode.
\n
"
" noxfixes disable xfixes cursor shape mode.
\n
"
" alphacut:n set -alphacut to n.
\n
"
...
...
@@ -18356,27 +18930,27 @@ static void print_help(int mode) {
" the returned value corresponds to (hint: the ext_*
\n
"
" variables correspond to the presence of X extensions):
\n
"
"
\n
"
" ans= stop quit exit shutdown ping blacken zero
\n
"
" re
fresh reset close disconnect id sid clip
waitmapped
\n
"
"
nowaitmapped
flashcmap noflashcmap truecolor notruecolor
\n
"
" ans= stop quit exit shutdown ping blacken zero
refresh
\n
"
" re
set close disconnect id sid waitmapped no
waitmapped
\n
"
"
clip
flashcmap noflashcmap truecolor notruecolor
\n
"
" overlay nooverlay overlay_cursor overlay_yescursor
\n
"
" nooverlay_nocursor nooverlay_cursor nooverlay_yescursor
\n
"
" overlay_nocursor visual scale
viewonly no
viewonly
\n
"
"
shared noshared forever noforever once timeout deny
\n
"
"
lock nodeny unlock connect allowonce allow localhost
\n
"
"
nolocalhost listen accept gone shm noshm flipbyteorder
\n
"
"
noflipbyteorder onetile noonetile solid_color solid
\n
"
" no
solid blackout xinerama noxinerama xrandr noxrandr
\n
"
"
xrandr_mode padgeom quiet q noquiet modtweak nomodtweak
\n
"
"
xkb noxkb skip_keycodes add_keysyms noadd_keysym
s
\n
"
"
clear_mods noclear_mods clear_keys noclear_key
s
\n
"
"
remap repeat norepeat fb nofb bell nobell sel
\n
"
"
nosel primary noprimary cursorshape no
cursorshape
\n
"
"
cursorpos nocursorpos cursor show_cursor no
show_cursor
\n
"
" no
cursor xfixes noxfixes xdamage noxdamage xd_area
\n
"
"
xd_mem alphacut alphafrac alpharemove no
alpharemove
\n
"
"
alphablend noalphablend xwarp xwarppointer noxwarp
\n
"
" noxwarppointer buttonmap dragging nodragging
\n
"
" overlay_nocursor visual scale
scale_cursor
viewonly
\n
"
"
noviewonly shared noshared forever noforever once
\n
"
"
timeout deny lock nodeny unlock connect allowonce
\n
"
"
allow localhost nolocalhost listen accept gone
\n
"
"
shm noshm flipbyteorder noflipbyteorder onetile
\n
"
" no
onetile solid_color solid nosolid blackout xinerama
\n
"
"
noxinerama xrandr noxrandr xrandr_mode padgeom quiet
\n
"
"
q noquiet modtweak nomodtweak xkb noxkb skip_keycode
s
\n
"
"
add_keysyms noadd_keysyms clear_mods noclear_mod
s
\n
"
"
clear_keys noclear_keys remap repeat norepeat fb nofb
\n
"
"
bell nobell sel nosel primary noprimary
cursorshape
\n
"
"
nocursorshape cursorpos nocursorpos cursor
show_cursor
\n
"
" no
show_cursor nocursor arrow xfixes noxfixes xdamage
\n
"
"
noxdamage xd_area xd_mem alphacut alphafrac
alpharemove
\n
"
"
noalpharemove alphablend noalphablend xwarp xwarppointer
\n
"
" noxwarp
noxwarp
pointer buttonmap dragging nodragging
\n
"
" pointer_mode pm input_skip input client_input speeds
\n
"
" debug_pointer dp nodebug_pointer nodp debug_keyboard dk
\n
"
" nodebug_keyboard nodk deferupdate defer wait rfbwait
\n
"
...
...
@@ -18486,6 +19060,7 @@ static void print_help(int mode) {
vnc_connect
?
"-vncconnect"
:
"-novncconnect"
,
use_modifier_tweak
?
"-modtweak"
:
"-nomodtweak"
,
no_autorepeat
?
"-norepeat"
:
"-repeat"
,
alt_arrow_max
,
alt_arrow
,
alpha_threshold
,
alpha_frac
,
cursor_pos_updates
?
"-cursorpos"
:
"-nocursorpos"
,
...
...
@@ -18968,6 +19543,9 @@ int main(int argc, char* argv[]) {
}
else
if
(
!
strcmp
(
arg
,
"-scale"
))
{
CHECK_ARGC
scale_str
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-scale_cursor"
))
{
CHECK_ARGC
scale_cursor_str
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-viewonly"
))
{
view_only
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-shared"
))
{
...
...
@@ -19114,6 +19692,15 @@ int main(int argc, char* argv[]) {
remap_file
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-norepeat"
))
{
no_autorepeat
=
1
;
if
(
i
<
argc
-
1
)
{
char
*
s
=
argv
[
i
+
1
];
if
(
*
s
==
'-'
)
{
s
++
;
}
if
(
isdigit
(
*
s
))
{
no_repeat_countdown
=
atoi
(
argv
[
++
i
]);
}
}
}
else
if
(
!
strcmp
(
arg
,
"-repeat"
))
{
no_autorepeat
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-nofb"
))
{
...
...
@@ -19139,6 +19726,9 @@ int main(int argc, char* argv[]) {
}
else
if
(
!
strcmp
(
arg
,
"-nocursor"
))
{
multiple_cursors_mode
=
strdup
(
"none"
);
show_cursor
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-arrow"
))
{
CHECK_ARGC
alt_arrow
=
atoi
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-noxfixes"
))
{
use_xfixes
=
0
;
}
else
if
(
!
strcmp
(
arg
,
"-alphacut"
))
{
...
...
@@ -19639,6 +20229,7 @@ int main(int argc, char* argv[]) {
fprintf
(
stderr
,
" remap: %s
\n
"
,
remap_file
?
remap_file
:
"null"
);
fprintf
(
stderr
,
" norepeat: %d
\n
"
,
no_autorepeat
);
fprintf
(
stderr
,
" norepeatcnt:%d
\n
"
,
no_repeat_countdown
);
fprintf
(
stderr
,
" nofb: %d
\n
"
,
nofb
);
fprintf
(
stderr
,
" watchbell: %d
\n
"
,
watch_bell
);
fprintf
(
stderr
,
" watchsel: %d
\n
"
,
watch_selection
);
...
...
@@ -19711,11 +20302,12 @@ int main(int argc, char* argv[]) {
if
(
xkbcompat
)
{
Bool
rc
=
XkbIgnoreExtension
(
True
);
if
(
!
quiet
)
{
rfbLog
(
"disabling xkb extension. rc=%d
\n
"
,
rc
);
rfbLog
(
"Disabling xkb XKEYBOARD extension. rc=%d
\n
"
,
rc
);
}
if
(
watch_bell
)
{
watch_bell
=
0
;
if
(
!
quiet
)
rfbLog
(
"
d
isabling bell.
\n
"
);
if
(
!
quiet
)
rfbLog
(
"
D
isabling bell.
\n
"
);
}
}
#else
...
...
@@ -19792,7 +20384,7 @@ int main(int argc, char* argv[]) {
#if LIBVNCSERVER_HAVE_LIBXFIXES
if
(
!
XFixesQueryExtension
(
dpy
,
&
xfixes_base_event_type
,
&
er
))
{
if
(
!
quiet
)
{
rfbLog
(
"
disabling xfixes
mode: display does not "
rfbLog
(
"
Disabling XFIXES
mode: display does not "
"support it.
\n
"
);
}
xfixes_present
=
0
;
...
...
@@ -19803,8 +20395,8 @@ int main(int argc, char* argv[]) {
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
if
(
!
XDamageQueryExtension
(
dpy
,
&
xdamage_base_event_type
,
&
er
))
{
if
(
0
&&
!
quiet
)
{
rfbLog
(
"
disabling xdamage
mode: display does not "
if
(
!
quiet
)
{
rfbLog
(
"
Disabling X DAMAGE
mode: display does not "
"support it.
\n
"
);
}
xdamage_present
=
0
;
...
...
@@ -19823,7 +20415,7 @@ int main(int argc, char* argv[]) {
#ifdef SOLARIS_OVERLAY
if
(
!
XQueryExtension
(
dpy
,
"SUN_OVL"
,
&
maj
,
&
ev
,
&
er
))
{
if
(
!
quiet
&&
overlay
)
{
rfbLog
(
"
d
isabling -overlay: SUN_OVL "
rfbLog
(
"
D
isabling -overlay: SUN_OVL "
"extension not available.
\n
"
);
}
}
else
{
...
...
@@ -19833,7 +20425,7 @@ int main(int argc, char* argv[]) {
#ifdef IRIX_OVERLAY
if
(
!
XReadDisplayQueryExtension
(
dpy
,
&
ev
,
&
er
))
{
if
(
!
quiet
&&
overlay
)
{
rfbLog
(
"
d
isabling -overlay: IRIX ReadDisplay "
rfbLog
(
"
D
isabling -overlay: IRIX ReadDisplay "
"extension not available.
\n
"
);
}
}
else
{
...
...
@@ -19906,11 +20498,20 @@ int main(int argc, char* argv[]) {
/* check for XTEST */
if
(
!
XTestQueryExtension_wr
(
dpy
,
&
ev
,
&
er
,
&
maj
,
&
min
))
{
if
(
!
quiet
)
{
rfbLog
(
"warning: XTest extension not available, most user"
" input
\n
"
);
rfbLog
(
"(pointer and keyboard) will be discarded.
\n
"
);
rfbLog
(
"no XTest extension, switching to -xwarppointer mode
\n
"
);
rfbLog
(
"for pointer motion input.
\n
"
);
rfbLog
(
"WARNING: XTEST extension not available "
"(either missing from
\n
"
);
rfbLog
(
" display or client library libXtst "
"missing at build time).
\n
"
);
rfbLog
(
" MOST user input (pointer and keyboard) "
"will be DISCARDED.
\n
"
);
rfbLog
(
" If display does have XTEST, be sure to "
"build x11vnc with
\n
"
);
rfbLog
(
" a working libXtst build environment "
"(e.g. libxtst-dev,
\n
"
);
rfbLog
(
" or other packages).
\n
"
);
rfbLog
(
"No XTEST extension, switching to "
"-xwarppointer mode for
\n
"
);
rfbLog
(
" pointer motion input.
\n
"
);
}
xtest_present
=
0
;
use_xwarppointer
=
1
;
...
...
@@ -19980,8 +20581,8 @@ int main(int argc, char* argv[]) {
#if LIBVNCSERVER_HAVE_LIBXRANDR
if
(
!
XRRQueryExtension
(
dpy
,
&
xrandr_base_event_type
,
&
er
))
{
if
(
xrandr
&&
!
quiet
)
{
rfbLog
(
"
d
isabling -xrandr mode: display does not"
" support
it
.
\n
"
);
rfbLog
(
"
D
isabling -xrandr mode: display does not"
" support
X RANDR
.
\n
"
);
}
xrandr
=
0
;
xrandr_present
=
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment