/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ /*----------------------------------------------------------------------*/ /* */ /* Name: */ /* Description: XfeBypassShell widget source. */ /* Author: Ramiro Estrugo */ /* */ /*----------------------------------------------------------------------*/ #include #include #include #include #ifdef EDITRES #include #endif #define MESSAGE1 "Widget is not an XfeBypassShell." #define MESSAGE2 "XfeBypassShell can only have one managed child." #define STRUCTURE_EVENTS StructureNotifyMask /*----------------------------------------------------------------------*/ /* */ /* Core class methods */ /* */ /*----------------------------------------------------------------------*/ static void ClassInitialize (); static void Initialize (Widget,Widget,ArgList,Cardinal *); static void Resize (Widget); static void Redisplay (Widget,XEvent *,Region); static void Realize (Widget,XtValueMask *,XSetWindowAttributes *); static void Destroy (Widget); static Boolean SetValues (Widget,Widget,Widget,ArgList,Cardinal *); /*----------------------------------------------------------------------*/ /* */ /* Composite Class Methods */ /* */ /*----------------------------------------------------------------------*/ static void InsertChild (Widget); static void DeleteChild (Widget); static void ChangeManaged (Widget); static XtGeometryResult GeometryManager (Widget,XtWidgetGeometry *, XtWidgetGeometry *); /*----------------------------------------------------------------------*/ /* */ /* XfeBypassShell action procedures */ /* */ /*----------------------------------------------------------------------*/ static void BtnUp (Widget,XEvent *,char **,Cardinal *); static void BtnDown (Widget,XEvent *,char **,Cardinal *); /*----------------------------------------------------------------------*/ /* */ /* Misc XfeBypassShell functions */ /* */ /*----------------------------------------------------------------------*/ static void DrawShadow (Widget,XEvent *,Region,XRectangle *); /*----------------------------------------------------------------------*/ /* */ /* Shell structure event handler */ /* */ /*----------------------------------------------------------------------*/ static void MappingEH (Widget,XtPointer,XEvent *,Boolean *); /*----------------------------------------------------------------------*/ /* */ /* XfeBypassShell resources */ /* */ /*----------------------------------------------------------------------*/ static XtResource resources[] = { /* Realization callback resources */ { XmNrealizeCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . realize_callback), XmRImmediate, (XtPointer) NULL, }, { XmNbeforeRealizeCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . before_realize_callback), XmRImmediate, (XtPointer) NULL, }, /* Mapping callback resources */ { XmNmapCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . map_callback), XmRImmediate, (XtPointer) NULL, }, { XmNunmapCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . unmap_callback), XmRImmediate, (XtPointer) NULL, }, { XmNchangeManagedCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . change_managed_callback), XmRImmediate, (XtPointer) NULL, }, /* Shadow resources */ { XmNbottomShadowColor, XmCBottomShadowColor, XmRPixel, sizeof(Pixel), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . bottom_shadow_color), XmRCallProc, (XtPointer) _XmBottomShadowColorDefault, }, { XmNtopShadowColor, XmCTopShadowColor, XmRPixel, sizeof(Pixel), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . top_shadow_color), XmRCallProc, (XtPointer) _XmTopShadowColorDefault, }, { XmNshadowThickness, XmCShadowThickness, XmRDimension, sizeof(Dimension), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . shadow_thickness), XmRImmediate, (XtPointer) 1 }, { XmNshadowType, XmCShadowType, XmRShadowType, sizeof(unsigned char), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . shadow_type), XmRImmediate, (XtPointer) XmSHADOW_OUT }, /* Cursor resources */ { XmNcursor, XmCCursor, XmRCursor, sizeof(Cursor), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . cursor), XmRString, "arrow" }, /* Other resources */ { XmNignoreExposures, XmCIgnoreExposures, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeBypassShellRec , xfe_bypass_shell . ignore_exposures), XmRImmediate, (XtPointer) False }, /* Override Shell resources */ { XmNallowShellResize, XmCAllowShellResize, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeBypassShellRec , shell . allow_shell_resize), XmRImmediate, (XtPointer) True }, { XmNoverrideRedirect, XmCOverrideRedirect, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeBypassShellRec , shell . override_redirect), XmRImmediate, (XtPointer) True }, { XmNsaveUnder, XmCSaveUnder, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeBypassShellRec , shell . save_under), XmRImmediate, (XtPointer) False }, /* Override WmShell resources */ { XmNtransient, XmCTransient, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeBypassShellRec , wm . transient), XmRImmediate, (XtPointer) True }, { XmNwaitForWm, XmCWaitForWm, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeBypassShellRec , wm . wait_for_wm), XmRImmediate, (XtPointer) False }, }; /*----------------------------------------------------------------------*/ /* */ /* XfeBypassShell actions */ /* */ /*----------------------------------------------------------------------*/ static XtActionsRec actions[] = { { "BtnDown", BtnDown }, { "BtnUp", BtnUp }, }; /*----------------------------------------------------------------------*/ /* */ /* XfeBypassShell translations */ /* */ /*----------------------------------------------------------------------*/ static char default_translations[] ="\ : BtnUp()\n\ : BtnDown()"; /*----------------------------------------------------------------------*/ /* */ /* Widget Class Record Initialization */ /* */ /*----------------------------------------------------------------------*/ _XFE_WIDGET_CLASS_RECORD(bypassshell,BypassShell) = { { (WidgetClass) &vendorShellClassRec, /* superclass */ "XfeBypassShell", /* class_name */ sizeof(XfeBypassShellRec), /* widget_size */ ClassInitialize, /* class_initialize */ NULL, /* class_part_initialize*/ False, /* class_inited */ Initialize, /* initialize */ NULL, /* initialize_hook */ Realize, /* realize */ #if 0 actions, /* actions */ XtNumber(actions), /* num_actions */ #else NULL, /* actions */ 0, /* num_actions */ #endif (XtResource *)resources, /* resources */ XtNumber(resources), /* num_resources */ NULLQUARK, /* xrm_class */ True, /* compress_motion */ XtExposeCompressMaximal, /* compress_exposure */ True, /* compress_enterleave */ False, /* visible_interest */ Destroy, /* destroy */ Resize, /* resize */ Redisplay, /* expose */ SetValues, /* set_values */ NULL, /* set_values_hook */ NULL, /* set_values_almost */ NULL, /* get_values_hook */ NULL, /* access_focus */ XtVersion, /* version */ NULL, /* callback_private */ default_translations, /* tm_table */ NULL, /* query_geometry */ NULL, /* display accelerator */ NULL, /* extension */ }, /* Composite Part */ { _XfeLiberalGeometryManager, /* geometry_manager */ ChangeManaged, /* change_managed */ XtInheritInsertChild, /* insert_child */ XtInheritDeleteChild, /* delete_child */ NULL /* extension */ }, /* Shell */ { NULL, /* extension */ }, /* WMShell */ { NULL, /* extension */ }, /* VendorShell */ { NULL, /* extension */ }, /* XfeBypassShell Part */ { NULL, /* extension */ }, }; /*----------------------------------------------------------------------*/ /* */ /* xfeBypassShellWidgetClass declaration. */ /* */ /*----------------------------------------------------------------------*/ _XFE_WIDGET_CLASS(bypassshell,BypassShell); /*----------------------------------------------------------------------*/ /* */ /* Core Class methods */ /* */ /*----------------------------------------------------------------------*/ static void ClassInitialize() { /* Register Xfe Converters */ /*XfeRegisterConverters();*/ /* Register Representation Types */ /* XfeRegisterRepresentationTypes(); */ } /*----------------------------------------------------------------------*/ static void Initialize(Widget rw,Widget nw,ArgList args,Cardinal *nargs) { XfeBypassShellPart * bp = _XfeBypassShellPart(nw); /* Make sure the shadow type is ok */ XfeRepTypeCheck(nw,XmRShadowType,&bp->shadow_type,XmSHADOW_OUT); /* Add mapping event handler */ XtAddEventHandler(nw,StructureNotifyMask,True,MappingEH,nw); /* Allocate the shadow GCs */ bp->top_shadow_GC = XfeAllocateColorGc(nw,bp->top_shadow_color,None,True); bp->bottom_shadow_GC = XfeAllocateColorGc(nw,bp->bottom_shadow_color,None,True); /* Initialize private members */ bp->managed_child = False; } /*----------------------------------------------------------------------*/ static void Destroy(Widget w) { XfeBypassShellPart * bp = _XfeBypassShellPart(w); XtReleaseGC(w,bp->top_shadow_GC); XtReleaseGC(w,bp->bottom_shadow_GC); } /*----------------------------------------------------------------------*/ static void Realize(Widget w,XtValueMask * mask,XSetWindowAttributes * wa) { XfeBypassShellPart * bp = _XfeBypassShellPart(w); /* Invoke before realize Callbacks */ _XfeInvokeCallbacks(w,bp->before_realize_callback, XmCR_BEFORE_REALIZE,NULL,False); /* The actual realization is handled by the superclass */ (*vendorShellWidgetClass->core_class.realize)(w,mask,wa); /* Invoke realize Callbacks */ _XfeInvokeCallbacks(w,bp->realize_callback,XmCR_REALIZE,NULL,False); } /*----------------------------------------------------------------------*/ static void Resize(Widget w) { XfeBypassShellPart * bp = _XfeBypassShellPart(w); /* The actual resize is handled by the superclass */ (*vendorShellWidgetClass->core_class.resize)(w); /* printf("Resize(%s)\n",XtName(w)); */ /* Place the managed child in the center of the shell */ if (_XfeIsAlive(bp->managed_child)) { _XfeMoveWidget(bp->managed_child, bp->shadow_thickness, bp->shadow_thickness); } } /*----------------------------------------------------------------------*/ static void Redisplay(Widget w,XEvent *event,Region region) { XfeBypassShellPart * bp = _XfeBypassShellPart(w); if (!bp->ignore_exposures) { DrawShadow(w,event,region,NULL); } } /*----------------------------------------------------------------------*/ static Boolean SetValues(Widget ow,Widget rw,Widget nw,ArgList args,Cardinal *nargs) { XfeBypassShellPart * np = _XfeBypassShellPart(nw); XfeBypassShellPart * op = _XfeBypassShellPart(ow); Boolean redisplay = False; /* shadow_thickness */ if (np->shadow_thickness != op->shadow_thickness) { redisplay = True; } /* shadow_type */ if (np->shadow_type != op->shadow_type) { /* Make sure the new shadow type is ok */ XfeRepTypeCheck(nw,XmRShadowType,&np->shadow_type,XmSHADOW_OUT); redisplay = True; } /* bottom_shadow_color */ if (np->bottom_shadow_color != op->bottom_shadow_color) { XtReleaseGC(nw,np->bottom_shadow_GC); np->bottom_shadow_GC = XfeAllocateColorGc(nw,np->bottom_shadow_color,None,True); redisplay = True; } /* top_shadow_color */ if (np->top_shadow_color != op->top_shadow_color) { XtReleaseGC(nw,np->top_shadow_GC); np->top_shadow_GC = XfeAllocateColorGc(nw,np->top_shadow_color,None,True); redisplay = True; } return redisplay; } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* Composite Class Methods */ /* */ /*----------------------------------------------------------------------*/ static void InsertChild(Widget child) { } /*----------------------------------------------------------------------*/ static void DeleteChild(Widget child) { } /*----------------------------------------------------------------------*/ static void ChangeManaged(Widget w) { XfeBypassShellPart * bp = _XfeBypassShellPart(w); Cardinal i; Widget new_managed_child = NULL; Widget old_managed_child = bp->managed_child; for (i = 0; i < _XfemNumChildren(w); i++) { Widget child = _XfeChildrenIndex(w,i); /* Look for the first child that is managed */ if ((child != old_managed_child) && _XfeChildIsShown(child)) { new_managed_child = child; } } #if 0 printf("ChangeManaged(%s,last = %s, new = %s)\n", XtName(w), old_managed_child ? XtName(old_managed_child) : "NULL", new_managed_child ? XtName(new_managed_child) : "NULL"); #endif if (new_managed_child) { /* Assign the new managed child */ bp->managed_child = new_managed_child; /* * Request that we be resized to the new geometry. * */ _XfeMakeGeometryRequest(w, _XfeWidth(bp->managed_child) + 2 * bp->shadow_thickness, _XfeHeight(bp->managed_child) + 2 * bp->shadow_thickness); /* Invoke before change managed Callbacks */ _XfeInvokeCallbacks(w,bp->change_managed_callback, XmCR_CHANGE_MANAGED,NULL,False); /* Place the managed child in the center of the shell */ _XfeMoveWidget(bp->managed_child, bp->shadow_thickness, bp->shadow_thickness); /* Raise the managed child's window to the top if needed */ if (XtIsWidget(w) && _XfeIsRealized(bp->managed_child)) { XRaiseWindow(XtDisplay(w),_XfeWindow(bp->managed_child)); } } } /*----------------------------------------------------------------------*/ static XtGeometryResult GeometryManager(Widget child,XtWidgetGeometry *request,XtWidgetGeometry *reply) { Widget w = XtParent(child); XfeBypassShellPart * bp = _XfeBypassShellPart(w); #if 0 printf("GeometryManager(w = %s,child = %s)\n",XtName(w),XtName(child)); #endif if (request->request_mode & XtCWQueryOnly) { return XtGeometryYes; } if (request->request_mode & CWX) { _XfeX(child) = request->x; } if (request->request_mode & CWY) { _XfeY(child) = request->y; } if (request->request_mode & CWWidth) { _XfeWidth(child) = request->width; } if (request->request_mode & CWHeight) { _XfeHeight(child) = request->height; } if (request->request_mode & CWBorderWidth) { _XfeBorderWidth(child) = request->border_width; } _XfeMakeGeometryRequest(w, _XfeWidth(bp->managed_child) + 2 * bp->shadow_thickness, _XfeHeight(bp->managed_child) + 2 * bp->shadow_thickness); XfeResize(w); return XtGeometryYes; } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfeBypassShell action procedures */ /* */ /*----------------------------------------------------------------------*/ static void BtnDown(Widget w,XEvent * event,char ** params,Cardinal * nparams) { XfeBypassShellPart * bp = _XfeBypassShellPart(w); /* printf("BtnDown(%s)\n",XtName(w)); */ } /*----------------------------------------------------------------------*/ static void BtnUp(Widget w,XEvent * event,char ** params,Cardinal * nparams) { XfeBypassShellPart * bp = _XfeBypassShellPart(w); /* printf("BtnUp(%s)\n",XtName(w)); */ } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* Shell structure event handler */ /* */ /*----------------------------------------------------------------------*/ static void MappingEH(Widget shell, XtPointer client_data, XEvent * event, Boolean * cont) { Widget w = (Widget) client_data; XfeBypassShellPart * bp = _XfeBypassShellPart(w); /* Make sure the shell is still alive */ if (_XfeIsAlive(w)) { switch(event->type) { /* Map */ case MapNotify: DrawShadow(w,NULL,NULL,NULL); /* Invoke map callbacks */ _XfeInvokeCallbacks(w,bp->map_callback,XmCR_MAP,NULL,False); break; /* Unmap */ case UnmapNotify: /* Invoke unmap callbacks */ _XfeInvokeCallbacks(w,bp->unmap_callback,XmCR_UNMAP,NULL,False); break; } } *cont = True; } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* Misc XfeBypassShell functions */ /* */ /*----------------------------------------------------------------------*/ static void DrawShadow(Widget w,XEvent * event,Region region,XRectangle * clip_rect) { XfeBypassShellPart * bp = _XfeBypassShellPart(w); if (!bp->shadow_thickness) { return; } _XmDrawShadows(XtDisplay(w),_XfeWindow(w), bp->top_shadow_GC,bp->bottom_shadow_GC, 0,0,_XfeWidth(w),_XfeHeight(w), bp->shadow_thickness,bp->shadow_type); } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfeBypassShell private methods */ /* */ /*----------------------------------------------------------------------*/ static Widget _bypass_shell_global = NULL; /*----------------------------------------------------------------------*/ /* extern */ Boolean _XfeBypassShellGlobalIsAlive(void) { return _XfeIsAlive(_bypass_shell_global); } /*----------------------------------------------------------------------*/ /* extern */ Widget _XfeBypassShellGlobalAccess(void) { assert( _XfeIsAlive(_bypass_shell_global) ); return _bypass_shell_global; } /*----------------------------------------------------------------------*/ /* extern */ Widget _XfeBypassShellGlobalInitialize(Widget pw,char * name,Arg * av,Cardinal ac) { assert( ! _XfeIsAlive(_bypass_shell_global) ); _bypass_shell_global = XfeCreateBypassShell(pw,name,av,ac); return _bypass_shell_global; } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfeBypassShell public methods */ /* */ /*----------------------------------------------------------------------*/ /* extern */ Widget XfeCreateBypassShell(Widget pw,char * name,Arg * av,Cardinal ac) { return XtCreatePopupShell(name,xfeBypassShellWidgetClass,pw,av,ac); } /*----------------------------------------------------------------------*/ /* extern */ void XfeBypassShellUpdateSize(Widget w) { XfeBypassShellPart * bp = _XfeBypassShellPart(w); assert( XfeIsBypassShell(w) ); /* printf("XfeBypassShellUpdateSize(%s)\n",XtName(w)); */ if (_XfeIsAlive(bp->managed_child)) { _XfeMakeGeometryRequest(w, _XfeWidth(bp->managed_child) + 2 * bp->shadow_thickness, _XfeHeight(bp->managed_child) + 2 * bp->shadow_thickness); } XfeResize(w); } /*----------------------------------------------------------------------*/