XTkBitmapWidgetsImpl.mesa
Copyright Ó 1988, 1989, 1990, 1991, 1992 by Xerox Corporation. All rights reserved.
Christian Jacobi, October 21, 1988 1:13:59 pm PDT
Christian Jacobi, April 28, 1992 5:02 pm PDT
DIRECTORY
Imager,
ImagerSample,
IO,
SF,
Xl,
XlColorMapAccess,
XlBitmap,
XlBitmapWindow,
XTk,
XTkFriends,
XTkBitmapWidgets,
XTkShellWidgets;
XTkBitmapWidgetsImpl: CEDAR MONITOR
LOCKS bmRef USING bmRef: REF BMRec
IMPORTS ImagerSample, SF, XlBitmapWindow, XlColorMapAccess, Xl, XlBitmap, XTk, XTkFriends, XTkShellWidgets
EXPORTS XTkBitmapWidgets =
BEGIN OPEN Xl, XTk, XTkBitmapWidgets;
bmClass: ImplementorClass ¬ XTkFriends.CreateClass[[
key: $bitmapWidget, wDataNum: 1,
configureLR: BMConfigureLR,
destroyWindowLR: BMDestroyWindowLR,
preStopFastAccess: BMPreStopFastAccess,
fullStopFastAccessLR: BMFullStopFastAccessLR,
destroyWidget: BMDestroyWidget,
initInstPart: InitInstPart,
eventMask: [exposure: TRUE, structureNotify: TRUE],
backgroundKey: $white
]];
BMRec: TYPE = MONITORED RECORD [
handle: XlBitmapWindow.Handle ¬ NIL,
bm: XlBitmap.Bitmap ¬ NIL,
origin: Xl.Point ¬ [0, 0],
restrict: SF.Box ¬ SF.maxBox,
notify: BitmapEventProc,
data: REF ¬ NIL,
ownedBitmap: XlBitmap.Bitmap ¬ NIL
];
GetInstData: PROC [w: Widget] RETURNS [REF BMRec] = INLINE {
RETURN [NARROW[XTkFriends.InstPart[w, bmClass]]];
};
mapEvents: Xl.EventFilter = Xl.CreateEventFilter[unmapNotify, mapNotify];
NotifyMapChange: Xl.EventProcType = {
widget: Widget = NARROW[clientData];
bmRef: REF BMRec ~ GetInstData[widget];
IF bmRef.notify#NIL THEN {
SELECT event.type FROM
mapNotify => bmRef.notify[widget, map, bmRef.data];
unmapNotify => bmRef.notify[widget, unmap, bmRef.data];
ENDCASE => {};
};
};
BMDestroyWindowLR: TerminateProc = {
bmRef: REF BMRec ~ GetInstData[widget];
IF bmRef.notify#NIL THEN bmRef.notify[widget, destroyWindow, bmRef.data];
XTkFriends.SimpleDestroyWindowLR[widget, reason];
};
dummyBitmap: XlBitmap.Bitmap ¬ XlBitmap.Create[[s: 1, f: 32], 1, FALSE]; -- Used to uinstall other bitmaps
BMConfigureLR: ConfigureProc = {
bmRef: REF BMRec ~ GetInstData[widget];
existW, createW: BOOL;
reason: BitmapEventReason ¬ resize;
existW ¬ widget.actualMapping<unconfigured;
createW ¬ mapping<unconfigured AND ~existW;
IF createW THEN {
XTk.AddTemporaryMatch[widget, [NotifyMapChange, mapEvents, widget.rootTQ, widget], [exposure: TRUE]];
};
XTkFriends.SimpleConfigureOneLevelLR[widget, geometry, mapping];
IF existW OR createW THEN {
IF createW AND bmRef.ownedBitmap#NIL THEN InitColormap[widget, bmRef.ownedBitmap];
SetBM[bmRef, widget, FALSE, TRUE];
IF createW THEN {
XlBitmapWindow.SetWindow[handle: bmRef.handle, c: widget.connection, w: widget.window, immediateRefresh: FALSE];
reason ¬ createWindow;
};
IF bmRef.notify#NIL THEN bmRef.notify[widget, reason, bmRef.data];
};
};
BMPreStopFastAccess: TerminateProc = {
bmRef: REF BMRec ~ GetInstData[widget];
XlBitmapWindow.SetNoWindow[bmRef.handle];
};
BMFullStopFastAccessLR: FullStopFastAccessProc = {
bmRef: REF BMRec ~ GetInstData[widget];
XlBitmapWindow.SetNoWindow[bmRef.handle];
XlBitmapWindow.Wait[bmRef.handle, TRUE];
IF bmRef.notify#NIL THEN bmRef.notify[widget, destroyWindow, bmRef.data];
};
BMDestroyWidget: WidgetProc = {
bmRef: REF BMRec ~ GetInstData[widget];
XlBitmapWindow.DestroyHandle[handle: bmRef.handle];
};
NullNotify: BitmapEventProc = {};
InitInstPart: InitInstancePartProc = {
XTkFriends.AssignInstPart[widget, bmClass, NEW[BMRec ¬ [notify: NullNotify, handle: XlBitmapWindow.CreateHandle[]]]];
XTk.SetWidgetFlag[widget, XTk.preferredSizeCurrent, TRUE];
};
DontNotify: BitmapEventProc = {};
SetCallbacks: PUBLIC PROC [bmw: BitmapWidget, notify: BitmapEventProc ¬ NIL, data: REF ¬ NIL] = {
bmRef: REF BMRec ~ GetInstData[bmw];
IF notify=NIL THEN notify ¬ DontNotify;
bmRef.notify ¬ notify;
bmRef.data ¬ data;
};
varyingFlag: XTk.WidgetFlagKey ~ wf6;
CreateBitmapWidget: PUBLIC PROC [widgetSpec: WidgetSpec, notify: BitmapEventProc, data: REF] RETURNS [widget: Widget] = {
widget ¬ XTk.CreateWidget[widgetSpec, bmClass];
XTk.SetWidgetFlag[widget, varyingFlag];
SetCallbacks[widget, notify, data];
};
SetBitmap: PUBLIC PROC [widget: BitmapWidget, bitmap: XlBitmap.Bitmap, restrict: SF.Box ¬ SF.maxBox, origin: Xl.Point ¬ [0, 0], immediateRefresh: BOOL ¬ TRUE, retainRefreshs: BOOL ¬ FALSE] = {
bmRef: REF BMRec ~ GetInstData[widget];
bmRef.bm ¬ bitmap;
bmRef.restrict ¬ SF.Intersect[restrict, XlBitmap.GetBox[bitmap]];
bmRef.origin ¬ origin;
IF widget.state=realized THEN
SetBM[bmRef, widget, immediateRefresh, retainRefreshs];
};
GetBitmap: PUBLIC PROC [widget: BitmapWidget] RETURNS [bitmap: XlBitmap.Bitmap, restrict: SF.Box, origin: Xl.Point] = {
bmRef: REF BMRec ~ GetInstData[widget];
bitmap ¬ bmRef.bm;
restrict ¬ bmRef.restrict;
origin ¬ bmRef.origin;
};
SetBM: PROC [bmRef: REF BMRec, widget: BitmapWidget, immediateRefresh: BOOL, retainRefreshs: BOOL] = {
Range: PROC [x: INT] RETURNS [INTEGER] = {
RETURN[ MIN[ MAX[x, FIRST[INTEGER]], LAST[INTEGER] ] ]
};
bm: XlBitmap.Bitmap ¬ bmRef.bm;
IF bm#NIL THEN {
origin: Xl.Point ¬ bmRef.origin;
clip: SF.Box ¬ [
min: [s: Range[-origin.y], f: Range[-origin.x]],
max: [s: Range[widget.actual.size.height-origin.y], f: Range[widget.actual.size.width-origin.x]]
];
restrict: SF.Box ¬ SF.Intersect[bmRef.restrict, clip];
bpp: NAT ¬ ImagerSample.GetBitsPerSample[XlBitmap.GetSM[bm]];
IF bpp>1 THEN {
IF widget.screenDepth=NIL OR XlColorMapAccess.Find8BitPseudoColorVisualType[widget.screenDepth.screen]=NIL THEN {
--make sure we never use an old bitmap with incopatible bits per pixel producing match errors
XlBitmapWindow.SetBitmap[handle: bmRef.handle, bitmap: dummyBitmap, immediateRefresh: FALSE];
RETURN; 
};
};
XlBitmapWindow.SetBitmap[handle: bmRef.handle, bitmap: bmRef.bm, restrict: restrict, origin: origin, immediateRefresh: immediateRefresh, retainRefreshs: retainRefreshs];
};
};
GetImplData: PUBLIC PROC [widget: BitmapWidget] RETURNS [REF] = {
bmRef: REF BMRec ~ GetInstData[widget];
RETURN [bmRef.handle];
};
Wait: PUBLIC PROC [widget: BitmapWidget, server: BOOL ¬ FALSE] = {
bmRef: REF BMRec ~ GetInstData[widget];
XlBitmapWindow.Wait[bmRef.handle, server];
};
CreateContext: PUBLIC PROC [widget: BitmapWidget, surfaceUnitsPerPixel: NAT ¬ 1] RETURNS [context: Imager.Context] = {
bmRef: REF BMRec ~ GetInstData[widget];
context ¬ XlBitmap.CreateContext[bmRef.bm, surfaceUnitsPerPixel];
};
CreateAndSetBitmap: PUBLIC PROC [widget: BitmapWidget, size: SF.Vec, bpp: NAT ¬ 1, origin: Xl.Point ¬ [0, 0]] = {
bmRef: REF BMRec ~ GetInstData[widget];
bm: XlBitmap.Bitmap;
IF bpp=0 THEN {
IF widget.screenDepth#NIL AND XlColorMapAccess.Find8BitPseudoColorVisualType[widget.screenDepth.screen]#NIL
THEN bpp ¬ 8
ELSE bpp ¬ 1;
};
bm ¬ XlBitmap.Create[size, bpp];
SetBitmap[widget: widget, bitmap: bm, origin: origin];
IF widget.screenDepth#NIL
THEN InitColormap[widget, bm]
ELSE bmRef.ownedBitmap ¬ bm
};
InitColormap: PROC [widget: XTk.Widget, bitmap: XlBitmap.Bitmap] = {
IF bitmap#NIL THEN {
cd: XlColorMapAccess.ColorData ¬ XlColorMapAccess.Access[widget.screenDepth.screen];
IF cd#NIL AND cd.hasColors THEN {
XlBitmap.SetColormap[bitmap, cd.entries];
IF cd.hasPrivateColormap AND widget.attributes.colorMap#cd.colormap THEN {
attributes: Xl.Attributes ¬ [];
widget.attributes.colorMap ¬ attributes.colorMap ¬ cd.colormap;
XlBitmap.SetColormap[bitmap, cd.entries];
XTkShellWidgets.TrackColorMap[shell: NIL, w: widget];
Xl.ChangeWindowAttributes[widget.connection, widget.window, attributes];
};
};
};
};
END.