2011-08-26 02:07:52 +04:00
/**
2012-10-09 07:02:04 +04:00
* FreeRDP : A Remote Desktop Protocol Implementation
2011-08-26 02:07:52 +04:00
* X11 GDI
*
* Copyright 2011 Marc - Andre Moreau < marcandre . moreau @ gmail . com >
*
* Licensed under the Apache License , Version 2.0 ( the " License " ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
2012-08-15 01:20:53 +04:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
2011-10-27 21:29:16 +04:00
# include <X11/Xlib.h>
# include <X11/Xutil.h>
2011-09-12 06:32:22 +04:00
# include <freerdp/gdi/gdi.h>
2011-10-03 04:52:17 +04:00
# include <freerdp/codec/rfx.h>
# include <freerdp/codec/nsc.h>
2011-09-12 05:22:03 +04:00
# include <freerdp/constants.h>
2011-10-03 04:28:20 +04:00
# include <freerdp/codec/color.h>
2011-10-03 07:09:13 +04:00
# include <freerdp/codec/bitmap.h>
2011-08-26 22:48:51 +04:00
2011-08-26 02:07:52 +04:00
# include "xf_gdi.h"
2013-02-10 03:10:45 +04:00
static UINT8 GDI_BS_HATCHED_PATTERNS [ ] =
2013-02-07 06:57:49 +04:00
{
2013-02-04 18:28:48 +04:00
0xFF , 0xFF , 0xFF , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , /* HS_HORIZONTAL */
0xF7 , 0xF7 , 0xF7 , 0xF7 , 0xF7 , 0xF7 , 0xF7 , 0xF7 , /* HS_VERTICAL */
0xFE , 0xFD , 0xFB , 0xF7 , 0xEF , 0xDF , 0xBF , 0x7F , /* HS_FDIAGONAL */
0x7F , 0xBF , 0xDF , 0xEF , 0xF7 , 0xFB , 0xFD , 0xFE , /* HS_BDIAGONAL */
0xF7 , 0xF7 , 0xF7 , 0x00 , 0xF7 , 0xF7 , 0xF7 , 0xF7 , /* HS_CROSS */
0x7E , 0xBD , 0xDB , 0xE7 , 0xE7 , 0xDB , 0xBD , 0x7E /* HS_DIACROSS */
} ;
2012-10-09 11:01:37 +04:00
static const BYTE xf_rop2_table [ ] =
2011-08-26 02:07:52 +04:00
{
0 ,
GXclear , /* 0 */
GXnor , /* DPon */
GXandInverted , /* DPna */
GXcopyInverted , /* Pn */
GXandReverse , /* PDna */
GXinvert , /* Dn */
GXxor , /* DPx */
GXnand , /* DPan */
GXand , /* DPa */
GXequiv , /* DPxn */
GXnoop , /* D */
GXorInverted , /* DPno */
GXcopy , /* P */
GXorReverse , /* PDno */
GXor , /* DPo */
GXset /* 1 */
} ;
2013-06-13 02:57:25 +04:00
BOOL xf_set_rop2 ( xfContext * xfc , int rop2 )
2011-08-26 02:07:52 +04:00
{
if ( ( rop2 < 0x01 ) | | ( rop2 > 0x10 ) )
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " Unsupported ROP2: %d \n " , rop2 ) ;
2012-10-09 10:31:28 +04:00
return FALSE ;
2011-08-26 02:07:52 +04:00
}
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , xf_rop2_table [ rop2 ] ) ;
2012-10-09 10:31:28 +04:00
return TRUE ;
2011-08-26 02:07:52 +04:00
}
2013-06-13 02:57:25 +04:00
BOOL xf_set_rop3 ( xfContext * xfc , int rop3 )
2011-08-26 02:07:52 +04:00
{
int function = - 1 ;
switch ( rop3 )
{
case GDI_BLACKNESS :
function = GXclear ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_DPon :
2011-08-26 02:07:52 +04:00
function = GXnor ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_DPna :
2011-08-26 02:07:52 +04:00
function = GXandInverted ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_Pn :
2011-08-26 02:07:52 +04:00
function = GXcopyInverted ;
break ;
case GDI_NOTSRCERASE :
function = GXnor ;
break ;
case GDI_DSna :
function = GXandInverted ;
break ;
case GDI_NOTSRCCOPY :
function = GXcopyInverted ;
break ;
case GDI_SRCERASE :
function = GXandReverse ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_PDna :
2011-08-26 02:07:52 +04:00
function = GXandReverse ;
break ;
case GDI_DSTINVERT :
function = GXinvert ;
break ;
case GDI_PATINVERT :
function = GXxor ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_DPan :
2011-08-26 02:07:52 +04:00
function = GXnand ;
break ;
case GDI_SRCINVERT :
function = GXxor ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_DSan :
2011-08-26 02:07:52 +04:00
function = GXnand ;
break ;
case GDI_SRCAND :
function = GXand ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_DSxn :
2011-08-26 02:07:52 +04:00
function = GXequiv ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_DPa :
2011-08-26 02:07:52 +04:00
function = GXand ;
break ;
case GDI_PDxn :
function = GXequiv ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_D :
2011-08-26 02:07:52 +04:00
function = GXnoop ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_DPno :
2011-08-26 02:07:52 +04:00
function = GXorInverted ;
break ;
case GDI_MERGEPAINT :
function = GXorInverted ;
break ;
case GDI_SRCCOPY :
function = GXcopy ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_SDno :
2011-08-26 02:07:52 +04:00
function = GXorReverse ;
break ;
case GDI_SRCPAINT :
function = GXor ;
break ;
case GDI_PATCOPY :
function = GXcopy ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_PDno :
2011-08-26 02:07:52 +04:00
function = GXorReverse ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_DPo :
2011-08-26 02:07:52 +04:00
function = GXor ;
break ;
case GDI_WHITENESS :
function = GXset ;
break ;
2012-02-13 03:12:28 +04:00
case GDI_PSDPxax :
function = GXand ;
break ;
2011-08-26 02:07:52 +04:00
default :
break ;
}
if ( function < 0 )
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " Unsupported ROP3: 0x%08X \n " , rop3 ) ;
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXclear ) ;
2012-10-09 10:31:28 +04:00
return FALSE ;
2011-08-26 02:07:52 +04:00
}
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , function ) ;
2011-08-26 02:07:52 +04:00
2012-10-09 10:31:28 +04:00
return TRUE ;
2011-08-26 02:07:52 +04:00
}
2013-06-13 02:57:25 +04:00
Pixmap xf_brush_new ( xfContext * xfc , int width , int height , int bpp , BYTE * data )
2011-10-13 23:51:07 +04:00
{
Pixmap bitmap ;
2012-10-09 11:01:37 +04:00
BYTE * cdata ;
2011-10-13 23:51:07 +04:00
XImage * image ;
2013-06-13 02:57:25 +04:00
bitmap = XCreatePixmap ( xfc - > display , xfc - > drawable , width , height , xfc - > depth ) ;
2011-10-13 23:51:07 +04:00
2012-02-13 03:12:28 +04:00
if ( data ! = NULL )
2011-10-13 23:51:07 +04:00
{
2012-02-13 03:12:28 +04:00
GC gc ;
2012-01-01 02:00:26 +04:00
2013-06-13 02:57:25 +04:00
cdata = freerdp_image_convert ( data , NULL , width , height , bpp , xfc - > bpp , xfc - > clrconv ) ;
2012-02-13 03:12:28 +04:00
2013-06-13 02:57:25 +04:00
image = XCreateImage ( xfc - > display , xfc - > visual , xfc - > depth ,
ZPixmap , 0 , ( char * ) cdata , width , height , xfc - > scanline_pad , 0 ) ;
2011-10-13 23:51:07 +04:00
2013-06-13 02:57:25 +04:00
gc = XCreateGC ( xfc - > display , xfc - > drawable , 0 , NULL ) ;
XPutImage ( xfc - > display , bitmap , gc , image , 0 , 0 , 0 , 0 , width , height ) ;
2011-10-13 23:51:07 +04:00
XFree ( image ) ;
2012-02-13 03:12:28 +04:00
2011-10-13 23:51:07 +04:00
if ( cdata ! = data )
2012-10-09 07:21:26 +04:00
free ( cdata ) ;
2012-01-01 02:00:26 +04:00
2013-06-13 02:57:25 +04:00
XFreeGC ( xfc - > display , gc ) ;
2011-10-13 23:51:07 +04:00
}
return bitmap ;
}
2013-06-13 02:57:25 +04:00
Pixmap xf_mono_bitmap_new ( xfContext * xfc , int width , int height , BYTE * data )
2011-09-12 06:32:22 +04:00
{
int scanline ;
XImage * image ;
Pixmap bitmap ;
scanline = ( width + 7 ) / 8 ;
2013-06-13 02:57:25 +04:00
bitmap = XCreatePixmap ( xfc - > display , xfc - > drawable , width , height , 1 ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
image = XCreateImage ( xfc - > display , xfc - > visual , 1 ,
2011-09-12 06:32:22 +04:00
ZPixmap , 0 , ( char * ) data , width , height , 8 , scanline ) ;
2013-06-13 02:57:25 +04:00
XPutImage ( xfc - > display , bitmap , xfc - > gc_mono , image , 0 , 0 , 0 , 0 , width , height ) ;
2011-09-12 06:32:22 +04:00
XFree ( image ) ;
return bitmap ;
}
2011-11-22 04:41:49 +04:00
void xf_gdi_palette_update ( rdpContext * context , PALETTE_UPDATE * palette )
2011-08-26 02:07:52 +04:00
{
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
CopyMemory ( xfc - > clrconv - > palette , palette , sizeof ( rdpPalette ) ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
2011-11-22 04:41:49 +04:00
void xf_gdi_set_bounds ( rdpContext * context , rdpBounds * bounds )
2011-08-26 02:07:52 +04:00
{
2011-08-26 22:48:51 +04:00
XRectangle clip ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-08-26 02:07:52 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2011-08-26 22:48:51 +04:00
if ( bounds ! = NULL )
{
clip . x = bounds - > left ;
clip . y = bounds - > top ;
clip . width = bounds - > right - bounds - > left + 1 ;
clip . height = bounds - > bottom - bounds - > top + 1 ;
2013-06-13 02:57:25 +04:00
XSetClipRectangles ( xfc - > display , xfc - > gc , 0 , 0 , & clip , 1 , YXBanded ) ;
2011-08-26 22:48:51 +04:00
}
else
{
2013-06-13 02:57:25 +04:00
XSetClipMask ( xfc - > display , xfc - > gc , None ) ;
2011-08-26 22:48:51 +04:00
}
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
2011-11-22 03:11:43 +04:00
void xf_gdi_dstblt ( rdpContext * context , DSTBLT_ORDER * dstblt )
2011-08-26 02:07:52 +04:00
{
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-08-26 22:48:51 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_set_rop3 ( xfc , gdi_rop3_code ( dstblt - > bRop ) ) ;
2011-08-26 02:07:52 +04:00
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XFillRectangle ( xfc - > display , xfc - > drawing , xfc - > gc ,
2011-08-26 22:48:51 +04:00
dstblt - > nLeftRect , dstblt - > nTopRect ,
dstblt - > nWidth , dstblt - > nHeight ) ;
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2011-08-26 22:48:51 +04:00
{
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
XFillRectangle ( xfc - > display , xfc - > drawable , xfc - > gc , dstblt - > nLeftRect , dstblt - > nTopRect , dstblt - > nWidth , dstblt - > nHeight ) ;
}
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , dstblt - > nLeftRect , dstblt - > nTopRect , dstblt - > nWidth , dstblt - > nHeight ) ;
2011-08-26 22:48:51 +04:00
}
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
2011-11-22 03:11:43 +04:00
void xf_gdi_patblt ( rdpContext * context , PATBLT_ORDER * patblt )
2011-08-26 02:07:52 +04:00
{
2011-09-12 06:32:22 +04:00
Pixmap pattern ;
2011-10-21 01:28:59 +04:00
rdpBrush * brush ;
2012-10-09 11:26:39 +04:00
UINT32 foreColor ;
UINT32 backColor ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2011-09-12 06:32:22 +04:00
brush = & patblt - > brush ;
2013-06-13 02:57:25 +04:00
xf_set_rop3 ( xfc , gdi_rop3_code ( patblt - > bRop ) ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
foreColor = freerdp_color_convert_var ( patblt - > foreColor , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
backColor = freerdp_color_convert_var ( patblt - > backColor , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
2011-09-12 06:32:22 +04:00
if ( brush - > style = = GDI_BS_SOLID )
{
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetForeground ( xfc - > display , xfc - > gc , foreColor ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
XFillRectangle ( xfc - > display , xfc - > drawing , xfc - > gc ,
2011-09-12 06:32:22 +04:00
patblt - > nLeftRect , patblt - > nTopRect , patblt - > nWidth , patblt - > nHeight ) ;
}
2013-02-04 18:28:48 +04:00
else if ( brush - > style = = GDI_BS_HATCHED )
{
2013-06-13 02:57:25 +04:00
pattern = xf_mono_bitmap_new ( xfc , 8 , 8 , GDI_BS_HATCHED_PATTERNS + 8 * brush - > hatch ) ;
2013-02-04 18:28:48 +04:00
2013-06-13 02:57:25 +04:00
XSetForeground ( xfc - > display , xfc - > gc , backColor ) ;
XSetBackground ( xfc - > display , xfc - > gc , foreColor ) ;
XSetFillStyle ( xfc - > display , xfc - > gc , FillOpaqueStippled ) ;
XSetStipple ( xfc - > display , xfc - > gc , pattern ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , brush - > x , brush - > y ) ;
2013-02-04 18:28:48 +04:00
2013-06-13 02:57:25 +04:00
XFillRectangle ( xfc - > display , xfc - > drawing , xfc - > gc ,
2013-02-04 18:28:48 +04:00
patblt - > nLeftRect , patblt - > nTopRect , patblt - > nWidth , patblt - > nHeight ) ;
2013-06-13 02:57:25 +04:00
XFreePixmap ( xfc - > display , pattern ) ;
2013-02-04 18:28:48 +04:00
}
2011-09-12 06:32:22 +04:00
else if ( brush - > style = = GDI_BS_PATTERN )
{
if ( brush - > bpp > 1 )
{
2013-06-13 02:57:25 +04:00
pattern = xf_brush_new ( xfc , 8 , 8 , brush - > bpp , brush - > data ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillTiled ) ;
XSetTile ( xfc - > display , xfc - > gc , pattern ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , brush - > x , brush - > y ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
XFillRectangle ( xfc - > display , xfc - > drawing , xfc - > gc ,
2011-09-12 06:32:22 +04:00
patblt - > nLeftRect , patblt - > nTopRect , patblt - > nWidth , patblt - > nHeight ) ;
2013-06-13 02:57:25 +04:00
XSetTile ( xfc - > display , xfc - > gc , xfc - > primary ) ;
2012-01-01 02:00:26 +04:00
2013-06-13 02:57:25 +04:00
XFreePixmap ( xfc - > display , pattern ) ;
2011-09-12 06:32:22 +04:00
}
else
{
2013-06-13 02:57:25 +04:00
pattern = xf_mono_bitmap_new ( xfc , 8 , 8 , brush - > data ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
XSetForeground ( xfc - > display , xfc - > gc , backColor ) ;
XSetBackground ( xfc - > display , xfc - > gc , foreColor ) ;
XSetFillStyle ( xfc - > display , xfc - > gc , FillOpaqueStippled ) ;
XSetStipple ( xfc - > display , xfc - > gc , pattern ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , brush - > x , brush - > y ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
XFillRectangle ( xfc - > display , xfc - > drawing , xfc - > gc ,
2011-09-12 06:32:22 +04:00
patblt - > nLeftRect , patblt - > nTopRect , patblt - > nWidth , patblt - > nHeight ) ;
2012-01-01 02:00:26 +04:00
2013-06-13 02:57:25 +04:00
XFreePixmap ( xfc - > display , pattern ) ;
2011-09-12 06:32:22 +04:00
}
}
else
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " unimplemented brush style:%d \n " , brush - > style ) ;
2011-09-12 06:32:22 +04:00
}
2011-08-26 02:07:52 +04:00
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2011-09-12 06:32:22 +04:00
{
2013-12-02 06:41:58 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
if ( xfc - > remote_app ! = TRUE )
{
XCopyArea ( xfc - > display , xfc - > primary , xfc - > drawable , xfc - > gc , patblt - > nLeftRect , patblt - > nTopRect , patblt - > nWidth , patblt - > nHeight , patblt - > nLeftRect , patblt - > nTopRect ) ;
}
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , patblt - > nLeftRect , patblt - > nTopRect , patblt - > nWidth , patblt - > nHeight ) ;
2011-09-12 06:32:22 +04:00
}
2011-10-21 07:15:18 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
2011-11-22 03:11:43 +04:00
void xf_gdi_scrblt ( rdpContext * context , SCRBLT_ORDER * scrblt )
2011-08-26 02:07:52 +04:00
{
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-08-26 22:48:51 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_set_rop3 ( xfc , gdi_rop3_code ( scrblt - > bRop ) ) ;
2011-09-23 08:06:39 +04:00
2013-06-13 02:57:25 +04:00
XCopyArea ( xfc - > display , xfc - > primary , xfc - > drawing , xfc - > gc , scrblt - > nXSrc , scrblt - > nYSrc ,
2011-08-26 22:48:51 +04:00
scrblt - > nWidth , scrblt - > nHeight , scrblt - > nLeftRect , scrblt - > nTopRect ) ;
2011-08-26 02:07:52 +04:00
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2011-08-26 22:48:51 +04:00
{
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
if ( xfc - > unobscured )
{
XCopyArea ( xfc - > display , xfc - > drawable , xfc - > drawable , xfc - > gc , scrblt - > nXSrc , scrblt - > nYSrc ,
scrblt - > nWidth , scrblt - > nHeight , scrblt - > nLeftRect , scrblt - > nTopRect ) ;
}
}
else
{
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
XCopyArea ( xfc - > display , xfc - > primary , xfc - > drawable , xfc - > gc , scrblt - > nLeftRect , scrblt - > nTopRect , scrblt - > nWidth , scrblt - > nHeight , scrblt - > nLeftRect , scrblt - > nTopRect ) ;
}
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , scrblt - > nLeftRect , scrblt - > nTopRect , scrblt - > nWidth , scrblt - > nHeight ) ;
2011-08-26 22:48:51 +04:00
}
2011-10-21 07:15:18 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
2011-11-22 03:11:43 +04:00
void xf_gdi_opaque_rect ( rdpContext * context , OPAQUE_RECT_ORDER * opaque_rect )
2011-08-26 02:07:52 +04:00
{
2012-10-09 11:26:39 +04:00
UINT32 color ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-08-26 22:48:51 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
color = freerdp_color_convert_var ( opaque_rect - > color , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
2011-08-26 02:07:52 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetForeground ( xfc - > display , xfc - > gc , color ) ;
2012-01-10 03:45:36 +04:00
2013-06-13 02:57:25 +04:00
XFillRectangle ( xfc - > display , xfc - > drawing , xfc - > gc ,
2011-08-26 22:48:51 +04:00
opaque_rect - > nLeftRect , opaque_rect - > nTopRect ,
opaque_rect - > nWidth , opaque_rect - > nHeight ) ;
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2011-08-26 22:48:51 +04:00
{
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
XFillRectangle ( xfc - > display , xfc - > drawable , xfc - > gc ,
opaque_rect - > nLeftRect , opaque_rect - > nTopRect ,
opaque_rect - > nWidth , opaque_rect - > nHeight ) ;
}
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , opaque_rect - > nLeftRect , opaque_rect - > nTopRect ,
2011-09-23 08:06:39 +04:00
opaque_rect - > nWidth , opaque_rect - > nHeight ) ;
2011-08-26 22:48:51 +04:00
}
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
2011-11-22 03:11:43 +04:00
void xf_gdi_multi_opaque_rect ( rdpContext * context , MULTI_OPAQUE_RECT_ORDER * multi_opaque_rect )
2011-08-26 02:07:52 +04:00
{
2011-08-26 22:48:51 +04:00
int i ;
2012-10-09 11:26:39 +04:00
UINT32 color ;
2011-08-26 22:48:51 +04:00
DELTA_RECT * rectangle ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-08-26 22:48:51 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
color = freerdp_color_convert_var ( multi_opaque_rect - > color , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
2011-08-26 02:07:52 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetForeground ( xfc - > display , xfc - > gc , color ) ;
2011-08-26 22:48:51 +04:00
for ( i = 1 ; i < multi_opaque_rect - > numRectangles + 1 ; i + + )
{
rectangle = & multi_opaque_rect - > rectangles [ i ] ;
2013-06-13 02:57:25 +04:00
XFillRectangle ( xfc - > display , xfc - > drawing , xfc - > gc ,
2011-08-26 22:48:51 +04:00
rectangle - > left , rectangle - > top ,
rectangle - > width , rectangle - > height ) ;
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2011-08-26 22:48:51 +04:00
{
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
XFillRectangle ( xfc - > display , xfc - > drawable , xfc - > gc ,
rectangle - > left , rectangle - > top ,
rectangle - > width , rectangle - > height ) ;
}
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , rectangle - > left , rectangle - > top , rectangle - > width , rectangle - > height ) ;
2011-08-26 22:48:51 +04:00
}
}
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
2012-02-13 04:41:39 +04:00
void xf_gdi_draw_nine_grid ( rdpContext * context , DRAW_NINE_GRID_ORDER * draw_nine_grid )
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " DrawNineGrid \n " ) ;
2012-02-13 04:41:39 +04:00
}
2011-11-22 03:11:43 +04:00
void xf_gdi_line_to ( rdpContext * context , LINE_TO_ORDER * line_to )
2011-08-26 02:07:52 +04:00
{
2012-10-09 11:26:39 +04:00
UINT32 color ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-08-26 02:07:52 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_set_rop2 ( xfc , line_to - > bRop2 ) ;
color = freerdp_color_convert_var ( line_to - > penColor , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetForeground ( xfc - > display , xfc - > gc , color ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
XDrawLine ( xfc - > display , xfc - > drawing , xfc - > gc ,
2011-09-12 06:32:22 +04:00
line_to - > nXStart , line_to - > nYStart , line_to - > nXEnd , line_to - > nYEnd ) ;
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2011-09-12 06:32:22 +04:00
{
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
XDrawLine ( xfc - > display , xfc - > drawable , xfc - > gc ,
line_to - > nXStart , line_to - > nYStart , line_to - > nXEnd , line_to - > nYEnd ) ;
}
2012-01-14 04:07:27 +04:00
int width , height ;
width = line_to - > nXStart - line_to - > nXEnd ;
height = line_to - > nYStart - line_to - > nYEnd ;
2011-09-23 08:06:39 +04:00
2012-01-14 04:07:27 +04:00
if ( width < 0 )
width * = ( - 1 ) ;
2011-09-23 08:06:39 +04:00
2012-01-14 04:07:27 +04:00
if ( height < 0 )
height * = ( - 1 ) ;
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , line_to - > nXStart , line_to - > nYStart , width , height ) ;
2011-09-23 08:06:39 +04:00
2011-09-12 06:32:22 +04:00
}
2011-10-21 07:15:18 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
2011-11-22 03:11:43 +04:00
void xf_gdi_polyline ( rdpContext * context , POLYLINE_ORDER * polyline )
2011-08-26 02:07:52 +04:00
{
2011-09-12 06:32:22 +04:00
int i ;
2011-10-10 05:43:31 +04:00
int x , y ;
2011-10-13 02:10:54 +04:00
int x1 , y1 ;
int x2 , y2 ;
int npoints ;
2012-10-09 11:26:39 +04:00
UINT32 color ;
2011-09-12 06:32:22 +04:00
XPoint * points ;
2011-10-10 05:43:31 +04:00
int width , height ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_set_rop2 ( xfc , polyline - > bRop2 ) ;
color = freerdp_color_convert_var ( polyline - > penColor , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
2011-09-12 06:32:22 +04:00
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetForeground ( xfc - > display , xfc - > gc , color ) ;
2011-09-12 06:32:22 +04:00
2011-10-13 02:10:54 +04:00
npoints = polyline - > numPoints + 1 ;
2012-10-09 07:21:26 +04:00
points = malloc ( sizeof ( XPoint ) * npoints ) ;
2011-10-13 02:10:54 +04:00
points [ 0 ] . x = polyline - > xStart ;
points [ 0 ] . y = polyline - > yStart ;
2011-09-12 06:32:22 +04:00
for ( i = 0 ; i < polyline - > numPoints ; i + + )
{
2011-10-13 02:10:54 +04:00
points [ i + 1 ] . x = polyline - > points [ i ] . x ;
points [ i + 1 ] . y = polyline - > points [ i ] . y ;
2011-09-12 06:32:22 +04:00
}
2013-06-13 02:57:25 +04:00
XDrawLines ( xfc - > display , xfc - > drawing , xfc - > gc , points , npoints , CoordModePrevious ) ;
2011-08-26 02:07:52 +04:00
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2011-09-12 06:32:22 +04:00
{
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
XDrawLines ( xfc - > display , xfc - > drawable , xfc - > gc , points , npoints , CoordModePrevious ) ;
}
2011-10-13 02:10:54 +04:00
x1 = points [ 0 ] . x ;
y1 = points [ 0 ] . y ;
2011-10-13 00:00:10 +04:00
2011-10-13 02:10:54 +04:00
for ( i = 1 ; i < npoints ; i + + )
2011-09-23 08:06:39 +04:00
{
2011-10-13 02:10:54 +04:00
x2 = points [ i ] . x + x1 ;
y2 = points [ i ] . y + y1 ;
2011-10-10 05:43:31 +04:00
2011-10-13 02:10:54 +04:00
x = ( x2 < x1 ) ? x2 : x1 ;
width = ( x2 > x1 ) ? x2 - x1 : x1 - x2 ;
2011-10-27 21:29:16 +04:00
2011-10-13 02:10:54 +04:00
y = ( y2 < y1 ) ? y2 : y1 ;
height = ( y2 > y1 ) ? y2 - y1 : y1 - y2 ;
x1 = x2 ;
y1 = y2 ;
2011-10-10 05:43:31 +04:00
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , x , y , width , height ) ;
2011-09-23 08:06:39 +04:00
}
2011-09-12 06:32:22 +04:00
}
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
2012-10-09 07:21:26 +04:00
free ( points ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
2011-11-22 03:11:43 +04:00
void xf_gdi_memblt ( rdpContext * context , MEMBLT_ORDER * memblt )
2011-10-05 05:29:01 +04:00
{
2011-10-13 23:51:07 +04:00
xfBitmap * bitmap ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-10-05 05:29:01 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2011-10-13 23:51:07 +04:00
bitmap = ( xfBitmap * ) memblt - > bitmap ;
2013-06-13 02:57:25 +04:00
xf_set_rop3 ( xfc , gdi_rop3_code ( memblt - > bRop ) ) ;
2011-10-12 04:21:35 +04:00
2013-06-13 02:57:25 +04:00
XCopyArea ( xfc - > display , bitmap - > pixmap , xfc - > drawing , xfc - > gc ,
2011-10-13 23:51:07 +04:00
memblt - > nXSrc , memblt - > nYSrc , memblt - > nWidth , memblt - > nHeight ,
2011-10-05 05:29:01 +04:00
memblt - > nLeftRect , memblt - > nTopRect ) ;
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2011-10-05 05:29:01 +04:00
{
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
XCopyArea ( xfc - > display , bitmap - > pixmap , xfc - > drawable , xfc - > gc ,
memblt - > nXSrc , memblt - > nYSrc , memblt - > nWidth , memblt - > nHeight ,
memblt - > nLeftRect , memblt - > nTopRect ) ;
}
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , memblt - > nLeftRect , memblt - > nTopRect , memblt - > nWidth , memblt - > nHeight ) ;
2011-10-05 05:29:01 +04:00
}
2011-10-21 07:15:18 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-10-05 05:29:01 +04:00
}
2011-11-22 03:11:43 +04:00
void xf_gdi_mem3blt ( rdpContext * context , MEM3BLT_ORDER * mem3blt )
2011-10-05 05:29:01 +04:00
{
2012-02-13 03:12:28 +04:00
rdpBrush * brush ;
xfBitmap * bitmap ;
2012-10-09 11:26:39 +04:00
UINT32 foreColor ;
UINT32 backColor ;
2012-02-13 03:12:28 +04:00
Pixmap pattern = 0 ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2012-02-13 03:12:28 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2012-02-13 03:12:28 +04:00
brush = & mem3blt - > brush ;
bitmap = ( xfBitmap * ) mem3blt - > bitmap ;
2013-06-13 02:57:25 +04:00
xf_set_rop3 ( xfc , gdi_rop3_code ( mem3blt - > bRop ) ) ;
foreColor = freerdp_color_convert_var ( mem3blt - > foreColor , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
backColor = freerdp_color_convert_var ( mem3blt - > backColor , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
2012-02-13 03:12:28 +04:00
if ( brush - > style = = GDI_BS_PATTERN )
{
if ( brush - > bpp > 1 )
{
2013-06-13 02:57:25 +04:00
pattern = xf_brush_new ( xfc , 8 , 8 , brush - > bpp , brush - > data ) ;
2012-02-13 03:12:28 +04:00
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillTiled ) ;
XSetTile ( xfc - > display , xfc - > gc , pattern ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , brush - > x , brush - > y ) ;
2012-02-13 03:12:28 +04:00
}
else
{
2013-06-13 02:57:25 +04:00
pattern = xf_mono_bitmap_new ( xfc , 8 , 8 , brush - > data ) ;
2012-02-13 03:12:28 +04:00
2013-06-13 02:57:25 +04:00
XSetForeground ( xfc - > display , xfc - > gc , backColor ) ;
XSetBackground ( xfc - > display , xfc - > gc , foreColor ) ;
XSetFillStyle ( xfc - > display , xfc - > gc , FillOpaqueStippled ) ;
XSetStipple ( xfc - > display , xfc - > gc , pattern ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , brush - > x , brush - > y ) ;
2012-02-13 03:12:28 +04:00
}
}
else if ( brush - > style = = GDI_BS_SOLID )
{
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetForeground ( xfc - > display , xfc - > gc , backColor ) ;
XSetBackground ( xfc - > display , xfc - > gc , foreColor ) ;
2012-02-13 04:41:39 +04:00
2013-06-13 02:57:25 +04:00
XSetTSOrigin ( xfc - > display , xfc - > gc , brush - > x , brush - > y ) ;
2012-02-13 03:12:28 +04:00
}
else
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " Mem3Blt unimplemented brush style:%d \n " , brush - > style ) ;
2012-02-13 03:12:28 +04:00
}
2013-06-13 02:57:25 +04:00
XCopyArea ( xfc - > display , bitmap - > pixmap , xfc - > drawing , xfc - > gc ,
2012-02-13 03:12:28 +04:00
mem3blt - > nXSrc , mem3blt - > nYSrc , mem3blt - > nWidth , mem3blt - > nHeight ,
mem3blt - > nLeftRect , mem3blt - > nTopRect ) ;
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2012-02-13 03:12:28 +04:00
{
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
XCopyArea ( xfc - > display , bitmap - > pixmap , xfc - > drawable , xfc - > gc ,
mem3blt - > nXSrc , mem3blt - > nYSrc , mem3blt - > nWidth , mem3blt - > nHeight ,
mem3blt - > nLeftRect , mem3blt - > nTopRect ) ;
}
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , mem3blt - > nLeftRect , mem3blt - > nTopRect , mem3blt - > nWidth , mem3blt - > nHeight ) ;
2012-02-13 03:12:28 +04:00
}
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , 0 , 0 ) ;
2012-02-13 03:12:28 +04:00
if ( pattern ! = 0 )
2013-06-13 02:57:25 +04:00
XFreePixmap ( xfc - > display , pattern ) ;
2012-02-13 03:12:28 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2012-02-13 02:14:59 +04:00
}
void xf_gdi_polygon_sc ( rdpContext * context , POLYGON_SC_ORDER * polygon_sc )
{
int i , npoints ;
XPoint * points ;
2012-10-09 11:26:39 +04:00
UINT32 brush_color ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2012-02-13 02:14:59 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_set_rop2 ( xfc , polygon_sc - > bRop2 ) ;
brush_color = freerdp_color_convert_var ( polygon_sc - > brushColor , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
2012-02-13 02:14:59 +04:00
npoints = polygon_sc - > numPoints + 1 ;
2012-10-09 07:21:26 +04:00
points = malloc ( sizeof ( XPoint ) * npoints ) ;
2012-02-13 02:14:59 +04:00
points [ 0 ] . x = polygon_sc - > xStart ;
points [ 0 ] . y = polygon_sc - > yStart ;
for ( i = 0 ; i < polygon_sc - > numPoints ; i + + )
{
points [ i + 1 ] . x = polygon_sc - > points [ i ] . x ;
points [ i + 1 ] . y = polygon_sc - > points [ i ] . y ;
}
switch ( polygon_sc - > fillMode )
{
case 1 : /* alternate */
2013-06-13 02:57:25 +04:00
XSetFillRule ( xfc - > display , xfc - > gc , EvenOddRule ) ;
2012-02-13 02:14:59 +04:00
break ;
case 2 : /* winding */
2013-06-13 02:57:25 +04:00
XSetFillRule ( xfc - > display , xfc - > gc , WindingRule ) ;
2012-02-13 02:14:59 +04:00
break ;
default :
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " PolygonSC unknown fillMode: %d \n " , polygon_sc - > fillMode ) ;
2012-02-13 02:14:59 +04:00
break ;
}
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetForeground ( xfc - > display , xfc - > gc , brush_color ) ;
2012-02-13 02:14:59 +04:00
2013-06-13 02:57:25 +04:00
XFillPolygon ( xfc - > display , xfc - > drawing , xfc - > gc ,
2012-02-13 02:14:59 +04:00
points , npoints , Complex , CoordModePrevious ) ;
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2012-02-13 02:14:59 +04:00
{
2013-06-13 02:57:25 +04:00
XFillPolygon ( xfc - > display , xfc - > drawable , xfc - > gc ,
2012-02-13 02:14:59 +04:00
points , npoints , Complex , CoordModePrevious ) ;
}
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
2012-10-09 07:21:26 +04:00
free ( points ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2012-02-13 02:14:59 +04:00
}
void xf_gdi_polygon_cb ( rdpContext * context , POLYGON_CB_ORDER * polygon_cb )
{
int i , npoints ;
XPoint * points ;
Pixmap pattern ;
rdpBrush * brush ;
2012-10-09 11:26:39 +04:00
UINT32 foreColor ;
UINT32 backColor ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-10-05 05:29:01 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2012-02-13 02:14:59 +04:00
brush = & ( polygon_cb - > brush ) ;
2013-06-13 02:57:25 +04:00
xf_set_rop2 ( xfc , polygon_cb - > bRop2 ) ;
foreColor = freerdp_color_convert_var ( polygon_cb - > foreColor , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
backColor = freerdp_color_convert_var ( polygon_cb - > backColor , context - > settings - > ColorDepth , xfc - > bpp , xfc - > clrconv ) ;
2012-02-13 02:14:59 +04:00
npoints = polygon_cb - > numPoints + 1 ;
2012-10-09 07:21:26 +04:00
points = malloc ( sizeof ( XPoint ) * npoints ) ;
2012-02-13 02:14:59 +04:00
points [ 0 ] . x = polygon_cb - > xStart ;
points [ 0 ] . y = polygon_cb - > yStart ;
for ( i = 0 ; i < polygon_cb - > numPoints ; i + + )
{
points [ i + 1 ] . x = polygon_cb - > points [ i ] . x ;
points [ i + 1 ] . y = polygon_cb - > points [ i ] . y ;
}
switch ( polygon_cb - > fillMode )
{
2013-12-10 21:30:25 +04:00
case GDI_FILL_ALTERNATE : /* alternate */
2013-06-13 02:57:25 +04:00
XSetFillRule ( xfc - > display , xfc - > gc , EvenOddRule ) ;
2012-02-13 02:14:59 +04:00
break ;
2013-12-10 21:30:25 +04:00
case GDI_FILL_WINDING : /* winding */
2013-06-13 02:57:25 +04:00
XSetFillRule ( xfc - > display , xfc - > gc , WindingRule ) ;
2012-02-13 02:14:59 +04:00
break ;
default :
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " PolygonCB unknown fillMode: %d \n " , polygon_cb - > fillMode ) ;
2012-02-13 02:14:59 +04:00
break ;
}
if ( brush - > style = = GDI_BS_PATTERN )
{
if ( brush - > bpp > 1 )
{
2013-06-13 02:57:25 +04:00
pattern = xf_brush_new ( xfc , 8 , 8 , brush - > bpp , brush - > data ) ;
2012-02-13 02:14:59 +04:00
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillTiled ) ;
XSetTile ( xfc - > display , xfc - > gc , pattern ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , brush - > x , brush - > y ) ;
2012-02-13 02:14:59 +04:00
2013-06-13 02:57:25 +04:00
XFillPolygon ( xfc - > display , xfc - > drawing , xfc - > gc ,
2012-02-13 02:14:59 +04:00
points , npoints , Complex , CoordModePrevious ) ;
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2012-02-13 02:14:59 +04:00
{
2013-06-13 02:57:25 +04:00
XFillPolygon ( xfc - > display , xfc - > drawable , xfc - > gc ,
2012-02-13 02:14:59 +04:00
points , npoints , Complex , CoordModePrevious ) ;
}
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , 0 , 0 ) ;
XFreePixmap ( xfc - > display , pattern ) ;
2012-02-13 02:14:59 +04:00
}
else
{
2013-06-13 02:57:25 +04:00
pattern = xf_mono_bitmap_new ( xfc , 8 , 8 , brush - > data ) ;
2012-02-13 02:14:59 +04:00
2013-06-13 02:57:25 +04:00
XSetForeground ( xfc - > display , xfc - > gc , backColor ) ;
XSetBackground ( xfc - > display , xfc - > gc , foreColor ) ;
2012-02-13 02:14:59 +04:00
if ( polygon_cb - > backMode = = BACKMODE_TRANSPARENT )
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillStippled ) ;
2012-02-13 02:14:59 +04:00
else if ( polygon_cb - > backMode = = BACKMODE_OPAQUE )
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillOpaqueStippled ) ;
2012-02-13 02:14:59 +04:00
2013-06-13 02:57:25 +04:00
XSetStipple ( xfc - > display , xfc - > gc , pattern ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , brush - > x , brush - > y ) ;
2012-02-13 02:14:59 +04:00
2013-06-13 02:57:25 +04:00
XFillPolygon ( xfc - > display , xfc - > drawing , xfc - > gc ,
2012-02-13 02:14:59 +04:00
points , npoints , Complex , CoordModePrevious ) ;
2013-06-13 02:57:25 +04:00
if ( xfc - > drawing = = xfc - > primary )
2012-02-13 02:14:59 +04:00
{
2013-06-13 02:57:25 +04:00
XFillPolygon ( xfc - > display , xfc - > drawable , xfc - > gc ,
2012-02-13 02:14:59 +04:00
points , npoints , Complex , CoordModePrevious ) ;
}
2013-06-13 02:57:25 +04:00
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
XSetTSOrigin ( xfc - > display , xfc - > gc , 0 , 0 ) ;
XFreePixmap ( xfc - > display , pattern ) ;
2012-02-13 02:14:59 +04:00
}
}
else
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " PolygonCB unimplemented brush style:%d \n " , brush - > style ) ;
2012-02-13 02:14:59 +04:00
}
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
2012-10-09 07:21:26 +04:00
free ( points ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2012-02-13 02:14:59 +04:00
}
void xf_gdi_ellipse_sc ( rdpContext * context , ELLIPSE_SC_ORDER * ellipse_sc )
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " EllipseSC \n " ) ;
2012-02-13 02:14:59 +04:00
}
void xf_gdi_ellipse_cb ( rdpContext * context , ELLIPSE_CB_ORDER * ellipse_cb )
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " EllipseCB \n " ) ;
2011-10-05 05:29:01 +04:00
}
2011-11-25 20:30:15 +04:00
void xf_gdi_surface_frame_marker ( rdpContext * context , SURFACE_FRAME_MARKER * surface_frame_marker )
2011-11-25 14:48:51 +04:00
{
2013-01-17 08:58:01 +04:00
rdpSettings * settings ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2012-05-26 10:41:38 +04:00
2013-06-13 02:57:25 +04:00
settings = xfc - > instance - > settings ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2012-05-26 10:41:38 +04:00
switch ( surface_frame_marker - > frameAction )
{
case SURFACECMD_FRAMEACTION_BEGIN :
2013-06-13 02:57:25 +04:00
xfc - > frame_begin = TRUE ;
xfc - > frame_x1 = 0 ;
xfc - > frame_y1 = 0 ;
xfc - > frame_x2 = 0 ;
xfc - > frame_y2 = 0 ;
2012-05-26 10:41:38 +04:00
break ;
case SURFACECMD_FRAMEACTION_END :
2013-06-13 02:57:25 +04:00
xfc - > frame_begin = FALSE ;
if ( ( xfc - > frame_x2 > xfc - > frame_x1 ) & & ( xfc - > frame_y2 > xfc - > frame_y1 ) )
2012-05-26 10:41:38 +04:00
{
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , xfc - > frame_x1 , xfc - > frame_y1 ,
xfc - > frame_x2 - xfc - > frame_x1 , xfc - > frame_y2 - xfc - > frame_y1 ) ;
2012-05-26 10:41:38 +04:00
}
2013-01-17 08:58:01 +04:00
if ( settings - > FrameAcknowledge > 0 )
{
2013-06-13 02:57:25 +04:00
IFCALL ( xfc - > instance - > update - > SurfaceFrameAcknowledge , context , surface_frame_marker - > frameId ) ;
2013-01-17 08:58:01 +04:00
}
2012-05-26 10:41:38 +04:00
break ;
}
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2012-05-26 10:41:38 +04:00
}
2011-11-25 14:48:51 +04:00
2013-06-13 02:57:25 +04:00
static void xf_gdi_surface_update_frame ( xfContext * xfc , UINT16 tx , UINT16 ty , UINT16 width , UINT16 height )
2012-05-26 10:41:38 +04:00
{
2013-06-13 02:57:25 +04:00
if ( ! xfc - > remote_app )
2012-05-26 10:41:38 +04:00
{
2013-06-13 02:57:25 +04:00
if ( xfc - > frame_begin )
2012-05-26 10:41:38 +04:00
{
2013-06-13 02:57:25 +04:00
if ( xfc - > frame_x2 > xfc - > frame_x1 & & xfc - > frame_y2 > xfc - > frame_y1 )
2012-05-26 10:41:38 +04:00
{
2013-06-13 02:57:25 +04:00
xfc - > frame_x1 = MIN ( xfc - > frame_x1 , tx ) ;
xfc - > frame_y1 = MIN ( xfc - > frame_y1 , ty ) ;
xfc - > frame_x2 = MAX ( xfc - > frame_x2 , tx + width ) ;
xfc - > frame_y2 = MAX ( xfc - > frame_y2 , ty + height ) ;
2012-05-26 10:41:38 +04:00
}
else
{
2013-06-13 02:57:25 +04:00
xfc - > frame_x1 = tx ;
xfc - > frame_y1 = ty ;
xfc - > frame_x2 = tx + width ;
xfc - > frame_y2 = ty + height ;
2012-05-26 10:41:38 +04:00
}
}
else
{
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , tx , ty , width , height ) ;
2012-05-26 10:41:38 +04:00
}
}
else
{
2013-06-13 02:57:25 +04:00
gdi_InvalidateRegion ( xfc - > hdc , tx , ty , width , height ) ;
2012-05-26 10:41:38 +04:00
}
2011-11-25 14:48:51 +04:00
}
2011-11-22 04:41:49 +04:00
void xf_gdi_surface_bits ( rdpContext * context , SURFACE_BITS_COMMAND * surface_bits_command )
2011-08-26 02:07:52 +04:00
{
2011-09-12 05:22:03 +04:00
int i , tx , ty ;
2011-09-19 06:34:19 +04:00
XImage * image ;
2011-09-12 05:22:03 +04:00
RFX_MESSAGE * message ;
2013-06-13 02:57:25 +04:00
xfContext * xfc = ( xfContext * ) context ;
2011-09-12 05:22:03 +04:00
2013-06-13 02:57:25 +04:00
xf_lock_x11 ( xfc , FALSE ) ;
2013-02-07 06:57:49 +04:00
2013-01-12 17:49:01 +04:00
if ( surface_bits_command - > codecID = = RDP_CODEC_ID_REMOTEFX )
2011-09-12 05:22:03 +04:00
{
2014-06-05 02:03:25 +04:00
message = rfx_process_message ( xfc - > rfx ,
2011-11-22 04:41:49 +04:00
surface_bits_command - > bitmapData , surface_bits_command - > bitmapDataLength ) ;
2011-09-12 05:22:03 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
2011-09-12 05:22:03 +04:00
2013-06-13 02:57:25 +04:00
XSetClipRectangles ( xfc - > display , xfc - > gc ,
2011-09-12 05:22:03 +04:00
surface_bits_command - > destLeft , surface_bits_command - > destTop ,
2013-08-14 01:18:59 +04:00
( XRectangle * ) message - > rects , message - > numRects , YXBanded ) ;
2011-08-26 02:07:52 +04:00
2011-09-12 05:22:03 +04:00
/* Draw the tiles to primary surface, each is 64x64. */
2013-08-14 01:18:59 +04:00
for ( i = 0 ; i < message - > numTiles ; i + + )
2011-09-12 05:22:03 +04:00
{
2013-06-13 02:57:25 +04:00
image = XCreateImage ( xfc - > display , xfc - > visual , 24 , ZPixmap , 0 ,
2011-09-12 05:22:03 +04:00
( char * ) message - > tiles [ i ] - > data , 64 , 64 , 32 , 0 ) ;
tx = message - > tiles [ i ] - > x + surface_bits_command - > destLeft ;
ty = message - > tiles [ i ] - > y + surface_bits_command - > destTop ;
2013-06-13 02:57:25 +04:00
XPutImage ( xfc - > display , xfc - > primary , xfc - > gc , image , 0 , 0 , tx , ty , 64 , 64 ) ;
2011-09-12 05:22:03 +04:00
XFree ( image ) ;
}
/* Copy the updated region from backstore to the window. */
2013-08-14 01:18:59 +04:00
for ( i = 0 ; i < message - > numRects ; i + + )
2011-09-12 05:22:03 +04:00
{
tx = message - > rects [ i ] . x + surface_bits_command - > destLeft ;
ty = message - > rects [ i ] . y + surface_bits_command - > destTop ;
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
XCopyArea ( xfc - > display , xfc - > primary , xfc - > drawable , xfc - > gc , tx , ty , message - > rects [ i ] . width , message - > rects [ i ] . height , tx , ty ) ;
}
2011-09-12 05:22:03 +04:00
2013-06-13 02:57:25 +04:00
xf_gdi_surface_update_frame ( xfc , tx , ty , message - > rects [ i ] . width , message - > rects [ i ] . height ) ;
2011-09-12 05:22:03 +04:00
}
2013-06-13 02:57:25 +04:00
XSetClipMask ( xfc - > display , xfc - > gc , None ) ;
2014-06-05 02:03:25 +04:00
rfx_message_free ( xfc - > rfx , message ) ;
2011-09-12 05:22:03 +04:00
}
2013-01-12 17:49:01 +04:00
else if ( surface_bits_command - > codecID = = RDP_CODEC_ID_NSCODEC )
2011-10-02 23:16:22 +04:00
{
2014-06-05 02:03:25 +04:00
nsc_process_message ( xfc - > nsc , surface_bits_command - > bpp , surface_bits_command - > width , surface_bits_command - > height ,
2012-03-05 13:32:14 +04:00
surface_bits_command - > bitmapData , surface_bits_command - > bitmapDataLength ) ;
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
2011-10-02 23:16:22 +04:00
2013-06-13 02:57:25 +04:00
xfc - > bmp_codec_nsc = ( BYTE * ) realloc ( xfc - > bmp_codec_nsc ,
2011-10-02 23:16:22 +04:00
surface_bits_command - > width * surface_bits_command - > height * 4 ) ;
2014-06-05 02:03:25 +04:00
freerdp_image_flip ( xfc - > nsc - > BitmapData , xfc - > bmp_codec_nsc ,
2011-10-02 23:16:22 +04:00
surface_bits_command - > width , surface_bits_command - > height , 32 ) ;
2013-06-13 02:57:25 +04:00
image = XCreateImage ( xfc - > display , xfc - > visual , 24 , ZPixmap , 0 ,
( char * ) xfc - > bmp_codec_nsc , surface_bits_command - > width , surface_bits_command - > height , 32 , 0 ) ;
2011-10-02 23:16:22 +04:00
2013-06-13 02:57:25 +04:00
XPutImage ( xfc - > display , xfc - > primary , xfc - > gc , image , 0 , 0 ,
2011-10-02 23:16:22 +04:00
surface_bits_command - > destLeft , surface_bits_command - > destTop ,
surface_bits_command - > width , surface_bits_command - > height ) ;
2012-03-29 15:01:42 +04:00
XFree ( image ) ;
2013-08-29 13:07:19 +04:00
free ( xfc - > bmp_codec_nsc ) ;
xfc - > bmp_codec_nsc = NULL ;
2011-10-02 23:16:22 +04:00
2014-06-05 02:03:25 +04:00
if ( ! xfc - > remote_app )
2013-12-02 06:41:58 +04:00
{
XCopyArea ( xfc - > display , xfc - > primary , xfc - > window - > handle , xfc - > gc ,
surface_bits_command - > destLeft , surface_bits_command - > destTop ,
surface_bits_command - > width , surface_bits_command - > height ,
surface_bits_command - > destLeft , surface_bits_command - > destTop ) ;
}
2014-06-05 02:03:25 +04:00
2013-06-13 02:57:25 +04:00
xf_gdi_surface_update_frame ( xfc ,
2012-05-26 10:41:38 +04:00
surface_bits_command - > destLeft , surface_bits_command - > destTop ,
surface_bits_command - > width , surface_bits_command - > height ) ;
2011-10-02 23:16:22 +04:00
2013-06-13 02:57:25 +04:00
XSetClipMask ( xfc - > display , xfc - > gc , None ) ;
2011-10-02 23:16:22 +04:00
}
2013-01-12 17:49:01 +04:00
else if ( surface_bits_command - > codecID = = RDP_CODEC_ID_NONE )
2011-09-12 05:22:03 +04:00
{
2013-06-13 02:57:25 +04:00
XSetFunction ( xfc - > display , xfc - > gc , GXcopy ) ;
XSetFillStyle ( xfc - > display , xfc - > gc , FillSolid ) ;
2011-09-14 22:47:04 +04:00
2012-03-05 01:59:15 +04:00
/* Validate that the data received is large enough */
2013-02-07 06:57:49 +04:00
if ( ( surface_bits_command - > width * surface_bits_command - > height * surface_bits_command - > bpp / 8 ) < = ( surface_bits_command - > bitmapDataLength ) )
2012-03-05 01:59:15 +04:00
{
2013-06-13 02:57:25 +04:00
xfc - > bmp_codec_none = ( BYTE * ) realloc ( xfc - > bmp_codec_none ,
2012-03-05 01:59:15 +04:00
surface_bits_command - > width * surface_bits_command - > height * 4 ) ;
2011-09-14 22:47:04 +04:00
2013-06-13 02:57:25 +04:00
freerdp_image_flip ( surface_bits_command - > bitmapData , xfc - > bmp_codec_none ,
2012-03-05 01:59:15 +04:00
surface_bits_command - > width , surface_bits_command - > height , 32 ) ;
2011-09-14 22:47:04 +04:00
2013-06-13 02:57:25 +04:00
image = XCreateImage ( xfc - > display , xfc - > visual , 24 , ZPixmap , 0 ,
( char * ) xfc - > bmp_codec_none , surface_bits_command - > width , surface_bits_command - > height , 32 , 0 ) ;
2011-09-12 05:22:03 +04:00
2013-06-13 02:57:25 +04:00
XPutImage ( xfc - > display , xfc - > primary , xfc - > gc , image , 0 , 0 ,
2012-03-05 01:59:15 +04:00
surface_bits_command - > destLeft , surface_bits_command - > destTop ,
surface_bits_command - > width , surface_bits_command - > height ) ;
2012-03-29 15:01:42 +04:00
XFree ( image ) ;
2013-08-29 13:07:19 +04:00
free ( xfc - > bmp_codec_none ) ;
xfc - > bmp_codec_none = NULL ;
2011-09-14 22:47:04 +04:00
2013-12-02 06:41:58 +04:00
if ( xfc - > remote_app ! = TRUE )
{
XCopyArea ( xfc - > display , xfc - > primary , xfc - > window - > handle , xfc - > gc ,
surface_bits_command - > destLeft , surface_bits_command - > destTop ,
surface_bits_command - > width , surface_bits_command - > height ,
surface_bits_command - > destLeft , surface_bits_command - > destTop ) ;
}
2013-06-13 02:57:25 +04:00
xf_gdi_surface_update_frame ( xfc ,
2012-05-26 10:41:38 +04:00
surface_bits_command - > destLeft , surface_bits_command - > destTop ,
surface_bits_command - > width , surface_bits_command - > height ) ;
2011-09-14 22:47:04 +04:00
2013-06-13 02:57:25 +04:00
XSetClipMask ( xfc - > display , xfc - > gc , None ) ;
2013-02-07 06:57:49 +04:00
}
else
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " Invalid bitmap size - data is %d bytes for %dx%d \n update " , surface_bits_command - > bitmapDataLength , surface_bits_command - > width , surface_bits_command - > height ) ;
2012-03-05 01:59:15 +04:00
}
2011-09-12 05:22:03 +04:00
}
else
{
2013-03-29 02:06:34 +04:00
fprintf ( stderr , " Unsupported codecID %d \n " , surface_bits_command - > codecID ) ;
2011-09-12 05:22:03 +04:00
}
2013-02-07 06:57:49 +04:00
2013-06-13 02:57:25 +04:00
xf_unlock_x11 ( xfc , FALSE ) ;
2011-08-26 02:07:52 +04:00
}
void xf_gdi_register_update_callbacks ( rdpUpdate * update )
{
2011-11-22 03:11:43 +04:00
rdpPrimaryUpdate * primary = update - > primary ;
2011-08-26 02:07:52 +04:00
update - > Palette = xf_gdi_palette_update ;
update - > SetBounds = xf_gdi_set_bounds ;
2011-11-22 03:11:43 +04:00
primary - > DstBlt = xf_gdi_dstblt ;
primary - > PatBlt = xf_gdi_patblt ;
primary - > ScrBlt = xf_gdi_scrblt ;
primary - > OpaqueRect = xf_gdi_opaque_rect ;
primary - > DrawNineGrid = NULL ;
primary - > MultiDstBlt = NULL ;
primary - > MultiPatBlt = NULL ;
primary - > MultiScrBlt = NULL ;
primary - > MultiOpaqueRect = xf_gdi_multi_opaque_rect ;
primary - > MultiDrawNineGrid = NULL ;
primary - > LineTo = xf_gdi_line_to ;
primary - > Polyline = xf_gdi_polyline ;
primary - > MemBlt = xf_gdi_memblt ;
primary - > Mem3Blt = xf_gdi_mem3blt ;
primary - > SaveBitmap = NULL ;
primary - > GlyphIndex = NULL ;
primary - > FastIndex = NULL ;
primary - > FastGlyph = NULL ;
2012-02-13 02:14:59 +04:00
primary - > PolygonSC = xf_gdi_polygon_sc ;
primary - > PolygonCB = xf_gdi_polygon_cb ;
primary - > EllipseSC = xf_gdi_ellipse_sc ;
primary - > EllipseCB = xf_gdi_ellipse_cb ;
2011-08-26 02:07:52 +04:00
update - > SurfaceBits = xf_gdi_surface_bits ;
2011-11-25 14:48:51 +04:00
update - > SurfaceFrameMarker = xf_gdi_surface_frame_marker ;
2011-08-26 02:07:52 +04:00
}