123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they 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.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $TOG: MainWindow.C /main/13 1998/04/06 13:22:40 mgreess $ */
- /*
- *+SNOTICE
- *
- * $TOG: MainWindow.C /main/13 1998/04/06 13:22:40 mgreess $
- *
- * RESTRICTED CONFIDENTIAL INFORMATION:
- *
- * The information in this document is subject to special
- * restrictions in a confidential disclosure agreement bertween
- * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
- * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
- * Sun's specific written approval. This documment and all copies
- * and derivative works thereof must be returned or destroyed at
- * Sun's request.
- *
- * Copyright 1993, 1994, 1995 Sun Microsystems, Inc. All rights reserved.
- *
- *+ENOTICE
- */
- ///////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // This example code is from the book:
- //
- // Object-Oriented Programming with C++ and OSF/Motif
- // by
- // Douglas Young
- // Prentice Hall, 1992
- // ISBN 0-13-630252-1
- //
- // Copyright 1991 by Prentice Hall
- // All Rights Reserved
- //
- // Permission to use, copy, modify, and distribute this software for
- // any purpose except publication and without fee is hereby granted, provided
- // that the above copyright notice appear in all copies of the software.
- ///////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////
- // MainWindow.C: Support a toplevel window
- ////////////////////////////////////////////////////////////////////
- #include <assert.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <Xm/Protocols.h>
- #include <Xm/AtomMgr.h>
- #include <Xm/MainW.h>
- #include <Dt/Wsm.h>
- #include <Dt/Session.h>
- #include <DtMail/IO.hh>
- #include <X11/Shell.h>
- #include <X11/Xmu/Editres.h>
- #include "Application.h"
- #include "MainWindow.h"
- #include "Help.hh"
- // The following headers are private to CDE and should NOT be required
- // but unfortunately are.
- //
- extern "C" {
- #include <Dt/HourGlass.h>
- }
- #include <Dt/Icon.h>
- #include <Dt/IconP.h>
- #include <Dt/IconFile.h>
- // This is a private CDE function that should be public, but is not,
- // and does not even have a prototype in a header. Yes, it is required.
- //
- extern "C" Pixmap _DtGetMask(Screen * screen, char * image_name);
- #if 0
- static const char * DefaultIcon = "Dtablnk";
- #endif
- static const unsigned long FLASH_INTERVAL = 250; // milliseconds
- MainWindow::MainWindow( char *name, Boolean allowResize ) : UIComponent ( name )
- {
- _workArea = NULL;
- _flashing = 0;
- _icon_invert = NULL;
- _window_invert = NULL;
- _icon = 0;
- _allow_resize = allowResize;
- _last_state = 0;
- _flash_owin = 0;
- _flash_iwin = 0;
- _main = NULL;
- memset(&_window_attributes, 0, sizeof(XWindowAttributes));
- assert ( theApplication != NULL ); // Application object must exist
- // before any MainWindow object
- theApplication->registerWindow ( this );
- }
- void
- MainWindow::initialize( )
- {
- char *appWorkspaces;
- // All toplevel windows in the MotifApp framework are
- // implemented as a popup shell off the Application's
- // base widget.
- //
- // XmNdeleteResponse is being set to DO_NOTHING so
- // that the user can Cancel their close request.
- _w = XtVaCreatePopupShell ( _name,
- topLevelShellWidgetClass,
- theApplication->baseWidget(),
- XmNdeleteResponse, XmDO_NOTHING,
- XmNallowShellResize, _allow_resize,
- NULL, NULL );
- #ifdef USE_EDITRES
- XtAddEventHandler(
- _w, (EventMask) 0, True,
- (XtEventHandler) _XEditResCheckMessages, NULL);
- #endif
- installDestroyHandler();
-
- // Use a Motif XmMainWindow widget to handle window layout
-
- _main = XtCreateManagedWidget ( "mainWindow",
- xmMainWindowWidgetClass,
- _w,
- NULL, 0 );
- printHelpId("_main", _main);
- /* install callback */
- // XtAddCallback(_main, XmNhelpCallback, HelpCB, helpId);
- XtAddCallback(_main, XmNhelpCallback,
- HelpCB, (void *)"_HOMETOPIC");
-
- // Called derived class to create the work area
-
- _workArea = createWorkArea ( _main );
- assert ( _workArea != NULL );
-
- // Designate the _workArea widget as the XmMainWindow
- // widget's XmNworkWindow widget
-
- XtVaSetValues ( _main,
- XmNworkWindow, _workArea,
- NULL );
- Atom WM_DELETE_WINDOW=XmInternAtom( XtDisplay( _w ),
- "WM_DELETE_WINDOW",
- False );
- XmAddWMProtocolCallback( _w,
- WM_DELETE_WINDOW,
- ( XtCallbackProc ) quitCallback,
- this );
- #if 0
- // Why are we setting the icon to Dtablnk. This is simply going to
- // be overriden by some other function setting it to the appropriate
- // icon.
- setIconName(DefaultIcon);
- #endif
- _window_invert = NULL;
- _last_state = 0;
- _flash_owin = (Window) NULL;
- _flash_iwin = (Window) NULL;
- memset((char*) &(this->_window_attributes), 0, sizeof(XWindowAttributes));
- // Manage the work area if the derived class hasn't already.
-
- if ( !XtIsManaged ( _workArea ) )
- XtManageChild ( _workArea );
- XtRealizeWidget(_w);
- appWorkspaces = theApplication->getAppWorkspaceList();
- setWorkspacesOccupied(appWorkspaces);
- }
- MainWindow::~MainWindow( )
- {
- // Unregister this window with the Application object
- if (_w) {
- Atom WM_DELETE_WINDOW=XmInternAtom( XtDisplay( _w ),
- "WM_DELETE_WINDOW",
- False );
- XmRemoveWMProtocolCallback( _w,
- WM_DELETE_WINDOW,
- ( XtCallbackProc ) quitCallback,
- NULL );
- if (_icon_invert) XFreeGC(XtDisplay(_w), _icon_invert);
- if (_window_invert) XFreeGC(XtDisplay(_w), _window_invert);
- if (_flash_iwin != (Window) NULL)
- XDestroyWindow( XtDisplay(_w), _flash_iwin );
- if (_flash_owin != (Window) NULL)
- XDestroyWindow( XtDisplay(_w), _flash_owin );
- }
-
- theApplication->unregisterWindow ( this );
- }
- void
- MainWindow::enableWorkAreaResize()
- {
- XtVaSetValues(_workArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
- }
- void
- MainWindow::disableWorkAreaResize()
- {
- XtVaSetValues(_workArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
- }
- void
- MainWindow::manage()
- {
- assert ( _w != NULL );
- XtPopup ( _w, XtGrabNone );
-
- // Map the window, in case the window is iconified
- if ( XtIsRealized ( _w ) )
- XMapRaised ( XtDisplay ( _w ), XtWindow ( _w ) );
- }
- void
- MainWindow::unmanage()
- {
- assert ( _w != NULL );
- XtPopdown ( _w );
- }
- void
- MainWindow::iconify()
- {
- assert ( _w != NULL );
-
- // Set the widget to have an initial iconic state
- // in case the base widget has not yet been realized
-
- XtVaSetValues ( _w, XmNiconic, TRUE, NULL );
-
- // If the widget has already been realized,
- // iconify the window
-
- if ( XtIsRealized ( _w ) )
- XIconifyWindow ( XtDisplay ( _w ), XtWindow ( _w ), 0 );
- }
- void
- MainWindow::setIconTitle(const char * title)
- {
- XtVaSetValues(_w, XmNiconName, title, NULL);
- }
- void
- MainWindow::setIconName(const char * path)
- {
- char * icon_filename = XmGetIconFileName(XtScreen(_w),
- NULL,
- (char *)path, // Bug!
- NULL,
- DtLARGE);
- if (icon_filename == NULL) {
- return;
- }
- Pixel fg = 0, bg = 0;
- getIconColors(fg, bg);
- _icon = XmGetPixmap(XtScreen(_w),
- icon_filename,
- fg, bg);
- Pixmap icon_mask_map = _DtGetMask(XtScreen(_w), icon_filename);
- if (!_icon || !icon_mask_map) {
- return;
- }
- XtVaSetValues(_w,
- XmNiconPixmap, _icon,
- XmNiconMask, icon_mask_map,
- NULL);
- // Build the inverted icon mask for flashing.
- //
- if (_icon_invert) {
- XFreeGC(XtDisplay(_w), _icon_invert);
- }
- XGCValues gc_vals;
- gc_vals.foreground = bg;
- gc_vals.function = GXxor;
- _icon_invert = XCreateGC(XtDisplay(_w), _icon, GCForeground | GCFunction,
- &gc_vals);
- XtFree(icon_filename);
- }
- void
- MainWindow::busyCursor()
- {
- // Do nothing if the widget has not been realized
- if (XtIsRealized(_w)) {
- _DtTurnOnHourGlass(_w);
- }
- }
- void
- MainWindow::normalCursor()
- {
- // Do nothing if the widget has not been realized
-
- if (XtIsRealized ( _w ))
- {
- _DtTurnOffHourGlass(_w);
- }
- }
- void
- MainWindow::setStatus(const char *)
- {
- // Noop in our case.
- }
- void
- MainWindow::clearStatus(void)
- {
- // Noop in our case.
- }
- void
- MainWindow::title(const char *text )
- {
- XtVaSetValues ( _w, XmNtitle, (char *)text, NULL );
- }
- void
- MainWindow::quitCallback( Widget,
- XtPointer clientData,
- XmAnyCallbackStruct *)
- {
- MainWindow *window=( MainWindow *) clientData;
- window->quit();
- }
- void
- MainWindow::getIconColors(Pixel & fore, Pixel & back)
- {
- XtVaGetValues (_w,
- XmNforeground, &fore,
- XmNbackground, &back,
- NULL);
- }
- struct WM_STATE {
- int state;
- Window icon;
- };
- static int
- getWindowState(Widget w)
- {
- Atom wmStateAtom, actualType;
- int actualFormat;
- int retval;
- unsigned long nitems, leftover;
- WM_STATE *wmState;
-
- /* Getting the WM_STATE property to see if iconified or not */
- wmStateAtom = XInternAtom(XtDisplay(w), "WM_STATE", False);
-
- XGetWindowProperty (XtDisplay(w), XtWindow(w),
- wmStateAtom, 0L,
- (long)BUFSIZ, False, wmStateAtom, &actualType,
- &actualFormat, &nitems, &leftover,
- (unsigned char **) &wmState);
- if (wmState)
- retval = wmState->state;
- else
- retval = 0;
- free((void*) wmState);
- return retval;
- }
- void
- MainWindow::flash(const int count)
- {
- XWindowAttributes window_attributes;
- if (count == 0) return;
- if (_flashing > 0) return;
- if (_window_invert == NULL) {
- // Create a GC to flash the window.
- //
- XGCValues gc_vals;
- Pixel fg, bg;
- getIconColors(fg, bg);
-
- gc_vals.foreground = bg;
- gc_vals.function = GXxor;
- _window_invert = XCreateGC(XtDisplay(_w), XtWindow(_w),
- GCForeground | GCFunction, &gc_vals);
- XSetSubwindowMode(XtDisplay(_w), _window_invert, IncludeInferiors);
- }
- _last_state = getWindowState(_w);
- //
- // The original method here, to invert the window and timeout
- // before inverting back to the original (pixels), breaks when
- // the window is left with pixels XOR'd in the flash ON state.
- //
- // One quick fix, uses a transparent window (or windows) on top
- // of the window to be flashed. The temp window(s) are used to
- // prevent updates while flash is ON and/or cause a full update
- // (expose) after each flash.
- //
- // First, (this part optional) put an "InputOnly" window on top of
- // the window to be flashed and ignore all events to this window.
- // This has the effect of preventing user input (events) from
- // causing application updates to the window. This temp window
- // can be left up (with the wait cursor) until flashing is done.
- //
- // Next, handle expose events by using a transparent "InputOutput"
- // window on top of everything only when flash is ON. This has
- // the effect of preventing expose events from causing application
- // updates to the real window when flash is ON. It especially,
- // ensures other problems (e.g. updates to the window caused by
- // other application timeout events and overlapping window pixels
- // from an expose event) are cleaned up by an expose event when
- // this temp window is unmapped or destroyed (between each flash).
- //
-
- XGetWindowAttributes(XtDisplay(_w), XtWindow(_w), &window_attributes);
- if ((Window) NULL != _flash_owin &&
- (window_attributes.width != _window_attributes.width ||
- window_attributes.height != _window_attributes.height ||
- window_attributes.border_width != _window_attributes.border_width))
- {
- XDestroyWindow( XtDisplay(_w), _flash_iwin );
- XDestroyWindow( XtDisplay(_w), _flash_owin );
- _flash_iwin = (Window) NULL;
- _flash_owin = (Window) NULL;
- }
- if ((Window) NULL == _flash_owin)
- {
- XSetWindowAttributes sw_attr;
- memcpy((char*) &(this->_window_attributes),
- (char*) &window_attributes,
- sizeof(window_attributes));
- sw_attr.event_mask = 0;
- _flash_iwin = XCreateWindow(
- XtDisplay(_w), XtWindow(_w), 0, 0,
- _window_attributes.width, _window_attributes.height,
- _window_attributes.border_width, (int) CopyFromParent,
- InputOnly, CopyFromParent,
- CWEventMask, &sw_attr );
- XMapWindow( XtDisplay(_w), _flash_iwin );
- _flash_owin = XCreateWindow(
- XtDisplay(_w), XtWindow(_w), 0, 0,
- _window_attributes.width, _window_attributes.height,
- _window_attributes.border_width, (int) CopyFromParent,
- InputOutput, CopyFromParent,
- CWEventMask, &sw_attr );
- }
- _flashing = count * 2;
- XtAppAddTimeOut(
- XtWidgetToApplicationContext(_w),
- FLASH_INTERVAL, flashCallback, this);
- }
- void
- MainWindow::flashCallback(XtPointer client_data, XtIntervalId * interval_id)
- {
- MainWindow * mw = (MainWindow *)client_data;
- mw->doFlash(interval_id);
- }
- void
- MainWindow::doFlash(XtIntervalId *)
- {
- static int busy_cursor = 0;
- int state = getWindowState(_w);
- // We are going to make things flash an even number of times.
- // to do this, we will lie about the state, and leave it at the
- // old state for one iteration.
- if (state != _last_state && (_flashing % 2) != 0)
- state = _last_state;
-
- if (! busy_cursor) {
- busyCursor();
- busy_cursor = 1;
- }
- if (state == IconicState) {
- Pixmap image = _icon;
- XFillRectangle(XtDisplay(_w), image, _icon_invert, 0, 0, 48, 48);
- XtVaSetValues(_w, XmNiconPixmap, NULL, NULL);
- XtVaSetValues(_w, XmNiconPixmap, image, NULL);
- }
- else if (state != 0) {
- // Map temp window to prevent expose updates and other
- // application event updates ... when flash is on.
- if ( (_flashing % 2) == 0 )
- XMapWindow( XtDisplay(_w), _flash_owin );
- XFillRectangle(
- XtDisplay(_w), XtWindow(_w),
- _window_invert, 0, 0,
- _window_attributes.width, _window_attributes.height);
- // Remove temp window to update display when flash is off.
- if ( (_flashing % 2) != 0 )
- XUnmapWindow( XtDisplay(_w), _flash_owin );
- }
- _flashing -= 1;
- if (_flashing > 0) {
- XtAppAddTimeOut(
- XtWidgetToApplicationContext(_w),
- FLASH_INTERVAL, flashCallback, this);
- _last_state = state;
- }
- else {
- XUnmapWindow( XtDisplay(_w), _flash_iwin );
- XUnmapWindow( XtDisplay(_w), _flash_owin );
- normalCursor();
- busy_cursor = 0;
- }
- }
- Boolean
- MainWindow::isIconified()
- {
-
- Atom wmStateAtom, actualType;
- int actualFormat;
- unsigned long nitems, leftover;
- WM_STATE *wmState;
- Boolean retval = FALSE;
-
- assert ( _w != NULL );
- /* Getting the WM_STATE property to see if iconified or not */
- wmStateAtom = XInternAtom(XtDisplay(_w), "WM_STATE", False);
-
- XGetWindowProperty (XtDisplay(_w), XtWindow(_w),
- wmStateAtom, 0L,
- (long)BUFSIZ, False, wmStateAtom, &actualType,
- &actualFormat, &nitems, &leftover,
- (unsigned char **) &wmState);
- if (wmState && wmState->state == IconicState)
- retval = TRUE;
-
- free((void*) wmState);
- return retval;
- }
- /************************************************************************
- * MbStrchr -
- ************************************************************************/
- char *
- MainWindow::MbStrchr(char *str, int ch)
- {
- size_t mbCurMax = MB_CUR_MAX;
- wchar_t targetChar, curChar;
- char tmpChar;
- int i, numBytes, byteLen;
- if(mbCurMax <= 1) return strchr(str, ch);
- tmpChar = (char)ch;
- mbtowc(&targetChar, &tmpChar, mbCurMax);
- for(i = 0, numBytes = 0, byteLen = strlen(str); i < byteLen; i += numBytes)
- {
- numBytes = mbtowc(&curChar, &str[i], mbCurMax);
- if(curChar == targetChar) return &str[i];
- }
- return (char *)NULL;
- }
- void
- MainWindow::setWorkspacesOccupied(char *workspaces)
- {
- char *ptr;
- Atom *workspace_atoms = NULL;
- int nworkspaces=0;
- if (workspaces)
- {
- do
- {
- ptr = MbStrchr (workspaces, ' ');
- if (ptr != NULL) *ptr = '\0';
- workspace_atoms = (Atom*) XtRealloc(
- (char *) workspace_atoms,
- sizeof(Atom)*(nworkspaces+1));
- workspace_atoms[nworkspaces] = XmInternAtom(
- XtDisplay(_w),
- workspaces, True);
- nworkspaces++;
- if (ptr != NULL)
- {
- *ptr = ' ';
- workspaces = ptr + 1;
- }
- } while (ptr != NULL);
- DtWsmSetWorkspacesOccupied(
- XtDisplay(_w), XtWindow (_w),
- workspace_atoms, nworkspaces);
- XtFree ((char *) workspace_atoms);
- workspace_atoms = NULL;
- }
- else
- {
- Window rootWindow;
- Atom pCurrent;
- Screen *currentScreen;
- int screen;
- screen = XDefaultScreen(XtDisplay(_w));
- currentScreen = XScreenOfDisplay(XtDisplay(_w), screen);
- rootWindow = RootWindowOfScreen(currentScreen);
- if (DtWsmGetCurrentWorkspace(
- XtDisplay(_w),
- rootWindow,
- &pCurrent) == Success)
- DtWsmSetWorkspacesOccupied(
- XtDisplay(_w),
- XtWindow(_w),
- &pCurrent, 1);
- }
- }
|