X11InputExtensionTest.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, January 9, 1992
Christian Jacobi, March 27, 1992 10:40 am PST
This is a test. This is a test. This is a test only.
Tests multiple pens.
DIRECTORY
Commander,
Imager,
Rope,
Xl,
XlInputExtension,
XTk,
XTkBitmapWidgets,
XTkWidgets;
X11InputExtensionTest: CEDAR MONITOR
LOCKS i USING i: Instance
IMPORTS Commander, Imager, Rope, Xl, XlInputExtension, XTk, XTkBitmapWidgets, XTkWidgets =
BEGIN
Widget: TYPE = XTkWidgets.Widget;
Instance: TYPE = REF InstanceRec;
InstanceRec: TYPE = MONITORED RECORD [
shell: Widget ¬ NIL,
bitmap: Widget ¬ NIL,
context: Imager.Context ¬ NIL,
deviceInfos: LIST OF XlInputExtension.DeviceInfo ¬ NIL
];
PenState: TYPE = RECORD [
i: Instance,
beginValid: BOOL ¬ FALSE,
beginPos: Xl.Point ¬ [0, 0]
];
debugLastInstance: Instance;
CreateInstance: Commander.CommandProc = {
i: Instance ¬ debugLastInstance ¬ NEW[InstanceRec];
shell: Widget ¬ i.shell ¬ XTkWidgets.CreateShell[
className: $X11InputExtensionTest, windowHeader: "X11InputExtensionTest",
standardMigration: TRUE
];
bitmap: Widget ¬ i.bitmap ¬ XTkBitmapWidgets.CreateBitmapWidget[
widgetSpec: [geometry: [size: [150, 400], borderWidth: 1]],
notify: BitmapChanged, data: i
];
XTk.RegisterNotifier[bitmap, XTk.postWindowCreationKey, PostWindowCreation, i];
XTkWidgets.SetShellChild[shell, bitmap];
XTkWidgets.RealizeShell[shell];
};
penDeviceType: Rope.ROPE ¬ "TABLET";
PostWindowCreation: XTk.WidgetNotifyProc = {
--register events explicitely only now because we should figure out availability of extension events first. Handle core event the same way for documentation reason.
i: Instance ¬ NARROW[registerData];
BEGIN --Set up base event
p: REF PenState ¬ NEW[PenState ¬ [i: i]];
XTk.AddTemporaryMatch[widget,
[proc: EventReceived, handles: Xl.CreateEventFilter[motionNotify, buttonRelease, buttonPress], tq: NIL, data: p],
[pointerMotion: TRUE, buttonRelease: TRUE, buttonPress: TRUE]
];
END;
BEGIN --Set up extension events...
i.deviceInfos ¬ XlInputExtension.ListInputDevices[widget.connection];
FOR list: LIST OF XlInputExtension.DeviceInfo ¬ i.deviceInfos, list.rest WHILE list#NIL DO
type: Rope.ROPE ¬ Xl.GetAtomName[widget.connection, list.first.type];
IF Rope.Equal[type, penDeviceType] THEN {
d: REF XlInputExtension.OpenDeviceRec ¬ XlInputExtension.OpenDevice[widget.connection, list.first.id];
IF d#NIL THEN {
interest: LIST OF XlInputExtension.EventClass ¬
LIST[
XlInputExtension.MakeEventClass[d, deviceButtonRelease],
XlInputExtension.MakeEventClass[d, deviceButtonPress],
XlInputExtension.MakeEventClass[d, deviceMotionNotify]
];
p: REF PenState ¬ NEW[PenState ¬ [i: i]];
XTk.AddTemporaryMatch[widget,
[proc: EventReceived, handles: Xl.FullCreateEventFilter[extensions: LIST[XlInputExtension.deviceButtonPressKey, XlInputExtension.deviceButtonReleaseKey, XlInputExtension.deviceMotionNotifyKey]], tq: NIL, data: p]
];
XlInputExtension.SelectExtensionEvents[c: widget.connection, window: widget.window, interest: interest];
};
};
ENDLOOP;
END;
};
Move: ENTRY PROC [i: Instance, p: REF PenState, down: BOOL, pos: Xl.Point] = {
SELECT TRUE FROM
down AND ~p.beginValid => {
p.beginValid ¬ TRUE
};
down AND p.beginValid => {
Line[p, p.beginPos, pos];
};
~down AND p.beginValid => {
Line[p, p.beginPos, pos];
p.beginValid ¬ FALSE;
};
~down AND ~p.beginValid => {
};
ENDCASE => {};
p.beginPos ¬ pos
};
Line: PROC [p: REF PenState, pos1, pos2: Xl.Point] = {
h: INT ¬ p.i.bitmap.actual.size.height;
context: Imager.Context ¬ p.i.context;
IF context#NIL THEN
Imager.MaskVector[context, [pos1.x, h-pos1.y], [pos2.x, h-pos2.y]];
};
BitmapChanged: XTkBitmapWidgets.BitmapEventProc = {
NewBitmap: ENTRY PROC [i: Instance, widget: XTk.Widget] = {
context: Imager.Context;
XTkBitmapWidgets.CreateAndSetBitmap[widget: widget, size: [widget.actual.size.height, widget.actual.size.width], bpp: 1];
context ¬ XTkBitmapWidgets.CreateContext[widget];
Imager.SetColor[context, Imager.white];
Imager.MaskRectangleI[context: context, x: -1000, y: -1000, w: 4000, h: 4000];
Imager.SetStrokeWidth[context,1];
Imager.SetStrokeEnd[context, round];
Imager.SetStrokeJoint[context, round];
Imager.SetColor[context, Imager.black];
i.context ¬ context;
};
SELECT reason FROM
createWindow, resize, map => {
NewBitmap[NARROW[data], widget];
};
ENDCASE => {}
};
EventReceived: Xl.EventProcType = {
p: REF PenState ~ NARROW[clientData];
SELECT event.type FROM
Xl.EventCode.motionNotify => {
e: Xl.MotionNotifyEvent ~ NARROW[event];
Move[p.i, p, e.state.button1 OR e.state.button2 OR e.state.button3, e.pos];
};
Xl.EventCode.buttonRelease => {
e: Xl.ButtonReleaseEvent ~ NARROW[event];
Move[p.i, p, FALSE, e.pos];
};
Xl.EventCode.buttonPress => {
e: Xl.ButtonPressEvent ~ NARROW[event];
Move[p.i, p, TRUE, e.pos];
};
Xl.EventCode.extension => {
e: Xl.ExtensionEvent ~ NARROW[event];
WITH e.decoded SELECT FROM
x: XlInputExtension.DeviceBaseEvent => {
pos: Xl.Point ¬ x.eventPos;
IF x.valuators=NIL OR x.valuators.leng<2 THEN RETURN;
pos.x ¬ x.valuators[0];
pos.y ¬ x.valuators[1];
SELECT x.eventOffset FROM
deviceButtonPress => {
Move[p.i, p, TRUE, pos];
};
deviceButtonRelease => {
Move[p.i, p, FALSE, pos];
};
deviceMotionNotify => {
Move[p.i, p, x.state.button1 OR x.state.button2 OR x.state.button3, pos];
};
ENDCASE => {}
};
ENDCASE => {}
};
ENDCASE => {};
};
Commander.Register["X11InputExtensionTest", CreateInstance, "Create test widget to debug X input extension with multiple pens"];
END.