Blame lib/Xm/DrTog.c

Packit b099d7
/* $XConsortium: DrTog.c /main/6 1995/10/25 20:00:29 cde-sun $ */
Packit b099d7
/*
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
 * 
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * HISTORY
Packit b099d7
 */
Packit b099d7
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#include "XmI.h"
Packit b099d7
#include <Xm/DrawP.h>
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/**************************** DrTog module ***************************
Packit b099d7
 *
Packit b099d7
 * Draw API used by Toggle Button only.
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
static void DrawCheckMark(Display *display,
Packit b099d7
			  Drawable d,
Packit b099d7
			  GC gc,
Packit b099d7
			  Position x,
Packit b099d7
			  Position y,
Packit b099d7
			  Dimension width,
Packit b099d7
			  Dimension height,
Packit b099d7
			  Dimension margin);
Packit b099d7
Packit b099d7
static void DrawCross(Display *display,
Packit b099d7
		      Drawable d,
Packit b099d7
		      GC gc,
Packit b099d7
		      Position x,
Packit b099d7
		      Position y,
Packit b099d7
		      Dimension width,
Packit b099d7
		      Dimension height,
Packit b099d7
		      Dimension margin);
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
Packit b099d7
#define CHECK_TEMPLATE_WIDTH	32
Packit b099d7
#define CHECK_TEMPLATE_HEIGHT	32
Packit b099d7
Packit b099d7
static XmConst XPoint check_template[] = {
Packit b099d7
  {  0, 15 },
Packit b099d7
  {  6,  9 },
Packit b099d7
  { 14, 17 },
Packit b099d7
  { 31,  0 },
Packit b099d7
  { 31,  3 },
Packit b099d7
  { 21, 17 },
Packit b099d7
  { 16, 31 },
Packit b099d7
  {  0, 15 }
Packit b099d7
};
Packit b099d7
Packit b099d7
static void
Packit b099d7
DrawCheckMark(Display *display,
Packit b099d7
	      Drawable d,
Packit b099d7
	      GC gc,
Packit b099d7
	      Position x,
Packit b099d7
	      Position y,
Packit b099d7
	      Dimension width,
Packit b099d7
	      Dimension height,
Packit b099d7
	      Dimension margin)
Packit b099d7
{
Packit b099d7
  XGCValues old_values, new_values;
Packit b099d7
  XtGCMask mask;
Packit b099d7
  XPoint check[XtNumber(check_template)];
Packit b099d7
  float scale_x = (width - 2 * margin - 1) / (float)CHECK_TEMPLATE_WIDTH;
Packit b099d7
  float scale_y = (height - 2 * margin - 1) / (float)CHECK_TEMPLATE_HEIGHT;
Packit b099d7
  int npoints = XtNumber(check_template);
Packit b099d7
  int i;
Packit b099d7
Packit b099d7
  /* Scale and translate the glyph to the desired area. */
Packit b099d7
  for (i = 0; i < npoints; i++)
Packit b099d7
    {
Packit b099d7
      check[i].x = (Position)(check_template[i].x*scale_x + 0.5) + x + margin;
Packit b099d7
      check[i].y = (Position)(check_template[i].y*scale_y + 0.5) + y + margin;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /* CR 9656: Force line_width so test results are not platform-dependent. */
Packit b099d7
  mask = 0;
Packit b099d7
  new_values.line_width = 1, mask |= GCLineWidth;
Packit b099d7
  XGetGCValues(display, gc, mask, &old_values);
Packit b099d7
  XChangeGC(display, gc, mask, &new_values);
Packit b099d7
Packit b099d7
  /* Draw the check mark. */
Packit b099d7
  XFillPolygon(display, d, gc, check, npoints - 1, Nonconvex, CoordModeOrigin);
Packit b099d7
  XDrawLines(display, d, gc, check, npoints, CoordModeOrigin);
Packit b099d7
Packit b099d7
  XChangeGC(display, gc, mask, &old_values);
Packit b099d7
}
Packit b099d7

Packit b099d7
static void
Packit b099d7
DrawCross(Display *display,
Packit b099d7
	  Drawable d,
Packit b099d7
	  GC gc,
Packit b099d7
	  Position x,
Packit b099d7
	  Position y,
Packit b099d7
	  Dimension width,
Packit b099d7
	  Dimension height,
Packit b099d7
	  Dimension margin)
Packit b099d7
{
Packit b099d7
  Position left   = x + margin;
Packit b099d7
  Position right  = x + width - margin - 1;
Packit b099d7
  Position top    = y + margin;
Packit b099d7
  Position bottom = y + height - margin - 1;
Packit b099d7
Packit b099d7
  XSegment segs[6];
Packit b099d7
  Cardinal nsegs = 0;
Packit b099d7
    
Packit b099d7
  segs[nsegs].x1 = left;
Packit b099d7
  segs[nsegs].y1 = top + 1;
Packit b099d7
  segs[nsegs].x2 = right - 1;
Packit b099d7
  segs[nsegs].y2 = bottom;
Packit b099d7
  nsegs++;
Packit b099d7
	    
Packit b099d7
  segs[nsegs].x1 = left;
Packit b099d7
  segs[nsegs].y1 = top;
Packit b099d7
  segs[nsegs].x2 = right;
Packit b099d7
  segs[nsegs].y2 = bottom;
Packit b099d7
  nsegs++;
Packit b099d7
Packit b099d7
  segs[nsegs].x1 = left + 1;
Packit b099d7
  segs[nsegs].y1 = top;
Packit b099d7
  segs[nsegs].x2 = right;
Packit b099d7
  segs[nsegs].y2 = bottom - 1;
Packit b099d7
  nsegs++;
Packit b099d7
	    
Packit b099d7
  segs[nsegs].x1 = left;
Packit b099d7
  segs[nsegs].y1 = bottom - 1;
Packit b099d7
  segs[nsegs].x2 = right - 1;
Packit b099d7
  segs[nsegs].y2 = top;
Packit b099d7
  nsegs++;
Packit b099d7
Packit b099d7
  segs[nsegs].x1 = left;
Packit b099d7
  segs[nsegs].y1 = bottom;
Packit b099d7
  segs[nsegs].x2 = right;
Packit b099d7
  segs[nsegs].y2 = top;
Packit b099d7
  nsegs++;
Packit b099d7
	    
Packit b099d7
  segs[nsegs].x1 = left + 1;
Packit b099d7
  segs[nsegs].y1 = bottom;
Packit b099d7
  segs[nsegs].x2 = right;
Packit b099d7
  segs[nsegs].y2 = top + 1;
Packit b099d7
  nsegs++;
Packit b099d7
Packit b099d7
  assert(nsegs <= XtNumber(segs));
Packit b099d7
Packit b099d7
  XDrawSegments(display, d, gc, segs, nsegs);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/***********************XmeDrawDiamond**********************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void XmeDrawDiamond(Display *display, Drawable d, 
Packit b099d7
                    GC top_gc, GC bottom_gc, GC center_gc, 
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                    int x, int y, 
Packit b099d7
                    int width, 
Packit b099d7
		    int height, /* unused */
Packit b099d7
                    int shadow_thick,
Packit b099d7
		    int margin)
Packit b099d7
#else
Packit b099d7
                    Position x, Position y, 
Packit b099d7
                    Dimension width, 
Packit b099d7
       		    Dimension height, /* unused */
Packit b099d7
                    Dimension shadow_thick,
Packit b099d7
	            Dimension margin)
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   XSegment seg[12];
Packit b099d7
   XPoint   pt[4];
Packit b099d7
   int midX, midY;
Packit b099d7
   int delta;
Packit b099d7
   _XmDisplayToAppContext(display);
Packit b099d7
Packit b099d7
   if (!d || !width) return ;
Packit b099d7
Packit b099d7
   _XmAppLock(app);
Packit b099d7
   if (width % 2 == 0) width--;
Packit b099d7
Packit b099d7
   if (width == 1) {
Packit b099d7
       XDrawPoint(display, d, top_gc, x,y);
Packit b099d7
       _XmAppUnlock(app);
Packit b099d7
       return ;
Packit b099d7
   } else
Packit b099d7
   if (width == 3) {
Packit b099d7
       seg[0].x1 = x;                   
Packit b099d7
       seg[0].y1 = seg[0].y2 = y + 1;
Packit b099d7
       seg[0].x2 = x + 2;
Packit b099d7
Packit b099d7
       seg[1].x1 = seg[1].x2 = x + 1;           
Packit b099d7
       seg[1].y1 = y ;
Packit b099d7
       seg[1].y2 = y + 2;
Packit b099d7
       XDrawSegments (display, d, top_gc, seg, 2);
Packit b099d7
       _XmAppUnlock(app);
Packit b099d7
       return ;
Packit b099d7
   } else   {        /* NORMAL SIZED ToggleButtonS : initial width >= 5 */
Packit b099d7
       midX = x + (width + 1) / 2;
Packit b099d7
       midY = y + (width + 1) / 2;
Packit b099d7
       /*  The top shadow segments  */
Packit b099d7
       seg[0].x1 = x;                   /*  1  */
Packit b099d7
       seg[0].y1 = midY - 1;
Packit b099d7
       seg[0].x2 = midX - 1;            /*  2  */
Packit b099d7
       seg[0].y2 = y;
Packit b099d7
Packit b099d7
       seg[1].x1 = x + 1;               /*  3  */
Packit b099d7
       seg[1].y1 = midY - 1;
Packit b099d7
       seg[1].x2 = midX - 1;            /*  4  */
Packit b099d7
       seg[1].y2 = y + 1;
Packit b099d7
Packit b099d7
       seg[2].x1 = x + 2;               /*  3  */
Packit b099d7
       seg[2].y1 = midY - 1;
Packit b099d7
       seg[2].x2 = midX - 1;            /*  4  */
Packit b099d7
       seg[2].y2 = y + 2;
Packit b099d7
Packit b099d7
       seg[3].x1 = midX - 1;            /*  5  */
Packit b099d7
       seg[3].y1 = y;
Packit b099d7
       seg[3].x2 = x + width - 1;       /*  6  */
Packit b099d7
       seg[3].y2 = midY - 1;
Packit b099d7
Packit b099d7
       seg[4].x1 = midX - 1;            /*  7  */
Packit b099d7
       seg[4].y1 = y + 1;
Packit b099d7
       seg[4].x2 = x + width - 2;       /*  8  */
Packit b099d7
       seg[4].y2 = midY - 1;
Packit b099d7
Packit b099d7
       seg[5].x1 = midX - 1;            /*  7  */
Packit b099d7
       seg[5].y1 = y + 2;
Packit b099d7
       seg[5].x2 = x + width - 3;       /*  8  */
Packit b099d7
       seg[5].y2 = midY - 1;
Packit b099d7
Packit b099d7
       /*  The bottom shadow segments  */
Packit b099d7
       seg[6].x1 = x;                   /*  9  */
Packit b099d7
       seg[6].y1 = midY - 1;
Packit b099d7
       seg[6].x2 = midX - 1;            /*  10  */
Packit b099d7
       seg[6].y2 = y + width - 1;
Packit b099d7
Packit b099d7
       seg[7].x1 = x + 1;               /*  11  */
Packit b099d7
       seg[7].y1 = midY - 1;
Packit b099d7
       seg[7].x2 = midX - 1;            /*  12  */
Packit b099d7
       seg[7].y2 = y + width - 2;
Packit b099d7
Packit b099d7
       seg[8].x1 = x + 2;               /*  11  */
Packit b099d7
       seg[8].y1 = midY - 1;
Packit b099d7
       seg[8].x2 = midX - 1;            /*  12  */
Packit b099d7
       seg[8].y2 = y + width - 3;
Packit b099d7
Packit b099d7
       seg[9].x1 = midX - 1;            /*  13  */
Packit b099d7
       seg[9].y1 = y + width - 1;
Packit b099d7
       seg[9].x2 = x + width - 1;       /*  14  */
Packit b099d7
       seg[9].y2 = midY - 1;
Packit b099d7
Packit b099d7
       seg[10].x1 = midX - 1;           /*  15  */
Packit b099d7
       seg[10].y1 = y + width - 2;
Packit b099d7
       seg[10].x2 = x + width - 2;      /*  16  */
Packit b099d7
       seg[10].y2 = midY - 1;
Packit b099d7
Packit b099d7
       seg[11].x1 = midX - 1;           /*  15  */
Packit b099d7
       seg[11].y1 = y + width - 3;
Packit b099d7
       seg[11].x2 = x + width - 3;      /*  16  */
Packit b099d7
       seg[11].y2 = midY - 1;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   XDrawSegments (display, d, top_gc, &seg[3], 3);
Packit b099d7
   XDrawSegments (display, d, bottom_gc, &seg[6], 6);
Packit b099d7
   XDrawSegments (display, d, top_gc, &seg[0], 3);
Packit b099d7
Packit b099d7
   if (width == 5 || !center_gc) { _XmAppUnlock(app); return ; }   /* <= 5 in fact */
Packit b099d7
Packit b099d7
   if (shadow_thick == 0) 
Packit b099d7
     delta = -3 ;
Packit b099d7
   else if (shadow_thick == 1) 
Packit b099d7
     delta = -1 ;
Packit b099d7
   else 
Packit b099d7
     delta = margin;
Packit b099d7
Packit b099d7
   pt[0].x = x + 3 + delta;
Packit b099d7
   pt[0].y = pt[2].y = midY - 1;
Packit b099d7
   pt[1].x = pt[3].x = midX - 1 ;
Packit b099d7
   pt[1].y = y + 2 + delta;
Packit b099d7
   pt[2].x = x + width - 3 - delta;
Packit b099d7
   pt[3].y = y + width - 3 - delta;
Packit b099d7
   
Packit b099d7
   XFillPolygon (display, d, center_gc, pt, 4, Convex, CoordModeOrigin);
Packit b099d7
   _XmAppUnlock(app);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/******************************XmeDrawIndicator**********************/
Packit b099d7
void 
Packit b099d7
XmeDrawIndicator(Display *display, 
Packit b099d7
		 Drawable d, 
Packit b099d7
		 GC gc, 
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
		 int x, int y, 
Packit b099d7
		 int width, int height, 
Packit b099d7
		 int margin,
Packit b099d7
		 int type)
Packit b099d7
#else
Packit b099d7
                 Position x, Position y, 
Packit b099d7
                 Dimension width, Dimension height, 
Packit b099d7
                 Dimension margin,
Packit b099d7
                 XtEnum type)
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
  _XmDisplayToAppContext(display);
Packit b099d7
Packit b099d7
  _XmAppLock(app);
Packit b099d7
  switch(type & 0xf0)
Packit b099d7
    {
Packit b099d7
    case XmINDICATOR_CHECK:
Packit b099d7
      DrawCheckMark(display, d, gc, x, y, width, height, margin);
Packit b099d7
      break;
Packit b099d7
	    
Packit b099d7
    case XmINDICATOR_CROSS:
Packit b099d7
      DrawCross(display, d, gc, x, y, width, height, margin);
Packit b099d7
      break;
Packit b099d7
    }
Packit b099d7
  _XmAppUnlock(app);
Packit b099d7
}
Packit b099d7

Packit b099d7
void
Packit b099d7
XmeDrawCircle(Display *display,
Packit b099d7
	      Drawable d,
Packit b099d7
	      GC top_gc,
Packit b099d7
	      GC bottom_gc,
Packit b099d7
	      GC center_gc,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
	      int x,
Packit b099d7
	      int y,
Packit b099d7
	      int width,
Packit b099d7
	      int height,
Packit b099d7
	      int shadow_thick,
Packit b099d7
	      int margin)
Packit b099d7
#else
Packit b099d7
	      Position x,
Packit b099d7
	      Position y,
Packit b099d7
	      Dimension width,
Packit b099d7
	      Dimension height,
Packit b099d7
	      Dimension shadow_thick,
Packit b099d7
	      Dimension margin)
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
  int line_width = MIN(shadow_thick, MIN(width, height) / 2);
Packit b099d7
  _XmDisplayToAppContext(display);
Packit b099d7
Packit b099d7
  if ((width <= 0) || (height <= 0))
Packit b099d7
    return;
Packit b099d7
Packit b099d7
  _XmAppLock(app);
Packit b099d7
  if (shadow_thick > 0)
Packit b099d7
    {
Packit b099d7
      /* Force the GCs to use our values. */
Packit b099d7
      XGCValues top_values, bottom_values, new_values;
Packit b099d7
      XtGCMask mask;
Packit b099d7
Packit b099d7
      mask = 0;
Packit b099d7
      new_values.line_width = line_width, mask |= GCLineWidth;
Packit b099d7
Packit b099d7
      XGetGCValues(display, top_gc, mask, &top_values);
Packit b099d7
      XGetGCValues(display, bottom_gc, mask, &bottom_values);
Packit b099d7
Packit b099d7
      XChangeGC(display, top_gc, mask, &new_values);
Packit b099d7
      XChangeGC(display, bottom_gc, mask, &new_values);
Packit b099d7
Packit b099d7
#ifdef FIX_1402
Packit b099d7
      if (center_gc != NULL) {
Packit b099d7
    	  int delta = MIN(line_width + margin, MIN(width, height) / 2) -1;
Packit b099d7
    	  XFillArc(display, d, center_gc,
Packit b099d7
    			  x + delta, y + delta,
Packit b099d7
    			  MAX(width - 2 * delta, 1), 
Packit b099d7
    			  MAX(height - 2 * delta, 1),
Packit b099d7
    			  0, 360 * 64);
Packit b099d7
      }
Packit b099d7
#endif
Packit b099d7
      
Packit b099d7
      XDrawArc(display, d, top_gc,
Packit b099d7
	       x + line_width/2, y + line_width/2, 
Packit b099d7
	       MAX(width - line_width, 1),
Packit b099d7
	       MAX(height - line_width, 1),
Packit b099d7
	       45 * 64, 180 * 64);
Packit b099d7
      XDrawArc(display, d, bottom_gc,
Packit b099d7
	       x + line_width/2, y + line_width/2, 
Packit b099d7
	       MAX(width - line_width, 1),
Packit b099d7
	       MAX(height - line_width, 1),
Packit b099d7
	       45 * 64, -180 * 64);
Packit b099d7
Packit b099d7
      XChangeGC(display, top_gc, mask, &top_values);
Packit b099d7
      XChangeGC(display, bottom_gc, mask, &bottom_values);
Packit b099d7
    }
Packit b099d7
Packit b099d7
#ifdef FIX_1402
Packit b099d7
  else {
Packit b099d7
	  if (center_gc != NULL) {
Packit b099d7
		  int delta = MIN(line_width + margin, MIN(width, height) / 2);
Packit b099d7
		  XFillArc(display, d, center_gc,
Packit b099d7
				  x + delta, y + delta,
Packit b099d7
				  MAX(width - 2 * delta, 1), 
Packit b099d7
				  MAX(height - 2 * delta, 1),
Packit b099d7
				  0, 360 * 64);
Packit b099d7
	  }
Packit b099d7
  }
Packit b099d7
#else
Packit b099d7
  if (center_gc != NULL)
Packit b099d7
    {
Packit b099d7
      /* Fill the center of the circle. */
Packit b099d7
      int delta = MIN(line_width + margin, MIN(width, height) / 2);
Packit b099d7
      XFillArc(display, d, center_gc,
Packit b099d7
	       x + delta, y + delta,
Packit b099d7
	       MAX(width - 2 * delta, 1), 
Packit b099d7
	       MAX(height - 2 * delta, 1),
Packit b099d7
	       0, 360 * 64);
Packit b099d7
    }
Packit b099d7
#endif
Packit b099d7
  _XmAppUnlock(app);
Packit b099d7
}