Esempio n. 1
0
static void
ShadowPutImage(DrawablePtr pDraw,
               GCPtr pGC,
               int depth,
               int x, int y, int w, int h,
               int leftPad, int format, char *pImage)
{
    BoxRec box;
    Bool boxNotEmpty = FALSE;

    SHADOW_GC_OP_PROLOGUE(pGC);

    if (IS_VISIBLE(pDraw)) {
        box.x1 = x + pDraw->x;
        box.x2 = box.x1 + w;
        box.y1 = y + pDraw->y;
        box.y2 = box.y1 + h;

        TRIM_BOX(box, pGC);
        if (BOX_NOT_EMPTY(box)) {
            if (pPriv->preRefresh)
                (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
            boxNotEmpty = TRUE;
        }
    }

    (*pGC->ops->PutImage) (pDraw, pGC, depth, x, y, w, h,
                           leftPad, format, pImage);

    if (boxNotEmpty && pPriv->postRefresh)
        (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);

    SHADOW_GC_OP_EPILOGUE(pGC);

}
Esempio n. 2
0
static void
ShadowSetSpans(
    DrawablePtr		pDraw,
    GCPtr		pGC,
    char		*pcharsrc,
    DDXPointPtr 	pptInit,
    int			*pwidthInit,
    int			nspans,
    int			fSorted 
){
    SHADOW_GC_OP_PROLOGUE(pGC);

    if(IS_VISIBLE(pDraw) && nspans) {
	DDXPointPtr ppt = pptInit;
	int *pwidth = pwidthInit;
	int i = nspans;
	BoxRec box;
        Bool boxNotEmpty = FALSE;

	box.x1 = ppt->x;
	box.x2 = box.x1 + *pwidth;
	box.y2 = box.y1 = ppt->y;

	while(--i) {
	   ppt++;
	   pwidth++;
	   if(box.x1 > ppt->x) box.x1 = ppt->x;
	   if(box.x2 < (ppt->x + *pwidth)) 
		box.x2 = ppt->x + *pwidth;
	   if(box.y1 > ppt->y) box.y1 = ppt->y;
	   else if(box.y2 < ppt->y) box.y2 = ppt->y;
	}

	box.y2++;

        if(!pGC->miTranslate) {
           TRANSLATE_BOX(box, pDraw);
        }
        TRIM_BOX(box, pGC);

	if(BOX_NOT_EMPTY(box)) {
           if(pPriv->preRefresh)
	      (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
           boxNotEmpty = TRUE;
        }

	(*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit, 
				pwidthInit, nspans, fSorted);

	if(boxNotEmpty && pPriv->postRefresh)
	   (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
    } else
	(*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit, 
				pwidthInit, nspans, fSorted);

    SHADOW_GC_OP_EPILOGUE(pGC);
}
Esempio n. 3
0
VAR_t POSCALL nosGetNameByHandle(NOSGENERICHANDLE_t handle,
                                 char *buffer, VAR_t bufsize,
                                 NOSREGTYPE_t what)
{
  NOSREGTYPE_t  rt;
  REGELEM_t re = NULL;
  VAR_t status = -E_NOTFOUND;
  VAR_t i;
  char  c;

  posSemaGet(reglist_sema_g);

  if (what != REGTYPE_SEARCHALL)
  {
    if (what <= MAX_REGTYPE)
    {
      re = n_findKeyByHandle(what, handle);
    }
    else
    {
      status = -E_ARG;
    }
  }
  else  
  for (rt = MIN_REGTYPE; rt <= MAX_REGTYPE; ++rt)
  {
#if NOSCFG_FEATURE_USERREG
    if (rt != REGTYPE_USER)
#endif
    {
      re = n_findKeyByHandle(rt, handle);
      if (re != NULL)
        break;
    }
  }

  if (re != NULL)
  {
    if (IS_VISIBLE(re))
    {
      status = E_OK;
      if ((buffer != NULL) && (bufsize > 0))
      {
        for (i=0; (i<bufsize-1) && (i<NOS_MAX_REGKEYLEN); ++i)
        {
          c = re->name[i];
          if (c == 0)  break;
          buffer[i] = c;
        }
        buffer[i] = 0;
      }
    }
  }

  posSemaSignal(reglist_sema_g);
  return status;
}
Esempio n. 4
0
VAR_t POSCALL nosRegQueryElem(NOSREGQHANDLE_t qh, NOSGENERICHANDLE_t *genh,
                              char* namebuf, VAR_t bufsize)
{
  REGQUERY_t rq = (REGQUERY_t) qh;
  REGELEM_t re;
  VAR_t i;

  if ((rq == NULL) || (genh == NULL) || (namebuf == NULL))
    return -E_ARG;

  posSemaGet(reglist_sema_g);

  if (rq->queryElem == NULL)
  {
    re = reglist_syselem_g[rq->type];
  }
  else
  {
    re = rq->queryElem->next;
    DEC_REFCOUNT(rq->queryElem, rq->type);
  }

  for(;;)
  {
    rq->queryElem = re;

    if (re == NULL)
    {
      posSemaSignal(reglist_sema_g);
      return -E_NOMORE;
    }

    if (IS_VISIBLE(re))
      break;

    re = re->next;
  }

  INC_REFCOUNT(re);

  *genh = re->handle.generic;
  for (i=0; (i < NOS_MAX_REGKEYLEN) && 
            (i < (bufsize-1)) && (re->name[i] != 0); ++i)
  {
    namebuf[i] = re->name[i];
  }
  namebuf[i] = 0;

  posSemaSignal(reglist_sema_g);
  return E_OK;
}
Esempio n. 5
0
static void
ShadowPolyPoint(
    DrawablePtr pDraw,
    GCPtr pGC,
    int mode,
    int nptInit,
    xPoint *pptInit 
){
    BoxRec box;
    Bool boxNotEmpty = FALSE;
    
    SHADOW_GC_OP_PROLOGUE(pGC);

    if(IS_VISIBLE(pDraw) && nptInit) {
        xPoint *ppt = pptInit;
        int npt = nptInit;

	box.x2 = box.x1 = pptInit->x;
	box.y2 = box.y1 = pptInit->y;

	/* this could be slow if the points were spread out */

	while(--npt) {
	   ppt++;
	   if(box.x1 > ppt->x) box.x1 = ppt->x;
	   else if(box.x2 < ppt->x) box.x2 = ppt->x;
	   if(box.y1 > ppt->y) box.y1 = ppt->y;
	   else if(box.y2 < ppt->y) box.y2 = ppt->y;
	}

	box.x2++;
	box.y2++;

	TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
	if(BOX_NOT_EMPTY(box)) {
           if(pPriv->preRefresh)
	      (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
           boxNotEmpty = TRUE;
        }
    }
    
    (*pGC->ops->PolyPoint)(pDraw, pGC, mode, nptInit, pptInit);
    
    if(boxNotEmpty && pPriv->postRefresh)
        (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);

    SHADOW_GC_OP_EPILOGUE(pGC);
}
Esempio n. 6
0
NOSGENERICHANDLE_t POSCALL nosGetHandleByName(NOSREGTYPE_t objtype, 
                                              const char *objname)
{
  REGELEM_t re;

  if ((objtype > MAX_REGTYPE) || (objname ==NULL))
    return NULL;
  if (n_strlen(objname) > NOS_MAX_REGKEYLEN)
    return NULL;

  posSemaGet(reglist_sema_g);
  re = n_findKeyByName(objtype, objname);
  posSemaSignal(reglist_sema_g);

  if (re == NULL)
    return NULL;
  return IS_VISIBLE(re) ? re->handle.generic : NULL;
}
Esempio n. 7
0
static RegionPtr
ShadowCopyPlane(
    DrawablePtr	pSrc,
    DrawablePtr	pDst,
    GCPtr pGC,
    int	srcx, int srcy,
    int	width, int height,
    int	dstx, int dsty,
    unsigned long bitPlane 
){
    RegionPtr ret;
    BoxRec box;
    Bool boxNotEmpty = FALSE;
    
    SHADOW_GC_OP_PROLOGUE(pGC);

    if(IS_VISIBLE(pDst)) {
	box.x1 = dstx + pDst->x;
	box.x2 = box.x1 + width;
	box.y1 = dsty + pDst->y;
	box.y2 = box.y1 + height;

	TRIM_BOX(box, pGC);
	if(BOX_NOT_EMPTY(box)) {
           if(pPriv->preRefresh)
	      (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
           boxNotEmpty = TRUE;
        }
    }
    
    ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
	       pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
    
    if(boxNotEmpty && pPriv->postRefresh)
        (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
    
    SHADOW_GC_OP_EPILOGUE(pGC);

    return ret;
}
Esempio n. 8
0
VAR_t POSCALL nosRegGet(const char *keyname, KEYVALUE_t *keyvalue)
{
  REGELEM_t re;

  if ((keyname == NULL) || (keyvalue == NULL))
    return -E_ARG;

  posSemaGet(reglist_sema_g);

  re = n_findKeyByName(REGTYPE_USER, keyname);
  if (re != NULL)
  {
    if (IS_VISIBLE(re)) {
      *keyvalue = re->handle.ukv;
    } else {
      re = NULL;
    }
  }

  posSemaSignal(reglist_sema_g);
  return (re == NULL) ? -E_FAIL : E_OK;
}
Esempio n. 9
0
int needs_body(Symbol name)  /*;needs_body*/	
{
	/* Procedures and function specs need bodies of course. So do package
	 * specs that contain objects which need bodies.
	 */

	Symbol	obj;
	char	*id;
	Fordeclared	fd1;
	int	nat;

	if (cdebug2 > 3) TO_ERRFILE("AT PROC :  needs_body");

	nat = NATURE(name);
	if (nat == na_package_spec || nat == na_generic_package_spec) {
		FORDECLARED(id, obj, DECLARED(name), fd1);
			if (IS_VISIBLE(fd1) && obj->scope_of == name
			  && needs_body(obj)) return TRUE;
		ENDFORDECLARED(fd1);
		FORDECLARED(id, obj, DECLARED(name), fd1)
		    if (TYPE_OF(obj) == symbol_incomplete) return TRUE;
		ENDFORDECLARED(fd1);
		return FALSE;
	}
Esempio n. 10
0
///////////////////////////////////////////////////////////////////////////////
// Paint the toolbar
void CToolBarXP::OnPaint ()
{
    if ( m_bDelayedButtonLayout )
    {
        Layout();
    }
    CPaintDC cpDC (this);
    CBufferDC cDC (cpDC);
    CRect rcClip;
    cDC.GetClipBox (rcClip);
    cDC.SetBkMode (TRANSPARENT);
    cDC.SelectObject (CFont::FromHandle ((HFONT)GetStockObject (DEFAULT_GUI_FONT)));

    cDC.FillSolidRect (rcClip, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), 20, 0));

    CPoint ptCursor;
    ::GetCursorPos (&ptCursor);
    ScreenToClient (&ptCursor);

    CClientRect rcClient (this);
    HIMAGELIST m_hImageList = (HIMAGELIST)DefWindowProc (TB_GETIMAGELIST, 0, 0);
    TBBUTTON tbbutton;
    int nCount = DefWindowProc (TB_BUTTONCOUNT, 0, 0);
    int nHotItem = GetToolBarCtrl().GetHotItem();

    for ( int i = 0; i < nCount; i++ )
    {
        VERIFY(DefWindowProc (TB_GETBUTTON, i, (LPARAM)&tbbutton));

        if ( !IS_VISIBLE(tbbutton) )
        {
            continue;
        }
        CRect rcButton;
        VERIFY(DefWindowProc (TB_GETITEMRECT, i, (LPARAM)&rcButton));

        if ( !CRect().IntersectRect (rcClip, rcButton) )
        {
            continue;
        }
        bool bOver = nHotItem == i && IS_ENABLED(tbbutton);
        bool bPressed = false;

        if ( IS_INDETERMINATE(tbbutton) )
        {
            CPenDC pen (cDC, ::GetSysColor (COLOR_3DSHADOW));

            cDC.MoveTo (rcButton.left, rcButton.bottom);
            cDC.LineTo (rcButton.left, rcButton.top);
            cDC.LineTo (rcButton.right-1, rcButton.top);
            cDC.LineTo (rcButton.right-1, rcButton.bottom-1);
            cDC.LineTo (rcButton.left, rcButton.bottom-1);
            bOver = true;
        }
        else if ( bOver || IS_CHECKED(tbbutton) )
        {
            bPressed = KEYDOWN(VK_LBUTTON) && rcButton.PtInRect (ptCursor);

            if ( IS_DROPDOWN(tbbutton) && bPressed )
            {
                bPressed = ptCursor.x < rcButton.right-13;

                if ( bPressed )
                {
                    rcButton.right -= 13;
                }
            }
            COLORREF crHighLight = ::GetSysColor (COLOR_HIGHLIGHT);
            CPenDC pen (cDC, crHighLight);
            CBrushDC brush (cDC, bPressed||(bOver&&IS_CHECKED(tbbutton)) ? HLS_TRANSFORM (crHighLight, +50, -50) : (bOver ? HLS_TRANSFORM (crHighLight, +70, -57) : HLS_TRANSFORM (crHighLight, +80, -66)));

            cDC.Rectangle (&rcButton);

            if ( IS_DROPDOWN(tbbutton) )
            {
                if ( bPressed )
                {
                    int nLeft = rcButton.left;

                    rcButton.left = rcButton.right-1;
                    rcButton.right += 13;

                    brush.Color (HLS_TRANSFORM (crHighLight, +70, -66));
                    cDC.Rectangle (&rcButton);

                    rcButton.left = nLeft;
                }
                else
                {
                    cDC.MoveTo (rcButton.right-14, rcButton.top);
                    cDC.LineTo (rcButton.right-14, rcButton.bottom);
                }
            }
        }
        if ( IS_SEPARATOR(tbbutton) )
        {
            CPenDC pen (cDC, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -15, 0));

            if ( IS_WRAP(tbbutton) )
            {
                cDC.MoveTo (rcClient.left+2, rcButton.bottom-4);
                cDC.LineTo (rcClient.right-2, rcButton.bottom-4);
            }
            else
            {
                cDC.MoveTo ((rcButton.right+rcButton.left)/2-1, rcButton.top+2);
                cDC.LineTo ((rcButton.right+rcButton.left)/2-1, rcButton.bottom-2);
            }
        }
        else if ( !IS_CONTROL(tbbutton) )
        {
            if ( IS_DROPDOWN(tbbutton) )
            {
                CPenDC pen (cDC, ( bOver && !IS_INDETERMINATE(tbbutton) ) ? RGB(0,0,0) : ::GetSysColor (IS_ENABLED(tbbutton) ? COLOR_BTNTEXT : COLOR_GRAYTEXT));

                cDC.MoveTo (rcButton.right-9, (rcButton.top+rcButton.bottom)/2-1);
                cDC.LineTo (rcButton.right-4, (rcButton.top+rcButton.bottom)/2-1);
                cDC.MoveTo (rcButton.right-8, (rcButton.top+rcButton.bottom)/2);
                cDC.LineTo (rcButton.right-5, (rcButton.top+rcButton.bottom)/2);
                cDC.SetPixel (rcButton.right-7, (rcButton.top+rcButton.bottom)/2+1, pen.Color());

                rcButton.right -= 14;
            }
            if ( tbbutton.iBitmap >= 0 )
            {
                if ( !IS_ENABLED(tbbutton) || (bOver && !bPressed) )
                {
                    HICON hIcon = ImageList_ExtractIcon (NULL, m_hImageList, tbbutton.iBitmap);
                    cDC.DrawState (CPoint (rcButton.left + ( bOver ? 4 : 3 ), rcButton.top + ( bOver ? 4 : 3 )), m_sizeImage, hIcon, DSS_MONO, CBrush (bOver ? (IS_INDETERMINATE(tbbutton) ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -20, 0) : HLS_TRANSFORM (::GetSysColor (COLOR_HIGHLIGHT), +50, -66)) : HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -27, 0)));
                    DestroyIcon (hIcon);
                }
                if ( IS_ENABLED(tbbutton) )
                {
                    ::ImageList_Draw (m_hImageList, tbbutton.iBitmap, cDC.m_hDC,
                                      rcButton.left + ( (bOver && !bPressed) ? 2 : 3 ), rcButton.top + ( (bOver && !bPressed) ? 2 : 3 ), ILD_TRANSPARENT);
                }
            }
        }
    }
}
Esempio n. 11
0
static void
ShadowPolylines(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		mode,		
    int		nptInit,		
    DDXPointPtr pptInit 
){
    BoxRec box;
    Bool boxNotEmpty = FALSE;
    
    SHADOW_GC_OP_PROLOGUE(pGC);

    if(IS_VISIBLE(pDraw) && nptInit) {
        DDXPointPtr ppt = pptInit;
        int npt = nptInit;
	int extra = pGC->lineWidth >> 1;

	box.x2 = box.x1 = pptInit->x;
	box.y2 = box.y1 = pptInit->y;

	if(npt > 1) {
	   if(pGC->joinStyle == JoinMiter)
		extra = 6 * pGC->lineWidth;
	   else if(pGC->capStyle == CapProjecting)
		extra = pGC->lineWidth;
        }

	if(mode == CoordModePrevious) {
	   int x = box.x1;
	   int y = box.y1;
	   while(--npt) {
		ppt++;
		x += ppt->x;
		y += ppt->y;
		if(box.x1 > x) box.x1 = x;
		else if(box.x2 < x) box.x2 = x;
		if(box.y1 > y) box.y1 = y;
		else if(box.y2 < y) box.y2 = y;
	    }
	} else {
	   while(--npt) {
		ppt++;
		if(box.x1 > ppt->x) box.x1 = ppt->x;
		else if(box.x2 < ppt->x) box.x2 = ppt->x;
		if(box.y1 > ppt->y) box.y1 = ppt->y;
		else if(box.y2 < ppt->y) box.y2 = ppt->y;
	    }
	}

	box.x2++;
	box.y2++;

	if(extra) {
	   box.x1 -= extra;
	   box.x2 += extra;
	   box.y1 -= extra;
	   box.y2 += extra;
        }

	TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
	if(BOX_NOT_EMPTY(box)) {
           if(pPriv->preRefresh)
	      (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
           boxNotEmpty = TRUE;
        }
    }
Esempio n. 12
0
void TileMap::DrawFogOfWar(ieByte* explored_mask, ieByte* visible_mask, Region viewport)
{
	// viewport - pos & size of the control
	int w = XCellCount * CELL_RATIO;
	int h = YCellCount * CELL_RATIO;
	if (LargeMap) {
		w++;
		h++;
	}
	Color black = { 0, 0, 0, 255 };

	Video* vid = core->GetVideoDriver();
	Region vp = vid->GetViewport();

	vp.w = viewport.w;
	vp.h = viewport.h;
	if (( vp.x + vp.w ) > w * CELL_SIZE) {
		vp.x = ( w * CELL_SIZE - vp.w );
	}
	if (vp.x < 0) {
		vp.x = 0;
	}
	if (( vp.y + vp.h ) > h * CELL_SIZE) {
		vp.y = ( h * CELL_SIZE - vp.h );
	}
	if (vp.y < 0) {
		vp.y = 0;
	}
	int sx = ( vp.x ) / CELL_SIZE;
	int sy = ( vp.y ) / CELL_SIZE;
	int dx = sx + vp.w / CELL_SIZE + 2;
	int dy = sy + vp.h / CELL_SIZE + 2;
	int x0 = sx * CELL_SIZE - vp.x;
	int y0 = sy * CELL_SIZE - vp.y;
	if (LargeMap) {
		x0 -= CELL_SIZE / 2;
		y0 -= CELL_SIZE / 2;
		dx++;
		dy++;
	}
	for (int y = sy; y < dy && y < h; y++) {
		for (int x = sx; x < dx && x < w; x++) {
			Region r = Region(x0 + viewport.x + ( (x - sx) * CELL_SIZE ), y0 + viewport.y + ( (y - sy) * CELL_SIZE ), CELL_SIZE, CELL_SIZE);
			if (! IS_EXPLORED( x, y )) {
				// Unexplored tiles are all black
				vid->DrawRect(r, black, true, true);
				continue;  // Don't draw 'invisible' fog
			}
			else {
				// If an explored tile is adjacent to an
				//   unexplored one, we draw border sprite
				//   (gradient black <-> transparent)
				// Tiles in four cardinal directions have these
				//   values.
				//
				//      1
				//    2   8
				//      4
				//
				// Values of those unexplored are
				//   added together, the resulting number being
				//   an index of shadow sprite to use. For now,
				//   some tiles are made 'on the fly' by
				//   drawing two or more tiles

				int e = ! IS_EXPLORED( x, y - 1);
				if (! IS_EXPLORED( x - 1, y )) e |= 2;
				if (! IS_EXPLORED( x, y + 1 )) e |= 4;
				if (! IS_EXPLORED( x + 1, y )) e |= 8;

				switch (e) {
				case 1:
				case 2:
				case 3:
				case 4:
				case 6:
				case 8:
				case 9:
				case 12:
					FOG( e );
					break;
				case 5:
					FOG( 1 );
					FOG( 4 );
					break;
				case 7:
					FOG( 3 );
					FOG( 6 );
					break;
				case 10:
					FOG( 2 );
					FOG( 8 );
					break;
				case 11:
					FOG( 3 );
					FOG( 9 );
					break;
				case 13:
					FOG( 9 );
					FOG( 12 );
					break;
				case 14:
					FOG( 6 );
					FOG( 12 );
					break;
				case 15: //this is black too
					vid->DrawRect(r, black, true, true);
					break;
				}
			}

			if (! IS_VISIBLE( x, y )) {
				// Invisible tiles are all gray
				FOG( 16 );
				continue;  // Don't draw 'invisible' fog
			}
			else {
				// If a visible tile is adjacent to an
				//   invisible one, we draw border sprite
				//   (gradient gray <-> transparent)
				// Tiles in four cardinal directions have these
				//   values.
				//
				//      1
				//    2   8
				//      4
				//
				// Values of those invisible are
				//   added together, the resulting number being
				//   an index of shadow sprite to use. For now,
				//   some tiles are made 'on the fly' by
				//   drawing two or more tiles

				int e = ! IS_VISIBLE( x, y - 1);
				if (! IS_VISIBLE( x - 1, y )) e |= 2;
				if (! IS_VISIBLE( x, y + 1 )) e |= 4;
				if (! IS_VISIBLE( x + 1, y )) e |= 8;

				switch (e) {
				case 1:
				case 2:
				case 3:
				case 4:
				case 6:
				case 8:
				case 9:
				case 12:
					FOG( 16 + e );
					break;
				case 5:
					FOG( 16 + 1 );
					FOG( 16 + 4 );
					break;
				case 7:
					FOG( 16 + 3 );
					FOG( 16 + 6 );
					break;
				case 10:
					FOG( 16 + 2 );
					FOG( 16 + 8 );
					break;
				case 11:
					FOG( 16 + 3 );
					FOG( 16 + 9 );
					break;
				case 13:
					FOG( 16 + 9 );
					FOG( 16 + 12 );
					break;
				case 14:
					FOG( 16 + 6 );
					FOG( 16 + 12 );
					break;
				case 15: //this is unseen too
					FOG( 16 );
					break;
				}
			}
		}
	}
}
Esempio n. 13
0
static void
SMI_Polylines(DrawablePtr pDraw, GCPtr pGC, int mode, int npt,
			  DDXPointPtr pptInit)
{
	XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
	ScrnInfoPtr pScrn = infoRec->pScrn;
	SMIPtr pSmi = SMIPTR(pScrn);

	ENTER_PROC("SMI_Polylines");

	/* Call the original Polylines function. */
	pGC->ops->Polylines = XAAFallbackOps.Polylines;
	(*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
	pGC->ops->Polylines = SMI_Polylines;

	if (IS_VISIBLE(pDraw) && npt)
	{
		/* Allocate a temporary buffer for all segments of the polyline. */
		BoxPtr pBox = xnfcalloc(sizeof(BoxRec), npt);
		int extra = pGC->lineWidth >> 1, box;

		if (npt > 1)
		{
			/* Adjust the extra space required per polyline segment. */
			if (pGC->joinStyle == JoinMiter)
			{
				extra = 6 * pGC->lineWidth;
			}
			else if (pGC->capStyle == CapProjecting)
			{
				extra = pGC->lineWidth;
			}
		}

		for (box = 0; --npt;)
		{
			/* Setup the bounding box for one polyline segment. */
			pBox[box].x1 = pptInit->x;
			pBox[box].y1 = pptInit->y;
			pptInit++;
			pBox[box].x2 = pptInit->x;
			pBox[box].y2 = pptInit->y;
			if (mode == CoordModePrevious)
			{
				pBox[box].x2 += pBox[box].x1;
				pBox[box].y2 += pBox[box].y1;
			}

			/* Sort coordinates. */
			if (pBox[box].x1 > pBox[box].x2)
			{
				int tmp = pBox[box].x1;
				pBox[box].x1 = pBox[box].x2;
				pBox[box].x2 = tmp;
			}
			if (pBox[box].y1 > pBox[box].y2)
			{
				int tmp = pBox[box].y1;
				pBox[box].y1 = pBox[box].y2;
				pBox[box].y2 = tmp;
			}

			/* Add extra space required for each polyline segment. */
			pBox[box].x1 -= extra;
			pBox[box].y1 -= extra;
			pBox[box].x2 += extra + 1;
			pBox[box].y2 += extra + 1;

			/* See if we need to draw this polyline segment. */
			TRANSLATE_BOX(pBox[box], pDraw);
			TRIM_BOX(pBox[box], pGC);
			if (BOX_NOT_EMPTY(pBox[box]))
			{
				box++;
			}
		}

		if (box)
		{
			/* Refresh all polyline segments now. */
			SMI_RefreshArea(pScrn, box, pBox);
		}

		/* Free the temporary buffer. */
		xfree(pBox);
	}