/*
* event.cc
*
* Copyright (C) 1995, 1996, 1997, 1997, 1998, 1999, 2000, 2001, 2002 Kenichi Kourai
* Copyright (C) 1999, 2000, 2001, 2002 Luiz Blanes
*
* This program 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.
*
* This program 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 blwm; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#ifdef __EMX__
#include <sys/select.h>
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/shape.h>
#ifdef USE_XSMP
#include <X11/ICE/ICElib.h>
#endif
#include "main.h"
#include "misc.h"
#include "blwm.h"
#include "event.h"
#include "taskbar.h"
#include "fbutton.h"
#include "tbutton.h"
#include "sbutton.h"
#include "startmenu.h"
#include "menu.h"
#include "util.h"
#include "icon.h"
#include "blwmrc.h"
#include "paging.h"
#include "pager.h"
#include "mini.h"
#include "key.h"
#include "indicator.h"
#include "timer.h"
#include "focus_mgr.h"
#include "desktop.h"
#include "gnome.h"
#include "tooltip.h"
#include "session.h"
#include "remote_cmd.h"
#if defined(sun) && !defined(__SVR4)
extern "C" int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
# if defined(__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 8
# else
extern "C" void bzero(char *, int);
# endif
#endif
Blwm* Blwm::focusBlwm;
/*
* MainLoop --
* Wait event and timeout.
*/
void Event::MainLoop()
{
XEvent ev;
int fd = ConnectionNumber(display);
fd_set fds;
struct timeval tm, *timep;
int fdMax;
#ifdef USE_XSMP
// int s;
int iceConnFd;
#endif
#ifdef ALLOW_RMTCMD
int rmtCmdFd = -1;
#endif
while (1) {
while (XPending(display) != 0) {
XNextEvent(display, &ev);
DispatchEvent(ev);
timer->CheckTimeout(&tm);
}
FD_ZERO(&fds);
FD_SET(fd, &fds);
fdMax = fd;
#ifdef USE_XSMP
iceConnFd = session->GetIceConnFd();
if (iceConnFd >= 0) {
FD_SET(iceConnFd, &fds);
if (iceConnFd > fdMax) {
fdMax = iceConnFd;
}
}
#endif // USE_XSMP
#ifdef ALLOW_RMTCMD
if (AllowRemoteCmd) {
rmtCmdFd = remoteCmd->getRmtCmdFd();
if (rmtCmdFd >= 0) {
FD_SET(rmtCmdFd, &fds);
if (rmtCmdFd > fdMax)
fdMax = rmtCmdFd;
}
}
#endif // ALLOW_RMTCMD
/* ???
#ifdef USE_XSMP
// Why we should waitpid here, ...
waitpid(-1, &s, WNOHANG);
#endif
*/
/*
* If next timeout does not exist, select blocks until next events.
*/
if (!timer->CheckTimeout(&tm))
timep = NULL;
else
timep = &tm;
// Flush all requests before select, or some requests is not
// flushed until select is returned.
XFlush(display);
if (XPending(display) > 0)
continue;
#if defined(__hpux) && !defined(_XPG4_EXTENDED)
if (select(fdMax + 1, (int *)&fds, 0, 0, timep) == 0) { // timeout
#else
if (select(fdMax + 1, &fds, 0, 0, timep) == 0) { // timeout
#endif
timer->CheckTimeout(&tm);
}
#ifdef USE_XSMP
else if (iceConnFd >=0 && FD_ISSET(iceConnFd, &fds)) {
Bool res;
IceProcessMessagesStatus rc;
rc = IceProcessMessages(session->GetIceConn(), NULL, &res);
if (rc == IceProcessMessagesIOError) {
session->CloseConnection();
}
//else if (rc == IceProcessMessagesConnectionClosed) {
//}
}
#endif // USE_XSMP
#ifdef ALLOW_RMTCMD
else if (rmtCmdFd >= 0 && FD_ISSET(rmtCmdFd, &fds)) {
remoteCmd->process();
}
#endif
}
}
/*
* DispatchEvent --
* Call the event procedure according to a event type.
*/
void Event::DispatchEvent(const XEvent& ev)
{
switch (ev.type) {
case Expose: {
const XExposeEvent& xev = (const XExposeEvent &)ev;
ExposeProc(xev);
break;
}
case EnterNotify: {
const XCrossingEvent& xev = (const XCrossingEvent &)ev;
EnterNotifyProc(xev);
break;
}
case LeaveNotify: {
const XCrossingEvent& xev = (const XCrossingEvent &)ev;
LeaveNotifyProc(xev);
break;
}
case MotionNotify: {
const XMotionEvent& xev = (const XMotionEvent &)ev;
MotionNotifyProc(xev);
break;
}
case MapRequest: {
const XMapRequestEvent& xev = (const XMapRequestEvent &)ev;
MapRequestProc(xev);
break;
}
case MapNotify: {
const XMapEvent& xev = (const XMapEvent &)ev;
MapNotifyProc(xev);
break;
}
case UnmapNotify: {
if (ev.xany.window == root)
return;
const XUnmapEvent& xev = (const XUnmapEvent &)ev;
UnmapNotifyProc(xev);
break;
}
case DestroyNotify: {
const XDestroyWindowEvent& xev = (const XDestroyWindowEvent &)ev;
DestroyNotifyProc(xev);
break;
}
case ButtonPress: {
const XButtonEvent& xev = (const XButtonEvent &)ev;
ButtonPressProc(xev);
ptPrevRoot = Point(xev.x_root, xev.y_root);
break;
}
case ButtonRelease: {
const XButtonEvent& xev = (const XButtonEvent &)ev;
ButtonReleaseProc(xev);
break;
}
case KeyPress: {
const XKeyEvent& xev = (const XKeyEvent &)ev;
KeyPressProc(xev);
break;
}
case ClientMessage: {
const XClientMessageEvent& xev = (const XClientMessageEvent &)ev;
ClientMessageProc(xev);
break;
}
case ColormapNotify: {
const XColormapEvent& xev = (const XColormapEvent &)ev;
ColormapNotifyProc(xev);
break;
}
case ConfigureRequest: {
const XConfigureRequestEvent& xev = (const XConfigureRequestEvent &)ev;
ConfigureRequestProc(xev);
break;
}
case CirculateRequest: {
const XCirculateRequestEvent& xev = (const XCirculateRequestEvent &)ev;
CirculateRequestProc(xev);
break;
}
case PropertyNotify: {
const XPropertyEvent& xev = (const XPropertyEvent &)ev;
PropertyNotifyProc(xev);
break;
}
case FocusIn: {
const XFocusChangeEvent& xev = (const XFocusChangeEvent &)ev;
FocusInProc(xev);
break;
}
case FocusOut:
break;
default:
if (shapeSupport) {
if (ev.type == shapeEventBase + ShapeNotify) {
const XShapeEvent &xev = (const XShapeEvent &)ev;
ShapeNotifyProc(xev);
}
}
break;
}
}
/*
* ExposeProc --
* Process Expose event.
*/
void Event::ExposeProc(const XExposeEvent& ev)
{
Blwm* blWm;
Button* button;
Menu* menu;
Icon* icon;
Miniature* mini;
Tooltip* tt;
XEvent xev;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
if (blWm == NULL) /* XXX */
return;
blWm->Exposure(ev.window);
}
else if (XFindContext(display, ev.window, Button::context, (caddr_t*)&button)
== XCSUCCESS) {
ASSERT(button);
button->DrawButton();
}
else if (XFindContext(display, ev.window, Menu::context, (caddr_t*)&menu)
== XCSUCCESS) {
ASSERT(menu);
menu->DrawMenu(ev.window);
}
else if (XFindContext(display, ev.window, Icon::context, (caddr_t*)&icon)
== XCSUCCESS) {
ASSERT(icon);
icon->DrawIcon(icon == Icon::focusIcon);
}
else if (XFindContext(display, ev.window, Miniature::context,
(caddr_t*)&mini) == XCSUCCESS) {
ASSERT(mini);
mini->DrawMiniature();
}
else if (XFindContext(display, ev.window, Tooltip::context, (caddr_t*)&tt)
== XCSUCCESS) {
ASSERT(tt);
tt->DrawTooltip();
}
else if (UseTaskbar && taskBar->IsTaskbarWindows(ev.window)) {
taskBar->Exposure(ev.window);
}
else if (UsePager && pager->IsPagerWindows(ev.window)) {
pager->Exposure(ev.window);
}
else
return;
while (XCheckWindowEvent(display, ev.window, ExposureMask, &xev))
;
}
/*
* EnterNotifyProc --
* Process EnterNotify event.
*/
void Event::EnterNotifyProc(const XCrossingEvent& ev)
{
XEvent xev;
Blwm* blWm;
Menu* menu;
Icon* icon;
Button* button;
Miniature* mini;
/*
* So that EnterNotify to taskbar is not canceled out by next LeaveNotify.
*/
if (UseTaskbar && taskBar->IsTaskbarWindows(ev.window)) {
taskBar->Enter(ev.window, Point(ev.x_root, ev.y_root), ev.detail);
return;
}
/*
* Check if there is LeaveNotify event for the window and if so, return.
*/
if (XCheckTypedWindowEvent(display, ev.window, LeaveNotify, &xev)) {
if (xev.xcrossing.mode == NotifyNormal &&
xev.xcrossing.detail != NotifyInferior)
return;
}
ASSERT(paging);
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->Enter(ev.window, ev.state);
}
else if (XFindContext(display, ev.window, Menu::context, (caddr_t*)&menu)
== XCSUCCESS) {
ASSERT(menu);
menu->Enter(ev.window);
}
else if (XFindContext(display, ev.window, Icon::context, (caddr_t*)&icon)
== XCSUCCESS) {
ASSERT(icon);
icon->Enter();
}
else if (XFindContext(display, ev.window, Button::context, (caddr_t*)&button)
== XCSUCCESS) {
ASSERT(button);
button->Enter();
}
else if (XFindContext(display, ev.window, Miniature::context,
(caddr_t*)&mini) == XCSUCCESS) {
ASSERT(mini);
mini->Enter();
}
}
/*
* LeaveNotifyProc --
* Process LeaveNotify event.
*/
void Event::LeaveNotifyProc(const XCrossingEvent& ev)
{
Blwm* blWm;
Menu* menu;
Icon* icon;
Button* button;
Miniature* mini;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->Leave(ev.window);
}
else if (XFindContext(display, ev.window, Menu::context, (caddr_t*)&menu)
== XCSUCCESS) {
ASSERT(menu);
menu->Leave(ev.window);
}
else if (XFindContext(display, ev.window, Icon::context, (caddr_t*)&icon)
== XCSUCCESS) {
ASSERT(icon);
icon->Leave();
}
else if (XFindContext(display, ev.window, Button::context, (caddr_t*)&button)
== XCSUCCESS) {
ASSERT(button);
button->Leave();
}
else if (XFindContext(display, ev.window, Miniature::context,
(caddr_t*)&mini) == XCSUCCESS) {
ASSERT(mini);
mini->Leave();
}
else if (UseTaskbar && taskBar->IsTaskbarWindows(ev.window)) {
taskBar->Leave(ev.window, Point(ev.x_root, ev.y_root), ev.detail);
}
}
/*
* MotionNotifyProc --
* Process MotionNotify event.
*/
void Event::MotionNotifyProc(const XMotionEvent& ev)
{
Blwm* blWm;
Menu* menu;
Icon* icon;
Button* button;
Miniature* mini;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
if (ev.state & Button1Mask)
blWm->Button1Motion(ev.window, ptPrevRoot);
else if (ev.state & Button2Mask)
blWm->Button2Motion(ev.window, ptPrevRoot);
else
blWm->PointerMotion(ev.window);
}
else if (XFindContext(display, ev.window, Menu::context, (caddr_t*)&menu)
== XCSUCCESS) {
ASSERT(menu);
menu->PointerMotion(ev.window);
}
else if (XFindContext(display, ev.window, Icon::context, (caddr_t*)&icon)
== XCSUCCESS) {
ASSERT(icon);
if (ev.state & Button1Mask)
icon->Button1Motion(ptPrevRoot);
else
icon->PointerMotion();
}
else if (XFindContext(display, ev.window, Button::context, (caddr_t*)&button)
== XCSUCCESS) {
ASSERT(button);
button->PointerMotion();
}
else if (XFindContext(display, ev.window, Miniature::context,
(caddr_t*)&mini) == XCSUCCESS) {
ASSERT(mini);
mini->PointerMotion();
}
else if (UseTaskbar && taskBar->IsTaskbarWindows(ev.window)) {
if (ev.state & Button1Mask)
taskBar->Button1Motion(ev.window, ptPrevRoot);
else
taskBar->PointerMotion();
}
}
/*
* MapRequestProc --
* Process MapRequest event.
*/
void Event::MapRequestProc(const XMapRequestEvent& ev)
{
/*
* Check the window is valid.
*/
Window junkRoot;
Rect rcJunk;
unsigned int junkBW, junkDepth;
if (XGetGeometry(display, ev.window, &junkRoot, &rcJunk.x, &rcJunk.y,
(unsigned int *)&rcJunk.width,
(unsigned int *)&rcJunk.height,
&junkBW, &junkDepth) == 0)
return;
// Blwm deals with a window whose size is larger than 32768 as an invalid
// window. (This may be incorrect in some cases...)
if ((short)rcJunk.width < 0 || (short)rcJunk.height < 0) {
BlwmError("window size is probably invalid: %d(%d)x%d(%d)",
rcJunk.width, (short)rcJunk.width,
rcJunk.height, (short)rcJunk.height);
return;
}
/*
* If the name of the window is requested by Indicator, the window becomes
* an indicator.
*/
XTextProperty xtp;
char** cl = NULL;
int n;
XClassHint classHints;
Indicator* ind;
char* title = "";
if (XGetWMName(display, ev.window, &xtp) != 0) {
XmbTextPropertyToTextList(display, &xtp, &cl, &n);
if (cl)
title = cl[0];
}
classHints.res_name = NULL;
classHints.res_class = NULL;
XGetClassHint(display, ev.window, &classHints);
if ((ind = Indicator::LookInList(title, classHints))) {
XFreeStringList(cl);
if (classHints.res_name)
XFree(classHints.res_name);
if (classHints.res_class)
XFree(classHints.res_class);
ind->CreateIndicator(ev.window);
return;
}
else {
XFreeStringList(cl);
if (classHints.res_name)
XFree(classHints.res_name);
if (classHints.res_class)
XFree(classHints.res_class);
}
/*
* Frame setup.
*/
Blwm* blWm;
XWMHints *wmHints;
/*
* If blWm has already created and is unmapped, need not create new blWm.
*/
if ((blWm = desktop.LookInList(ev.window)) == NULL) {
blWm = new Blwm(ev.window, False);
desktop.GetBlwmList().InsertTail(blWm);
}
if (blWm->CheckFlags(CLOSE_SOON)) {
#ifdef DEBUG
BlwmError("force to close a window: %s", blWm->GetName());
#endif
XReparentWindow(display, ev.window, root,
rcScreen.x + rcScreen.width, rcScreen.y + rcScreen.height);
blWm->CloseWindow();
desktop.GetBlwmList().Remove(blWm);
delete blWm;
return;
}
wmHints = blWm->GetWMHints();
if ((wmHints && (wmHints->flags & StateHint) &&
wmHints->initial_state == IconicState) ||
blWm->CheckFlags(INIT_MINIMIZE))
blWm->MinimizeWindow(False);
else if (blWm->CheckFlags(INIT_MAXIMIZE)) {
blWm->fButton[1]->ChangeImage(FrameButton::RESTORE);
blWm->MaximizeWindow(False, False);
}
else if (blWm->CheckStatus(MINIMIZE_WINDOW))
blWm->RestoreWindow(False, False);
else
blWm->MapWindows();
ASSERT(blWm->tButton);
blWm->tButton->MapButton();
if (!blWm->CheckStatus(MINIMIZE_WINDOW)) {
if (ClickToFocus || FocusOnMap)
blWm->SetFocus();
}
else
focusMgr.InsertUnmapList(blWm);
Gnome::ChangeClientList();
XSync(display, 0);
}
/*
* MapNotifyProc --
* Process MapNotify event.
*/
void Event::MapNotifyProc(const XMapEvent& ev)
{
Blwm* blWm;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
// WM should not interfere if override_redirect is True, but does
// interfere when override_redirect is changed from False to True.
// So reparent the window and return if override_redirect is True.
if (ev.override_redirect) {
XSelectInput(display, ev.window, 0);
Window junkRoot;
Rect rect;
unsigned int junkBW, junkDepth;
XGetGeometry(display, ev.window, &junkRoot, &rect.x, &rect.y,
(unsigned int *)&rect.width,
(unsigned int *)&rect.height,
&junkBW, &junkDepth);
XReparentWindow(display, ev.window, root, rect.x, rect.y);
desktop.GetBlwmList().Remove(blWm);
delete blWm;
return;
}
if (!blWm->CheckMapped()) {
Menu::UnmapAllMenus();
XGrabServer(display);
if (blWm->CheckStatus(MINIMIZE_WINDOW))
blWm->RestoreWindow(False, False);
else {
blWm->MapWindows();
blWm->tButton->MapButton();
XAddToSaveSet(display, blWm->GetWin());
}
if (ClickToFocus || FocusOnMap)
blWm->SetFocus();
XSync(display, 0);
XUngrabServer(display);
}
}
}
/*
* UnmapNotifyProc --
* Process UnmapNotify event.
*/
void Event::UnmapNotifyProc(const XUnmapEvent& ev)
{
Blwm* blWm;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
XGrabServer(display);
blWm->SetStateProperty(WithdrawnState);
Rect rcRoot = rootBlwm->GetRect();
Rect rcOrig = blWm->GetOrigRect();
Point pt;
// adjust the position so that the window is in the real screen
pt.x = rcOrig.x % rcRoot.width;
if (pt.x < 0)
pt.x += rcRoot.width;
pt.y = rcOrig.y % rcRoot.height;
if (pt.y < 0)
pt.y += rcRoot.height;
XReparentWindow(display, blWm->GetWin(), root, pt.x, pt.y);
XUnmapWindow(display, blWm->GetWin());
DestroyBlwm(blWm);
XSync(display, 0);
XUngrabServer(display);
}
}
/*
* DestroyNotifyProc --
* Process DestroyNotify event.
*/
void Event::DestroyNotifyProc(const XDestroyWindowEvent& ev)
{
Blwm* blWm;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
XGrabServer(display);
DestroyBlwm(blWm);
XUngrabServer(display);
}
}
void Event::DestroyBlwm(Blwm* blWm)
{
Bool yield = False;
if (blWm == Blwm::focusBlwm) {
yield = True;
blWm->YieldFocus();
}
if (blWm->CheckMapped())
blWm->UnmapWindows();
focusMgr.RemoveUnmapList(blWm);
focusMgr.Remove(blWm);
XRemoveFromSaveSet(display, blWm->GetWin());
desktop.GetBlwmList().Remove(blWm);
blWm->tButton->UnmapButton();
delete blWm;
Gnome::ChangeClientList();
if (yield && !ClickToFocus)
desktop.ChangeFocusToCursor();
}
/*
* ButtonPressProc --
* Process ButtonPress event.
*/
void Event::ButtonPressProc(const XButtonEvent& ev)
{
Blwm* blWm;
Button* button;
Menu* menu;
Icon* icon;
Miniature* mini;
if (ev.button == Button1) {
/*
* Left button.
*/
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->Button1Press(ev.window, ev.time, Point(ev.x_root, ev.y_root),
ev.state);
}
else if (XFindContext(display, ev.window, Button::context, (caddr_t*)&button)
== XCSUCCESS) {
ASSERT(button);
button->Button1Press();
}
else if (XFindContext(display, ev.window, Menu::context, (caddr_t*)&menu)
== XCSUCCESS) {
ASSERT(menu);
menu->Button1Press(ev.window);
}
else if (XFindContext(display, ev.window, Icon::context, (caddr_t*)&icon)
== XCSUCCESS) {
ASSERT(icon);
icon->Button1Press(ev.time, Point(ev.x_root, ev.y_root));
}
else if (XFindContext(display, ev.window, Miniature::context, (caddr_t*)&mini)
== XCSUCCESS) {
ASSERT(mini);
mini->Button1Press(Point(ev.x_root, ev.y_root));
}
else if (UseTaskbar && taskBar->IsTaskbarWindows(ev.window))
taskBar->Button1Press();
else if (UsePager && pager->IsPagerWindows(ev.window))
pager->Button1Press(ev.window, Point(ev.x_root, ev.y_root),
Point(ev.x, ev.y));
}
else if (ev.button == Button2) {
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->Button2Press(ev.window);
}
else if (XFindContext(display, ev.window, Miniature::context,
(caddr_t*)&mini) == XCSUCCESS) {
ASSERT(mini);
mini->Button2Press(Point(ev.x_root, ev.y_root));
}
}
else if (ev.button == Button3) {
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->Button3Press();
}
else if (UsePager) {
ASSERT(pager);
if (ev.window == pager->GetVisualWin())
pager->Button3Press(Point(ev.x_root, ev.y_root));
}
}
XAllowEvents(display, ReplayPointer, CurrentTime);
}
/*
* ButtonReleaseProc --
* Process ButtonRelease event.
*/
void Event::ButtonReleaseProc(const XButtonEvent& ev)
{
Blwm* blWm;
Button* button;
Menu* menu;
Icon* icon;
if (ev.state & Button1Mask) {
/*
* Left button.
*/
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->Button1Release();
}
else if (XFindContext(display, ev.window, Menu::context, (caddr_t*)&menu)
== XCSUCCESS) {
ASSERT(menu);
menu->Button1Release(ev.window);
}
}
else if (ev.state & Button2Mask) {
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->Button2Release(ev.window);
}
}
else if (ev.state & Button3Mask) {
/*
* Right button.
*/
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->Button3Release(ev.window, Point(ev.x_root, ev.y_root));
}
else if (XFindContext(display, ev.window, Button::context, (caddr_t*)&button)
== XCSUCCESS) {
ASSERT(button);
button->Button3Release(Point(ev.x_root, ev.y_root));
}
else if (XFindContext(display, ev.window, Icon::context, (caddr_t*)&icon)
== XCSUCCESS) {
ASSERT(icon);
icon->Button3Release(Point(ev.x_root, ev.y_root));
}
else if (UseTaskbar && taskBar->IsTaskbarWindows(ev.window)) {
taskBar->Button3Release(Point(ev.x_root, ev.y_root));
}
}
}
/*
* KeyPressProc --
* Process KeyPress event.
*/
void Event::KeyPressProc(const XKeyEvent& ev)
{
Menu* menu;
Blwm* blWm;
if (XFindContext(display, ev.window, Menu::context, (caddr_t*)&menu)
== XCSUCCESS) {
if (!menuKey->ExecShortCutKey(ev.keycode, ev.state, menu)) {
char key;
KeySym sym;
if (XLookupString((XKeyEvent *)&ev, &key, 1, &sym, NULL) == 1)
menu->ExecShortCutKey(key);
}
}
else if (ev.window == root)
scKey->ExecShortCutKey(ev.keycode, ev.state, rootBlwm->ctrlMenu);
else if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
ASSERT(blWm->ctrlMenu);
blWm->ctrlMenu->SetBlwm(blWm);
scKey->ExecShortCutKey(ev.keycode, ev.state, blWm->ctrlMenu);
}
}
/*
* ClientMessageProc --
* Process ClientMessageNotify event.
*/
void Event::ClientMessageProc(const XClientMessageEvent& ev)
{
Blwm* blWm;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
if (ev.message_type == _XA_WM_CHANGE_STATE &&
ev.data.l[0] == IconicState)
blWm->MinimizeWindow();
else
Gnome::SetProperty(blWm, ev.message_type, (long *)ev.data.l);
}
}
/*
* ColormapNotifyProc --
* Process ColormapNotify event.
*/
void Event::ColormapNotifyProc(const XColormapEvent& ev)
{
Blwm* blWm;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t *)&blWm)
!= XCSUCCESS)
return;
blWm->ChangeColormap(ev);
}
/*
* ConfigureRequestProc --
* Process ConfigureRequest event.
*/
void Event::ConfigureRequestProc(const XConfigureRequestEvent& ev)
{
Blwm* blWm;
XWindowChanges xwc;
unsigned long xwcm;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCNOENT) {
xwcm = ev.value_mask & (CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
xwc.x = ev.x;
xwc.y = ev.y;
xwc.width = ev.width;
xwc.height = ev.height;
xwc.border_width = ev.border_width;
XConfigureWindow(display, ev.window, xwcm, &xwc);
}
else {
ASSERT(blWm);
blWm->Configure(&ev);
}
}
void Event::CirculateRequestProc(const XCirculateRequestEvent& ev)
{
Blwm* blWm;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->Circulate(ev.place);
}
}
/*
* PropertyNotifyProc --
* Process PropertyNotify event.
*/
void Event::PropertyNotifyProc(const XPropertyEvent& ev)
{
Blwm* blWm;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->SetProperty(ev.atom);
}
}
void Event::FocusInProc(const XFocusChangeEvent& ev)
{
Blwm* blWm;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
if (ev.mode == NotifyUngrab)
XSetInputFocus(display, blWm->GetWin(), RevertToParent, CurrentTime);
}
}
/*
* ShapeNotifyProc --
* Process ShapeNotify event.
*/
void Event::ShapeNotifyProc(const XShapeEvent& ev)
{
Blwm* blWm;
if (ev.kind != ShapeBounding)
return;
if (XFindContext(display, ev.window, Blwm::context, (caddr_t*)&blWm)
== XCSUCCESS) {
ASSERT(blWm);
blWm->SetShape();
}
}
syntax highlighted by Code2HTML, v. 0.9.1