You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
10499 lines
302 KiB
10499 lines
302 KiB
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/Vncviewer vnc_unixsrc/vncviewer/Vncviewer
|
|
--- vnc_unixsrc.orig/vncviewer/Vncviewer 2003-02-07 05:30:57.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/Vncviewer 2007-04-05 23:13:59.000000000 -0400
|
|
@@ -5,9 +5,9 @@
|
|
|
|
!
|
|
! The title of the main window. "%s" will be replaced by the desktop name.
|
|
-!
|
|
+!
|
|
|
|
-Vncviewer.title: TightVNC: %s
|
|
+Vncviewer.title: SSVNC: %s Press F8 for Menu
|
|
|
|
|
|
!
|
|
@@ -50,6 +50,7 @@
|
|
|
|
*desktop.baseTranslations:\
|
|
<Key>F8: ShowPopup()\n\
|
|
+ <Key>F9: ToggleFullScreen()\n\
|
|
<ButtonPress>: SendRFBEvent()\n\
|
|
<ButtonRelease>: SendRFBEvent()\n\
|
|
<Motion>: SendRFBEvent()\n\
|
|
@@ -77,9 +78,9 @@
|
|
! Popup window appearance
|
|
!
|
|
|
|
-*popup.title: TightVNC popup
|
|
+*popup.title: SSVNC popup
|
|
*popup*background: grey
|
|
-*popup*font: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*
|
|
+*popup*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*
|
|
*popup.buttonForm.Command.borderWidth: 0
|
|
*popup.buttonForm.Toggle.borderWidth: 0
|
|
|
|
@@ -96,43 +97,160 @@
|
|
! Popup buttons
|
|
!
|
|
|
|
-*popupButtonCount: 8
|
|
+*popupButtonCount: 28
|
|
|
|
*popup*button1.label: Dismiss popup
|
|
-*popup*button1.translations: #override\n\
|
|
- <Btn1Down>,<Btn1Up>: HidePopup()
|
|
+*popup*button1.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: HidePopup()
|
|
|
|
*popup*button2.label: Quit viewer
|
|
-*popup*button2.translations: #override\n\
|
|
- <Btn1Down>,<Btn1Up>: Quit()
|
|
+*popup*button2.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: Quit()
|
|
|
|
-*popup*button3.label: Full screen
|
|
+*popup*button3.label: Full screen (also F9)
|
|
*popup*button3.type: toggle
|
|
-*popup*button3.translations: #override\n\
|
|
- <Visible>: SetFullScreenState()\n\
|
|
- <Btn1Down>,<Btn1Up>: toggle() HidePopup() ToggleFullScreen()
|
|
+*popup*button3.translations: #override\\n\
|
|
+ <Visible>: SetFullScreenState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleFullScreen() HidePopup()
|
|
|
|
*popup*button4.label: Clipboard: local -> remote
|
|
-*popup*button4.translations: #override\n\
|
|
- <Btn1Down>,<Btn1Up>: SelectionToVNC(always) HidePopup()
|
|
+*popup*button4.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SelectionToVNC(always) HidePopup()
|
|
|
|
*popup*button5.label: Clipboard: local <- remote
|
|
-*popup*button5.translations: #override\n\
|
|
- <Btn1Down>,<Btn1Up>: SelectionFromVNC(always) HidePopup()
|
|
+*popup*button5.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SelectionFromVNC(always) HidePopup()
|
|
|
|
*popup*button6.label: Request refresh
|
|
-*popup*button6.translations: #override\n\
|
|
- <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate) HidePopup()
|
|
+*popup*button6.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate) HidePopup()
|
|
|
|
*popup*button7.label: Send ctrl-alt-del
|
|
-*popup*button7.translations: #override\n\
|
|
- <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L)\
|
|
- SendRFBEvent(keydown,Alt_L)\
|
|
- SendRFBEvent(key,Delete)\
|
|
- SendRFBEvent(keyup,Alt_L)\
|
|
- SendRFBEvent(keyup,Control_L)\
|
|
- HidePopup()
|
|
+*popup*button7.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L)\
|
|
+ SendRFBEvent(keydown,Alt_L)\
|
|
+ SendRFBEvent(key,Delete)\
|
|
+ SendRFBEvent(keyup,Alt_L)\
|
|
+ SendRFBEvent(keyup,Control_L)\
|
|
+ HidePopup()
|
|
|
|
*popup*button8.label: Send F8
|
|
-*popup*button8.translations: #override\n\
|
|
- <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup()
|
|
+*popup*button8.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup()
|
|
+
|
|
+*popup*button9.label: Send F9
|
|
+*popup*button9.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F9) HidePopup()
|
|
+
|
|
+*popup*button10.label: ViewOnly
|
|
+*popup*button10.type: toggle
|
|
+*popup*button10.translations: #override\\n\
|
|
+ <Visible>: SetViewOnlyState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleViewOnly() HidePopup()
|
|
+
|
|
+*popup*button11.label: Disable Bell
|
|
+*popup*button11.type: toggle
|
|
+*popup*button11.translations: #override\\n\
|
|
+ <Visible>: SetBellState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleBell() HidePopup()
|
|
+
|
|
+*popup*button12.label: Cursor Shape
|
|
+*popup*button12.type: toggle
|
|
+*popup*button12.translations: #override\\n\
|
|
+ <Visible>: SetCursorShapeState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorShape() HidePopup()
|
|
+
|
|
+*popup*button13.label: X11 Cursor
|
|
+*popup*button13.type: toggle
|
|
+*popup*button13.translations: #override\\n\
|
|
+ <Visible>: SetX11CursorState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleX11Cursor() HidePopup()
|
|
+
|
|
+*popup*button14.label: Cursor Alphablend
|
|
+*popup*button14.type: toggle
|
|
+*popup*button14.translations: #override\\n\
|
|
+ <Visible>: SetCursorAlphaState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorAlpha() HidePopup()
|
|
+
|
|
+*popup*button15.label: Toggle Tight/ZRLE
|
|
+*popup*button15.type: toggle
|
|
+*popup*button15.translations: #override\\n\
|
|
+ <Visible>: SetZRLEState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleTightZRLE() HidePopup()
|
|
+
|
|
+*popup*button16.label: Disable JPEG
|
|
+*popup*button16.type: toggle
|
|
+*popup*button16.translations: #override\\n\
|
|
+ <Visible>: SetNOJPEGState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleJPEG() HidePopup()
|
|
+
|
|
+*popup*button17.label: Prefer raw for localhost
|
|
+*popup*button17.type: toggle
|
|
+*popup*button17.translations: #override\\n\
|
|
+ <Visible>: SetRawLocalState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleRawLocal() HidePopup()
|
|
+
|
|
+*popup*button18.label: Full Color
|
|
+*popup*button18.type: toggle
|
|
+*popup*button18.translations: #override\\n\
|
|
+ <Visible>: SetFullColorState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleFullColor() HidePopup()
|
|
+
|
|
+*popup*button19.label: Grey Scale (16 & 8-bpp)
|
|
+*popup*button19.type: toggle
|
|
+*popup*button19.translations: #override\\n\
|
|
+ <Visible>: SetGreyScaleState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleGreyScale() HidePopup()
|
|
+
|
|
+*popup*button20.label: 16 bit color (BGR565)
|
|
+*popup*button20.type: toggle
|
|
+*popup*button20.translations: #override\\n\
|
|
+ <Visible>: Set16bppState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle16bpp() HidePopup()
|
|
+
|
|
+*popup*button21.label: 8 bit color (BGR233)
|
|
+*popup*button21.type: toggle
|
|
+*popup*button21.translations: #override\\n\
|
|
+ <Visible>: Set8bppState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle8bpp() HidePopup()
|
|
+
|
|
+*popup*button22.label: - 256 colors
|
|
+*popup*button22.type: toggle
|
|
+*popup*button22.translations: #override\\n\
|
|
+ <Visible>: Set256ColorsState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle256Colors() HidePopup()
|
|
+
|
|
+*popup*button23.label: - 64 colors
|
|
+*popup*button23.type: toggle
|
|
+*popup*button23.translations: #override\\n\
|
|
+ <Visible>: Set64ColorsState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle64Colors() HidePopup()
|
|
+
|
|
+*popup*button24.label: - 8 colors
|
|
+*popup*button24.type: toggle
|
|
+*popup*button24.translations: #override\\n\
|
|
+ <Visible>: Set8ColorsState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle8Colors() HidePopup()
|
|
+
|
|
+*popup*button25.label: Disable Remote Input
|
|
+*popup*button25.type: toggle
|
|
+*popup*button25.translations: #override\\n\
|
|
+ <Visible>: SetServerInputState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleServerInput() HidePopup()
|
|
+
|
|
+*popup*button26.label: Single Window
|
|
+*popup*button26.type: toggle
|
|
+*popup*button26.translations: #override\\n\
|
|
+ <Visible>: SetSingleWindowState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleSingleWindow() HidePopup()
|
|
+
|
|
+*popup*button27.label: Set 1/n Server Scale
|
|
+*popup*button27.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: DoServerScale() HidePopup()
|
|
+
|
|
+*popup*button28.label: Text Chat
|
|
+*popup*button28.type: toggle
|
|
+*popup*button28.translations: #override\\n\
|
|
+ <Visible>: SetTextChatState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleTextChat() HidePopup()
|
|
+
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/vncviewer/argsresources.c
|
|
--- vnc_unixsrc.orig/vncviewer/argsresources.c 2007-02-04 17:10:31.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/argsresources.c 2007-05-21 11:08:21.000000000 -0400
|
|
@@ -31,7 +31,7 @@
|
|
|
|
char *fallback_resources[] = {
|
|
|
|
- "Vncviewer.title: TightVNC: %s",
|
|
+ "Vncviewer.title: SSVNC: %s - Press F8 for Menu",
|
|
|
|
"Vncviewer.translations:\
|
|
<Enter>: SelectionToVNC()\\n\
|
|
@@ -45,8 +45,14 @@
|
|
"*viewport.useRight: True",
|
|
"*viewport*Scrollbar*thumb: None",
|
|
|
|
+ "*viewport.horizontal.height: 6 ",
|
|
+ "*viewport.vertical.width: 6 ",
|
|
+ "vncviewer*viewport.horizontal.height: 6 ",
|
|
+ "vncviewer*viewport.vertical.width: 6 ",
|
|
+
|
|
"*desktop.baseTranslations:\
|
|
- <Key>F8: ShowPopup()\\n\
|
|
+ <Key>F8: ShowPopup()\\n\
|
|
+ <Key>F9: ToggleFullScreen()\\n\
|
|
<ButtonPress>: SendRFBEvent()\\n\
|
|
<ButtonRelease>: SendRFBEvent()\\n\
|
|
<Motion>: SendRFBEvent()\\n\
|
|
@@ -64,17 +70,25 @@
|
|
"*passwordDialog.dialog.value.translations: #override\\n\
|
|
<Key>Return: PasswordDialogDone()",
|
|
|
|
- "*popup.title: TightVNC popup",
|
|
+ "*popup.title: SSVNC popup",
|
|
"*popup*background: grey",
|
|
- "*popup*font: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*",
|
|
+ "*popup*font_old: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*",
|
|
+ "*popup*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*",
|
|
"*popup.buttonForm.Command.borderWidth: 0",
|
|
"*popup.buttonForm.Toggle.borderWidth: 0",
|
|
|
|
+ "*scaleN.title: 1/n scale",
|
|
+ "*scaleN*background: grey",
|
|
+ "*scaleN*font_old: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*",
|
|
+ "*scaleN*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*",
|
|
+ "*scaleN.buttonForm.Command.borderWidth: 0",
|
|
+ "*scaleN.buttonForm.Toggle.borderWidth: 0",
|
|
+
|
|
"*popup.translations: #override <Message>WM_PROTOCOLS: HidePopup()",
|
|
"*popup.buttonForm.translations: #override\\n\
|
|
<KeyPress>: SendRFBEvent() HidePopup()",
|
|
|
|
- "*popupButtonCount: 8",
|
|
+ "*popupButtonCount: 28",
|
|
|
|
"*popup*button1.label: Dismiss popup",
|
|
"*popup*button1.translations: #override\\n\
|
|
@@ -84,7 +98,7 @@
|
|
"*popup*button2.translations: #override\\n\
|
|
<Btn1Down>,<Btn1Up>: Quit()",
|
|
|
|
- "*popup*button3.label: Full screen",
|
|
+ "*popup*button3.label: Full screen (also F9)",
|
|
"*popup*button3.type: toggle",
|
|
"*popup*button3.translations: #override\\n\
|
|
<Visible>: SetFullScreenState()\\n\
|
|
@@ -115,9 +129,166 @@
|
|
"*popup*button8.translations: #override\\n\
|
|
<Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup()",
|
|
|
|
+ "*popup*button9.label: Send F9",
|
|
+ "*popup*button9.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F9) HidePopup()",
|
|
+
|
|
+ "*popup*button10.label: ViewOnly",
|
|
+ "*popup*button10.type: toggle",
|
|
+ "*popup*button10.translations: #override\\n\
|
|
+ <Visible>: SetViewOnlyState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleViewOnly() HidePopup()",
|
|
+
|
|
+ "*popup*button11.label: Disable Bell",
|
|
+ "*popup*button11.type: toggle",
|
|
+ "*popup*button11.translations: #override\\n\
|
|
+ <Visible>: SetBellState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleBell() HidePopup()",
|
|
+
|
|
+ "*popup*button12.label: Cursor Shape",
|
|
+ "*popup*button12.type: toggle",
|
|
+ "*popup*button12.translations: #override\\n\
|
|
+ <Visible>: SetCursorShapeState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorShape() HidePopup()",
|
|
+
|
|
+ "*popup*button13.label: X11 Cursor",
|
|
+ "*popup*button13.type: toggle",
|
|
+ "*popup*button13.translations: #override\\n\
|
|
+ <Visible>: SetX11CursorState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleX11Cursor() HidePopup()",
|
|
+
|
|
+ "*popup*button14.label: Cursor Alphablend",
|
|
+ "*popup*button14.type: toggle",
|
|
+ "*popup*button14.translations: #override\\n\
|
|
+ <Visible>: SetCursorAlphaState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorAlpha() HidePopup()",
|
|
+
|
|
+ "*popup*button15.label: Toggle Tight/ZRLE",
|
|
+ "*popup*button15.type: toggle",
|
|
+ "*popup*button15.translations: #override\\n\
|
|
+ <Visible>: SetZRLEState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleTightZRLE() HidePopup()",
|
|
+
|
|
+ "*popup*button16.label: Disable JPEG",
|
|
+ "*popup*button16.type: toggle",
|
|
+ "*popup*button16.translations: #override\\n\
|
|
+ <Visible>: SetNOJPEGState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleJPEG() HidePopup()",
|
|
+
|
|
+ "*popup*button17.label: Full Color",
|
|
+ "*popup*button17.type: toggle",
|
|
+ "*popup*button17.translations: #override\\n\
|
|
+ <Visible>: SetFullColorState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleFullColor() HidePopup()",
|
|
+
|
|
+ "*popup*button18.label: Grey Scale (16 & 8-bpp)",
|
|
+ "*popup*button18.type: toggle",
|
|
+ "*popup*button18.translations: #override\\n\
|
|
+ <Visible>: SetGreyScaleState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleGreyScale() HidePopup()",
|
|
+
|
|
+ "*popup*button19.label: 16 bit color (BGR565)",
|
|
+ "*popup*button19.type: toggle",
|
|
+ "*popup*button19.translations: #override\\n\
|
|
+ <Visible>: Set16bppState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle16bpp() HidePopup()",
|
|
+
|
|
+ "*popup*button20.label: 8 bit color (BGR233)",
|
|
+ "*popup*button20.type: toggle",
|
|
+ "*popup*button20.translations: #override\\n\
|
|
+ <Visible>: Set8bppState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle8bpp() HidePopup()",
|
|
+
|
|
+ "*popup*button21.label: - 256 colors",
|
|
+ "*popup*button21.type: toggle",
|
|
+ "*popup*button21.translations: #override\\n\
|
|
+ <Visible>: Set256ColorsState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle256Colors() HidePopup()",
|
|
+
|
|
+ "*popup*button22.label: - 64 colors",
|
|
+ "*popup*button22.type: toggle",
|
|
+ "*popup*button22.translations: #override\\n\
|
|
+ <Visible>: Set64ColorsState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle64Colors() HidePopup()",
|
|
+
|
|
+ "*popup*button23.label: - 8 colors",
|
|
+ "*popup*button23.type: toggle",
|
|
+ "*popup*button23.translations: #override\\n\
|
|
+ <Visible>: Set8ColorsState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() Toggle8Colors() HidePopup()",
|
|
+
|
|
+ "*popup*button24.label: UltraVNC Extensions:",
|
|
+ "*popup*button24.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: HidePopup()",
|
|
+
|
|
+ "*popup*button25.label: - Disable Remote Input",
|
|
+ "*popup*button25.type: toggle",
|
|
+ "*popup*button25.translations: #override\\n\
|
|
+ <Visible>: SetServerInputState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleServerInput() HidePopup()",
|
|
+
|
|
+ "*popup*button26.label: - Single Window",
|
|
+ "*popup*button26.type: toggle",
|
|
+ "*popup*button26.translations: #override\\n\
|
|
+ <Visible>: SetSingleWindowState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleSingleWindow() HidePopup()",
|
|
+
|
|
+ "*popup*button27.label: - Set 1/n Server Scale",
|
|
+ "*popup*button27.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: ShowScaleN() HidePopup()",
|
|
+
|
|
+ "*popup*button28.label: - Text Chat",
|
|
+ "*popup*button28.type: toggle",
|
|
+ "*popup*button28.translations: #override\\n\
|
|
+ <Visible>: SetTextChatState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleTextChat() HidePopup()",
|
|
+
|
|
+ "*scaleN*button0.label: Dismiss",
|
|
+ "*scaleN*button0.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: HideScaleN()",
|
|
+
|
|
+ "*scaleN*button1.label: 1/1",
|
|
+ "*scaleN*button1.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SetScaleN(1) HideScaleN()",
|
|
+
|
|
+ "*scaleN*button2.label: 1/2",
|
|
+ "*scaleN*button2.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SetScaleN(2) HideScaleN()",
|
|
+
|
|
+ "*scaleN*button3.label: 1/3",
|
|
+ "*scaleN*button3.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SetScaleN(3) HideScaleN()",
|
|
+
|
|
+ "*scaleN*button4.label: 1/4",
|
|
+ "*scaleN*button4.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SetScaleN(4) HideScaleN()",
|
|
+
|
|
+ "*scaleN*button5.label: 1/5",
|
|
+ "*scaleN*button5.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: SetScaleN(5) HideScaleN()",
|
|
+
|
|
+ "*scaleN*button6.label: Other",
|
|
+ "*scaleN*button6.translations: #override\\n\
|
|
+ <Btn1Down>,<Btn1Up>: DoServerScale() HideScaleN()",
|
|
+
|
|
NULL
|
|
};
|
|
|
|
+#if 0
|
|
+ "*popup*button14.label: - ZRLE/ZWYRLE",
|
|
+ "*popup*button14.type: toggle",
|
|
+ "*popup*button14.translations: #override\\n\
|
|
+ <Visible>: SetZRLEState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleTightZRLE() HidePopup()",
|
|
+
|
|
+ "*popup*button17.label: Prefer raw for localhost",
|
|
+ "*popup*button17.type: toggle",
|
|
+ "*popup*button17.translations: #override\\n\
|
|
+ <Visible>: SetRawLocalState()\\n\
|
|
+ <Btn1Down>,<Btn1Up>: toggle() ToggleRawLocal() HidePopup()",
|
|
+
|
|
+#endif
|
|
+
|
|
|
|
/*
|
|
* vncServerHost and vncServerPort are set either from the command line or
|
|
@@ -135,6 +306,7 @@
|
|
*/
|
|
|
|
AppData appData;
|
|
+AppData appDataNew;
|
|
|
|
static XtResource appDataResourceList[] = {
|
|
{"shareDesktop", "ShareDesktop", XtRBool, sizeof(Bool),
|
|
@@ -161,8 +333,20 @@
|
|
{"encodings", "Encodings", XtRString, sizeof(String),
|
|
XtOffsetOf(AppData, encodingsString), XtRImmediate, (XtPointer) 0},
|
|
|
|
- {"useBGR233", "UseBGR233", XtRBool, sizeof(Bool),
|
|
- XtOffsetOf(AppData, useBGR233), XtRImmediate, (XtPointer) False},
|
|
+ {"useBGR233", "UseBGR233", XtRInt, sizeof(int),
|
|
+ XtOffsetOf(AppData, useBGR233), XtRImmediate, (XtPointer) 0},
|
|
+
|
|
+ {"useBGR565", "UseBGR565", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, useBGR565), XtRImmediate, (XtPointer) False},
|
|
+
|
|
+ {"useGreyScale", "UseGreyScale", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, useGreyScale), XtRImmediate, (XtPointer) False},
|
|
+
|
|
+ {"yCrop", "yCrop", XtRInt, sizeof(int),
|
|
+ XtOffsetOf(AppData, yCrop), XtRImmediate, (XtPointer) 0},
|
|
+
|
|
+ {"sbWidth", "sbWidth", XtRInt, sizeof(int),
|
|
+ XtOffsetOf(AppData, sbWidth), XtRImmediate, (XtPointer) 2},
|
|
|
|
{"nColours", "NColours", XtRInt, sizeof(int),
|
|
XtOffsetOf(AppData, nColours), XtRImmediate, (XtPointer) 256},
|
|
@@ -179,9 +363,12 @@
|
|
{"requestedDepth", "RequestedDepth", XtRInt, sizeof(int),
|
|
XtOffsetOf(AppData, requestedDepth), XtRImmediate, (XtPointer) 0},
|
|
|
|
- {"useSharedMemory", "UseSharedMemory", XtRBool, sizeof(Bool),
|
|
+ {"useShm", "UseShm", XtRBool, sizeof(Bool),
|
|
XtOffsetOf(AppData, useShm), XtRImmediate, (XtPointer) True},
|
|
|
|
+ {"termChat", "TermChat", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, termChat), XtRImmediate, (XtPointer) False},
|
|
+
|
|
{"wmDecorationWidth", "WmDecorationWidth", XtRInt, sizeof(int),
|
|
XtOffsetOf(AppData, wmDecorationWidth), XtRImmediate, (XtPointer) 4},
|
|
|
|
@@ -206,8 +393,13 @@
|
|
{"bumpScrollPixels", "BumpScrollPixels", XtRInt, sizeof(int),
|
|
XtOffsetOf(AppData, bumpScrollPixels), XtRImmediate, (XtPointer) 20},
|
|
|
|
+#if 0
|
|
{"compressLevel", "CompressionLevel", XtRInt, sizeof(int),
|
|
XtOffsetOf(AppData, compressLevel), XtRImmediate, (XtPointer) -1},
|
|
+#endif
|
|
+
|
|
+ {"compressLevel", "CompressionLevel", XtRInt, sizeof(int),
|
|
+ XtOffsetOf(AppData, compressLevel), XtRImmediate, (XtPointer) 7},
|
|
|
|
{"qualityLevel", "QualityLevel", XtRInt, sizeof(int),
|
|
XtOffsetOf(AppData, qualityLevel), XtRImmediate, (XtPointer) 6},
|
|
@@ -218,14 +410,52 @@
|
|
{"useRemoteCursor", "UseRemoteCursor", XtRBool, sizeof(Bool),
|
|
XtOffsetOf(AppData, useRemoteCursor), XtRImmediate, (XtPointer) True},
|
|
|
|
+ {"useCursorAlpha", "UseCursorAlpha", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, useCursorAlpha), XtRImmediate, (XtPointer) False},
|
|
+
|
|
+ {"useRawLocal", "UseRawLocal", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, useRawLocal), XtRImmediate, (XtPointer) False},
|
|
+
|
|
{"useX11Cursor", "UseX11Cursor", XtRBool, sizeof(Bool),
|
|
XtOffsetOf(AppData, useX11Cursor), XtRImmediate, (XtPointer) False},
|
|
|
|
+ {"useBell", "UseBell", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, useBell), XtRImmediate, (XtPointer) True},
|
|
+
|
|
{"grabKeyboard", "GrabKeyboard", XtRBool, sizeof(Bool),
|
|
- XtOffsetOf(AppData, grabKeyboard), XtRImmediate, (XtPointer) False},
|
|
+ XtOffsetOf(AppData, grabKeyboard), XtRImmediate, (XtPointer) True},
|
|
|
|
{"autoPass", "AutoPass", XtRBool, sizeof(Bool),
|
|
- XtOffsetOf(AppData, autoPass), XtRImmediate, (XtPointer) False}
|
|
+ XtOffsetOf(AppData, autoPass), XtRImmediate, (XtPointer) False},
|
|
+
|
|
+ {"grabAll", "GrabAll", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, grabAll), XtRImmediate, (XtPointer) False},
|
|
+
|
|
+#if 0
|
|
+ {"useBackingstore", "UseBackingstore", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, useBackingstore), XtRImmediate, (XtPointer) True},
|
|
+#else
|
|
+ {"useBackingstore", "UseBackingstore", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, useBackingstore), XtRImmediate, (XtPointer) False},
|
|
+#endif
|
|
+
|
|
+ {"overrideRedir", "OverrideRedir", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, overrideRedir), XtRImmediate, (XtPointer) True},
|
|
+
|
|
+ {"serverInput", "ServerInput", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, serverInput), XtRImmediate, (XtPointer) True},
|
|
+
|
|
+ {"singleWindow", "SingleWindow", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, singleWindow), XtRImmediate, (XtPointer) False},
|
|
+
|
|
+ {"serverScale", "ServerScale", XtRInt, sizeof(int),
|
|
+ XtOffsetOf(AppData, serverScale), XtRImmediate, (XtPointer) 1},
|
|
+
|
|
+ {"chatActive", "ChatActive", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, chatActive), XtRImmediate, (XtPointer) False},
|
|
+
|
|
+ {"popupFix", "PopupFix", XtRBool, sizeof(Bool),
|
|
+ XtOffsetOf(AppData, popupFix), XtRImmediate, (XtPointer) False}
|
|
};
|
|
|
|
|
|
@@ -243,7 +473,20 @@
|
|
{"-passwd", "*passwordFile", XrmoptionSepArg, 0},
|
|
{"-user", "*userLogin", XrmoptionSepArg, 0},
|
|
{"-encodings", "*encodings", XrmoptionSepArg, 0},
|
|
- {"-bgr233", "*useBGR233", XrmoptionNoArg, "True"},
|
|
+ {"-bgr233", "*useBGR233", XrmoptionNoArg, "256"},
|
|
+ {"-use64", "*useBGR233", XrmoptionNoArg, "64"},
|
|
+ {"-bgr222", "*useBGR233", XrmoptionNoArg, "64"},
|
|
+ {"-use8", "*useBGR233", XrmoptionNoArg, "8"},
|
|
+ {"-bgr111", "*useBGR233", XrmoptionNoArg, "8"},
|
|
+ {"-16bpp", "*useBGR565", XrmoptionNoArg, "True"},
|
|
+ {"-bgr565", "*useBGR565", XrmoptionNoArg, "True"},
|
|
+ {"-grey", "*useGreyScale", XrmoptionNoArg, "True"},
|
|
+ {"-gray", "*useGreyScale", XrmoptionNoArg, "True"},
|
|
+ {"-sbwidth", "*sbwidth", XrmoptionSepArg, 0},
|
|
+ {"-ycrop", "*yCrop", XrmoptionSepArg, 0},
|
|
+ {"-sbwidth", "*sbwidth", XrmoptionSepArg, 0},
|
|
+ {"-rawlocal", "*useRawLocal", XrmoptionNoArg, "True"},
|
|
+ {"-alpha", "*useCursorAlpha", XrmoptionNoArg, "True"},
|
|
{"-owncmap", "*forceOwnCmap", XrmoptionNoArg, "True"},
|
|
{"-truecolor", "*forceTrueColour", XrmoptionNoArg, "True"},
|
|
{"-truecolour", "*forceTrueColour", XrmoptionNoArg, "True"},
|
|
@@ -253,7 +496,19 @@
|
|
{"-nojpeg", "*enableJPEG", XrmoptionNoArg, "False"},
|
|
{"-nocursorshape", "*useRemoteCursor", XrmoptionNoArg, "False"},
|
|
{"-x11cursor", "*useX11Cursor", XrmoptionNoArg, "True"},
|
|
- {"-autopass", "*autoPass", XrmoptionNoArg, "True"}
|
|
+ {"-nobell", "*useBell", XrmoptionNoArg, "False"},
|
|
+ {"-autopass", "*autoPass", XrmoptionNoArg, "True"},
|
|
+ {"-graball", "*grabAll", XrmoptionNoArg, "True"},
|
|
+ {"-grabkbd", "*grabKeyboard", XrmoptionNoArg, "True"},
|
|
+ {"-nograbkbd", "*grabKeyboard", XrmoptionNoArg, "False"},
|
|
+ {"-grabkeyboard", "*grabKeyboard", XrmoptionNoArg, "True"},
|
|
+ {"-nograbkeyboard","*grabKeyboard", XrmoptionNoArg, "False"},
|
|
+ {"-nooverride", "*overrideRedir", XrmoptionNoArg, "False"},
|
|
+ {"-bs", "*useBackingstore", XrmoptionNoArg, "True"},
|
|
+ {"-nobs", "*useBackingstore", XrmoptionNoArg, "False"},
|
|
+ {"-popupfix", "*popupFix", XrmoptionNoArg, "True"},
|
|
+ {"-noshm", "*useShm", XrmoptionNoArg, "False"},
|
|
+ {"-termchat", "*termChat", XrmoptionNoArg, "True"}
|
|
|
|
};
|
|
|
|
@@ -268,6 +523,7 @@
|
|
{"SendRFBEvent", SendRFBEvent},
|
|
{"ShowPopup", ShowPopup},
|
|
{"HidePopup", HidePopup},
|
|
+ {"HideScaleN", HideScaleN},
|
|
{"ToggleFullScreen", ToggleFullScreen},
|
|
{"SetFullScreenState", SetFullScreenState},
|
|
{"SelectionFromVNC", SelectionFromVNC},
|
|
@@ -277,6 +533,45 @@
|
|
{"Pause", Pause},
|
|
{"RunCommand", RunCommand},
|
|
{"Quit", Quit},
|
|
+ {"Toggle8bpp", Toggle8bpp},
|
|
+ {"Toggle16bpp", Toggle16bpp},
|
|
+ {"ToggleFullColor", ToggleFullColor},
|
|
+ {"Toggle256Colors", Toggle256Colors},
|
|
+ {"Toggle64Colors", Toggle64Colors},
|
|
+ {"Toggle8Colors", Toggle8Colors},
|
|
+ {"ToggleGreyScale", ToggleGreyScale},
|
|
+ {"ToggleTightZRLE", ToggleTightZRLE},
|
|
+ {"ToggleViewOnly", ToggleViewOnly},
|
|
+ {"ToggleJPEG", ToggleJPEG},
|
|
+ {"ToggleCursorShape", ToggleCursorShape},
|
|
+ {"ToggleCursorAlpha", ToggleCursorAlpha},
|
|
+ {"ToggleX11Cursor", ToggleX11Cursor},
|
|
+ {"ToggleBell", ToggleBell},
|
|
+ {"ToggleRawLocal", ToggleRawLocal},
|
|
+ {"ToggleServerInput", ToggleServerInput},
|
|
+ {"ToggleSingleWindow", ToggleSingleWindow},
|
|
+ {"ToggleTextChat", ToggleTextChat},
|
|
+ {"DoServerScale", DoServerScale},
|
|
+ {"ShowScaleN", ShowScaleN},
|
|
+ {"SetScaleN", SetScaleN},
|
|
+ {"Set8bppState", Set8bppState},
|
|
+ {"Set16bppState", Set16bppState},
|
|
+ {"SetFullColorState", SetFullColorState},
|
|
+ {"Set256ColorsState", Set256ColorsState},
|
|
+ {"Set64ColorsState", Set64ColorsState},
|
|
+ {"Set8ColorsState", Set8ColorsState},
|
|
+ {"SetGreyScaleState", SetGreyScaleState},
|
|
+ {"SetZRLEState", SetZRLEState},
|
|
+ {"SetNOJPEGState", SetNOJPEGState},
|
|
+ {"SetViewOnlyState", SetViewOnlyState},
|
|
+ {"SetCursorShapeState", SetCursorShapeState},
|
|
+ {"SetCursorAlphaState", SetCursorAlphaState},
|
|
+ {"SetX11CursorState", SetX11CursorState},
|
|
+ {"SetBellState", SetBellState},
|
|
+ {"SetRawLocalState", SetRawLocalState},
|
|
+ {"SetServerInputState", SetServerInputState},
|
|
+ {"SetSingleWindowState", SetSingleWindowState},
|
|
+ {"SetTextChatState", SetTextChatState}
|
|
};
|
|
|
|
|
|
@@ -302,8 +597,8 @@
|
|
void
|
|
usage(void)
|
|
{
|
|
- fprintf(stderr,
|
|
- "TightVNC viewer version 1.3dev7\n"
|
|
+ fprintf(stdout,
|
|
+ "TightVNC viewer version 1.3.9 (SSVNC)\n"
|
|
"\n"
|
|
"Usage: %s [<OPTIONS>] [<HOST>][:<DISPLAY#>]\n"
|
|
" %s [<OPTIONS>] [<HOST>][::<PORT#>]\n"
|
|
@@ -332,10 +627,117 @@
|
|
" -autopass\n"
|
|
"\n"
|
|
"Option names may be abbreviated, e.g. -bgr instead of -bgr233.\n"
|
|
- "See the manual page for more information."
|
|
+ "See the manual page for more information.\n"
|
|
+ "\n"
|
|
+ "\n"
|
|
+ "Enhanced TightVNC viewer (SSVNC) options:\n"
|
|
+ "\n"
|
|
+ " URL http://www.karlrunge.com/x11vnc/ssvnc.html\n"
|
|
+ "\n"
|
|
+ " Note: ZRLE encoding is now supported.\n"
|
|
+ "\n"
|
|
+ " Note: F9 is shortcut to Toggle FullScreen mode.\n"
|
|
+ "\n"
|
|
+ " -use64 In -bgr233 mode, use 64 colors instead of 256.\n"
|
|
+ " -bgr222 Same as -use64.\n"
|
|
+ "\n"
|
|
+ " -use8 In -bgr233 mode, use 8 colors instead of 256.\n"
|
|
+ " -bgr111 Same as -use8.\n"
|
|
+ "\n"
|
|
+ " -16bpp If the vnc viewer X display is depth 24 at 32bpp\n"
|
|
+ " request a 16bpp format from the VNC server to cut\n"
|
|
+ " network traffic by up to 2X, then tranlate the\n"
|
|
+ " pixels to 32bpp locally.\n"
|
|
+ " -bgr565 Same as -16bpp.\n"
|
|
+ "\n"
|
|
+ " -grey Use a grey scale for the 16- and 8-bpp modes.\n"
|
|
+ "\n"
|
|
+ " -alpha Use alphablending transparency for local cursors\n"
|
|
+ " requires: x11vnc server, both client and server\n"
|
|
+ " must be 32bpp and same endianness.\n"
|
|
+ "\n"
|
|
+ " -ycrop n Only show the top n rows of the framebuffer. For\n"
|
|
+ " use with x11vnc -ncache client caching option\n"
|
|
+ " to help \"hide\" the pixel cache region.\n"
|
|
+ " Use a negative value (e.g. -1) for autodetection.\n"
|
|
+ " Autodetection will always take place if the remote\n"
|
|
+ " fb height is more than 2 times the width.\n"
|
|
+ "\n"
|
|
+ " -sbwidth n Scrollbar width for x11vnc -ncache mode (-ycrop),\n"
|
|
+ " default is very narrow: 2 pixels, it is narrow to\n"
|
|
+ " avoid distraction in -ycrop mode.\n"
|
|
+ "\n"
|
|
+ " -nobell Disable bell.\n"
|
|
+ "\n"
|
|
+ " -rawlocal Prefer raw encoding for localhost, default is\n"
|
|
+ " no, i.e. assumes you have a SSH tunnel instead.\n"
|
|
+ "\n"
|
|
+ " -graball Grab the entire X server when in fullscreen mode,\n"
|
|
+ " needed by some old window managers like fvwm2.\n"
|
|
+ " -popupfix Warp the popup back to the pointer position,\n"
|
|
+ " needed by some old window managers like fvwm2.\n"
|
|
+ "\n"
|
|
+ " -grabkbd Grab the X keyboard when in fullscreen mode,\n"
|
|
+ " needed by some window managers. Same as -grabkeyboard.\n"
|
|
+ " -grabkbd is the default, use -nograbkbd to disable.\n"
|
|
+ "\n"
|
|
+ " -bs, -nobs Whether or not to use X server Backingstore for the\n"
|
|
+ " main viewer window. The default is to not, mainly\n"
|
|
+ " because most Linux, etc, systems X servers disable\n"
|
|
+ " *all* Backingstore by default. To re-enable it put\n"
|
|
+ "\n"
|
|
+ " Option \"Backingstore\"\n"
|
|
+ "\n"
|
|
+ " in the Device section of /etc/X11/xorg.conf.\n"
|
|
+ " In -bs mode with no X server backingstore, whenever an\n"
|
|
+ " area of the screen is re-exposed it must go out to the\n"
|
|
+ " VNC server to retrieve the pixels. This is too slow.\n"
|
|
+ "\n"
|
|
+ " In -nobs mode, memory is allocated by the viewer to\n"
|
|
+ " provide its own backing of the main viewer window. This\n"
|
|
+ " actually makes some activities faster (changes in large\n"
|
|
+ " regions) but can appear to \"flash\" too much.\n"
|
|
+ "\n"
|
|
+ " -noshm Disable use of MIT shared memory extension (not recommended)\n"
|
|
+ "\n"
|
|
+ " -termchat Do the UltraVNC chat in the terminal vncviewer is in\n"
|
|
+ " instead of in an independent window.\n"
|
|
+ "\n"
|
|
+ " New Popup actions:\n"
|
|
+ "\n"
|
|
+ " ViewOnly: ~ -viewonly\n"
|
|
+ " Disable Bell: ~ -nobell\n"
|
|
+ " Cursor Shape: ~ -nocursorshape\n"
|
|
+ " X11 Cursor: ~ -x11cursor\n"
|
|
+ " Cursor Alphablend: ~ -alpha\n"
|
|
+ " Toggle Tight/ZRLE: ~ -encodings ...\n"
|
|
+ " Disable JPEG: ~ -nojpeg\n"
|
|
+ " Full Color as many colors as local screen allows.\n"
|
|
+ " Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.\n"
|
|
+ " 16 bit color (BGR565) ~ -16bpp / -bgr565\n"
|
|
+ " 8 bit color (BGR233) ~ -bgr233\n"
|
|
+ " 256 colors ~ -bgr233 default # of colors.\n"
|
|
+ " 64 colors ~ -bgr222 / -use64\n"
|
|
+ " 8 colors ~ -bgr111 / -use8\n"
|
|
+ "\n"
|
|
+ " UltraVNC Extensions:\n"
|
|
+ " Disable Remote Input Ultravnc ext. Try to prevent input and\n"
|
|
+ " viewing of monitor at physical display.\n"
|
|
+ " Single Window Ultravnc ext. Grab and view a single window.\n"
|
|
+ " (click on the window you want).\n"
|
|
+ " Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.\n"
|
|
+ " prompt is from the terminal.\n"
|
|
+ " Text Chat Ultravnc ext. Do Text Chat.\n"
|
|
+ "\n"
|
|
+ " Note: the Ultravnc extensions only apply to servers that support\n"
|
|
+ " them. x11vnc/libvncserver supports some of them.\n"
|
|
+ "\n"
|
|
"\n", programName, programName, programName, programName);
|
|
exit(1);
|
|
}
|
|
+#if 0
|
|
+ " -nooverride Do not apply OverrideRedirect in fullscreen mode.\n"
|
|
+#endif
|
|
|
|
|
|
/*
|
|
@@ -350,6 +752,7 @@
|
|
int i;
|
|
char *vncServerName, *colonPos;
|
|
int len, portOffset;
|
|
+ int disp;
|
|
|
|
/* Turn app resource specs into our appData structure for the rest of the
|
|
program to use */
|
|
@@ -357,6 +760,23 @@
|
|
XtGetApplicationResources(toplevel, &appData, appDataResourceList,
|
|
XtNumber(appDataResourceList), 0, 0);
|
|
|
|
+ if (getenv("VNCVIEWER_ALPHABLEND")) {
|
|
+ appData.useCursorAlpha = True;
|
|
+ }
|
|
+ if (getenv("VNCVIEWER_POPUP_FIX")) {
|
|
+ appData.popupFix = True;
|
|
+ }
|
|
+ if (getenv("VNCVIEWER_GRAB_SERVER")) {
|
|
+ appData.grabAll = True;
|
|
+ }
|
|
+ if (getenv("VNCVIEWER_YCROP")) {
|
|
+ int n = atoi(getenv("VNCVIEWER_YCROP"));
|
|
+ if (n != 0) {
|
|
+ appData.yCrop = n;
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
/* Add our actions to the actions table so they can be used in widget
|
|
resource specs */
|
|
|
|
@@ -376,6 +796,10 @@
|
|
return;
|
|
}
|
|
|
|
+ if (appData.useBGR233 && appData.useBGR565) {
|
|
+ appData.useBGR233 = 0;
|
|
+ }
|
|
+
|
|
if (argc == 1) {
|
|
vncServerName = DoServerDialog();
|
|
appData.passwordDialog = True;
|
|
@@ -414,6 +838,13 @@
|
|
if (!len || strspn(colonPos + 1, "0123456789") != len) {
|
|
usage();
|
|
}
|
|
+#if 0
|
|
vncServerPort = atoi(colonPos + 1) + portOffset;
|
|
+#else
|
|
+ disp = atoi(colonPos + 1);
|
|
+ if (portOffset != 0 && disp >= 100)
|
|
+ portOffset = 0;
|
|
+ vncServerPort = disp + portOffset;
|
|
+#endif
|
|
}
|
|
}
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/colour.c vnc_unixsrc/vncviewer/colour.c
|
|
--- vnc_unixsrc.orig/vncviewer/colour.c 2002-04-30 09:07:31.000000000 -0400
|
|
+++ vnc_unixsrc/vncviewer/colour.c 2007-03-22 21:36:12.000000000 -0400
|
|
@@ -31,9 +31,12 @@
|
|
#define BGR233_SIZE 256
|
|
unsigned long BGR233ToPixel[BGR233_SIZE];
|
|
|
|
+#define BGR565_SIZE 65536
|
|
+unsigned long BGR565ToPixel[BGR565_SIZE];
|
|
+
|
|
Colormap cmap;
|
|
Visual *vis;
|
|
-unsigned int visdepth, visbpp;
|
|
+unsigned int visdepth, visbpp, isLSB;
|
|
Bool allocColorFailed = False;
|
|
|
|
static int nBGR233ColoursAllocated;
|
|
@@ -45,6 +48,8 @@
|
|
static void AllocateExactBGR233Colours();
|
|
static Bool AllocateBGR233Colour(int r, int g, int b);
|
|
|
|
+static void SetupBGR565Map();
|
|
+
|
|
|
|
/*
|
|
* SetVisualAndCmap() deals with the wonderful world of X "visuals" (which are
|
|
@@ -97,6 +102,44 @@
|
|
visbpp = GetBPPForDepth(visdepth);
|
|
cmap = DefaultColormap(dpy,DefaultScreen(dpy));
|
|
|
|
+ if (ImageByteOrder(dpy) == LSBFirst) {
|
|
+ isLSB = 1;
|
|
+ } else {
|
|
+ isLSB = 0;
|
|
+ }
|
|
+ if (visbpp == 24) {
|
|
+ if (!appData.useBGR233) {
|
|
+ fprintf(stderr, "Warning: for 24bpp enabling -bgr565 -- Don't use FullColor!\n");
|
|
+ appData.useBGR565 = True;
|
|
+ } else {
|
|
+ fprintf(stderr, "Warning: for 24bpp using -bgr233 -- Don't use FullColor!\n");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (appData.useBGR565) {
|
|
+ if (visdepth < 24 || visbpp < 24 || vis->class != TrueColor) {
|
|
+ fprintf(stderr, "disabling -16bpp BGR565 on non-depth 24 machine\n");
|
|
+ appData.useBGR565 = False;
|
|
+ } else {
|
|
+ myFormat.bitsPerPixel = 16;
|
|
+ myFormat.depth = 16;
|
|
+ myFormat.trueColour = 1;
|
|
+ myFormat.bigEndian = 0;
|
|
+ myFormat.redMax = 31;
|
|
+ myFormat.greenMax = 63;
|
|
+ myFormat.blueMax = 31;
|
|
+ myFormat.redShift = 11;
|
|
+ myFormat.greenShift = 5;
|
|
+ myFormat.blueShift = 0;
|
|
+
|
|
+ fprintf(stderr, "Using default colormap and translating from BGR565 (65536 colors). Pixel format:\n");
|
|
+ PrintPixelFormat(&myFormat);
|
|
+
|
|
+ SetupBGR565Map();
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
if (!appData.useBGR233 && (vis->class == TrueColor)) {
|
|
|
|
myFormat.bitsPerPixel = visbpp;
|
|
@@ -116,21 +159,42 @@
|
|
return;
|
|
}
|
|
|
|
- appData.useBGR233 = True;
|
|
+ if (appData.useBGR233 == 0) {
|
|
+ appData.useBGR233 = 256;
|
|
+ }
|
|
|
|
myFormat.bitsPerPixel = 8;
|
|
myFormat.depth = 8;
|
|
myFormat.trueColour = 1;
|
|
myFormat.bigEndian = 0;
|
|
- myFormat.redMax = 7;
|
|
+ myFormat.redMax = 7;
|
|
myFormat.greenMax = 7;
|
|
- myFormat.blueMax = 3;
|
|
- myFormat.redShift = 0;
|
|
+ myFormat.blueMax = 3;
|
|
+ myFormat.redShift = 0;
|
|
myFormat.greenShift = 3;
|
|
- myFormat.blueShift = 6;
|
|
+ myFormat.blueShift = 6;
|
|
+
|
|
+ if (appData.useBGR233 == 64) {
|
|
+ /* BGR222 */
|
|
+ myFormat.redMax = 3;
|
|
+ myFormat.greenMax = 3;
|
|
+ myFormat.blueMax = 3;
|
|
+ myFormat.redShift = 0;
|
|
+ myFormat.greenShift = 2;
|
|
+ myFormat.blueShift = 4;
|
|
+ }
|
|
+ if (appData.useBGR233 == 8) {
|
|
+ /* BGR111 */
|
|
+ myFormat.redMax = 2;
|
|
+ myFormat.greenMax = 2;
|
|
+ myFormat.blueMax = 2;
|
|
+ myFormat.redShift = 0;
|
|
+ myFormat.greenShift = 1;
|
|
+ myFormat.blueShift = 2;
|
|
+ }
|
|
|
|
fprintf(stderr,
|
|
- "Using default colormap and translating from BGR233. Pixel format:\n");
|
|
+ "Using default colormap and translating from BGR233 (%d colors). Pixel format:\n", appData.useBGR233);
|
|
PrintPixelFormat(&myFormat);
|
|
|
|
SetupBGR233Map();
|
|
@@ -282,8 +346,12 @@
|
|
XFree(format);
|
|
|
|
if (bpp != 1 && bpp != 8 && bpp != 16 && bpp != 32) {
|
|
- fprintf(stderr,"Can't cope with %d bits-per-pixel. Sorry.\n", bpp);
|
|
- exit(1);
|
|
+ if (bpp == 24) {
|
|
+ fprintf(stderr,"Warning: 24 bits-per-pixel may have problems...\n");
|
|
+ } else {
|
|
+ fprintf(stderr,"Can't cope with %d bits-per-pixel. Sorry.\n", bpp);
|
|
+ exit(1);
|
|
+ }
|
|
}
|
|
|
|
return bpp;
|
|
@@ -394,16 +462,43 @@
|
|
for (r = 0; r < 8; r++) {
|
|
for (g = 0; g < 8; g++) {
|
|
for (b = 0; b < 4; b++) {
|
|
- if (BGR233ToPixel[(b<<6) | (g<<3) | r] == INVALID_PIXEL) {
|
|
+ int bs = 6, gs = 3, rs = 0;
|
|
+ int bm = 3, gm = 7, rm = 7;
|
|
+ if (appData.useBGR233 == 64) {
|
|
+ bs = 4; gs = 2; rs = 0;
|
|
+ bm = 3; gm = 3; rm = 3;
|
|
+ }
|
|
+ if (appData.useBGR233 == 8) {
|
|
+ bs = 2; gs = 1; rs = 0;
|
|
+ bm = 1; gm = 1; rm = 1;
|
|
+ }
|
|
+ if ((b > bm || g > gm || r > rm)) {
|
|
+ continue;
|
|
+ }
|
|
+ if (BGR233ToPixel[(b<<bs) | (g<<gs) | (r<<rs)] == INVALID_PIXEL) {
|
|
|
|
unsigned long minDistance = ULONG_MAX;
|
|
|
|
for (i = 0; i < cmapSize; i++) {
|
|
if (exactBGR233[i] || shared[i]) {
|
|
- unsigned long distance
|
|
- = (abs(cmapEntry[i].red - r * 65535 / 7)
|
|
- + abs(cmapEntry[i].green - g * 65535 / 7)
|
|
- + abs(cmapEntry[i].blue - b * 65535 / 3));
|
|
+ unsigned long distance;
|
|
+ int r1, g1, b1;
|
|
+ if (appData.useGreyScale) {
|
|
+ int ave;
|
|
+ ave = (r + g + 2*b)/3;
|
|
+ r1 = ave;
|
|
+ g1 = ave;
|
|
+ b1 = ave/2;
|
|
+ } else {
|
|
+ r1 = r;
|
|
+ g1 = g;
|
|
+ b1 = b;
|
|
+ }
|
|
+ distance
|
|
+ = ( abs(cmapEntry[i].red - r1 * 65535 / rm)
|
|
+ + abs(cmapEntry[i].green - g1 * 65535 / gm)
|
|
+ + abs(cmapEntry[i].blue - b1 * 65535 / bm));
|
|
+
|
|
|
|
if (distance < minDistance) {
|
|
minDistance = distance;
|
|
@@ -412,7 +507,7 @@
|
|
}
|
|
}
|
|
|
|
- BGR233ToPixel[(b<<6) | (g<<3) | r] = nearestPixel;
|
|
+ BGR233ToPixel[(b<<bs) | (g<<gs) | (r<<rs)] = nearestPixel;
|
|
if (shared[nearestPixel] && !usedAsNearest[nearestPixel])
|
|
nSharedUsed++;
|
|
usedAsNearest[nearestPixel] = True;
|
|
@@ -433,6 +528,53 @@
|
|
}
|
|
}
|
|
|
|
+static void
|
|
+SetupBGR565Map()
|
|
+{
|
|
+ int r, g, b;
|
|
+ int r2, g2, b2;
|
|
+ long i, idx;
|
|
+ int cnt = 0;
|
|
+ unsigned long pixel = 0;
|
|
+
|
|
+ for (r = 0; r < 32; r++) {
|
|
+ for (g = 0; g < 64; g++) {
|
|
+ for (b = 0; b < 32; b++) {
|
|
+ int bs = 0, gs = 5, rs = 11;
|
|
+ int bm = 31, gm = 63, rm = 31;
|
|
+ if ((b > bm || g > gm || r > rm)) {
|
|
+ continue;
|
|
+ }
|
|
+ r2 = (255 * r) / rm;
|
|
+ g2 = (255 * g) / gm;
|
|
+ b2 = (255 * b) / bm;
|
|
+
|
|
+ pixel = (r2 << 16) | (g2 << 8) | (b2 << 0);
|
|
+ if (appData.useGreyScale) {
|
|
+ int ave;
|
|
+ int r1, g1, b1;
|
|
+ ave = (2*r + g + 2*b)/3;
|
|
+ r1 = ave/2;
|
|
+ g1 = ave;
|
|
+ b1 = ave/2;
|
|
+
|
|
+ r2 = (255 * r1) / rm;
|
|
+ g2 = (255 * g1) / gm;
|
|
+ b2 = (255 * b1) / bm;
|
|
+
|
|
+ pixel = (r2 << 16) | (g2 << 8) | (b2 << 0);
|
|
+ }
|
|
+
|
|
+ idx = (b<<bs) | (g<<gs) | (r<<rs);
|
|
+ if (0) fprintf(stderr, "cnt: %5d idx: %5d pixel: 0x%08x\n", cnt, idx, pixel);
|
|
+ BGR565ToPixel[idx] = pixel;
|
|
+ cnt++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
|
|
/*
|
|
* AllocateExactBGR233Colours() attempts to allocate each of the colours in the
|
|
@@ -484,8 +626,13 @@
|
|
ri = rn;
|
|
for (gi = 0; gi < gn; gi++) {
|
|
for (bi = 0; bi < bn; bi++) {
|
|
- if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi]))
|
|
- return;
|
|
+ if (appData.useBGR233 == 64 && (bv[bi] > 3 || gv[gi] > 3 || rv[ri] > 3)) {
|
|
+ nBGR233ColoursAllocated++;
|
|
+ } else if (appData.useBGR233 == 8 && (bv[bi] > 1 || gv[gi] > 1 || rv[ri] > 1)) {
|
|
+ nBGR233ColoursAllocated++;
|
|
+ } else if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) {
|
|
+ return;
|
|
+ }
|
|
}
|
|
}
|
|
rn++;
|
|
@@ -496,8 +643,13 @@
|
|
gi = gn;
|
|
for (ri = 0; ri < rn; ri++) {
|
|
for (bi = 0; bi < bn; bi++) {
|
|
- if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi]))
|
|
- return;
|
|
+ if (appData.useBGR233 == 64 && (bv[bi] > 3 || gv[gi] > 3 || rv[ri] > 3)) {
|
|
+ nBGR233ColoursAllocated++;
|
|
+ } else if (appData.useBGR233 == 8 && (bv[bi] > 1 || gv[gi] > 1 || rv[ri] > 1)) {
|
|
+ nBGR233ColoursAllocated++;
|
|
+ } else if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) {
|
|
+ return;
|
|
+ }
|
|
}
|
|
}
|
|
gn++;
|
|
@@ -507,8 +659,13 @@
|
|
bi = bn;
|
|
for (ri = 0; ri < rn; ri++) {
|
|
for (gi = 0; gi < gn; gi++) {
|
|
- if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi]))
|
|
- return;
|
|
+ if (appData.useBGR233 == 64 && (bv[bi] > 3 || gv[gi] > 3 || rv[ri] > 3)) {
|
|
+ nBGR233ColoursAllocated++;
|
|
+ } else if (appData.useBGR233 == 8 && (bv[bi] > 1 || gv[gi] > 1 || rv[ri] > 1)) {
|
|
+ nBGR233ColoursAllocated++;
|
|
+ } else if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) {
|
|
+ return;
|
|
+ }
|
|
}
|
|
}
|
|
bn++;
|
|
@@ -529,18 +686,36 @@
|
|
AllocateBGR233Colour(int r, int g, int b)
|
|
{
|
|
XColor c;
|
|
+ int bs = 6, gs = 3, rs = 0;
|
|
+ int bm = 3, gm = 7, rm = 7;
|
|
|
|
if (nBGR233ColoursAllocated >= appData.nColours)
|
|
return False;
|
|
|
|
- c.red = r * 65535 / 7;
|
|
- c.green = g * 65535 / 7;
|
|
- c.blue = b * 65535 / 3;
|
|
+ if (appData.useBGR233 == 64) {
|
|
+ bs = 4; gs = 2, rs = 0;
|
|
+ bm = 3; gm = 3; rm = 3;
|
|
+ }
|
|
+ if (appData.useBGR233 == 8) {
|
|
+ bs = 2; gs = 1, rs = 0;
|
|
+ bm = 1; gm = 1; rm = 1;
|
|
+ }
|
|
+
|
|
+ c.red = r * 65535 / rm;
|
|
+ c.green = g * 65535 / gm;
|
|
+ c.blue = b * 65535 / bm;
|
|
+ if (appData.useGreyScale) {
|
|
+ int ave;
|
|
+ ave = (c.red + c.green + c.blue)/3;
|
|
+ c.red = ave;
|
|
+ c.green = ave;
|
|
+ c.blue = ave;
|
|
+ }
|
|
|
|
if (!XAllocColor(dpy, cmap, &c))
|
|
return False;
|
|
|
|
- BGR233ToPixel[(b<<6) | (g<<3) | r] = c.pixel;
|
|
+ BGR233ToPixel[(b<<bs) | (g<<gs) | r] = c.pixel;
|
|
|
|
nBGR233ColoursAllocated++;
|
|
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/corre.c vnc_unixsrc/vncviewer/corre.c
|
|
--- vnc_unixsrc.orig/vncviewer/corre.c 2000-06-11 08:00:53.000000000 -0400
|
|
+++ vnc_unixsrc/vncviewer/corre.c 2007-02-17 22:50:15.000000000 -0500
|
|
@@ -29,6 +29,18 @@
|
|
#define HandleCoRREBPP CONCAT2E(HandleCoRRE,BPP)
|
|
#define CARDBPP CONCAT2E(CARD,BPP)
|
|
|
|
+#define FillRectangle(x, y, w, h, color) \
|
|
+ { \
|
|
+ XGCValues _gcv; \
|
|
+ _gcv.foreground = color; \
|
|
+ if (!appData.useBackingstore) { \
|
|
+ FillScreen(x, y, w, h, _gcv.foreground); \
|
|
+ } else { \
|
|
+ XChangeGC(dpy, gc, GCForeground, &_gcv); \
|
|
+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \
|
|
+ } \
|
|
+ }
|
|
+
|
|
static Bool
|
|
HandleCoRREBPP (int rx, int ry, int rw, int rh)
|
|
{
|
|
@@ -50,11 +62,19 @@
|
|
#if (BPP == 8)
|
|
gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
|
|
#else
|
|
+#if (BPP == 16)
|
|
+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix);
|
|
+#else
|
|
gcv.foreground = pix;
|
|
#endif
|
|
+#endif
|
|
|
|
+#if 0
|
|
XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
|
|
+#else
|
|
+ FillRectangle(rx, ry, rw, rh, gcv.foreground);
|
|
+#endif
|
|
|
|
if (!ReadFromRFBServer(buffer, hdr.nSubrects * (4 + (BPP / 8))))
|
|
return False;
|
|
@@ -72,12 +92,22 @@
|
|
#if (BPP == 8)
|
|
gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
|
|
#else
|
|
+#if (BPP == 16)
|
|
+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix);
|
|
+#else
|
|
gcv.foreground = pix;
|
|
#endif
|
|
+#endif
|
|
|
|
+#if 0
|
|
XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
XFillRectangle(dpy, desktopWin, gc, rx + x, ry + y, w, h);
|
|
+#else
|
|
+ FillRectangle(rx + x, ry + y, w, h, gcv.foreground);
|
|
+#endif
|
|
}
|
|
|
|
return True;
|
|
}
|
|
+
|
|
+#undef FillRectangle
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/cp_it vnc_unixsrc/vncviewer/cp_it
|
|
--- vnc_unixsrc.orig/vncviewer/cp_it 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/cp_it 2007-03-24 10:05:16.000000000 -0400
|
|
@@ -0,0 +1,14 @@
|
|
+#!/bin/sh
|
|
+
|
|
+dest=/dist/bin/vncviewerz-1.3dev5-resize
|
|
+suc "cp -p $dest $dest.back; mv $dest $dest.unlink; mv $dest.back $dest; rm $dest.unlink"
|
|
+strip ./vncviewer
|
|
+cat ./vncviewer > $dest
|
|
+touch -r ./vncviewer $dest
|
|
+yy=/dist/src/apps/VNC/etc/libvncserver_cvs/expts/etv/ssvnc/bin/Linux.i686/vncviewer
|
|
+mv $yy $yy.unlink
|
|
+cp -p ./vncviewer $yy
|
|
+cp -p ./vncviewer $HOME/etv_col/Linux.i686
|
|
+chmod 755 $yy
|
|
+rm -f $yy.unlink
|
|
+ls -l ./vncviewer $dest $yy $HOME/etv_col/Linux.i686/vncviewer
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/cursor.c vnc_unixsrc/vncviewer/cursor.c
|
|
--- vnc_unixsrc.orig/vncviewer/cursor.c 2003-01-15 04:46:52.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/cursor.c 2007-03-17 22:48:34.000000000 -0400
|
|
@@ -39,7 +39,7 @@
|
|
|
|
static Bool prevSoftCursorSet = False;
|
|
static Pixmap rcSavedArea;
|
|
-static CARD8 *rcSource, *rcMask;
|
|
+static CARD8 *rcSource = NULL, *rcMask;
|
|
static int rcHotX, rcHotY, rcWidth, rcHeight;
|
|
static int rcCursorX = 0, rcCursorY = 0;
|
|
static int rcLockX, rcLockY, rcLockWidth, rcLockHeight;
|
|
@@ -48,8 +48,8 @@
|
|
static Bool SoftCursorInLockedArea(void);
|
|
static void SoftCursorCopyArea(int oper);
|
|
static void SoftCursorDraw(void);
|
|
-static void FreeSoftCursor(void);
|
|
-static void FreeX11Cursor();
|
|
+void FreeSoftCursor(void);
|
|
+void FreeX11Cursor();
|
|
|
|
/* Copied from Xvnc/lib/font/util/utilbitmap.c */
|
|
static unsigned char _reverse_byte[0x100] = {
|
|
@@ -195,6 +195,7 @@
|
|
buf = malloc(bytesMaskData);
|
|
if (buf == NULL) {
|
|
free(rcSource);
|
|
+ rcSource = NULL;
|
|
return False;
|
|
}
|
|
|
|
@@ -209,6 +210,7 @@
|
|
/* Read and convert background and foreground colors. */
|
|
if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) {
|
|
free(rcSource);
|
|
+ rcSource = NULL;
|
|
free(buf);
|
|
return False;
|
|
}
|
|
@@ -218,6 +220,7 @@
|
|
/* Read 1bpp pixel data into a temporary buffer. */
|
|
if (!ReadFromRFBServer(buf, bytesMaskData)) {
|
|
free(rcSource);
|
|
+ rcSource = NULL;
|
|
free(buf);
|
|
return False;
|
|
}
|
|
@@ -257,6 +260,7 @@
|
|
|
|
if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) {
|
|
free(rcSource);
|
|
+ rcSource = NULL;
|
|
free(buf);
|
|
return False;
|
|
}
|
|
@@ -267,6 +271,7 @@
|
|
|
|
if (!ReadFromRFBServer(buf, bytesMaskData)) {
|
|
free(rcSource);
|
|
+ rcSource = NULL;
|
|
free(buf);
|
|
return False;
|
|
}
|
|
@@ -274,6 +279,7 @@
|
|
rcMask = malloc(width * height);
|
|
if (rcMask == NULL) {
|
|
free(rcSource);
|
|
+ rcSource = NULL;
|
|
free(buf);
|
|
return False;
|
|
}
|
|
@@ -429,41 +435,63 @@
|
|
rcLockY + rcLockHeight > rcCursorY - rcHotY);
|
|
}
|
|
|
|
+extern XImage *image;
|
|
+
|
|
static void SoftCursorCopyArea(int oper)
|
|
{
|
|
- int x, y, w, h;
|
|
+ int x, y, w, h;
|
|
|
|
- x = rcCursorX - rcHotX;
|
|
- y = rcCursorY - rcHotY;
|
|
- if (x >= si.framebufferWidth || y >= si.framebufferHeight)
|
|
- return;
|
|
+ x = rcCursorX - rcHotX;
|
|
+ y = rcCursorY - rcHotY;
|
|
+ if (x >= si.framebufferWidth || y >= si.framebufferHeight) {
|
|
+ return;
|
|
+ }
|
|
|
|
- w = rcWidth;
|
|
- h = rcHeight;
|
|
- if (x < 0) {
|
|
- w += x;
|
|
- x = 0;
|
|
- } else if (x + w > si.framebufferWidth) {
|
|
- w = si.framebufferWidth - x;
|
|
- }
|
|
- if (y < 0) {
|
|
- h += y;
|
|
- y = 0;
|
|
- } else if (y + h > si.framebufferHeight) {
|
|
- h = si.framebufferHeight - y;
|
|
- }
|
|
+ w = rcWidth;
|
|
+ h = rcHeight;
|
|
+ if (x < 0) {
|
|
+ w += x;
|
|
+ x = 0;
|
|
+ } else if (x + w > si.framebufferWidth) {
|
|
+ w = si.framebufferWidth - x;
|
|
+ }
|
|
+ if (y < 0) {
|
|
+ h += y;
|
|
+ y = 0;
|
|
+ } else if (y + h > si.framebufferHeight) {
|
|
+ h = si.framebufferHeight - y;
|
|
+ }
|
|
|
|
- if (oper == OPER_SAVE) {
|
|
- /* Save screen area in memory. */
|
|
+ if (oper == OPER_SAVE) {
|
|
+ /* Save screen area in memory. */
|
|
+//fprintf(stderr, "OPER_SAVE\n");
|
|
+#if 0
|
|
#ifdef MITSHM
|
|
- if (appData.useShm)
|
|
- XSync(dpy, False);
|
|
+ if (appData.useShm) {
|
|
+ XSync(dpy, False);
|
|
+ } else
|
|
#endif
|
|
- XCopyArea(dpy, desktopWin, rcSavedArea, gc, x, y, w, h, 0, 0);
|
|
- } else {
|
|
- /* Restore screen area. */
|
|
- XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, w, h, x, y);
|
|
- }
|
|
+ {
|
|
+ XSync(dpy, False);
|
|
+ }
|
|
+#endif
|
|
+ if (appData.useBackingstore) {
|
|
+ XSync(dpy, False);
|
|
+ XCopyArea(dpy, desktopWin, rcSavedArea, gc, x, y, w, h, 0, 0);
|
|
+ } else {
|
|
+ XPutImage(dpy, rcSavedArea, gc, image, x, y, 0, 0, w, h);
|
|
+ }
|
|
+ } else {
|
|
+//fprintf(stderr, "OPER_RESTORE\n");
|
|
+ /* Restore screen area. */
|
|
+ if (appData.useBackingstore) {
|
|
+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, w, h, x, y);
|
|
+ XGetSubImage(dpy, rcSavedArea, 0, 0, w, h, AllPlanes, ZPixmap, image, x, y);
|
|
+ } else {
|
|
+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, w, h, x, y);
|
|
+ XGetSubImage(dpy, rcSavedArea, 0, 0, w, h, AllPlanes, ZPixmap, image, x, y);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
static void SoftCursorDraw(void)
|
|
@@ -472,6 +500,139 @@
|
|
int offset, bytesPerPixel;
|
|
char *pos;
|
|
|
|
+#define alphahack
|
|
+#ifdef alphahack
|
|
+ /* hack to have cursor transparency at 32bpp <runge@karlrunge.com> */
|
|
+ int alphablend = 0;
|
|
+
|
|
+ if (!rcSource) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (appData.useCursorAlpha) {
|
|
+ alphablend = 1;
|
|
+ }
|
|
+
|
|
+ bytesPerPixel = myFormat.bitsPerPixel / 8;
|
|
+
|
|
+ if (alphablend && bytesPerPixel == 4) {
|
|
+ unsigned long pixel, put, *upos, *upix;
|
|
+ int got_alpha = 0, rsX, rsY, rsW, rsH;
|
|
+ static XImage *alpha_image = NULL;
|
|
+ static int iwidth = 128;
|
|
+
|
|
+ if (! alpha_image) {
|
|
+ /* watch out for tiny fb (rare) */
|
|
+ if (iwidth > si.framebufferWidth) {
|
|
+ iwidth = si.framebufferWidth;
|
|
+ }
|
|
+ if (iwidth > si.framebufferHeight) {
|
|
+ iwidth = si.framebufferHeight;
|
|
+ }
|
|
+
|
|
+ /* initialize an XImage with a chunk of desktopWin */
|
|
+ alpha_image = XGetImage(dpy, desktopWin, 0, 0, iwidth, iwidth,
|
|
+ AllPlanes, ZPixmap);
|
|
+ }
|
|
+
|
|
+ /* first check if there is any non-zero alpha channel data at all: */
|
|
+ for (y = 0; y < rcHeight; y++) {
|
|
+ for (x = 0; x < rcWidth; x++) {
|
|
+ int alpha;
|
|
+
|
|
+ offset = y * rcWidth + x;
|
|
+ pos = (char *)&rcSource[offset * bytesPerPixel];
|
|
+
|
|
+ upos = (unsigned long *) pos;
|
|
+ alpha = (*upos & 0xff000000) >> 24;
|
|
+ if (alpha) {
|
|
+ got_alpha = 1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (got_alpha) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!got_alpha) {
|
|
+ /* no alpha channel data, fallback to the old way */
|
|
+ goto oldway;
|
|
+ }
|
|
+
|
|
+ /* load the saved fb patch in to image (faster way?) */
|
|
+ XGetSubImage(dpy, rcSavedArea, 0, 0, rcWidth, rcHeight,
|
|
+ AllPlanes, ZPixmap, alpha_image, 0, 0);
|
|
+ upix = (unsigned long *)alpha_image->data;
|
|
+
|
|
+ /* if the richcursor is clipped, the fb patch will be smaller */
|
|
+ rsW = rcWidth;
|
|
+ rsX = 0; /* used to denote a shift from the left side */
|
|
+ x = rcCursorX - rcHotX;
|
|
+ if (x < 0) {
|
|
+ rsW += x;
|
|
+ rsX = -x;
|
|
+ } else if (x + rsW > si.framebufferWidth) {
|
|
+ rsW = si.framebufferWidth - x;
|
|
+ }
|
|
+ rsH = rcHeight;
|
|
+ rsY = 0; /* used to denote a shift from the top side */
|
|
+ y = rcCursorY - rcHotY;
|
|
+ if (y < 0) {
|
|
+ rsH += y;
|
|
+ rsY = -y;
|
|
+ } else if (y + rsH > si.framebufferHeight) {
|
|
+ rsH = si.framebufferHeight - y;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * now loop over the cursor data, blend in the fb values,
|
|
+ * and then overwrite the fb (CopyDataToScreen())
|
|
+ */
|
|
+ for (y = 0; y < rcHeight; y++) {
|
|
+ y0 = rcCursorY - rcHotY + y;
|
|
+ if (y0 < 0 || y0 >= si.framebufferHeight) {
|
|
+ continue; /* clipped */
|
|
+ }
|
|
+ for (x = 0; x < rcWidth; x++) {
|
|
+ int alpha, color_curs, color_fb, i;
|
|
+
|
|
+ x0 = rcCursorX - rcHotX + x;
|
|
+ if (x0 < 0 || x0 >= si.framebufferWidth) {
|
|
+ continue; /* clipped */
|
|
+ }
|
|
+
|
|
+ offset = y * rcWidth + x;
|
|
+ pos = (char *)&rcSource[offset * bytesPerPixel];
|
|
+
|
|
+ /* extract secret alpha byte from rich cursor: */
|
|
+ upos = (unsigned long *) pos;
|
|
+ alpha = (*upos & 0xff000000) >> 24; /* XXX MSB? */
|
|
+
|
|
+ /* extract the pixel from the fb: */
|
|
+ pixel = *(upix + (y-rsY)*iwidth + (x-rsX));
|
|
+
|
|
+ put = 0;
|
|
+ /* for simplicity, blend all 4 bytes */
|
|
+ for (i = 0; i < 4; i++) {
|
|
+ int sh = i*8;
|
|
+ color_curs = ((0xff << sh) & *upos) >> sh;
|
|
+ color_fb = ((0xff << sh) & pixel) >> sh;
|
|
+
|
|
+ /* XXX assumes pre-multipled color_curs */
|
|
+ color_fb = color_curs
|
|
+ + ((0xff - alpha) * color_fb)/0xff;
|
|
+ put |= color_fb << sh;
|
|
+ }
|
|
+ /* place in the fb: */
|
|
+ CopyDataToScreen((char *)&put, x0, y0, 1, 1);
|
|
+ }
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+oldway:
|
|
+#endif
|
|
+
|
|
bytesPerPixel = myFormat.bitsPerPixel / 8;
|
|
|
|
/* FIXME: Speed optimization is possible. */
|
|
@@ -490,25 +651,26 @@
|
|
}
|
|
}
|
|
}
|
|
+ XSync(dpy, False);
|
|
}
|
|
|
|
-static void FreeSoftCursor(void)
|
|
+void FreeSoftCursor(void)
|
|
{
|
|
- if (prevSoftCursorSet) {
|
|
- SoftCursorCopyArea(OPER_RESTORE);
|
|
- XFreePixmap(dpy, rcSavedArea);
|
|
- free(rcSource);
|
|
- free(rcMask);
|
|
- prevSoftCursorSet = False;
|
|
- }
|
|
+ if (prevSoftCursorSet) {
|
|
+ SoftCursorCopyArea(OPER_RESTORE);
|
|
+ XFreePixmap(dpy, rcSavedArea);
|
|
+ free(rcSource);
|
|
+ rcSource = NULL;
|
|
+ free(rcMask);
|
|
+ prevSoftCursorSet = False;
|
|
+ }
|
|
}
|
|
|
|
|
|
-static void FreeX11Cursor()
|
|
+void FreeX11Cursor()
|
|
{
|
|
- if (prevXCursorSet) {
|
|
- XFreeCursor(dpy, prevXCursor);
|
|
- prevXCursorSet = False;
|
|
- }
|
|
+ if (prevXCursorSet) {
|
|
+ XFreeCursor(dpy, prevXCursor);
|
|
+ prevXCursorSet = False;
|
|
+ }
|
|
}
|
|
-
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncviewer/desktop.c
|
|
--- vnc_unixsrc.orig/vncviewer/desktop.c 2004-05-28 13:29:29.000000000 -0400
|
|
+++ vnc_unixsrc/vncviewer/desktop.c 2007-05-21 02:36:02.000000000 -0400
|
|
@@ -28,21 +28,28 @@
|
|
#include <X11/extensions/XShm.h>
|
|
#endif
|
|
|
|
+#include <X11/cursorfont.h>
|
|
+
|
|
GC gc;
|
|
GC srcGC, dstGC; /* used for debugging copyrect */
|
|
Window desktopWin;
|
|
-Cursor dotCursor;
|
|
+Cursor dotCursor = None;
|
|
+Cursor bogoCursor = None;
|
|
Widget form, viewport, desktop;
|
|
|
|
static Bool modifierPressed[256];
|
|
|
|
-static XImage *image = NULL;
|
|
+XImage *image = NULL;
|
|
+XImage *image_ycrop = NULL;
|
|
|
|
static Cursor CreateDotCursor();
|
|
+static Cursor CreateBogoCursor();
|
|
static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width,int height);
|
|
static void HandleBasicDesktopEvent(Widget w, XtPointer ptr, XEvent *ev,
|
|
Boolean *cont);
|
|
|
|
+static void CopyBGR565ToScreen(CARD16 *buf, int x, int y, int width,int height);
|
|
+
|
|
static XtResource desktopBackingStoreResources[] = {
|
|
{
|
|
XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int), 0,
|
|
@@ -50,6 +57,86 @@
|
|
},
|
|
};
|
|
|
|
+void create_image() {
|
|
+ image = NULL;
|
|
+ image_ycrop = NULL;
|
|
+
|
|
+//fprintf(stderr, "useShm: %d\n", appData.useShm);
|
|
+
|
|
+#ifdef MITSHM
|
|
+ if (appData.useShm) {
|
|
+ image = CreateShmImage(0);
|
|
+ if (!image) {
|
|
+ if (appData.yCrop > 0) {
|
|
+ image_ycrop = CreateShmImage(1);
|
|
+ if (!image_ycrop) {
|
|
+ appData.useShm = False;
|
|
+ } else {
|
|
+ fprintf(stderr, "created smaller image_ycrop "
|
|
+ "shm image\n");
|
|
+ }
|
|
+ } else {
|
|
+ appData.useShm = False;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if (!image) {
|
|
+ image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
|
|
+ si.framebufferWidth, si.framebufferHeight, BitmapPad(dpy), 0);
|
|
+
|
|
+ image->data = malloc(image->bytes_per_line * image->height);
|
|
+ if (!image->data) {
|
|
+ fprintf(stderr,"malloc failed\n");
|
|
+ exit(1);
|
|
+ } else {
|
|
+ fprintf(stderr, "created non-shm image\n");
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+int old_width = 0;
|
|
+int old_height = 0;
|
|
+
|
|
+int guessCrop(void) {
|
|
+ int w = si.framebufferWidth;
|
|
+
|
|
+ if (w == 320) {
|
|
+ return 240;
|
|
+ } else if (w == 400) {
|
|
+ return 300;
|
|
+ } else if (w == 640) {
|
|
+ return 480;
|
|
+ } else if (w == 800) {
|
|
+ return 600;
|
|
+ } else if (w == 1024) {
|
|
+ return 768;
|
|
+ } else if (w == 1152) {
|
|
+ return 864;
|
|
+ } else if (w == 1280) {
|
|
+ return 1024;
|
|
+ } else if (w == 1600) {
|
|
+ return 1200;
|
|
+ } else if (w == 1920) {
|
|
+ return 1200;
|
|
+ } else {
|
|
+ int h = (3 * w) / 4;
|
|
+ return h;
|
|
+ }
|
|
+}
|
|
+
|
|
+void check_tall(void) {
|
|
+ if (! appData.yCrop) {
|
|
+ int w = si.framebufferWidth;
|
|
+ int h = si.framebufferHeight;
|
|
+ if (h > 2 * w) {
|
|
+ fprintf(stderr, "Tall display (%dx%d) suspect 'x11vnc -ncache' mode,\n", w, h);
|
|
+ fprintf(stderr, " setting auto -ycrop detection.\n", w, h);
|
|
+ appData.yCrop = -1;
|
|
+ }
|
|
+ }
|
|
+}
|
|
|
|
/*
|
|
* DesktopInitBeforeRealization creates the "desktop" widget and the viewport
|
|
@@ -59,53 +146,158 @@
|
|
void
|
|
DesktopInitBeforeRealization()
|
|
{
|
|
- int i;
|
|
+ int i;
|
|
|
|
- form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel,
|
|
- XtNborderWidth, 0,
|
|
- XtNdefaultDistance, 0, NULL);
|
|
+ form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel,
|
|
+ XtNborderWidth, 0, XtNdefaultDistance, 0, NULL);
|
|
|
|
- viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form,
|
|
- XtNborderWidth, 0,
|
|
- NULL);
|
|
+ viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form,
|
|
+ XtNborderWidth, 0, NULL);
|
|
|
|
- desktop = XtVaCreateManagedWidget("desktop", coreWidgetClass, viewport,
|
|
- XtNborderWidth, 0,
|
|
- NULL);
|
|
-
|
|
- XtVaSetValues(desktop, XtNwidth, si.framebufferWidth,
|
|
- XtNheight, si.framebufferHeight, NULL);
|
|
+ desktop = XtVaCreateManagedWidget("desktop", coreWidgetClass, viewport,
|
|
+ XtNborderWidth, 0, NULL);
|
|
+
|
|
+ XtVaSetValues(desktop, XtNwidth, si.framebufferWidth,
|
|
+ XtNheight, si.framebufferHeight, NULL);
|
|
+
|
|
+ XtAddEventHandler(desktop, LeaveWindowMask|ExposureMask,
|
|
+ True, HandleBasicDesktopEvent, NULL);
|
|
+
|
|
+
|
|
+ check_tall();
|
|
+
|
|
+ if (appData.yCrop) {
|
|
+ int wm, hm;
|
|
+ if (appData.yCrop < 0) {
|
|
+ appData.yCrop = guessCrop();
|
|
+ fprintf(stderr, "Set -ycrop to: %d\n", appData.yCrop);
|
|
+ }
|
|
+ hm = appData.yCrop;
|
|
+ if (0 && appData.sbWidth <= 6 && appData.sbWidth > 0) {
|
|
+ hm += appData.sbWidth;
|
|
+ }
|
|
+ XtVaSetValues(toplevel, XtNmaxHeight, hm, NULL);
|
|
+ XtVaSetValues(form, XtNmaxHeight, hm, NULL);
|
|
+ XtVaSetValues(viewport, XtNforceBars, False, NULL);
|
|
+ }
|
|
+ old_width = si.framebufferWidth;
|
|
+ old_height = si.framebufferHeight;
|
|
|
|
- XtAddEventHandler(desktop, LeaveWindowMask|ExposureMask,
|
|
- True, HandleBasicDesktopEvent, NULL);
|
|
+ for (i = 0; i < 256; i++) {
|
|
+ modifierPressed[i] = False;
|
|
+ }
|
|
|
|
- for (i = 0; i < 256; i++)
|
|
- modifierPressed[i] = False;
|
|
+ create_image();
|
|
+}
|
|
|
|
- image = NULL;
|
|
+static Widget scrollbar_y = NULL;
|
|
|
|
-#ifdef MITSHM
|
|
- if (appData.useShm) {
|
|
- image = CreateShmImage();
|
|
- if (!image)
|
|
- appData.useShm = False;
|
|
- }
|
|
-#endif
|
|
+static int xsst = 2;
|
|
+#include <X11/Xaw/Scrollbar.h>
|
|
|
|
- if (!image) {
|
|
- image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
|
|
- si.framebufferWidth, si.framebufferHeight,
|
|
- BitmapPad(dpy), 0);
|
|
-
|
|
- image->data = malloc(image->bytes_per_line * image->height);
|
|
- if (!image->data) {
|
|
- fprintf(stderr,"malloc failed\n");
|
|
- exit(1);
|
|
- }
|
|
- }
|
|
+static XtCallbackProc Scrolled(Widget w, XtPointer closure, XtPointer call_data) {
|
|
+ Position x, y;
|
|
+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL);
|
|
+ if (0) fprintf(stderr, "scrolled by %d pixels x=%d y=%d\n", (int) call_data, x, y);
|
|
+ if (xsst == 2) {
|
|
+ x = 0;
|
|
+ y = 0;
|
|
+ XtVaSetValues(desktop, XtNx, x, XtNy, y, NULL);
|
|
+ } else if (xsst) {
|
|
+ XawScrollbarSetThumb(w, 0.0, 0.0);
|
|
+ } else {
|
|
+ float t = 0.0;
|
|
+ XtVaSetValues(w, XtNtopOfThumb, &t, NULL);
|
|
+ }
|
|
+}
|
|
+static XtCallbackProc Jumped(Widget w, XtPointer closure, XtPointer call_data) {
|
|
+ float top = *((float *) call_data);
|
|
+ Position x, y;
|
|
+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL);
|
|
+ if (0) fprintf(stderr, "thumb value: %.4f x=%d y=%d\n", top, x, y);
|
|
+ if (top > 0.01) {
|
|
+ if (xsst == 2) {
|
|
+ x = 0;
|
|
+ y = 0;
|
|
+ XtVaSetValues(desktop, XtNx, x, XtNy, y, NULL);
|
|
+ } else if (xsst) {
|
|
+ XawScrollbarSetThumb(w, 0.0, 0.0);
|
|
+ } else {
|
|
+ float t = 0.0, s = 1.0;
|
|
+ XtVaSetValues(w, XtNtopOfThumb, *(XtArgVal*)&t, XtNshown, *(XtArgVal*)&s, NULL);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
|
|
+extern double dnow(void);
|
|
+
|
|
+void check_things() {
|
|
+ static int installed_callback = 0;
|
|
+ static int first = 1;
|
|
+ static double last_scrollbar = 0.0;
|
|
+ int w = si.framebufferWidth;
|
|
+ int h = si.framebufferHeight;
|
|
+ double now = dnow();
|
|
+ static double last = 0;
|
|
+
|
|
+ if (first) {
|
|
+ first = 0;
|
|
+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False);
|
|
+ }
|
|
+ if (appData.yCrop > 0 && appData.yCrop < dpyHeight && h > 2*w && now > last_scrollbar + 0.25) {
|
|
+ Widget wv, wh, wc;
|
|
+ Position x0, y0;
|
|
+ Position x1, y1;
|
|
+ Dimension w0, h0, b0;
|
|
+ Dimension w1, h1, b1;
|
|
+ Dimension w2, h2, b2;
|
|
+
|
|
+ wc = XtNameToWidget(viewport, "clip");
|
|
+ wv = XtNameToWidget(viewport, "vertical");
|
|
+ wh = XtNameToWidget(viewport, "horizontal");
|
|
+ if (wc && wv && wh) {
|
|
+ int doit = 1;
|
|
+ int sb = appData.sbWidth;
|
|
+ XtVaGetValues(wv, XtNwidth, &w0, XtNheight, &h0, XtNborderWidth, &b0, XtNx, &x0, XtNy, &y0, NULL);
|
|
+ XtVaGetValues(wh, XtNwidth, &w1, XtNheight, &h1, XtNborderWidth, &b1, XtNx, &x1, XtNy, &y1, NULL);
|
|
+ XtVaGetValues(wc, XtNwidth, &w2, XtNheight, &h2, XtNborderWidth, &b2, NULL);
|
|
+ if (!sb) {
|
|
+ sb = 2;
|
|
+ }
|
|
+ if (w0 != sb || h1 != sb) {
|
|
+ fprintf(stderr, "Very tall (-ncache) fb, setting scrollbar thickness to: %d pixels\n", sb);
|
|
+
|
|
+ XtUnmanageChild(wv);
|
|
+ XtUnmanageChild(wh);
|
|
+ XtUnmanageChild(wc);
|
|
+
|
|
+ XtVaSetValues(wv, XtNwidth, sb, XtNx, x0 + (w0 - sb), NULL);
|
|
+ XtVaSetValues(wh, XtNheight, sb, XtNy, y1 + (h1 - sb), NULL);
|
|
+ w2 = w2 + (w0 - sb);
|
|
+ h2 = h2 + (h1 - sb);
|
|
+ if (w2 > 10 && h2 > 10) {
|
|
+ XtVaSetValues(wc, XtNwidth, w2, XtNheight, h2, NULL);
|
|
+ }
|
|
+
|
|
+ XtManageChild(wv);
|
|
+ XtManageChild(wh);
|
|
+ XtManageChild(wc);
|
|
+ }
|
|
+ }
|
|
+ last_scrollbar = dnow();
|
|
+ }
|
|
+
|
|
+ if (now <= last + 1.0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy));
|
|
+ dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy));
|
|
+
|
|
+ last = dnow();
|
|
+}
|
|
+
|
|
/*
|
|
* DesktopInitAfterRealization does things which require the X windows to
|
|
* exist. It creates some GCs and sets the dot cursor.
|
|
@@ -114,34 +306,110 @@
|
|
void
|
|
DesktopInitAfterRealization()
|
|
{
|
|
- XGCValues gcv;
|
|
- XSetWindowAttributes attr;
|
|
- unsigned long valuemask;
|
|
-
|
|
- desktopWin = XtWindow(desktop);
|
|
-
|
|
- gc = XCreateGC(dpy,desktopWin,0,NULL);
|
|
-
|
|
- gcv.function = GXxor;
|
|
- gcv.foreground = 0x0f0f0f0f;
|
|
- srcGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv);
|
|
- gcv.foreground = 0xf0f0f0f0;
|
|
- dstGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv);
|
|
-
|
|
- XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
|
|
- NULL, 0);
|
|
-
|
|
- XtVaGetApplicationResources(desktop, (XtPointer)&attr.backing_store,
|
|
- desktopBackingStoreResources, 1, NULL);
|
|
- valuemask = CWBackingStore;
|
|
-
|
|
- if (!appData.useX11Cursor) {
|
|
- dotCursor = CreateDotCursor();
|
|
- attr.cursor = dotCursor;
|
|
- valuemask |= CWCursor;
|
|
- }
|
|
+ XGCValues gcv;
|
|
+ XSetWindowAttributes attr;
|
|
+ XWindowAttributes gattr;
|
|
+ unsigned long valuemask = 0;
|
|
+
|
|
+ desktopWin = XtWindow(desktop);
|
|
+
|
|
+ gc = XCreateGC(dpy,desktopWin,0,NULL);
|
|
+
|
|
+ gcv.function = GXxor;
|
|
+ gcv.foreground = 0x0f0f0f0f;
|
|
+ srcGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv);
|
|
+ gcv.foreground = 0xf0f0f0f0;
|
|
+ dstGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv);
|
|
+
|
|
+ XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
|
|
+ NULL, 0);
|
|
+
|
|
+ if (appData.useBackingstore) {
|
|
+ Screen *s = DefaultScreenOfDisplay(dpy);
|
|
+ if (DoesBackingStore(s) != Always) {
|
|
+ fprintf(stderr, "X server does not do backingstore, disabling it.\n");
|
|
+ appData.useBackingstore = False;
|
|
+ }
|
|
+ }
|
|
|
|
- XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr);
|
|
+ if (appData.useBackingstore) {
|
|
+ XtVaGetApplicationResources(desktop, (XtPointer)&attr.backing_store,
|
|
+ desktopBackingStoreResources, 1, NULL);
|
|
+ valuemask |= CWBackingStore;
|
|
+ } else {
|
|
+ attr.background_pixel = BlackPixel(dpy, DefaultScreen(dpy));
|
|
+ valuemask |= CWBackPixel;
|
|
+ }
|
|
+
|
|
+ if (!appData.useX11Cursor) {
|
|
+ dotCursor = CreateDotCursor();
|
|
+ attr.cursor = dotCursor;
|
|
+ valuemask |= CWCursor;
|
|
+ }
|
|
+ bogoCursor = XCreateFontCursor(dpy, XC_bogosity);
|
|
+
|
|
+ XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr);
|
|
+ if (XGetWindowAttributes(dpy, desktopWin, &gattr)) {
|
|
+#if 0
|
|
+ fprintf(stderr, "desktopWin backingstore: %d save_under: %d\n", gattr.backing_store, gattr.save_under);
|
|
+#endif
|
|
+ }
|
|
+ fprintf(stderr, "\n");
|
|
+}
|
|
+
|
|
+extern void FreeX11Cursor(void);
|
|
+extern void FreeSoftCursor(void);
|
|
+
|
|
+void
|
|
+DesktopCursorOff()
|
|
+{
|
|
+ XSetWindowAttributes attr;
|
|
+ unsigned long valuemask;
|
|
+
|
|
+ if (dotCursor == None) {
|
|
+ dotCursor = CreateDotCursor();
|
|
+ }
|
|
+ XDefineCursor(dpy, desktopWin, dotCursor);
|
|
+ FreeX11Cursor();
|
|
+ FreeSoftCursor();
|
|
+}
|
|
+
|
|
+void put_image(int src_x, int src_y, int dst_x, int dst_y, int width,
|
|
+ int height) {
|
|
+
|
|
+#ifdef MITSHM
|
|
+ if (appData.useShm) {
|
|
+ if (image_ycrop == NULL) {
|
|
+//fprintf(stderr, "shm not image_ycrop\n");
|
|
+ XShmPutImage(dpy, desktopWin, gc, image, src_x, src_y,
|
|
+ dst_x, dst_y, width, height, False);
|
|
+ } else if ((width < 32 && height < 32) || height > appData.yCrop) {
|
|
+//fprintf(stderr, "non-shmB image %d %d %d %d %d %d\n", src_x, src_y, dst_x, dst_y, width, height);
|
|
+ XPutImage(dpy, desktopWin, gc, image, src_x, src_y,
|
|
+ dst_x, dst_y, width, height);
|
|
+ } else {
|
|
+ char *src, *dst;
|
|
+ int Bpp = image->bits_per_pixel / 8;
|
|
+ int Bpl = image->bytes_per_line, h;
|
|
+ int Bpl2 = image_ycrop->bytes_per_line;
|
|
+ src = image->data + src_y * Bpl + src_x * Bpp;
|
|
+ dst = image_ycrop->data;
|
|
+ for (h = 0; h < height; h++) {
|
|
+ memcpy(dst, src, width * Bpp);
|
|
+ src += Bpl;
|
|
+ dst += Bpl2;
|
|
+ }
|
|
+//fprintf(stderr, "shm image_ycrop %d %d %d %d %d %d\n", 0, 0, dst_x, dst_y, width, height);
|
|
+ XShmPutImage(dpy, desktopWin, gc, image_ycrop, 0, 0,
|
|
+ dst_x, dst_y, width, height, False);
|
|
+ }
|
|
+ } else
|
|
+#endif
|
|
+ {
|
|
+//fprintf(stderr, "non-shmA image %d %d %d %d %d %d\n", src_x, src_y, dst_x, dst_y, width, height);
|
|
+ XPutImage(dpy, desktopWin, gc, image, src_x, src_y,
|
|
+ dst_x, dst_y, width, height);
|
|
+ }
|
|
}
|
|
|
|
|
|
@@ -152,39 +420,53 @@
|
|
static void
|
|
HandleBasicDesktopEvent(Widget w, XtPointer ptr, XEvent *ev, Boolean *cont)
|
|
{
|
|
- int i;
|
|
+ int i, x, y, width, height;
|
|
|
|
- switch (ev->type) {
|
|
|
|
+ switch (ev->type) {
|
|
case Expose:
|
|
case GraphicsExpose:
|
|
/* sometimes due to scrollbars being added/removed we get an expose outside
|
|
the actual desktop area. Make sure we don't pass it on to the RFB
|
|
server. */
|
|
+ x = ev->xexpose.x;
|
|
+ y = ev->xexpose.y;
|
|
+ width = ev->xexpose.width;
|
|
+ height = ev->xexpose.height;
|
|
+
|
|
+//fprintf(stderr, "Expose: %dx%d+%d+%d\n", width, height, x, y);
|
|
+ if (x + width > si.framebufferWidth) {
|
|
+ width = si.framebufferWidth - x;
|
|
+ if (width <= 0) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
|
|
- if (ev->xexpose.x + ev->xexpose.width > si.framebufferWidth) {
|
|
- ev->xexpose.width = si.framebufferWidth - ev->xexpose.x;
|
|
- if (ev->xexpose.width <= 0) break;
|
|
- }
|
|
-
|
|
- if (ev->xexpose.y + ev->xexpose.height > si.framebufferHeight) {
|
|
- ev->xexpose.height = si.framebufferHeight - ev->xexpose.y;
|
|
- if (ev->xexpose.height <= 0) break;
|
|
- }
|
|
+ if (y + height > si.framebufferHeight) {
|
|
+ height = si.framebufferHeight - y;
|
|
+ if (height <= 0) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
|
|
- SendFramebufferUpdateRequest(ev->xexpose.x, ev->xexpose.y,
|
|
- ev->xexpose.width, ev->xexpose.height, False);
|
|
- break;
|
|
+ if (appData.useBackingstore) {
|
|
+ SendFramebufferUpdateRequest(x, y, width, height, False);
|
|
+ } else {
|
|
+ put_image(x, y, x, y, width, height);
|
|
+ XSync(dpy, False);
|
|
+ }
|
|
+ break;
|
|
|
|
case LeaveNotify:
|
|
- for (i = 0; i < 256; i++) {
|
|
- if (modifierPressed[i]) {
|
|
- SendKeyEvent(XKeycodeToKeysym(dpy, i, 0), False);
|
|
- modifierPressed[i] = False;
|
|
- }
|
|
- }
|
|
- break;
|
|
+ for (i = 0; i < 256; i++) {
|
|
+ if (modifierPressed[i]) {
|
|
+ SendKeyEvent(XKeycodeToKeysym(dpy, i, 0), False);
|
|
+ modifierPressed[i] = False;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
}
|
|
+ check_things();
|
|
}
|
|
|
|
|
|
@@ -201,6 +483,10 @@
|
|
* button2 down, 3 for both, etc).
|
|
*/
|
|
|
|
+extern Bool selectingSingleWindow;
|
|
+
|
|
+extern Cursor dotCursor;
|
|
+
|
|
void
|
|
SendRFBEvent(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
{
|
|
@@ -208,12 +494,28 @@
|
|
char keyname[256];
|
|
int buttonMask, x, y;
|
|
|
|
- if (appData.fullScreen && ev->type == MotionNotify) {
|
|
- if (BumpScroll(ev))
|
|
- return;
|
|
- }
|
|
+ if (appData.fullScreen && ev->type == MotionNotify) {
|
|
+ if (BumpScroll(ev)) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
|
|
- if (appData.viewOnly) return;
|
|
+ if (selectingSingleWindow && ev->type == ButtonPress) {
|
|
+ selectingSingleWindow = False;
|
|
+ SendSingleWindow(ev->xbutton.x, ev->xbutton.y);
|
|
+ XDefineCursor(dpy, desktopWin, dotCursor);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (appData.viewOnly) {
|
|
+ if (*num_params != 0) {
|
|
+ if (strcasecmp(params[0],"fbupdate") == 0) {
|
|
+ SendFramebufferUpdateRequest(0, 0,
|
|
+ si.framebufferWidth, si.framebufferHeight, False);
|
|
+ }
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
|
|
if (*num_params != 0) {
|
|
if (strncasecmp(params[0],"key",3) == 0) {
|
|
@@ -329,26 +631,150 @@
|
|
* CreateDotCursor.
|
|
*/
|
|
|
|
+#ifndef very_small_dot_cursor
|
|
+static Cursor
|
|
+CreateDotCursor()
|
|
+{
|
|
+ Cursor cursor;
|
|
+ Pixmap src, msk;
|
|
+ static char srcBits[] = { 0, 14,14, 0 };
|
|
+ static char mskBits[] = { 14,31,31,14 };
|
|
+ XColor fg, bg;
|
|
+
|
|
+ src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits, 4, 4);
|
|
+ msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits, 4, 4);
|
|
+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "black",
|
|
+ &fg, &fg);
|
|
+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "white",
|
|
+ &bg, &bg);
|
|
+ cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 1, 1);
|
|
+ XFreePixmap(dpy, src);
|
|
+ XFreePixmap(dpy, msk);
|
|
+
|
|
+ return cursor;
|
|
+}
|
|
+#else
|
|
static Cursor
|
|
CreateDotCursor()
|
|
{
|
|
- Cursor cursor;
|
|
- Pixmap src, msk;
|
|
- static char srcBits[] = { 0, 14,14,14, 0 };
|
|
- static char mskBits[] = { 14,31,31,31,14 };
|
|
- XColor fg, bg;
|
|
-
|
|
- src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits, 5, 5);
|
|
- msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits, 5, 5);
|
|
- XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "black",
|
|
- &fg, &fg);
|
|
- XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "white",
|
|
- &bg, &bg);
|
|
- cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 2, 2);
|
|
- XFreePixmap(dpy, src);
|
|
- XFreePixmap(dpy, msk);
|
|
+ Cursor cursor;
|
|
+ Pixmap src, msk;
|
|
+ static char srcBits[] = { 0, 14, 0 };
|
|
+ static char mskBits[] = { 14,31,14 };
|
|
+ XColor fg, bg;
|
|
+
|
|
+ src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits, 3, 3);
|
|
+ msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits, 3, 3);
|
|
+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "black",
|
|
+ &fg, &fg);
|
|
+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "white",
|
|
+ &bg, &bg);
|
|
+ cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 1, 1);
|
|
+ XFreePixmap(dpy, src);
|
|
+ XFreePixmap(dpy, msk);
|
|
+
|
|
+ return cursor;
|
|
+}
|
|
+#endif
|
|
+
|
|
+void maybe_sync(int width, int height) {
|
|
+ static int singles = 0;
|
|
+ if (width > 1 || height > 1) {
|
|
+ XSync(dpy, False);
|
|
+ singles = 0;
|
|
+ } else {
|
|
+ if (++singles >= 32) {
|
|
+ singles = 0;
|
|
+ XSync(dpy, False);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+/*
|
|
+ * FillImage.
|
|
+ */
|
|
+
|
|
+void
|
|
+FillScreen(int x, int y, int width, int height, unsigned long fill)
|
|
+{
|
|
+ int bpp = image->bits_per_pixel;
|
|
+ int Bpp = image->bits_per_pixel / 8;
|
|
+ int Bpl = image->bytes_per_line;
|
|
+ int h, widthInBytes = width * Bpp;
|
|
+ static char *buf = NULL;
|
|
+ static int buflen = 0;
|
|
+ unsigned char *ucp;
|
|
+ unsigned short *usp;
|
|
+ unsigned int *uip;
|
|
+ char *scr;
|
|
+ int b0, b1, b2;
|
|
+
|
|
+//fprintf(stderr, "FillImage bpp=%d %04dx%04d+%04d+%04d -- 0x%x\n", bpp, width, height, x, y, fill);
|
|
+
|
|
+ if (widthInBytes > buflen || !buf) {
|
|
+ if (buf) {
|
|
+ free(buf);
|
|
+ }
|
|
+ buflen = widthInBytes * 2;
|
|
+ buf = (char *)malloc(buflen);
|
|
+ }
|
|
+ ucp = (unsigned char*) buf;
|
|
+ usp = (unsigned short*) buf;
|
|
+ uip = (unsigned int*) buf;
|
|
+
|
|
+ if (isLSB) {
|
|
+ b0 = 0; b1 = 1; b2 = 2;
|
|
+ } else {
|
|
+ b0 = 2; b1 = 1; b2 = 0;
|
|
+ }
|
|
+
|
|
+ for (h = 0; h < width; h++) {
|
|
+ if (bpp == 8) {
|
|
+ *(ucp+h) = (unsigned char) fill;
|
|
+ } else if (bpp == 16) {
|
|
+ *(usp+h) = (unsigned short) fill;
|
|
+ } else if (bpp == 24) {
|
|
+ *(ucp + 3*h + b0) = (unsigned char) ((fill & 0x0000ff) >> 0);
|
|
+ *(ucp + 3*h + b1) = (unsigned char) ((fill & 0x00ff00) >> 8);
|
|
+ *(ucp + 3*h + b2) = (unsigned char) ((fill & 0xff0000) >> 16);
|
|
+ } else if (bpp == 32) {
|
|
+ *(uip+h) = (unsigned int) fill;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ scr = image->data + y * Bpl + x * Bpp;
|
|
+
|
|
+ for (h = 0; h < height; h++) {
|
|
+ memcpy(scr, buf, widthInBytes);
|
|
+ scr += Bpl;
|
|
+ }
|
|
+ put_image(x, y, x, y, width, height);
|
|
+ maybe_sync(width, height);
|
|
+}
|
|
|
|
- return cursor;
|
|
+void copy_rect(int x, int y, int width, int height, int src_x, int src_y) {
|
|
+ char *src, *dst;
|
|
+ int i;
|
|
+ int Bpp = image->bits_per_pixel / 8;
|
|
+ int Bpl = image->bytes_per_line;
|
|
+
|
|
+//fprintf(stderr, "copy_rect: %04dx%04d+%04d+%04d -- %04d %04d Bpp=%d Bpl=%d\n", width, height, x, y, src_x, src_y, Bpp, Bpl);
|
|
+ if (y < src_y) {
|
|
+ src = image->data + src_y * Bpl + src_x * Bpp;
|
|
+ dst = image->data + y * Bpl + x * Bpp;
|
|
+ for (i = 0; i < height; i++) {
|
|
+ memmove(dst, src, Bpp * width);
|
|
+ src += Bpl;
|
|
+ dst += Bpl;
|
|
+ }
|
|
+ } else {
|
|
+ src = image->data + (src_y + height - 1) * Bpl + src_x * Bpp;
|
|
+ dst = image->data + (y + height - 1) * Bpl + x * Bpp;
|
|
+ for (i = 0; i < height; i++) {
|
|
+ memmove(dst, src, Bpp * width);
|
|
+ src -= Bpl;
|
|
+ dst -= Bpl;
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
|
|
@@ -359,38 +785,35 @@
|
|
void
|
|
CopyDataToScreen(char *buf, int x, int y, int width, int height)
|
|
{
|
|
- if (appData.rawDelay != 0) {
|
|
- XFillRectangle(dpy, desktopWin, gc, x, y, width, height);
|
|
-
|
|
- XSync(dpy,False);
|
|
-
|
|
- usleep(appData.rawDelay * 1000);
|
|
- }
|
|
+ if (appData.rawDelay != 0) {
|
|
+ XFillRectangle(dpy, desktopWin, gc, x, y, width, height);
|
|
+ XSync(dpy,False);
|
|
+ usleep(appData.rawDelay * 1000);
|
|
+ }
|
|
|
|
- if (!appData.useBGR233) {
|
|
- int h;
|
|
- int widthInBytes = width * myFormat.bitsPerPixel / 8;
|
|
- int scrWidthInBytes = si.framebufferWidth * myFormat.bitsPerPixel / 8;
|
|
-
|
|
- char *scr = (image->data + y * scrWidthInBytes
|
|
- + x * myFormat.bitsPerPixel / 8);
|
|
-
|
|
- for (h = 0; h < height; h++) {
|
|
- memcpy(scr, buf, widthInBytes);
|
|
- buf += widthInBytes;
|
|
- scr += scrWidthInBytes;
|
|
- }
|
|
- } else {
|
|
- CopyBGR233ToScreen((CARD8 *)buf, x, y, width, height);
|
|
- }
|
|
+ if (appData.useBGR233) {
|
|
+ CopyBGR233ToScreen((CARD8 *)buf, x, y, width, height);
|
|
+ } else if (appData.useBGR565) {
|
|
+ CopyBGR565ToScreen((CARD16 *)buf, x, y, width, height);
|
|
+ } else {
|
|
+ int h;
|
|
+ int widthInBytes = width * myFormat.bitsPerPixel / 8;
|
|
+ int scrWidthInBytes = si.framebufferWidth * myFormat.bitsPerPixel / 8;
|
|
+
|
|
+ char *scr = (image->data + y * scrWidthInBytes
|
|
+ + x * myFormat.bitsPerPixel / 8);
|
|
+
|
|
+//fprintf(stderr, "CopyDataToScreen %dx%d+%d+%d\n", width, height, x, y);
|
|
+
|
|
+ for (h = 0; h < height; h++) {
|
|
+ memcpy(scr, buf, widthInBytes);
|
|
+ buf += widthInBytes;
|
|
+ scr += scrWidthInBytes;
|
|
+ }
|
|
+ }
|
|
|
|
-#ifdef MITSHM
|
|
- if (appData.useShm) {
|
|
- XShmPutImage(dpy, desktopWin, gc, image, x, y, x, y, width, height, False);
|
|
- return;
|
|
- }
|
|
-#endif
|
|
- XPutImage(dpy, desktopWin, gc, image, x, y, x, y, width, height);
|
|
+ put_image(x, y, x, y, width, height);
|
|
+ maybe_sync(width, height);
|
|
}
|
|
|
|
|
|
@@ -401,62 +824,226 @@
|
|
static void
|
|
CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height)
|
|
{
|
|
- int p, q;
|
|
- int xoff = 7 - (x & 7);
|
|
- int xcur;
|
|
- int fbwb = si.framebufferWidth / 8;
|
|
- CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8;
|
|
- CARD8 *scrt;
|
|
- CARD8 *scr8 = ((CARD8 *)image->data) + y * si.framebufferWidth + x;
|
|
- CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x;
|
|
- CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x;
|
|
+ int p, q;
|
|
+ int xoff = 7 - (x & 7);
|
|
+ int xcur;
|
|
+ int fbwb = si.framebufferWidth / 8;
|
|
+ CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8;
|
|
+ CARD8 *scrt;
|
|
+ CARD8 *scr8 = ( (CARD8 *)image->data) + y * si.framebufferWidth + x;
|
|
+ CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x;
|
|
+ CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x;
|
|
+ int b0, b1, b2;
|
|
|
|
- switch (visbpp) {
|
|
+ switch (visbpp) {
|
|
|
|
/* thanks to Chris Hooper for single bpp support */
|
|
|
|
- case 1:
|
|
- for (q = 0; q < height; q++) {
|
|
- xcur = xoff;
|
|
- scrt = scr1;
|
|
- for (p = 0; p < width; p++) {
|
|
- *scrt = ((*scrt & ~(1 << xcur))
|
|
- | (BGR233ToPixel[*(buf++)] << xcur));
|
|
-
|
|
- if (xcur-- == 0) {
|
|
- xcur = 7;
|
|
- scrt++;
|
|
+ case 1:
|
|
+ for (q = 0; q < height; q++) {
|
|
+ xcur = xoff;
|
|
+ scrt = scr1;
|
|
+ for (p = 0; p < width; p++) {
|
|
+ *scrt = ((*scrt & ~(1 << xcur))
|
|
+ | (BGR233ToPixel[*(buf++)] << xcur));
|
|
+
|
|
+ if (xcur-- == 0) {
|
|
+ xcur = 7;
|
|
+ scrt++;
|
|
+ }
|
|
+ }
|
|
+ scr1 += fbwb;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case 8:
|
|
+ for (q = 0; q < height; q++) {
|
|
+ for (p = 0; p < width; p++) {
|
|
+ *(scr8++) = BGR233ToPixel[*(buf++)];
|
|
+ }
|
|
+ scr8 += si.framebufferWidth - width;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case 16:
|
|
+ for (q = 0; q < height; q++) {
|
|
+ for (p = 0; p < width; p++) {
|
|
+ *(scr16++) = BGR233ToPixel[*(buf++)];
|
|
+ }
|
|
+ scr16 += si.framebufferWidth - width;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case 24:
|
|
+ if (isLSB) {
|
|
+ b0 = 0; b1 = 1; b2 = 2;
|
|
+ } else {
|
|
+ b0 = 2; b1 = 1; b2 = 0;
|
|
+ }
|
|
+ scr8 = ((CARD8 *)image->data) + (y * si.framebufferWidth + x) * 3;
|
|
+ for (q = 0; q < height; q++) {
|
|
+ for (p = 0; p < width; p++) {
|
|
+ CARD32 v = BGR233ToPixel[*(buf++)];
|
|
+ *(scr8 + b0) = (unsigned char) ((v & 0x0000ff) >> 0);
|
|
+ *(scr8 + b1) = (unsigned char) ((v & 0x00ff00) >> 8);
|
|
+ *(scr8 + b2) = (unsigned char) ((v & 0xff0000) >> 16);
|
|
+ scr8 += 3;
|
|
+ }
|
|
+ scr8 += (si.framebufferWidth - width) * 3;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case 32:
|
|
+ for (q = 0; q < height; q++) {
|
|
+ for (p = 0; p < width; p++) {
|
|
+ *(scr32++) = BGR233ToPixel[*(buf++)];
|
|
+ }
|
|
+ scr32 += si.framebufferWidth - width;
|
|
+ }
|
|
+ break;
|
|
}
|
|
- }
|
|
- scr1 += fbwb;
|
|
- }
|
|
- break;
|
|
+}
|
|
|
|
- case 8:
|
|
- for (q = 0; q < height; q++) {
|
|
- for (p = 0; p < width; p++) {
|
|
- *(scr8++) = BGR233ToPixel[*(buf++)];
|
|
- }
|
|
- scr8 += si.framebufferWidth - width;
|
|
- }
|
|
- break;
|
|
+static void
|
|
+BGR565_24bpp(CARD16 *buf, int x, int y, int width, int height)
|
|
+{
|
|
+ int p, q;
|
|
+ int b0, b1, b2;
|
|
+ unsigned char *scr= (unsigned char *)image->data + (y * si.framebufferWidth + x) * 3;
|
|
+
|
|
+ if (isLSB) {
|
|
+ b0 = 0; b1 = 1; b2 = 2;
|
|
+ } else {
|
|
+ b0 = 2; b1 = 1; b2 = 0;
|
|
+ }
|
|
|
|
- case 16:
|
|
- for (q = 0; q < height; q++) {
|
|
- for (p = 0; p < width; p++) {
|
|
- *(scr16++) = BGR233ToPixel[*(buf++)];
|
|
- }
|
|
- scr16 += si.framebufferWidth - width;
|
|
- }
|
|
- break;
|
|
+ /* case 24: */
|
|
+ for (q = 0; q < height; q++) {
|
|
+ for (p = 0; p < width; p++) {
|
|
+ CARD32 v = BGR565ToPixel[*(buf++)];
|
|
+ *(scr + b0) = (unsigned char) ((v & 0x0000ff) >> 0);
|
|
+ *(scr + b1) = (unsigned char) ((v & 0x00ff00) >> 8);
|
|
+ *(scr + b2) = (unsigned char) ((v & 0xff0000) >> 16);
|
|
+ scr += 3;
|
|
+ }
|
|
+ scr += (si.framebufferWidth - width) * 3;
|
|
+ }
|
|
+}
|
|
|
|
- case 32:
|
|
- for (q = 0; q < height; q++) {
|
|
- for (p = 0; p < width; p++) {
|
|
- *(scr32++) = BGR233ToPixel[*(buf++)];
|
|
- }
|
|
- scr32 += si.framebufferWidth - width;
|
|
- }
|
|
- break;
|
|
- }
|
|
+static void
|
|
+CopyBGR565ToScreen(CARD16 *buf, int x, int y, int width, int height)
|
|
+{
|
|
+ int p, q;
|
|
+ CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x;
|
|
+
|
|
+ if (visbpp == 24) {
|
|
+ BGR565_24bpp(buf, x, y, width, height);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* case 32: */
|
|
+ for (q = 0; q < height; q++) {
|
|
+ for (p = 0; p < width; p++) {
|
|
+ *(scr32++) = BGR565ToPixel[*(buf++)];
|
|
+ }
|
|
+ scr32 += si.framebufferWidth - width;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void reset_image(void) {
|
|
+ if (UsingShm()) {
|
|
+ ShmCleanup();
|
|
+ }
|
|
+ if (image && image->data) {
|
|
+ XDestroyImage(image);
|
|
+ }
|
|
+ image = NULL;
|
|
+ if (image_ycrop && image_ycrop->data) {
|
|
+ XDestroyImage(image_ycrop);
|
|
+ }
|
|
+ image_ycrop = NULL;
|
|
+ create_image();
|
|
+ XFlush(dpy);
|
|
+}
|
|
+
|
|
+void ReDoDesktop(void) {
|
|
+ int w, h, x, y, dw, dh;
|
|
+
|
|
+ check_tall();
|
|
+ if (appData.yCrop) {
|
|
+ if (appData.yCrop < 0 || old_width <= 0) {
|
|
+ appData.yCrop = guessCrop();
|
|
+ fprintf(stderr, "Set -ycrop to: %d\n", appData.yCrop);
|
|
+ } else {
|
|
+ int w1 = si.framebufferWidth;
|
|
+ int w0 = old_width;
|
|
+ appData.yCrop = (w1 * appData.yCrop) / old_width;
|
|
+ if (appData.yCrop <= 100) {
|
|
+ appData.yCrop = guessCrop();
|
|
+ fprintf(stderr, "Set small -ycrop to: %d\n", appData.yCrop);
|
|
+ }
|
|
+ }
|
|
+ fprintf(stderr, "Using -ycrop: %d\n", appData.yCrop);
|
|
+ }
|
|
+ old_width = si.framebufferWidth;
|
|
+ old_height = si.framebufferHeight;
|
|
+
|
|
+ if (appData.fullScreen) {
|
|
+ if (image && image->data) {
|
|
+ int len;
|
|
+ int h = image->height;
|
|
+ int w = image->width;
|
|
+ len = image->bytes_per_line * image->height;
|
|
+ /* black out window first: */
|
|
+ memset(image->data, 0, len);
|
|
+ XPutImage(dpy, XtWindow(desktop), gc, image, 0, 0, 0, 0, w, h);
|
|
+ XFlush(dpy);
|
|
+ }
|
|
+ XtResizeWidget(desktop, si.framebufferWidth, si.framebufferHeight, 0);
|
|
+ XSync(dpy, False);
|
|
+ usleep(100*1000);
|
|
+ FullScreenOn();
|
|
+ XSync(dpy, False);
|
|
+ usleep(100*1000);
|
|
+ reset_image();
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ dw = appData.wmDecorationWidth;
|
|
+ dh = appData.wmDecorationHeight;
|
|
+
|
|
+ w = si.framebufferWidth;
|
|
+ h = si.framebufferHeight;
|
|
+ if (appData.yCrop > 0) {
|
|
+ h = appData.yCrop;
|
|
+ if (0 && appData.sbWidth <= 6 && appData.sbWidth > 0) {
|
|
+ h += appData.sbWidth;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (w + dw >= dpyWidth) {
|
|
+ w = dpyWidth - dw;
|
|
+ }
|
|
+ if (h + dh >= dpyHeight) {
|
|
+ h = dpyHeight - dh;
|
|
+ }
|
|
+
|
|
+ XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, h, NULL);
|
|
+
|
|
+ XtVaSetValues(desktop, XtNwidth, si.framebufferWidth,
|
|
+ XtNheight, si.framebufferHeight, NULL);
|
|
+
|
|
+ x = (dpyWidth - w - dw)/2;
|
|
+ y = (dpyHeight - h - dh)/2;
|
|
+
|
|
+ XtResizeWidget(desktop, si.framebufferWidth, si.framebufferHeight, 0);
|
|
+
|
|
+ if (appData.yCrop > 0) {
|
|
+ XtVaSetValues(toplevel, XtNmaxHeight, appData.yCrop, NULL);
|
|
+ XtVaSetValues(form, XtNmaxHeight, appData.yCrop, NULL);
|
|
+ }
|
|
+
|
|
+ XtConfigureWidget(toplevel, x + dw, y + dh, w, h, 0);
|
|
+
|
|
+ reset_image();
|
|
}
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/fullscreen.c vnc_unixsrc/vncviewer/fullscreen.c
|
|
--- vnc_unixsrc.orig/vncviewer/fullscreen.c 2003-10-09 05:23:49.000000000 -0400
|
|
+++ vnc_unixsrc/vncviewer/fullscreen.c 2007-02-17 16:32:23.000000000 -0500
|
|
@@ -85,10 +85,14 @@
|
|
Dimension oldViewportWidth, oldViewportHeight, clipWidth, clipHeight;
|
|
Position viewportX, viewportY;
|
|
|
|
+ Bool fsAlready = appData.fullScreen, toobig = False;
|
|
+
|
|
appData.fullScreen = True;
|
|
|
|
if (si.framebufferWidth > dpyWidth || si.framebufferHeight > dpyHeight) {
|
|
+ int eff_height = si.framebufferHeight;
|
|
|
|
+ toobig = True;
|
|
XtVaSetValues(viewport, XtNforceBars, True, NULL);
|
|
XtVaGetValues(viewport, XtNwidth, &oldViewportWidth,
|
|
XtNheight, &oldViewportHeight, NULL);
|
|
@@ -105,16 +109,23 @@
|
|
toplevelWidth = dpyWidth;
|
|
}
|
|
|
|
- if (si.framebufferHeight > dpyHeight) {
|
|
+ if (appData.yCrop > 0) {
|
|
+ eff_height = appData.yCrop;
|
|
+ }
|
|
+
|
|
+ if (eff_height > dpyHeight) {
|
|
viewportHeight = toplevelHeight = dpyHeight + scrollbarHeight;
|
|
} else {
|
|
- viewportHeight = si.framebufferHeight + scrollbarHeight;
|
|
+ viewportHeight = eff_height + scrollbarHeight;
|
|
toplevelHeight = dpyHeight;
|
|
}
|
|
|
|
} else {
|
|
viewportWidth = si.framebufferWidth;
|
|
viewportHeight = si.framebufferHeight;
|
|
+ if (appData.yCrop > 0) {
|
|
+ viewportHeight = appData.yCrop;
|
|
+ }
|
|
toplevelWidth = dpyWidth;
|
|
toplevelHeight = dpyHeight;
|
|
}
|
|
@@ -129,7 +140,12 @@
|
|
reparenting our window to the root. The window manager will get a
|
|
ReparentNotify and hopefully clean up its frame window. */
|
|
|
|
+if (! fsAlready) {
|
|
+ XUnmapWindow(dpy, XtWindow(toplevel));
|
|
XtVaSetValues(toplevel, XtNoverrideRedirect, True, NULL);
|
|
+ XtVaSetValues(viewport, XtNoverrideRedirect, True, NULL);
|
|
+ XtVaSetValues(desktop, XtNoverrideRedirect, True, NULL);
|
|
+ XtVaSetValues(popup, XtNoverrideRedirect, True, NULL);
|
|
|
|
XReparentWindow(dpy, XtWindow(toplevel), DefaultRootWindow(dpy), 0, 0);
|
|
|
|
@@ -139,6 +155,8 @@
|
|
with XReparentWindow. The last XSync seems to prevent losing
|
|
focus, but I don't know why. */
|
|
XSync(dpy, False);
|
|
+XMapWindow(dpy, XtWindow(toplevel));
|
|
+XRaiseWindow(dpy, XtWindow(toplevel));
|
|
XMoveWindow(dpy, XtWindow(toplevel), 0, 0);
|
|
XSync(dpy, False);
|
|
|
|
@@ -164,25 +182,67 @@
|
|
|
|
XtManageChild(viewport);
|
|
|
|
- /* Now we can set "toplevel" to its proper size. */
|
|
+} else {
|
|
+ XSync(dpy, False);
|
|
+}
|
|
|
|
+ /* Now we can set "toplevel" to its proper size. */
|
|
XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0);
|
|
|
|
- /* Set the popup to overrideRedirect too */
|
|
+if (fsAlready) {
|
|
+ XtResizeWidget(viewport, viewportWidth, viewportHeight, 0);
|
|
+ if (! toobig) {
|
|
+ XtVaSetValues(viewport, XtNforceBars, False, NULL);
|
|
+ }
|
|
+ XMoveWindow(dpy, XtWindow(viewport), viewportX, viewportY);
|
|
+ XSync(dpy, False);
|
|
+}
|
|
|
|
- XtVaSetValues(popup, XtNoverrideRedirect, True, NULL);
|
|
+ /* Set the popup to overrideRedirect too */
|
|
|
|
/* Try to get the input focus. */
|
|
|
|
+#if 0
|
|
XSetInputFocus(dpy, DefaultRootWindow(dpy), RevertToPointerRoot,
|
|
CurrentTime);
|
|
+#else
|
|
+ XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot,
|
|
+ CurrentTime);
|
|
+#endif
|
|
+
|
|
|
|
/* Optionally, grab the keyboard. */
|
|
|
|
- if (appData.grabKeyboard &&
|
|
- XtGrabKeyboard(desktop, True, GrabModeAsync,
|
|
- GrabModeAsync, CurrentTime) != GrabSuccess) {
|
|
- fprintf(stderr, "XtGrabKeyboard() failed.\n");
|
|
+#define FORCE_UP \
|
|
+ XSync(dpy, False); \
|
|
+ XUnmapWindow(dpy, XtWindow(toplevel)); \
|
|
+ XSync(dpy, False); \
|
|
+ XMapWindow(dpy, XtWindow(toplevel)); \
|
|
+ XRaiseWindow(dpy, XtWindow(toplevel)); \
|
|
+ XSync(dpy, False);
|
|
+
|
|
+ if (appData.grabKeyboard && XtGrabKeyboard(desktop, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) {
|
|
+ fprintf(stderr, "XtGrabKeyboard() failed.\n");
|
|
+ XSync(dpy, False);
|
|
+ usleep(200 * 1000);
|
|
+ FORCE_UP
|
|
+
|
|
+ if (XtGrabKeyboard(desktop, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) {
|
|
+ fprintf(stderr, "XtGrabKeyboard() failed again.\n");
|
|
+ usleep(200 * 1000);
|
|
+ XSync(dpy, True);
|
|
+ if (XtGrabKeyboard(desktop, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) {
|
|
+ fprintf(stderr, "XtGrabKeyboard() failed 3rd time.\n");
|
|
+ } else {
|
|
+ fprintf(stderr, "XtGrabKeyboard() OK 3rd try.\n");
|
|
+ }
|
|
+ } else {
|
|
+ fprintf(stderr, "XtGrabKeyboard() OK 2nd try.\n");
|
|
+ }
|
|
+ XRaiseWindow(dpy, XtWindow(toplevel));
|
|
+ } else if (appData.grabAll) { /* runge bot of FullScreenOn */
|
|
+ fprintf(stderr, "calling XGrabServer(dpy)\n");
|
|
+ XGrabServer(dpy);
|
|
}
|
|
}
|
|
|
|
@@ -210,8 +270,14 @@
|
|
|
|
appData.fullScreen = False;
|
|
|
|
- if (appData.grabKeyboard)
|
|
- XtUngrabKeyboard(desktop, CurrentTime);
|
|
+
|
|
+ if (appData.grabAll) { /* runge top of FullScreenOff */
|
|
+ fprintf(stderr, "calling XUngrabServer(dpy)\n");
|
|
+ XUngrabServer(dpy);
|
|
+ }
|
|
+ if (appData.grabKeyboard) {
|
|
+ XtUngrabKeyboard(desktop, CurrentTime);
|
|
+ }
|
|
|
|
XtUnmapWidget(toplevel);
|
|
|
|
@@ -238,6 +304,9 @@
|
|
XtManageChild(viewport);
|
|
|
|
XtVaSetValues(toplevel, XtNoverrideRedirect, False, NULL);
|
|
+ XtVaSetValues(viewport, XtNoverrideRedirect, False, NULL);
|
|
+ XtVaSetValues(desktop, XtNoverrideRedirect, False, NULL);
|
|
+ XtVaSetValues(popup, XtNoverrideRedirect, False, NULL);
|
|
|
|
if ((toplevelWidth + appData.wmDecorationWidth) >= dpyWidth)
|
|
toplevelWidth = dpyWidth - appData.wmDecorationWidth;
|
|
@@ -345,7 +414,9 @@
|
|
}
|
|
|
|
if (scrollDown) {
|
|
- if (desktopY < si.framebufferHeight - dpyHeight) {
|
|
+ if (appData.yCrop > 0 && desktopY + dpyHeight >= appData.yCrop) {
|
|
+ ;
|
|
+ } else if (desktopY < si.framebufferHeight - dpyHeight) {
|
|
desktopY += appData.bumpScrollPixels;
|
|
if (desktopY > si.framebufferHeight - dpyHeight)
|
|
desktopY = si.framebufferHeight - dpyHeight;
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncviewer/hextile.c
|
|
--- vnc_unixsrc.orig/vncviewer/hextile.c 2007-02-17 22:33:46.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/hextile.c 2007-02-17 22:48:39.000000000 -0500
|
|
@@ -30,6 +30,18 @@
|
|
#define CARDBPP CONCAT2E(CARD,BPP)
|
|
#define GET_PIXEL CONCAT2E(GET_PIXEL,BPP)
|
|
|
|
+#define FillRectangle(x, y, w, h, color) \
|
|
+ { \
|
|
+ XGCValues _gcv; \
|
|
+ _gcv.foreground = color; \
|
|
+ if (!appData.useBackingstore) { \
|
|
+ FillScreen(x, y, w, h, _gcv.foreground); \
|
|
+ } else { \
|
|
+ XChangeGC(dpy, gc, GCForeground, &_gcv); \
|
|
+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \
|
|
+ } \
|
|
+ }
|
|
+
|
|
static Bool
|
|
HandleHextileBPP (int rx, int ry, int rw, int rh)
|
|
{
|
|
@@ -66,14 +78,25 @@
|
|
return False;
|
|
|
|
#if (BPP == 8)
|
|
- if (appData.useBGR233)
|
|
+ if (appData.useBGR233) {
|
|
gcv.foreground = BGR233ToPixel[bg];
|
|
- else
|
|
+ } else
|
|
#endif
|
|
+#if (BPP == 16)
|
|
+ if (appData.useBGR565) {
|
|
+ gcv.foreground = BGR565ToPixel[bg];
|
|
+ } else
|
|
+#endif
|
|
+ {
|
|
gcv.foreground = bg;
|
|
+ }
|
|
|
|
- XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
- XFillRectangle(dpy, desktopWin, gc, x, y, w, h);
|
|
+#if 0
|
|
+ XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h);
|
|
+#else
|
|
+ FillRectangle(x, y, w, h, gcv.foreground);
|
|
+#endif
|
|
|
|
if (subencoding & rfbHextileForegroundSpecified)
|
|
if (!ReadFromRFBServer((char *)&fg, sizeof(fg)))
|
|
@@ -101,14 +124,25 @@
|
|
sh = rfbHextileExtractH(*ptr);
|
|
ptr++;
|
|
#if (BPP == 8)
|
|
- if (appData.useBGR233)
|
|
+ if (appData.useBGR233) {
|
|
gcv.foreground = BGR233ToPixel[fg];
|
|
- else
|
|
+ } else
|
|
+#endif
|
|
+#if (BPP == 16)
|
|
+ if (appData.useBGR565) {
|
|
+ gcv.foreground = BGR565ToPixel[fg];
|
|
+ } else
|
|
#endif
|
|
+ {
|
|
gcv.foreground = fg;
|
|
+ }
|
|
|
|
- XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
- XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh);
|
|
+#if 0
|
|
+ XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
+ XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh);
|
|
+#else
|
|
+ FillRectangle(x+sx, y+sy, sw, sh, gcv.foreground);
|
|
+#endif
|
|
}
|
|
|
|
} else {
|
|
@@ -116,13 +150,22 @@
|
|
return False;
|
|
|
|
#if (BPP == 8)
|
|
- if (appData.useBGR233)
|
|
+ if (appData.useBGR233) {
|
|
gcv.foreground = BGR233ToPixel[fg];
|
|
- else
|
|
+ } else
|
|
#endif
|
|
+#if (BPP == 16)
|
|
+ if (appData.useBGR565) {
|
|
+ gcv.foreground = BGR565ToPixel[fg];
|
|
+ } else
|
|
+#endif
|
|
+ {
|
|
gcv.foreground = fg;
|
|
+ }
|
|
|
|
+#if 0
|
|
XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
+#endif
|
|
|
|
for (i = 0; i < nSubrects; i++) {
|
|
sx = rfbHextileExtractX(*ptr);
|
|
@@ -131,7 +174,11 @@
|
|
sw = rfbHextileExtractW(*ptr);
|
|
sh = rfbHextileExtractH(*ptr);
|
|
ptr++;
|
|
+#if 0
|
|
XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh);
|
|
+#else
|
|
+ FillRectangle(x+sx, y+sy, sw, sh, gcv.foreground);
|
|
+#endif
|
|
}
|
|
}
|
|
}
|
|
@@ -139,3 +186,5 @@
|
|
|
|
return True;
|
|
}
|
|
+
|
|
+#undef FillRectangle
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewer/listen.c
|
|
--- vnc_unixsrc.orig/vncviewer/listen.c 2001-01-16 03:07:57.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/listen.c 2007-03-23 22:30:46.000000000 -0400
|
|
@@ -111,13 +111,14 @@
|
|
getFlashFont(d);
|
|
|
|
listenSocket = ListenAtTcpPort(listenPort);
|
|
- flashSocket = ListenAtTcpPort(flashPort);
|
|
+//flashSocket = ListenAtTcpPort(flashPort);
|
|
+ flashSocket = 1234;
|
|
|
|
if ((listenSocket < 0) || (flashSocket < 0)) exit(1);
|
|
|
|
- fprintf(stderr,"%s -listen: Listening on port %d (flash port %d)\n",
|
|
- programName,listenPort,flashPort);
|
|
- fprintf(stderr,"%s -listen: Command line errors are not reported until "
|
|
+ fprintf(stderr,"%s -listen: Listening on port %d\n",
|
|
+ programName,listenPort);
|
|
+ fprintf(stderr,"%s -listen: Cmdline errors are not reported until "
|
|
"a connection comes in.\n", programName);
|
|
|
|
while (True) {
|
|
@@ -132,12 +133,13 @@
|
|
|
|
FD_ZERO(&fds);
|
|
|
|
- FD_SET(flashSocket, &fds);
|
|
+// FD_SET(flashSocket, &fds);
|
|
FD_SET(listenSocket, &fds);
|
|
FD_SET(ConnectionNumber(d), &fds);
|
|
|
|
select(FD_SETSIZE, &fds, NULL, NULL, NULL);
|
|
|
|
+#if 0
|
|
if (FD_ISSET(flashSocket, &fds)) {
|
|
|
|
sock = AcceptTcpConnection(flashSocket);
|
|
@@ -151,6 +153,7 @@
|
|
}
|
|
close(sock);
|
|
}
|
|
+#endif
|
|
|
|
if (FD_ISSET(listenSocket, &fds)) {
|
|
rfbsock = AcceptTcpConnection(listenSocket);
|
|
@@ -182,6 +185,10 @@
|
|
exit(1);
|
|
}
|
|
getFlashFont(d);
|
|
+ fprintf(stderr,"\n\n%s -listen: Listening on port %d\n",
|
|
+ programName,listenPort);
|
|
+ fprintf(stderr,"%s -listen: Cmdline errors are not reported until "
|
|
+ "a connection comes in.\n\n", programName);
|
|
break;
|
|
}
|
|
}
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer/popup.c
|
|
--- vnc_unixsrc.orig/vncviewer/popup.c 2000-06-11 08:00:53.000000000 -0400
|
|
+++ vnc_unixsrc/vncviewer/popup.c 2007-05-21 02:30:10.000000000 -0400
|
|
@@ -25,15 +25,44 @@
|
|
|
|
#include <X11/Xaw/Form.h>
|
|
#include <X11/Xaw/Command.h>
|
|
+#include <X11/Xaw/AsciiText.h>
|
|
#include <X11/Xaw/Toggle.h>
|
|
|
|
Widget popup, fullScreenToggle;
|
|
|
|
+static void popupFixer(Widget wid) {
|
|
+ Window rr, cr;
|
|
+ unsigned int m;
|
|
+ int x0 = 500, y0 = 500;
|
|
+ int xr, yr, wxr, wyr;
|
|
+ Dimension ph;
|
|
+ if (XQueryPointer(dpy, DefaultRootWindow(dpy), &rr, &cr, &xr, &yr, &wxr, &wyr, &m)) {
|
|
+ x0 = xr;
|
|
+ y0 = yr;
|
|
+ }
|
|
+ XtPopup(wid, XtGrabNone);
|
|
+ XtVaGetValues(wid, XtNheight, &ph, NULL);
|
|
+ if (y0 + (int) ph > dpyHeight) {
|
|
+ y0 = dpyHeight - (int) ph;
|
|
+ if (y0 < 0) {
|
|
+ y0 = 0;
|
|
+ }
|
|
+ }
|
|
+ XtMoveWidget(wid, x0, y0);
|
|
+}
|
|
+
|
|
void
|
|
ShowPopup(Widget w, XEvent *event, String *params, Cardinal *num_params)
|
|
{
|
|
- XtMoveWidget(popup, event->xbutton.x_root, event->xbutton.y_root);
|
|
- XtPopup(popup, XtGrabNone);
|
|
+ if (appData.popupFix) {
|
|
+ popupFixer(popup);
|
|
+ } else {
|
|
+ XtMoveWidget(popup, event->xbutton.x_root, event->xbutton.y_root);
|
|
+ XtPopup(popup, XtGrabNone);
|
|
+ }
|
|
+ if (appData.grabAll) {
|
|
+ XRaiseWindow(dpy, XtWindow(popup));
|
|
+ }
|
|
XSetWMProtocols(dpy, XtWindow(popup), &wmDeleteWindow, 1);
|
|
}
|
|
|
|
@@ -91,3 +120,230 @@
|
|
prevButton = button;
|
|
}
|
|
}
|
|
+
|
|
+
|
|
+Widget scaleN;
|
|
+
|
|
+void
|
|
+ShowScaleN(Widget w, XEvent *event, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.popupFix) {
|
|
+ popupFixer(scaleN);
|
|
+
|
|
+ } else {
|
|
+ XtMoveWidget(scaleN, event->xbutton.x_root, event->xbutton.y_root);
|
|
+ XtPopup(scaleN, XtGrabNone);
|
|
+ }
|
|
+ if (appData.grabAll) {
|
|
+ XRaiseWindow(dpy, XtWindow(scaleN));
|
|
+ }
|
|
+ XSetWMProtocols(dpy, XtWindow(scaleN), &wmDeleteWindow, 1);
|
|
+}
|
|
+
|
|
+void
|
|
+HideScaleN(Widget w, XEvent *event, String *params, Cardinal *num_params)
|
|
+{
|
|
+ XtPopdown(scaleN);
|
|
+}
|
|
+
|
|
+
|
|
+void
|
|
+CreateScaleN()
|
|
+{
|
|
+ Widget buttonForm, button, prevButton = NULL;
|
|
+ int i;
|
|
+ char buttonName[32];
|
|
+ String buttonType;
|
|
+
|
|
+ scaleN = XtVaCreatePopupShell("scaleN", transientShellWidgetClass, toplevel,
|
|
+ NULL);
|
|
+
|
|
+ buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, scaleN,
|
|
+ NULL);
|
|
+
|
|
+ for (i = 0; i <= 6; i++) {
|
|
+ sprintf(buttonName, "button%d", i);
|
|
+ XtVaGetSubresources(buttonForm, (XtPointer)&buttonType, buttonName,
|
|
+ "Button", resources, 1, NULL);
|
|
+
|
|
+ button = XtVaCreateManagedWidget(buttonName, commandWidgetClass,
|
|
+ buttonForm, NULL);
|
|
+ XtVaSetValues(button, XtNfromVert, prevButton,
|
|
+ XtNleft, XawChainLeft, XtNright, XawChainRight, NULL);
|
|
+ prevButton = button;
|
|
+ }
|
|
+}
|
|
+
|
|
+Widget chat, entry, text;
|
|
+
|
|
+static int chat_visible = 0;
|
|
+
|
|
+void
|
|
+ShowChat(Widget w, XEvent *event, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.termChat) {
|
|
+ return;
|
|
+ }
|
|
+ if (! chat_visible) {
|
|
+ XtPopup(chat, XtGrabNone);
|
|
+ chat_visible = 1;
|
|
+ XSetWMProtocols(dpy, XtWindow(chat), &wmDeleteWindow, 1);
|
|
+ XSync(dpy, False);
|
|
+ usleep(200 * 1000);
|
|
+ }
|
|
+}
|
|
+
|
|
+void hidechat(void) {
|
|
+ if (appData.termChat) {
|
|
+ return;
|
|
+ }
|
|
+ if (chat_visible) {
|
|
+ XtPopdown(chat);
|
|
+ chat_visible = 0;
|
|
+ XSync(dpy, False);
|
|
+ usleep(200 * 1000);
|
|
+ }
|
|
+}
|
|
+
|
|
+void HideChat(Widget w, XEvent *event, String *params, Cardinal *num_params) {
|
|
+ SendTextChatClose();
|
|
+ hidechat();
|
|
+}
|
|
+
|
|
+void dismiss_proc(Widget w, XtPointer client_data, XtPointer call_data) {
|
|
+ SendTextChatClose();
|
|
+ hidechat();
|
|
+}
|
|
+
|
|
+extern void printChat(char *, Bool);
|
|
+
|
|
+void CheckTextInput(void) {
|
|
+ Arg args[2];
|
|
+ String str;
|
|
+ int len;
|
|
+
|
|
+ if (appData.termChat) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ XtSetArg(args[0], XtNstring, &str);
|
|
+ XtGetValues(entry, args, 1);
|
|
+ if (str == NULL || str[0] == '\0') {
|
|
+ return;
|
|
+ } else {
|
|
+ len = strlen(str);
|
|
+ if (len <= 0) {
|
|
+ return;
|
|
+ }
|
|
+ if (str[len-1] == '\n') {
|
|
+ char *s = strdup(str);
|
|
+ if (s) {
|
|
+ SendTextChat(s);
|
|
+ printChat("Send: ", True);
|
|
+ printChat(s, True);
|
|
+ XtVaSetValues(entry, XtNtype, XawAsciiString, XtNstring, "", NULL);
|
|
+ free(s);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void AppendChatInput0(char *in) {
|
|
+ Arg args[10];
|
|
+ int n;
|
|
+ String str;
|
|
+ int len;
|
|
+ static char *s = NULL;
|
|
+ static int slen = -1;
|
|
+ XawTextPosition pos;
|
|
+
|
|
+ fprintf(stderr, "AppendChatInput: in= '%s'\n", in);
|
|
+
|
|
+ XtSetArg(args[0], XtNstring, &str);
|
|
+ XtGetValues(text, args, 1);
|
|
+ fprintf(stderr, "AppendChatInput: str='%s'\n", str);
|
|
+
|
|
+ len = strlen(str) + strlen(in);
|
|
+
|
|
+ if (slen <= len) {
|
|
+ slen = 2 * (len + 10);
|
|
+ if (s) free(s);
|
|
+ s = (char *) malloc(slen+1);
|
|
+ }
|
|
+
|
|
+ s[0] = '\0';
|
|
+ strcat(s, str);
|
|
+ strcat(s, in);
|
|
+ fprintf(stderr, "AppendChatInput s= '%s'\n", s);
|
|
+ pos = (XawTextPosition) (len-1);
|
|
+ n = 0;
|
|
+ XtSetArg(args[n], XtNtype, XawAsciiString); n++;
|
|
+ XtSetArg(args[n], XtNstring, s); n++;
|
|
+ XtSetArg(args[n], XtNdisplayPosition, pos); n++;
|
|
+ XtSetArg(args[n], XtNinsertPosition, pos); n++;
|
|
+ XtSetValues(text, args, n);
|
|
+ fprintf(stderr, "AppendChatInput done\n");
|
|
+}
|
|
+
|
|
+void AppendChatInput(char *in) {
|
|
+ int len;
|
|
+ XawTextPosition beg, end;
|
|
+ static XawTextPosition pos = 0;
|
|
+ XawTextBlock txt;
|
|
+
|
|
+ if (appData.termChat) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ XawTextSetInsertionPoint(text, pos);
|
|
+ beg = XawTextGetInsertionPoint(text);
|
|
+ end = beg;
|
|
+ //fprintf(stderr, "AppendChatInput: pos=%d in= '%s'\n", beg, in);
|
|
+
|
|
+ txt.firstPos = 0;
|
|
+ txt.length = strlen(in);
|
|
+ txt.ptr = in;
|
|
+ txt.format = FMT8BIT;
|
|
+
|
|
+ XawTextReplace(text, beg, end, &txt);
|
|
+ XawTextSetInsertionPoint(text, beg + txt.length);
|
|
+
|
|
+ pos = XawTextGetInsertionPoint(text);
|
|
+ //fprintf(stderr, "AppendChatInput done pos=%d\n", pos);
|
|
+}
|
|
+
|
|
+static char errorbuf[1] = {0};
|
|
+
|
|
+void CreateChat(void) {
|
|
+
|
|
+ Widget myform, dismiss;
|
|
+ int i, n;
|
|
+ Dimension w = 400, h = 300;
|
|
+ Dimension x = 33, y = 33;
|
|
+ Arg args[10];
|
|
+
|
|
+ chat = XtVaCreatePopupShell("chat", topLevelShellWidgetClass, toplevel, XtNmappedWhenManaged, False, NULL);
|
|
+
|
|
+ myform = XtVaCreateManagedWidget("myform", formWidgetClass, chat, NULL);
|
|
+
|
|
+ text = XtVaCreateManagedWidget("text", asciiTextWidgetClass, myform,
|
|
+ XtNresize, XawtextResizeBoth, XtNresizable, True, XtNwrap, XawtextWrapWord,
|
|
+ XtNscrollHorizontal, XawtextScrollNever, XtNscrollVertical, XawtextScrollAlways,
|
|
+ XtNwidth, w, XtNheight, h, XtNdisplayCaret, False,
|
|
+ XtNeditType, XawtextAppend, XtNtype, XawAsciiString,
|
|
+ XtNuseStringInPlace, False, NULL);
|
|
+
|
|
+ entry = XtVaCreateManagedWidget("entry", asciiTextWidgetClass, myform,
|
|
+ XtNresize, XawtextResizeWidth, XtNresizable, True, XtNwrap, XawtextWrapWord,
|
|
+ XtNscrollHorizontal, XawtextScrollNever, XtNscrollVertical, XawtextScrollNever,
|
|
+ XtNheight, 20, XtNwidth, 400, XtNfromVert, text,
|
|
+ XtNdisplayCaret, True, XtNeditType, XawtextEdit, NULL);
|
|
+
|
|
+ dismiss = XtVaCreateManagedWidget("dismiss", commandWidgetClass, myform, XtNlabel, "Close Chat", XtNfromVert, entry, NULL);
|
|
+
|
|
+ AppendChatInput("");
|
|
+
|
|
+ XtAddCallback(dismiss, XtNcallback, dismiss_proc, NULL);
|
|
+
|
|
+ XtRealizeWidget(chat);
|
|
+}
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup_ad vnc_unixsrc/vncviewer/popup_ad
|
|
--- vnc_unixsrc.orig/vncviewer/popup_ad 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/popup_ad 2007-02-18 19:52:31.000000000 -0500
|
|
@@ -0,0 +1,19 @@
|
|
+#!/usr/bin/perl
|
|
+
|
|
+$ok = 0;
|
|
+
|
|
+open(A, "<argsresources.c") || die;
|
|
+
|
|
+while (<A>) {
|
|
+ if (/popupButtonCount:/) {
|
|
+ $on = 1;
|
|
+ } elsif (/^\s*NULL/) {
|
|
+ $on = 0;
|
|
+ }
|
|
+ next unless $on;
|
|
+ chomp;
|
|
+ $_ =~ s/^\s*"//;
|
|
+ $_ =~ s/",//;
|
|
+ $_ .= "\n" unless $_ =~ /\n/;
|
|
+ print;
|
|
+}
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncviewer/rfbproto.c
|
|
--- vnc_unixsrc.orig/vncviewer/rfbproto.c 2004-03-11 13:14:39.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/rfbproto.c 2007-05-21 01:56:46.000000000 -0400
|
|
@@ -57,6 +57,25 @@
|
|
static Bool HandleTight16(int rx, int ry, int rw, int rh);
|
|
static Bool HandleTight32(int rx, int ry, int rw, int rh);
|
|
|
|
+/* runge add zrle */
|
|
+static Bool HandleZRLE8(int rx, int ry, int rw, int rh);
|
|
+static Bool HandleZRLE16(int rx, int ry, int rw, int rh);
|
|
+static Bool HandleZRLE24(int rx, int ry, int rw, int rh);
|
|
+static Bool HandleZRLE24Up(int rx, int ry, int rw, int rh);
|
|
+static Bool HandleZRLE24Down(int rx, int ry, int rw, int rh);
|
|
+static Bool HandleZRLE32(int rx, int ry, int rw, int rh);
|
|
+
|
|
+typedef struct {
|
|
+ unsigned long length;
|
|
+} rfbZRLEHeader;
|
|
+
|
|
+long zywrle;
|
|
+
|
|
+#define sz_rfbZRLEHeader 4
|
|
+
|
|
+#define rfbZRLETileWidth 64
|
|
+#define rfbZRLETileHeight 64
|
|
+
|
|
static void ReadConnFailedReason(void);
|
|
static long ReadCompactLen (void);
|
|
|
|
@@ -68,6 +87,9 @@
|
|
int compressedLen);
|
|
|
|
|
|
+int sent_FBU = 0;
|
|
+int skip_XtUpdate = 0;
|
|
+
|
|
int rfbsock;
|
|
char *desktopName;
|
|
rfbPixelFormat myFormat;
|
|
@@ -177,6 +199,9 @@
|
|
sig_rfbEncodingPointerPos, "Pointer position update");
|
|
CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor,
|
|
sig_rfbEncodingLastRect, "LastRect protocol extension");
|
|
+
|
|
+ CapsAdd(encodingCaps, rfbEncodingNewFBSize, rfbTightVncVendor,
|
|
+ sig_rfbEncodingNewFBSize, "New FB size protocol extension");
|
|
}
|
|
|
|
|
|
@@ -187,21 +212,21 @@
|
|
Bool
|
|
ConnectToRFBServer(const char *hostname, int port)
|
|
{
|
|
- unsigned int host;
|
|
+ unsigned int host;
|
|
|
|
- if (!StringToIPAddr(hostname, &host)) {
|
|
- fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname);
|
|
- return False;
|
|
- }
|
|
+ if (!StringToIPAddr(hostname, &host)) {
|
|
+ fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname);
|
|
+ return False;
|
|
+ }
|
|
|
|
- rfbsock = ConnectToTcpAddr(host, port);
|
|
+ rfbsock = ConnectToTcpAddr(host, port);
|
|
|
|
- if (rfbsock < 0) {
|
|
- fprintf(stderr,"Unable to connect to VNC server\n");
|
|
- return False;
|
|
- }
|
|
+ if (rfbsock < 0) {
|
|
+ fprintf(stderr,"Unable to connect to VNC server\n");
|
|
+ return False;
|
|
+ }
|
|
|
|
- return SetNonBlocking(rfbsock);
|
|
+ return SetNonBlocking(rfbsock);
|
|
}
|
|
|
|
|
|
@@ -212,211 +237,228 @@
|
|
Bool
|
|
InitialiseRFBConnection(void)
|
|
{
|
|
- rfbProtocolVersionMsg pv;
|
|
- int server_major, server_minor;
|
|
- int viewer_major, viewer_minor;
|
|
- rfbClientInitMsg ci;
|
|
- int secType;
|
|
+ rfbProtocolVersionMsg pv;
|
|
+ int server_major, server_minor;
|
|
+ int viewer_major, viewer_minor;
|
|
+ rfbClientInitMsg ci;
|
|
+ int secType;
|
|
|
|
- /* if the connection is immediately closed, don't report anything, so
|
|
- that pmw's monitor can make test connections */
|
|
+ /* if the connection is immediately closed, don't report anything, so
|
|
+ that pmw's monitor can make test connections */
|
|
|
|
- if (listenSpecified)
|
|
- errorMessageOnReadFailure = False;
|
|
+ if (listenSpecified) {
|
|
+ errorMessageOnReadFailure = False;
|
|
+ }
|
|
|
|
- if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg))
|
|
- return False;
|
|
+ if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- errorMessageOnReadFailure = True;
|
|
+ errorMessageOnReadFailure = True;
|
|
|
|
- pv[sz_rfbProtocolVersionMsg] = 0;
|
|
+ pv[sz_rfbProtocolVersionMsg] = 0;
|
|
|
|
- if (sscanf(pv, rfbProtocolVersionFormat,
|
|
- &server_major, &server_minor) != 2) {
|
|
- fprintf(stderr,"Not a valid VNC server\n");
|
|
- return False;
|
|
- }
|
|
+ if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) {
|
|
+ fprintf(stderr,"Not a valid VNC server\n");
|
|
+ return False;
|
|
+ }
|
|
|
|
- viewer_major = rfbProtocolMajorVersion;
|
|
- if (server_major == 3 && server_minor >= rfbProtocolMinorVersion) {
|
|
- /* the server supports at least the standard protocol 3.7 */
|
|
- viewer_minor = rfbProtocolMinorVersion;
|
|
- } else {
|
|
- /* any other server version, request the standard 3.3 */
|
|
- viewer_minor = rfbProtocolFallbackMinorVersion;
|
|
- }
|
|
+ viewer_major = rfbProtocolMajorVersion;
|
|
+ if (server_major == 3 && server_minor >= rfbProtocolMinorVersion) {
|
|
+ /* the server supports at least the standard protocol 3.7 */
|
|
+ viewer_minor = rfbProtocolMinorVersion;
|
|
+ } else {
|
|
+ /* any other server version, request the standard 3.3 */
|
|
+ viewer_minor = rfbProtocolFallbackMinorVersion;
|
|
+ }
|
|
|
|
- fprintf(stderr, "Connected to RFB server, using protocol version %d.%d\n",
|
|
- viewer_major, viewer_minor);
|
|
+ fprintf(stderr, "Connected to RFB server, using protocol version %d.%d\n", viewer_major, viewer_minor);
|
|
|
|
- sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor);
|
|
+ sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor);
|
|
|
|
- if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg))
|
|
- return False;
|
|
+ if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- /* Read or select the security type. */
|
|
- if (viewer_minor == rfbProtocolMinorVersion) {
|
|
- secType = SelectSecurityType();
|
|
- } else {
|
|
- secType = ReadSecurityType();
|
|
- }
|
|
- if (secType == rfbSecTypeInvalid)
|
|
- return False;
|
|
+ /* Read or select the security type. */
|
|
+ if (viewer_minor == rfbProtocolMinorVersion) {
|
|
+ secType = SelectSecurityType();
|
|
+ } else {
|
|
+ secType = ReadSecurityType();
|
|
+ }
|
|
+ if (secType == rfbSecTypeInvalid) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- switch (secType) {
|
|
- case rfbSecTypeNone:
|
|
- fprintf(stderr, "No authentication needed\n");
|
|
- break;
|
|
- case rfbSecTypeVncAuth:
|
|
- if (!AuthenticateVNC())
|
|
- return False;
|
|
- break;
|
|
- case rfbSecTypeTight:
|
|
- tightVncProtocol = True;
|
|
- InitCapabilities();
|
|
- if (!SetupTunneling())
|
|
- return False;
|
|
- if (!PerformAuthenticationTight())
|
|
- return False;
|
|
- break;
|
|
- default: /* should never happen */
|
|
- fprintf(stderr, "Internal error: Invalid security type\n");
|
|
- return False;
|
|
- }
|
|
+ switch (secType) {
|
|
+ case rfbSecTypeNone:
|
|
+ fprintf(stderr, "No authentication needed\n");
|
|
+ break;
|
|
+ case rfbSecTypeVncAuth:
|
|
+ if (!AuthenticateVNC()) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case rfbSecTypeTight:
|
|
+ tightVncProtocol = True;
|
|
+ InitCapabilities();
|
|
+ if (!SetupTunneling()) {
|
|
+ return False;
|
|
+ }
|
|
+ if (!PerformAuthenticationTight()) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ default: /* should never happen */
|
|
+ fprintf(stderr, "Internal error: Invalid security type\n");
|
|
+ return False;
|
|
+ }
|
|
|
|
- ci.shared = (appData.shareDesktop ? 1 : 0);
|
|
+ ci.shared = (appData.shareDesktop ? 1 : 0);
|
|
|
|
- if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg))
|
|
- return False;
|
|
+ if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg))
|
|
- return False;
|
|
+ if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
|
|
- si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
|
|
- si.format.redMax = Swap16IfLE(si.format.redMax);
|
|
- si.format.greenMax = Swap16IfLE(si.format.greenMax);
|
|
- si.format.blueMax = Swap16IfLE(si.format.blueMax);
|
|
- si.nameLength = Swap32IfLE(si.nameLength);
|
|
-
|
|
- /* FIXME: Check arguments to malloc() calls. */
|
|
- desktopName = malloc(si.nameLength + 1);
|
|
- if (!desktopName) {
|
|
- fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
|
|
- (unsigned long)si.nameLength);
|
|
- return False;
|
|
- }
|
|
+ si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
|
|
+ si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
|
|
+ si.format.redMax = Swap16IfLE(si.format.redMax);
|
|
+ si.format.greenMax = Swap16IfLE(si.format.greenMax);
|
|
+ si.format.blueMax = Swap16IfLE(si.format.blueMax);
|
|
+ si.nameLength = Swap32IfLE(si.nameLength);
|
|
+
|
|
+ /* FIXME: Check arguments to malloc() calls. */
|
|
+ desktopName = malloc(si.nameLength + 1);
|
|
+ if (!desktopName) {
|
|
+ fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
|
|
+ (unsigned long)si.nameLength);
|
|
+ return False;
|
|
+ }
|
|
|
|
- if (!ReadFromRFBServer(desktopName, si.nameLength)) return False;
|
|
+ if (!ReadFromRFBServer(desktopName, si.nameLength)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- desktopName[si.nameLength] = 0;
|
|
+ desktopName[si.nameLength] = 0;
|
|
|
|
- fprintf(stderr,"Desktop name \"%s\"\n",desktopName);
|
|
+ fprintf(stderr,"Desktop name \"%s\"\n",desktopName);
|
|
|
|
- fprintf(stderr,"VNC server default format:\n");
|
|
- PrintPixelFormat(&si.format);
|
|
+ fprintf(stderr,"VNC server default format:\n");
|
|
+ PrintPixelFormat(&si.format);
|
|
|
|
- if (tightVncProtocol) {
|
|
- /* Read interaction capabilities (protocol 3.7t) */
|
|
- if (!ReadInteractionCaps())
|
|
- return False;
|
|
- }
|
|
+ if (tightVncProtocol) {
|
|
+ /* Read interaction capabilities (protocol 3.7t) */
|
|
+ if (!ReadInteractionCaps()) {
|
|
+ return False;
|
|
+ }
|
|
+ }
|
|
|
|
- return True;
|
|
+ return True;
|
|
}
|
|
|
|
|
|
/*
|
|
- * Read security type from the server (protocol version 3.3)
|
|
+ * Read security type from the server (protocol 3.3)
|
|
*/
|
|
|
|
static int
|
|
ReadSecurityType(void)
|
|
{
|
|
- CARD32 secType;
|
|
+ CARD32 secType;
|
|
|
|
- /* Read the security type */
|
|
- if (!ReadFromRFBServer((char *)&secType, sizeof(secType)))
|
|
- return rfbSecTypeInvalid;
|
|
+ /* Read the security type */
|
|
+ if (!ReadFromRFBServer((char *)&secType, sizeof(secType))) {
|
|
+ return rfbSecTypeInvalid;
|
|
+ }
|
|
|
|
- secType = Swap32IfLE(secType);
|
|
+ secType = Swap32IfLE(secType);
|
|
|
|
- if (secType == rfbSecTypeInvalid) {
|
|
- ReadConnFailedReason();
|
|
- return rfbSecTypeInvalid;
|
|
- }
|
|
+ if (secType == rfbSecTypeInvalid) {
|
|
+ ReadConnFailedReason();
|
|
+ return rfbSecTypeInvalid;
|
|
+ }
|
|
|
|
- if (secType != rfbSecTypeNone && secType != rfbSecTypeVncAuth) {
|
|
- fprintf(stderr, "Unknown security type from RFB server: %d\n",
|
|
- (int)secType);
|
|
- return rfbSecTypeInvalid;
|
|
- }
|
|
+ if (secType != rfbSecTypeNone && secType != rfbSecTypeVncAuth) {
|
|
+ fprintf(stderr, "Unknown security type from RFB server: %d\n",
|
|
+ (int)secType);
|
|
+ return rfbSecTypeInvalid;
|
|
+ }
|
|
|
|
- return (int)secType;
|
|
+ return (int)secType;
|
|
}
|
|
|
|
|
|
/*
|
|
- * Select security type from the server's list (protocol version 3.7)
|
|
+ * Select security type from the server's list (protocol 3.7)
|
|
*/
|
|
|
|
static int
|
|
SelectSecurityType(void)
|
|
{
|
|
- CARD8 nSecTypes;
|
|
- char *secTypeNames[] = {"None", "VncAuth"};
|
|
- CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth};
|
|
- int nKnownSecTypes = sizeof(knownSecTypes);
|
|
- CARD8 *secTypes;
|
|
- CARD8 secType = rfbSecTypeInvalid;
|
|
- int i, j;
|
|
-
|
|
- /* Read the list of secutiry types. */
|
|
- if (!ReadFromRFBServer((char *)&nSecTypes, sizeof(nSecTypes)))
|
|
- return rfbSecTypeInvalid;
|
|
-
|
|
- if (nSecTypes == 0) {
|
|
- ReadConnFailedReason();
|
|
- return rfbSecTypeInvalid;
|
|
- }
|
|
+ CARD8 nSecTypes;
|
|
+ char *secTypeNames[] = {"None", "VncAuth"};
|
|
+ CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth};
|
|
+ int nKnownSecTypes = sizeof(knownSecTypes);
|
|
+ CARD8 *secTypes;
|
|
+ CARD8 secType = rfbSecTypeInvalid;
|
|
+ int i, j;
|
|
+
|
|
+ /* Read the list of secutiry types. */
|
|
+ if (!ReadFromRFBServer((char *)&nSecTypes, sizeof(nSecTypes))) {
|
|
+ return rfbSecTypeInvalid;
|
|
+ }
|
|
|
|
- secTypes = malloc(nSecTypes);
|
|
- if (!ReadFromRFBServer((char *)secTypes, nSecTypes))
|
|
- return rfbSecTypeInvalid;
|
|
-
|
|
- /* Find out if the server supports TightVNC protocol extensions */
|
|
- for (j = 0; j < (int)nSecTypes; j++) {
|
|
- if (secTypes[j] == rfbSecTypeTight) {
|
|
- free(secTypes);
|
|
- secType = rfbSecTypeTight;
|
|
- if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType)))
|
|
- return rfbSecTypeInvalid;
|
|
- fprintf(stderr, "Enabling TightVNC protocol extensions\n");
|
|
- return rfbSecTypeTight;
|
|
- }
|
|
- }
|
|
+ if (nSecTypes == 0) {
|
|
+ ReadConnFailedReason();
|
|
+ return rfbSecTypeInvalid;
|
|
+ }
|
|
|
|
- /* Find first supported security type */
|
|
- for (j = 0; j < (int)nSecTypes; j++) {
|
|
- for (i = 0; i < nKnownSecTypes; i++) {
|
|
- if (secTypes[j] == knownSecTypes[i]) {
|
|
- secType = secTypes[j];
|
|
- if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) {
|
|
- free(secTypes);
|
|
- return rfbSecTypeInvalid;
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
- if (secType != rfbSecTypeInvalid) break;
|
|
- }
|
|
+ secTypes = malloc(nSecTypes);
|
|
+ if (!ReadFromRFBServer((char *)secTypes, nSecTypes)) {
|
|
+ return rfbSecTypeInvalid;
|
|
+ }
|
|
+
|
|
+ /* Find out if the server supports TightVNC protocol extensions */
|
|
+ for (j = 0; j < (int)nSecTypes; j++) {
|
|
+ if (secTypes[j] == rfbSecTypeTight) {
|
|
+ free(secTypes);
|
|
+ secType = rfbSecTypeTight;
|
|
+ if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) {
|
|
+ return rfbSecTypeInvalid;
|
|
+ }
|
|
+ fprintf(stderr, "Enabling TightVNC protocol extensions\n");
|
|
+ return rfbSecTypeTight;
|
|
+ }
|
|
+ }
|
|
|
|
- free(secTypes);
|
|
+ /* Find first supported security type */
|
|
+ for (j = 0; j < (int)nSecTypes; j++) {
|
|
+ for (i = 0; i < nKnownSecTypes; i++) {
|
|
+ if (secTypes[j] == knownSecTypes[i]) {
|
|
+ secType = secTypes[j];
|
|
+ if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) {
|
|
+ free(secTypes);
|
|
+ return rfbSecTypeInvalid;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (secType != rfbSecTypeInvalid) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ free(secTypes);
|
|
|
|
- if (secType == rfbSecTypeInvalid)
|
|
- fprintf(stderr, "Server did not offer supported security type\n");
|
|
+ if (secType == rfbSecTypeInvalid) {
|
|
+ fprintf(stderr, "Server did not offer supported security type\n");
|
|
+ }
|
|
|
|
- return (int)secType;
|
|
+ return (int)secType;
|
|
}
|
|
|
|
|
|
@@ -451,6 +493,9 @@
|
|
return True;
|
|
}
|
|
|
|
+static char *restart_session_pw = NULL;
|
|
+static int restart_session_len = 0;
|
|
+
|
|
|
|
/*
|
|
* Negotiate authentication scheme (protocol version 3.7t)
|
|
@@ -459,56 +504,61 @@
|
|
static Bool
|
|
PerformAuthenticationTight(void)
|
|
{
|
|
- rfbAuthenticationCapsMsg caps;
|
|
- CARD32 authScheme;
|
|
- int i;
|
|
+ rfbAuthenticationCapsMsg caps;
|
|
+ CARD32 authScheme;
|
|
+ int i;
|
|
|
|
- /* In the protocol version 3.7t, the server informs us about supported
|
|
- authentication schemes. Here we read this information. */
|
|
+ /* In the protocol version 3.7t, the server informs us about supported
|
|
+ authentication schemes. Here we read this information. */
|
|
|
|
- if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg))
|
|
- return False;
|
|
+ if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes);
|
|
+ caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes);
|
|
|
|
- if (!caps.nAuthTypes) {
|
|
- fprintf(stderr, "No authentication needed\n");
|
|
- return True;
|
|
- }
|
|
+ if (!caps.nAuthTypes) {
|
|
+ fprintf(stderr, "No authentication needed\n");
|
|
+ return True;
|
|
+ }
|
|
|
|
- if (!ReadCapabilityList(authCaps, caps.nAuthTypes))
|
|
- return False;
|
|
+ if (!ReadCapabilityList(authCaps, caps.nAuthTypes)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- /* Prefer Unix login authentication if a user name was given. */
|
|
- if (appData.userLogin && CapsIsEnabled(authCaps, rfbAuthUnixLogin)) {
|
|
- authScheme = Swap32IfLE(rfbAuthUnixLogin);
|
|
- if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme)))
|
|
- return False;
|
|
- return AuthenticateUnixLogin();
|
|
- }
|
|
+ /* Prefer Unix login authentication if a user name was given. */
|
|
+ if (appData.userLogin && CapsIsEnabled(authCaps, rfbAuthUnixLogin)) {
|
|
+ authScheme = Swap32IfLE(rfbAuthUnixLogin);
|
|
+ if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme))) {
|
|
+ return False;
|
|
+ }
|
|
+ return AuthenticateUnixLogin();
|
|
+ }
|
|
|
|
- /* Otherwise, try server's preferred authentication scheme. */
|
|
- for (i = 0; i < CapsNumEnabled(authCaps); i++) {
|
|
- authScheme = CapsGetByOrder(authCaps, i);
|
|
- if (authScheme != rfbAuthUnixLogin && authScheme != rfbAuthVNC)
|
|
- continue; /* unknown scheme - cannot use it */
|
|
- authScheme = Swap32IfLE(authScheme);
|
|
- if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme)))
|
|
- return False;
|
|
- authScheme = Swap32IfLE(authScheme); /* convert it back */
|
|
- if (authScheme == rfbAuthUnixLogin) {
|
|
- return AuthenticateUnixLogin();
|
|
- } else if (authScheme == rfbAuthVNC) {
|
|
- return AuthenticateVNC();
|
|
- } else {
|
|
- /* Should never happen. */
|
|
- fprintf(stderr, "Assertion failed: unknown authentication scheme\n");
|
|
- return False;
|
|
- }
|
|
- }
|
|
+ /* Otherwise, try server's preferred authentication scheme. */
|
|
+ for (i = 0; i < CapsNumEnabled(authCaps); i++) {
|
|
+ authScheme = CapsGetByOrder(authCaps, i);
|
|
+ if (authScheme != rfbAuthUnixLogin && authScheme != rfbAuthVNC) {
|
|
+ continue; /* unknown scheme - cannot use it */
|
|
+ }
|
|
+ authScheme = Swap32IfLE(authScheme);
|
|
+ if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme))) {
|
|
+ return False;
|
|
+ }
|
|
+ authScheme = Swap32IfLE(authScheme); /* convert it back */
|
|
+ if (authScheme == rfbAuthUnixLogin) {
|
|
+ return AuthenticateUnixLogin();
|
|
+ } else if (authScheme == rfbAuthVNC) {
|
|
+ return AuthenticateVNC();
|
|
+ } else {
|
|
+ /* Should never happen. */
|
|
+ fprintf(stderr, "Assertion failed: unknown authentication scheme\n");
|
|
+ return False;
|
|
+ }
|
|
+ }
|
|
|
|
- fprintf(stderr, "No suitable authentication schemes offered by server\n");
|
|
- return False;
|
|
+ fprintf(stderr, "No suitable authentication schemes offered by server\n");
|
|
+ return False;
|
|
}
|
|
|
|
|
|
@@ -519,80 +569,97 @@
|
|
static Bool
|
|
AuthenticateVNC(void)
|
|
{
|
|
- CARD32 authScheme, authResult;
|
|
- CARD8 challenge[CHALLENGESIZE];
|
|
- char *passwd;
|
|
- char buffer[64];
|
|
- char* cstatus;
|
|
- int len;
|
|
+ CARD32 authScheme, authResult;
|
|
+ CARD8 challenge[CHALLENGESIZE];
|
|
+ char *passwd = NULL;
|
|
+ char buffer[64];
|
|
+ char* cstatus;
|
|
+ int len;
|
|
+ int restart = 0;
|
|
|
|
- fprintf(stderr, "Performing standard VNC authentication\n");
|
|
+ fprintf(stderr, "Performing standard VNC authentication\n");
|
|
|
|
- if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE))
|
|
- return False;
|
|
+ if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- if (appData.passwordFile) {
|
|
- passwd = vncDecryptPasswdFromFile(appData.passwordFile);
|
|
- if (!passwd) {
|
|
- fprintf(stderr, "Cannot read valid password from file \"%s\"\n",
|
|
- appData.passwordFile);
|
|
- return False;
|
|
- }
|
|
- } else if (appData.autoPass) {
|
|
- passwd = buffer;
|
|
- cstatus = fgets(buffer, sizeof buffer, stdin);
|
|
- if (cstatus == NULL)
|
|
- buffer[0] = '\0';
|
|
- else
|
|
- {
|
|
- len = strlen(buffer);
|
|
- if (len > 0 && buffer[len - 1] == '\n')
|
|
- buffer[len - 1] = '\0';
|
|
- }
|
|
- } else if (appData.passwordDialog) {
|
|
- passwd = DoPasswordDialog();
|
|
- } else {
|
|
- passwd = getpass("Password: ");
|
|
- }
|
|
+ if (restart_session_pw != NULL) {
|
|
+ passwd = restart_session_pw;
|
|
+ restart_session_pw = NULL;
|
|
+ restart = 1;
|
|
+ } else if (appData.passwordFile) {
|
|
+ passwd = vncDecryptPasswdFromFile(appData.passwordFile);
|
|
+ if (!passwd) {
|
|
+ fprintf(stderr, "Cannot read valid password from file \"%s\"\n",
|
|
+ appData.passwordFile);
|
|
+ return False;
|
|
+ }
|
|
+ } else if (appData.autoPass) {
|
|
+ passwd = buffer;
|
|
+ cstatus = fgets(buffer, sizeof buffer, stdin);
|
|
+ if (cstatus == NULL) {
|
|
+ buffer[0] = '\0';
|
|
+ } else {
|
|
+ len = strlen(buffer);
|
|
+ if (len > 0 && buffer[len - 1] == '\n') {
|
|
+ buffer[len - 1] = '\0';
|
|
+ }
|
|
+ }
|
|
+ } else if (appData.passwordDialog) {
|
|
+ passwd = DoPasswordDialog();
|
|
+ } else {
|
|
+ passwd = getpass("Password: ");
|
|
+ }
|
|
|
|
- if (!passwd || strlen(passwd) == 0) {
|
|
- fprintf(stderr, "Reading password failed\n");
|
|
- return False;
|
|
- }
|
|
- if (strlen(passwd) > 8) {
|
|
- passwd[8] = '\0';
|
|
- }
|
|
+ if (restart) {
|
|
+#define EN0 0
|
|
+#define DE1 1
|
|
+ unsigned char s_fixedkey[8] = {23,82,107,6,35,78,88,7};
|
|
+ deskey(s_fixedkey, DE1);
|
|
+ des(passwd, passwd);
|
|
+ } else {
|
|
+ if (!passwd || strlen(passwd) == 0) {
|
|
+ fprintf(stderr, "Reading password failed\n");
|
|
+ return False;
|
|
+ }
|
|
+ if (strlen(passwd) > 8) {
|
|
+ passwd[8] = '\0';
|
|
+ }
|
|
+ }
|
|
+ vncEncryptBytes(challenge, passwd);
|
|
+
|
|
|
|
- vncEncryptBytes(challenge, passwd);
|
|
|
|
- /* Lose the password from memory */
|
|
- memset(passwd, '\0', strlen(passwd));
|
|
+// /* Lose the password from memory */
|
|
+// memset(passwd, '\0', strlen(passwd));
|
|
|
|
- if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE))
|
|
- return False;
|
|
+ if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- if (!ReadFromRFBServer((char *)&authResult, 4))
|
|
- return False;
|
|
+ if (!ReadFromRFBServer((char *)&authResult, 4)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- authResult = Swap32IfLE(authResult);
|
|
+ authResult = Swap32IfLE(authResult);
|
|
|
|
- switch (authResult) {
|
|
- case rfbVncAuthOK:
|
|
- fprintf(stderr, "VNC authentication succeeded\n");
|
|
- break;
|
|
- case rfbVncAuthFailed:
|
|
- fprintf(stderr, "VNC authentication failed\n");
|
|
- return False;
|
|
- case rfbVncAuthTooMany:
|
|
- fprintf(stderr, "VNC authentication failed - too many tries\n");
|
|
- return False;
|
|
- default:
|
|
- fprintf(stderr, "Unknown VNC authentication result: %d\n",
|
|
- (int)authResult);
|
|
- return False;
|
|
- }
|
|
+ switch (authResult) {
|
|
+ case rfbVncAuthOK:
|
|
+ fprintf(stderr, "VNC authentication succeeded\n");
|
|
+ break;
|
|
+ case rfbVncAuthFailed:
|
|
+ fprintf(stderr, "VNC authentication failed\n");
|
|
+ return False;
|
|
+ case rfbVncAuthTooMany:
|
|
+ fprintf(stderr, "VNC authentication failed - too many tries\n");
|
|
+ return False;
|
|
+ default:
|
|
+ fprintf(stderr, "Unknown VNC authentication result: %d\n",
|
|
+ (int)authResult);
|
|
+ return False;
|
|
+ }
|
|
|
|
- return True;
|
|
+ return True;
|
|
}
|
|
|
|
/*
|
|
@@ -602,68 +669,71 @@
|
|
static Bool
|
|
AuthenticateUnixLogin(void)
|
|
{
|
|
- CARD32 loginLen, passwdLen, authResult;
|
|
- char *login;
|
|
- char *passwd;
|
|
- struct passwd *ps;
|
|
-
|
|
- fprintf(stderr, "Performing Unix login-style authentication\n");
|
|
-
|
|
- if (appData.userLogin) {
|
|
- login = appData.userLogin;
|
|
- } else {
|
|
- ps = getpwuid(getuid());
|
|
- login = ps->pw_name;
|
|
- }
|
|
+ CARD32 loginLen, passwdLen, authResult;
|
|
+ char *login;
|
|
+ char *passwd;
|
|
+ struct passwd *ps;
|
|
+
|
|
+ fprintf(stderr, "Performing Unix login-style authentication\n");
|
|
+
|
|
+ if (appData.userLogin) {
|
|
+ login = appData.userLogin;
|
|
+ } else {
|
|
+ ps = getpwuid(getuid());
|
|
+ login = ps->pw_name;
|
|
+ }
|
|
|
|
- fprintf(stderr, "Using user name \"%s\"\n", login);
|
|
+ fprintf(stderr, "Using user name \"%s\"\n", login);
|
|
|
|
- if (appData.passwordDialog) {
|
|
- passwd = DoPasswordDialog();
|
|
- } else {
|
|
- passwd = getpass("Password: ");
|
|
- }
|
|
- if (!passwd || strlen(passwd) == 0) {
|
|
- fprintf(stderr, "Reading password failed\n");
|
|
- return False;
|
|
- }
|
|
+ if (appData.passwordDialog) {
|
|
+ passwd = DoPasswordDialog();
|
|
+ } else {
|
|
+ passwd = getpass("Password: ");
|
|
+ }
|
|
+ if (!passwd || strlen(passwd) == 0) {
|
|
+ fprintf(stderr, "Reading password failed\n");
|
|
+ return False;
|
|
+ }
|
|
|
|
- loginLen = Swap32IfLE((CARD32)strlen(login));
|
|
- passwdLen = Swap32IfLE((CARD32)strlen(passwd));
|
|
+ loginLen = Swap32IfLE((CARD32)strlen(login));
|
|
+ passwdLen = Swap32IfLE((CARD32)strlen(passwd));
|
|
|
|
- if (!WriteExact(rfbsock, (char *)&loginLen, sizeof(loginLen)) ||
|
|
- !WriteExact(rfbsock, (char *)&passwdLen, sizeof(passwdLen)))
|
|
- return False;
|
|
+ if (!WriteExact(rfbsock, (char *)&loginLen, sizeof(loginLen)) ||
|
|
+ !WriteExact(rfbsock, (char *)&passwdLen, sizeof(passwdLen))) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- if (!WriteExact(rfbsock, login, strlen(login)) ||
|
|
- !WriteExact(rfbsock, passwd, strlen(passwd)))
|
|
- return False;
|
|
+ if (!WriteExact(rfbsock, login, strlen(login)) ||
|
|
+ !WriteExact(rfbsock, passwd, strlen(passwd))) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- /* Lose the password from memory */
|
|
- memset(passwd, '\0', strlen(passwd));
|
|
+// /* Lose the password from memory */
|
|
+// memset(passwd, '\0', strlen(passwd));
|
|
|
|
- if (!ReadFromRFBServer((char *)&authResult, sizeof(authResult)))
|
|
- return False;
|
|
+ if (!ReadFromRFBServer((char *)&authResult, sizeof(authResult))) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- authResult = Swap32IfLE(authResult);
|
|
+ authResult = Swap32IfLE(authResult);
|
|
|
|
- switch (authResult) {
|
|
- case rfbVncAuthOK:
|
|
- fprintf(stderr, "Authentication succeeded\n");
|
|
- break;
|
|
- case rfbVncAuthFailed:
|
|
- fprintf(stderr, "Authentication failed\n");
|
|
- return False;
|
|
- case rfbVncAuthTooMany:
|
|
- fprintf(stderr, "Authentication failed - too many tries\n");
|
|
- return False;
|
|
- default:
|
|
- fprintf(stderr, "Unknown authentication result: %d\n",
|
|
- (int)authResult);
|
|
- return False;
|
|
- }
|
|
+ switch (authResult) {
|
|
+ case rfbVncAuthOK:
|
|
+ fprintf(stderr, "Authentication succeeded\n");
|
|
+ break;
|
|
+ case rfbVncAuthFailed:
|
|
+ fprintf(stderr, "Authentication failed\n");
|
|
+ return False;
|
|
+ case rfbVncAuthTooMany:
|
|
+ fprintf(stderr, "Authentication failed - too many tries\n");
|
|
+ return False;
|
|
+ default:
|
|
+ fprintf(stderr, "Unknown authentication result: %d\n",
|
|
+ (int)authResult);
|
|
+ return False;
|
|
+ }
|
|
|
|
- return True;
|
|
+ return True;
|
|
}
|
|
|
|
|
|
@@ -675,19 +745,20 @@
|
|
static Bool
|
|
ReadInteractionCaps(void)
|
|
{
|
|
- rfbInteractionCapsMsg intr_caps;
|
|
+ rfbInteractionCapsMsg intr_caps;
|
|
|
|
- /* Read the counts of list items following */
|
|
- if (!ReadFromRFBServer((char *)&intr_caps, sz_rfbInteractionCapsMsg))
|
|
- return False;
|
|
- intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes);
|
|
- intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes);
|
|
- intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes);
|
|
-
|
|
- /* Read the lists of server- and client-initiated messages */
|
|
- return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) &&
|
|
- ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) &&
|
|
- ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes));
|
|
+ /* Read the counts of list items following */
|
|
+ if (!ReadFromRFBServer((char *)&intr_caps, sz_rfbInteractionCapsMsg)) {
|
|
+ return False;
|
|
+ }
|
|
+ intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes);
|
|
+ intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes);
|
|
+ intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes);
|
|
+
|
|
+ /* Read the lists of server- and client-initiated messages */
|
|
+ return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) &&
|
|
+ ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) &&
|
|
+ ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes));
|
|
}
|
|
|
|
|
|
@@ -700,17 +771,18 @@
|
|
static Bool
|
|
ReadCapabilityList(CapsContainer *caps, int count)
|
|
{
|
|
- rfbCapabilityInfo msginfo;
|
|
- int i;
|
|
+ rfbCapabilityInfo msginfo;
|
|
+ int i;
|
|
|
|
- for (i = 0; i < count; i++) {
|
|
- if (!ReadFromRFBServer((char *)&msginfo, sz_rfbCapabilityInfo))
|
|
- return False;
|
|
- msginfo.code = Swap32IfLE(msginfo.code);
|
|
- CapsEnable(caps, &msginfo);
|
|
- }
|
|
+ for (i = 0; i < count; i++) {
|
|
+ if (!ReadFromRFBServer((char *)&msginfo, sz_rfbCapabilityInfo)) {
|
|
+ return False;
|
|
+ }
|
|
+ msginfo.code = Swap32IfLE(msginfo.code);
|
|
+ CapsEnable(caps, &msginfo);
|
|
+ }
|
|
|
|
- return True;
|
|
+ return True;
|
|
}
|
|
|
|
|
|
@@ -729,6 +801,10 @@
|
|
Bool requestCompressLevel = False;
|
|
Bool requestQualityLevel = False;
|
|
Bool requestLastRectEncoding = False;
|
|
+ Bool requestNewFBSizeEncoding = True;
|
|
+ Bool requestTextChatEncoding = True;
|
|
+
|
|
+// fprintf(stderr, "SetFormatAndEncodings: sent_FBU state: %2d\n", sent_FBU);
|
|
|
|
spf.type = rfbSetPixelFormat;
|
|
spf.format = myFormat;
|
|
@@ -736,6 +812,7 @@
|
|
spf.format.greenMax = Swap16IfLE(spf.format.greenMax);
|
|
spf.format.blueMax = Swap16IfLE(spf.format.blueMax);
|
|
|
|
+
|
|
if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg))
|
|
return False;
|
|
|
|
@@ -754,6 +831,12 @@
|
|
encStrLen = strlen(encStr);
|
|
}
|
|
|
|
+if (getenv("DEBUG_SETFORMAT")) {
|
|
+ fprintf(stderr, "encs: ");
|
|
+ write(2, encStr, encStrLen);
|
|
+ fprintf(stderr, "\n");
|
|
+}
|
|
+
|
|
if (strncasecmp(encStr,"raw",encStrLen) == 0) {
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
|
|
} else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
|
|
@@ -775,6 +858,10 @@
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
|
|
} else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);
|
|
+ } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) {
|
|
+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZRLE);
|
|
+ } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) {
|
|
+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZYWRLE);
|
|
} else {
|
|
fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr);
|
|
}
|
|
@@ -797,7 +884,7 @@
|
|
if (appData.useRemoteCursor) {
|
|
if (se->nEncodings < MAX_ENCODINGS)
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
|
|
- if (se->nEncodings < MAX_ENCODINGS)
|
|
+ if (se->nEncodings < MAX_ENCODINGS && !appData.useX11Cursor)
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
|
|
if (se->nEncodings < MAX_ENCODINGS)
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
|
|
@@ -806,10 +893,14 @@
|
|
if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
|
|
}
|
|
+
|
|
+ if (se->nEncodings < MAX_ENCODINGS && requestNewFBSizeEncoding) {
|
|
+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);
|
|
+ }
|
|
}
|
|
else {
|
|
if (SameMachine(rfbsock)) {
|
|
- if (!tunnelSpecified) {
|
|
+ if (!tunnelSpecified && appData.useRawLocal) {
|
|
fprintf(stderr,"Same machine: preferring raw encoding\n");
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
|
|
} else {
|
|
@@ -819,6 +910,7 @@
|
|
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
|
|
+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZRLE);
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
|
|
@@ -844,11 +936,14 @@
|
|
|
|
if (appData.useRemoteCursor) {
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
|
|
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
|
|
+ if (!appData.useX11Cursor) {
|
|
+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
|
|
+ }
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
|
|
}
|
|
|
|
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
|
|
+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);
|
|
}
|
|
|
|
len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
|
|
@@ -868,8 +963,8 @@
|
|
Bool
|
|
SendIncrementalFramebufferUpdateRequest()
|
|
{
|
|
- return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
|
|
- si.framebufferHeight, True);
|
|
+ return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
|
|
+ si.framebufferHeight, True);
|
|
}
|
|
|
|
|
|
@@ -880,19 +975,26 @@
|
|
Bool
|
|
SendFramebufferUpdateRequest(int x, int y, int w, int h, Bool incremental)
|
|
{
|
|
- rfbFramebufferUpdateRequestMsg fur;
|
|
+ rfbFramebufferUpdateRequestMsg fur;
|
|
|
|
- fur.type = rfbFramebufferUpdateRequest;
|
|
- fur.incremental = incremental ? 1 : 0;
|
|
- fur.x = Swap16IfLE(x);
|
|
- fur.y = Swap16IfLE(y);
|
|
- fur.w = Swap16IfLE(w);
|
|
- fur.h = Swap16IfLE(h);
|
|
+ fur.type = rfbFramebufferUpdateRequest;
|
|
+ fur.incremental = incremental ? 1 : 0;
|
|
+ fur.x = Swap16IfLE(x);
|
|
+ fur.y = Swap16IfLE(y);
|
|
+ fur.w = Swap16IfLE(w);
|
|
+ fur.h = Swap16IfLE(h);
|
|
+
|
|
+ if (incremental) {
|
|
+ sent_FBU = 1;
|
|
+ } else {
|
|
+ sent_FBU = 2;
|
|
+ }
|
|
|
|
- if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
|
|
- return False;
|
|
+ if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- return True;
|
|
+ return True;
|
|
}
|
|
|
|
|
|
@@ -903,19 +1005,20 @@
|
|
Bool
|
|
SendPointerEvent(int x, int y, int buttonMask)
|
|
{
|
|
- rfbPointerEventMsg pe;
|
|
+ rfbPointerEventMsg pe;
|
|
|
|
- pe.type = rfbPointerEvent;
|
|
- pe.buttonMask = buttonMask;
|
|
- if (x < 0) x = 0;
|
|
- if (y < 0) y = 0;
|
|
-
|
|
- if (!appData.useX11Cursor)
|
|
- SoftCursorMove(x, y);
|
|
-
|
|
- pe.x = Swap16IfLE(x);
|
|
- pe.y = Swap16IfLE(y);
|
|
- return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg);
|
|
+ pe.type = rfbPointerEvent;
|
|
+ pe.buttonMask = buttonMask;
|
|
+ if (x < 0) x = 0;
|
|
+ if (y < 0) y = 0;
|
|
+
|
|
+ if (!appData.useX11Cursor) {
|
|
+ SoftCursorMove(x, y);
|
|
+ }
|
|
+
|
|
+ pe.x = Swap16IfLE(x);
|
|
+ pe.y = Swap16IfLE(y);
|
|
+ return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg);
|
|
}
|
|
|
|
|
|
@@ -926,12 +1029,12 @@
|
|
Bool
|
|
SendKeyEvent(CARD32 key, Bool down)
|
|
{
|
|
- rfbKeyEventMsg ke;
|
|
+ rfbKeyEventMsg ke;
|
|
|
|
- ke.type = rfbKeyEvent;
|
|
- ke.down = down ? 1 : 0;
|
|
- ke.key = Swap32IfLE(key);
|
|
- return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
|
|
+ ke.type = rfbKeyEvent;
|
|
+ ke.down = down ? 1 : 0;
|
|
+ ke.key = Swap32IfLE(key);
|
|
+ return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
|
|
}
|
|
|
|
|
|
@@ -942,281 +1045,565 @@
|
|
Bool
|
|
SendClientCutText(char *str, int len)
|
|
{
|
|
- rfbClientCutTextMsg cct;
|
|
+ rfbClientCutTextMsg cct;
|
|
+
|
|
+ if (serverCutText) {
|
|
+ free(serverCutText);
|
|
+ }
|
|
+ serverCutText = NULL;
|
|
+
|
|
+ if (appData.viewOnly) {
|
|
+ return True;
|
|
+ }
|
|
|
|
- if (serverCutText)
|
|
- free(serverCutText);
|
|
- serverCutText = NULL;
|
|
-
|
|
- cct.type = rfbClientCutText;
|
|
- cct.length = Swap32IfLE(len);
|
|
- return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) &&
|
|
- WriteExact(rfbsock, str, len));
|
|
+ cct.type = rfbClientCutText;
|
|
+ cct.length = Swap32IfLE(len);
|
|
+ return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) &&
|
|
+ WriteExact(rfbsock, str, len));
|
|
}
|
|
|
|
+Bool
|
|
+SendServerScale(int nfac)
|
|
+{
|
|
+ rfbSetScaleMsg ssc;
|
|
+ if (nfac < 0 || nfac > 100) {
|
|
+ return True;
|
|
+ }
|
|
|
|
-/*
|
|
- * HandleRFBServerMessage.
|
|
- */
|
|
+ ssc.type = rfbSetScale;
|
|
+ ssc.scale = nfac;
|
|
+ return WriteExact(rfbsock, (char *)&ssc, sz_rfbSetScaleMsg);
|
|
+}
|
|
|
|
Bool
|
|
-HandleRFBServerMessage()
|
|
+SendServerInput(Bool enabled)
|
|
{
|
|
- rfbServerToClientMsg msg;
|
|
+ rfbSetServerInputMsg sim;
|
|
|
|
- if (!ReadFromRFBServer((char *)&msg, 1))
|
|
- return False;
|
|
+ sim.type = rfbSetServerInput;
|
|
+ sim.status = enabled;
|
|
+ return WriteExact(rfbsock, (char *)&sim, sz_rfbSetServerInputMsg);
|
|
+}
|
|
|
|
- switch (msg.type) {
|
|
+Bool
|
|
+SendSingleWindow(int x, int y)
|
|
+{
|
|
+ rfbSetSWMsg sw;
|
|
|
|
- case rfbSetColourMapEntries:
|
|
- {
|
|
- int i;
|
|
- CARD16 rgb[3];
|
|
- XColor xc;
|
|
+ fprintf(stderr, "SendSingleWindow: %d %d\n", x, y);
|
|
|
|
- if (!ReadFromRFBServer(((char *)&msg) + 1,
|
|
- sz_rfbSetColourMapEntriesMsg - 1))
|
|
- return False;
|
|
+ if (x == -1 && y == -1) {
|
|
+ sw.type = rfbSetSW;
|
|
+ sw.x = Swap16IfLE(1);
|
|
+ sw.y = Swap16IfLE(1);
|
|
+ } else {
|
|
+ sw.type = rfbSetSW;
|
|
+ sw.x = Swap16IfLE(x);
|
|
+ sw.y = Swap16IfLE(y);
|
|
+ }
|
|
+ sw.status = True;
|
|
+ return WriteExact(rfbsock, (char *)&sw, sz_rfbSetSWMsg);
|
|
+}
|
|
|
|
- msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
|
|
- msg.scme.nColours = Swap16IfLE(msg.scme.nColours);
|
|
+Bool
|
|
+SendTextChat(char *str)
|
|
+{
|
|
+ rfbTextChatMsg chat;
|
|
+ chat.type = rfbTextChat;
|
|
+ chat.pad1 = 0;
|
|
+ chat.pad2 = 0;
|
|
+ chat.length = (unsigned int) strlen(str);
|
|
+ //fprintf(stderr, "SendTextChat: %d '%s'\n", chat.length, str);
|
|
+ chat.length = Swap32IfLE(chat.length);
|
|
+ if (!WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg)) {
|
|
+ return False;
|
|
+ }
|
|
+ return WriteExact(rfbsock, str, strlen(str));
|
|
+}
|
|
|
|
- for (i = 0; i < msg.scme.nColours; i++) {
|
|
- if (!ReadFromRFBServer((char *)rgb, 6))
|
|
- return False;
|
|
- xc.pixel = msg.scme.firstColour + i;
|
|
- xc.red = Swap16IfLE(rgb[0]);
|
|
- xc.green = Swap16IfLE(rgb[1]);
|
|
- xc.blue = Swap16IfLE(rgb[2]);
|
|
- xc.flags = DoRed|DoGreen|DoBlue;
|
|
- XStoreColor(dpy, cmap, &xc);
|
|
- }
|
|
+extern void raiseme(void);
|
|
|
|
- break;
|
|
- }
|
|
+Bool
|
|
+SendTextChatOpen(void)
|
|
+{
|
|
+ raiseme();
|
|
+ rfbTextChatMsg chat;
|
|
+ chat.type = rfbTextChat;
|
|
+ chat.pad1 = 0;
|
|
+ chat.pad2 = 0;
|
|
+ chat.length = Swap32IfLE(rfbTextChatOpen);
|
|
+ return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg);
|
|
+}
|
|
|
|
- case rfbFramebufferUpdate:
|
|
- {
|
|
- rfbFramebufferUpdateRectHeader rect;
|
|
- int linesToRead;
|
|
- int bytesPerLine;
|
|
- int i;
|
|
- int usecs;
|
|
+Bool
|
|
+SendTextChatClose(void)
|
|
+{
|
|
+ rfbTextChatMsg chat;
|
|
+ chat.type = rfbTextChat;
|
|
+ chat.pad1 = 0;
|
|
+ chat.pad2 = 0;
|
|
+ chat.length = Swap32IfLE(rfbTextChatClose);
|
|
+ return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg);
|
|
+}
|
|
|
|
- if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
|
|
- sz_rfbFramebufferUpdateMsg - 1))
|
|
- return False;
|
|
+Bool
|
|
+SendTextChatFinished(void)
|
|
+{
|
|
+ rfbTextChatMsg chat;
|
|
+ chat.type = rfbTextChat;
|
|
+ chat.pad1 = 0;
|
|
+ chat.pad2 = 0;
|
|
+ chat.length = Swap32IfLE(rfbTextChatFinished);
|
|
+ return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg);
|
|
+}
|
|
+
|
|
+extern int do_format_change;
|
|
+extern int do_cursor_change;
|
|
+extern double do_fb_update;
|
|
+extern void cutover_format_change(void);
|
|
+
|
|
+double dtime(double *t_old) {
|
|
+ /*
|
|
+ * usage: call with 0.0 to initialize, subsequent calls give
|
|
+ * the time difference since last call.
|
|
+ */
|
|
+ double t_now, dt;
|
|
+ struct timeval now;
|
|
+
|
|
+ gettimeofday(&now, NULL);
|
|
+ t_now = now.tv_sec + ( (double) now.tv_usec/1000000. );
|
|
+ if (*t_old == 0.0) {
|
|
+ *t_old = t_now;
|
|
+ return t_now;
|
|
+ }
|
|
+ dt = t_now - *t_old;
|
|
+ *t_old = t_now;
|
|
+ return(dt);
|
|
+}
|
|
|
|
- msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
|
|
+/* common dtime() activities: */
|
|
+double dtime0(double *t_old) {
|
|
+ *t_old = 0.0;
|
|
+ return dtime(t_old);
|
|
+}
|
|
|
|
- for (i = 0; i < msg.fu.nRects; i++) {
|
|
- if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
|
|
- return False;
|
|
+double dnow(void) {
|
|
+ double t;
|
|
+ return dtime0(&t);
|
|
+}
|
|
|
|
- rect.encoding = Swap32IfLE(rect.encoding);
|
|
- if (rect.encoding == rfbEncodingLastRect)
|
|
- break;
|
|
|
|
- rect.r.x = Swap16IfLE(rect.r.x);
|
|
- rect.r.y = Swap16IfLE(rect.r.y);
|
|
- rect.r.w = Swap16IfLE(rect.r.w);
|
|
- rect.r.h = Swap16IfLE(rect.r.h);
|
|
-
|
|
- if (rect.encoding == rfbEncodingXCursor ||
|
|
- rect.encoding == rfbEncodingRichCursor) {
|
|
- if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h,
|
|
- rect.encoding)) {
|
|
- return False;
|
|
- }
|
|
- continue;
|
|
- }
|
|
+/*
|
|
+ * HandleRFBServerMessage.
|
|
+ */
|
|
|
|
- if (rect.encoding == rfbEncodingPointerPos) {
|
|
- if (!HandleCursorPos(rect.r.x, rect.r.y)) {
|
|
- return False;
|
|
- }
|
|
- continue;
|
|
- }
|
|
+Bool
|
|
+HandleRFBServerMessage()
|
|
+{
|
|
+ int db = 0;
|
|
+ rfbServerToClientMsg msg;
|
|
|
|
- if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
|
|
- (rect.r.y + rect.r.h > si.framebufferHeight))
|
|
- {
|
|
- fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
|
|
- rect.r.w, rect.r.h, rect.r.x, rect.r.y);
|
|
- return False;
|
|
+ if (!ReadFromRFBServer((char *)&msg, 1)) {
|
|
+ return False;
|
|
}
|
|
|
|
- if (rect.r.h * rect.r.w == 0) {
|
|
- fprintf(stderr,"Zero size rect - ignoring\n");
|
|
- continue;
|
|
- }
|
|
+ switch (msg.type) {
|
|
|
|
- /* If RichCursor encoding is used, we should prevent collisions
|
|
- between framebuffer updates and cursor drawing operations. */
|
|
- SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);
|
|
-
|
|
- switch (rect.encoding) {
|
|
+ case rfbSetColourMapEntries:
|
|
+ {
|
|
+ int i;
|
|
+ CARD16 rgb[3];
|
|
+ XColor xc;
|
|
|
|
- case rfbEncodingRaw:
|
|
+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbSetColourMapEntriesMsg - 1)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
|
|
- linesToRead = BUFFER_SIZE / bytesPerLine;
|
|
+ msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
|
|
+ msg.scme.nColours = Swap16IfLE(msg.scme.nColours);
|
|
|
|
- while (rect.r.h > 0) {
|
|
- if (linesToRead > rect.r.h)
|
|
- linesToRead = rect.r.h;
|
|
+ for (i = 0; i < msg.scme.nColours; i++) {
|
|
+ if (!ReadFromRFBServer((char *)rgb, 6)) {
|
|
+ return False;
|
|
+ }
|
|
+ xc.pixel = msg.scme.firstColour + i;
|
|
+ xc.red = Swap16IfLE(rgb[0]);
|
|
+ xc.green = Swap16IfLE(rgb[1]);
|
|
+ xc.blue = Swap16IfLE(rgb[2]);
|
|
+ if (appData.useGreyScale) {
|
|
+ int ave = (xc.red + xc.green + xc.blue)/3;
|
|
+ xc.red = ave;
|
|
+ xc.green = ave;
|
|
+ xc.blue = ave;
|
|
+ }
|
|
+ xc.flags = DoRed|DoGreen|DoBlue;
|
|
+ XStoreColor(dpy, cmap, &xc);
|
|
+ }
|
|
|
|
- if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
|
|
- return False;
|
|
+ break;
|
|
+ }
|
|
|
|
- CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
|
|
- linesToRead);
|
|
+ case rfbFramebufferUpdate:
|
|
+ {
|
|
+ rfbFramebufferUpdateRectHeader rect;
|
|
+ int linesToRead;
|
|
+ int bytesPerLine;
|
|
+ int i;
|
|
+ int usecs;
|
|
+
|
|
+ int area_copyrect = 0;
|
|
+ int area_tight = 0;
|
|
+ int area_zrle = 0;
|
|
+ int area_raw = 0;
|
|
+ if (db) fprintf(stderr, "FBU-0: %.6f\n", dnow());
|
|
|
|
- rect.r.h -= linesToRead;
|
|
- rect.r.y += linesToRead;
|
|
+ int skip_incFBU = 0;
|
|
+ sent_FBU = -1;
|
|
|
|
+ if (!ReadFromRFBServer(((char *)&msg.fu) + 1, sz_rfbFramebufferUpdateMsg - 1)) {
|
|
+ return False;
|
|
}
|
|
- break;
|
|
|
|
- case rfbEncodingCopyRect:
|
|
- {
|
|
- rfbCopyRect cr;
|
|
-
|
|
- if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
|
|
- return False;
|
|
-
|
|
- cr.srcX = Swap16IfLE(cr.srcX);
|
|
- cr.srcY = Swap16IfLE(cr.srcY);
|
|
-
|
|
- /* If RichCursor encoding is used, we should extend our
|
|
- "cursor lock area" (previously set to destination
|
|
- rectangle) to the source rectangle as well. */
|
|
- SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);
|
|
-
|
|
- if (appData.copyRectDelay != 0) {
|
|
- XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
|
|
- rect.r.w, rect.r.h);
|
|
- XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
|
|
- rect.r.w, rect.r.h);
|
|
- XSync(dpy,False);
|
|
- usleep(appData.copyRectDelay * 1000);
|
|
- XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
|
|
- rect.r.w, rect.r.h);
|
|
- XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
|
|
- rect.r.w, rect.r.h);
|
|
- }
|
|
+ msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
|
|
|
|
- XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY,
|
|
- rect.r.w, rect.r.h, rect.r.x, rect.r.y);
|
|
+ for (i = 0; i < msg.fu.nRects; i++) {
|
|
+ if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) {
|
|
+ return False;
|
|
+ }
|
|
+
|
|
+ rect.encoding = Swap32IfLE(rect.encoding);
|
|
+ if (rect.encoding == rfbEncodingLastRect) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ rect.r.x = Swap16IfLE(rect.r.x);
|
|
+ rect.r.y = Swap16IfLE(rect.r.y);
|
|
+ rect.r.w = Swap16IfLE(rect.r.w);
|
|
+ rect.r.h = Swap16IfLE(rect.r.h);
|
|
+
|
|
+ if (rect.encoding == rfbEncodingXCursor || rect.encoding == rfbEncodingRichCursor) {
|
|
+ if (db) fprintf(stderr, "FBU-Cur1 %.6f\n", dnow());
|
|
+ if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rect.encoding)) {
|
|
+ return False;
|
|
+ }
|
|
+ if (db) fprintf(stderr, "FBU-Cur2 %.6f\n", dnow());
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (rect.encoding == rfbEncodingPointerPos) {
|
|
+ if (db) fprintf(stderr, "FBU-Pos1 %.6f\n", dnow());
|
|
+ if (!HandleCursorPos(rect.r.x, rect.r.y)) {
|
|
+ return False;
|
|
+ }
|
|
+ if (db) fprintf(stderr, "FBU-Pos2 %.6f\n", dnow());
|
|
+ continue;
|
|
+ }
|
|
+ if (rect.encoding == rfbEncodingNewFBSize) {
|
|
+ fprintf(stderr,"New Size: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
|
|
+ si.framebufferWidth = rect.r.w;
|
|
+ si.framebufferHeight = rect.r.h;
|
|
+ //fprintf(stderr, "si: %d %d\n", si.framebufferWidth, si.framebufferHeight);
|
|
+ ReDoDesktop();
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
|
|
+ (rect.r.y + rect.r.h > si.framebufferHeight)) {
|
|
+ fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
|
|
+ rect.r.w, rect.r.h, rect.r.x, rect.r.y);
|
|
+ return False;
|
|
+ }
|
|
+
|
|
+ if (rect.r.h * rect.r.w == 0) {
|
|
+ fprintf(stderr,"Zero size rect - ignoring\n");
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /* If RichCursor encoding is used, we should prevent collisions
|
|
+ between framebuffer updates and cursor drawing operations. */
|
|
+ if (db) fprintf(stderr, "FBU-SCL1 %.6f\n", dnow());
|
|
+
|
|
+ SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);
|
|
+
|
|
+ if (db) fprintf(stderr, "FBU-SCL2 %.6f\n", dnow());
|
|
+
|
|
+ switch (rect.encoding) {
|
|
+
|
|
+ case rfbEncodingRaw:
|
|
+
|
|
+ bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
|
|
+ linesToRead = BUFFER_SIZE / bytesPerLine;
|
|
+
|
|
+ if (db) fprintf(stderr, "Raw: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
|
|
+ area_raw += rect.r.w * rect.r.h;
|
|
+
|
|
+ while (rect.r.h > 0) {
|
|
+ if (linesToRead > rect.r.h) {
|
|
+ linesToRead = rect.r.h;
|
|
+ }
|
|
+
|
|
+ if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead)) {
|
|
+ return False;
|
|
+ }
|
|
+
|
|
+ CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, linesToRead);
|
|
+
|
|
+ rect.r.h -= linesToRead;
|
|
+ rect.r.y += linesToRead;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case rfbEncodingCopyRect:
|
|
+ {
|
|
+ rfbCopyRect cr;
|
|
+
|
|
+ if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect)) {
|
|
+ return False;
|
|
+ }
|
|
+
|
|
+ cr.srcX = Swap16IfLE(cr.srcX);
|
|
+ cr.srcY = Swap16IfLE(cr.srcY);
|
|
+
|
|
+ if (db) fprintf(stderr, "Copy: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
|
|
+ area_copyrect += rect.r.w * rect.r.h;
|
|
+
|
|
+ /* If RichCursor encoding is used, we should extend our
|
|
+ "cursor lock area" (previously set to destination
|
|
+ rectangle) to the source rectangle as well. */
|
|
+
|
|
+ if (db) fprintf(stderr, "FBU-SCL3 %.6f\n", dnow());
|
|
+
|
|
+ SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);
|
|
+
|
|
+ if (db) fprintf(stderr, "FBU-SCL4 %.6f\n", dnow());
|
|
+
|
|
+ if (appData.copyRectDelay != 0) {
|
|
+ XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h);
|
|
+ XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
|
|
+ XSync(dpy,False);
|
|
+ usleep(appData.copyRectDelay * 1000);
|
|
+ XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
|
|
+ XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h);
|
|
+ }
|
|
+
|
|
+ if (db) fprintf(stderr, "FBU-CPA1 %.6f\n", dnow());
|
|
+ if (!appData.useBackingstore) {
|
|
+ copy_rect(rect.r.x, rect.r.y, rect.r.w, rect.r.h, cr.srcX, cr.srcY);
|
|
+ put_image(rect.r.x, rect.r.y, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
|
|
+ XSync(dpy, False);
|
|
+ } else {
|
|
+ XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY,
|
|
+ rect.r.w, rect.r.h, rect.r.x, rect.r.y);
|
|
+ }
|
|
+ if (db) fprintf(stderr, "FBU-CPA2 %.6f\n", dnow());
|
|
+
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case rfbEncodingRRE:
|
|
+ {
|
|
+ switch (myFormat.bitsPerPixel) {
|
|
+ case 8:
|
|
+ if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 16:
|
|
+ if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 32:
|
|
+ if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case rfbEncodingCoRRE:
|
|
+ {
|
|
+ switch (myFormat.bitsPerPixel) {
|
|
+ case 8:
|
|
+ if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 16:
|
|
+ if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 32:
|
|
+ if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case rfbEncodingHextile:
|
|
+ {
|
|
+ switch (myFormat.bitsPerPixel) {
|
|
+ case 8:
|
|
+ if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 16:
|
|
+ if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 32:
|
|
+ if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case rfbEncodingZlib:
|
|
+ {
|
|
+ switch (myFormat.bitsPerPixel) {
|
|
+ case 8:
|
|
+ if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 16:
|
|
+ if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 32:
|
|
+ if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case rfbEncodingTight:
|
|
+ {
|
|
+ if (db) fprintf(stderr, "Tight: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
|
|
+ area_tight += rect.r.w * rect.r.h;
|
|
+ if (db) fprintf(stderr, "FBU-TGH1 %.6f\n", dnow());
|
|
+
|
|
+ switch (myFormat.bitsPerPixel) {
|
|
+ case 8:
|
|
+ if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 16:
|
|
+ if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 32:
|
|
+ if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ if (db) fprintf(stderr, "FBU-TGH2 %.6f\n", dnow());
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* runge adds zrle and zywrle: */
|
|
+ case rfbEncodingZRLE:
|
|
+ {
|
|
+ if (db) fprintf(stderr, "ZRLE: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
|
|
+ area_zrle += rect.r.w * rect.r.h;
|
|
+ switch (myFormat.bitsPerPixel) {
|
|
+ case 8:
|
|
+ if (!HandleZRLE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 16:
|
|
+ if (!HandleZRLE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ case 32:
|
|
+ {
|
|
+ unsigned int maxColor=(myFormat.redMax<<myFormat.redShift)|
|
|
+ (myFormat.greenMax<<myFormat.greenShift)|
|
|
+ (myFormat.blueMax<<myFormat.blueShift);
|
|
+ if ((myFormat.bigEndian && (maxColor&0xff)==0) || (!myFormat.bigEndian && (maxColor&0xff000000)==0)) {
|
|
+ if (!HandleZRLE24(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ } else if (!myFormat.bigEndian && (maxColor&0xff)==0) {
|
|
+ if (!HandleZRLE24Up(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ } else if (myFormat.bigEndian && (maxColor&0xff000000)==0) {
|
|
+ if (!HandleZRLE24Down(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ } else if (!HandleZRLE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
|
|
+ return False;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ default:
|
|
+ fprintf(stderr,"Unknown rect encoding %d\n", (int)rect.encoding);
|
|
+ return False;
|
|
+ }
|
|
|
|
- break;
|
|
- }
|
|
+ /* Now we may discard "soft cursor locks". */
|
|
+ if (db) fprintf(stderr, "FBU-SUL1 %.6f\n", dnow());
|
|
|
|
- case rfbEncodingRRE:
|
|
- {
|
|
- switch (myFormat.bitsPerPixel) {
|
|
- case 8:
|
|
- if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 16:
|
|
- if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 32:
|
|
- if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- }
|
|
- break;
|
|
- }
|
|
+ SoftCursorUnlockScreen();
|
|
|
|
- case rfbEncodingCoRRE:
|
|
- {
|
|
- switch (myFormat.bitsPerPixel) {
|
|
- case 8:
|
|
- if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 16:
|
|
- if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 32:
|
|
- if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
+ if (db) fprintf(stderr, "FBU-SUL2 %.6f\n", dnow());
|
|
}
|
|
- break;
|
|
- }
|
|
|
|
- case rfbEncodingHextile:
|
|
- {
|
|
- switch (myFormat.bitsPerPixel) {
|
|
- case 8:
|
|
- if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 16:
|
|
- if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 32:
|
|
- if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
+ if (1 || area_copyrect) {
|
|
+ if (db) fprintf(stderr, "FBU-XSN1 %.6f\n", dnow());
|
|
+ XSync(dpy, False);
|
|
+ if (db) fprintf(stderr, "FBU-XSN2 %.6f\n", dnow());
|
|
}
|
|
- break;
|
|
- }
|
|
-
|
|
- case rfbEncodingZlib:
|
|
- {
|
|
- switch (myFormat.bitsPerPixel) {
|
|
- case 8:
|
|
- if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 16:
|
|
- if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 32:
|
|
- if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
+ sent_FBU = 0;
|
|
+ /*
|
|
+ * we need to be careful since Xt events are processed
|
|
+ * usually in the middle of FBU. So we do any scheduled ones now
|
|
+ * which is pretty safe but not absolutely safe.
|
|
+ */
|
|
+ if (do_format_change) {
|
|
+ cutover_format_change();
|
|
+ do_format_change = 0;
|
|
+ SetVisualAndCmap();
|
|
+ SetFormatAndEncodings();
|
|
+ if (do_cursor_change) {
|
|
+ if (do_cursor_change == 1) {
|
|
+ DesktopCursorOff();
|
|
+ }
|
|
+ do_cursor_change = 0;
|
|
+ } else {
|
|
+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
|
|
+ si.framebufferHeight, False);
|
|
+ skip_incFBU = 1;
|
|
+ }
|
|
}
|
|
- break;
|
|
- }
|
|
-
|
|
- case rfbEncodingTight:
|
|
- {
|
|
- switch (myFormat.bitsPerPixel) {
|
|
- case 8:
|
|
- if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 16:
|
|
- if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
- case 32:
|
|
- if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
|
|
- return False;
|
|
- break;
|
|
+ if (do_fb_update != 0.0) {
|
|
+ if (dnow() > do_fb_update + 1.1) {
|
|
+ do_fb_update = 0.0;
|
|
+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
|
|
+ si.framebufferHeight, False);
|
|
+ }
|
|
}
|
|
- break;
|
|
- }
|
|
-
|
|
- default:
|
|
- fprintf(stderr,"Unknown rect encoding %d\n",
|
|
- (int)rect.encoding);
|
|
- return False;
|
|
- }
|
|
-
|
|
- /* Now we may discard "soft cursor locks". */
|
|
- SoftCursorUnlockScreen();
|
|
- }
|
|
|
|
#ifdef MITSHM
|
|
/* if using shared memory PutImage, make sure that the X server has
|
|
@@ -1224,59 +1611,142 @@
|
|
mainly to avoid copyrect using invalid screen contents - not sure
|
|
if we'd need it otherwise. */
|
|
|
|
- if (appData.useShm)
|
|
- XSync(dpy, False);
|
|
+ if (appData.useShm) {
|
|
+ XSync(dpy, False);
|
|
+ } else
|
|
#endif
|
|
+ {
|
|
+ XSync(dpy, False);
|
|
+ }
|
|
+
|
|
+ if (skip_XtUpdate || skip_incFBU) {
|
|
+ ;
|
|
+ } else if (!SendIncrementalFramebufferUpdateRequest()) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- if (!SendIncrementalFramebufferUpdateRequest())
|
|
- return False;
|
|
-
|
|
- break;
|
|
+ break;
|
|
}
|
|
|
|
case rfbBell:
|
|
{
|
|
- Window toplevelWin;
|
|
+ Window toplevelWin;
|
|
+
|
|
+ if (appData.useBell) {
|
|
+ XBell(dpy, 0);
|
|
+ }
|
|
|
|
- XBell(dpy, 0);
|
|
+ if (appData.raiseOnBeep) {
|
|
+ toplevelWin = XtWindow(toplevel);
|
|
+ XMapRaised(dpy, toplevelWin);
|
|
+ }
|
|
|
|
- if (appData.raiseOnBeep) {
|
|
- toplevelWin = XtWindow(toplevel);
|
|
- XMapRaised(dpy, toplevelWin);
|
|
+ break;
|
|
}
|
|
|
|
- break;
|
|
- }
|
|
+ case rfbServerCutText:
|
|
+ {
|
|
+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbServerCutTextMsg - 1)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- case rfbServerCutText:
|
|
- {
|
|
- if (!ReadFromRFBServer(((char *)&msg) + 1,
|
|
- sz_rfbServerCutTextMsg - 1))
|
|
- return False;
|
|
+ msg.sct.length = Swap32IfLE(msg.sct.length);
|
|
|
|
- msg.sct.length = Swap32IfLE(msg.sct.length);
|
|
+ if (serverCutText) {
|
|
+ free(serverCutText);
|
|
+ }
|
|
|
|
- if (serverCutText)
|
|
- free(serverCutText);
|
|
+ serverCutText = malloc(msg.sct.length+1);
|
|
|
|
- serverCutText = malloc(msg.sct.length+1);
|
|
+ if (!ReadFromRFBServer(serverCutText, msg.sct.length)) {
|
|
+ return False;
|
|
+ }
|
|
|
|
- if (!ReadFromRFBServer(serverCutText, msg.sct.length))
|
|
- return False;
|
|
+ serverCutText[msg.sct.length] = 0;
|
|
|
|
- serverCutText[msg.sct.length] = 0;
|
|
+ newServerCutText = True;
|
|
|
|
- newServerCutText = True;
|
|
+ break;
|
|
+ }
|
|
|
|
- break;
|
|
- }
|
|
+ case rfbTextChat:
|
|
+ {
|
|
+ char *buffer = NULL;
|
|
+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbTextChatMsg - 1)) {
|
|
+ return False;
|
|
+ }
|
|
+ msg.tc.length = Swap32IfLE(msg.tc.length);
|
|
+ switch(msg.tc.length) {
|
|
+ case rfbTextChatOpen:
|
|
+ if (appData.termChat) {
|
|
+ printChat("\n*ChatOpen*\n\nSend: ", True);
|
|
+ } else {
|
|
+ printChat("\n*ChatOpen*\n", True);
|
|
+ }
|
|
+ appData.chatActive = True;
|
|
+ break;
|
|
+ case rfbTextChatClose:
|
|
+ printChat("\n*ChatClose*\n", False);
|
|
+ appData.chatActive = False;
|
|
+ break;
|
|
+ case rfbTextChatFinished:
|
|
+ printChat("\n*ChatFinished*\n", False);
|
|
+ appData.chatActive = False;
|
|
+ break;
|
|
+ default:
|
|
+ buffer = (char *)malloc(msg.tc.length+1);
|
|
+ if (!ReadFromRFBServer(buffer, msg.tc.length)) {
|
|
+ free(buffer);
|
|
+ return False;
|
|
+ }
|
|
+ buffer[msg.tc.length] = '\0';
|
|
+ appData.chatActive = True;
|
|
+ GotChatText(buffer, msg.tc.length);
|
|
+ free(buffer);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
|
|
- default:
|
|
- fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
|
|
- return False;
|
|
- }
|
|
+ case rfbRestartConnection:
|
|
+ {
|
|
+ rfbRestartConnectionMsg rc;
|
|
+ int len;
|
|
+ char *rs_str;
|
|
+ char buf[5] = "\xff\xff\xff\xff";
|
|
+ fprintf(stderr, "rfbRestartConnection. type=%d\n", (int) rc.type);
|
|
+ if (!ReadFromRFBServer((char *)&rc + 1, sz_rfbRestartConnectionMsg - 1)) {
|
|
+ return False;
|
|
+ }
|
|
+ len = Swap32IfLE(rc.length);
|
|
+ fprintf(stderr, "rfbRestartConnection. pad1=%d\n", (int) rc.pad1);
|
|
+ fprintf(stderr, "rfbRestartConnection. pad2=%d\n", (int) rc.pad2);
|
|
+ fprintf(stderr, "rfbRestartConnection. len=%d\n", len);
|
|
+ if (len) {
|
|
+ rs_str = (char *)malloc(2*len);
|
|
+ if (!ReadFromRFBServer(rs_str, len)) {
|
|
+ return False;
|
|
+ }
|
|
+ restart_session_pw = rs_str;
|
|
+ restart_session_len = len;
|
|
+ }
|
|
+ if (!WriteExact(rfbsock, buf, 4)) {
|
|
+ return False;
|
|
+ }
|
|
+ InitialiseRFBConnection();
|
|
+ SetVisualAndCmap();
|
|
+ SetFormatAndEncodings();
|
|
+ DesktopCursorOff();
|
|
+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False);
|
|
|
|
- return True;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ default:
|
|
+ fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
|
|
+ return False;
|
|
+ }
|
|
+
|
|
+ return True;
|
|
}
|
|
|
|
|
|
@@ -1296,12 +1766,19 @@
|
|
#define CONCAT2(a,b) a##b
|
|
#define CONCAT2E(a,b) CONCAT2(a,b)
|
|
|
|
+#define CONCAT3(a,b,c) a##b##c
|
|
+#define CONCAT3E(a,b,c) CONCAT3(a,b,c)
|
|
+
|
|
+static unsigned char* frameBuffer = NULL;
|
|
+static int frameBufferLen = 0;
|
|
+
|
|
#define BPP 8
|
|
#include "rre.c"
|
|
#include "corre.c"
|
|
#include "hextile.c"
|
|
#include "zlib.c"
|
|
#include "tight.c"
|
|
+#include "zrle.c"
|
|
#undef BPP
|
|
#define BPP 16
|
|
#include "rre.c"
|
|
@@ -1309,6 +1786,7 @@
|
|
#include "hextile.c"
|
|
#include "zlib.c"
|
|
#include "tight.c"
|
|
+#include "zrle.c"
|
|
#undef BPP
|
|
#define BPP 32
|
|
#include "rre.c"
|
|
@@ -1316,6 +1794,15 @@
|
|
#include "hextile.c"
|
|
#include "zlib.c"
|
|
#include "tight.c"
|
|
+#include "zrle.c"
|
|
+#define REALBPP 24
|
|
+#include "zrle.c"
|
|
+#define REALBPP 24
|
|
+#define UNCOMP 8
|
|
+#include "zrle.c"
|
|
+#define REALBPP 24
|
|
+#define UNCOMP -8
|
|
+#include "zrle.c"
|
|
#undef BPP
|
|
|
|
/*
|
|
@@ -1358,9 +1845,9 @@
|
|
" %s significant bit in each byte is leftmost on the screen.\n",
|
|
(format->bigEndian ? "Most" : "Least"));
|
|
} else {
|
|
- fprintf(stderr," %d bits per pixel.\n",format->bitsPerPixel);
|
|
+ fprintf(stderr," %d bits per pixel. ",format->bitsPerPixel);
|
|
if (format->bitsPerPixel != 8) {
|
|
- fprintf(stderr," %s significant byte first in each pixel.\n",
|
|
+ fprintf(stderr,"%s significant byte first in each pixel.\n",
|
|
(format->bigEndian ? "Most" : "Least"));
|
|
}
|
|
if (format->trueColour) {
|
|
@@ -1463,3 +1950,115 @@
|
|
cinfo->src = &jpegSrcManager;
|
|
}
|
|
|
|
+#define DO_ZYWRLE 0
|
|
+#if DO_ZYWRLE
|
|
+
|
|
+#define ZYWRLE_ENDIAN ENDIAN_LITTLE
|
|
+
|
|
+#undef END_FIX
|
|
+#if ZYWRLE_ENDIAN == ENDIAN_LITTLE
|
|
+# define END_FIX LE
|
|
+#elif ZYWRLE_ENDIAN == ENDIAN_BIG
|
|
+# define END_FIX BE
|
|
+#else
|
|
+# define END_FIX NE
|
|
+#endif
|
|
+#define ZYWRLE_DECODE
|
|
+
|
|
+#ifndef __RFB_CONCAT2E
|
|
+#define __RFB_CONCAT2(a,b) a##b
|
|
+#define __RFB_CONCAT2E(a,b) __RFB_CONCAT2(a,b)
|
|
+#endif
|
|
+
|
|
+#ifndef __RFB_CONCAT3E
|
|
+#define __RFB_CONCAT3(a,b,c) a##b##c
|
|
+#define __RFB_CONCAT3E(a,b,c) __RFB_CONCAT3(a,b,c)
|
|
+#endif
|
|
+
|
|
+#undef END_FIX
|
|
+#if ZYWRLE_ENDIAN == ENDIAN_LITTLE
|
|
+# define END_FIX LE
|
|
+#elif ZYWRLE_ENDIAN == ENDIAN_BIG
|
|
+# define END_FIX BE
|
|
+#else
|
|
+# define END_FIX NE
|
|
+#endif
|
|
+
|
|
+#include "zrletypes.h"
|
|
+#include "zrlepalettehelper.h"
|
|
+
|
|
+#if 0
|
|
+typedef unsigned short uint16_t;
|
|
+typedef unsigned int uint32_t;
|
|
+
|
|
+#ifdef CPIXEL
|
|
+#define PIXEL_T __RFB_CONCAT3E(uint,BPP,_t)
|
|
+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,CPIXEL)
|
|
+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,CPIXEL,END_FIX)
|
|
+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,CPIXEL,END_FIX)
|
|
+#define BPPOUT 24
|
|
+#elif BPP==15
|
|
+#define PIXEL_T __RFB_CONCAT3E(uint,16,_t)
|
|
+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,16)
|
|
+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX)
|
|
+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX)
|
|
+#define BPPOUT 16
|
|
+#else
|
|
+#define PIXEL_T __RFB_CONCAT3E(uint,BPP,_t)
|
|
+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,BPP)
|
|
+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX)
|
|
+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX)
|
|
+#define BPPOUT BPP
|
|
+#endif
|
|
+
|
|
+#else
|
|
+
|
|
+#ifdef CPIXEL
|
|
+#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP)
|
|
+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,CPIXEL)
|
|
+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,CPIXEL,END_FIX)
|
|
+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,CPIXEL,END_FIX)
|
|
+#define BPPOUT 24
|
|
+#elif BPP==15
|
|
+#define PIXEL_T __RFB_CONCAT2E(zrle_U,16)
|
|
+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,16)
|
|
+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX)
|
|
+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX)
|
|
+#define BPPOUT 16
|
|
+#else
|
|
+#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP)
|
|
+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,BPP)
|
|
+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX)
|
|
+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX)
|
|
+#define BPPOUT BPP
|
|
+#endif
|
|
+
|
|
+#endif
|
|
+
|
|
+#ifndef ZRLE_ONCE
|
|
+#define ZRLE_ONCE
|
|
+
|
|
+static const int bitsPerPackedPixel[] = {
|
|
+ 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
|
|
+};
|
|
+
|
|
+int zywrle_level;
|
|
+int zywrleBuf[rfbZRLETileWidth*rfbZRLETileHeight];
|
|
+
|
|
+static zrlePaletteHelper paletteHelper;
|
|
+
|
|
+#endif /* ZRLE_ONCE */
|
|
+
|
|
+#if 0
|
|
+void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os);
|
|
+#endif
|
|
+
|
|
+#define BPP 16
|
|
+#include "zywrletemplate.c"
|
|
+#undef BPP
|
|
+#define BPP 32
|
|
+#include "zywrletemplate.c"
|
|
+#undef BPP
|
|
+
|
|
+#endif /* DO_ZYWRLE */
|
|
+
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rre.c vnc_unixsrc/vncviewer/rre.c
|
|
--- vnc_unixsrc.orig/vncviewer/rre.c 2000-06-11 08:00:53.000000000 -0400
|
|
+++ vnc_unixsrc/vncviewer/rre.c 2007-02-17 22:52:24.000000000 -0500
|
|
@@ -29,6 +29,18 @@
|
|
#define HandleRREBPP CONCAT2E(HandleRRE,BPP)
|
|
#define CARDBPP CONCAT2E(CARD,BPP)
|
|
|
|
+#define FillRectangle(x, y, w, h, color) \
|
|
+ { \
|
|
+ XGCValues _gcv; \
|
|
+ _gcv.foreground = color; \
|
|
+ if (!appData.useBackingstore) { \
|
|
+ FillScreen(x, y, w, h, _gcv.foreground); \
|
|
+ } else { \
|
|
+ XChangeGC(dpy, gc, GCForeground, &_gcv); \
|
|
+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \
|
|
+ } \
|
|
+ }
|
|
+
|
|
static Bool
|
|
HandleRREBPP (int rx, int ry, int rw, int rh)
|
|
{
|
|
@@ -49,11 +61,19 @@
|
|
#if (BPP == 8)
|
|
gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
|
|
#else
|
|
+#if (BPP == 16)
|
|
+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix);
|
|
+#else
|
|
gcv.foreground = pix;
|
|
#endif
|
|
+#endif
|
|
|
|
+#if 0
|
|
XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
|
|
+#else
|
|
+ FillRectangle(rx, ry, rw, rh, gcv.foreground);
|
|
+#endif
|
|
|
|
for (i = 0; i < hdr.nSubrects; i++) {
|
|
if (!ReadFromRFBServer((char *)&pix, sizeof(pix)))
|
|
@@ -70,13 +90,23 @@
|
|
#if (BPP == 8)
|
|
gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
|
|
#else
|
|
+#if (BPP == 16)
|
|
+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix);
|
|
+#else
|
|
gcv.foreground = pix;
|
|
#endif
|
|
+#endif
|
|
|
|
+#if 0
|
|
XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
XFillRectangle(dpy, desktopWin, gc, rx + subrect.x, ry + subrect.y,
|
|
subrect.w, subrect.h);
|
|
+#else
|
|
+ FillRectangle(rx + subrect.x, ry + subrect.y, subrect.w, subrect.h, gcv.foreground);
|
|
+#endif
|
|
}
|
|
|
|
return True;
|
|
}
|
|
+
|
|
+#undef FillRectangle
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/shm.c vnc_unixsrc/vncviewer/shm.c
|
|
--- vnc_unixsrc.orig/vncviewer/shm.c 2000-06-11 08:00:53.000000000 -0400
|
|
+++ vnc_unixsrc/vncviewer/shm.c 2007-03-23 22:20:35.000000000 -0400
|
|
@@ -33,68 +33,80 @@
|
|
void
|
|
ShmCleanup()
|
|
{
|
|
- fprintf(stderr,"ShmCleanup called\n");
|
|
- if (needShmCleanup) {
|
|
- shmdt(shminfo.shmaddr);
|
|
- shmctl(shminfo.shmid, IPC_RMID, 0);
|
|
- needShmCleanup = False;
|
|
- }
|
|
+ fprintf(stderr,"ShmCleanup called\n");
|
|
+ if (needShmCleanup) {
|
|
+ shmdt(shminfo.shmaddr);
|
|
+ shmctl(shminfo.shmid, IPC_RMID, 0);
|
|
+ needShmCleanup = False;
|
|
+ }
|
|
+}
|
|
+
|
|
+Bool UsingShm() {
|
|
+ return needShmCleanup;
|
|
}
|
|
|
|
static int
|
|
ShmCreationXErrorHandler(Display *dpy, XErrorEvent *error)
|
|
{
|
|
- caughtShmError = True;
|
|
- return 0;
|
|
+ caughtShmError = True;
|
|
+ return 0;
|
|
}
|
|
|
|
XImage *
|
|
-CreateShmImage()
|
|
+CreateShmImage(int do_ycrop)
|
|
{
|
|
- XImage *image;
|
|
- XErrorHandler oldXErrorHandler;
|
|
-
|
|
- if (!XShmQueryExtension(dpy))
|
|
- return NULL;
|
|
-
|
|
- image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &shminfo,
|
|
- si.framebufferWidth, si.framebufferHeight);
|
|
- if (!image) return NULL;
|
|
-
|
|
- shminfo.shmid = shmget(IPC_PRIVATE,
|
|
- image->bytes_per_line * image->height,
|
|
- IPC_CREAT|0777);
|
|
-
|
|
- if (shminfo.shmid == -1) {
|
|
- XDestroyImage(image);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
|
|
-
|
|
- if (shminfo.shmaddr == (char *)-1) {
|
|
- XDestroyImage(image);
|
|
- shmctl(shminfo.shmid, IPC_RMID, 0);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- shminfo.readOnly = True;
|
|
-
|
|
- oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler);
|
|
- XShmAttach(dpy, &shminfo);
|
|
- XSync(dpy, False);
|
|
- XSetErrorHandler(oldXErrorHandler);
|
|
-
|
|
- if (caughtShmError) {
|
|
- XDestroyImage(image);
|
|
- shmdt(shminfo.shmaddr);
|
|
- shmctl(shminfo.shmid, IPC_RMID, 0);
|
|
- return NULL;
|
|
- }
|
|
+ XImage *image;
|
|
+ XErrorHandler oldXErrorHandler;
|
|
+ int ymax = si.framebufferHeight;
|
|
+
|
|
+ if (!XShmQueryExtension(dpy)) {
|
|
+ return NULL;
|
|
+ }
|
|
+ if (!appData.useShm) {
|
|
+ return NULL;
|
|
+ }
|
|
+ if (do_ycrop) {
|
|
+ ymax = appData.yCrop;
|
|
+ }
|
|
+
|
|
+ image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &shminfo,
|
|
+ si.framebufferWidth, ymax);
|
|
+ if (!image) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT|0777);
|
|
+
|
|
+ if (shminfo.shmid == -1) {
|
|
+ XDestroyImage(image);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
|
|
+
|
|
+ if (shminfo.shmaddr == (char *)-1) {
|
|
+ XDestroyImage(image);
|
|
+ shmctl(shminfo.shmid, IPC_RMID, 0);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ shminfo.readOnly = True;
|
|
+
|
|
+ oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler);
|
|
+ XShmAttach(dpy, &shminfo);
|
|
+ XSync(dpy, False);
|
|
+ XSetErrorHandler(oldXErrorHandler);
|
|
+
|
|
+ if (caughtShmError) {
|
|
+ XDestroyImage(image);
|
|
+ shmdt(shminfo.shmaddr);
|
|
+ shmctl(shminfo.shmid, IPC_RMID, 0);
|
|
+ return NULL;
|
|
+ }
|
|
|
|
- needShmCleanup = True;
|
|
+ needShmCleanup = True;
|
|
|
|
- fprintf(stderr,"Using shared memory PutImage\n");
|
|
+ fprintf(stderr,"Using shared memory (PutImage ycrop=%d)\n", do_ycrop);
|
|
|
|
- return image;
|
|
+ return image;
|
|
}
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/smake vnc_unixsrc/vncviewer/smake
|
|
--- vnc_unixsrc.orig/vncviewer/smake 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/smake 2007-02-19 12:28:05.000000000 -0500
|
|
@@ -0,0 +1,11 @@
|
|
+#!/bin/sh
|
|
+
|
|
+PATH=`pwd`/../..:/usr/sfw/bin:/usr/ccs/bin:$PATH
|
|
+export PATH
|
|
+if [ "X$1" != "X" ]; then
|
|
+ "$@"
|
|
+else
|
|
+ make
|
|
+ strip vncviewer
|
|
+ ls -l vncviewer
|
|
+fi
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncviewer/sockets.c
|
|
--- vnc_unixsrc.orig/vncviewer/sockets.c 2001-01-14 22:54:18.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/sockets.c 2007-05-20 21:24:33.000000000 -0400
|
|
@@ -63,15 +63,64 @@
|
|
XtRemoveInput(*id);
|
|
}
|
|
|
|
+extern int skip_XtUpdate;
|
|
+extern void CheckTextInput(void);
|
|
+
|
|
static void
|
|
ProcessXtEvents()
|
|
{
|
|
- rfbsockReady = False;
|
|
- XtAppAddInput(appContext, rfbsock, (XtPointer)XtInputReadMask,
|
|
- rfbsockReadyCallback, NULL);
|
|
- while (!rfbsockReady) {
|
|
- XtAppProcessEvent(appContext, XtIMAll);
|
|
- }
|
|
+ if (appData.chatActive) {
|
|
+ fd_set fds;
|
|
+ struct timeval tv;
|
|
+ int i, igot = -1, n = fileno(stdin);
|
|
+ char strs[100][512];
|
|
+ char buf[rfbTextMaxSize];
|
|
+
|
|
+ if (appData.termChat) {
|
|
+ for (i=0; i < 100; i++) {
|
|
+ FD_ZERO(&fds);
|
|
+ FD_SET(n,&fds);
|
|
+ tv.tv_sec = 0;
|
|
+ tv.tv_usec = 0;
|
|
+ if (select(n+1, &fds, NULL, NULL, &tv) > 0) {
|
|
+ if (FD_ISSET(n, &fds)) {
|
|
+ fgets(strs[i], 512, stdin);
|
|
+ igot = i;
|
|
+ } else {
|
|
+ break;
|
|
+ }
|
|
+ } else {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ buf[0] = '\0';
|
|
+ for (i=0; i <= igot; i++) {
|
|
+ if (strlen(buf) + strlen(strs[i]) < rfbTextMaxSize) {
|
|
+ strcat(buf, strs[i]);
|
|
+ } else {
|
|
+ SendTextChat(buf);
|
|
+ buf[0] = '0';
|
|
+ }
|
|
+ }
|
|
+ if (buf[0] != '\0') {
|
|
+ SendTextChat(buf);
|
|
+ }
|
|
+ if (igot >= 0) printChat("Send: ");
|
|
+ } else {
|
|
+ CheckTextInput();
|
|
+ }
|
|
+ }
|
|
+ if (skip_XtUpdate) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ rfbsockReady = False;
|
|
+ XtAppAddInput(appContext, rfbsock, (XtPointer)XtInputReadMask,
|
|
+ rfbsockReadyCallback, NULL);
|
|
+
|
|
+ while (!rfbsockReady) {
|
|
+ XtAppProcessEvent(appContext, XtIMAll);
|
|
+ }
|
|
}
|
|
|
|
Bool
|
|
@@ -283,6 +332,10 @@
|
|
addr.sin_port = htons(port);
|
|
addr.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
+ if (getenv("VNCVIEWER_LISTEN_LOCALHOST")) {
|
|
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
+ }
|
|
+
|
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (sock < 0) {
|
|
fprintf(stderr,programName);
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tight.c vnc_unixsrc/vncviewer/tight.c
|
|
--- vnc_unixsrc.orig/vncviewer/tight.c 2002-04-30 09:07:31.000000000 -0400
|
|
+++ vnc_unixsrc/vncviewer/tight.c 2007-02-17 22:08:20.000000000 -0500
|
|
@@ -129,14 +129,21 @@
|
|
#endif
|
|
|
|
#if (BPP == 8)
|
|
- gcv.foreground = (appData.useBGR233) ?
|
|
- BGR233ToPixel[fill_colour] : fill_colour;
|
|
+ gcv.foreground = (appData.useBGR233) ? BGR233ToPixel[fill_colour] : fill_colour;
|
|
+#else
|
|
+#if (BPP == 16)
|
|
+ gcv.foreground = (appData.useBGR565) ? BGR565ToPixel[fill_colour] : fill_colour;
|
|
#else
|
|
gcv.foreground = fill_colour;
|
|
#endif
|
|
+#endif
|
|
|
|
- XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
- XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
|
|
+ if (!appData.useBackingstore) {
|
|
+ FillScreen(rx, ry, rw, rh, gcv.foreground);
|
|
+ } else {
|
|
+ XChangeGC(dpy, gc, GCForeground, &gcv);
|
|
+ XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
|
|
+ }
|
|
return True;
|
|
}
|
|
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tunnel.c vnc_unixsrc/vncviewer/tunnel.c
|
|
--- vnc_unixsrc.orig/vncviewer/tunnel.c 2003-07-31 04:03:49.000000000 -0400
|
|
+++ vnc_unixsrc/vncviewer/tunnel.c 2007-05-08 21:28:01.000000000 -0400
|
|
@@ -132,6 +132,7 @@
|
|
{
|
|
char *colonPos;
|
|
int len, portOffset;
|
|
+ int disp;
|
|
|
|
if (tunnelArgIndex >= *pargc - 2)
|
|
usage();
|
|
@@ -153,7 +154,14 @@
|
|
if (!len || strspn(colonPos, "-0123456789") != len) {
|
|
usage();
|
|
}
|
|
+#if 0
|
|
*remotePort = atoi(colonPos) + portOffset;
|
|
+#else
|
|
+ disp = atoi(colonPos);
|
|
+ if (portOffset != 0 && disp >= 100)
|
|
+ portOffset = 0;
|
|
+ *remotePort = disp + portOffset;
|
|
+#endif
|
|
}
|
|
|
|
sprintf(lastArgv, "localhost::%d", localPort);
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vncviewer/vncviewer._man
|
|
--- vnc_unixsrc.orig/vncviewer/vncviewer._man 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/vncviewer._man 2007-05-21 11:29:52.000000000 -0400
|
|
@@ -0,0 +1,506 @@
|
|
+'\" t
|
|
+.\" ** The above line should force tbl to be a preprocessor **
|
|
+.\" Man page for X vncviewer
|
|
+.\"
|
|
+.\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de
|
|
+.\" Copyright (C) 2000,2001 Red Hat, Inc.
|
|
+.\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru>
|
|
+.\"
|
|
+.\" You may distribute under the terms of the GNU General Public
|
|
+.\" License as specified in the file LICENCE.TXT that comes with the
|
|
+.\" TightVNC distribution.
|
|
+.\"
|
|
+.TH vncviewer 1 "January 2003" "" "TightVNC"
|
|
+.SH NAME
|
|
+vncviewer \- an X viewer client for VNC
|
|
+.SH SYNOPSIS
|
|
+.B vncviewer
|
|
+.RI [\| options \|]
|
|
+.RI [\| host \|][\| :display \|]
|
|
+.br
|
|
+.B vncviewer
|
|
+.RI [\| options \|]
|
|
+.RI [\| host \|][\| ::port \|]
|
|
+.br
|
|
+.B vncviewer
|
|
+.RI [\| options \|]
|
|
+.IR \-listen
|
|
+.RI [\| display \|]
|
|
+.br
|
|
+.B vncviewer
|
|
+.IR \-help
|
|
+.br
|
|
+.SH DESCRIPTION
|
|
+.B vncviewer
|
|
+is an Xt\-based client application for the VNC (Virtual Network
|
|
+Computing) system. It can connect to any VNC\-compatible server such
|
|
+as \fBXvnc\fR or WinVNC, allowing you to control desktop environment
|
|
+of a different machine.
|
|
+
|
|
+You can use F8 to display a pop\-up utility menu. Press F8 twice to
|
|
+pass single F8 to the remote side.
|
|
+.SH OPTIONS
|
|
+.TP
|
|
+\fB\-help\fR
|
|
+Prints a short usage notice to stderr.
|
|
+.TP
|
|
+\fB\-listen\fR
|
|
+Make the viewer listen on port 5500+\fIdisplay\fR for reverse
|
|
+connections from a server. WinVNC supports reverse connections using
|
|
+the "Add New Client" menu option, or the \-connect command line
|
|
+option. \fBXvnc\fR requires the use of the helper program
|
|
+\fBvncconnect\fR.
|
|
+.TP
|
|
+\fB\-via\fR \fIgateway\fR
|
|
+Automatically create encrypted TCP tunnel to the \fIgateway\fR machine
|
|
+before connection, connect to the \fIhost\fR through that tunnel
|
|
+(TightVNC\-specific). By default, this option invokes SSH local port
|
|
+forwarding, assuming that SSH client binary can be accessed as
|
|
+/usr/bin/ssh. Note that when using the \fB\-via\fR option, the host
|
|
+machine name should be specified as known to the gateway machine, e.g.
|
|
+"localhost" denotes the \fIgateway\fR, not the machine where vncviewer
|
|
+was launched. See the ENVIRONMENT section below for the information on
|
|
+configuring the \fB\-via\fR option.
|
|
+.TP
|
|
+\fB\-shared\fR
|
|
+When connecting, specify that a shared connection is requested. In
|
|
+TightVNC, this is the default mode, allowing you to share the desktop
|
|
+with other clients already using it.
|
|
+.TP
|
|
+\fB\-noshared\fR
|
|
+When connecting, specify that the session may not be shared. This
|
|
+would either disconnect other connected clients or refuse your
|
|
+connection, depending on the server configuration.
|
|
+.TP
|
|
+\fB\-viewonly\fR
|
|
+Disable transfer of mouse and keyboard events from the client to the
|
|
+server.
|
|
+.TP
|
|
+\fB\-fullscreen\fR
|
|
+Start in full\-screen mode. Please be aware that operating in
|
|
+full\-screen mode may confuse X window managers. Typically, such
|
|
+conflicts cause incorrect handling of input focus or make the viewer
|
|
+window disappear mysteriously. See the grabKeyboard setting in the
|
|
+RESOURCES section below for a method to solve input focus problem.
|
|
+.TP
|
|
+\fB\-noraiseonbeep\fR
|
|
+By default, the viewer shows and raises its window on remote beep
|
|
+(bell) event. This option disables such behaviour
|
|
+(TightVNC\-specific).
|
|
+.TP
|
|
+\fB\-user\fR \fIusername\fR
|
|
+User name for Unix login authentication. Default is to use current
|
|
+Unix user name. If this option was given, the viewer will prefer Unix
|
|
+login authentication over the standard VNC authentication.
|
|
+.TP
|
|
+\fB\-passwd\fR \fIpasswd\-file\fR
|
|
+File from which to get the password (as generated by the
|
|
+\fBvncpasswd\fR(1) program). This option affects only the standard VNC
|
|
+authentication.
|
|
+.TP
|
|
+\fB\-encodings\fR \fIencoding\-list\fR
|
|
+TightVNC supports several different compression methods to encode
|
|
+screen updates; this option specifies a set of them to use in order of
|
|
+preference. Encodings are specified separated with spaces, and must
|
|
+thus be enclosed in quotes if more than one is specified. Available
|
|
+encodings, in default order for a remote connection, are "copyrect
|
|
+tight hextile zlib corre rre raw". For a local connection (to the same
|
|
+machine), the default order to try is "raw copyrect tight hextile zlib
|
|
+corre rre". Raw encoding is always assumed as a last option if no
|
|
+other encoding can be used for some reason. For more information on
|
|
+encodings, see the section ENCODINGS below.
|
|
+.TP
|
|
+\fB\-bgr233\fR
|
|
+Always use the BGR233 format to encode pixel data. This reduces
|
|
+network traffic, but colors may be represented inaccurately. The
|
|
+bgr233 format is an 8\-bit "true color" format, with 2 bits blue, 3
|
|
+bits green, and 3 bits red.
|
|
+.TP
|
|
+\fB\-owncmap\fR
|
|
+Try to use a PseudoColor visual and a private colormap. This allows
|
|
+the VNC server to control the colormap.
|
|
+.TP
|
|
+\fB\-truecolour\fR, \fB\-truecolor\fR
|
|
+Try to use a TrueColor visual.
|
|
+.TP
|
|
+\fB\-depth\fR \fIdepth\fR
|
|
+On an X server which supports multiple TrueColor visuals of different
|
|
+depths, attempt to use the specified one (in bits per pixel); if
|
|
+successful, this depth will be requested from the VNC server.
|
|
+.TP
|
|
+\fB\-compresslevel \fIlevel\fR
|
|
+Use specified compression \fIlevel\fR (0..9) for "tight" and "zlib"
|
|
+encodings (TightVNC\-specific). Level 1 uses minimum of CPU time and
|
|
+achieves weak compression ratios, while level 9 offers best
|
|
+compression but is slow in terms of CPU time consumption on the server
|
|
+side. Use high levels with very slow network connections, and low
|
|
+levels when working over high\-speed LANs. It's not recommended to use
|
|
+compression level 0, reasonable choices start from the level 1.
|
|
+.TP
|
|
+\fB\-quality \fIlevel\fR
|
|
+Use the specified JPEG quality \fIlevel\fR (0..9) for the "tight"
|
|
+encoding (TightVNC\-specific). Quality level 0 denotes bad image
|
|
+quality but very impressive compression ratios, while level 9 offers
|
|
+very good image quality at lower compression ratios. Note that the
|
|
+"tight" encoder uses JPEG to encode only those screen areas that look
|
|
+suitable for lossy compression, so quality level 0 does not always
|
|
+mean unacceptable image quality.
|
|
+.TP
|
|
+\fB\-nojpeg\fR
|
|
+Disable lossy JPEG compression in Tight encoding (TightVNC\-specific).
|
|
+Disabling JPEG compression is not a good idea in typical cases, as
|
|
+that makes the Tight encoder less efficient. You might want to use
|
|
+this option if it's absolutely necessary to achieve perfect image
|
|
+quality (see also the \fB\-quality\fR option).
|
|
+.TP
|
|
+\fB\-nocursorshape\fR
|
|
+Disable cursor shape updates, protocol extensions used to handle
|
|
+remote cursor movements locally on the client side
|
|
+(TightVNC\-specific). Using cursor shape updates decreases delays with
|
|
+remote cursor movements, and can improve bandwidth usage dramatically.
|
|
+.TP
|
|
+\fB\-x11cursor\fR
|
|
+Use a real X11 cursor with X-style cursor shape updates, instead of
|
|
+drawing the remote cursor on the framebuffer. This option also
|
|
+disables the dot cursor, and disables cursor position updates in
|
|
+non-fullscreen mode.
|
|
+.TP
|
|
+\fB\-autopass\fR
|
|
+Read a plain-text password from stdin. This option affects only the
|
|
+standard VNC authentication.
|
|
+
|
|
+.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS
|
|
+.TP
|
|
+Enhanced TightVNC Viewer (SSVNC) web page is located at:
|
|
+.TP
|
|
+http://www.karlrunge.com/x11vnc/ssvnc.html
|
|
+.TP
|
|
+Note: ZRLE encoding is now supported.
|
|
+.TP
|
|
+Note: F9 is shortcut to Toggle FullScreen mode.
|
|
+.TP
|
|
+\fB\-use64\fR
|
|
+In \fB\-bgr233\fR mode, use 64 colors instead of 256.
|
|
+.TP
|
|
+\fB\-bgr222\fR
|
|
+Same as \fB\-use64\fR.
|
|
+.TP
|
|
+\fB\-use8\fR
|
|
+In \fB\-bgr233\fR mode, use 8 colors instead of 256.
|
|
+.TP
|
|
+\fB\-bgr111\fR
|
|
+Same as \fB\-use8\fR.
|
|
+.TP
|
|
+\fB\-16bpp\fR
|
|
+If the vnc viewer X display is depth 24 at 32bpp
|
|
+request a 16bpp format from the VNC server to cut
|
|
+network traffic by up to 2X, then tranlate the
|
|
+pixels to 32bpp locally.
|
|
+.TP
|
|
+\fB\-bgr565\fR
|
|
+Same as \fB\-16bpp\fR.
|
|
+.TP
|
|
+\fB\-grey\fR
|
|
+Use a grey scale for the 16- and 8\fB\-bpp\fR modes.
|
|
+.TP
|
|
+\fB\-alpha\fR
|
|
+Use alphablending transparency for local cursors
|
|
+requires: x11vnc server, both client and server
|
|
+must be 32bpp and same endianness.
|
|
+.TP
|
|
+\fB\-ycrop\fR n
|
|
+Only show the top n rows of the framebuffer. For
|
|
+use with x11vnc \fB\-ncache\fR client caching option
|
|
+to help "hide" the pixel cache region.
|
|
+Use a negative value (e.g. \fB\-1\fR) for autodetection.
|
|
+Autodetection will always take place if the remote
|
|
+fb height is more than 2 times the width.
|
|
+.TP
|
|
+\fB\-sbwidth\fR n
|
|
+Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR),
|
|
+default is very narrow: 2 pixels, it is narrow to
|
|
+avoid distraction in \fB\-ycrop\fR mode.
|
|
+.TP
|
|
+\fB\-nobell\fR
|
|
+Disable bell.
|
|
+.TP
|
|
+\fB\-rawlocal\fR
|
|
+Prefer raw encoding for localhost, default is
|
|
+no, i.e. assumes you have a SSH tunnel instead.
|
|
+.TP
|
|
+\fB\-graball\fR
|
|
+Grab the entire X server when in fullscreen mode,
|
|
+needed by some old window managers like fvwm2.
|
|
+.TP
|
|
+\fB\-popupfix\fR
|
|
+Warp the popup back to the pointer position,
|
|
+needed by some old window managers like fvwm2.
|
|
+.TP
|
|
+\fB\-grabkbd\fR
|
|
+Grab the X keyboard when in fullscreen mode,
|
|
+needed by some window managers. Same as \fB\-grabkeyboard\fR.
|
|
+\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable.
|
|
+.TP
|
|
+\fB\-bs\fR, \fB\-nobs\fR
|
|
+Whether or not to use X server Backingstore for the
|
|
+main viewer window. The default is to not, mainly
|
|
+because most Linux, etc, systems X servers disable
|
|
+*all* Backingstore by default. To re\fB\-enable\fR it put
|
|
+Option "Backingstore"
|
|
+in the Device section of /etc/X11/xorg.conf.
|
|
+In \fB\-bs\fR mode with no X server backingstore, whenever an
|
|
+area of the screen is re\fB\-exposed\fR it must go out to the
|
|
+VNC server to retrieve the pixels. This is too slow.
|
|
+In \fB\-nobs\fR mode, memory is allocated by the viewer to
|
|
+provide its own backing of the main viewer window. This
|
|
+actually makes some activities faster (changes in large
|
|
+regions) but can appear to "flash" too much.
|
|
+.TP
|
|
+\fB\-noshm\fR
|
|
+Disable use of MIT shared memory extension (not recommended)
|
|
+.TP
|
|
+\fB\-termchat\fR
|
|
+Do the UltraVNC chat in the terminal vncviewer is in
|
|
+instead of in an independent window.
|
|
+.TP
|
|
+\fB New Popup actions:\fR
|
|
+
|
|
+ ViewOnly: ~ -viewonly
|
|
+ Disable Bell: ~ -nobell
|
|
+ Cursor Shape: ~ -nocursorshape
|
|
+ X11 Cursor: ~ -x11cursor
|
|
+ Cursor Alphablend: ~ -alpha
|
|
+ Toggle Tight/ZRLE: ~ -encodings ...
|
|
+ Disable JPEG: ~ -nojpeg
|
|
+ Full Color as many colors as local screen allows.
|
|
+ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.
|
|
+ 16 bit color (BGR565) ~ -16bpp / -bgr565
|
|
+ 8 bit color (BGR233) ~ -bgr233
|
|
+ 256 colors ~ -bgr233 default # of colors.
|
|
+ 64 colors ~ -bgr222 / -use64
|
|
+ 8 colors ~ -bgr111 / -use8
|
|
+
|
|
+ UltraVNC Extensions:
|
|
+ Disable Remote Input Ultravnc ext. Try to prevent input and
|
|
+ viewing of monitor at physical display.
|
|
+ Single Window Ultravnc ext. Grab and view a single window.
|
|
+ (click on the window you want).
|
|
+ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.
|
|
+ prompt is from the terminal.
|
|
+ Text Chat Ultravnc ext. Do Text Chat.
|
|
+
|
|
+ Note: the Ultravnc extensions only apply to servers that support
|
|
+ them. x11vnc/libvncserver supports some of them.
|
|
+
|
|
+.SH ENCODINGS
|
|
+The server supplies information in whatever format is desired by the
|
|
+client, in order to make the client as easy as possible to implement.
|
|
+If the client represents itself as able to use multiple formats, the
|
|
+server will choose one.
|
|
+
|
|
+.I Pixel format
|
|
+refers to the representation of an individual pixel. The most common
|
|
+formats are 24 and 16 bit "true\-color" values, and 8\-bit "color map"
|
|
+representations, where an arbitrary map converts the color number to
|
|
+RGB values.
|
|
+
|
|
+.I Encoding
|
|
+refers to how a rectangle of pixels are sent (all pixel information in
|
|
+VNC is sent as rectangles). All rectangles come with a header giving
|
|
+the location and size of the rectangle and an encoding type used by
|
|
+the data which follows. These types are listed below.
|
|
+.TP
|
|
+.B Raw
|
|
+The raw encoding simply sends width*height pixel values. All clients
|
|
+are required to support this encoding type. Raw is also the fastest
|
|
+when the server and viewer are on the same machine, as the connection
|
|
+speed is essentially infinite and raw encoding minimizes processing
|
|
+time.
|
|
+.TP
|
|
+.B CopyRect
|
|
+The Copy Rectangle encoding is efficient when something is being
|
|
+moved; the only data sent is the location of a rectangle from which
|
|
+data should be copied to the current location. Copyrect could also be
|
|
+used to efficiently transmit a repeated pattern.
|
|
+.TP
|
|
+.B RRE
|
|
+The Rise\-and\-Run\-length\-Encoding is basically a 2D version of
|
|
+run\-length encoding (RLE). In this encoding, a sequence of identical
|
|
+pixels are compressed to a single value and repeat count. In VNC, this
|
|
+is implemented with a background color, and then specifications of an
|
|
+arbitrary number of subrectangles and color for each. This is an
|
|
+efficient encoding for large blocks of constant color.
|
|
+.TP
|
|
+.B CoRRE
|
|
+This is a minor variation on RRE, using a maximum of 255x255 pixel
|
|
+rectangles. This allows for single\-byte values to be used, reducing
|
|
+packet size. This is in general more efficient, because the savings
|
|
+from sending 1\-byte values generally outweighs the losses from the
|
|
+(relatively rare) cases where very large regions are painted the same
|
|
+color.
|
|
+.TP
|
|
+.B Hextile
|
|
+Here, rectangles are split up in to 16x16 tiles, which are sent in a
|
|
+predetermined order. The data within the tiles is sent either raw or
|
|
+as a variant on RRE. Hextile encoding is usually the best choice for
|
|
+using in high\-speed network environments (e.g. Ethernet local\-area
|
|
+networks).
|
|
+.TP
|
|
+.B Zlib
|
|
+Zlib is a very simple encoding that uses zlib library to compress raw
|
|
+pixel data. This encoding achieves good compression, but consumes a
|
|
+lot of CPU time. Support for this encoding is provided for
|
|
+compatibility with VNC servers that might not understand Tight
|
|
+encoding which is more efficient than Zlib in nearly all real\-life
|
|
+situations.
|
|
+.TP
|
|
+.B Tight
|
|
+Like Zlib encoding, Tight encoding uses zlib library to compress the
|
|
+pixel data, but it pre\-processes data to maximize compression ratios,
|
|
+and to minimize CPU usage on compression. Also, JPEG compression may
|
|
+be used to encode color\-rich screen areas (see the description of
|
|
+\-quality and \-nojpeg options above). Tight encoding is usually the
|
|
+best choice for low\-bandwidth network environments (e.g. slow modem
|
|
+connections).
|
|
+.SH RESOURCES
|
|
+X resources that \fBvncviewer\fR knows about, aside from the
|
|
+normal Xt resources, are as follows:
|
|
+.TP
|
|
+.B shareDesktop
|
|
+Equivalent of \fB\-shared\fR/\fB\-noshared\fR options. Default true.
|
|
+.TP
|
|
+.B viewOnly
|
|
+Equivalent of \fB\-viewonly\fR option. Default false.
|
|
+.TP
|
|
+.B fullScreen
|
|
+Equivalent of \fB\-fullscreen\fR option. Default false.
|
|
+.TP
|
|
+.B grabKeyboard
|
|
+Grab keyboard in full-screen mode. This can help to solve problems
|
|
+with losing keyboard focus. Default false.
|
|
+.TP
|
|
+.B raiseOnBeep
|
|
+Equivalent of \fB\-noraiseonbeep\fR option, when set to false. Default
|
|
+true.
|
|
+.TP
|
|
+.B passwordFile
|
|
+Equivalent of \fB\-passwd\fR option.
|
|
+.TP
|
|
+.B userLogin
|
|
+Equivalent of \fB\-user\fR option.
|
|
+.TP
|
|
+.B passwordDialog
|
|
+Whether to use a dialog box to get the password (true) or get it from
|
|
+the tty (false). Irrelevant if \fBpasswordFile\fR is set. Default
|
|
+false.
|
|
+.TP
|
|
+.B encodings
|
|
+Equivalent of \fB\-encodings\fR option.
|
|
+.TP
|
|
+.B compressLevel
|
|
+Equivalent of \fB\-compresslevel\fR option (TightVNC\-specific).
|
|
+.TP
|
|
+.B qualityLevel
|
|
+Equivalent of \fB\-quality\fR option (TightVNC\-specific).
|
|
+.TP
|
|
+.B enableJPEG
|
|
+Equivalent of \fB\-nojpeg\fR option, when set to false. Default true.
|
|
+.TP
|
|
+.B useRemoteCursor
|
|
+Equivalent of \fB\-nocursorshape\fR option, when set to false
|
|
+(TightVNC\-specific). Default true.
|
|
+.TP
|
|
+.B useBGR233
|
|
+Equivalent of \fB\-bgr233\fR option. Default false.
|
|
+.TP
|
|
+.B nColours
|
|
+When using BGR233, try to allocate this many "exact" colors from the
|
|
+BGR233 color cube. When using a shared colormap, setting this resource
|
|
+lower leaves more colors for other X clients. Irrelevant when using
|
|
+truecolor. Default is 256 (i.e. all of them).
|
|
+.TP
|
|
+.B useSharedColours
|
|
+If the number of "exact" BGR233 colors successfully allocated is less
|
|
+than 256 then the rest are filled in using the "nearest" colors
|
|
+available. This resource says whether to only use the "exact" BGR233
|
|
+colors for this purpose, or whether to use other clients' "shared"
|
|
+colors as well. Default true (i.e. use other clients' colors).
|
|
+.TP
|
|
+.B forceOwnCmap
|
|
+Equivalent of \fB\-owncmap\fR option. Default false.
|
|
+.TP
|
|
+.B forceTrueColour
|
|
+Equivalent of \fB\-truecolour\fR option. Default false.
|
|
+.TP
|
|
+.B requestedDepth
|
|
+Equivalent of \fB\-depth\fR option.
|
|
+.TP
|
|
+.B useSharedMemory
|
|
+Use MIT shared memory extension if on the same machine as the X
|
|
+server. Default true.
|
|
+.TP
|
|
+.B wmDecorationWidth, wmDecorationHeight
|
|
+The total width and height taken up by window manager decorations.
|
|
+This is used to calculate the maximum size of the VNC viewer window.
|
|
+Default is width 4, height 24.
|
|
+.TP
|
|
+.B bumpScrollTime, bumpScrollPixels
|
|
+When in full screen mode and the VNC desktop is bigger than the X
|
|
+display, scrolling happens whenever the mouse hits the edge of the
|
|
+screen. The maximum speed of scrolling is bumpScrollPixels pixels
|
|
+every bumpScrollTime milliseconds. The actual speed of scrolling will
|
|
+be slower than this, of course, depending on how fast your machine is.
|
|
+Default 20 pixels every 25 milliseconds.
|
|
+.TP
|
|
+.B popupButtonCount
|
|
+The number of buttons in the popup window. See the README file for
|
|
+more information on how to customize the buttons.
|
|
+.TP
|
|
+.B debug
|
|
+For debugging. Default false.
|
|
+.TP
|
|
+.B rawDelay, copyRectDelay
|
|
+For debugging, see the README file for details. Default 0 (off).
|
|
+.SH ENVIRONMENT
|
|
+When started with the \fB\-via\fR option, vncviewer reads the
|
|
+\fBVNC_VIA_CMD\fR environment variable, expands patterns beginning
|
|
+with the "%" character, and executes result as a command assuming that
|
|
+it would create TCP tunnel that should be used for VNC connection. If
|
|
+not set, this environment variable defaults to "/usr/bin/ssh -f -L
|
|
+%L:%H:%R %G sleep 20".
|
|
+
|
|
+The following patterns are recognized in the \fBVNC_VIA_CMD\fR (note
|
|
+that all the patterns %G, %H, %L and %R must be present in the command
|
|
+template):
|
|
+.TP
|
|
+.B %%
|
|
+A literal "%";
|
|
+.TP
|
|
+.B %G
|
|
+gateway host name;
|
|
+.TP
|
|
+.B %H
|
|
+remote VNC host name, as known to the gateway;
|
|
+.TP
|
|
+.B %L
|
|
+local TCP port number;
|
|
+.TP
|
|
+.B %R
|
|
+remote TCP port number.
|
|
+.SH SEE ALSO
|
|
+\fBvncserver\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1),
|
|
+\fBvncconnect\fR(1), \fBssh\fR(1)
|
|
+.SH AUTHORS
|
|
+Original VNC was developed in AT&T Laboratories Cambridge. TightVNC
|
|
+additions was implemented by Constantin Kaplinsky. Many other people
|
|
+participated in development, testing and support.
|
|
+
|
|
+\fBMan page authors:\fR
|
|
+.br
|
|
+Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>,
|
|
+.br
|
|
+Terran Melconian <terran@consistent.org>,
|
|
+.br
|
|
+Tim Waugh <twaugh@redhat.com>,
|
|
+.br
|
|
+Constantin Kaplinsky <const@ce.cctpu.edu.ru>
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncviewer/vncviewer.c
|
|
--- vnc_unixsrc.orig/vncviewer/vncviewer.c 2004-01-13 09:22:05.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/vncviewer.c 2007-05-21 10:49:37.000000000 -0400
|
|
@@ -22,6 +22,7 @@
|
|
*/
|
|
|
|
#include "vncviewer.h"
|
|
+#include <X11/Xaw/Toggle.h>
|
|
|
|
char *programName;
|
|
XtAppContext appContext;
|
|
@@ -29,11 +30,47 @@
|
|
|
|
Widget toplevel;
|
|
|
|
+void set_sbwidth(int sbw) {
|
|
+ char *q, *p, t[5];
|
|
+ int i, k, N = 4;
|
|
+ int db = 0;
|
|
+
|
|
+ if (sbw < 1) {
|
|
+ sbw = 2;
|
|
+ } else if (sbw > 100) {
|
|
+ sbw = 100;
|
|
+ }
|
|
+ if (db) fprintf(stderr, "sbw: %d\n", sbw);
|
|
+
|
|
+ sprintf(t, "%4d", sbw);
|
|
+ k = 0;
|
|
+ while (fallback_resources[k] != NULL) {
|
|
+ q = strstr(fallback_resources[k], "horizontal.height: ");
|
|
+ if (!q) {
|
|
+ q = strstr(fallback_resources[k], "vertical.width: ");
|
|
+ }
|
|
+ if (q) {
|
|
+ p = strdup(fallback_resources[k]);
|
|
+ q = strstr(p, ": ");
|
|
+ if (q) {
|
|
+ q++;
|
|
+ q++;
|
|
+ for (i=0; i < N; i++) {
|
|
+ *(q+i) = t[i];
|
|
+ }
|
|
+ fallback_resources[k] = p;
|
|
+ if (db) fprintf(stderr, "res: %s\n", p);
|
|
+ }
|
|
+ }
|
|
+ k++;
|
|
+ }
|
|
+}
|
|
+
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
- int i;
|
|
- programName = argv[0];
|
|
+ int i, save_sbw;
|
|
+ programName = argv[0];
|
|
|
|
/* The -listen option is used to make us a daemon process which listens for
|
|
incoming connections from servers, rather than actively connecting to a
|
|
@@ -45,89 +82,807 @@
|
|
listenForIncomingConnections() returns, setting the listenSpecified
|
|
flag. */
|
|
|
|
- for (i = 1; i < argc; i++) {
|
|
- if (strcmp(argv[i], "-listen") == 0) {
|
|
- listenForIncomingConnections(&argc, argv, i);
|
|
- break;
|
|
- }
|
|
- if (strcmp(argv[i], "-tunnel") == 0 || strcmp(argv[i], "-via") == 0) {
|
|
- if (!createTunnel(&argc, argv, i))
|
|
- exit(1);
|
|
- break;
|
|
- }
|
|
- }
|
|
+ for (i = 1; i < argc; i++) {
|
|
+ if (strcmp(argv[i], "-listen") == 0) {
|
|
+ listenForIncomingConnections(&argc, argv, i);
|
|
+ break;
|
|
+ }
|
|
+ if (strcmp(argv[i], "-tunnel") == 0 || strcmp(argv[i], "-via") == 0) {
|
|
+ if (!createTunnel(&argc, argv, i)) {
|
|
+ exit(1);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (argc > 1 && strstr(argv[1], "-h") == argv[1]) {
|
|
+ usage();
|
|
+ return 0;
|
|
+ }
|
|
|
|
/* Call the main Xt initialisation function. It parses command-line options,
|
|
generating appropriate resource specs, and makes a connection to the X
|
|
display. */
|
|
|
|
- toplevel = XtVaAppInitialize(&appContext, "Vncviewer",
|
|
- cmdLineOptions, numCmdLineOptions,
|
|
- &argc, argv, fallback_resources,
|
|
- XtNborderWidth, 0, NULL);
|
|
+ appData.sbWidth = 0;
|
|
+ if (getenv("VNCVIEWER_SBWIDTH")) {
|
|
+ int sbw = atoi(getenv("VNCVIEWER_SBWIDTH"));
|
|
+ if (sbw > 0) {
|
|
+ appData.sbWidth = sbw;
|
|
+ }
|
|
+ }
|
|
+ if (appData.sbWidth == 0) {
|
|
+ int i, sbw = 0;
|
|
+ for (i = 1; i < argc - 1; i++) {
|
|
+ if (!strcmp(argv[i], "-sbwidth")) {
|
|
+ sbw = atoi(argv[i+1]);
|
|
+ }
|
|
+ }
|
|
+ if (sbw > 0) {
|
|
+ appData.sbWidth = sbw;
|
|
+ }
|
|
+ }
|
|
+ save_sbw = appData.sbWidth;
|
|
+ if (save_sbw > 0) {
|
|
+ set_sbwidth(save_sbw);
|
|
+ } else {
|
|
+ set_sbwidth(6);
|
|
+ }
|
|
+
|
|
+ toplevel = XtVaAppInitialize(&appContext, "Vncviewer", cmdLineOptions,
|
|
+ numCmdLineOptions, &argc, argv, fallback_resources,
|
|
+ XtNborderWidth, 0, NULL);
|
|
|
|
- dpy = XtDisplay(toplevel);
|
|
+ dpy = XtDisplay(toplevel);
|
|
|
|
/* Interpret resource specs and process any remaining command-line arguments
|
|
(i.e. the VNC server name). If the server name isn't specified on the
|
|
command line, getArgsAndResources() will pop up a dialog box and wait
|
|
for one to be entered. */
|
|
|
|
- GetArgsAndResources(argc, argv);
|
|
+ GetArgsAndResources(argc, argv);
|
|
+
|
|
+ if (save_sbw) {
|
|
+ appData.sbWidth = save_sbw;
|
|
+ }
|
|
|
|
/* Unless we accepted an incoming connection, make a TCP connection to the
|
|
given VNC server */
|
|
|
|
- if (!listenSpecified) {
|
|
- if (!ConnectToRFBServer(vncServerHost, vncServerPort)) exit(1);
|
|
- }
|
|
+ if (!listenSpecified) {
|
|
+ if (!ConnectToRFBServer(vncServerHost, vncServerPort)) {
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
|
|
/* Initialise the VNC connection, including reading the password */
|
|
|
|
- if (!InitialiseRFBConnection()) exit(1);
|
|
+ if (!InitialiseRFBConnection()) {
|
|
+ exit(1);
|
|
+ }
|
|
|
|
/* Create the "popup" widget - this won't actually appear on the screen until
|
|
some user-defined event causes the "ShowPopup" action to be invoked */
|
|
|
|
- CreatePopup();
|
|
+ CreatePopup();
|
|
+ CreateScaleN();
|
|
+ CreateChat();
|
|
|
|
/* Find the best pixel format and X visual/colormap to use */
|
|
|
|
- SetVisualAndCmap();
|
|
+ SetVisualAndCmap();
|
|
|
|
/* Create the "desktop" widget, and perform initialisation which needs doing
|
|
before the widgets are realized */
|
|
|
|
- ToplevelInitBeforeRealization();
|
|
+ ToplevelInitBeforeRealization();
|
|
|
|
- DesktopInitBeforeRealization();
|
|
+ DesktopInitBeforeRealization();
|
|
|
|
/* "Realize" all the widgets, i.e. actually create and map their X windows */
|
|
|
|
- XtRealizeWidget(toplevel);
|
|
+ XtRealizeWidget(toplevel);
|
|
|
|
/* Perform initialisation that needs doing after realization, now that the X
|
|
windows exist */
|
|
|
|
- InitialiseSelection();
|
|
+ InitialiseSelection();
|
|
|
|
- ToplevelInitAfterRealization();
|
|
+ ToplevelInitAfterRealization();
|
|
|
|
- DesktopInitAfterRealization();
|
|
+ DesktopInitAfterRealization();
|
|
|
|
/* Tell the VNC server which pixel format and encodings we want to use */
|
|
|
|
- SetFormatAndEncodings();
|
|
+ SetFormatAndEncodings();
|
|
|
|
/* Now enter the main loop, processing VNC messages. X events will
|
|
automatically be processed whenever the VNC connection is idle. */
|
|
|
|
- while (1) {
|
|
- if (!HandleRFBServerMessage())
|
|
- break;
|
|
- }
|
|
+ while (1) {
|
|
+ if (!HandleRFBServerMessage()) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ Cleanup();
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Toggle8bpp
|
|
+ */
|
|
+
|
|
+static int last_ncolors = 0;
|
|
+static int save_useBGR233 = 0;
|
|
+static Bool save_useBGR565 = False;
|
|
+
|
|
+static Widget b8 = NULL;
|
|
+static Widget b16 = NULL;
|
|
+static Widget bfull = NULL;
|
|
+
|
|
+int do_format_change = 0;
|
|
+int do_cursor_change = 0;
|
|
+int do_fb_update = 0.0;
|
|
+static void schedule_format_change(void) {
|
|
+ do_format_change = 1;
|
|
+ do_cursor_change = 0;
|
|
+}
|
|
+extern double dnow(void);
|
|
+static void schedule_fb_update(void) {
|
|
+ do_fb_update = dnow();
|
|
+}
|
|
+static void init_format_change(void) {
|
|
+ appDataNew.useBGR233 = appData.useBGR233;
|
|
+ appDataNew.useBGR565 = appData.useBGR565;
|
|
+ appDataNew.useGreyScale = appData.useGreyScale;
|
|
+ appDataNew.enableJPEG = appData.enableJPEG;
|
|
+ appDataNew.encodingsString = appData.encodingsString;
|
|
+ appDataNew.useRemoteCursor = appData.useRemoteCursor;
|
|
+ appDataNew.useX11Cursor = appData.useX11Cursor;
|
|
+ appDataNew.useRawLocal = appData.useRawLocal;
|
|
+}
|
|
+void cutover_format_change(void) {
|
|
+ appData.useBGR233 = appDataNew.useBGR233;
|
|
+ appData.useBGR565 = appDataNew.useBGR565;
|
|
+ appData.useGreyScale = appDataNew.useGreyScale;
|
|
+ appData.enableJPEG = appDataNew.enableJPEG;
|
|
+ appData.encodingsString = appDataNew.encodingsString;
|
|
+ appData.useRemoteCursor = appDataNew.useRemoteCursor;
|
|
+ appData.useX11Cursor = appDataNew.useX11Cursor;
|
|
+ appData.useRawLocal = appDataNew.useRawLocal;
|
|
+}
|
|
+
|
|
+void
|
|
+Toggle8bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ fprintf(stderr, "Toggle8bpp: %d\n", appData.useBGR233);
|
|
+ b8 = w;
|
|
+ init_format_change();
|
|
+ if (appData.useBGR233) {
|
|
+ last_ncolors = appData.useBGR233;
|
|
+ appDataNew.useBGR233 = 0;
|
|
+ appDataNew.useBGR565 = save_useBGR565;
|
|
+ fprintf(stderr, "8bpp: off\n");
|
|
+ } else {
|
|
+ if (!last_ncolors) last_ncolors = 256;
|
|
+ appDataNew.useBGR233 = last_ncolors;
|
|
+ save_useBGR565 = appData.useBGR565;
|
|
+ appDataNew.useBGR565 = False;
|
|
+ fprintf(stderr, "8bpp: on (%d colors)\n", appDataNew.useBGR233);
|
|
+ }
|
|
+ schedule_format_change();
|
|
+}
|
|
+
|
|
+
|
|
+void
|
|
+Toggle16bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ fprintf(stderr, "Toggle16bpp: %d\n", appData.useBGR565);
|
|
+ b16 = w;
|
|
+ init_format_change();
|
|
+ if (appData.useBGR565) {
|
|
+ appDataNew.useBGR565 = False;
|
|
+ appDataNew.useBGR233 = save_useBGR233;
|
|
+ fprintf(stderr, "16bpp: off\n");
|
|
+ } else {
|
|
+ appDataNew.useBGR565 = True;
|
|
+ save_useBGR233 = appData.useBGR233;
|
|
+ appDataNew.useBGR233 = 0;
|
|
+ fprintf(stderr, "16bpp: on\n");
|
|
+ }
|
|
+ schedule_format_change();
|
|
+}
|
|
+
|
|
+void
|
|
+ToggleFullColor(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ fprintf(stderr, "ToggleFullColor\n");
|
|
+ bfull = w;
|
|
+ init_format_change();
|
|
+ if (appData.useBGR565 || appData.useBGR233) {
|
|
+ save_useBGR565 = appData.useBGR565;
|
|
+ appDataNew.useBGR565 = False;
|
|
+ save_useBGR233 = appData.useBGR233;
|
|
+ appDataNew.useBGR233 = 0;
|
|
+ fprintf(stderr, "FullColor: on\n");
|
|
+ } else {
|
|
+ if (save_useBGR565) {
|
|
+ appDataNew.useBGR565 = True;
|
|
+ appDataNew.useBGR233 = 0;
|
|
+ fprintf(stderr, "FullColor off -> 16bpp.\n");
|
|
+ } else {
|
|
+ appDataNew.useBGR565 = False;
|
|
+ if (!save_useBGR233) save_useBGR233 = 256;
|
|
+ appDataNew.useBGR233 = save_useBGR233;
|
|
+ fprintf(stderr, "FullColor off -> 8bpp.\n");
|
|
+ }
|
|
+ }
|
|
+ schedule_format_change();
|
|
+}
|
|
+
|
|
+/*
|
|
+ * ToggleNColors
|
|
+ */
|
|
|
|
- Cleanup();
|
|
+static Widget w256 = NULL;
|
|
+static Widget w64 = NULL;
|
|
+static Widget w8 = NULL;
|
|
|
|
- return 0;
|
|
+void
|
|
+Toggle256Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ w256 = w;
|
|
+ if (appData.useBGR233 != 256) {
|
|
+ fprintf(stderr, "256 colors: on\n");
|
|
+ init_format_change();
|
|
+ last_ncolors = appDataNew.useBGR233 = 256;
|
|
+ save_useBGR565 = appData.useBGR565;
|
|
+ appDataNew.useBGR565 = False;
|
|
+ schedule_format_change();
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+Toggle64Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ w64 = w;
|
|
+ if (appData.useBGR233 != 64) {
|
|
+ fprintf(stderr, "64 colors: on\n");
|
|
+ init_format_change();
|
|
+ last_ncolors = appDataNew.useBGR233 = 64;
|
|
+ save_useBGR565 = appData.useBGR565;
|
|
+ appDataNew.useBGR565 = False;
|
|
+ schedule_format_change();
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+Toggle8Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ w8 = w;
|
|
+ if (appData.useBGR233 != 8) {
|
|
+ fprintf(stderr, "8 colors: on\n");
|
|
+ init_format_change();
|
|
+ last_ncolors = appDataNew.useBGR233 = 8;
|
|
+ save_useBGR565 = appData.useBGR565;
|
|
+ appDataNew.useBGR565 = False;
|
|
+ schedule_format_change();
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+ToggleGreyScale(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ fprintf(stderr, "ToggleGreyScale\n");
|
|
+ init_format_change();
|
|
+ if (appData.useGreyScale) {
|
|
+ appDataNew.useGreyScale = False;
|
|
+ fprintf(stderr, "greyscale: off\n");
|
|
+ } else {
|
|
+ appDataNew.useGreyScale = True;
|
|
+ fprintf(stderr, "greyscale: on\n");
|
|
+ }
|
|
+ schedule_format_change();
|
|
+}
|
|
+
|
|
+/*
|
|
+ * ToggleJPEG
|
|
+ */
|
|
+
|
|
+void
|
|
+ToggleJPEG(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ init_format_change();
|
|
+ if (appData.enableJPEG) {
|
|
+ appDataNew.enableJPEG = False;
|
|
+ fprintf(stderr, "JPEG: off\n");
|
|
+ } else {
|
|
+ appDataNew.enableJPEG = True;
|
|
+ fprintf(stderr, "JPEG: on\n");
|
|
+ }
|
|
+ schedule_format_change();
|
|
+}
|
|
+
|
|
+/*
|
|
+ * ToggleTightZRLE
|
|
+ */
|
|
+
|
|
+static Bool usingZRLE = False;
|
|
+
|
|
+void
|
|
+ToggleTightZRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ char prefTight[] = "copyrect tight zrle zlib hextile corre rre raw";
|
|
+ char prefZRLE[] = "copyrect zrle tight zlib hextile corre rre raw";
|
|
+ init_format_change();
|
|
+ if (! appData.encodingsString) {
|
|
+ appDataNew.encodingsString = strdup(prefZRLE);
|
|
+ usingZRLE = True;
|
|
+ fprintf(stderr, "prefer: ZRLE\n");
|
|
+ } else {
|
|
+ char *p, *q;
|
|
+ p = strstr(appData.encodingsString, "tight");
|
|
+ q = strstr(appData.encodingsString, "zrle");
|
|
+ if (! p) {
|
|
+ appDataNew.encodingsString = strdup(prefZRLE);
|
|
+ usingZRLE = True;
|
|
+ fprintf(stderr, "prefer: ZRLE\n");
|
|
+ } else if (! q) {
|
|
+ appDataNew.encodingsString = strdup(prefTight);
|
|
+ usingZRLE = False;
|
|
+ fprintf(stderr, "prefer: Tight\n");
|
|
+ } else {
|
|
+ if (p < q) {
|
|
+ appDataNew.encodingsString = strdup(prefZRLE);
|
|
+ usingZRLE = True;
|
|
+ fprintf(stderr, "prefer: ZRLE\n");
|
|
+ } else {
|
|
+ appDataNew.encodingsString = strdup(prefTight);
|
|
+ usingZRLE = False;
|
|
+ fprintf(stderr, "prefer: Tight\n");
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ schedule_format_change();
|
|
+}
|
|
+
|
|
+/*
|
|
+ * ToggleViewOnly
|
|
+ */
|
|
+
|
|
+void
|
|
+ToggleViewOnly(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.viewOnly) {
|
|
+ appData.viewOnly = False;
|
|
+ fprintf(stderr, "viewonly: off\n");
|
|
+ } else {
|
|
+ appData.viewOnly = True;
|
|
+ fprintf(stderr, "viewonly: on\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+ToggleCursorShape(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ init_format_change();
|
|
+ if (appData.useRemoteCursor) {
|
|
+ appDataNew.useRemoteCursor = False;
|
|
+ fprintf(stderr, "useRemoteCursor: off\n");
|
|
+ } else {
|
|
+ appDataNew.useRemoteCursor = True;
|
|
+ fprintf(stderr, "useRemoteCursor: on\n");
|
|
+ }
|
|
+ schedule_format_change();
|
|
+ if (!appDataNew.useRemoteCursor) {
|
|
+ do_cursor_change = 1;
|
|
+ } else {
|
|
+ do_cursor_change = -1;
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+ToggleCursorAlpha(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useCursorAlpha) {
|
|
+ appData.useCursorAlpha = False;
|
|
+ fprintf(stderr, "useCursorAlpha: off\n");
|
|
+ } else {
|
|
+ appData.useCursorAlpha = True;
|
|
+ fprintf(stderr, "useCursorAlpha: on\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+ToggleX11Cursor(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ init_format_change();
|
|
+ if (appData.useX11Cursor) {
|
|
+ appDataNew.useX11Cursor = False;
|
|
+ fprintf(stderr, "useX11Cursor: off\n");
|
|
+ } else {
|
|
+ appDataNew.useX11Cursor = True;
|
|
+ fprintf(stderr, "useX11Cursor: on\n");
|
|
+ }
|
|
+ schedule_format_change();
|
|
+ do_cursor_change = 1;
|
|
+}
|
|
+
|
|
+void
|
|
+ToggleBell(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useBell) {
|
|
+ appData.useBell = False;
|
|
+ fprintf(stderr, "useBell: off\n");
|
|
+ } else {
|
|
+ appData.useBell = True;
|
|
+ fprintf(stderr, "useBell: on\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+ToggleRawLocal(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ init_format_change();
|
|
+ if (appData.useRawLocal) {
|
|
+ appDataNew.useRawLocal = False;
|
|
+ fprintf(stderr, "useRawLocal: off\n");
|
|
+ } else {
|
|
+ appDataNew.useRawLocal = True;
|
|
+ fprintf(stderr, "useRawLocal: on\n");
|
|
+ }
|
|
+ schedule_format_change();
|
|
+}
|
|
+
|
|
+void
|
|
+ToggleServerInput(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.serverInput) {
|
|
+ appData.serverInput= False;
|
|
+ fprintf(stderr, "serverInput: off\n");
|
|
+ SendServerInput(True);
|
|
+ } else {
|
|
+ appData.serverInput = True;
|
|
+ fprintf(stderr, "serverInput: on\n");
|
|
+ SendServerInput(False);
|
|
+ }
|
|
+}
|
|
+
|
|
+Bool _sw1_ = False; /* XXX this is a weird bug... */
|
|
+Bool _sw2_ = False;
|
|
+Bool _sw3_ = False;
|
|
+Bool selectingSingleWindow = False;
|
|
+
|
|
+extern Cursor bogoCursor;
|
|
+
|
|
+void
|
|
+ToggleSingleWindow(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.singleWindow) {
|
|
+ appData.singleWindow= False;
|
|
+ fprintf(stderr, "singleWindow: off\n");
|
|
+ SendSingleWindow(-1, -1);
|
|
+ } else {
|
|
+ appData.singleWindow = True;
|
|
+ selectingSingleWindow = True;
|
|
+ fprintf(stderr, "singleWindow: on\n");
|
|
+ if (bogoCursor != None) {
|
|
+ XDefineCursor(dpy, desktopWin, bogoCursor);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void raiseme(void);
|
|
+void AppendChatInput(char *);
|
|
+
|
|
+void printChat(char *str, Bool raise) {
|
|
+ if (appData.termChat) {
|
|
+ if (raise) {
|
|
+ raiseme();
|
|
+ }
|
|
+ fprintf(stderr, str);
|
|
+ } else {
|
|
+ if (raise) {
|
|
+ ShowChat();
|
|
+ }
|
|
+ AppendChatInput(str);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+ToggleTextChat(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.chatActive) {
|
|
+ printChat("\n*SentClose*\n\n", False);
|
|
+ SendTextChatClose();
|
|
+ HideChat();
|
|
+ appData.chatActive= False;
|
|
+ } else {
|
|
+ ShowChat();
|
|
+ SendTextChatOpen();
|
|
+ if (appData.termChat) {
|
|
+ printChat("\n*SentOpen*\n\nSend: ", True);
|
|
+ } else {
|
|
+ printChat("\n*SentOpen*\n", True);
|
|
+ }
|
|
+ appData.chatActive = True;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int fooHandler(Display *dpy, XErrorEvent *error) {
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void raiseme(void) {
|
|
+ if (appData.termChat && getenv("WINDOWID")) {
|
|
+ unsigned long w;
|
|
+ if (sscanf(getenv("WINDOWID"), "%lu", &w) == 1) {
|
|
+ ;
|
|
+ } else if (sscanf(getenv("WINDOWID"), "0x%lx", &w) == 1) {
|
|
+ ;
|
|
+ } else {
|
|
+ w = 0;
|
|
+ }
|
|
+ if (w != 0) {
|
|
+ XErrorHandler old = XSetErrorHandler(fooHandler);
|
|
+ XMapRaised(dpy, (Window) w);
|
|
+ XSync(dpy, False);
|
|
+ XSetErrorHandler(old);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static void set_server_scale(int n) {
|
|
+ if (n >= 1 && n < 100) {
|
|
+ int w = si.framebufferWidth;
|
|
+ int h = si.framebufferHeight;
|
|
+ appData.serverScale = n;
|
|
+ SendServerScale(n);
|
|
+ SendFramebufferUpdateRequest(0, 0, w, h, False);
|
|
+ schedule_fb_update();
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+DoServerScale(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ char str[100], *q;
|
|
+ int n;
|
|
+ raiseme();
|
|
+ fprintf(stderr, "\n\n\a\nEnter integer n for 1/n server scaling: ");
|
|
+ str[0] = '\0';
|
|
+ fgets(str, 100, stdin);
|
|
+ q = strstr(str, "\n");
|
|
+ if (q) *q = '\0';
|
|
+ if (str[0] != '\0') {
|
|
+ n = atoi(str);
|
|
+ set_server_scale(n);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+SetScaleN(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (*num_params != 0) {
|
|
+ int n = atoi(params[0]);
|
|
+ set_server_scale(n);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+GotChatText(char *str, int len)
|
|
+{
|
|
+ static char *b = NULL;
|
|
+ static int blen = -1;
|
|
+ int i;
|
|
+ if (appData.termChat) {
|
|
+ printChat("\nChat: ", True);
|
|
+ } else {
|
|
+ printChat("Chat: ", True);
|
|
+ }
|
|
+
|
|
+ if (len < 0) len = 0;
|
|
+
|
|
+ if (blen < len+1) {
|
|
+ if (b) free(b);
|
|
+ blen = 2 * (len + 10);
|
|
+ b = (char *) malloc(blen);
|
|
+ }
|
|
+
|
|
+ for (i=0; i < len; i++) {
|
|
+ b[i] = str[i];
|
|
+ }
|
|
+ b[len] = '\0';
|
|
+ printChat(b, True);
|
|
+
|
|
+ if (appData.termChat) {
|
|
+ if (strstr(str, "\n")) {
|
|
+ printChat("Send: ", True);
|
|
+ } else {
|
|
+ printChat("\nSend: ", True);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+SetViewOnlyState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.viewOnly)
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+SetNOJPEGState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.enableJPEG)
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+Set8bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useBGR233) {
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ if (b16 != NULL) XtVaSetValues(b16, XtNstate, False, NULL);
|
|
+ if (bfull != NULL) XtVaSetValues(bfull, XtNstate, False, NULL);
|
|
+ } else {
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+Set16bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useBGR565) {
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ if (b8 != NULL) XtVaSetValues(b8, XtNstate, False, NULL);
|
|
+ if (bfull != NULL) XtVaSetValues(bfull, XtNstate, False, NULL);
|
|
+ } else {
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+SetFullColorState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useBGR565 || appData.useBGR233) {
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+ } else {
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ if (b8 != NULL) XtVaSetValues(b8, XtNstate, False, NULL);
|
|
+ if (b16 != NULL) XtVaSetValues(b16, XtNstate, False, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+Set256ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useBGR233 == 256) {
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ if (w64 != NULL) XtVaSetValues(w64 , XtNstate, False, NULL);
|
|
+ if (w8 != NULL) XtVaSetValues(w8 , XtNstate, False, NULL);
|
|
+ } else {
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+Set64ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useBGR233 == 64) {
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ if (w256 != NULL) XtVaSetValues(w256, XtNstate, False, NULL);
|
|
+ if (w8 != NULL) XtVaSetValues(w8 , XtNstate, False, NULL);
|
|
+ } else {
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+Set8ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useBGR233 == 8) {
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ if (w256 != NULL) XtVaSetValues(w256, XtNstate, False, NULL);
|
|
+ if (w64 != NULL) XtVaSetValues(w64 , XtNstate, False, NULL);
|
|
+ } else {
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+SetGreyScaleState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useGreyScale) {
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ } else {
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+SetZRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (usingZRLE)
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+SetCursorShapeState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useRemoteCursor)
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+SetCursorAlphaState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useCursorAlpha)
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+SetX11CursorState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useX11Cursor)
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+SetBellState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useBell)
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+SetRawLocalState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.useRawLocal)
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+SetServerInputState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (!appData.serverInput)
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+SetSingleWindowState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.singleWindow)
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
+}
|
|
+
|
|
+void
|
|
+SetTextChatState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
|
|
+{
|
|
+ if (appData.chatActive)
|
|
+ XtVaSetValues(w, XtNstate, True, NULL);
|
|
+ else
|
|
+ XtVaSetValues(w, XtNstate, False, NULL);
|
|
}
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.foo vnc_unixsrc/vncviewer/vncviewer.foo
|
|
--- vnc_unixsrc.orig/vncviewer/vncviewer.foo 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/vncviewer.foo 2007-05-21 11:28:51.000000000 -0400
|
|
@@ -0,0 +1,506 @@
|
|
+'\" t
|
|
+.\" ** The above line should force tbl to be a preprocessor **
|
|
+.\" Man page for X vncviewer
|
|
+.\"
|
|
+.\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de
|
|
+.\" Copyright (C) 2000,2001 Red Hat, Inc.
|
|
+.\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru>
|
|
+.\"
|
|
+.\" You may distribute under the terms of the GNU General Public
|
|
+.\" License as specified in the file LICENCE.TXT that comes with the
|
|
+.\" TightVNC distribution.
|
|
+.\"
|
|
+.TH vncviewer 1 "January 2003" "" "TightVNC"
|
|
+.SH NAME
|
|
+vncviewer \- an X viewer client for VNC
|
|
+.SH SYNOPSIS
|
|
+.B vncviewer
|
|
+.RI [\| options \|]
|
|
+.RI [\| host \|][\| :display \|]
|
|
+.br
|
|
+.B vncviewer
|
|
+.RI [\| options \|]
|
|
+.RI [\| host \|][\| ::port \|]
|
|
+.br
|
|
+.B vncviewer
|
|
+.RI [\| options \|]
|
|
+.IR \-listen
|
|
+.RI [\| display \|]
|
|
+.br
|
|
+.B vncviewer
|
|
+.IR \-help
|
|
+.br
|
|
+.SH DESCRIPTION
|
|
+.B vncviewer
|
|
+is an Xt\-based client application for the VNC (Virtual Network
|
|
+Computing) system. It can connect to any VNC\-compatible server such
|
|
+as \fBXvnc\fR or WinVNC, allowing you to control desktop environment
|
|
+of a different machine.
|
|
+
|
|
+You can use F8 to display a pop\-up utility menu. Press F8 twice to
|
|
+pass single F8 to the remote side.
|
|
+.SH OPTIONS
|
|
+.TP
|
|
+\fB\-help\fR
|
|
+Prints a short usage notice to stderr.
|
|
+.TP
|
|
+\fB\-listen\fR
|
|
+Make the viewer listen on port 5500+\fIdisplay\fR for reverse
|
|
+connections from a server. WinVNC supports reverse connections using
|
|
+the "Add New Client" menu option, or the \-connect command line
|
|
+option. \fBXvnc\fR requires the use of the helper program
|
|
+\fBvncconnect\fR.
|
|
+.TP
|
|
+\fB\-via\fR \fIgateway\fR
|
|
+Automatically create encrypted TCP tunnel to the \fIgateway\fR machine
|
|
+before connection, connect to the \fIhost\fR through that tunnel
|
|
+(TightVNC\-specific). By default, this option invokes SSH local port
|
|
+forwarding, assuming that SSH client binary can be accessed as
|
|
+/usr/bin/ssh. Note that when using the \fB\-via\fR option, the host
|
|
+machine name should be specified as known to the gateway machine, e.g.
|
|
+"localhost" denotes the \fIgateway\fR, not the machine where vncviewer
|
|
+was launched. See the ENVIRONMENT section below for the information on
|
|
+configuring the \fB\-via\fR option.
|
|
+.TP
|
|
+\fB\-shared\fR
|
|
+When connecting, specify that a shared connection is requested. In
|
|
+TightVNC, this is the default mode, allowing you to share the desktop
|
|
+with other clients already using it.
|
|
+.TP
|
|
+\fB\-noshared\fR
|
|
+When connecting, specify that the session may not be shared. This
|
|
+would either disconnect other connected clients or refuse your
|
|
+connection, depending on the server configuration.
|
|
+.TP
|
|
+\fB\-viewonly\fR
|
|
+Disable transfer of mouse and keyboard events from the client to the
|
|
+server.
|
|
+.TP
|
|
+\fB\-fullscreen\fR
|
|
+Start in full\-screen mode. Please be aware that operating in
|
|
+full\-screen mode may confuse X window managers. Typically, such
|
|
+conflicts cause incorrect handling of input focus or make the viewer
|
|
+window disappear mysteriously. See the grabKeyboard setting in the
|
|
+RESOURCES section below for a method to solve input focus problem.
|
|
+.TP
|
|
+\fB\-noraiseonbeep\fR
|
|
+By default, the viewer shows and raises its window on remote beep
|
|
+(bell) event. This option disables such behaviour
|
|
+(TightVNC\-specific).
|
|
+.TP
|
|
+\fB\-user\fR \fIusername\fR
|
|
+User name for Unix login authentication. Default is to use current
|
|
+Unix user name. If this option was given, the viewer will prefer Unix
|
|
+login authentication over the standard VNC authentication.
|
|
+.TP
|
|
+\fB\-passwd\fR \fIpasswd\-file\fR
|
|
+File from which to get the password (as generated by the
|
|
+\fBvncpasswd\fR(1) program). This option affects only the standard VNC
|
|
+authentication.
|
|
+.TP
|
|
+\fB\-encodings\fR \fIencoding\-list\fR
|
|
+TightVNC supports several different compression methods to encode
|
|
+screen updates; this option specifies a set of them to use in order of
|
|
+preference. Encodings are specified separated with spaces, and must
|
|
+thus be enclosed in quotes if more than one is specified. Available
|
|
+encodings, in default order for a remote connection, are "copyrect
|
|
+tight hextile zlib corre rre raw". For a local connection (to the same
|
|
+machine), the default order to try is "raw copyrect tight hextile zlib
|
|
+corre rre". Raw encoding is always assumed as a last option if no
|
|
+other encoding can be used for some reason. For more information on
|
|
+encodings, see the section ENCODINGS below.
|
|
+.TP
|
|
+\fB\-bgr233\fR
|
|
+Always use the BGR233 format to encode pixel data. This reduces
|
|
+network traffic, but colors may be represented inaccurately. The
|
|
+bgr233 format is an 8\-bit "true color" format, with 2 bits blue, 3
|
|
+bits green, and 3 bits red.
|
|
+.TP
|
|
+\fB\-owncmap\fR
|
|
+Try to use a PseudoColor visual and a private colormap. This allows
|
|
+the VNC server to control the colormap.
|
|
+.TP
|
|
+\fB\-truecolour\fR, \fB\-truecolor\fR
|
|
+Try to use a TrueColor visual.
|
|
+.TP
|
|
+\fB\-depth\fR \fIdepth\fR
|
|
+On an X server which supports multiple TrueColor visuals of different
|
|
+depths, attempt to use the specified one (in bits per pixel); if
|
|
+successful, this depth will be requested from the VNC server.
|
|
+.TP
|
|
+\fB\-compresslevel \fIlevel\fR
|
|
+Use specified compression \fIlevel\fR (0..9) for "tight" and "zlib"
|
|
+encodings (TightVNC\-specific). Level 1 uses minimum of CPU time and
|
|
+achieves weak compression ratios, while level 9 offers best
|
|
+compression but is slow in terms of CPU time consumption on the server
|
|
+side. Use high levels with very slow network connections, and low
|
|
+levels when working over high\-speed LANs. It's not recommended to use
|
|
+compression level 0, reasonable choices start from the level 1.
|
|
+.TP
|
|
+\fB\-quality \fIlevel\fR
|
|
+Use the specified JPEG quality \fIlevel\fR (0..9) for the "tight"
|
|
+encoding (TightVNC\-specific). Quality level 0 denotes bad image
|
|
+quality but very impressive compression ratios, while level 9 offers
|
|
+very good image quality at lower compression ratios. Note that the
|
|
+"tight" encoder uses JPEG to encode only those screen areas that look
|
|
+suitable for lossy compression, so quality level 0 does not always
|
|
+mean unacceptable image quality.
|
|
+.TP
|
|
+\fB\-nojpeg\fR
|
|
+Disable lossy JPEG compression in Tight encoding (TightVNC\-specific).
|
|
+Disabling JPEG compression is not a good idea in typical cases, as
|
|
+that makes the Tight encoder less efficient. You might want to use
|
|
+this option if it's absolutely necessary to achieve perfect image
|
|
+quality (see also the \fB\-quality\fR option).
|
|
+.TP
|
|
+\fB\-nocursorshape\fR
|
|
+Disable cursor shape updates, protocol extensions used to handle
|
|
+remote cursor movements locally on the client side
|
|
+(TightVNC\-specific). Using cursor shape updates decreases delays with
|
|
+remote cursor movements, and can improve bandwidth usage dramatically.
|
|
+.TP
|
|
+\fB\-x11cursor\fR
|
|
+Use a real X11 cursor with X-style cursor shape updates, instead of
|
|
+drawing the remote cursor on the framebuffer. This option also
|
|
+disables the dot cursor, and disables cursor position updates in
|
|
+non-fullscreen mode.
|
|
+.TP
|
|
+\fB\-autopass\fR
|
|
+Read a plain-text password from stdin. This option affects only the
|
|
+standard VNC authentication.
|
|
+
|
|
+.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS
|
|
+.TP
|
|
+Enhanced TightVNC Viewer (SSVNC) web page is located at:
|
|
+.TP
|
|
+http://www.karlrunge.com/x11vnc/ssvnc.html
|
|
+.TP
|
|
+Note: ZRLE encoding is now supported.
|
|
+.TP
|
|
+Note: F9 is shortcut to Toggle FullScreen mode.
|
|
+.TP
|
|
+\fB\-use64\fR
|
|
+In \fB\-bgr233\fR mode, use 64 colors instead of 256.
|
|
+.TP
|
|
+\fB\-bgr222\fR
|
|
+Same as \fB\-use64\fR.
|
|
+.TP
|
|
+\fB\-use8\fR
|
|
+In \fB\-bgr233\fR mode, use 8 colors instead of 256.
|
|
+.TP
|
|
+\fB\-bgr111\fR
|
|
+Same as \fB\-use8\fR.
|
|
+.TP
|
|
+\fB\-16bpp\fR
|
|
+If the vnc viewer X display is depth 24 at 32bpp
|
|
+request a 16bpp format from the VNC server to cut
|
|
+network traffic by up to 2X, then tranlate the
|
|
+pixels to 32bpp locally.
|
|
+.TP
|
|
+\fB\-bgr565\fR
|
|
+Same as \fB\-16bpp\fR.
|
|
+.TP
|
|
+\fB\-grey\fR
|
|
+Use a grey scale for the 16- and 8\fB\-bpp\fR modes.
|
|
+.TP
|
|
+\fB\-alpha\fR
|
|
+Use alphablending transparency for local cursors
|
|
+requires: x11vnc server, both client and server
|
|
+must be 32bpp and same endianness.
|
|
+.TP
|
|
+\fB\-ycrop\fR n
|
|
+Only show the top n rows of the framebuffer. For
|
|
+use with x11vnc \fB\-ncache\fR client caching option
|
|
+to help "hide" the pixel cache region.
|
|
+Use a negative value (e.g. \fB\-1\fR) for autodetection.
|
|
+Autodetection will always take place if the remote
|
|
+fb height is more than 2 times the width.
|
|
+.TP
|
|
+\fB\-sbwidth\fR n
|
|
+Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR),
|
|
+default is very narrow: 2 pixels, it is narrow to
|
|
+avoid distraction in \fB\-ycrop\fR mode.
|
|
+.TP
|
|
+\fB\-nobell\fR
|
|
+Disable bell.
|
|
+.TP
|
|
+\fB\-rawlocal\fR
|
|
+Prefer raw encoding for localhost, default is
|
|
+no, i.e. assumes you have a SSH tunnel instead.
|
|
+.TP
|
|
+\fB\-graball\fR
|
|
+Grab the entire X server when in fullscreen mode,
|
|
+needed by some old window managers like fvwm2.
|
|
+.TP
|
|
+\fB\-popupfix\fR
|
|
+Warp the popup back to the pointer position,
|
|
+needed by some old window managers like fvwm2.
|
|
+.TP
|
|
+\fB\-grabkbd\fR
|
|
+Grab the X keyboard when in fullscreen mode,
|
|
+needed by some window managers. Same as \fB\-grabkeyboard\fR.
|
|
+\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable.
|
|
+.TP
|
|
+\fB\-bs\fR, \fB\-nobs\fR
|
|
+Whether or not to use X server Backingstore for the
|
|
+main viewer window. The default is to not, mainly
|
|
+because most Linux, etc, systems X servers disable
|
|
+*all* Backingstore by default. To re\fB\-enable\fR it put
|
|
+Option "Backingstore"
|
|
+in the Device section of /etc/X11/xorg.conf.
|
|
+In \fB\-bs\fR mode with no X server backingstore, whenever an
|
|
+area of the screen is re\fB\-exposed\fR it must go out to the
|
|
+VNC server to retrieve the pixels. This is too slow.
|
|
+In \fB\-nobs\fR mode, memory is allocated by the viewer to
|
|
+provide its own backing of the main viewer window. This
|
|
+actually makes some activities faster (changes in large
|
|
+regions) but can appear to "flash" too much.
|
|
+.TP
|
|
+\fB\-noshm\fR
|
|
+Disable use of MIT shared memory extension (not recommended)
|
|
+.TP
|
|
+\fB\-termchat\fR
|
|
+Do the UltraVNC chat in the terminal vncviewer is in
|
|
+instead of in an independent window.
|
|
+.TP
|
|
+\fB New Popup actions:\fR
|
|
+
|
|
+ ViewOnly: ~ -viewonly
|
|
+ Disable Bell: ~ -nobell
|
|
+ Cursor Shape: ~ -nocursorshape
|
|
+ X11 Cursor: ~ -x11cursor
|
|
+ Cursor Alphablend: ~ -alpha
|
|
+ Toggle Tight/ZRLE: ~ -encodings ...
|
|
+ Disable JPEG: ~ -nojpeg
|
|
+ Full Color as many colors as local screen allows.
|
|
+ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.
|
|
+ 16 bit color (BGR565) ~ -16bpp / -bgr565
|
|
+ 8 bit color (BGR233) ~ -bgr233
|
|
+ 256 colors ~ -bgr233 default # of colors.
|
|
+ 64 colors ~ -bgr222 / -use64
|
|
+ 8 colors ~ -bgr111 / -use8
|
|
+
|
|
+ UltraVNC Extensions:
|
|
+ Disable Remote Input Ultravnc ext. Try to prevent input and
|
|
+ viewing of monitor at physical display.
|
|
+ Single Window Ultravnc ext. Grab and view a single window.
|
|
+ (click on the window you want).
|
|
+ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.
|
|
+ prompt is from the terminal.
|
|
+ Text Chat Ultravnc ext. Do Text Chat.
|
|
+
|
|
+ Note: the Ultravnc extensions only apply to servers that support
|
|
+ them. x11vnc/libvncserver supports some of them.
|
|
+
|
|
+.SH ENCODINGS
|
|
+The server supplies information in whatever format is desired by the
|
|
+client, in order to make the client as easy as possible to implement.
|
|
+If the client represents itself as able to use multiple formats, the
|
|
+server will choose one.
|
|
+
|
|
+.I Pixel format
|
|
+refers to the representation of an individual pixel. The most common
|
|
+formats are 24 and 16 bit "true\-color" values, and 8\-bit "color map"
|
|
+representations, where an arbitrary map converts the color number to
|
|
+RGB values.
|
|
+
|
|
+.I Encoding
|
|
+refers to how a rectangle of pixels are sent (all pixel information in
|
|
+VNC is sent as rectangles). All rectangles come with a header giving
|
|
+the location and size of the rectangle and an encoding type used by
|
|
+the data which follows. These types are listed below.
|
|
+.TP
|
|
+.B Raw
|
|
+The raw encoding simply sends width*height pixel values. All clients
|
|
+are required to support this encoding type. Raw is also the fastest
|
|
+when the server and viewer are on the same machine, as the connection
|
|
+speed is essentially infinite and raw encoding minimizes processing
|
|
+time.
|
|
+.TP
|
|
+.B CopyRect
|
|
+The Copy Rectangle encoding is efficient when something is being
|
|
+moved; the only data sent is the location of a rectangle from which
|
|
+data should be copied to the current location. Copyrect could also be
|
|
+used to efficiently transmit a repeated pattern.
|
|
+.TP
|
|
+.B RRE
|
|
+The Rise\-and\-Run\-length\-Encoding is basically a 2D version of
|
|
+run\-length encoding (RLE). In this encoding, a sequence of identical
|
|
+pixels are compressed to a single value and repeat count. In VNC, this
|
|
+is implemented with a background color, and then specifications of an
|
|
+arbitrary number of subrectangles and color for each. This is an
|
|
+efficient encoding for large blocks of constant color.
|
|
+.TP
|
|
+.B CoRRE
|
|
+This is a minor variation on RRE, using a maximum of 255x255 pixel
|
|
+rectangles. This allows for single\-byte values to be used, reducing
|
|
+packet size. This is in general more efficient, because the savings
|
|
+from sending 1\-byte values generally outweighs the losses from the
|
|
+(relatively rare) cases where very large regions are painted the same
|
|
+color.
|
|
+.TP
|
|
+.B Hextile
|
|
+Here, rectangles are split up in to 16x16 tiles, which are sent in a
|
|
+predetermined order. The data within the tiles is sent either raw or
|
|
+as a variant on RRE. Hextile encoding is usually the best choice for
|
|
+using in high\-speed network environments (e.g. Ethernet local\-area
|
|
+networks).
|
|
+.TP
|
|
+.B Zlib
|
|
+Zlib is a very simple encoding that uses zlib library to compress raw
|
|
+pixel data. This encoding achieves good compression, but consumes a
|
|
+lot of CPU time. Support for this encoding is provided for
|
|
+compatibility with VNC servers that might not understand Tight
|
|
+encoding which is more efficient than Zlib in nearly all real\-life
|
|
+situations.
|
|
+.TP
|
|
+.B Tight
|
|
+Like Zlib encoding, Tight encoding uses zlib library to compress the
|
|
+pixel data, but it pre\-processes data to maximize compression ratios,
|
|
+and to minimize CPU usage on compression. Also, JPEG compression may
|
|
+be used to encode color\-rich screen areas (see the description of
|
|
+\-quality and \-nojpeg options above). Tight encoding is usually the
|
|
+best choice for low\-bandwidth network environments (e.g. slow modem
|
|
+connections).
|
|
+.SH RESOURCES
|
|
+X resources that \fBvncviewer\fR knows about, aside from the
|
|
+normal Xt resources, are as follows:
|
|
+.TP
|
|
+.B shareDesktop
|
|
+Equivalent of \fB\-shared\fR/\fB\-noshared\fR options. Default true.
|
|
+.TP
|
|
+.B viewOnly
|
|
+Equivalent of \fB\-viewonly\fR option. Default false.
|
|
+.TP
|
|
+.B fullScreen
|
|
+Equivalent of \fB\-fullscreen\fR option. Default false.
|
|
+.TP
|
|
+.B grabKeyboard
|
|
+Grab keyboard in full-screen mode. This can help to solve problems
|
|
+with losing keyboard focus. Default false.
|
|
+.TP
|
|
+.B raiseOnBeep
|
|
+Equivalent of \fB\-noraiseonbeep\fR option, when set to false. Default
|
|
+true.
|
|
+.TP
|
|
+.B passwordFile
|
|
+Equivalent of \fB\-passwd\fR option.
|
|
+.TP
|
|
+.B userLogin
|
|
+Equivalent of \fB\-user\fR option.
|
|
+.TP
|
|
+.B passwordDialog
|
|
+Whether to use a dialog box to get the password (true) or get it from
|
|
+the tty (false). Irrelevant if \fBpasswordFile\fR is set. Default
|
|
+false.
|
|
+.TP
|
|
+.B encodings
|
|
+Equivalent of \fB\-encodings\fR option.
|
|
+.TP
|
|
+.B compressLevel
|
|
+Equivalent of \fB\-compresslevel\fR option (TightVNC\-specific).
|
|
+.TP
|
|
+.B qualityLevel
|
|
+Equivalent of \fB\-quality\fR option (TightVNC\-specific).
|
|
+.TP
|
|
+.B enableJPEG
|
|
+Equivalent of \fB\-nojpeg\fR option, when set to false. Default true.
|
|
+.TP
|
|
+.B useRemoteCursor
|
|
+Equivalent of \fB\-nocursorshape\fR option, when set to false
|
|
+(TightVNC\-specific). Default true.
|
|
+.TP
|
|
+.B useBGR233
|
|
+Equivalent of \fB\-bgr233\fR option. Default false.
|
|
+.TP
|
|
+.B nColours
|
|
+When using BGR233, try to allocate this many "exact" colors from the
|
|
+BGR233 color cube. When using a shared colormap, setting this resource
|
|
+lower leaves more colors for other X clients. Irrelevant when using
|
|
+truecolor. Default is 256 (i.e. all of them).
|
|
+.TP
|
|
+.B useSharedColours
|
|
+If the number of "exact" BGR233 colors successfully allocated is less
|
|
+than 256 then the rest are filled in using the "nearest" colors
|
|
+available. This resource says whether to only use the "exact" BGR233
|
|
+colors for this purpose, or whether to use other clients' "shared"
|
|
+colors as well. Default true (i.e. use other clients' colors).
|
|
+.TP
|
|
+.B forceOwnCmap
|
|
+Equivalent of \fB\-owncmap\fR option. Default false.
|
|
+.TP
|
|
+.B forceTrueColour
|
|
+Equivalent of \fB\-truecolour\fR option. Default false.
|
|
+.TP
|
|
+.B requestedDepth
|
|
+Equivalent of \fB\-depth\fR option.
|
|
+.TP
|
|
+.B useSharedMemory
|
|
+Use MIT shared memory extension if on the same machine as the X
|
|
+server. Default true.
|
|
+.TP
|
|
+.B wmDecorationWidth, wmDecorationHeight
|
|
+The total width and height taken up by window manager decorations.
|
|
+This is used to calculate the maximum size of the VNC viewer window.
|
|
+Default is width 4, height 24.
|
|
+.TP
|
|
+.B bumpScrollTime, bumpScrollPixels
|
|
+When in full screen mode and the VNC desktop is bigger than the X
|
|
+display, scrolling happens whenever the mouse hits the edge of the
|
|
+screen. The maximum speed of scrolling is bumpScrollPixels pixels
|
|
+every bumpScrollTime milliseconds. The actual speed of scrolling will
|
|
+be slower than this, of course, depending on how fast your machine is.
|
|
+Default 20 pixels every 25 milliseconds.
|
|
+.TP
|
|
+.B popupButtonCount
|
|
+The number of buttons in the popup window. See the README file for
|
|
+more information on how to customize the buttons.
|
|
+.TP
|
|
+.B debug
|
|
+For debugging. Default false.
|
|
+.TP
|
|
+.B rawDelay, copyRectDelay
|
|
+For debugging, see the README file for details. Default 0 (off).
|
|
+.SH ENVIRONMENT
|
|
+When started with the \fB\-via\fR option, vncviewer reads the
|
|
+\fBVNC_VIA_CMD\fR environment variable, expands patterns beginning
|
|
+with the "%" character, and executes result as a command assuming that
|
|
+it would create TCP tunnel that should be used for VNC connection. If
|
|
+not set, this environment variable defaults to "/usr/bin/ssh -f -L
|
|
+%L:%H:%R %G sleep 20".
|
|
+
|
|
+The following patterns are recognized in the \fBVNC_VIA_CMD\fR (note
|
|
+that all the patterns %G, %H, %L and %R must be present in the command
|
|
+template):
|
|
+.TP
|
|
+.B %%
|
|
+A literal "%";
|
|
+.TP
|
|
+.B %G
|
|
+gateway host name;
|
|
+.TP
|
|
+.B %H
|
|
+remote VNC host name, as known to the gateway;
|
|
+.TP
|
|
+.B %L
|
|
+local TCP port number;
|
|
+.TP
|
|
+.B %R
|
|
+remote TCP port number.
|
|
+.SH SEE ALSO
|
|
+\fBvncserver\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1),
|
|
+\fBvncconnect\fR(1), \fBssh\fR(1)
|
|
+.SH AUTHORS
|
|
+Original VNC was developed in AT&T Laboratories Cambridge. TightVNC
|
|
+additions was implemented by Constantin Kaplinsky. Many other people
|
|
+participated in development, testing and support.
|
|
+
|
|
+\fBMan page authors:\fR
|
|
+.br
|
|
+Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>,
|
|
+.br
|
|
+Terran Melconian <terran@consistent.org>,
|
|
+.br
|
|
+Tim Waugh <twaugh@redhat.com>,
|
|
+.br
|
|
+Constantin Kaplinsky <const@ce.cctpu.edu.ru>
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncviewer/vncviewer.h
|
|
--- vnc_unixsrc.orig/vncviewer/vncviewer.h 2004-03-11 13:14:40.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/vncviewer.h 2007-05-20 18:17:54.000000000 -0400
|
|
@@ -68,51 +68,71 @@
|
|
/* argsresources.c */
|
|
|
|
typedef struct {
|
|
- Bool shareDesktop;
|
|
- Bool viewOnly;
|
|
- Bool fullScreen;
|
|
- Bool grabKeyboard;
|
|
- Bool raiseOnBeep;
|
|
-
|
|
- String encodingsString;
|
|
-
|
|
- Bool useBGR233;
|
|
- int nColours;
|
|
- Bool useSharedColours;
|
|
- Bool forceOwnCmap;
|
|
- Bool forceTrueColour;
|
|
- int requestedDepth;
|
|
-
|
|
- Bool useShm;
|
|
-
|
|
- int wmDecorationWidth;
|
|
- int wmDecorationHeight;
|
|
-
|
|
- char *userLogin;
|
|
-
|
|
- char *passwordFile;
|
|
- Bool passwordDialog;
|
|
-
|
|
- int rawDelay;
|
|
- int copyRectDelay;
|
|
-
|
|
- Bool debug;
|
|
-
|
|
- int popupButtonCount;
|
|
-
|
|
- int bumpScrollTime;
|
|
- int bumpScrollPixels;
|
|
-
|
|
- int compressLevel;
|
|
- int qualityLevel;
|
|
- Bool enableJPEG;
|
|
- Bool useRemoteCursor;
|
|
- Bool useX11Cursor;
|
|
- Bool autoPass;
|
|
+ Bool shareDesktop;
|
|
+ Bool viewOnly;
|
|
+ Bool fullScreen;
|
|
+ Bool grabKeyboard;
|
|
+ Bool raiseOnBeep;
|
|
+
|
|
+ String encodingsString;
|
|
+
|
|
+ int useBGR233;
|
|
+ int nColours;
|
|
+ Bool useSharedColours;
|
|
+ Bool forceOwnCmap;
|
|
+ Bool forceTrueColour;
|
|
+ int requestedDepth;
|
|
+ Bool useBGR565;
|
|
+ Bool useGreyScale;
|
|
+
|
|
+ Bool grabAll;
|
|
+ Bool useBackingstore;
|
|
+ Bool overrideRedir;
|
|
+ Bool popupFix;
|
|
+
|
|
+ Bool useShm;
|
|
+ Bool termChat;
|
|
+
|
|
+ int wmDecorationWidth;
|
|
+ int wmDecorationHeight;
|
|
+
|
|
+ char *userLogin;
|
|
+
|
|
+ char *passwordFile;
|
|
+ Bool passwordDialog;
|
|
+
|
|
+ int rawDelay;
|
|
+ int copyRectDelay;
|
|
+
|
|
+ int yCrop;
|
|
+ int sbWidth;
|
|
+ Bool useCursorAlpha;
|
|
+ Bool useRawLocal;
|
|
+
|
|
+ Bool debug;
|
|
+
|
|
+ int popupButtonCount;
|
|
+
|
|
+ int bumpScrollTime;
|
|
+ int bumpScrollPixels;
|
|
+
|
|
+ int compressLevel;
|
|
+ int qualityLevel;
|
|
+ Bool enableJPEG;
|
|
+ Bool useRemoteCursor;
|
|
+ Bool useX11Cursor;
|
|
+ Bool useBell;
|
|
+ Bool autoPass;
|
|
+
|
|
+ Bool serverInput;
|
|
+ Bool singleWindow;
|
|
+ int serverScale;
|
|
+ Bool chatActive;
|
|
|
|
} AppData;
|
|
|
|
extern AppData appData;
|
|
+extern AppData appDataNew;
|
|
|
|
extern char *fallback_resources[];
|
|
extern char vncServerHost[];
|
|
@@ -130,10 +150,11 @@
|
|
/* colour.c */
|
|
|
|
extern unsigned long BGR233ToPixel[];
|
|
+extern unsigned long BGR565ToPixel[];
|
|
|
|
extern Colormap cmap;
|
|
extern Visual *vis;
|
|
-extern unsigned int visdepth, visbpp;
|
|
+extern unsigned int visdepth, visbpp, isLSB;
|
|
|
|
extern void SetVisualAndCmap();
|
|
|
|
@@ -160,8 +181,14 @@
|
|
extern void SendRFBEvent(Widget w, XEvent *event, String *params,
|
|
Cardinal *num_params);
|
|
extern void CopyDataToScreen(char *buf, int x, int y, int width, int height);
|
|
+extern void FillScreen(int x, int y, int width, int height, unsigned long fill);
|
|
extern void SynchroniseScreen();
|
|
|
|
+extern void ReDoDesktop();
|
|
+extern void DesktopCursorOff();
|
|
+extern void put_image(int x1, int y1, int x2, int y2, int width, int height);
|
|
+extern void copy_rect(int x, int y, int width, int height, int src_x, int src_y);
|
|
+
|
|
/* dialogs.c */
|
|
|
|
extern void ServerDialogDone(Widget w, XEvent *event, String *params,
|
|
@@ -207,6 +234,10 @@
|
|
Cardinal *num_params);
|
|
extern void CreatePopup();
|
|
|
|
+extern void HideScaleN(Widget w, XEvent *event, String *params,
|
|
+ Cardinal *num_params);
|
|
+extern void CreateScaleN();
|
|
+
|
|
/* rfbproto.c */
|
|
|
|
extern int rfbsock;
|
|
@@ -229,6 +260,15 @@
|
|
extern Bool SendClientCutText(char *str, int len);
|
|
extern Bool HandleRFBServerMessage();
|
|
|
|
+extern Bool SendServerInput(Bool enabled);
|
|
+extern Bool SendSingleWindow(int x, int y);
|
|
+extern Bool SendServerScale(int n);
|
|
+
|
|
+extern Bool SendTextChat(char *str);
|
|
+extern Bool SendTextChatOpen(void);
|
|
+extern Bool SendTextChatClose(void);
|
|
+extern Bool SendTextChatFinish(void);
|
|
+
|
|
extern void PrintPixelFormat(rfbPixelFormat *format);
|
|
|
|
/* selection.c */
|
|
@@ -241,8 +281,9 @@
|
|
|
|
/* shm.c */
|
|
|
|
-extern XImage *CreateShmImage();
|
|
+extern XImage *CreateShmImage(int do_ycrop);
|
|
extern void ShmCleanup();
|
|
+extern Bool UsingShm();
|
|
|
|
/* sockets.c */
|
|
|
|
@@ -271,3 +312,48 @@
|
|
extern XtAppContext appContext;
|
|
extern Display* dpy;
|
|
extern Widget toplevel;
|
|
+
|
|
+extern void GotChatText(char *str, int len);
|
|
+
|
|
+extern void Toggle8bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void Toggle16bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleFullColor(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void Toggle256Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void Toggle64Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void Toggle8Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleGreyScale(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleTightZRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleViewOnly(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleJPEG(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleCursorShape(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleCursorAlpha(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleX11Cursor(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleBell(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleRawLocal(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleServerInput(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleSingleWindow(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void DoServerScale(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ShowScaleN(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetScaleN(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleTextChat(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void ToggleTermTextChat(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+
|
|
+extern void SetViewOnlyState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetNOJPEGState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void Set8bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void Set16bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetFullColorState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void Set256ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void Set64ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void Set8ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetGreyScaleState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetZRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetCursorShapeState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetCursorAlphaState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetX11CursorState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetBellState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetRawLocalState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetServerInputState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetSingleWindowState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetTextChatState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
+extern void SetTermTextChatState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vncviewer/vncviewer.man
|
|
--- vnc_unixsrc.orig/vncviewer/vncviewer.man 2004-03-11 13:14:40.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/vncviewer.man 2007-05-21 11:29:52.000000000 -0400
|
|
@@ -168,6 +168,130 @@
|
|
\fB\-autopass\fR
|
|
Read a plain-text password from stdin. This option affects only the
|
|
standard VNC authentication.
|
|
+
|
|
+.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS
|
|
+.TP
|
|
+Enhanced TightVNC Viewer (SSVNC) web page is located at:
|
|
+.TP
|
|
+http://www.karlrunge.com/x11vnc/ssvnc.html
|
|
+.TP
|
|
+Note: ZRLE encoding is now supported.
|
|
+.TP
|
|
+Note: F9 is shortcut to Toggle FullScreen mode.
|
|
+.TP
|
|
+\fB\-use64\fR
|
|
+In \fB\-bgr233\fR mode, use 64 colors instead of 256.
|
|
+.TP
|
|
+\fB\-bgr222\fR
|
|
+Same as \fB\-use64\fR.
|
|
+.TP
|
|
+\fB\-use8\fR
|
|
+In \fB\-bgr233\fR mode, use 8 colors instead of 256.
|
|
+.TP
|
|
+\fB\-bgr111\fR
|
|
+Same as \fB\-use8\fR.
|
|
+.TP
|
|
+\fB\-16bpp\fR
|
|
+If the vnc viewer X display is depth 24 at 32bpp
|
|
+request a 16bpp format from the VNC server to cut
|
|
+network traffic by up to 2X, then tranlate the
|
|
+pixels to 32bpp locally.
|
|
+.TP
|
|
+\fB\-bgr565\fR
|
|
+Same as \fB\-16bpp\fR.
|
|
+.TP
|
|
+\fB\-grey\fR
|
|
+Use a grey scale for the 16- and 8\fB\-bpp\fR modes.
|
|
+.TP
|
|
+\fB\-alpha\fR
|
|
+Use alphablending transparency for local cursors
|
|
+requires: x11vnc server, both client and server
|
|
+must be 32bpp and same endianness.
|
|
+.TP
|
|
+\fB\-ycrop\fR n
|
|
+Only show the top n rows of the framebuffer. For
|
|
+use with x11vnc \fB\-ncache\fR client caching option
|
|
+to help "hide" the pixel cache region.
|
|
+Use a negative value (e.g. \fB\-1\fR) for autodetection.
|
|
+Autodetection will always take place if the remote
|
|
+fb height is more than 2 times the width.
|
|
+.TP
|
|
+\fB\-sbwidth\fR n
|
|
+Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR),
|
|
+default is very narrow: 2 pixels, it is narrow to
|
|
+avoid distraction in \fB\-ycrop\fR mode.
|
|
+.TP
|
|
+\fB\-nobell\fR
|
|
+Disable bell.
|
|
+.TP
|
|
+\fB\-rawlocal\fR
|
|
+Prefer raw encoding for localhost, default is
|
|
+no, i.e. assumes you have a SSH tunnel instead.
|
|
+.TP
|
|
+\fB\-graball\fR
|
|
+Grab the entire X server when in fullscreen mode,
|
|
+needed by some old window managers like fvwm2.
|
|
+.TP
|
|
+\fB\-popupfix\fR
|
|
+Warp the popup back to the pointer position,
|
|
+needed by some old window managers like fvwm2.
|
|
+.TP
|
|
+\fB\-grabkbd\fR
|
|
+Grab the X keyboard when in fullscreen mode,
|
|
+needed by some window managers. Same as \fB\-grabkeyboard\fR.
|
|
+\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable.
|
|
+.TP
|
|
+\fB\-bs\fR, \fB\-nobs\fR
|
|
+Whether or not to use X server Backingstore for the
|
|
+main viewer window. The default is to not, mainly
|
|
+because most Linux, etc, systems X servers disable
|
|
+*all* Backingstore by default. To re\fB\-enable\fR it put
|
|
+Option "Backingstore"
|
|
+in the Device section of /etc/X11/xorg.conf.
|
|
+In \fB\-bs\fR mode with no X server backingstore, whenever an
|
|
+area of the screen is re\fB\-exposed\fR it must go out to the
|
|
+VNC server to retrieve the pixels. This is too slow.
|
|
+In \fB\-nobs\fR mode, memory is allocated by the viewer to
|
|
+provide its own backing of the main viewer window. This
|
|
+actually makes some activities faster (changes in large
|
|
+regions) but can appear to "flash" too much.
|
|
+.TP
|
|
+\fB\-noshm\fR
|
|
+Disable use of MIT shared memory extension (not recommended)
|
|
+.TP
|
|
+\fB\-termchat\fR
|
|
+Do the UltraVNC chat in the terminal vncviewer is in
|
|
+instead of in an independent window.
|
|
+.TP
|
|
+\fB New Popup actions:\fR
|
|
+
|
|
+ ViewOnly: ~ -viewonly
|
|
+ Disable Bell: ~ -nobell
|
|
+ Cursor Shape: ~ -nocursorshape
|
|
+ X11 Cursor: ~ -x11cursor
|
|
+ Cursor Alphablend: ~ -alpha
|
|
+ Toggle Tight/ZRLE: ~ -encodings ...
|
|
+ Disable JPEG: ~ -nojpeg
|
|
+ Full Color as many colors as local screen allows.
|
|
+ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.
|
|
+ 16 bit color (BGR565) ~ -16bpp / -bgr565
|
|
+ 8 bit color (BGR233) ~ -bgr233
|
|
+ 256 colors ~ -bgr233 default # of colors.
|
|
+ 64 colors ~ -bgr222 / -use64
|
|
+ 8 colors ~ -bgr111 / -use8
|
|
+
|
|
+ UltraVNC Extensions:
|
|
+ Disable Remote Input Ultravnc ext. Try to prevent input and
|
|
+ viewing of monitor at physical display.
|
|
+ Single Window Ultravnc ext. Grab and view a single window.
|
|
+ (click on the window you want).
|
|
+ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.
|
|
+ prompt is from the terminal.
|
|
+ Text Chat Ultravnc ext. Do Text Chat.
|
|
+
|
|
+ Note: the Ultravnc extensions only apply to servers that support
|
|
+ them. x11vnc/libvncserver supports some of them.
|
|
+
|
|
.SH ENCODINGS
|
|
The server supplies information in whatever format is desired by the
|
|
client, in order to make the client as easy as possible to implement.
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrle.c vnc_unixsrc/vncviewer/zrle.c
|
|
--- vnc_unixsrc.orig/vncviewer/zrle.c 2007-02-04 18:59:50.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/zrle.c 2007-02-17 22:36:37.000000000 -0500
|
|
@@ -0,0 +1,455 @@
|
|
+/*
|
|
+ * Copyright (C) 2005 Johannes E. Schindelin. All Rights Reserved.
|
|
+ *
|
|
+ * This is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This software 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 General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this software; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
+ * USA.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * zrle.c - handle zrle encoding.
|
|
+ *
|
|
+ * This file shouldn't be compiled directly. It is included multiple times by
|
|
+ * rfbproto.c, each time with a different definition of the macro BPP. For
|
|
+ * each value of BPP, this file defines a function which handles an zrle
|
|
+ * encoded rectangle with BPP bits per pixel.
|
|
+ */
|
|
+
|
|
+#ifndef REALBPP
|
|
+#define REALBPP BPP
|
|
+#endif
|
|
+
|
|
+#if !defined(UNCOMP) || UNCOMP==0
|
|
+#define HandleZRLE CONCAT2E(HandleZRLE,REALBPP)
|
|
+#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
|
|
+#elif UNCOMP>0
|
|
+#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Down)
|
|
+#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down)
|
|
+#else
|
|
+#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Up)
|
|
+#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up)
|
|
+#endif
|
|
+#undef CARDBPP
|
|
+#undef CARDREALBPP
|
|
+#define CARDBPP CONCAT2E(CARD, BPP)
|
|
+#define CARDREALBPP CONCAT2E(CARD,REALBPP)
|
|
+
|
|
+#define FillRectangle(x, y, w, h, color) \
|
|
+ { \
|
|
+ XGCValues _gcv; \
|
|
+ _gcv.foreground = color; \
|
|
+ if (!appData.useBackingstore) { \
|
|
+ FillScreen(x, y, w, h, _gcv.foreground); \
|
|
+ } else { \
|
|
+ XChangeGC(dpy, gc, GCForeground, &_gcv); \
|
|
+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \
|
|
+ } \
|
|
+ }
|
|
+
|
|
+static int HandleZRLETile(
|
|
+ unsigned char* buffer,size_t buffer_length,
|
|
+ int x,int y,int w,int h);
|
|
+
|
|
+static Bool
|
|
+HandleZRLE (int rx, int ry, int rw, int rh)
|
|
+{
|
|
+ rfbZRLEHeader header;
|
|
+ int remaining;
|
|
+ int inflateResult;
|
|
+ int toRead;
|
|
+ int min_buffer_size = rw * rh * (REALBPP / 8) * 2;
|
|
+
|
|
+ /* First make sure we have a large enough raw buffer to hold the
|
|
+ * decompressed data. In practice, with a fixed REALBPP, fixed frame
|
|
+ * buffer size and the first update containing the entire frame
|
|
+ * buffer, this buffer allocation should only happen once, on the
|
|
+ * first update.
|
|
+ */
|
|
+ if ( raw_buffer_size < min_buffer_size) {
|
|
+
|
|
+ if ( raw_buffer != NULL ) {
|
|
+
|
|
+ free( raw_buffer );
|
|
+
|
|
+ }
|
|
+
|
|
+ raw_buffer_size = min_buffer_size;
|
|
+ raw_buffer = (char*) malloc( raw_buffer_size );
|
|
+
|
|
+ }
|
|
+
|
|
+ if (!ReadFromRFBServer((char *)&header, sz_rfbZRLEHeader))
|
|
+ return False;
|
|
+
|
|
+ remaining = Swap32IfLE(header.length);
|
|
+
|
|
+ /* Need to initialize the decompressor state. */
|
|
+ decompStream.next_in = ( Bytef * )buffer;
|
|
+ decompStream.avail_in = 0;
|
|
+ decompStream.next_out = ( Bytef * )raw_buffer;
|
|
+ decompStream.avail_out = raw_buffer_size;
|
|
+ decompStream.data_type = Z_BINARY;
|
|
+
|
|
+ /* Initialize the decompression stream structures on the first invocation. */
|
|
+ if ( decompStreamInited == False ) {
|
|
+
|
|
+ inflateResult = inflateInit( &decompStream );
|
|
+
|
|
+ if ( inflateResult != Z_OK ) {
|
|
+ fprintf(stderr,
|
|
+ "inflateInit returned error: %d, msg: %s\n",
|
|
+ inflateResult,
|
|
+ decompStream.msg);
|
|
+ return False;
|
|
+ }
|
|
+
|
|
+ decompStreamInited = True;
|
|
+
|
|
+ }
|
|
+
|
|
+ inflateResult = Z_OK;
|
|
+
|
|
+ /* Process buffer full of data until no more to process, or
|
|
+ * some type of inflater error, or Z_STREAM_END.
|
|
+ */
|
|
+ while (( remaining > 0 ) &&
|
|
+ ( inflateResult == Z_OK )) {
|
|
+
|
|
+ if ( remaining > BUFFER_SIZE ) {
|
|
+ toRead = BUFFER_SIZE;
|
|
+ }
|
|
+ else {
|
|
+ toRead = remaining;
|
|
+ }
|
|
+
|
|
+ /* Fill the buffer, obtaining data from the server. */
|
|
+ if (!ReadFromRFBServer(buffer,toRead))
|
|
+ return False;
|
|
+
|
|
+ decompStream.next_in = ( Bytef * )buffer;
|
|
+ decompStream.avail_in = toRead;
|
|
+
|
|
+ /* Need to uncompress buffer full. */
|
|
+ inflateResult = inflate( &decompStream, Z_SYNC_FLUSH );
|
|
+
|
|
+ /* We never supply a dictionary for compression. */
|
|
+ if ( inflateResult == Z_NEED_DICT ) {
|
|
+ fprintf(stderr, "zlib inflate needs a dictionary!\n");
|
|
+ return False;
|
|
+ }
|
|
+ if ( inflateResult < 0 ) {
|
|
+ fprintf(stderr,
|
|
+ "zlib inflate returned error: %d, msg: %s\n",
|
|
+ inflateResult,
|
|
+ decompStream.msg);
|
|
+ return False;
|
|
+ }
|
|
+
|
|
+ /* Result buffer allocated to be at least large enough. We should
|
|
+ * never run out of space!
|
|
+ */
|
|
+ if (( decompStream.avail_in > 0 ) &&
|
|
+ ( decompStream.avail_out <= 0 )) {
|
|
+ fprintf(stderr, "zlib inflate ran out of space!\n");
|
|
+ return False;
|
|
+ }
|
|
+
|
|
+ remaining -= toRead;
|
|
+
|
|
+ } /* while ( remaining > 0 ) */
|
|
+
|
|
+ if ( inflateResult == Z_OK ) {
|
|
+ void* buf=raw_buffer;
|
|
+ int i,j;
|
|
+
|
|
+ remaining = raw_buffer_size-decompStream.avail_out;
|
|
+
|
|
+ for(j=0; j<rh; j+=rfbZRLETileHeight)
|
|
+ for(i=0; i<rw; i+=rfbZRLETileWidth) {
|
|
+ int subWidth=(i+rfbZRLETileWidth>rw)?rw-i:rfbZRLETileWidth;
|
|
+ int subHeight=(j+rfbZRLETileHeight>rh)?rh-j:rfbZRLETileHeight;
|
|
+ int result=HandleZRLETile(buf,remaining,rx+i,ry+j,subWidth,subHeight);
|
|
+
|
|
+ if(result<0) {
|
|
+ fprintf(stderr, "ZRLE decoding failed (%d)\n",result);
|
|
+return True;
|
|
+ return False;
|
|
+ }
|
|
+
|
|
+ buf+=result;
|
|
+ remaining-=result;
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+
|
|
+ fprintf(stderr,
|
|
+ "zlib inflate returned error: %d, msg: %s\n",
|
|
+ inflateResult,
|
|
+ decompStream.msg);
|
|
+ return False;
|
|
+
|
|
+ }
|
|
+
|
|
+ return True;
|
|
+}
|
|
+
|
|
+#if REALBPP!=BPP && defined(UNCOMP) && UNCOMP!=0
|
|
+#if UNCOMP>0
|
|
+#define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)>>UNCOMP)
|
|
+#else
|
|
+#define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)<<(-(UNCOMP)))
|
|
+#endif
|
|
+#else
|
|
+#define UncompressCPixel(pointer) (*(CARDBPP*)pointer)
|
|
+#endif
|
|
+
|
|
+static int HandleZRLETile(
|
|
+ unsigned char* buffer,size_t buffer_length,
|
|
+ int x,int y,int w,int h) {
|
|
+ unsigned char* buffer_copy = buffer;
|
|
+ unsigned char* buffer_end = buffer+buffer_length;
|
|
+ unsigned char type;
|
|
+
|
|
+ if(buffer_length<1)
|
|
+ return -2;
|
|
+
|
|
+ if (frameBufferLen < w * h * REALBPP/8) {
|
|
+ if(frameBuffer) {
|
|
+ free(frameBuffer);
|
|
+ }
|
|
+ frameBufferLen = w * h * REALBPP/8 * 2;
|
|
+ frameBuffer = (unsigned char *) malloc(frameBufferLen);
|
|
+ }
|
|
+
|
|
+ type = *buffer;
|
|
+ buffer++;
|
|
+ switch(type) {
|
|
+ case 0: /* raw */
|
|
+ {
|
|
+#if REALBPP!=BPP
|
|
+ int m0 = 0, i,j;
|
|
+
|
|
+ if(1+w*h*REALBPP/8>buffer_length) {
|
|
+ fprintf(stderr, "expected %d bytes, got only %d (%dx%d)\n",1+w*h*REALBPP/8,buffer_length,w,h);
|
|
+ return -3;
|
|
+ }
|
|
+
|
|
+ for(j=y*si.framebufferWidth; j<(y+h)*si.framebufferWidth; j+=si.framebufferWidth) {
|
|
+ for(i=x; i<x+w; i++,buffer+=REALBPP/8) {
|
|
+# if 0
|
|
+ ((CARDBPP*)frameBuffer)[j+i] = UncompressCPixel(buffer);
|
|
+ /* alt */
|
|
+ CARDBPP color = UncompressCPixel(buffer);
|
|
+ CopyDataToScreen((char *)&color, i, j/si.framebufferWidth, 1, 1);
|
|
+# else
|
|
+ ((CARDBPP*)frameBuffer)[m0++] = UncompressCPixel(buffer);
|
|
+# endif
|
|
+ }
|
|
+ }
|
|
+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
|
|
+if (0) fprintf(stderr, "cha1: %dx%d+%d+%d\n", w, h, x, y);
|
|
+
|
|
+#else
|
|
+# if 0
|
|
+ CopyRectangle(buffer, x, y, w, h);
|
|
+# else
|
|
+ CopyDataToScreen((char *)buffer, x, y, w, h);
|
|
+# endif
|
|
+ buffer+=w*h*REALBPP/8;
|
|
+#endif
|
|
+ break;
|
|
+ }
|
|
+ case 1: /* solid */
|
|
+ {
|
|
+ CARDBPP color = UncompressCPixel(buffer);
|
|
+
|
|
+ if(1+REALBPP/8>buffer_length)
|
|
+ return -4;
|
|
+
|
|
+ if ((BPP == 8 && appData.useBGR233) || (BPP == 16 && appData.useBGR565)) {
|
|
+ int m0;
|
|
+ for (m0=0; m0 < w*h; m0++) {
|
|
+ ((CARDBPP*)frameBuffer)[m0] = color;
|
|
+ }
|
|
+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
|
|
+ } else {
|
|
+ FillRectangle(x, y, w, h, color);
|
|
+ }
|
|
+if (0) fprintf(stderr, "cha2: %dx%d+%d+%d\n", w, h, x, y);
|
|
+
|
|
+ buffer+=REALBPP/8;
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ case 2 ... 127: /* packed Palette */
|
|
+ {
|
|
+ CARDBPP palette[16];
|
|
+ int m0, i,j,shift,
|
|
+ bpp=(type>4?(type>16?8:4):(type>2?2:1)),
|
|
+ mask=(1<<bpp)-1,
|
|
+ divider=(8/bpp);
|
|
+
|
|
+ if(1+type*REALBPP/8+((w+divider-1)/divider)*h>buffer_length)
|
|
+ return -5;
|
|
+
|
|
+ /* read palette */
|
|
+ for(i=0; i<type; i++,buffer+=REALBPP/8)
|
|
+ palette[i] = UncompressCPixel(buffer);
|
|
+
|
|
+ m0 = 0;
|
|
+ /* read palettized pixels */
|
|
+ for(j=y*si.framebufferWidth; j<(y+h)*si.framebufferWidth; j+=si.framebufferWidth) {
|
|
+ for(i=x,shift=8-bpp; i<x+w; i++) {
|
|
+# if 0
|
|
+ ((CARDBPP*)frameBuffer)[j+i] = palette[((*buffer)>>shift)&mask];
|
|
+ /* alt */
|
|
+ CARDBPP color = palette[((*buffer)>>shift)&mask];
|
|
+ CopyDataToScreen((char *)&color, i, j/si.framebufferWidth, 1, 1);
|
|
+# else
|
|
+ ((CARDBPP*)frameBuffer)[m0++] = palette[((*buffer)>>shift)&mask];
|
|
+# endif
|
|
+ shift-=bpp;
|
|
+ if(shift<0) {
|
|
+ shift=8-bpp;
|
|
+ buffer++;
|
|
+ }
|
|
+ }
|
|
+ if(shift<8-bpp)
|
|
+ buffer++;
|
|
+ }
|
|
+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
|
|
+if (0) fprintf(stderr, "cha3: %dx%d+%d+%d\n", w, h, x, y);
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ /* case 17 ... 127: not used, but valid */
|
|
+ case 128: /* plain RLE */
|
|
+ {
|
|
+ int m0=0, i=0,j=0;
|
|
+ while(j<h) {
|
|
+ int color,length;
|
|
+ /* read color */
|
|
+ if(buffer+REALBPP/8+1>buffer_end)
|
|
+ return -7;
|
|
+ color = UncompressCPixel(buffer);
|
|
+ buffer+=REALBPP/8;
|
|
+ /* read run length */
|
|
+ length=1;
|
|
+ while(*buffer==0xff) {
|
|
+ if(buffer+1>=buffer_end)
|
|
+ return -8;
|
|
+ length+=*buffer;
|
|
+ buffer++;
|
|
+ }
|
|
+ length+=*buffer;
|
|
+ buffer++;
|
|
+ while(j<h && length>0) {
|
|
+# if 0
|
|
+ ((CARDBPP*)frameBuffer)[(y+j)*si.framebufferWidth+x+i] = color;
|
|
+ /* alt */
|
|
+ CopyDataToScreen((char *)&color, x+i, y+j, 1, 1);
|
|
+# else
|
|
+ ((CARDBPP*)frameBuffer)[m0++] = color;
|
|
+# endif
|
|
+ length--;
|
|
+ i++;
|
|
+ if(i>=w) {
|
|
+ i=0;
|
|
+ j++;
|
|
+ }
|
|
+ }
|
|
+ if(length>0)
|
|
+ fprintf(stderr, "Warning: possible ZRLE corruption\n");
|
|
+ }
|
|
+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
|
|
+if (0) fprintf(stderr, "cha4: %dx%d+%d+%d\n", w, h, x, y);
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ case 129: /* unused */
|
|
+ {
|
|
+ return -8;
|
|
+ }
|
|
+ case 130 ... 255: /* palette RLE */
|
|
+ {
|
|
+ CARDBPP palette[128];
|
|
+ int m0 = 0, i,j;
|
|
+
|
|
+ if(2+(type-128)*REALBPP/8>buffer_length)
|
|
+ return -9;
|
|
+
|
|
+ /* read palette */
|
|
+ for(i=0; i<type-128; i++,buffer+=REALBPP/8)
|
|
+ palette[i] = UncompressCPixel(buffer);
|
|
+ /* read palettized pixels */
|
|
+ i=j=0;
|
|
+ while(j<h) {
|
|
+ int color,length;
|
|
+ /* read color */
|
|
+ if(buffer>=buffer_end)
|
|
+ return -10;
|
|
+ color = palette[(*buffer)&0x7f];
|
|
+ length=1;
|
|
+ if(*buffer&0x80) {
|
|
+ if(buffer+1>=buffer_end)
|
|
+ return -11;
|
|
+ buffer++;
|
|
+ /* read run length */
|
|
+ while(*buffer==0xff) {
|
|
+ if(buffer+1>=buffer_end)
|
|
+ return -8;
|
|
+ length+=*buffer;
|
|
+ buffer++;
|
|
+ }
|
|
+ length+=*buffer;
|
|
+ }
|
|
+ buffer++;
|
|
+ while(j<h && length>0) {
|
|
+# if 0
|
|
+ ((CARDBPP*)frameBuffer)[(y+j)*si.framebufferWidth+x+i] = color;
|
|
+ /* alt */
|
|
+ CopyDataToScreen((char *)&color, x+i, y+j, 1, 1);
|
|
+# else
|
|
+ ((CARDBPP*)frameBuffer)[m0++] = color;
|
|
+# endif
|
|
+ length--;
|
|
+ i++;
|
|
+ if(i>=w) {
|
|
+ i=0;
|
|
+ j++;
|
|
+ }
|
|
+ }
|
|
+ if(length>0)
|
|
+ fprintf(stderr, "Warning: possible ZRLE corruption\n");
|
|
+ }
|
|
+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
|
|
+if (0) fprintf(stderr, "cha5: %dx%d+%d+%d\n", w, h, x, y);
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return buffer-buffer_copy;
|
|
+}
|
|
+
|
|
+#undef CARDBPP
|
|
+#undef CARDREALBPP
|
|
+#undef HandleZRLE
|
|
+#undef HandleZRLETile
|
|
+#undef UncompressCPixel
|
|
+#undef REALBPP
|
|
+
|
|
+#undef UNCOMP
|
|
+
|
|
+#undef FillRectangle
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrleencodetemplate.c vnc_unixsrc/vncviewer/zrleencodetemplate.c
|
|
--- vnc_unixsrc.orig/vncviewer/zrleencodetemplate.c 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/zrleencodetemplate.c 2007-02-04 23:18:09.000000000 -0500
|
|
@@ -0,0 +1,317 @@
|
|
+/*
|
|
+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
|
|
+ * Copyright (C) 2003 Sun Microsystems, Inc.
|
|
+ *
|
|
+ * This is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This software 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 General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this software; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
+ * USA.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Before including this file, you must define a number of CPP macros.
|
|
+ *
|
|
+ * BPP should be 8, 16 or 32 depending on the bits per pixel.
|
|
+ * GET_IMAGE_INTO_BUF should be some code which gets a rectangle of pixel data
|
|
+ * into the given buffer. EXTRA_ARGS can be defined to pass any other
|
|
+ * arguments needed by GET_IMAGE_INTO_BUF.
|
|
+ *
|
|
+ * Note that the buf argument to ZRLE_ENCODE needs to be at least one pixel
|
|
+ * bigger than the largest tile of pixel data, since the ZRLE encoding
|
|
+ * algorithm writes to the position one past the end of the pixel data.
|
|
+ */
|
|
+
|
|
+#include "zrleoutstream.h"
|
|
+#include "zrlepalettehelper.h"
|
|
+#include <assert.h>
|
|
+
|
|
+/* __RFB_CONCAT2 concatenates its two arguments. __RFB_CONCAT2E does the same
|
|
+ but also expands its arguments if they are macros */
|
|
+
|
|
+#ifndef __RFB_CONCAT2E
|
|
+#define __RFB_CONCAT2(a,b) a##b
|
|
+#define __RFB_CONCAT2E(a,b) __RFB_CONCAT2(a,b)
|
|
+#endif
|
|
+
|
|
+#ifndef __RFB_CONCAT3E
|
|
+#define __RFB_CONCAT3(a,b,c) a##b##c
|
|
+#define __RFB_CONCAT3E(a,b,c) __RFB_CONCAT3(a,b,c)
|
|
+#endif
|
|
+
|
|
+#undef END_FIX
|
|
+#if ZYWRLE_ENDIAN == ENDIAN_LITTLE
|
|
+# define END_FIX LE
|
|
+#elif ZYWRLE_ENDIAN == ENDIAN_BIG
|
|
+# define END_FIX BE
|
|
+#else
|
|
+# define END_FIX NE
|
|
+#endif
|
|
+
|
|
+#ifdef CPIXEL
|
|
+#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP)
|
|
+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,CPIXEL)
|
|
+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,CPIXEL,END_FIX)
|
|
+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,CPIXEL,END_FIX)
|
|
+#define BPPOUT 24
|
|
+#elif BPP==15
|
|
+#define PIXEL_T __RFB_CONCAT2E(zrle_U,16)
|
|
+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,16)
|
|
+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX)
|
|
+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX)
|
|
+#define BPPOUT 16
|
|
+#else
|
|
+#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP)
|
|
+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,BPP)
|
|
+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX)
|
|
+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX)
|
|
+#define BPPOUT BPP
|
|
+#endif
|
|
+
|
|
+#ifndef ZRLE_ONCE
|
|
+#define ZRLE_ONCE
|
|
+
|
|
+static const int bitsPerPackedPixel[] = {
|
|
+ 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
|
|
+};
|
|
+
|
|
+int zywrle_level;
|
|
+int zywrleBuf[rfbZRLETileWidth*rfbZRLETileHeight];
|
|
+
|
|
+static zrlePaletteHelper paletteHelper;
|
|
+
|
|
+#endif /* ZRLE_ONCE */
|
|
+
|
|
+void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os);
|
|
+
|
|
+#if BPP!=8
|
|
+#define ZYWRLE_ENCODE
|
|
+#include "zywrletemplate.c"
|
|
+#endif
|
|
+
|
|
+static void ZRLE_ENCODE (int x, int y, int w, int h,
|
|
+ zrleOutStream* os, void* buf
|
|
+ EXTRA_ARGS
|
|
+ )
|
|
+{
|
|
+ int ty;
|
|
+ for (ty = y; ty < y+h; ty += rfbZRLETileHeight) {
|
|
+ int tx, th = rfbZRLETileHeight;
|
|
+ if (th > y+h-ty) th = y+h-ty;
|
|
+ for (tx = x; tx < x+w; tx += rfbZRLETileWidth) {
|
|
+ int tw = rfbZRLETileWidth;
|
|
+ if (tw > x+w-tx) tw = x+w-tx;
|
|
+
|
|
+ GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf);
|
|
+
|
|
+ ZRLE_ENCODE_TILE((PIXEL_T*)buf, tw, th, os);
|
|
+ }
|
|
+ }
|
|
+ zrleOutStreamFlush(os);
|
|
+}
|
|
+
|
|
+
|
|
+void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os)
|
|
+{
|
|
+ /* First find the palette and the number of runs */
|
|
+
|
|
+ zrlePaletteHelper *ph;
|
|
+
|
|
+ int runs = 0;
|
|
+ int singlePixels = 0;
|
|
+
|
|
+ rfbBool useRle;
|
|
+ rfbBool usePalette;
|
|
+
|
|
+ int estimatedBytes;
|
|
+ int plainRleBytes;
|
|
+ int i;
|
|
+
|
|
+ PIXEL_T* ptr = data;
|
|
+ PIXEL_T* end = ptr + h * w;
|
|
+ *end = ~*(end-1); /* one past the end is different so the while loop ends */
|
|
+
|
|
+ ph = &paletteHelper;
|
|
+ zrlePaletteHelperInit(ph);
|
|
+
|
|
+ while (ptr < end) {
|
|
+ PIXEL_T pix = *ptr;
|
|
+ if (*++ptr != pix) {
|
|
+ singlePixels++;
|
|
+ } else {
|
|
+ while (*++ptr == pix) ;
|
|
+ runs++;
|
|
+ }
|
|
+ zrlePaletteHelperInsert(ph, pix);
|
|
+ }
|
|
+
|
|
+ /* Solid tile is a special case */
|
|
+
|
|
+ if (ph->size == 1) {
|
|
+ zrleOutStreamWriteU8(os, 1);
|
|
+ zrleOutStreamWRITE_PIXEL(os, ph->palette[0]);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* Try to work out whether to use RLE and/or a palette. We do this by
|
|
+ estimating the number of bytes which will be generated and picking the
|
|
+ method which results in the fewest bytes. Of course this may not result
|
|
+ in the fewest bytes after compression... */
|
|
+
|
|
+ useRle = FALSE;
|
|
+ usePalette = FALSE;
|
|
+
|
|
+ estimatedBytes = w * h * (BPPOUT/8); /* start assuming raw */
|
|
+
|
|
+#if BPP!=8
|
|
+ if( (zywrle_level>0)&& !(zywrle_level & 0x80) ){
|
|
+ estimatedBytes >>= zywrle_level;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ plainRleBytes = ((BPPOUT/8)+1) * (runs + singlePixels);
|
|
+
|
|
+ if (plainRleBytes < estimatedBytes) {
|
|
+ useRle = TRUE;
|
|
+ estimatedBytes = plainRleBytes;
|
|
+ }
|
|
+
|
|
+ if (ph->size < 128) {
|
|
+ int paletteRleBytes = (BPPOUT/8) * ph->size + 2 * runs + singlePixels;
|
|
+
|
|
+ if (paletteRleBytes < estimatedBytes) {
|
|
+ useRle = TRUE;
|
|
+ usePalette = TRUE;
|
|
+ estimatedBytes = paletteRleBytes;
|
|
+ }
|
|
+
|
|
+ if (ph->size < 17) {
|
|
+ int packedBytes = ((BPPOUT/8) * ph->size +
|
|
+ w * h * bitsPerPackedPixel[ph->size-1] / 8);
|
|
+
|
|
+ if (packedBytes < estimatedBytes) {
|
|
+ useRle = FALSE;
|
|
+ usePalette = TRUE;
|
|
+ estimatedBytes = packedBytes;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!usePalette) ph->size = 0;
|
|
+
|
|
+ zrleOutStreamWriteU8(os, (useRle ? 128 : 0) | ph->size);
|
|
+
|
|
+ for (i = 0; i < ph->size; i++) {
|
|
+ zrleOutStreamWRITE_PIXEL(os, ph->palette[i]);
|
|
+ }
|
|
+
|
|
+ if (useRle) {
|
|
+
|
|
+ PIXEL_T* ptr = data;
|
|
+ PIXEL_T* end = ptr + w * h;
|
|
+ PIXEL_T* runStart;
|
|
+ PIXEL_T pix;
|
|
+ while (ptr < end) {
|
|
+ int len;
|
|
+ runStart = ptr;
|
|
+ pix = *ptr++;
|
|
+ while (*ptr == pix && ptr < end)
|
|
+ ptr++;
|
|
+ len = ptr - runStart;
|
|
+ if (len <= 2 && usePalette) {
|
|
+ int index = zrlePaletteHelperLookup(ph, pix);
|
|
+ if (len == 2)
|
|
+ zrleOutStreamWriteU8(os, index);
|
|
+ zrleOutStreamWriteU8(os, index);
|
|
+ continue;
|
|
+ }
|
|
+ if (usePalette) {
|
|
+ int index = zrlePaletteHelperLookup(ph, pix);
|
|
+ zrleOutStreamWriteU8(os, index | 128);
|
|
+ } else {
|
|
+ zrleOutStreamWRITE_PIXEL(os, pix);
|
|
+ }
|
|
+ len -= 1;
|
|
+ while (len >= 255) {
|
|
+ zrleOutStreamWriteU8(os, 255);
|
|
+ len -= 255;
|
|
+ }
|
|
+ zrleOutStreamWriteU8(os, len);
|
|
+ }
|
|
+
|
|
+ } else {
|
|
+
|
|
+ /* no RLE */
|
|
+
|
|
+ if (usePalette) {
|
|
+ int bppp;
|
|
+ PIXEL_T* ptr = data;
|
|
+
|
|
+ /* packed pixels */
|
|
+
|
|
+ assert (ph->size < 17);
|
|
+
|
|
+ bppp = bitsPerPackedPixel[ph->size-1];
|
|
+
|
|
+ for (i = 0; i < h; i++) {
|
|
+ zrle_U8 nbits = 0;
|
|
+ zrle_U8 byte = 0;
|
|
+
|
|
+ PIXEL_T* eol = ptr + w;
|
|
+
|
|
+ while (ptr < eol) {
|
|
+ PIXEL_T pix = *ptr++;
|
|
+ zrle_U8 index = zrlePaletteHelperLookup(ph, pix);
|
|
+ byte = (byte << bppp) | index;
|
|
+ nbits += bppp;
|
|
+ if (nbits >= 8) {
|
|
+ zrleOutStreamWriteU8(os, byte);
|
|
+ nbits = 0;
|
|
+ }
|
|
+ }
|
|
+ if (nbits > 0) {
|
|
+ byte <<= 8 - nbits;
|
|
+ zrleOutStreamWriteU8(os, byte);
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+
|
|
+ /* raw */
|
|
+
|
|
+#if BPP!=8
|
|
+ if( (zywrle_level>0)&& !(zywrle_level & 0x80) ){
|
|
+ ZYWRLE_ANALYZE( data, data, w, h, w, zywrle_level, zywrleBuf );
|
|
+ zywrle_level |= 0x80;
|
|
+ ZRLE_ENCODE_TILE( data, w, h, os );
|
|
+ zywrle_level &= 0x7F;
|
|
+ }else
|
|
+#endif
|
|
+ {
|
|
+#ifdef CPIXEL
|
|
+ PIXEL_T *ptr;
|
|
+ for (ptr = data; ptr < data+w*h; ptr++) {
|
|
+ zrleOutStreamWRITE_PIXEL(os, *ptr);
|
|
+ }
|
|
+#else
|
|
+ zrleOutStreamWriteBytes(os, (zrle_U8 *)data, w*h*(BPP/8));
|
|
+#endif
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+#undef PIXEL_T
|
|
+#undef zrleOutStreamWRITE_PIXEL
|
|
+#undef ZRLE_ENCODE
|
|
+#undef ZRLE_ENCODE_TILE
|
|
+#undef ZYWRLE_ENCODE_TILE
|
|
+#undef BPPOUT
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrleoutstream.c vnc_unixsrc/vncviewer/zrleoutstream.c
|
|
--- vnc_unixsrc.orig/vncviewer/zrleoutstream.c 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/zrleoutstream.c 2005-05-15 10:57:54.000000000 -0400
|
|
@@ -0,0 +1,275 @@
|
|
+/*
|
|
+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
|
|
+ * Copyright (C) 2003 Sun Microsystems, Inc.
|
|
+ *
|
|
+ * This is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This software 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 General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this software; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
+ * USA.
|
|
+ */
|
|
+
|
|
+#include "zrleoutstream.h"
|
|
+#include <stdlib.h>
|
|
+
|
|
+#define ZRLE_IN_BUFFER_SIZE 16384
|
|
+#define ZRLE_OUT_BUFFER_SIZE 1024
|
|
+#undef ZRLE_DEBUG
|
|
+
|
|
+static rfbBool zrleBufferAlloc(zrleBuffer *buffer, int size)
|
|
+{
|
|
+ buffer->ptr = buffer->start = malloc(size);
|
|
+ if (buffer->start == NULL) {
|
|
+ buffer->end = NULL;
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ buffer->end = buffer->start + size;
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static void zrleBufferFree(zrleBuffer *buffer)
|
|
+{
|
|
+ if (buffer->start)
|
|
+ free(buffer->start);
|
|
+ buffer->start = buffer->ptr = buffer->end = NULL;
|
|
+}
|
|
+
|
|
+static rfbBool zrleBufferGrow(zrleBuffer *buffer, int size)
|
|
+{
|
|
+ int offset;
|
|
+
|
|
+ size += buffer->end - buffer->start;
|
|
+ offset = ZRLE_BUFFER_LENGTH (buffer);
|
|
+
|
|
+ buffer->start = realloc(buffer->start, size);
|
|
+ if (!buffer->start) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ buffer->end = buffer->start + size;
|
|
+ buffer->ptr = buffer->start + offset;
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+zrleOutStream *zrleOutStreamNew(void)
|
|
+{
|
|
+ zrleOutStream *os;
|
|
+
|
|
+ os = malloc(sizeof(zrleOutStream));
|
|
+ if (os == NULL)
|
|
+ return NULL;
|
|
+
|
|
+ if (!zrleBufferAlloc(&os->in, ZRLE_IN_BUFFER_SIZE)) {
|
|
+ free(os);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (!zrleBufferAlloc(&os->out, ZRLE_OUT_BUFFER_SIZE)) {
|
|
+ zrleBufferFree(&os->in);
|
|
+ free(os);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ os->zs.zalloc = Z_NULL;
|
|
+ os->zs.zfree = Z_NULL;
|
|
+ os->zs.opaque = Z_NULL;
|
|
+ if (deflateInit(&os->zs, Z_DEFAULT_COMPRESSION) != Z_OK) {
|
|
+ zrleBufferFree(&os->in);
|
|
+ free(os);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return os;
|
|
+}
|
|
+
|
|
+void zrleOutStreamFree (zrleOutStream *os)
|
|
+{
|
|
+ deflateEnd(&os->zs);
|
|
+ zrleBufferFree(&os->in);
|
|
+ zrleBufferFree(&os->out);
|
|
+ free(os);
|
|
+}
|
|
+
|
|
+rfbBool zrleOutStreamFlush(zrleOutStream *os)
|
|
+{
|
|
+ os->zs.next_in = os->in.start;
|
|
+ os->zs.avail_in = ZRLE_BUFFER_LENGTH (&os->in);
|
|
+
|
|
+#ifdef ZRLE_DEBUG
|
|
+ rfbLog("zrleOutStreamFlush: avail_in %d\n", os->zs.avail_in);
|
|
+#endif
|
|
+
|
|
+ while (os->zs.avail_in != 0) {
|
|
+ do {
|
|
+ int ret;
|
|
+
|
|
+ if (os->out.ptr >= os->out.end &&
|
|
+ !zrleBufferGrow(&os->out, os->out.end - os->out.start)) {
|
|
+ rfbLog("zrleOutStreamFlush: failed to grow output buffer\n");
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ os->zs.next_out = os->out.ptr;
|
|
+ os->zs.avail_out = os->out.end - os->out.ptr;
|
|
+
|
|
+#ifdef ZRLE_DEBUG
|
|
+ rfbLog("zrleOutStreamFlush: calling deflate, avail_in %d, avail_out %d\n",
|
|
+ os->zs.avail_in, os->zs.avail_out);
|
|
+#endif
|
|
+
|
|
+ if ((ret = deflate(&os->zs, Z_SYNC_FLUSH)) != Z_OK) {
|
|
+ rfbLog("zrleOutStreamFlush: deflate failed with error code %d\n", ret);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+#ifdef ZRLE_DEBUG
|
|
+ rfbLog("zrleOutStreamFlush: after deflate: %d bytes\n",
|
|
+ os->zs.next_out - os->out.ptr);
|
|
+#endif
|
|
+
|
|
+ os->out.ptr = os->zs.next_out;
|
|
+ } while (os->zs.avail_out == 0);
|
|
+ }
|
|
+
|
|
+ os->in.ptr = os->in.start;
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static int zrleOutStreamOverrun(zrleOutStream *os,
|
|
+ int size)
|
|
+{
|
|
+#ifdef ZRLE_DEBUG
|
|
+ rfbLog("zrleOutStreamOverrun\n");
|
|
+#endif
|
|
+
|
|
+ while (os->in.end - os->in.ptr < size && os->in.ptr > os->in.start) {
|
|
+ os->zs.next_in = os->in.start;
|
|
+ os->zs.avail_in = ZRLE_BUFFER_LENGTH (&os->in);
|
|
+
|
|
+ do {
|
|
+ int ret;
|
|
+
|
|
+ if (os->out.ptr >= os->out.end &&
|
|
+ !zrleBufferGrow(&os->out, os->out.end - os->out.start)) {
|
|
+ rfbLog("zrleOutStreamOverrun: failed to grow output buffer\n");
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ os->zs.next_out = os->out.ptr;
|
|
+ os->zs.avail_out = os->out.end - os->out.ptr;
|
|
+
|
|
+#ifdef ZRLE_DEBUG
|
|
+ rfbLog("zrleOutStreamOverrun: calling deflate, avail_in %d, avail_out %d\n",
|
|
+ os->zs.avail_in, os->zs.avail_out);
|
|
+#endif
|
|
+
|
|
+ if ((ret = deflate(&os->zs, 0)) != Z_OK) {
|
|
+ rfbLog("zrleOutStreamOverrun: deflate failed with error code %d\n", ret);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+#ifdef ZRLE_DEBUG
|
|
+ rfbLog("zrleOutStreamOverrun: after deflate: %d bytes\n",
|
|
+ os->zs.next_out - os->out.ptr);
|
|
+#endif
|
|
+
|
|
+ os->out.ptr = os->zs.next_out;
|
|
+ } while (os->zs.avail_out == 0);
|
|
+
|
|
+ /* output buffer not full */
|
|
+
|
|
+ if (os->zs.avail_in == 0) {
|
|
+ os->in.ptr = os->in.start;
|
|
+ } else {
|
|
+ /* but didn't consume all the data? try shifting what's left to the
|
|
+ * start of the buffer.
|
|
+ */
|
|
+ rfbLog("zrleOutStreamOverrun: out buf not full, but in data not consumed\n");
|
|
+ memmove(os->in.start, os->zs.next_in, os->in.ptr - os->zs.next_in);
|
|
+ os->in.ptr -= os->zs.next_in - os->in.start;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (size > os->in.end - os->in.ptr)
|
|
+ size = os->in.end - os->in.ptr;
|
|
+
|
|
+ return size;
|
|
+}
|
|
+
|
|
+static int zrleOutStreamCheck(zrleOutStream *os, int size)
|
|
+{
|
|
+ if (os->in.ptr + size > os->in.end) {
|
|
+ return zrleOutStreamOverrun(os, size);
|
|
+ }
|
|
+ return size;
|
|
+}
|
|
+
|
|
+void zrleOutStreamWriteBytes(zrleOutStream *os,
|
|
+ const zrle_U8 *data,
|
|
+ int length)
|
|
+{
|
|
+ const zrle_U8* dataEnd = data + length;
|
|
+ while (data < dataEnd) {
|
|
+ int n = zrleOutStreamCheck(os, dataEnd - data);
|
|
+ memcpy(os->in.ptr, data, n);
|
|
+ os->in.ptr += n;
|
|
+ data += n;
|
|
+ }
|
|
+}
|
|
+
|
|
+void zrleOutStreamWriteU8(zrleOutStream *os, zrle_U8 u)
|
|
+{
|
|
+ zrleOutStreamCheck(os, 1);
|
|
+ *os->in.ptr++ = u;
|
|
+}
|
|
+
|
|
+void zrleOutStreamWriteOpaque8(zrleOutStream *os, zrle_U8 u)
|
|
+{
|
|
+ zrleOutStreamCheck(os, 1);
|
|
+ *os->in.ptr++ = u;
|
|
+}
|
|
+
|
|
+void zrleOutStreamWriteOpaque16 (zrleOutStream *os, zrle_U16 u)
|
|
+{
|
|
+ zrleOutStreamCheck(os, 2);
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[0];
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[1];
|
|
+}
|
|
+
|
|
+void zrleOutStreamWriteOpaque32 (zrleOutStream *os, zrle_U32 u)
|
|
+{
|
|
+ zrleOutStreamCheck(os, 4);
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[0];
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[1];
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[2];
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[3];
|
|
+}
|
|
+
|
|
+void zrleOutStreamWriteOpaque24A(zrleOutStream *os, zrle_U32 u)
|
|
+{
|
|
+ zrleOutStreamCheck(os, 3);
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[0];
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[1];
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[2];
|
|
+}
|
|
+
|
|
+void zrleOutStreamWriteOpaque24B(zrleOutStream *os, zrle_U32 u)
|
|
+{
|
|
+ zrleOutStreamCheck(os, 3);
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[1];
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[2];
|
|
+ *os->in.ptr++ = ((zrle_U8*)&u)[3];
|
|
+}
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrleoutstream.h vnc_unixsrc/vncviewer/zrleoutstream.h
|
|
--- vnc_unixsrc.orig/vncviewer/zrleoutstream.h 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/zrleoutstream.h 2004-05-25 06:05:15.000000000 -0400
|
|
@@ -0,0 +1,62 @@
|
|
+/*
|
|
+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
|
|
+ * Copyright (C) 2003 Sun Microsystems, Inc.
|
|
+ *
|
|
+ * This is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This software 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 General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this software; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
+ * USA.
|
|
+ */
|
|
+
|
|
+#ifndef __ZRLE_OUT_STREAM_H__
|
|
+#define __ZRLE_OUT_STREAM_H__
|
|
+
|
|
+#include <zlib.h>
|
|
+#include "zrletypes.h"
|
|
+#include "rfb/rfb.h"
|
|
+
|
|
+typedef struct {
|
|
+ zrle_U8 *start;
|
|
+ zrle_U8 *ptr;
|
|
+ zrle_U8 *end;
|
|
+} zrleBuffer;
|
|
+
|
|
+typedef struct {
|
|
+ zrleBuffer in;
|
|
+ zrleBuffer out;
|
|
+
|
|
+ z_stream zs;
|
|
+} zrleOutStream;
|
|
+
|
|
+#define ZRLE_BUFFER_LENGTH(b) ((b)->ptr - (b)->start)
|
|
+
|
|
+zrleOutStream *zrleOutStreamNew (void);
|
|
+void zrleOutStreamFree (zrleOutStream *os);
|
|
+rfbBool zrleOutStreamFlush (zrleOutStream *os);
|
|
+void zrleOutStreamWriteBytes (zrleOutStream *os,
|
|
+ const zrle_U8 *data,
|
|
+ int length);
|
|
+void zrleOutStreamWriteU8 (zrleOutStream *os,
|
|
+ zrle_U8 u);
|
|
+void zrleOutStreamWriteOpaque8 (zrleOutStream *os,
|
|
+ zrle_U8 u);
|
|
+void zrleOutStreamWriteOpaque16 (zrleOutStream *os,
|
|
+ zrle_U16 u);
|
|
+void zrleOutStreamWriteOpaque32 (zrleOutStream *os,
|
|
+ zrle_U32 u);
|
|
+void zrleOutStreamWriteOpaque24A(zrleOutStream *os,
|
|
+ zrle_U32 u);
|
|
+void zrleOutStreamWriteOpaque24B(zrleOutStream *os,
|
|
+ zrle_U32 u);
|
|
+
|
|
+#endif /* __ZRLE_OUT_STREAM_H__ */
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrlepalettehelper.c vnc_unixsrc/vncviewer/zrlepalettehelper.c
|
|
--- vnc_unixsrc.orig/vncviewer/zrlepalettehelper.c 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/zrlepalettehelper.c 2004-05-25 06:05:15.000000000 -0400
|
|
@@ -0,0 +1,62 @@
|
|
+/*
|
|
+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
|
|
+ * Copyright (C) 2003 Sun Microsystems, Inc.
|
|
+ *
|
|
+ * This is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This software 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 General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this software; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
+ * USA.
|
|
+ */
|
|
+
|
|
+#include "zrlepalettehelper.h"
|
|
+#include <assert.h>
|
|
+#include <string.h>
|
|
+
|
|
+#define ZRLE_HASH(pix) (((pix) ^ ((pix) >> 17)) & 4095)
|
|
+
|
|
+void zrlePaletteHelperInit(zrlePaletteHelper *helper)
|
|
+{
|
|
+ memset(helper->palette, 0, sizeof(helper->palette));
|
|
+ memset(helper->index, 255, sizeof(helper->index));
|
|
+ memset(helper->key, 0, sizeof(helper->key));
|
|
+ helper->size = 0;
|
|
+}
|
|
+
|
|
+void zrlePaletteHelperInsert(zrlePaletteHelper *helper, zrle_U32 pix)
|
|
+{
|
|
+ if (helper->size < ZRLE_PALETTE_MAX_SIZE) {
|
|
+ int i = ZRLE_HASH(pix);
|
|
+
|
|
+ while (helper->index[i] != 255 && helper->key[i] != pix)
|
|
+ i++;
|
|
+ if (helper->index[i] != 255) return;
|
|
+
|
|
+ helper->index[i] = helper->size;
|
|
+ helper->key[i] = pix;
|
|
+ helper->palette[helper->size] = pix;
|
|
+ }
|
|
+ helper->size++;
|
|
+}
|
|
+
|
|
+int zrlePaletteHelperLookup(zrlePaletteHelper *helper, zrle_U32 pix)
|
|
+{
|
|
+ int i = ZRLE_HASH(pix);
|
|
+
|
|
+ assert(helper->size <= ZRLE_PALETTE_MAX_SIZE);
|
|
+
|
|
+ while (helper->index[i] != 255 && helper->key[i] != pix)
|
|
+ i++;
|
|
+ if (helper->index[i] != 255) return helper->index[i];
|
|
+
|
|
+ return -1;
|
|
+}
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrlepalettehelper.h vnc_unixsrc/vncviewer/zrlepalettehelper.h
|
|
--- vnc_unixsrc.orig/vncviewer/zrlepalettehelper.h 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/zrlepalettehelper.h 2004-05-25 06:05:15.000000000 -0400
|
|
@@ -0,0 +1,46 @@
|
|
+/*
|
|
+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
|
|
+ * Copyright (C) 2003 Sun Microsystems, Inc.
|
|
+ *
|
|
+ * This is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This software 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 General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this software; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
+ * USA.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * The PaletteHelper class helps us build up the palette from pixel data by
|
|
+ * storing a reverse index using a simple hash-table
|
|
+ */
|
|
+
|
|
+#ifndef __ZRLE_PALETTE_HELPER_H__
|
|
+#define __ZRLE_PALETTE_HELPER_H__
|
|
+
|
|
+#include "zrletypes.h"
|
|
+
|
|
+#define ZRLE_PALETTE_MAX_SIZE 127
|
|
+
|
|
+typedef struct {
|
|
+ zrle_U32 palette[ZRLE_PALETTE_MAX_SIZE];
|
|
+ zrle_U8 index[ZRLE_PALETTE_MAX_SIZE + 4096];
|
|
+ zrle_U32 key[ZRLE_PALETTE_MAX_SIZE + 4096];
|
|
+ int size;
|
|
+} zrlePaletteHelper;
|
|
+
|
|
+void zrlePaletteHelperInit (zrlePaletteHelper *helper);
|
|
+void zrlePaletteHelperInsert(zrlePaletteHelper *helper,
|
|
+ zrle_U32 pix);
|
|
+int zrlePaletteHelperLookup(zrlePaletteHelper *helper,
|
|
+ zrle_U32 pix);
|
|
+
|
|
+#endif /* __ZRLE_PALETTE_HELPER_H__ */
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrletypes.h vnc_unixsrc/vncviewer/zrletypes.h
|
|
--- vnc_unixsrc.orig/vncviewer/zrletypes.h 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/zrletypes.h 2004-05-25 06:05:15.000000000 -0400
|
|
@@ -0,0 +1,30 @@
|
|
+/*
|
|
+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
|
|
+ *
|
|
+ * This is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This software 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 General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this software; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
+ * USA.
|
|
+ */
|
|
+
|
|
+#ifndef __ZRLE_TYPES_H__
|
|
+#define __ZRLE_TYPES_H__
|
|
+
|
|
+typedef unsigned char zrle_U8;
|
|
+typedef unsigned short zrle_U16;
|
|
+typedef unsigned int zrle_U32;
|
|
+typedef signed char zrle_S8;
|
|
+typedef signed short zrle_S16;
|
|
+typedef signed int zrle_S32;
|
|
+
|
|
+#endif /* __ZRLE_TYPES_H__ */
|
|
diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zywrletemplate.c vnc_unixsrc/vncviewer/zywrletemplate.c
|
|
--- vnc_unixsrc.orig/vncviewer/zywrletemplate.c 1969-12-31 19:00:00.000000000 -0500
|
|
+++ vnc_unixsrc/vncviewer/zywrletemplate.c 2007-02-04 23:24:16.000000000 -0500
|
|
@@ -0,0 +1,804 @@
|
|
+
|
|
+/********************************************************************
|
|
+ * *
|
|
+ * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. *
|
|
+ * *
|
|
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
|
+ * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. *
|
|
+ * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
|
+ * *
|
|
+ * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 *
|
|
+ * BY Hitachi Systems & Services, Ltd. *
|
|
+ * (Noriaki Yamazaki, Research & Developement Center) * *
|
|
+ * *
|
|
+ ********************************************************************
|
|
+Redistribution and use in source and binary forms, with or without
|
|
+modification, are permitted provided that the following conditions
|
|
+are met:
|
|
+
|
|
+- Redistributions of source code must retain the above copyright
|
|
+notice, this list of conditions and the following disclaimer.
|
|
+
|
|
+- Redistributions in binary form must reproduce the above copyright
|
|
+notice, this list of conditions and the following disclaimer in the
|
|
+documentation and/or other materials provided with the distribution.
|
|
+
|
|
+- Neither the name of the Hitachi Systems & Services, Ltd. nor
|
|
+the names of its contributors may be used to endorse or promote
|
|
+products derived from this software without specific prior written
|
|
+permission.
|
|
+
|
|
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
|
|
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
+ ********************************************************************/
|
|
+
|
|
+//#define ZYWRLE_ENCODE
|
|
+//#define ZYWRLE_DECODE
|
|
+#define ZYWRLE_QUANTIZE
|
|
+
|
|
+//[References]
|
|
+// PLHarr:
|
|
+// Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy, "An Improved N-Bit to N-Bit Reversible Haar-Like Transform," Pacific Graphics 2004, October 2004, pp. 371-380.
|
|
+// EZW:
|
|
+// Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients, IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993).
|
|
+
|
|
+
|
|
+// Template Macro stuffs.
|
|
+#undef ZYWRLE_ANALYZE
|
|
+#undef ZYWRLE_SYNTHESIZE
|
|
+#define ZYWRLE_ANALYZE __RFB_CONCAT3E(zywrleAnalyze,BPP,END_FIX)
|
|
+#define ZYWRLE_SYNTHESIZE __RFB_CONCAT3E(zywrleSynthesize,BPP,END_FIX)
|
|
+
|
|
+#define ZYWRLE_RGBYUV __RFB_CONCAT3E(zywrleRGBYUV,BPP,END_FIX)
|
|
+#define ZYWRLE_YUVRGB __RFB_CONCAT3E(zywrleYUVRGB,BPP,END_FIX)
|
|
+#define ZYWRLE_YMASK __RFB_CONCAT2E(ZYWRLE_YMASK,BPP)
|
|
+#define ZYWRLE_UVMASK __RFB_CONCAT2E(ZYWRLE_UVMASK,BPP)
|
|
+#define ZYWRLE_LOAD_PIXEL __RFB_CONCAT2E(ZYWRLE_LOAD_PIXEL,BPP)
|
|
+#define ZYWRLE_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP)
|
|
+
|
|
+// Packing/Unpacking pixel stuffs.
|
|
+// Endian conversion stuffs.
|
|
+#undef S_0
|
|
+#undef S_1
|
|
+#undef L_0
|
|
+#undef L_1
|
|
+#undef L_2
|
|
+#if ZYWRLE_ENDIAN == ENDIAN_BIG
|
|
+# define S_0 1
|
|
+# define S_1 0
|
|
+# define L_0 3
|
|
+# define L_1 2
|
|
+# define L_2 1
|
|
+#else
|
|
+# define S_0 0
|
|
+# define S_1 1
|
|
+# define L_0 0
|
|
+# define L_1 1
|
|
+# define L_2 2
|
|
+#endif
|
|
+
|
|
+// Load/Save pixel stuffs.
|
|
+#define ZYWRLE_YMASK15 0xFFFFFFF8
|
|
+#define ZYWRLE_UVMASK15 0xFFFFFFF8
|
|
+#define ZYWRLE_LOAD_PIXEL15(pSrc,R,G,B) { \
|
|
+ R = (((unsigned char*)pSrc)[S_1]<< 1)& 0xF8; \
|
|
+ G = ((((unsigned char*)pSrc)[S_1]<< 6)|(((unsigned char*)pSrc)[S_0]>> 2))& 0xF8; \
|
|
+ B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \
|
|
+}
|
|
+#define ZYWRLE_SAVE_PIXEL15(pDst,R,G,B) { \
|
|
+ R &= 0xF8; \
|
|
+ G &= 0xF8; \
|
|
+ B &= 0xF8; \
|
|
+ ((unsigned char*)pDst)[S_1] = (unsigned char)( (R>>1)|(G>>6) ); \
|
|
+ ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<2))& 0xFF); \
|
|
+}
|
|
+#define ZYWRLE_YMASK16 0xFFFFFFFC
|
|
+#define ZYWRLE_UVMASK16 0xFFFFFFF8
|
|
+#define ZYWRLE_LOAD_PIXEL16(pSrc,R,G,B) { \
|
|
+ R = ((unsigned char*)pSrc)[S_1] & 0xF8; \
|
|
+ G = ((((unsigned char*)pSrc)[S_1]<< 5)|(((unsigned char*)pSrc)[S_0]>> 3))& 0xFC; \
|
|
+ B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \
|
|
+}
|
|
+#define ZYWRLE_SAVE_PIXEL16(pDst,R,G,B) { \
|
|
+ R &= 0xF8; \
|
|
+ G &= 0xFC; \
|
|
+ B &= 0xF8; \
|
|
+ ((unsigned char*)pDst)[S_1] = (unsigned char)( R |(G>>5) ); \
|
|
+ ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<3))& 0xFF); \
|
|
+}
|
|
+#define ZYWRLE_YMASK32 0xFFFFFFFF
|
|
+#define ZYWRLE_UVMASK32 0xFFFFFFFF
|
|
+#define ZYWRLE_LOAD_PIXEL32(pSrc,R,G,B) { \
|
|
+ R = ((unsigned char*)pSrc)[L_2]; \
|
|
+ G = ((unsigned char*)pSrc)[L_1]; \
|
|
+ B = ((unsigned char*)pSrc)[L_0]; \
|
|
+}
|
|
+#define ZYWRLE_SAVE_PIXEL32(pDst,R,G,B) { \
|
|
+ ((unsigned char*)pDst)[L_2] = (unsigned char)R; \
|
|
+ ((unsigned char*)pDst)[L_1] = (unsigned char)G; \
|
|
+ ((unsigned char*)pDst)[L_0] = (unsigned char)B; \
|
|
+}
|
|
+
|
|
+#ifndef ZYWRLE_ONCE
|
|
+#define ZYWRLE_ONCE
|
|
+
|
|
+#ifdef WIN32
|
|
+#define InlineX __inline
|
|
+#else
|
|
+#define InlineX inline
|
|
+#endif
|
|
+
|
|
+#ifdef ZYWRLE_ENCODE
|
|
+// Tables for Coefficients filtering.
|
|
+# ifndef ZYWRLE_QUANTIZE
|
|
+// Type A:lower bit omitting of EZW style.
|
|
+const static unsigned int zywrleParam[3][3]={
|
|
+ {0x0000F000,0x00000000,0x00000000},
|
|
+ {0x0000C000,0x00F0F0F0,0x00000000},
|
|
+ {0x0000C000,0x00C0C0C0,0x00F0F0F0},
|
|
+// {0x0000FF00,0x00000000,0x00000000},
|
|
+// {0x0000FF00,0x00FFFFFF,0x00000000},
|
|
+// {0x0000FF00,0x00FFFFFF,0x00FFFFFF},
|
|
+};
|
|
+# else
|
|
+// Type B:Non liner quantization filter.
|
|
+static const signed char zywrleConv[4][256]={
|
|
+{ // bi=5, bo=5 r=0.0:PSNR=24.849
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+},
|
|
+{ // bi=5, bo=5 r=2.0:PSNR=74.031
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 32,
|
|
+ 32, 32, 32, 32, 32, 32, 32, 32,
|
|
+ 32, 32, 32, 32, 32, 32, 32, 32,
|
|
+ 48, 48, 48, 48, 48, 48, 48, 48,
|
|
+ 48, 48, 48, 56, 56, 56, 56, 56,
|
|
+ 56, 56, 56, 56, 64, 64, 64, 64,
|
|
+ 64, 64, 64, 64, 72, 72, 72, 72,
|
|
+ 72, 72, 72, 72, 80, 80, 80, 80,
|
|
+ 80, 80, 88, 88, 88, 88, 88, 88,
|
|
+ 88, 88, 88, 88, 88, 88, 96, 96,
|
|
+ 96, 96, 96, 104, 104, 104, 104, 104,
|
|
+ 104, 104, 104, 104, 104, 112, 112, 112,
|
|
+ 112, 112, 112, 112, 112, 112, 120, 120,
|
|
+ 120, 120, 120, 120, 120, 120, 120, 120,
|
|
+ 0, -120, -120, -120, -120, -120, -120, -120,
|
|
+ -120, -120, -120, -112, -112, -112, -112, -112,
|
|
+ -112, -112, -112, -112, -104, -104, -104, -104,
|
|
+ -104, -104, -104, -104, -104, -104, -96, -96,
|
|
+ -96, -96, -96, -88, -88, -88, -88, -88,
|
|
+ -88, -88, -88, -88, -88, -88, -88, -80,
|
|
+ -80, -80, -80, -80, -80, -72, -72, -72,
|
|
+ -72, -72, -72, -72, -72, -64, -64, -64,
|
|
+ -64, -64, -64, -64, -64, -56, -56, -56,
|
|
+ -56, -56, -56, -56, -56, -56, -48, -48,
|
|
+ -48, -48, -48, -48, -48, -48, -48, -48,
|
|
+ -48, -32, -32, -32, -32, -32, -32, -32,
|
|
+ -32, -32, -32, -32, -32, -32, -32, -32,
|
|
+ -32, -32, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+},
|
|
+{ // bi=5, bo=4 r=2.0:PSNR=64.441
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 48, 48, 48, 48, 48, 48, 48, 48,
|
|
+ 48, 48, 48, 48, 48, 48, 48, 48,
|
|
+ 48, 48, 48, 48, 48, 48, 48, 48,
|
|
+ 64, 64, 64, 64, 64, 64, 64, 64,
|
|
+ 64, 64, 64, 64, 64, 64, 64, 64,
|
|
+ 80, 80, 80, 80, 80, 80, 80, 80,
|
|
+ 80, 80, 80, 80, 80, 88, 88, 88,
|
|
+ 88, 88, 88, 88, 88, 88, 88, 88,
|
|
+ 104, 104, 104, 104, 104, 104, 104, 104,
|
|
+ 104, 104, 104, 112, 112, 112, 112, 112,
|
|
+ 112, 112, 112, 112, 120, 120, 120, 120,
|
|
+ 120, 120, 120, 120, 120, 120, 120, 120,
|
|
+ 0, -120, -120, -120, -120, -120, -120, -120,
|
|
+ -120, -120, -120, -120, -120, -112, -112, -112,
|
|
+ -112, -112, -112, -112, -112, -112, -104, -104,
|
|
+ -104, -104, -104, -104, -104, -104, -104, -104,
|
|
+ -104, -88, -88, -88, -88, -88, -88, -88,
|
|
+ -88, -88, -88, -88, -80, -80, -80, -80,
|
|
+ -80, -80, -80, -80, -80, -80, -80, -80,
|
|
+ -80, -64, -64, -64, -64, -64, -64, -64,
|
|
+ -64, -64, -64, -64, -64, -64, -64, -64,
|
|
+ -64, -48, -48, -48, -48, -48, -48, -48,
|
|
+ -48, -48, -48, -48, -48, -48, -48, -48,
|
|
+ -48, -48, -48, -48, -48, -48, -48, -48,
|
|
+ -48, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+},
|
|
+{ // bi=5, bo=2 r=2.0:PSNR=43.175
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 88, 88, 88, 88, 88, 88, 88, 88,
|
|
+ 88, 88, 88, 88, 88, 88, 88, 88,
|
|
+ 88, 88, 88, 88, 88, 88, 88, 88,
|
|
+ 88, 88, 88, 88, 88, 88, 88, 88,
|
|
+ 88, 88, 88, 88, 88, 88, 88, 88,
|
|
+ 88, 88, 88, 88, 88, 88, 88, 88,
|
|
+ 88, 88, 88, 88, 88, 88, 88, 88,
|
|
+ 88, 88, 88, 88, 88, 88, 88, 88,
|
|
+ 0, -88, -88, -88, -88, -88, -88, -88,
|
|
+ -88, -88, -88, -88, -88, -88, -88, -88,
|
|
+ -88, -88, -88, -88, -88, -88, -88, -88,
|
|
+ -88, -88, -88, -88, -88, -88, -88, -88,
|
|
+ -88, -88, -88, -88, -88, -88, -88, -88,
|
|
+ -88, -88, -88, -88, -88, -88, -88, -88,
|
|
+ -88, -88, -88, -88, -88, -88, -88, -88,
|
|
+ -88, -88, -88, -88, -88, -88, -88, -88,
|
|
+ -88, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+}
|
|
+};
|
|
+const static signed char* zywrleParam[3][3][3]={
|
|
+ {{zywrleConv[0],zywrleConv[2],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}},
|
|
+ {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}},
|
|
+ {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[2],zywrleConv[2],zywrleConv[2]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]}},
|
|
+};
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+static InlineX void Harr( signed char* pX0, signed char* pX1 ){
|
|
+ // Piecewise-Linear Harr(PLHarr)
|
|
+ int X0=(int)*pX0, X1=(int)*pX1;
|
|
+ int orgX0=X0, orgX1=X1;
|
|
+ if( (X0^X1)&0x80 ){
|
|
+ // differ sign
|
|
+ X1 += X0;
|
|
+ if( ((X1^orgX1)&0x80)==0 ){
|
|
+ // |X1| > |X0|
|
|
+ X0 -= X1; // H = -B
|
|
+ }
|
|
+ }else{
|
|
+ // same sign
|
|
+ X0 -= X1;
|
|
+ if( ((X0^orgX0)&0x80)==0 ){
|
|
+ // |X0| > |X1|
|
|
+ X1 += X0; // L = A
|
|
+ }
|
|
+ }
|
|
+ *pX0 = (signed char)X1;
|
|
+ *pX1 = (signed char)X0;
|
|
+}
|
|
+// 1D-Wavelet transform.
|
|
+//
|
|
+// In coefficients array, the famous 'pyramid' decomposition is well used.
|
|
+//
|
|
+// 1D Model:
|
|
+// |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0
|
|
+// |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1
|
|
+//
|
|
+// But this method needs line buffer because H/L is different position from X0/X1.
|
|
+// So, I used 'interleave' decomposition instead of it.
|
|
+//
|
|
+// 1D Model:
|
|
+// |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0
|
|
+// |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1
|
|
+//
|
|
+// In this method, H/L and X0/X1 is always same position.
|
|
+// This lead us to more speed and less memory.
|
|
+// Of cause, the result of both method is quite same
|
|
+// because it's only difference that coefficient position.
|
|
+
|
|
+static InlineX void WaveletLevel( int* data, int size, int l, int SkipPixel ){
|
|
+ int s, ofs;
|
|
+ signed char* pX0;
|
|
+ signed char* end;
|
|
+
|
|
+ pX0 = (signed char*)data;
|
|
+ s = (8<<l)*SkipPixel;
|
|
+ end = pX0+(size>>(l+1))*s;
|
|
+ s -= 2;
|
|
+ ofs = (4<<l)*SkipPixel;
|
|
+ while( pX0 < end ){
|
|
+ Harr( pX0, pX0+ofs );
|
|
+ pX0++;
|
|
+ Harr( pX0, pX0+ofs );
|
|
+ pX0++;
|
|
+ Harr( pX0, pX0+ofs );
|
|
+ pX0 += s;
|
|
+ }
|
|
+}
|
|
+#define InvWaveletLevel(d,s,l,pix) WaveletLevel(d,s,l,pix)
|
|
+
|
|
+#ifdef ZYWRLE_ENCODE
|
|
+# ifndef ZYWRLE_QUANTIZE
|
|
+// Type A:lower bit omitting of EZW style.
|
|
+static InlineX void FilterWaveletSquare( int* pBuf, int width, int height, int level, int l ){
|
|
+ int r, s;
|
|
+ int x, y;
|
|
+ int* pH;
|
|
+ const unsigned int* pM;
|
|
+
|
|
+ pM = &(zywrleParam[level-1][l]);
|
|
+ s = 2<<l;
|
|
+ for( r=1; r<4; r++ ){
|
|
+ pH = pBuf;
|
|
+ if( r & 0x01 ){
|
|
+ pH += s>>1;
|
|
+ }
|
|
+ if( r & 0x02 ){
|
|
+ pH += (s>>1)*width;
|
|
+ }
|
|
+ for( y=0; y<height/s; y++ ){
|
|
+ for( x=0; x<width/s; x++ ){
|
|
+ // these are same following code.
|
|
+ // pH[x] = pH[x] / (~pM[x]+1) * (~pM[x]+1);
|
|
+ // ( round pH[x] with pM[x] bit )
|
|
+ // '&' operator isn't 'round' but is 'floor'.
|
|
+ // So, we must offset when pH[x] is negative.
|
|
+ if( ((signed char*)pH)[0] & 0x80 ){
|
|
+ ((signed char*)pH)[0] += ~((signed char*)pM)[0];
|
|
+ }
|
|
+ if( ((signed char*)pH)[1] & 0x80 ){
|
|
+ ((signed char*)pH)[1] += ~((signed char*)pM)[1];
|
|
+ }
|
|
+ if( ((signed char*)pH)[2] & 0x80 ){
|
|
+ ((signed char*)pH)[2] += ~((signed char*)pM)[2];
|
|
+ }
|
|
+ *pH &= *pM;
|
|
+ pH += s;
|
|
+ }
|
|
+ pH += (s-1)*width;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+# else
|
|
+// Type B:Non liner quantization filter.
|
|
+//
|
|
+// Coefficients have Gaussian curve and smaller value which is
|
|
+// large part of coefficients isn't more important than larger value.
|
|
+// So, I use filter of Non liner quantize/dequantize table.
|
|
+// In general, Non liner quantize formula is explained as following.
|
|
+//
|
|
+// y=f(x) = sign(x)*round( ((abs(x)/(2^7))^ r )* 2^(bo-1) )*2^(8-bo)
|
|
+// x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi)
|
|
+// ( r:power coefficient bi:effective MSB in input bo:effective MSB in output )
|
|
+//
|
|
+// r < 1.0 : Smaller value is more important than larger value.
|
|
+// r > 1.0 : Larger value is more important than smaller value.
|
|
+// r = 1.0 : Liner quantization which is same with EZW style.
|
|
+//
|
|
+// r = 0.75 is famous non liner quantization used in MP3 audio codec.
|
|
+// In contrast to audio data, larger value is important in wavelet coefficients.
|
|
+// So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ).
|
|
+//
|
|
+// As compared with EZW style liner quantization, this filter tended to be
|
|
+// more sharp edge and be more compression rate but be more blocking noise and be less quality.
|
|
+// Especially, the surface of graphic objects has distinguishable noise in middle quality mode.
|
|
+//
|
|
+// We need only quantized-dequantized(filtered) value rather than quantized value itself
|
|
+// because all values are packed or palette-lized in later ZRLE section.
|
|
+// This lead us not to need to modify client decoder when we change
|
|
+// the filtering procedure in future.
|
|
+// Client only decodes coefficients given by encoder.
|
|
+static InlineX void FilterWaveletSquare( int* pBuf, int width, int height, int level, int l ){
|
|
+ int r, s;
|
|
+ int x, y;
|
|
+ int* pH;
|
|
+ const signed char** pM;
|
|
+
|
|
+ pM = zywrleParam[level-1][l];
|
|
+ s = 2<<l;
|
|
+ for( r=1; r<4; r++ ){
|
|
+ pH = pBuf;
|
|
+ if( r & 0x01 ){
|
|
+ pH += s>>1;
|
|
+ }
|
|
+ if( r & 0x02 ){
|
|
+ pH += (s>>1)*width;
|
|
+ }
|
|
+ for( y=0; y<height/s; y++ ){
|
|
+ for( x=0; x<width/s; x++ ){
|
|
+ ((signed char*)pH)[0] = pM[0][((unsigned char*)pH)[0]];
|
|
+ ((signed char*)pH)[1] = pM[1][((unsigned char*)pH)[1]];
|
|
+ ((signed char*)pH)[2] = pM[2][((unsigned char*)pH)[2]];
|
|
+ pH += s;
|
|
+ }
|
|
+ pH += (s-1)*width;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+# endif
|
|
+
|
|
+static InlineX void Wavelet( int* pBuf, int width, int height, int level ){
|
|
+ int l, s;
|
|
+ int* pTop;
|
|
+ int* pEnd;
|
|
+
|
|
+ for( l=0; l<level; l++ ){
|
|
+ pTop = pBuf;
|
|
+ pEnd = pBuf+height*width;
|
|
+ s = width<<l;
|
|
+ while( pTop < pEnd ){
|
|
+ WaveletLevel( pTop, width, l, 1 );
|
|
+ pTop += s;
|
|
+ }
|
|
+ pTop = pBuf;
|
|
+ pEnd = pBuf+width;
|
|
+ s = 1<<l;
|
|
+ while( pTop < pEnd ){
|
|
+ WaveletLevel( pTop, height,l, width );
|
|
+ pTop += s;
|
|
+ }
|
|
+ FilterWaveletSquare( pBuf, width, height, level, l );
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+#ifdef ZYWRLE_DECODE
|
|
+static InlineX void InvWavelet( int* pBuf, int width, int height, int level ){
|
|
+ int l, s;
|
|
+ int* pTop;
|
|
+ int* pEnd;
|
|
+
|
|
+ for( l=level-1; l>=0; l-- ){
|
|
+ pTop = pBuf;
|
|
+ pEnd = pBuf+width;
|
|
+ s = 1<<l;
|
|
+ while( pTop < pEnd ){
|
|
+ InvWaveletLevel( pTop, height,l, width );
|
|
+ pTop += s;
|
|
+ }
|
|
+ pTop = pBuf;
|
|
+ pEnd = pBuf+height*width;
|
|
+ s = width<<l;
|
|
+ while( pTop < pEnd ){
|
|
+ InvWaveletLevel( pTop, width, l, 1 );
|
|
+ pTop += s;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+// Load/Save coefficients stuffs.
|
|
+// Coefficients manages as 24 bits little-endian pixel.
|
|
+#define ZYWRLE_LOAD_COEFF(pSrc,R,G,B) { \
|
|
+ R = ((signed char*)pSrc)[2]; \
|
|
+ G = ((signed char*)pSrc)[1]; \
|
|
+ B = ((signed char*)pSrc)[0]; \
|
|
+}
|
|
+#define ZYWRLE_SAVE_COEFF(pDst,R,G,B) { \
|
|
+ ((signed char*)pDst)[2] = (signed char)R; \
|
|
+ ((signed char*)pDst)[1] = (signed char)G; \
|
|
+ ((signed char*)pDst)[0] = (signed char)B; \
|
|
+}
|
|
+
|
|
+// RGB <=> YUV conversion stuffs.
|
|
+// YUV coversion is explained as following formula in strict meaning:
|
|
+// Y = 0.299R + 0.587G + 0.114B ( 0<=Y<=255)
|
|
+// U = -0.169R - 0.331G + 0.500B (-128<=U<=127)
|
|
+// V = 0.500R - 0.419G - 0.081B (-128<=V<=127)
|
|
+//
|
|
+// I use simple conversion RCT(reversible color transform) which is described
|
|
+// in JPEG-2000 specification.
|
|
+// Y = (R + 2G + B)/4 ( 0<=Y<=255)
|
|
+// U = B-G (-256<=U<=255)
|
|
+// V = R-G (-256<=V<=255)
|
|
+
|
|
+#define ROUND(x) (((x)<0)?0:(((x)>255)?255:(x)))
|
|
+ // RCT is N-bit RGB to N-bit Y and N+1-bit UV.
|
|
+ // For make Same N-bit, UV is lossy.
|
|
+ // More exact PLHarr, we reduce to odd range(-127<=x<=127).
|
|
+#define ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ymask,uvmask) { \
|
|
+ Y = (R+(G<<1)+B)>>2; \
|
|
+ U = B-G; \
|
|
+ V = R-G; \
|
|
+ Y -= 128; \
|
|
+ U >>= 1; \
|
|
+ V >>= 1; \
|
|
+ Y &= ymask; \
|
|
+ U &= uvmask; \
|
|
+ V &= uvmask; \
|
|
+ if( Y == -128 ){ \
|
|
+ Y += (0xFFFFFFFF-ymask+1); \
|
|
+ } \
|
|
+ if( U == -128 ){ \
|
|
+ U += (0xFFFFFFFF-uvmask+1); \
|
|
+ } \
|
|
+ if( V == -128 ){ \
|
|
+ V += (0xFFFFFFFF-uvmask+1); \
|
|
+ } \
|
|
+}
|
|
+#define ZYWRLE_YUVRGB1(R,G,B,Y,U,V) { \
|
|
+ Y += 128; \
|
|
+ U <<= 1; \
|
|
+ V <<= 1; \
|
|
+ G = Y-((U+V)>>2); \
|
|
+ B = U+G; \
|
|
+ R = V+G; \
|
|
+ G = ROUND(G); \
|
|
+ B = ROUND(B); \
|
|
+ R = ROUND(R); \
|
|
+}
|
|
+
|
|
+// coefficient packing/unpacking stuffs.
|
|
+// Wavelet transform makes 4 sub coefficient image from 1 original image.
|
|
+//
|
|
+// model with pyramid decomposition:
|
|
+// +------+------+
|
|
+// | | |
|
|
+// | L | Hx |
|
|
+// | | |
|
|
+// +------+------+
|
|
+// | | |
|
|
+// | H | Hxy |
|
|
+// | | |
|
|
+// +------+------+
|
|
+//
|
|
+// So, we must transfer each sub images individually in strict meaning.
|
|
+// But at least ZRLE meaning, following one decompositon image is same as
|
|
+// avobe individual sub image. I use this format.
|
|
+// (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L)
|
|
+// for simplified procedure for any wavelet level.)
|
|
+//
|
|
+// +------+------+
|
|
+// | L |
|
|
+// +------+------+
|
|
+// | Hx |
|
|
+// +------+------+
|
|
+// | Hy |
|
|
+// +------+------+
|
|
+// | Hxy |
|
|
+// +------+------+
|
|
+
|
|
+#define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,TRANS) \
|
|
+ pH = pBuf; \
|
|
+ s = 2<<level; \
|
|
+ if( r & 0x01 ){ \
|
|
+ pH += s>>1; \
|
|
+ } \
|
|
+ if( r & 0x02 ){ \
|
|
+ pH += (s>>1)*width; \
|
|
+ } \
|
|
+ pEnd = pH+height*width; \
|
|
+ while( pH < pEnd ){ \
|
|
+ pLine = pH+width; \
|
|
+ while( pH < pLine ){ \
|
|
+ TRANS \
|
|
+ data++; \
|
|
+ pH += s; \
|
|
+ } \
|
|
+ pH += (s-1)*width; \
|
|
+ }
|
|
+
|
|
+#define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,level) \
|
|
+ ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);)
|
|
+
|
|
+#define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,level) \
|
|
+ ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,ZYWRLE_LOAD_PIXEL(data,R,G,B);ZYWRLE_SAVE_COEFF(pH,R,G,B);)
|
|
+
|
|
+#define ZYWRLE_SAVE_UNALIGN(data,TRANS) \
|
|
+ pTop = pBuf+w*h; \
|
|
+ pEnd = pTop + (w+uw)*(h+uh)-w*h; \
|
|
+ while( pTop < pEnd ){ \
|
|
+ TRANS \
|
|
+ data++; \
|
|
+ pTop++; \
|
|
+ }
|
|
+
|
|
+#define ZYWRLE_LOAD_UNALIGN(data,pData,TRANS) \
|
|
+ pTop = pBuf+w*h; \
|
|
+ if( uw ){ \
|
|
+ pData= data + w; \
|
|
+ pEnd = (int*)(pData+ h*scanline); \
|
|
+ while( pData < (PIXEL_T*)pEnd ){ \
|
|
+ pLine = (int*)(pData + uw); \
|
|
+ while( pData < (PIXEL_T*)pLine ){ \
|
|
+ TRANS \
|
|
+ pData++; \
|
|
+ pTop++; \
|
|
+ } \
|
|
+ pData += scanline-uw; \
|
|
+ } \
|
|
+ } \
|
|
+ if( uh ){ \
|
|
+ pData= data + h*scanline; \
|
|
+ pEnd = (int*)(pData+ uh*scanline); \
|
|
+ while( pData < (PIXEL_T*)pEnd ){ \
|
|
+ pLine = (int*)(pData + w); \
|
|
+ while( pData < (PIXEL_T*)pLine ){ \
|
|
+ TRANS \
|
|
+ pData++; \
|
|
+ pTop++; \
|
|
+ } \
|
|
+ pData += scanline-w; \
|
|
+ } \
|
|
+ } \
|
|
+ if( uw && uh ){ \
|
|
+ pData= data + w+ h*scanline; \
|
|
+ pEnd = (int*)(pData+ uh*scanline); \
|
|
+ while( pData < (PIXEL_T*)pEnd ){ \
|
|
+ pLine = (int*)(pData + uw); \
|
|
+ while( pData < (PIXEL_T*)pLine ){ \
|
|
+ TRANS \
|
|
+ pData++; \
|
|
+ pTop++; \
|
|
+ } \
|
|
+ pData += scanline-uw; \
|
|
+ } \
|
|
+ }
|
|
+
|
|
+static InlineX void zywrleCalcSize( int* pW, int* pH, int level ){
|
|
+ *pW &= ~((1<<level)-1);
|
|
+ *pH &= ~((1<<level)-1);
|
|
+}
|
|
+
|
|
+#endif // ZYWRLE_ONCE
|
|
+
|
|
+#ifndef CPIXEL
|
|
+#ifdef ZYWRLE_ENCODE
|
|
+static InlineX void ZYWRLE_RGBYUV( int* pBuf, PIXEL_T* data, int width, int height, int scanline ){
|
|
+ int R, G, B;
|
|
+ int Y, U, V;
|
|
+ int* pLine;
|
|
+ int* pEnd;
|
|
+ pEnd = pBuf+height*width;
|
|
+ while( pBuf < pEnd ){
|
|
+ pLine = pBuf+width;
|
|
+ while( pBuf < pLine ){
|
|
+ ZYWRLE_LOAD_PIXEL(data,R,G,B);
|
|
+ ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ZYWRLE_YMASK,ZYWRLE_UVMASK);
|
|
+ ZYWRLE_SAVE_COEFF(pBuf,V,Y,U);
|
|
+ pBuf++;
|
|
+ data++;
|
|
+ }
|
|
+ data += scanline-width;
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+#ifdef ZYWRLE_DECODE
|
|
+static InlineX void ZYWRLE_YUVRGB( int* pBuf, PIXEL_T* data, int width, int height, int scanline ){
|
|
+ int R, G, B;
|
|
+ int Y, U, V;
|
|
+ int* pLine;
|
|
+ int* pEnd;
|
|
+ pEnd = pBuf+height*width;
|
|
+ while( pBuf < pEnd ){
|
|
+ pLine = pBuf+width;
|
|
+ while( pBuf < pLine ){
|
|
+ ZYWRLE_LOAD_COEFF(pBuf,V,Y,U);
|
|
+ ZYWRLE_YUVRGB1(R,G,B,Y,U,V);
|
|
+ ZYWRLE_SAVE_PIXEL(data,R,G,B);
|
|
+ pBuf++;
|
|
+ data++;
|
|
+ }
|
|
+ data += scanline-width;
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+#ifdef ZYWRLE_ENCODE
|
|
+PIXEL_T* ZYWRLE_ANALYZE ( PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf ){
|
|
+ int l;
|
|
+ int uw = w;
|
|
+ int uh = h;
|
|
+ int* pTop;
|
|
+ int* pEnd;
|
|
+ int* pLine;
|
|
+ PIXEL_T* pSrc;
|
|
+ int R, G, B;
|
|
+ int s;
|
|
+ int* pH;
|
|
+
|
|
+ zywrleCalcSize( &w, &h, level );
|
|
+ if( (w==0)||(h==0) ){
|
|
+ return NULL;
|
|
+ }
|
|
+ uw -= w;
|
|
+ uh -= h;
|
|
+
|
|
+ ZYWRLE_LOAD_UNALIGN(src,pSrc,*(PIXEL_T*)pTop=*pSrc;)
|
|
+ ZYWRLE_RGBYUV( pBuf, src, w, h, scanline );
|
|
+ Wavelet( pBuf, w, h, level );
|
|
+ for( l=0; l<level; l++ ){
|
|
+ ZYWRLE_PACK_COEFF( pBuf, dst, 3, w, h, l );
|
|
+ ZYWRLE_PACK_COEFF( pBuf, dst, 2, w, h, l );
|
|
+ ZYWRLE_PACK_COEFF( pBuf, dst, 1, w, h, l );
|
|
+ if( l == level-1 ){
|
|
+ ZYWRLE_PACK_COEFF( pBuf, dst, 0, w, h, l );
|
|
+ }
|
|
+ }
|
|
+ ZYWRLE_SAVE_UNALIGN(dst,*dst=*(PIXEL_T*)pTop;)
|
|
+ return dst;
|
|
+}
|
|
+#endif
|
|
+#ifdef ZYWRLE_DECODE
|
|
+PIXEL_T* ZYWRLE_SYNTHESIZE ( PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf ){
|
|
+ int l;
|
|
+ int uw = w;
|
|
+ int uh = h;
|
|
+ int* pTop;
|
|
+ int* pEnd;
|
|
+ int* pLine;
|
|
+ PIXEL_T* pDst;
|
|
+ int R, G, B;
|
|
+ int s;
|
|
+ int* pH;
|
|
+
|
|
+ zywrleCalcSize( &w, &h, level );
|
|
+ if( (w==0)||(h==0) ){
|
|
+ return NULL;
|
|
+ }
|
|
+ uw -= w;
|
|
+ uh -= h;
|
|
+
|
|
+ for( l=0; l<level; l++ ){
|
|
+ ZYWRLE_UNPACK_COEFF( pBuf, src, 3, w, h, l );
|
|
+ ZYWRLE_UNPACK_COEFF( pBuf, src, 2, w, h, l );
|
|
+ ZYWRLE_UNPACK_COEFF( pBuf, src, 1, w, h, l );
|
|
+ if( l == level-1 ){
|
|
+ ZYWRLE_UNPACK_COEFF( pBuf, src, 0, w, h, l );
|
|
+ }
|
|
+ }
|
|
+ ZYWRLE_SAVE_UNALIGN(src,*(PIXEL_T*)pTop=*src;)
|
|
+ InvWavelet( pBuf, w, h, level );
|
|
+ ZYWRLE_YUVRGB( pBuf, dst, w, h, scanline );
|
|
+ ZYWRLE_LOAD_UNALIGN(dst,pDst,*pDst=*(PIXEL_T*)pTop;)
|
|
+ return src;
|
|
+}
|
|
+#endif
|
|
+#endif // CPIXEL
|
|
+
|
|
+#undef ZYWRLE_RGBYUV
|
|
+#undef ZYWRLE_YUVRGB
|
|
+#undef ZYWRLE_LOAD_PIXEL
|
|
+#undef ZYWRLE_SAVE_PIXEL
|
|
diff -Naur vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h
|
|
--- vnc_unixsrc.orig/include/rfbproto.h 2004-05-27 03:02:02.000000000 -0400
|
|
+++ vnc_unixsrc/include/rfbproto.h 2007-02-18 13:04:35.000000000 -0500
|
|
@@ -381,6 +381,10 @@
|
|
#define rfbBell 2
|
|
#define rfbServerCutText 3
|
|
|
|
+
|
|
+/* http://sourceforge.net/projects/vncsessmgr */
|
|
+#define rfbRestartConnection 82
|
|
+
|
|
#define rfbFileListData 130
|
|
#define rfbFileDownloadData 131
|
|
#define rfbFileUploadCancel 132
|
|
@@ -403,6 +407,18 @@
|
|
#define rfbPointerEvent 5
|
|
#define rfbClientCutText 6
|
|
|
|
+/* ultra */
|
|
+
|
|
+#define rfbFileTransfer 7
|
|
+#define rfbSetScale 8
|
|
+#define rfbSetServerInput 9
|
|
+#define rfbSetSW 10
|
|
+#define rfbTextChat 11
|
|
+#define rfbKeyFrameRequest 12
|
|
+#define rfbPalmVNCSetScaleFactor 0xF
|
|
+
|
|
+
|
|
+
|
|
#define rfbFileListRequest 130
|
|
#define rfbFileDownloadRequest 131
|
|
#define rfbFileUploadRequest 132
|
|
@@ -435,6 +451,11 @@
|
|
#define rfbEncodingTight 7
|
|
#define rfbEncodingZlibHex 8
|
|
|
|
+#define rfbEncodingZRLE 16
|
|
+// nyama/2006/08/02:new YUV-Wavlet lossy codec based on ZRLE (ZYWRLE)
|
|
+#define rfbEncodingZYWRLE 17
|
|
+
|
|
+
|
|
/* signatures for basic encoding types */
|
|
#define sig_rfbEncodingRaw "RAW_____"
|
|
#define sig_rfbEncodingCopyRect "COPYRECT"
|
|
@@ -955,6 +976,36 @@
|
|
#define sz_rfbFileDownloadFailedMsg 4
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
+ * RestartConnection - the server has restarted the client connection.
|
|
+ */
|
|
+
|
|
+typedef struct _rfbRestartConnectionMsg {
|
|
+ CARD8 type; /* always rfbRestartConnection */
|
|
+ CARD8 pad1;
|
|
+ CARD16 pad2;
|
|
+ CARD32 length;
|
|
+ /* followed by char text[length] */
|
|
+} rfbRestartConnectionMsg;
|
|
+
|
|
+#define sz_rfbRestartConnectionMsg 8
|
|
+
|
|
+
|
|
+typedef struct _rfbTextChatMsg {
|
|
+ CARD8 type; /* always rfbTextChat */
|
|
+ CARD8 pad1; // Could be used later as an additionnal param
|
|
+ CARD16 pad2; // Could be used later as text offset, for instance
|
|
+ CARD32 length; // Specific values for Open, close, finished (-1, -2, -3)
|
|
+ /* followed by char text[length] */
|
|
+} rfbTextChatMsg;
|
|
+
|
|
+#define sz_rfbTextChatMsg 8
|
|
+
|
|
+#define rfbTextMaxSize 4096
|
|
+#define rfbTextChatOpen 0xFFFFFFFF
|
|
+#define rfbTextChatClose 0xFFFFFFFE
|
|
+#define rfbTextChatFinished 0xFFFFFFFD
|
|
+
|
|
+/*-----------------------------------------------------------------------------
|
|
* Union of all server->client messages.
|
|
*/
|
|
|
|
@@ -968,6 +1019,8 @@
|
|
rfbFileDownloadDataMsg fdd;
|
|
rfbFileUploadCancelMsg fuc;
|
|
rfbFileDownloadFailedMsg fdf;
|
|
+ rfbRestartConnectionMsg rc;
|
|
+ rfbTextChatMsg tc;
|
|
} rfbServerToClientMsg;
|
|
|
|
|
|
@@ -1221,6 +1274,41 @@
|
|
|
|
#define sz_rfbFileCreateDirRequestMsg 4
|
|
|
|
+/* ultra */
|
|
+typedef struct _rfbSetScaleMsg {
|
|
+ CARD8 type; /* always rfbSetScale */
|
|
+ CARD8 scale; /* Scale value 1<sv<n */
|
|
+ CARD16 pad;
|
|
+} rfbSetScaleMsg;
|
|
+
|
|
+#define sz_rfbSetScaleMsg 4
|
|
+
|
|
+typedef struct {
|
|
+ CARD8 type; /* always rfbSetScaleFactor */
|
|
+
|
|
+ CARD8 scale; /* Scale factor (positive non-zero integer) */
|
|
+ CARD16 pad2;
|
|
+} rfbPalmVNCSetScaleFactorMsg;
|
|
+
|
|
+#define sz_rfbPalmVNCSetScaleFactorMsg (4)
|
|
+
|
|
+typedef struct _rfbSetServerInputMsg {
|
|
+ CARD8 type; /* always rfbSetServerInputMsg */
|
|
+ CARD8 status; /* on or off */
|
|
+ CARD16 pad;
|
|
+} rfbSetServerInputMsg;
|
|
+
|
|
+#define sz_rfbSetServerInputMsg 4
|
|
+
|
|
+typedef struct _rfbSetSWMsg {
|
|
+ CARD8 type; /* always rfbSetSW */
|
|
+ CARD8 status;
|
|
+ CARD16 x;
|
|
+ CARD16 y;
|
|
+} rfbSetSWMsg;
|
|
+
|
|
+#define sz_rfbSetSWMsg 6
|
|
+
|
|
/*-----------------------------------------------------------------------------
|
|
* Union of all client->server messages.
|
|
*/
|
|
@@ -1241,4 +1329,9 @@
|
|
rfbFileDownloadCancelMsg fdc;
|
|
rfbFileUploadFailedMsg fuf;
|
|
rfbFileCreateDirRequestMsg fcdr;
|
|
+ rfbSetScaleMsg ssc;
|
|
+ rfbPalmVNCSetScaleFactorMsg pssf;
|
|
+ rfbSetServerInputMsg sim;
|
|
+ rfbSetSWMsg sw;
|
|
+ rfbTextChatMsg tc;
|
|
} rfbClientToServerMsg;
|