Blame src/ShapeWidg.c

Packit Service 2b1f13
/*
Packit Service 2b1f13
Packit Service 2b1f13
Copyright 1988, 1998  The Open Group
Packit Service 2b1f13
Packit Service 2b1f13
Permission to use, copy, modify, distribute, and sell this software and its
Packit Service 2b1f13
documentation for any purpose is hereby granted without fee, provided that
Packit Service 2b1f13
the above copyright notice appear in all copies and that both that
Packit Service 2b1f13
copyright notice and this permission notice appear in supporting
Packit Service 2b1f13
documentation.
Packit Service 2b1f13
Packit Service 2b1f13
The above copyright notice and this permission notice shall be included in
Packit Service 2b1f13
all copies or substantial portions of the Software.
Packit Service 2b1f13
Packit Service 2b1f13
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit Service 2b1f13
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit Service 2b1f13
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
Packit Service 2b1f13
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
Packit Service 2b1f13
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit Service 2b1f13
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit Service 2b1f13
Packit Service 2b1f13
Except as contained in this notice, the name of The Open Group shall not be
Packit Service 2b1f13
used in advertising or otherwise to promote the sale, use or other dealings
Packit Service 2b1f13
in this Software without prior written authorization from The Open Group.
Packit Service 2b1f13
Packit Service 2b1f13
*/
Packit Service 2b1f13
Packit Service 2b1f13
#ifdef HAVE_CONFIG_H
Packit Service 2b1f13
#include <config.h>
Packit Service 2b1f13
#endif
Packit Service 2b1f13
#include <X11/IntrinsicP.h>
Packit Service 2b1f13
#include <X11/extensions/shape.h>
Packit Service 2b1f13
#include "Converters.h"
Packit Service 2b1f13
#include "Drawing.h"
Packit Service 2b1f13
#include "Misc.h"
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * Prototypes
Packit Service 2b1f13
 */
Packit Service 2b1f13
static void ShapeEllipseOrRoundedRectangle(Widget, Bool, int, int);
Packit Service 2b1f13
static void ShapeError(Widget);
Packit Service 2b1f13
static void ShapeOval(Widget);
Packit Service 2b1f13
static void ShapeRectangle(Widget);
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * Implementation
Packit Service 2b1f13
 */
Packit Service 2b1f13
Boolean
Packit Service 2b1f13
XmuReshapeWidget(Widget w, int shape_style,
Packit Service 2b1f13
		 int corner_width, int corner_height)
Packit Service 2b1f13
{
Packit Service 2b1f13
  switch (shape_style)
Packit Service 2b1f13
    {
Packit Service 2b1f13
      case XmuShapeRectangle:
Packit Service 2b1f13
	ShapeRectangle(w);
Packit Service 2b1f13
	break;
Packit Service 2b1f13
      case XmuShapeOval:
Packit Service 2b1f13
	ShapeOval(w);
Packit Service 2b1f13
	break;
Packit Service 2b1f13
      case XmuShapeEllipse:
Packit Service 2b1f13
      case XmuShapeRoundedRectangle:
Packit Service 2b1f13
      ShapeEllipseOrRoundedRectangle(w, shape_style == XmuShapeEllipse,
Packit Service 2b1f13
				     corner_width, corner_height);
Packit Service 2b1f13
	break;
Packit Service 2b1f13
      default:
Packit Service 2b1f13
	ShapeError(w);
Packit Service 2b1f13
      return (False);
Packit Service 2b1f13
    }
Packit Service 2b1f13
  return (True);
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
static void
Packit Service 2b1f13
ShapeError(Widget w)
Packit Service 2b1f13
{
Packit Service 2b1f13
    String params[1];
Packit Service 2b1f13
    Cardinal num_params = 1;
Packit Service 2b1f13
Packit Service 2b1f13
    params[0] = XtName(w);
Packit Service 2b1f13
  XtAppWarningMsg(XtWidgetToApplicationContext(w),
Packit Service 2b1f13
		     "shapeUnknown", "xmuReshapeWidget", "XmuLibrary",
Packit Service 2b1f13
		     "Unsupported shape style for Command widget \"%s\"",
Packit Service 2b1f13
		  params, &num_params);
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
static void
Packit Service 2b1f13
ShapeRectangle(Widget w)
Packit Service 2b1f13
{
Packit Service 2b1f13
  XShapeCombineMask(XtDisplay(w), XtWindow(w),
Packit Service 2b1f13
		    ShapeBounding, 0, 0, None, ShapeSet);
Packit Service 2b1f13
  XShapeCombineMask(XtDisplay(w), XtWindow(w),
Packit Service 2b1f13
		    ShapeClip, 0, 0, None, ShapeSet);
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * Function:
Packit Service 2b1f13
 *	ShapeOval
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Parameters:
Packit Service 2b1f13
 *	w - widget to be reshaped
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Description:
Packit Service 2b1f13
 *	Reshapes a widget to a oval format.
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Notes:
Packit Service 2b1f13
 *	  X11R6.3 behaviour changed. Now if the height is larger than the
Packit Service 2b1f13
 *	width, this function inverts the sense of the oval, instead of
Packit Service 2b1f13
 *	fallbacking to ellipse.
Packit Service 2b1f13
 */
Packit Service 2b1f13
static void
Packit Service 2b1f13
ShapeOval(Widget w)
Packit Service 2b1f13
{
Packit Service 2b1f13
    Display *dpy = XtDisplay(w);
Packit Service 2b1f13
    int width = w->core.width;
Packit Service 2b1f13
    int height = w->core.height;
Packit Service 2b1f13
    Pixmap p;
Packit Service 2b1f13
    XGCValues values;
Packit Service 2b1f13
    GC gc;
Packit Service 2b1f13
    int rad;
Packit Service 2b1f13
Packit Service 2b1f13
    if (width < 3 || height < 3)
Packit Service 2b1f13
      return;
Packit Service 2b1f13
    width += w->core.border_width << 1;
Packit Service 2b1f13
    height += w->core.border_width << 1;
Packit Service 2b1f13
Packit Service 2b1f13
    p = XCreatePixmap(dpy, XtWindow(w), width, height, 1);
Packit Service 2b1f13
    values.foreground = 0;
Packit Service 2b1f13
    values.background = 1;
Packit Service 2b1f13
    values.cap_style = CapRound;
Packit Service 2b1f13
    values.line_width = Min(width, height);
Packit Service 2b1f13
    gc = XCreateGC(dpy, p,
Packit Service 2b1f13
		    GCForeground | GCBackground | GCLineWidth | GCCapStyle,
Packit Service 2b1f13
		    &values);
Packit Service 2b1f13
    XFillRectangle(dpy, p, gc, 0, 0, width, height);
Packit Service 2b1f13
    XSetForeground(dpy, gc, 1);
Packit Service 2b1f13
Packit Service 2b1f13
    if (width < height)
Packit Service 2b1f13
      {
Packit Service 2b1f13
	rad = width >> 1;
Packit Service 2b1f13
	XDrawLine(dpy, p, gc, rad, rad, rad, height - rad - 1);
Packit Service 2b1f13
      }
Packit Service 2b1f13
    else
Packit Service 2b1f13
      {
Packit Service 2b1f13
	rad = height >> 1;
Packit Service 2b1f13
	XDrawLine(dpy, p, gc, rad, rad, width - rad - 1, rad);
Packit Service 2b1f13
    }
Packit Service 2b1f13
    XShapeCombineMask(dpy, XtWindow(w), ShapeBounding,
Packit Service 2b1f13
		      -(int)w->core.border_width, -(int)w->core.border_width,
Packit Service 2b1f13
		      p, ShapeSet);
Packit Service 2b1f13
    if (w->core.border_width)
Packit Service 2b1f13
      {
Packit Service 2b1f13
	XSetForeground(dpy, gc, 0);
Packit Service 2b1f13
	XFillRectangle(dpy, p, gc, 0, 0, width, height);
Packit Service 2b1f13
	values.line_width = Min(w->core.width, w->core.height);
Packit Service 2b1f13
	values.foreground = 1;
Packit Service 2b1f13
	XChangeGC(dpy, gc, GCLineWidth | GCForeground, &values);
Packit Service 2b1f13
	if (w->core.width < w->core.height)
Packit Service 2b1f13
	  {
Packit Service 2b1f13
	    rad = w->core.width >> 1;
Packit Service 2b1f13
	    XDrawLine(dpy, p, gc, rad, rad, rad, w->core.height - rad - 1);
Packit Service 2b1f13
	  }
Packit Service 2b1f13
	else
Packit Service 2b1f13
	  {
Packit Service 2b1f13
	    rad = w->core.height >> 1;
Packit Service 2b1f13
	    XDrawLine(dpy, p, gc, rad, rad, w->core.width - rad - 1, rad);
Packit Service 2b1f13
	}
Packit Service 2b1f13
	XShapeCombineMask(dpy, XtWindow(w), ShapeClip, 0, 0, p, ShapeSet);
Packit Service 2b1f13
    }
Packit Service 2b1f13
    else
Packit Service 2b1f13
      XShapeCombineMask(XtDisplay(w), XtWindow(w),
Packit Service 2b1f13
			ShapeClip, 0, 0, None, ShapeSet);
Packit Service 2b1f13
Packit Service 2b1f13
    XFreePixmap(dpy, p);
Packit Service 2b1f13
    XFreeGC(dpy, gc);
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * Function:
Packit Service 2b1f13
 *	ShapeEllipseOrRoundedRectangle
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Parameters:
Packit Service 2b1f13
 *	w	- widget to be reshaped
Packit Service 2b1f13
 *	ellipse - True if shape to ellise, rounded rectangle otherwise
Packit Service 2b1f13
 *	ew	- horizontal radius of rounded rectangle
Packit Service 2b1f13
 *	eh	- vertical radius of rouded rectangle
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Description:
Packit Service 2b1f13
 *	  Based on the ellipse parameter, gives the widget a elliptical
Packit Service 2b1f13
 *	shape, or rounded rectangle shape.
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Notes:
Packit Service 2b1f13
 *	  The GC is created with a line width of 2, what seens to draw the
Packit Service 2b1f13
 *	widget border correctly, if the width - height is not proportional.
Packit Service 2b1f13
 */
Packit Service 2b1f13
static void
Packit Service 2b1f13
ShapeEllipseOrRoundedRectangle(Widget w, Bool ellipse, int ew, int eh)
Packit Service 2b1f13
{
Packit Service 2b1f13
    Display *dpy = XtDisplay(w);
Packit Service 2b1f13
  unsigned width = w->core.width;
Packit Service 2b1f13
  unsigned height = w->core.height;
Packit Service 2b1f13
  Pixmap p;
Packit Service 2b1f13
    XGCValues values;
Packit Service 2b1f13
    GC gc;
Packit Service 2b1f13
  unsigned long mask;
Packit Service 2b1f13
Packit Service 2b1f13
  if (width < 3 || height < 3)
Packit Service 2b1f13
    return;
Packit Service 2b1f13
  width += w->core.border_width << 1;
Packit Service 2b1f13
  height += w->core.border_width << 1;
Packit Service 2b1f13
Packit Service 2b1f13
  mask = GCForeground | GCLineWidth;
Packit Service 2b1f13
  p = XCreatePixmap(dpy, XtWindow(w), width, height, 1);
Packit Service 2b1f13
Packit Service 2b1f13
    values.foreground = 0;
Packit Service 2b1f13
  values.line_width = 2;
Packit Service 2b1f13
Packit Service 2b1f13
  gc = XCreateGC(dpy, p, mask, &values);
Packit Service 2b1f13
  XFillRectangle(dpy, p, gc, 0, 0, width, height);
Packit Service 2b1f13
  XSetForeground(dpy, gc, 1);
Packit Service 2b1f13
    if (!ellipse)
Packit Service 2b1f13
    XmuFillRoundedRectangle(dpy, p, gc, 1, 1, width - 2, height - 2, ew, eh);
Packit Service 2b1f13
    else
Packit Service 2b1f13
    {
Packit Service 2b1f13
      XDrawArc(dpy, p, gc, 1, 1, width - 2, height - 2, 0, 360 * 64);
Packit Service 2b1f13
      XFillArc(dpy, p, gc, 2, 2, width - 4, height - 4, 0, 360 * 64);
Packit Service 2b1f13
    }
Packit Service 2b1f13
  XShapeCombineMask(dpy, XtWindow(w), ShapeBounding,
Packit Service 2b1f13
		    -(int)w->core.border_width, -(int)w->core.border_width,
Packit Service 2b1f13
		    p, ShapeSet);
Packit Service 2b1f13
  if (w->core.border_width)
Packit Service 2b1f13
    {
Packit Service 2b1f13
      XSetForeground(dpy, gc, 0);
Packit Service 2b1f13
      XFillRectangle(dpy, p, gc, 0, 0, width, height);
Packit Service 2b1f13
      XSetForeground(dpy, gc, 1);
Packit Service 2b1f13
	if (!ellipse)
Packit Service 2b1f13
	XmuFillRoundedRectangle(dpy, p, gc, 1, 1,
Packit Service 2b1f13
				w->core.width - 2, w->core.height - 2,
Packit Service 2b1f13
				ew, eh);
Packit Service 2b1f13
      else
Packit Service 2b1f13
	XFillArc(dpy, p, gc, 0, 0, w->core.width, w->core.height,
Packit Service 2b1f13
		 0, 360 * 64);
Packit Service 2b1f13
      XShapeCombineMask(dpy, XtWindow(w), ShapeClip, 0, 0, p, ShapeSet);
Packit Service 2b1f13
    }
Packit Service 2b1f13
  else
Packit Service 2b1f13
    XShapeCombineMask(XtDisplay(w), XtWindow(w),
Packit Service 2b1f13
		      ShapeClip, 0, 0, None, ShapeSet);
Packit Service 2b1f13
Packit Service 2b1f13
  XFreePixmap(dpy, p);
Packit Service 2b1f13
  XFreeGC(dpy, gc);
Packit Service 2b1f13
}