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.