File: [Development] / inventor / apps / examples / Toolmaker / 11.Events / DialNButton.c++ (download)
Revision 1.3, Sun Oct 29 15:04:16 2000 UTC (17 years ago) by jlim
Branch: MAIN
CVS Tags: release-2_1_5-9, release-2_1_5-8, release-2_1_5-10, HEAD Changes since 1.2: +2 -1
lines
Eliminated or reduced compiler errors and warnings, as tested with
egcs-2.91.66 (on Red Hat 6.0) and gcc 2.96 (on Red Hat 6.2).
|
/*
*
* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
*
*/
/*-------------------------------------------------------------
* This is an example from The Inventor Toolmaker,
* chapter 11.
*
* This is the source file for the "DialNButton" device.
*------------------------------------------------------------*/
#include <X11/Xlib.h>
#include <X11/extensions/XI.h>
#include <Inventor/SbTime.h>
#include <Inventor/Xt/SoXt.h>
#include <Inventor/events/SoButtonEvent.h>
#include "ButtonBoxEvent.h"
#include "DialEvent.h"
#include "DialNButton.h"
extern "C" {
XDeviceInfo *XListInputDevices(Display *, int *);
XDevice *XOpenDevice(Display *, XID);
int XSelectExtensionEvent(Display *, Window, XEventClass *, int);
}
#define DEVICE_NAME "dial+buttons"
// There are 3 event classes for this device:
// motion, button down, button up
static const int numEventClasses = 3;
// static members
SbBool DialNButton::firstTime = TRUE;
int DialNButton::motionEventType;
int DialNButton::buttonPressEventType;
int DialNButton::buttonReleaseEventType;
XEventClass DialNButton::eventClasses[3];
int DialNButton::eventTypes[3];
XDevice *DialNButton::device;
////////////////////////////////////////////////////////////////////////
//
// Description:
// Initialize the dial+button device. We only need to do this once.
//
// public
//
void
DialNButton::init(Display *display)
//
////////////////////////////////////////////////////////////////////////
{
// If already initialized, return.
if (! firstTime) return;
firstTime = FALSE;
// get the list of input devices that are attached to the display now
XDeviceInfoPtr list;
int numDevices;
list = (XDeviceInfoPtr) XListInputDevices(display, &numDevices);
// now run through the list looking for the device
device = NULL;
for (int i = 0; (i < numDevices) && (device == NULL); i++) {
// Open the device - the device id is set at runtime.
if (strcmp(list[i].name, DEVICE_NAME) == 0) {
device = XOpenDevice(display, list[i].id);
}
}
// make sure we found the device
if (device == NULL) {
fprintf(stderr, "DialNButton::init",
"Sorry there is no dial and button attached to this display");
return;
}
// Query the event types and classes
uint32_t eventClass;
DeviceMotionNotify(device, motionEventType, eventClass);
eventClasses[0] = eventClass;
eventTypes[0] = motionEventType;
DeviceButtonPress(device, buttonPressEventType, eventClass);
eventClasses[1] = eventClass;
eventTypes[1] = buttonPressEventType;
DeviceButtonRelease(device, buttonReleaseEventType, eventClass);
eventClasses[2] = eventClass;
eventTypes[2] = buttonReleaseEventType;
// Init all dial values to 0
static int vals[8] = {0, 0, 0, 0, 0, 0, 0, 0};
XSetDeviceValuators(display, device, vals, 0, 8);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Constructor using default display.
//
// public
//
DialNButton::DialNButton()
//
////////////////////////////////////////////////////////////////////////
{
init(SoXt::getDisplay());
buttonEvent = new ButtonBoxEvent;
dialEvent = new DialEvent;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Constructor.
//
// public
//
DialNButton::DialNButton(Display *d)
//
////////////////////////////////////////////////////////////////////////
{
init(d);
buttonEvent = new ButtonBoxEvent;
dialEvent = new DialEvent;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Destructor.
//
// public
//
DialNButton::~DialNButton()
//
////////////////////////////////////////////////////////////////////////
{
delete buttonEvent;
delete dialEvent;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// returns whether the dial+button device exists for use or not.
//
// static, public
//
SbBool
DialNButton::exists(Display *display)
//
////////////////////////////////////////////////////////////////////////
{
// get the list of input devices that are attached to the display now
XDeviceInfoPtr list;
int numDevices;
list = (XDeviceInfoPtr) XListInputDevices(display, &numDevices);
// now run through the list looking for the device
int i;
for (i = 0; (i < numDevices) &&
(strcmp(list[i].name, DEVICE_NAME) != 0); i++)
; // keep looping
// if we broke out of the loop before i reached numDevices,
// then the does in fact exist.
return (i < numDevices);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// This selects input for dial+button device events which occur in w.
// The callback routine is proc, and the callback data is clientData.
//
// virtual public
//
void
DialNButton::enable(
Widget w,
XtEventHandler proc,
XtPointer clientData,
Window window)
//
////////////////////////////////////////////////////////////////////////
{
if (numEventClasses == 0) return;
Display *display = XtDisplay(w);
if (display == NULL) {
fprintf(stderr, "DialNButton::enable",
"SoXt::init not properly called (Display is NULL).");
return;
}
if (w == NULL) {
fprintf(stderr, "DialNButton::enable",
"widget is NULL.");
return;
}
if (window == (Window) NULL) {
fprintf(stderr, "DialNButton::enable",
"widget must be realized (Window is NULL).");
return;
}
// select extension events for the dial+button which the user wants
XSelectExtensionEvent(display, window,
eventClasses, numEventClasses);
// tell Inventor about these extension events!
for (int i = 0; i < numEventClasses; i++)
SoXt::addExtensionEventHandler(
w, eventTypes[i], proc, clientData);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// This unselects input for dial+button device events which occur in w,
// i.e. dial+button events will no longer be recognized.
//
// virtual public
//
void
DialNButton::disable(
Widget w,
XtEventHandler proc,
XtPointer clientData)
//
////////////////////////////////////////////////////////////////////////
{
// tell Inventor to forget about these classes
for (int i = 0; i < numEventClasses; i++)
SoXt::removeExtensionEventHandler(
w, eventTypes[i], proc, clientData);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Translate X events into Inventor events.
//
// virtual public
//
const SoEvent *
DialNButton::translateEvent(XAnyEvent *xevent)
//
////////////////////////////////////////////////////////////////////////
{
SoEvent *event = NULL;
// see if this is a dial+button event
if (xevent->type == motionEventType) {
XDeviceMotionEvent *me = (XDeviceMotionEvent *) xevent;
if (me->deviceid == device->device_id)
event = translateMotionEvent(me);
}
else if (xevent->type == buttonPressEventType) {
XDeviceButtonEvent *be = (XDeviceButtonEvent *) xevent;
if (be->deviceid == device->device_id)
event = translateButtonEvent(be, SoButtonEvent::DOWN);
}
else if (xevent->type == buttonReleaseEventType) {
XDeviceButtonEvent *be = (XDeviceButtonEvent *) xevent;
if (be->deviceid == device->device_id)
event = translateButtonEvent(be, SoButtonEvent::UP);
}
return event;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// This returns a DialEvent for the passed X event.
//
// private
//
DialEvent *
DialNButton::translateMotionEvent(XDeviceMotionEvent *me)
//
////////////////////////////////////////////////////////////////////////
{
setEventPosition(dialEvent, me->x, me->y);
dialEvent->setTime(SbTime(0, 1000*me->time));
dialEvent->setShiftDown(me->state & ShiftMask);
dialEvent->setCtrlDown(me->state & ControlMask);
dialEvent->setAltDown(me->state & Mod1Mask);
// the dial that turned is stored as first_axis in the X event.
// the value is always in axis_data[0].
dialEvent->setDial(me->first_axis);
dialEvent->setValue(me->axis_data[0]);
return dialEvent;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// This returns a ButtonBoxEvent for the passed X event.
//
// private
//
ButtonBoxEvent *
DialNButton::translateButtonEvent(
XDeviceButtonEvent *be,
SoButtonEvent::State whichState)
//
////////////////////////////////////////////////////////////////////////
{
setEventPosition(buttonEvent, be->x, be->y);
buttonEvent->setTime(SbTime(0, 1000*be->time));
buttonEvent->setShiftDown(be->state & ShiftMask);
buttonEvent->setCtrlDown(be->state & ControlMask);
buttonEvent->setAltDown(be->state & Mod1Mask);
// set which button along with its state.
buttonEvent->setButton(be->button);
buttonEvent->setState(whichState);
return buttonEvent;
}