/* -*- 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: XfeTempShell widget source. */ /* Author: Ramiro Estrugo */ /* */ /*----------------------------------------------------------------------*/ #include #include #include #include #define BYPASS_SHELL_NAME "SharedBypassShell" #ifndef __hpux #define EDITRES 1 #endif #ifdef EDITRES #include #endif #define MESSAGE1 "Widget is not an XfeFrameShell." #define MESSAGE2 "XmNhasBeenMapped is a read-only resource." #define STRUCTURE_EVENTS StructureNotifyMask /*----------------------------------------------------------------------*/ /* */ /* Core class methods */ /* */ /*----------------------------------------------------------------------*/ static void ClassInitialize (); static void Initialize (Widget,Widget,ArgList,Cardinal *); static void Resize (Widget); static void Realize (Widget,XtValueMask *,XSetWindowAttributes *); static void Destroy (Widget); static Boolean SetValues (Widget,Widget,Widget,ArgList,Cardinal *); static void GetValuesHook (Widget,ArgList,Cardinal *); /*----------------------------------------------------------------------*/ /* */ /* Tracking update functions */ /* */ /*----------------------------------------------------------------------*/ static void SetTrackEditres (Widget,Boolean); static void SetTrackMapping (Widget,Boolean); static void SetTrackSaveYourself (Widget,Boolean); static void SetTrackDeleteWindow (Widget,Boolean); /*----------------------------------------------------------------------*/ /* */ /* Window manager protocol callbacks */ /* */ /*----------------------------------------------------------------------*/ static void DeleteWindowCB (Widget,XtPointer,XtPointer); static void SaveYourselfCB (Widget,XtPointer,XtPointer); /*----------------------------------------------------------------------*/ /* */ /* Shell structure event handler */ /* */ /*----------------------------------------------------------------------*/ static void StructureEH (Widget,XtPointer,XEvent *,Boolean *); static void MappingEH (Widget,XtPointer,XEvent *,Boolean *); /*----------------------------------------------------------------------*/ /* */ /* XfeFrameShell resources */ /* */ /*----------------------------------------------------------------------*/ static XtResource resources[] = { /* Realization callback resources */ { XmNrealizeCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.realize_callback), XmRImmediate, (XtPointer) NULL, }, { XmNbeforeRealizeCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.before_realize_callback), XmRImmediate, (XtPointer) NULL, }, /* Configure callback resources */ { XmNresizeCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.resize_callback), XmRImmediate, (XtPointer) NULL, }, { XmNbeforeResizeCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.before_resize_callback), XmRImmediate, (XtPointer) NULL, }, { XmNmoveCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.move_callback), XmRImmediate, (XtPointer) NULL, }, /* WM Protocol callback resources */ { XmNdeleteWindowCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.delete_window_callback), XmRImmediate, (XtPointer) NULL, }, { XmNsaveYourselfCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.save_yourself_callback), XmRImmediate, (XtPointer) NULL, }, /* Mapping callbacks */ { XmNfirstMapCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.first_map_callback), XmRImmediate, (XtPointer) NULL, }, { XmNmapCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.map_callback), XmRImmediate, (XtPointer) NULL, }, { XmNunmapCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.unmap_callback), XmRImmediate, (XtPointer) NULL, }, /* Title changed callback */ { XmNtitleChangedCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeFrameShellRec,xfe_frame_shell.title_changed_callback), XmRImmediate, (XtPointer) NULL, }, /* Tracking resources */ { XmNtrackEditres, XmCTrackEditres, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeFrameShellRec , xfe_frame_shell . track_editres), XmRImmediate, (XtPointer) False }, { XmNtrackMapping, XmCTrackMapping, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeFrameShellRec , xfe_frame_shell . track_mapping), XmRImmediate, (XtPointer) True }, { XmNtrackPosition, XmCTrackPosition, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeFrameShellRec , xfe_frame_shell . track_position), XmRImmediate, (XtPointer) True }, { XmNtrackSaveYourself, XmCTrackSaveYourself, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeFrameShellRec , xfe_frame_shell . track_save_yourself), XmRImmediate, (XtPointer) True }, { XmNtrackSize, XmCTrackSize, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeFrameShellRec , xfe_frame_shell . track_size), XmRImmediate, (XtPointer) True }, /* Other resources */ { XmNhasBeenMapped, XmCReadOnly, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeFrameShellRec , xfe_frame_shell . has_been_mapped), XmRImmediate, (XtPointer) False }, { XmNstartIconic, XmCStartIconic, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeFrameShellRec , xfe_frame_shell . start_iconic), XmRImmediate, (XtPointer) True }, { XmNbypassShell, XmCBypassShell, XmRWidget, sizeof(Widget), XtOffsetOf(XfeFrameShellRec , xfe_frame_shell . bypass_shell), XmRImmediate, (XtPointer) NULL }, }; /*----------------------------------------------------------------------*/ /* */ /* Widget Class Record Initialization */ /* */ /*----------------------------------------------------------------------*/ _XFE_WIDGET_CLASS_RECORD(frameshell,FrameShell) = { { (WidgetClass) &topLevelShellClassRec, /* superclass */ "XfeFrameShell", /* class_name */ sizeof(XfeFrameShellRec), /* widget_size */ ClassInitialize, /* class_initialize */ NULL, /* class_part_initialize*/ FALSE, /* class_inited */ Initialize, /* initialize */ NULL, /* initialize_hook */ Realize, /* realize */ NULL, /* actions */ 0, /* num_actions */ (XtResource *)resources, /* resources */ XtNumber(resources), /* num_resources */ NULLQUARK, /* xrm_class */ FALSE, /* compress_motion */ TRUE, /* compress_exposure */ FALSE, /* compress_enterleave */ FALSE, /* visible_interest */ Destroy, /* destroy */ Resize, /* resize */ XtInheritExpose, /* expose */ SetValues, /* set_values */ NULL, /* set_values_hook */ NULL, /* set_values_almost */ GetValuesHook, /* get_values_hook */ NULL, /* access_focus */ XtVersion, /* version */ NULL, /* callback_private */ XtInheritTranslations, /* tm_table */ NULL, /* query_geometry */ NULL, /* display accelerator */ NULL, /* extension */ }, /* Composite Part */ { XtInheritGeometryManager, /* geometry_manager */ XtInheritChangeManaged, /* change_managed */ XtInheritInsertChild, /* insert_child */ XtInheritDeleteChild, /* delete_child */ NULL /* extension */ }, /* Shell */ { NULL, /* extension */ }, /* WMShell */ { NULL, /* extension */ }, /* VendorShell */ { NULL, /* extension */ }, /* TopShell */ { NULL, /* extension */ }, /* XfeFrameShell Part */ { NULL, /* extension */ }, }; /*----------------------------------------------------------------------*/ /* */ /* xfeFrameShellWidgetClass declaration. */ /* */ /*----------------------------------------------------------------------*/ _XFE_WIDGET_CLASS(frameshell,FrameShell); /*----------------------------------------------------------------------*/ /* */ /* 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) { XfeFrameShellPart * fp = _XfeFrameShellPart(nw); /* Check read only resources */ if (fp->has_been_mapped) { fp->has_been_mapped = False; _XfeWarning(nw,MESSAGE2); } /* Initialize private members */ /* Update tracking */ /* SetTrackEditres(nw,fp->track_editres); */ SetTrackMapping(nw,fp->track_mapping); SetTrackSaveYourself(nw,fp->track_save_yourself); SetTrackDeleteWindow(nw,fp->track_delete_window); } /*----------------------------------------------------------------------*/ static void Destroy(Widget w) { /* XfeFrameShellPart * fp = _XfeFrameShellPart(w); */ #if 0 SetTrackEditres(w,False); SetTrackMapping(w,False); SetTrackSaveYourself(w,False); SetTrackDeleteWindow(w,False); #endif } /*----------------------------------------------------------------------*/ static void Realize(Widget w,XtValueMask * mask,XSetWindowAttributes * wa) { XfeFrameShellPart * fp = _XfeFrameShellPart(w); /* Invoke before realize Callbacks */ _XfeInvokeCallbacks(w,fp->before_realize_callback, XmCR_BEFORE_REALIZE,NULL,False); /* * HACKERY HACKERY HACKERY HACKERY HACKERY HACKERY HACKERY HACKERY * * This is a complete HACK. Hardcode the dimensions to 640x480 * until I write some clever code to compute dimensions from * resources, command line, children preferred geometries, and * other magical things. * * HACKERY HACKERY HACKERY HACKERY HACKERY HACKERY HACKERY HACKERY */ if (_XfeWidth(w) <= 2) { _XfeWidth(w) = 600; } if (_XfeHeight(w) <= 2) { _XfeHeight(w) = 480; } /* The actual realization is handled by the superclass */ (*topLevelShellWidgetClass->core_class.realize)(w,mask,wa); /* Invoke realize Callbacks */ _XfeInvokeCallbacks(w,fp->realize_callback,XmCR_REALIZE,NULL,False); } /*----------------------------------------------------------------------*/ static void Resize(Widget w) { XfeFrameShellPart * fp = _XfeFrameShellPart(w); /* Invoke before resize Callbacks */ _XfeInvokeCallbacks(w,fp->before_resize_callback, XmCR_BEFORE_RESIZE,NULL,False); /* The actual realization is handled by the superclass */ (*topLevelShellWidgetClass->core_class.resize)(w); /* Invoke resize Callbacks */ _XfeInvokeCallbacks(w,fp->resize_callback,XmCR_RESIZE,NULL,False); } /*----------------------------------------------------------------------*/ static Boolean SetValues(Widget ow,Widget rw,Widget nw,ArgList args,Cardinal *nargs) { XfeFrameShellPart * np = _XfeFrameShellPart(nw); XfeFrameShellPart * op = _XfeFrameShellPart(ow); WMShellPart * wm_np = _WMShellPart(nw); WMShellPart * wm_op = _WMShellPart(ow); /* has_been_mapped */ if (np->has_been_mapped != op->has_been_mapped) { np->has_been_mapped = op->has_been_mapped; _XfeWarning(nw,MESSAGE2); } /* track_editres */ if (np->track_editres != op->track_editres) { SetTrackEditres(nw,np->track_editres); } /* track_mapping */ if (np->track_mapping != op->track_mapping) { SetTrackMapping(nw,np->track_mapping); } /* track_save_yourself */ if (np->track_save_yourself != op->track_save_yourself) { SetTrackSaveYourself(nw,np->track_save_yourself); } /* track_delete_window */ if (np->track_delete_window != op->track_delete_window) { SetTrackDeleteWindow(nw,np->track_delete_window); } /* title */ if (wm_np->title != wm_op->title) { /* Invoke title changed Callbacks */ _XfeInvokeCallbacks(nw,np->title_changed_callback, XmCR_TITLE_CHANGED,NULL,False); } return False; } /*----------------------------------------------------------------------*/ static void GetValuesHook(Widget w,ArgList av,Cardinal * pac) { XfeFrameShellPart * fp = _XfeFrameShellPart(w); Cardinal i; for (i = 0; i < *pac; i++) { /* bypass_shell */ if (strcmp(av[i].name,XmNbypassShell) == 0) { *((XtArgVal *) av[i].value) = (XtArgVal) XfeFrameShellGetBypassShell(w); } } } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* Tracking update functions */ /* */ /*----------------------------------------------------------------------*/ static void SetTrackEditres(Widget w,Boolean state) { #ifdef EDITRES /* Remove any editres event handler that might have been added */ XtRemoveEventHandler(w,0,True,_XEditResCheckMessages,NULL); /* Add the editres event handler if needed */ if (state) { XtAddEventHandler(w,0,True,_XEditResCheckMessages,NULL); } #endif } /*----------------------------------------------------------------------*/ static void SetTrackMapping(Widget w,Boolean state) { /* Remove any mapping event handler that might have been added */ XtRemoveEventHandler(w,StructureNotifyMask,True,MappingEH,w); /* Add the mapping event handler if needed */ if (state) { XtAddEventHandler(w,StructureNotifyMask,True,MappingEH,w); } } /*----------------------------------------------------------------------*/ static void SetTrackDeleteWindow(Widget w,Boolean state) { static Atom WM_DELETE_WINDOW = None; /* Dont do nothing if the state is False and no Atom has been created */ if ((WM_DELETE_WINDOW == None) && !state) { return; } /* Create the Atom for the first time */ if (WM_DELETE_WINDOW == None) { WM_DELETE_WINDOW = XmInternAtom(XtDisplay(w),"WM_DELETE_WINDOW",False); XmAddWMProtocols(w,&WM_DELETE_WINDOW,1); } /* Remove any delete callback that might have been added */ XmRemoveWMProtocolCallback(w,WM_DELETE_WINDOW,DeleteWindowCB,w); /* Add the delete callback if needed */ if (state) { XmAddWMProtocolCallback(w,WM_DELETE_WINDOW,DeleteWindowCB,w); } } /*----------------------------------------------------------------------*/ static void SetTrackSaveYourself(Widget w,Boolean state) { static Atom WM_SAVE_YOURSELF = None; /* Dont do nothing if the state is False and no Atom has been created */ if ((WM_SAVE_YOURSELF == None) && !state) { return; } /* Create the Atom for the first time */ if (WM_SAVE_YOURSELF == None) { WM_SAVE_YOURSELF = XmInternAtom(XtDisplay(w),"WM_SAVE_YOURSELF",False); XmAddWMProtocols(w,&WM_SAVE_YOURSELF,1); } /* Remove any save yourself callback that might have been added */ XmRemoveWMProtocolCallback(w,WM_SAVE_YOURSELF,SaveYourselfCB,w); /* Add the save yourself callback if needed */ if (state) { XmAddWMProtocolCallback(w,WM_SAVE_YOURSELF,SaveYourselfCB,w); } } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* Window manager protocol callbacks */ /* */ /*----------------------------------------------------------------------*/ static void DeleteWindowCB(Widget shell,XtPointer client_data,XtPointer call_data) { Widget w = (Widget) client_data; XfeFrameShellPart * fp = _XfeFrameShellPart(w); /* XmVendorShellExtPart * vp = _XfeVendorShellPart(w); */ if (_XfeIsAlive(w) && fp->track_delete_window) { /* Invoke delete window callbacks */ _XfeInvokeCallbacks(w,fp->delete_window_callback, XmCR_DELETE_WINDOW,NULL,False); } } /*----------------------------------------------------------------------*/ static void SaveYourselfCB(Widget shell,XtPointer client_data,XtPointer call_data) { Widget w = (Widget) client_data; XfeFrameShellPart * fp = _XfeFrameShellPart(w); if (_XfeIsAlive(w) && fp->track_save_yourself) { /* Invoke save yourself callbacks */ _XfeInvokeCallbacks(w,fp->save_yourself_callback, XmCR_SAVE_YOURSELF,NULL,False); } } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* Shell structure event handler */ /* */ /*----------------------------------------------------------------------*/ static void MappingEH(Widget shell, XtPointer client_data, XEvent * event, Boolean * cont) { Widget w = (Widget) client_data; XfeFrameShellPart * fp = _XfeFrameShellPart(w); /* Make sure the shell is still alive */ if (_XfeIsAlive(w) && fp->track_mapping) { switch(event->type) { /* Map */ case MapNotify: if (XfeIsViewable(shell)) { /* Invoke first map callbacks */ if (!fp->has_been_mapped) { fp->has_been_mapped = True; _XfeInvokeCallbacks(w,fp->first_map_callback, XmCR_FIRST_MAP,NULL,False); } /* Invoke map callbacks */ else { _XfeInvokeCallbacks(w,fp->map_callback, XmCR_MAP,NULL,False); } } break; /* Unmap */ case UnmapNotify: /* Invoke unmap callbacks */ _XfeInvokeCallbacks(w,fp->unmap_callback, XmCR_UNMAP,NULL,False); break; } } *cont = True; } /*----------------------------------------------------------------------*/ static void StructureEH(Widget shell, XtPointer client_data, XEvent * event, Boolean * cont) { Widget w = (Widget) client_data; XfeFrameShellPart * fp = _XfeFrameShellPart(w); /* Make sure the shell is still alive */ if (!_XfeIsAlive(w)) { return; } switch(event->type) { case MapNotify: /* Invoke first map callbacks */ if (!fp->has_been_mapped) { fp->has_been_mapped = True; _XfeInvokeCallbacks(w,fp->first_map_callback, XmCR_FIRST_MAP,NULL,False); } /* Invoke map callbacks */ else { _XfeInvokeCallbacks(w,fp->map_callback, XmCR_MAP,NULL,False); } break; case UnmapNotify: /* Invoke unmap callbacks */ _XfeInvokeCallbacks(w,fp->unmap_callback, XmCR_UNMAP,NULL,False); break; } *cont = True; } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfeFrameShell Public Methods */ /* */ /*----------------------------------------------------------------------*/ /* extern */ Widget XfeCreateFrameShell(Widget pw,char * name,ArgList av,Cardinal ac) { return XtCreatePopupShell(name,xfeFrameShellWidgetClass,pw,av,ac); } /*----------------------------------------------------------------------*/ /* extern */ Widget XfeFrameShellGetBypassShell(Widget w) { XfeFrameShellPart * fp = _XfeFrameShellPart(w); Arg av[10]; Cardinal ac = 0; assert( XfeIsFrameShell(w) ); #if 0 assert( _XfeIsRealized(w) ); if (!_XfeIsRealized(w)) { return False; } #endif #if 1 /* * Make sure the frame shell is realized or else the colormap and visual * stuff below will fail. */ if (!_XfeIsRealized(w)) { XtRealizeWidget(w); } #endif /* Make sure a shared bypass shell does not already exist */ if (_XfeIsAlive(fp->bypass_shell)) { return fp->bypass_shell; } XtSetArg(av[ac],XmNcolormap, XfeColormap(w)); ac++; XtSetArg(av[ac],XmNvisual, XfeVisual(w)); ac++; XtSetArg(av[ac],XmNdepth, XfeDepth(w)); ac++; fp->bypass_shell = XfeCreateBypassShell(w,BYPASS_SHELL_NAME,av,ac); /* Make sure its realized */ XtRealizeWidget(fp->bypass_shell); return fp->bypass_shell; } /*----------------------------------------------------------------------*/