Mozilla/mozilla/cmd/xfe/src/Splash.cpp
cls%seawood.org 7904be8420 Removed the unused PREF_AlterSplashIcon(). This removes the xfe dependency from libpref. Approved by ramiro@netscape.com.
git-svn-id: svn://10.0.0.236/trunk@13087 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-19 08:31:54 +00:00

399 lines
8.6 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
Splash.cpp -- class for dealing with the unix splash screen.
Created: Chris Toshok <toshok@netscape.com>, 21-Dec-1996.
*/
#include "Splash.h"
#include "DisplayFactory.h"
#include "xpassert.h"
#include "prefapi.h"
#include <Xm/MenuShell.h>
#include <Xm/RowColumn.h>
#include <Xm/Label.h>
#include "private/prpriv.h" /* For PR_NewNamedMonitor */
#ifdef DEBUG_username
#define D(x) x
#else
#define D(x)
#endif
struct XFE_SplashEvent {
PREvent event; /* the PREvent structure */
char *text; /* the new text to be displayed. */
XFE_Splash *splash; /* the splash screen object we're going to muck with. */
};
static XFE_Splash *xfe_splash = NULL;
extern fe_icon_data Splash;
extern "C" Colormap fe_getColormap(fe_colormap *colormap);
fe_icon XFE_Splash::splash_icon = { 0 };
XFE_Splash::XFE_Splash(Widget toplevel)
{
Arg av[10];
int ac;
fe_colormap *cmap = XFE_DisplayFactory::theFactory()->getSharedColormap();
m_exposemonitor = PR_NewNamedMonitor("expose-monitor");
m_eventmonitor = PR_NewNamedMonitor("event-monitor");
m_stopmonitor = PR_NewNamedMonitor("stop-monitor");
m_done = 0;
m_context = XP_NewContext();
m_context->fe.data = XP_NEW_ZAP(fe_ContextData);
m_thread = PR_CreateThread(PR_USER_THREAD, splashThreadProc, this,
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
0); /* default stack size */
m_eventqueue = PR_CreateEventQueue("splash-events", m_thread);
ac = 0;
XtSetArg(av[ac], XmNwidth, 1); ac++;
XtSetArg(av[ac], XmNheight, 1); ac++;
XtSetArg(av[ac], XmNcolormap, fe_getColormap(cmap)); ac++;
XtSetArg(av[ac], XmNvisual, XFE_DisplayFactory::theFactory()->getVisual()); ac++;
XtSetArg(av[ac], XmNdepth, XFE_DisplayFactory::theFactory()->getVisualDepth()); ac++;
m_shell = XtCreatePopupShell("splashShell",
xmMenuShellWidgetClass,
toplevel,
av, ac);
m_rc = XtVaCreateManagedWidget("splashRC",
xmRowColumnWidgetClass,
m_shell,
XmNspacing, 0,
NULL);
CONTEXT_WIDGET(m_context) = m_shell;
CONTEXT_DATA (m_context)->colormap = cmap;
setBaseWidget(m_shell);
XtGetApplicationResources (m_widget,
(XtPointer) CONTEXT_DATA (m_context),
fe_Resources, fe_ResourcesSize,
0, 0);
fe_InitIconColors(m_context);
fe_init_image_callbacks(m_context);
fe_InitColormap (m_context);
//PREF_AlterSplashIcon(&Splash);
fe_NewMakeIcon(m_shell,
BlackPixelOfScreen(XtScreen(m_shell)), //XXX hack... doesn't really matter though.
BlackPixelOfScreen(XtScreen(m_shell)), //XXX hack... doesn't really matter though.
&splash_icon,
NULL,
Splash.width,
Splash.height,
Splash.mono_bits, Splash.color_bits, Splash.mask_bits,
FALSE);
XP_ASSERT(splash_icon.pixmap);
m_splashlabel = XtVaCreateManagedWidget("splashPixmap",
xmLabelWidgetClass,
m_rc,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, splash_icon.pixmap,
NULL);
m_statuslabel = XtVaCreateManagedWidget("splashStatus",
xmLabelWidgetClass,
m_rc,
NULL);
XtAddEventHandler(m_splashlabel, ExposureMask, False, splashExpose_eh, this);
}
XFE_Splash::~XFE_Splash()
{
if(m_eventqueue)
PR_DestroyEventQueue(m_eventqueue);
if (m_eventmonitor)
PR_DestroyMonitor(m_eventmonitor);
fe_DisposeColormap(m_context);
XP_FREE(CONTEXT_DATA(m_context));
XP_FREE(m_context);
}
void
XFE_Splash::splashExpose()
{
PR_EnterMonitor(m_exposemonitor);
PR_Notify(m_exposemonitor);
PR_ExitMonitor(m_exposemonitor);
XtRemoveEventHandler(m_splashlabel, ExposureMask, False, splashExpose_eh, this);
}
void
XFE_Splash::splashExpose_eh(Widget, XtPointer closure, XEvent *, Boolean *)
{
XFE_Splash *splash = (XFE_Splash*)closure;
splash->splashExpose();
}
/* Caller must wrap calls to show() in PR_XLock and PR_XUnlock. */
void
XFE_Splash::show()
{
Dimension height_of_splash, width_of_splash;
Dimension height_of_screen = HeightOfScreen(XtScreen(m_shell)),
width_of_screen = WidthOfScreen(XtScreen(m_shell));
XtRealizeWidget(m_shell);
XtVaGetValues(m_shell,
XmNwidth, &width_of_splash,
XmNheight, &height_of_splash,
NULL);
XtVaSetValues(m_shell,
XmNx, width_of_screen / 2 - width_of_splash / 2,
XmNy, height_of_screen / 2 - height_of_splash / 2,
NULL);
XtPopup(m_shell, XtGrabNone);
XSync(XtDisplay(m_shell), False);
}
/* Caller must wrap calls to hide() in PR_XLock and PR_XUnlock. */
void
XFE_Splash::hide()
{
XtPopdown(m_shell);
XSync(XtDisplay(m_shell), False);
}
void
XFE_Splash::waitForExpose()
{
PR_EnterMonitor(m_exposemonitor);
PR_Wait(m_exposemonitor, PR_INTERVAL_NO_TIMEOUT);
PR_ExitMonitor(m_exposemonitor);
PR_DestroyMonitor(m_exposemonitor);
}
void
XFE_Splash::setStatus(char *text)
{
XmString xmstr = XmStringCreate(text, XmFONTLIST_DEFAULT_TAG);
XtVaSetValues(m_statuslabel,
XmNlabelString, xmstr,
NULL);
XmStringFree(xmstr);
XSync(XtDisplay(m_statuslabel), False);
PR_EnterMonitor(m_eventmonitor);
PR_Notify(m_eventmonitor);
PR_ExitMonitor(m_eventmonitor);
}
void
XFE_Splash::update_text_handler(XFE_SplashEvent *event)
{
XP_ASSERT(event->text);
event->splash->setStatus(event->text);
}
void
XFE_Splash::update_text_destructor(XFE_SplashEvent *event)
{
XP_FREE(event);
}
PRThread *
XFE_Splash::getThread()
{
return m_thread;
}
PREventQueue *
XFE_Splash::getEventQueue()
{
return m_eventqueue;
}
PRMonitor *
XFE_Splash::getEventMonitor()
{
return m_eventmonitor;
}
PRMonitor *
XFE_Splash::getStopMonitor()
{
return m_stopmonitor;
}
void
XFE_Splash::splashThreadProc()
{
PREvent * event;
for (;;)
{
PR_EnterMonitor(m_stopmonitor);
if (m_done)
{
PR_ExitMonitor(m_stopmonitor);
return;
}
else
{
PR_ExitMonitor(m_stopmonitor);
}
PR_XLock();
XtInputMask pending = XtAppPending(fe_XtAppContext);
/* if there was a pending X event, handle it now */
if (pending)
XtAppProcessEvent(fe_XtAppContext, pending);
PR_EnterMonitor(m_eventmonitor);
event = PR_GetEvent(m_eventqueue);
PR_ExitMonitor(m_eventmonitor);
/* if we got an nspr event (telling us to update our status) do it */
if (event)
{
PR_HandleEvent(event);
PR_DestroyEvent(event);
}
PR_XUnlock();
}
}
void
XFE_Splash::splashThreadProc(void *a)
{
XFE_Splash *splash = (XFE_Splash*)a;
PRMonitor *monitor = splash->getStopMonitor();
splash->splashThreadProc();
delete splash;
PR_EnterMonitor(monitor);
PR_Notify(monitor);
PR_ExitMonitor(monitor);
D(printf ("exiting the splash thread\n");)
}
void
fe_splashStart(Widget toplevel)
{
XP_ASSERT(!xfe_splash);
xfe_splash = new XFE_Splash(toplevel);
PR_XLock();
xfe_splash->show();
PR_XUnlock();
xfe_splash->waitForExpose();
}
void
fe_splashUpdateText(char *text)
{
XP_ASSERT(xfe_splash);
D(printf ("fe_splashUpdateText('%s')\n", text);)
PRMonitor *monitor = xfe_splash->getEventMonitor();
XFE_SplashEvent *event = XP_NEW_ZAP(XFE_SplashEvent);
PR_InitEvent(&event->event, NULL,
(PRHandleEventProc)XFE_Splash::update_text_handler,
(PRDestroyEventProc)XFE_Splash::update_text_destructor);
event->text = text;
event->splash = xfe_splash;
PR_PostEvent(xfe_splash->getEventQueue(), &event->event);
if (monitor)
{
/* wake up the processing routine */
PR_EnterMonitor(monitor);
PR_Notify(monitor);
PR_ExitMonitor(monitor);
/* now we wait until it actually happens. */
PR_EnterMonitor(monitor);
PR_Wait(monitor, PR_INTERVAL_NO_TIMEOUT);
PR_ExitMonitor(monitor);
}
}
void
fe_splashStop(void)
{
XP_ASSERT(xfe_splash);
D(printf ("fe_splashStop()\n");)
PRMonitor *monitor = xfe_splash->getStopMonitor();
XP_ASSERT(monitor);
/* first we tell the splash screen to stop */
PR_EnterMonitor(monitor);
xfe_splash->m_done = 1;
PR_ExitMonitor(monitor);
/* now we wait until it actually happens. */
PR_EnterMonitor(monitor);
PR_Wait(monitor, PR_INTERVAL_NO_TIMEOUT);
PR_ExitMonitor(monitor);
PR_DestroyMonitor(monitor);
}