ShapeWidg.c

Go to the documentation of this file.
00001 /* $Xorg: ShapeWidg.c,v 1.4 2001/02/09 02:03:53 xorgcvs Exp $ */
00002 
00003 /* 
00004  
00005 Copyright 1988, 1998  The Open Group
00006 
00007 Permission to use, copy, modify, distribute, and sell this software and its
00008 documentation for any purpose is hereby granted without fee, provided that
00009 the above copyright notice appear in all copies and that both that
00010 copyright notice and this permission notice appear in supporting
00011 documentation.
00012 
00013 The above copyright notice and this permission notice shall be included in
00014 all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00019 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00020 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 
00023 Except as contained in this notice, the name of The Open Group shall not be
00024 used in advertising or otherwise to promote the sale, use or other dealings
00025 in this Software without prior written authorization from The Open Group.
00026 
00027 */
00028 /* $XFree86: xc/lib/Xmu/ShapeWidg.c,v 1.7 2001/01/17 19:42:56 dawes Exp $ */
00029 
00030 #include <X11/IntrinsicP.h>
00031 #include <X11/extensions/shape.h>
00032 #include "Converters.h"
00033 #include "Drawing.h"
00034 #include "Misc.h"
00035 
00036 /*
00037  * Prototypes
00038  */
00039 static void ShapeEllipseOrRoundedRectangle(Widget, Bool, int, int);
00040 static void ShapeError(Widget);
00041 static void ShapeOval(Widget);
00042 static void ShapeRectangle(Widget);
00043 
00044 /*
00045  * Implementation
00046  */
00047 Boolean
00048 XmuReshapeWidget(Widget w, int shape_style,
00049                  int corner_width, int corner_height)
00050 {
00051   switch (shape_style)
00052     {
00053       case XmuShapeRectangle:
00054         ShapeRectangle(w);
00055         break;
00056       case XmuShapeOval:
00057         ShapeOval(w);
00058         break;
00059       case XmuShapeEllipse:
00060       case XmuShapeRoundedRectangle:
00061       ShapeEllipseOrRoundedRectangle(w, shape_style == XmuShapeEllipse,
00062                                      corner_width, corner_height);
00063         break;
00064       default:
00065         ShapeError(w);
00066       return (False);
00067     }
00068   return (True);
00069 }
00070 
00071 static void
00072 ShapeError(Widget w)
00073 {
00074     String params[1];
00075     Cardinal num_params = 1;
00076 
00077     params[0] = XtName(w);
00078   XtAppWarningMsg(XtWidgetToApplicationContext(w),
00079                      "shapeUnknown", "xmuReshapeWidget", "XmuLibrary",
00080                      "Unsupported shape style for Command widget \"%s\"",
00081                   params, &num_params);
00082 }
00083 
00084 static void
00085 ShapeRectangle(Widget w)
00086 {
00087   XShapeCombineMask(XtDisplay(w), XtWindow(w),
00088                     ShapeBounding, 0, 0, None, ShapeSet);
00089   XShapeCombineMask(XtDisplay(w), XtWindow(w),
00090                     ShapeClip, 0, 0, None, ShapeSet);
00091 }
00092 
00093 /*
00094  * Function:
00095  *      ShapeOval
00096  *
00097  * Parameters:
00098  *      w - widget to be reshaped
00099  *
00100  * Description:
00101  *      Reshapes a widget to a oval format.
00102  *
00103  * Notes:
00104  *        X11R6.3 behaviour changed. Now if the height is larger than the
00105  *      width, this function inverts the sense of the oval, instead of
00106  *      fallbacking to ellipse.
00107  */
00108 static void
00109 ShapeOval(Widget w)
00110 {
00111     Display *dpy = XtDisplay(w);
00112     int width = w->core.width;
00113     int height = w->core.height;
00114     Pixmap p;
00115     XGCValues values;
00116     GC gc;
00117     int rad;
00118 
00119     if (width < 3 || height < 3)
00120       return;
00121     width += w->core.border_width << 1;
00122     height += w->core.border_width << 1;
00123 
00124     p = XCreatePixmap(dpy, XtWindow(w), width, height, 1);
00125     values.foreground = 0;
00126     values.background = 1;
00127     values.cap_style = CapRound;
00128     values.line_width = Min(width, height);
00129     gc = XCreateGC(dpy, p,
00130                     GCForeground | GCBackground | GCLineWidth | GCCapStyle,
00131                     &values);
00132     XFillRectangle(dpy, p, gc, 0, 0, width, height);
00133     XSetForeground(dpy, gc, 1);
00134 
00135     if (width < height)
00136       {
00137         rad = width >> 1;
00138         XDrawLine(dpy, p, gc, rad, rad, rad, height - rad - 1);
00139       }
00140     else
00141       {
00142         rad = height >> 1;
00143         XDrawLine(dpy, p, gc, rad, rad, width - rad - 1, rad);
00144     }
00145     XShapeCombineMask(dpy, XtWindow(w), ShapeBounding, 
00146                       -(int)w->core.border_width, -(int)w->core.border_width,
00147                       p, ShapeSet);
00148     if (w->core.border_width)
00149       {
00150         XSetForeground(dpy, gc, 0);
00151         XFillRectangle(dpy, p, gc, 0, 0, width, height);
00152         values.line_width = Min(w->core.width, w->core.height);
00153         values.foreground = 1;
00154         XChangeGC(dpy, gc, GCLineWidth | GCForeground, &values);
00155         if (w->core.width < w->core.height)
00156           {
00157             rad = w->core.width >> 1;
00158             XDrawLine(dpy, p, gc, rad, rad, rad, w->core.height - rad - 1);
00159           }
00160         else
00161           {
00162             rad = w->core.height >> 1;
00163             XDrawLine(dpy, p, gc, rad, rad, w->core.width - rad - 1, rad);
00164         }
00165         XShapeCombineMask(dpy, XtWindow(w), ShapeClip, 0, 0, p, ShapeSet);
00166     }
00167     else
00168       XShapeCombineMask(XtDisplay(w), XtWindow(w),
00169                         ShapeClip, 0, 0, None, ShapeSet);
00170 
00171     XFreePixmap(dpy, p);
00172     XFreeGC(dpy, gc);
00173 }
00174 
00175 /*
00176  * Function:
00177  *      ShapeEllipseOrRoundedRectangle
00178  *
00179  * Parameters:
00180  *      w       - widget to be reshaped
00181  *      ellipse - True if shape to ellise, rounded rectangle otherwise
00182  *      ew      - horizontal radius of rounded rectangle
00183  *      eh      - vertical radius of rouded rectangle
00184  *
00185  * Description:
00186  *        Based on the ellipse parameter, gives the widget a elliptical
00187  *      shape, or rounded rectangle shape.
00188  *
00189  * Notes:
00190  *        The GC is created with a line width of 2, what seens to draw the
00191  *      widget border correctly, if the width - height is not proportional.
00192  */
00193 static void
00194 ShapeEllipseOrRoundedRectangle(Widget w, Bool ellipse, int ew, int eh)
00195 {
00196     Display *dpy = XtDisplay(w);
00197   unsigned width = w->core.width;
00198   unsigned height = w->core.height;
00199   Pixmap p;
00200     XGCValues values;
00201     GC gc;
00202   unsigned long mask;
00203 
00204   if (width < 3 || width < 3)
00205     return;
00206   width += w->core.border_width << 1;
00207   height += w->core.border_width << 1;
00208 
00209   mask = GCForeground | GCLineWidth;
00210   p = XCreatePixmap(dpy, XtWindow(w), width, height, 1);
00211 
00212     values.foreground = 0;
00213   values.line_width = 2;
00214 
00215   gc = XCreateGC(dpy, p, mask, &values);
00216   XFillRectangle(dpy, p, gc, 0, 0, width, height);
00217   XSetForeground(dpy, gc, 1);
00218     if (!ellipse)
00219     XmuFillRoundedRectangle(dpy, p, gc, 1, 1, width - 2, height - 2, ew, eh);
00220     else
00221     {
00222       XDrawArc(dpy, p, gc, 1, 1, width - 2, height - 2, 0, 360 * 64);
00223       XFillArc(dpy, p, gc, 2, 2, width - 4, height - 4, 0, 360 * 64);
00224     }
00225   XShapeCombineMask(dpy, XtWindow(w), ShapeBounding,
00226                     -(int)w->core.border_width, -(int)w->core.border_width,
00227                     p, ShapeSet);
00228   if (w->core.border_width)
00229     {
00230       XSetForeground(dpy, gc, 0);
00231       XFillRectangle(dpy, p, gc, 0, 0, width, height);
00232       XSetForeground(dpy, gc, 1);
00233         if (!ellipse)
00234         XmuFillRoundedRectangle(dpy, p, gc, 1, 1,
00235                                 w->core.width - 2, w->core.height - 2,
00236                                 ew, eh);
00237       else
00238         XFillArc(dpy, p, gc, 0, 0, w->core.width, w->core.height,
00239                  0, 360 * 64);
00240       XShapeCombineMask(dpy, XtWindow(w), ShapeClip, 0, 0, p, ShapeSet);
00241     }
00242   else
00243     XShapeCombineMask(XtDisplay(w), XtWindow(w),
00244                       ShapeClip, 0, 0, None, ShapeSet);
00245 
00246   XFreePixmap(dpy, p);
00247   XFreeGC(dpy, gc);
00248 }

Generated on Sun Mar 4 15:03:56 2007 for Scilab [trunk] by  doxygen 1.5.1