home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1999 mARCH
/
PCWK3A99.iso
/
Linux
/
DDD331
/
DDD-3_1_.000
/
DDD-3_1_
/
ddd-3.1.1
/
ddd
/
Delay.C
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-06
|
8KB
|
309 lines
// $Id: Delay.C,v 1.24 1998/04/06 12:45:02 zeller Exp $ -*- C++ -*-
// Delay class -- displays an hourglass cursor until destroyed
// Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
// Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
//
// This file is part of DDD.
//
// DDD is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// DDD 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with DDD -- see the file COPYING.
// If not, write to the Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// DDD is the data display debugger.
// For details, see the DDD World-Wide-Web page,
// `http://www.cs.tu-bs.de/softech/ddd/',
// or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
char Delay_rcsid[] =
"$Id: Delay.C,v 1.24 1998/04/06 12:45:02 zeller Exp $";
#ifdef __GNUG__
#pragma implementation
#pragma implementation "DynArray.h"
#pragma implementation "VarArray.h"
#endif
#define LOG_DELAY 0
#include "Delay.h"
#include "assert.h"
#include "longName.h"
#include "HelpCB.h"
#include <X11/cursorfont.h>
#include <X11/StringDefs.h>
// ANSI C++ doesn't like the XtIsRealized() macro
#ifdef XtIsRealized
#undef XtIsRealized
#endif
DEFINE_TYPE_INFO_0(_Delay);
DEFINE_TYPE_INFO_0(Delay);
#define SMALL_HOURGLASS_CURSOR 1
#if SMALL_HOURGLASS_CURSOR || LARGE_HOURGLASS_CURSOR
#include "icons/cursors/time16.xbm"
#include "icons/cursors/time16m.xbm"
#if time16_width != time16m_width || time16_height != time16m_height
#error Bad mask for time16
#endif
#endif
#if LARGE_HOURGLASS_CURSOR
#include "icons/cursors/time32.xbm"
#include "icons/cursors/time32m.xbm"
#if time32_width != time32m_width || time32_height != time32m_height
#error Bad mask for time32
#endif
#endif
void (*Delay::shell_registered)(Widget w) = 0;
Cursor _Delay::hourglass_cache = 0;
Cursor _Delay::current_cursor = 0;
Cursor _Delay::hourglass_cursor()
{
if (hourglass_cache != 0)
return hourglass_cache;
Display *display = XtDisplay(widget);
#if SMALL_HOURGLASS_CURSOR || LARGE_HORGLASS_CURSOR
Screen *screen = XtScreen(widget);
Window rootWindow = RootWindowOfScreen(screen);
unsigned char *cursor_bits = time16_bits;
unsigned char *cursor_mask_bits = time16m_bits;
unsigned int cursor_width = time16_width;
unsigned int cursor_height = time16_height;
unsigned int cursor_x_hot = time16_x_hot;
unsigned int cursor_y_hot = time16_y_hot;
#if LARGE_HOURGLASS_CURSOR
// Fetch cursor shape
unsigned int width, height;
XQueryBestCursor(display, rootWindow, 32, 32, &width, &height);
Boolean largeCursors = (width >= 32 && height >= 32);
if (largeCursors)
{
cursor_bits = time32_bits;
cursor_mask_bits = time32m_bits;
cursor_width = time32_width;
cursor_height = time32_height;
cursor_x_hot = time32_x_hot;
cursor_y_hot = time32_y_hot;
}
#endif
Pixmap cursor_pixmap =
XCreateBitmapFromData(display, rootWindow, (char *)cursor_bits,
cursor_width, cursor_height);
Pixmap cursor_mask_pixmap =
XCreateBitmapFromData(display, rootWindow, (char *)cursor_mask_bits,
cursor_width, cursor_height);
XColor cursor_colors[2];
cursor_colors[0].pixel = BlackPixelOfScreen(screen);
cursor_colors[1].pixel = WhitePixelOfScreen(screen);
XQueryColors(display, DefaultColormapOfScreen(screen),
cursor_colors, 2);
hourglass_cache =
XCreatePixmapCursor(display, cursor_pixmap, cursor_mask_pixmap,
cursor_colors, cursor_colors + 1,
cursor_x_hot, cursor_y_hot);
#else // Watch cursor
hourglass_cache =
XCreateFontCursor(display, XC_watch);
#endif
return hourglass_cache;
}
_Delay::_Delay(Widget w):
widget(w), old_cursor(0)
{
if (widget == 0)
return;
#if LOG_DELAY
clog << "Setting " << XtName(widget) << " delay cursor\n";
#endif
Display *display = XtDisplay(widget);
if (current_cursor == 0)
{
// XC_left_ptr is the default cursor in OSF/Motif.
// (How do we determine the current cursor? - FIXME)
current_cursor = XCreateFontCursor(display, XC_left_ptr);
}
old_cursor = current_cursor;
if (XtIsRealized(widget))
{
XDefineCursor(display, XtWindow(widget), hourglass_cursor());
XFlush(display);
}
XtAddCallback(widget, XtNdestroyCallback, _Delay::DestroyCB, this);
}
_Delay::~_Delay()
{
if (widget == 0 || old_cursor == 0)
return;
#if LOG_DELAY
clog << "Removing " << XtName(widget) << " delay cursor\n";
#endif
if (XtIsRealized(widget))
{
XDefineCursor(XtDisplay(widget), XtWindow(widget), old_cursor);
XFlush(XtDisplay(widget));
}
current_cursor = old_cursor;
XtRemoveCallback(widget, XtNdestroyCallback, _Delay::DestroyCB, this);
}
// Make sure we do not attempt to delete a delay on a destroyed widget
void _Delay::DestroyCB(Widget, XtPointer client_data, XtPointer)
{
_Delay *delay = (_Delay *)client_data;
assert(ptr_cast(_Delay, delay));
delay->widget = 0;
delay->old_cursor = 0;
}
int Delay::delay_count = 0;
WidgetArray Delay::_shells;
DelayArray Delay::delays;
Delay::Delay(Widget w):
_Delay(w)
{
assert(delays.size() == _shells.size());
if (delay_count++ == 0)
{
for (int i = 0; i < delays.size(); i++)
{
assert(delays[i] == 0);
if (_shells[i])
{
#if LOG_DELAY
clog << "Slot " << i << ": ";
#endif
delays[i] = new _Delay(_shells[i]);
}
}
}
}
// Make sure the shell is unregistered when destroyed
void Delay::DestroyCB(Widget widget, XtPointer, XtPointer)
{
assert(delays.size() == _shells.size());
// Unregister shell
for (int i = 0; i < _shells.size(); i++)
if (_shells[i] == widget)
{
_shells[i] = 0;
if (delays[i])
{
delete delays[i];
delays[i] = 0;
}
#if LOG_DELAY
clog << "Unregistering " << XtName(widget)
<< " in slot " << i << "\n";
#endif
}
}
void Delay::register_shell(Widget widget)
{
assert(delays.size() == _shells.size());
// Check if the shell is already registered
int i;
for (i = 0; i < _shells.size(); i++)
if (_shells[i] == widget)
return;
// Look for an empty slot
for (i = 0; i < _shells.size() && _shells[i] != 0; i++)
;
XtAddCallback(widget, XtNdestroyCallback, DestroyCB, XtPointer(0));
_Delay *new_delay = 0;
if (delay_count)
new_delay = new _Delay(widget);
if (i == _shells.size())
{
_shells += Widget(0);
delays += (_Delay *)0;
}
assert(_shells[i] == 0);
assert(delays[i] == 0);
_shells[i] = widget;
delays[i] = new_delay;
#if LOG_DELAY
clog << "Registering " << XtName(widget) << " in slot " << i << "\n";
#endif
if (shell_registered != 0)
shell_registered(widget);
assert(delays.size() == _shells.size());
}
Delay::~Delay()
{
assert(delays.size() == _shells.size());
if (--delay_count == 0)
{
for (int i = 0; i < delays.size(); i++)
{
if (delays[i])
{
#if LOG_DELAY
clog << "Slot " << i << ": ";
#endif
delete delays[i];
delays[i] = 0;
}
}
}
}
// bullmann@fzi.de (Joerg Bullmann) says a dummy comment is required here...