/*----------------------------------------------------------------------*/ /* extern */ void _XfeBmProcWithoutDrawing(Widget w,XtWidgetProc proc) { Widget shell; Window window; assert( _XfeIsAlive(w) ); assert( proc != NULL ); /* * We pretend that the closest shell's window is the button's. This is * a hack so that the widget procedure 'proc' does not draw anything. */ shell = XfeAncestorFindByClass(w,shellWidgetClass,XfeFIND_ANY); window = _XfeWindow(w); /* * We change the width to 0, so that the real Enter() * action does not draw anything in the cascade button so that * we can draw the accent lines. */ _XfeWindow(w) = _XfeWindow(shell); (*proc)(w); _XfeWindow(w) = window; }
/*----------------------------------------------------------------------*/ static void DrawHighlight(Widget w,XEvent * event,Region region,XRectangle * clip_rect) { XfeComboBoxPart * cp = _XfeComboBoxPart(w); /* Make sure the highlight is needed */ if (!cp->highlight_thickness || !_XfeIsRealized(w)) { return; } if (cp->highlighted) { _XmDrawSimpleHighlight(XtDisplay(w), _XfeWindow(w), _XfemHighlightGC(w), 0,0, _XfeWidth(w),_XfeHeight(w), cp->highlight_thickness); } else { assert( XmIsManager(_XfeParent(w)) ); _XmDrawSimpleHighlight(XtDisplay(w), _XfeWindow(w), _XfemBackgroundGC(_XfeParent(w)), 0,0, _XfeWidth(w),_XfeHeight(w), cp->highlight_thickness); } }
/*----------------------------------------------------------------------*/ /* extern */ void _XfeBmActionWithoutDrawing(Widget w, XtActionProc proc, XEvent * event, char ** params, Cardinal * nparams) { Widget shell; Window window; assert( _XfeIsAlive(w) ); assert( proc != NULL ); shell = XfeAncestorFindByClass(w,shellWidgetClass,XfeFIND_ANY); window = _XfeWindow(w); /* * We change the width to 0, so that the real Enter() * action does not draw anything in the cascade button so that * we can draw the accent lines. */ _XfeWindow(w) = _XfeWindow(shell); (*proc)(w,event,params,nparams); _XfeWindow(w) = window; }
/*----------------------------------------------------------------------*/ static void AccentBottom(Widget w, GC top_gc, GC bottom_gc, Dimension offset_left, Dimension offset_right, Dimension shadow_thickness, Dimension accent_thickness, int code) { Widget pw = _XfeParent(w); int position_index = XfeMenuItemPositionIndex(w); Cardinal num_children = _XfemNumChildren(pw); Position x; Position y; Dimension width; Dimension height = 2 * shadow_thickness + accent_thickness; assert( code == ACCENT_DRAW || code == ACCENT_ERASE ); /* Last item */ if (position_index == (num_children - 1)) { x = _XfeX(w) + offset_left; y = _XfeY(w) + _XfeHeight(w) - height; width = _XfeWidth(w) - offset_left - offset_right; } /* Any other item */ else { x = _XfeX(w) + offset_left; y = _XfeY(w) + _XfeHeight(w) - height / 2; width = _XfeWidth(w) - offset_left - offset_right; } if (code == ACCENT_DRAW) { /* Draw accent */ _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc, x,y,width,height,shadow_thickness,XmSHADOW_IN); } else { /* Erase accent */ XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc, x,y,width,height,shadow_thickness); } }
/*----------------------------------------------------------------------*/ static Position GetPointerY(Widget w) { Window root; Window child; int rx; int ry; int cx; int cy; unsigned int mask; if (XQueryPointer(XtDisplay(w),_XfeWindow(w),&root,&child, &rx,&ry,&cx,&cy,&mask)) { cy -= _XfeY(w); if (cy < 0) { cy = 0; } if (cy > _XfeHeight(w)) { cy = _XfeHeight(w); } return cy; } return 0; }
/*----------------------------------------------------------------------*/ /* extern */ void XfeDrawShadowsAroundWidget(Widget parent, Widget child, GC top_gc, GC bottom_gc, Dimension offset, Dimension shadow_thickness, unsigned char shadow_type) { assert( _XfeIsAlive(parent) ); assert( _XfeIsAlive(child) ); assert( shadow_thickness > 0 ); assert( XmIsManager(parent) ); _XmDrawShadows(XtDisplay(parent), _XfeWindow(parent), _XfemTopShadowGC(parent), _XfemBottomShadowGC(parent), _XfeX(child) - shadow_thickness - offset, _XfeY(child) - shadow_thickness - offset, _XfeWidth(child) + 2 * shadow_thickness + 2 * offset, _XfeHeight(child) + 2 * shadow_thickness + 2 * offset, shadow_thickness, shadow_type); }
/*----------------------------------------------------------------------*/ static void Realize(Widget w,XtValueMask * mask,XSetWindowAttributes* wa) { XSetWindowAttributes attr; /* Make sure only subclasses of XfePrimitive get instanciated */ if ((XtClass(w) == xfePrimitiveWidgetClass)) { _XfeWarning(w,MESSAGE0); return; } /* Let XmPrimitive create the window */ (*xmPrimitiveWidgetClass->core_class.realize)(w,mask,wa); /* Set the Bit Gravity */ attr.bit_gravity = _XfePrimitiveAccessBitGravity(w); XChangeWindowAttributes(XtDisplay(w),_XfeWindow(w),CWBitGravity,&attr); /* Define the cursor if needed */ if (_XfeCursorGood(_XfeCursor(w)) && _XfePointerInside(w)) { XfeCursorDefine(w,_XfeCursor(w)); } }
/*----------------------------------------------------------------------*/ static void DrawPixmap(Widget w,XEvent *event,Region region) { XfeBmCascadePart * bmc = _XfeBmCascadePart(w); XmLabelPart * lp = _XfeXmLabelPart(w); Pixmap pixmap = XmUNSPECIFIED_PIXMAP; Pixmap mask = XmUNSPECIFIED_PIXMAP; Boolean armed = CB_IsArmed(w); if (armed && _XfePixmapGood(bmc->arm_pixmap)) { pixmap = bmc->arm_pixmap; if (_XfePixmapGood(bmc->arm_pixmap_mask)) { mask = bmc->arm_pixmap_mask; } } else if (_XfePixmapGood(lp->pixmap) && bmc->pixmap_width && bmc->pixmap_height) { pixmap = lp->pixmap; if (_XfePixmapGood(bmc->label_pixmap_mask)) { mask = bmc->label_pixmap_mask; } } if (_XfePixmapGood(pixmap)) { Position x = _XfePrimitiveOffset(w) + lp->margin_width; Position y = (_XfeHeight(w) - bmc->pixmap_height) / 2; if (_XfePixmapGood(mask)) { XSetClipOrigin(XtDisplay(w),bmc->pixmap_GC,x,y); XSetClipMask(XtDisplay(w),bmc->pixmap_GC,mask); } else { XSetClipMask(XtDisplay(w),bmc->pixmap_GC,None); } XCopyArea(XtDisplay(w), pixmap, _XfeWindow(w), bmc->pixmap_GC, 0,0, bmc->pixmap_width, bmc->pixmap_height, x, y); } }
/*----------------------------------------------------------------------*/ void _XfePrimitiveDrawBuffer(Widget w,XEvent * event,Region region) { XCopyArea(XtDisplay(w), _XfePrimitiveDrawable(w), _XfeWindow(w), _XfeBackgroundGC(w), _XfeHighlightThickness(w),_XfeHighlightThickness(w), _XfeWidth(w) - 2 * _XfeHighlightThickness(w), _XfeHeight(w) - 2 * _XfeHighlightThickness(w), _XfeHighlightThickness(w),_XfeHighlightThickness(w)); }
/*----------------------------------------------------------------------*/ static void DrawTitleShadow(Widget w,XEvent * event,Region region,XRectangle * clip_rect) { XfeFancyBoxPart * fp = _XfeFancyBoxPart(w); XfeComboBoxPart * cp = _XfeComboBoxPart(w); /* Make sure the shadow is needed */ if (!cp->title_shadow_thickness) { return; } if (_XfeIsAlive(fp->icon)) { Dimension icon_x1 = _XfeX(fp->icon) - cp->spacing; Dimension title_x2 = _XfeX(cp->title) + _XfeWidth(cp->title); /* Draw the shadow around the icon and text */ _XmDrawShadows(XtDisplay(w), _XfeWindow(w), _XfemTopShadowGC(w),_XfemBottomShadowGC(w), CB_OFFSET_LEFT(w,cp), _XfeY(cp->title) - cp->title_shadow_thickness, (title_x2 - icon_x1) + 2 * cp->title_shadow_thickness, _XfeHeight(cp->title) + 2 * cp->title_shadow_thickness, cp->title_shadow_thickness, cp->title_shadow_type); } else { /* Draw the shadow around the text only */ XfeDrawShadowsAroundWidget(w, cp->title, _XfemTopShadowGC(w), _XfemBottomShadowGC(w), 0, cp->title_shadow_thickness, cp->title_shadow_type); } }
/*----------------------------------------------------------------------*/ static void DrawShadow(Widget w,XEvent * event,Region region,XRectangle * clip_rect) { XfeComboBoxPart * cp = _XfeComboBoxPart(w); if (!_XfemShadowThickness(w)) { return; } /* Draw the shadow */ _XmDrawShadows(XtDisplay(w), _XfeWindow(w), _XfemTopShadowGC(w),_XfemBottomShadowGC(w), cp->highlight_thickness, cp->highlight_thickness, _XfeWidth(w) - 2 * cp->highlight_thickness, _XfeHeight(w) - 2 * cp->highlight_thickness, _XfemShadowThickness(w), _XfemShadowType(w)); }
/*----------------------------------------------------------------------*/ Drawable _XfePrimitiveDrawable(Widget w) { Drawable d = None; switch(_XfeBufferType(w)) { case XmBUFFER_NONE: d = _XfeWindow(w); break; case XmBUFFER_PRIVATE: d = _XfeBufferPixmap(w); break; case XmBUFFER_SHARED: d = _XfePixmapBufferAccess(); break; } return d; }
/*----------------------------------------------------------------------*/ void _XfePrimitiveClearBackground(Widget w) { /* Clear the widget background including margins */ if (_XfeBufferType(w) == XmBUFFER_NONE) { XClearArea(XtDisplay(w),_XfeWindow(w), _XfeHighlightThickness(w),_XfeHighlightThickness(w), _XfeWidth(w) - 2 * _XfeHighlightThickness(w), _XfeHeight(w) - 2 * _XfeHighlightThickness(w), False); /*XClearWindow(XtDisplay(w),_XfeWindow(w));*/ } else { XFillRectangle(XtDisplay(w), _XfePrimitiveDrawable(w), _XfeBackgroundGC(w), 0,0, _XfeWidth(w),_XfeHeight(w)); } }
/*----------------------------------------------------------------------*/ static void AccentAll(Widget w, GC top_gc, GC bottom_gc, Dimension offset_left, Dimension offset_right, Dimension shadow_thickness, Dimension accent_thickness, int code) { #if 1 if (code == ACCENT_DRAW) { /* Draw accent */ _XmDrawShadows(XtDisplay(w),_XfeWindow(w), top_gc,bottom_gc, _XfeHighlightThickness(w), _XfeHighlightThickness(w), _XfeWidth(w) - 2 * _XfeHighlightThickness(w), _XfeHeight(w) - 2 * _XfeHighlightThickness(w), _XfeShadowThickness(w), XmSHADOW_OUT); } else { /* Erase accent */ XfeDrawRectangle(XtDisplay(w),_XfeWindow(w),top_gc, _XfeHighlightThickness(w), _XfeHighlightThickness(w), _XfeWidth(w) - 2 * _XfeHighlightThickness(w), _XfeHeight(w) - 2 * _XfeHighlightThickness(w), _XfeShadowThickness(w)); } #else Widget pw = _XfeParent(w); int position_index = XfeMenuItemPositionIndex(w); Cardinal num_children = _XfemNumChildren(pw); Position x; Position y; Dimension width; Dimension height; Dimension total_thickness = shadow_thickness + accent_thickness; assert( code == ACCENT_DRAW || code == ACCENT_ERASE ); /* One and only */ if (num_children == 1) { x = _XfeX(w) + offset_left; y = _XfeY(w); width = _XfeWidth(w) - offset_left - offset_right; height = _XfeHeight(w); } else { Dimension overlap = (2 * shadow_thickness + accent_thickness) / 2; /* First item */ if (position_index == 0) { x = _XfeX(w) + offset_left; y = _XfeY(w); width = _XfeWidth(w) - offset_left - offset_right; height = _XfeHeight(w) + overlap; } /* Last item */ else if (position_index == (num_children - 1)) { x = _XfeX(w) + offset_left; y = _XfeY(w) - overlap; width = _XfeWidth(w) - offset_left - offset_right; height = _XfeHeight(w) + overlap; } /* In between two others */ else { x = _XfeX(w) + offset_left; y = _XfeY(w) - overlap; width = _XfeWidth(w) - offset_left - offset_right; height = _XfeHeight(w) + 2 * total_thickness; } } if (code == ACCENT_DRAW) { /* Draw accent */ _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc, x,y,width,height,shadow_thickness,XmSHADOW_IN); x += total_thickness; y += total_thickness; width -= (2 * total_thickness); height -= (2 * total_thickness); _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc, x,y,width,height,shadow_thickness,XmSHADOW_OUT); } else { /* Erase accent */ XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc, x,y,width,height,shadow_thickness); x += total_thickness; y += total_thickness; width -= (2 * total_thickness); height -= (2 * total_thickness); XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc, x,y,width,height,shadow_thickness); } #endif }
/*----------------------------------------------------------------------*/ /* extern */ Boolean XfeShellGetDecorationOffset(Widget shell, Position * x_out, Position * y_out) { Position x = 0; Position y = 0; Boolean result = False; assert( XtIsShell(shell) ); assert( x_out != NULL || y_out != NULL ); if (_XfeIsAlive(shell)) { Window root; Window parent = None; Window parent2 = None; Window * children = NULL; unsigned int num_children; if (!XQueryTree(XtDisplay(shell),_XfeWindow(shell), &root,&parent,&children,&num_children)) { parent2 = None; } if (children) { XFree(children); } if (children) { XFree(children); } if (parent != None) { int px; int py; unsigned int width; unsigned int height; unsigned int border; unsigned int depth; if (XGetGeometry(XtDisplay(shell),parent,&root,&px,&py, &width,&height,&border,&depth)) { x = px; y = py; result = True; } } } if (x_out) { *x_out = x; } if (y_out) { *y_out = y; } return result; }