This is xmView.m in view mode; [Download] [Up]
/* WidgetSet category mplementation of View class for X/Motif * * Copyright (C) 1994, 1995 The Board of Trustees of * The Leland Stanford Junior University. All Rights Reserved. * * Authors: Scott Francis, Paul Kunz, Tom Pavel, * Imran Qureshi, and Libing Wang (SLAC) * Adam Fedor (U Colorado) * * This file is part of an Objective-C class library for X/Motif * * xmView.m,v 1.36 1995/12/13 22:33:31 fedor Exp */ #include "View.h" #include "xtResponder.h" /* Required for implementation: */ #include <objc/List.h> #include "appkit/Motif.h" #include "Application.h" #include "Window.h" #define String X11String #include <Xm/BulletinB.h> /* for xmScrolledWindowWidgetClass */ #include <Xm/DrawingA.h> #include <X11/StringDefs.h> /* For non-Motif resource names */ #undef String #include "dpsclient/XtGState.h" #include "dpsclient/XtDrawContext.h" #include "dpsclient/xwfriends.h" #include "dpsclient/psops.h" #include "dpsclient/CGTMatrix.h" char *ViewInstanceName(void) { return "View"; } /* The contentView of a Window has this callback enabled. If the window is NONRETAINED, we send a windowDidExpose to the window delegate (if it responds), otherwise we try to handle the expose event ourselves (i.e. if we're doing backing store). */ static void _window_did_expose_callback(Widget w, XtPointer client_data, XtPointer call_data) { View *viewid = (View *) client_data; XmDrawingAreaCallbackStruct *cb = (XmDrawingAreaCallbackStruct*)call_data; Window *windowid; NXEvent nxevent; XEvent *ev; if ( cb->reason != XmCR_EXPOSE ) { return; } ev = cb->event; if (ev->type != Expose) { return; } /* Until we can calculate the exposted rectangles correctly, * will drop all the expose events except last one and flush * the whole window -- Paul */ if ( ![viewid isLastExposeEvent:ev] ) { return; } [viewid makeNXEvent:&nxevent fromXEvent:ev]; windowid = [viewid window]; if ([windowid backingType] == NX_NONRETAINED ) [windowid windowExposed:&nxevent]; else if ([windowid windowNum]) [windowid perform:@selector(_windowExposed:) with:(void *)&nxevent]; return; } @interface View(WidgetSet) - _setFrame:(const NXRect *)aFrame; @end @implementation View(WidgetSet) - _moveTo:(NXCoord)x :(NXCoord)y { if ( widgetid ) { XtMoveWidget(widgetid, x, y ); } return self; } - _setAdjustedFrame:(const NXRect *)aFrame { /* This method sets the position of the view in the X-Window * coordinate system. It should overriden by subclasses whenever * they need to adjust the size due to their contents */ [self _setArg:XmNx to:aFrame->origin.x]; [self _setArg:XmNy to:aFrame->origin.y]; [self _setArg:XmNwidth to:aFrame->size.width]; [self _setArg:XmNheight to:aFrame->size.height]; return self; } - _sizeTo:(const NXCoord)width :(const NXCoord)height { [self _setArg:XmNwidth to:width]; [self _setArg:XmNheight to:height]; return self; } - _init { /* This method is invoked from from the -initFrame and -awake * methods. Subclasses of View may override this method to * add to their initialization. In particular, any subclass * that doesn't want a xmDrawingArea widget must override this * method. */ classname = xmDrawingAreaWidgetClass; [self _setFrame:&frame]; [self _addArg:XmNallowOverlap:True]; [self _addArg:XmNnoResize:True]; [self _addArg:XmNresizePolicy :XmRESIZE_NONE]; [self _addArg:XmNmarginWidth :0]; [self _addArg:XmNmarginHeight :0]; /* [self _setArg:XmNforeground to:xtGrayToPixel((XMotifContext)[NXApp context], 0.0)]; [self _setArg:XmNbackground to:xtGrayToPixel((XMotifContext)[NXApp context], 0.6666)]; */ return self; } - _setAsBulletinBoard { /* This change of class name is used by Box contentView and * by the ScrollView subclass. */ classname = xmBulletinBoardWidgetClass; return self; } - _getFrame { [self _getArg:XmNx into:(XtArgVal *)&frame.origin.x]; [self _getArg:XmNy into:(XtArgVal *)&frame.origin.y]; [self _getArg:XmNwidth into:(XtArgVal *)&frame.size.width]; [self _getArg:XmNheight into:(XtArgVal *)&frame.size.height]; if ( superview ) { NXRect rect; [superview getFrame:&rect]; frame.origin.y = rect.size.height - frame.origin.y - frame.size.height; } return self; } - _addCallback { if ( !superview && window ) { XtAddCallback(widgetid, XmNexposeCallback, _window_did_expose_callback, self); } return self; } - _managedBy:parent wid:(void*)widget { if (!classname) fprintf(stderr, "%s: classname unknown\n", [self name]); if (widgetid) { XtManageChild(widgetid); } else { widgetid = XtCreateManagedWidget(instancename, classname, widget, [self _arglist], [self _numargs]); [self _addCallback]; } [self _setnumargs:0]; if ( subviews ) { [self _manageChildren]; } return self; } - _unManage { if ( widgetid ) { XtUnmanageChild(widgetid); } return self; } - _destroy { if ( widgetid ) { XtDestroyWidget(widgetid); } widgetid = NULL; if (nil != subviews) [subviews makeObjectsPerform:@selector(_destroy)]; return self; } /* Routines to handle gstates. We need to create a gstate for every view in X-Windows, because every view draws under a different widget. However, a separate X11 Graphic Context (GC) is not created for every view unless one is specifically asked for via the allocGState method. Otherwise, the X11 GC is just a pointer to the superview's GC. This causes changes to the X11 GC to propogate up the chain. */ - _keepGState: (int)gst { _gstate = gst; _vFlags.wantsGState = NO; vFlags.validGState = YES; return self; } - _displayFreeGState { return self; } - _displayPreLockFocus { return self; } /* Update the current gstate to reflect our new information */ - _displayLockFocus { // Install our own gstate if we have one, otherwise create one if (vFlags.validGState) { PSsetgstate(_gstate); } else { if (superview == nil || _vFlags.wantsGState) { PSgstateview(self); PSgetint(&_gstate); PSwindowdeviceview([window windowNum], self); [self _keepGState:_gstate]; if (_vFlags.notifyToInitGState == YES) [self initGState]; } else PSgsaveview(self); /* Update the coordinate system. Need to translate to our view frame only if we are drawing to backing store. */ if ([window backingType] != NX_NONRETAINED) PStranslate(NX_X(&frame), NX_Y(&frame)); NXRectClip(&bounds); if (_frameMatrix) PSconcat(cgtToMatrix([_frameMatrix currentMatrix])); if (_drawMatrix) PSconcat(cgtToMatrix([_drawMatrix currentMatrix])); } return self; } - _displayUnlockFocus { PSgrestore(); return self; } - _flushView { /* Because only Views with custom drawing draw to the backing store, * we need this method to flush the backing store to the widget's * window. When all drawing is done to the backing store, this * method will obsolete. -- Paul Kunz */ XtGState *gstate; if (vFlags.validGState) { PSgstateobject(_gstate, (void **)&gstate); if ( gstate && [gstate didDraw] ) { [self lockFocus]; [self setNeedsDisplay:YES]; [self unlockFocus]; } } [subviews makeObjectsPerform:@selector(_flushView)]; return self; } /* these last three methods set x resources, and should be methods only known to the category extension. Box makes use of all of these methods in its content view. */ - _setResize:(void *)policy { [self _setArg:XmNresizePolicy to:(XtArgVal)policy]; return self; } - _setOffsets:(NXSize *)offsets { [self _setArg:XmNmarginWidth to:offsets->width]; [self _setArg:XmNmarginHeight to:offsets->height]; return self; } - _setBorderShadow:(void *)shadow andThickness:(void *)thickness { [self _setArg:XmNshadowType to:(XtArgVal)shadow]; [self _setArg:XmNshadowThickness to:(XtArgVal)thickness]; return self; } - _setFrame:(const NXRect *)aFrame { NXRect xframe = *aFrame; if ( superview ) { NXRect rect; [superview getFrame:&rect]; xframe.origin.y = rect.size.height - aFrame->origin.y - aFrame->size.height; } [self _setAdjustedFrame:&xframe]; return self; } - _setNeedsDisplay:(BOOL)flag { XtGState *gstate; if (vFlags.validGState) { PSgstateobject(_gstate, (void **)&gstate); [gstate setNeedsDisplay:flag]; } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.