第四章 RDP Client 實做與程式分析
4.3 Primary order 的處理
4.3.2 圖形指令
圖形指令在 RDP order 中,可以分為四種:矩形、多邊形、橢圓以及線條,多邊 形及橢圓主要是應用在 power point 中的快取圖形,矩形主要是用在組合視窗的結構,
線條則是用在文字的底線部分。
z 矩形(rectangle)
在遠端桌面連線中,常見到背景單純的畫面或是視窗框架的部份,RDP Server 利 用傳送 rectangle 來呼叫 RDP Client 進行畫面的繪製,關於這個指令,我們定義一個 RECT_ORDER 的資料結構,如下圖。
圖 29. RECT ORDER 的結構
rdesktop 中建立一個 process_rect 的函數,將封包中的參數資料放入 RECT_ORDER 結構中,接著呼叫 ui_rect 然後引用 RECT_ORDER 的參數來設定矩形的顏色並將矩形 座標位置及長寬參數傳送給 FILL_RECTANGLE,在 RECTANGLE 中呼叫 X Lib 的 XFillRectangle 將矩形繪製出來,RDP Client 對於 RECTANGLE 的處理流程如下圖 30.。
圖 30. rect order 處理流程
進行畫面分析之前,先說明 XFillRectangle 函數的重要性,由於 rdesktop 是建立 在 X Window 中,XFillRectangle 是 rdesktop 和 X Window 的溝通函數。XFillRectangle
process_rect
根據 RDP Server 所傳遞的座標(X、Y)和大小(長、寬)在指定的繪圖區,也就是 rdesktop 程式視窗進行繪製。
瞭解 RECTANGLE 處理過程後,我們進行 rdesktop 程式碼的修改,將傳送過來的 RECTANGLE,前景顏色都設定為綠色,在呼叫 ui_rect 之前,設定 colour 為指定的綠 色,RDP Server 傳送過來的 rect order 以綠色矩形來顯示,幫助我們了解畫面的組成中 哪些是利用 RECTANGLE 來繪製畫面,遠端桌面系統中,很多背景都是單調的顏色,
RDP Server 利用 RECTANGLE 傳送參數後,由 RDP Client 進行繪製,可以大幅降低點 陣圖的傳送,在微軟 Windows 中利用 GDI(繪圖方面的 API)來處理;在 X window 中,rdesktop 則是利用 X Lib 的函數進行繪製,以下我們針對常使用的畫面進行分析。
圖 31. 正常的遠端登入畫面
圖 32. 利用修改後的 rdesktop 進行遠端登入
由上述比較,原本黑色的背景及灰白色的視窗中,利用修改後的 rdesktop 連線登 入,我們發現 RDP Server 在背景單純的畫面中,使用大量的 RECTANGLE 來繪製背 景,透過這樣的傳送方式可以有效節省頻寬的使用。
在桌面背景中,RDP Server 也傳遞 RECTANGLE 的命令,將畫面的背景交由 RDP Client 也就是使用者端來繪製,如圖 33.所示。透過 rect order 的方式傳送桌面背景,
參數化的指令其資料量遠小於傳送整張 bitmap 畫面的資料量。
圖 33. 利用修改後的 rdesktop 顯示遠端桌面
瞭解了桌面的畫面後,我們對 Internet Explorer 開啟網頁的畫面以及 PowerPoint 畫面進行分析,在網頁畫面的傳送中,剛開啟的網頁背景單純的畫面,會使用 RECTANGLE 的命令傳送給 RDP Client,可以看出畫面背景為綠色矩形,如圖 34.(a);
但是當改變視窗大小或是拖曳視窗後,RDP Server 會以 bitmap 命令進行更新,除了視 窗的框架外,網頁的畫面以點陣圖(bitmap)方式傳送,如圖 34.(b)。
圖 34.(a) rdesktop 顯示遠端網頁矩形特徵(剛開啟)
圖 34.(b) rdesktop 顯示遠端網頁矩形特徵(變動後)
在 PowerPoint 中,背景以及視窗的內部框架都是使用 rect order 來顯示畫面,而 較複雜的圖片則以點陣圖的方式傳送,如圖 35.。
圖 35. 利用修改後的 rdesktop 開啟遠端 PowerPoint z 多邊形(polygon)和橢圓(ellipse)
這部份的指令大多是使用在 PowerPoint 的快取圖案上,rdesktop 對於 polygone 和 ellipse 的處理,分為不透明跟透明,接下來,我們說明 rdesktop 對多邊形和橢圓命令 的實作流程。
多邊形:
在接收多邊形命令前,我們先定義多邊形的結構,基本上的架構包含了座標、顏 色、多邊形的樣式等等,多邊形其結構如下圖 36.。
圖 36. POLYGON ORDER 結構
接收到 polygon 的封包後,由 process_polygon 將資料資料從封包中讀取出來,呼 叫 ui_polygon 進行處理,在根據 fillmode 決定多邊形形狀,依定義的 brush 類型,設 定參數並呼叫 FILL_POLYGON 函數,FILL_POLYGON 則是呼叫 X Lib 中 XFIllPolygon 將圖形顯示在畫面上。程式流程方塊圖如下:
圖 37. 多邊形處理流程 process_polygon
ui_polygon
將參數從封包之料中讀取出來,並 傳送給 ui_polygon
引用了 opcode、fillmode、point、points、
brush、bgcolour、fgcolour,如果是不透明 brush 為 null,bgcolour 為 0
SET_FUNCTION
決定 fillmode
Style
FILL_POLYGON
決定多邊形的形狀,圖形樣 式,分為 EvenOddRule 和 WindingRule
brush 的樣式,在不透明的圖 形時,style 參數為 0,另外有 Hatch、Pattrn 類型
XFillPolygon 依據給定的參數,進行繪製矩形 依 opcode 決定
ROP2 的類型
在圖 37.中,提到 fillmode 決定了多邊形形狀,這個部分我們根據 X window 的繪 圖規則[11]說明,當我們決定多邊形各頂點時如圖 38.,無法確切決定樣式,根據 X window 的填充規則,分成兩種 EvenOddRule 和 WindingRule。
圖 38. 多邊形外框
EvenOddRule 就是利用一條直線,從某一點到多邊形外邊的點,如果這條直線和 多邊形交界次數是奇數的話,此點才是多邊形內部的點,也就是填充的部份,如圖 39.。
圖 39. 多邊形 EvenOddRule
WindingRule 凡是重疊的部份不管交叉幾次都是填充的部份,如圖 40.。
圖 40. 多邊形 WindingRule
瞭解了多邊形的填充模式(fillmode)後,我們針對 XFillPolygon 函數進行說明,
由於 rdesktop 建立在 X Window 平台上,因此最後需要呼叫 X Lib 的函數顯示在畫面 上,而 XFillPolygon 就是扮演這樣的角色。
XFillPolygon 的形式如下:
XFillPolygon ( display, drawable, gc, points, npoints, shape, mode ) Display:X Window 的顯示架構。
Drawable:可以是 window 或是 pixmap,差異在 window 為顯示的視窗,pixmap 可以 是一個繪圖的區塊,不一定會顯示出來。
GC:一個繪圖的環境,指定繪圖時必須使用的屬性,屬性包含顏色、寬度等。
Points:各端點的陣列。
nPoints:點的數目。
Shape:代表了圖形的形狀,分為:Convex(外凸)、NonConvex、Complex。rdesktop 將 Shape 設定為 Complex,也就是說不知道多邊形的邊是否交叉,交由 X Window 去 處理,花費較長,但是最後的圖形是正確的。
Mode : 為 各 端 點 座 標 的 位 置 , 分 為 CoordModeOrigin 和 CoorModePrevious 。 CoorModeOrigin 表示所有的端點座標都是相對於視窗的原點;CoorModePrevious 則表 示除了第一點相對於視窗的原點外,其餘各點相對於前一點的座標,rdesktop 是使用 CoorModePrevious 的設定。
Rdesktop 就是依 RDP Server 所傳遞的訊息,呼叫 XFillPolygon 將多邊形繪製於 rdesktop 連線視窗上。
橢圓形:
首先定義 Ellipse 的參數結構,如圖 41.。
圖 41. ELLIPSE ORDER 參數結構
由 process_ellipse 處理封包的參數,並將參數放入 ELLIPSE ORDER 結構中,接 著呼叫 ui_ellipse 處理,依據 opcode 決定 ROP2 參數,接著根據 brush 決定與背景的混 合模式(Solid、Hatch、Pattern),之後呼叫 DRAW_ELLIPSE,由於 rdesktop 應用在 X Window 系統中所以 DRAW_ELLIPSE 則是呼叫 X Lib 的 XDrawArc 將圖形繪出。
XDrawArc 是 X Lib 中畫弧形的函數,rdesktop 利用此函數進行橢圓的繪製,在角
度部份定義為 360 度,XDrawArc 的函數形式如下:
XDrawArc (display, drawable, gc, x, y, width, height,start_angle,stop_angle) Display:X Window 的顯示架構。
Drawable:可以是 window 或是 pixmap,差異在 window 為顯示的視窗,pixmap 可以 是一個繪圖的區塊,不一定會顯示出來。
GC:一個繪圖的環境,指定繪圖時必須使用的屬性,屬性包含顏色、寬度等。
X,Y:是圖形的左上角座標。
Width,Height:分別是橢圓中心的兩個軸的長度。
Start_angle:為弧線的起始角度,rdesktop 設為 0*。
Stop_angle:為弧線的停止角度,rdesktop 畫橢圓時設為 360*64。(*64 是 X Window 畫弧的角度計算)函式說明如圖 42.。
圖 42. rdesktop 橢圓形的定義 z 線條(Line)
主要是應用在文字的底線,首先我們依據 Line 的參數定義出 LINE_ORDER 的結 構,如下圖。
圖 43. LINE ORDER 參數結構
當收到一個 Line 命令時,rdesktop 呼叫 process_line 處理,這個函數先解開封包
內的參數,並將參數置入 LINE_ORDER 結構中,之後呼叫 rdp_parse_pen,將線條類 型(style)、寬度(width)、顏色(colour)根據收到的資料欄位設定參數,在呼叫 ui_line 進行繪製,而 ui_line 最後仍然呼叫 X Lib 的 XDrawLine 繪製線條。XDrawLine 函數形 式如下:
XDrawLine (Display, Drawable, GC, X1, Y1, X2, Y2)
XDrawArc (display, drawable, gc, x, y, width, height,start_angle,stop_angle) Display:X Window 的顯示架構。
Drawable:可以是 window 或是 pixmap,差異在 window 為顯示的視窗,pixmap 可以 是一個繪圖的區塊,不一定會顯示出來。
X1、Y1:為起始點座標 X2、Y2:為終點座標
在圖形的繪製上,不論是矩形、多邊形或是線條,其實都是依據 RDP Server 傳送 過來的封包,根據其定義的參數,參數不外乎座標、前景、背景及混合模式,之後呼 叫 X window 中的 X Lib 進行繪製,也就是說 X Lib 中的繪圖函數就是 rdesktop 和 X Window 的中介函數,透過參數的傳送在 Client 繪圖,而非直接傳送 bitmap 資料,可 以降低頻寬的使用。