home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / Splash.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  9.4 KB  |  414 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* 
  19.    Splash.cpp -- class for dealing with the unix splash screen.
  20.    Created: Chris Toshok <toshok@netscape.com>, 21-Dec-1996.
  21.  */
  22.  
  23.  
  24.  
  25. #include "Splash.h"
  26. #include "DisplayFactory.h"
  27. #include "xpassert.h"
  28. #include "prefapi.h"
  29. #include <Xm/MenuShell.h>
  30. #include <Xm/RowColumn.h>
  31. #include <Xm/Label.h>
  32.  
  33. #ifdef NSPR20
  34. #include "private/prpriv.h" /* For PR_NewNamedMonitor */
  35. #else
  36. #define PR_INTERVAL_NO_TIMEOUT    LL_MAXINT
  37. #endif
  38.  
  39. #ifdef DEBUG_username
  40. #define D(x) x
  41. #else
  42. #define D(x)
  43. #endif
  44.  
  45. struct XFE_SplashEvent {
  46.     PREvent    event;    /* the PREvent structure */
  47.     char        *text;  /* the new text to be displayed. */
  48.     XFE_Splash    *splash; /* the splash screen object we're going to muck with. */
  49. };
  50.  
  51. static XFE_Splash *xfe_splash = NULL;
  52.  
  53. extern fe_icon_data Splash;
  54. extern "C" Colormap fe_getColormap(fe_colormap *colormap);
  55.  
  56. fe_icon XFE_Splash::splash_icon = { 0 };
  57.  
  58. XFE_Splash::XFE_Splash(Widget toplevel)
  59. {
  60.   Arg av[10];
  61.   int ac;
  62.   fe_colormap *cmap = XFE_DisplayFactory::theFactory()->getSharedColormap();
  63.  
  64.   m_exposemonitor = PR_NewNamedMonitor("expose-monitor");
  65.   m_eventmonitor = PR_NewNamedMonitor("event-monitor");
  66.   m_stopmonitor = PR_NewNamedMonitor("stop-monitor");
  67.   m_done = 0;
  68.  
  69.   m_context = XP_NewContext();
  70.   m_context->fe.data = XP_NEW_ZAP(fe_ContextData);
  71.  
  72. #ifdef NSPR20
  73.   m_thread = PR_CreateThread(PR_USER_THREAD, splashThreadProc, this,
  74.                              PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
  75.                              0);        /* default stack size */
  76. #else
  77.   m_thread = PR_CreateThread("splash-thread", 24, 0);
  78. #endif
  79.   m_eventqueue = PR_CreateEventQueue("splash-events", m_thread);
  80.  
  81.   ac = 0;
  82.   XtSetArg(av[ac], XmNwidth, 1); ac++;
  83.   XtSetArg(av[ac], XmNheight, 1); ac++;
  84.   XtSetArg(av[ac], XmNcolormap, fe_getColormap(cmap)); ac++;
  85.   XtSetArg(av[ac], XmNvisual, XFE_DisplayFactory::theFactory()->getVisual()); ac++;
  86.   XtSetArg(av[ac], XmNdepth, XFE_DisplayFactory::theFactory()->getVisualDepth()); ac++;
  87.  
  88.   m_shell = XtCreatePopupShell("splashShell",
  89.                    xmMenuShellWidgetClass,
  90.                    toplevel,
  91.                    av, ac);
  92.  
  93.   m_rc = XtVaCreateManagedWidget("splashRC",
  94.                  xmRowColumnWidgetClass,
  95.                  m_shell,
  96.                  XmNspacing, 0,
  97.                  NULL);
  98.  
  99.   CONTEXT_WIDGET(m_context) = m_shell;
  100.   CONTEXT_DATA (m_context)->colormap = cmap;
  101.  
  102.   setBaseWidget(m_shell);
  103.  
  104.   XtGetApplicationResources (m_widget,
  105.                  (XtPointer) CONTEXT_DATA (m_context),
  106.                  fe_Resources, fe_ResourcesSize,
  107.                  0, 0);
  108.  
  109.   fe_InitIconColors(m_context);
  110.  
  111.   fe_init_image_callbacks(m_context);
  112.  
  113.   fe_InitColormap (m_context);
  114.  
  115.   PREF_AlterSplashIcon(&Splash);
  116.  
  117.   fe_NewMakeIcon(m_shell,
  118.          BlackPixelOfScreen(XtScreen(m_shell)), //XXX hack... doesn't really matter though.
  119.          BlackPixelOfScreen(XtScreen(m_shell)), //XXX hack... doesn't really matter though.
  120.          &splash_icon,
  121.          NULL,
  122.          Splash.width,
  123.          Splash.height,
  124.          Splash.mono_bits, Splash.color_bits, Splash.mask_bits,
  125.          FALSE);
  126.   
  127.     XP_ASSERT(splash_icon.pixmap);
  128.  
  129.     m_splashlabel = XtVaCreateManagedWidget("splashPixmap",
  130.                                             xmLabelWidgetClass,
  131.                                             m_rc,
  132.                                             XmNlabelType, XmPIXMAP,
  133.                                             XmNlabelPixmap, splash_icon.pixmap,
  134.                                             NULL);
  135.     m_statuslabel = XtVaCreateManagedWidget("splashStatus",
  136.                                             xmLabelWidgetClass,
  137.                                             m_rc,
  138.                                             NULL);
  139.  
  140.     XtAddEventHandler(m_splashlabel, ExposureMask, False, splashExpose_eh, this);
  141.  
  142. #ifndef NSPR20
  143.     PR_Start(m_thread, splashThreadProc, this, NULL);
  144. #endif
  145. }
  146.  
  147. XFE_Splash::~XFE_Splash()
  148. {
  149.     if(m_eventqueue)
  150.         PR_DestroyEventQueue(m_eventqueue);
  151.     if (m_eventmonitor)
  152.         PR_DestroyMonitor(m_eventmonitor);
  153.  
  154.     fe_DisposeColormap(m_context);
  155.     XP_FREE(CONTEXT_DATA(m_context));
  156.     XP_FREE(m_context);
  157. }
  158.  
  159. void
  160. XFE_Splash::splashExpose()
  161. {
  162.     PR_EnterMonitor(m_exposemonitor);
  163.     PR_Notify(m_exposemonitor);
  164.     PR_ExitMonitor(m_exposemonitor);
  165.  
  166.     XtRemoveEventHandler(m_splashlabel, ExposureMask, False, splashExpose_eh, this);
  167. }
  168.  
  169. void
  170. XFE_Splash::splashExpose_eh(Widget, XtPointer closure, XEvent *, Boolean *)
  171. {
  172.     XFE_Splash *splash = (XFE_Splash*)closure;
  173.  
  174.     splash->splashExpose();
  175. }
  176.  
  177. /* Caller must wrap calls to show() in PR_XLock and PR_XUnlock. */
  178. void
  179. XFE_Splash::show()
  180. {
  181.     Dimension height_of_splash, width_of_splash;
  182.     Dimension height_of_screen = HeightOfScreen(XtScreen(m_shell)),
  183.         width_of_screen = WidthOfScreen(XtScreen(m_shell));
  184.  
  185.     XtRealizeWidget(m_shell);
  186.  
  187.     XtVaGetValues(m_shell,
  188.                   XmNwidth, &width_of_splash,
  189.                   XmNheight, &height_of_splash,
  190.                   NULL);
  191.  
  192.     XtVaSetValues(m_shell,
  193.                   XmNx, width_of_screen / 2 - width_of_splash / 2,
  194.                   XmNy, height_of_screen / 2 - height_of_splash / 2,
  195.                   NULL);
  196.  
  197.     XtPopup(m_shell, XtGrabNone);
  198.  
  199.     XSync(XtDisplay(m_shell), False);
  200. }
  201.  
  202. /* Caller must wrap calls to hide() in PR_XLock and PR_XUnlock. */
  203. void
  204. XFE_Splash::hide()
  205. {
  206.     XtPopdown(m_shell);
  207.  
  208.     XSync(XtDisplay(m_shell), False);
  209. }
  210.  
  211. void
  212. XFE_Splash::waitForExpose()
  213. {
  214.     PR_EnterMonitor(m_exposemonitor);
  215.     PR_Wait(m_exposemonitor, PR_INTERVAL_NO_TIMEOUT);
  216.     PR_ExitMonitor(m_exposemonitor);
  217.  
  218.     PR_DestroyMonitor(m_exposemonitor);
  219. }
  220.  
  221. void
  222. XFE_Splash::setStatus(char *text)
  223. {
  224.     XmString xmstr = XmStringCreate(text, XmFONTLIST_DEFAULT_TAG);
  225.  
  226.     XtVaSetValues(m_statuslabel,
  227.                   XmNlabelString, xmstr,
  228.                   NULL);
  229.  
  230.     XmStringFree(xmstr);
  231.  
  232.     XSync(XtDisplay(m_statuslabel), False);
  233.  
  234.     PR_EnterMonitor(m_eventmonitor);
  235.     PR_Notify(m_eventmonitor);
  236.     PR_ExitMonitor(m_eventmonitor);
  237. }
  238.  
  239. void
  240. XFE_Splash::update_text_handler(XFE_SplashEvent *event)
  241. {
  242.     XP_ASSERT(event->text);
  243.  
  244.     event->splash->setStatus(event->text);
  245. }
  246.  
  247. void
  248. XFE_Splash::update_text_destructor(XFE_SplashEvent *event)
  249. {
  250.     XP_FREE(event);
  251. }
  252.  
  253. PRThread *
  254. XFE_Splash::getThread()
  255. {
  256.     return m_thread;
  257. }
  258.  
  259. PREventQueue *
  260. XFE_Splash::getEventQueue()
  261. {
  262.     return m_eventqueue;
  263. }
  264.  
  265. PRMonitor *
  266. XFE_Splash::getEventMonitor()
  267. {
  268.     return m_eventmonitor;
  269. }
  270.  
  271. PRMonitor *
  272. XFE_Splash::getStopMonitor()
  273. {
  274.     return m_stopmonitor;
  275. }
  276.  
  277. void
  278. XFE_Splash::splashThreadProc()
  279. {
  280.     PREvent      * event;
  281.  
  282.     for (;;) 
  283.         {
  284.             PR_EnterMonitor(m_stopmonitor);
  285.             if (m_done)
  286.                 {
  287.                     PR_ExitMonitor(m_stopmonitor);
  288.  
  289.                     return;
  290.                 }
  291.             else
  292.                 {
  293.                     PR_ExitMonitor(m_stopmonitor);
  294.                 }
  295.  
  296.             PR_XLock();
  297.  
  298.             XtInputMask pending = XtAppPending(fe_XtAppContext);
  299.  
  300.             /* if there was a pending X event, handle it now */
  301.             if (pending)
  302.                 XtAppProcessEvent(fe_XtAppContext, pending);
  303.       
  304.             PR_EnterMonitor(m_eventmonitor);
  305.             event = PR_GetEvent(m_eventqueue);
  306.             PR_ExitMonitor(m_eventmonitor);
  307.       
  308.             /* if we got an nspr event (telling us to update our status) do it */
  309.             if (event)
  310.                 {
  311.                     PR_HandleEvent(event);
  312.                     PR_DestroyEvent(event);
  313.                 }
  314.       
  315.             PR_XUnlock();
  316.         }
  317. }
  318.  
  319. void
  320. #ifndef NSPR20
  321. XFE_Splash::splashThreadProc(void *a, void *)
  322. #else
  323. XFE_Splash::splashThreadProc(void *a)
  324. #endif /* NSPR20 */
  325. {
  326.     XFE_Splash *splash = (XFE_Splash*)a;
  327.     PRMonitor *monitor = splash->getStopMonitor();
  328.  
  329.     splash->splashThreadProc();
  330.  
  331.     delete splash;
  332.  
  333.     PR_EnterMonitor(monitor);
  334.     PR_Notify(monitor);
  335.     PR_ExitMonitor(monitor);
  336.  
  337.     D(printf ("exiting the splash thread\n");)
  338.  
  339. #ifndef NSPR20
  340.     PR_Exit();
  341. #endif
  342. }
  343.  
  344. void
  345. fe_splashStart(Widget toplevel)
  346. {
  347.     XP_ASSERT(!xfe_splash);
  348.  
  349.     xfe_splash = new XFE_Splash(toplevel);
  350.  
  351.     PR_XLock();
  352.  
  353.     xfe_splash->show();
  354.  
  355.     PR_XUnlock();
  356.  
  357.     xfe_splash->waitForExpose();
  358. }
  359.  
  360. void
  361. fe_splashUpdateText(char *text)
  362. {
  363.     XP_ASSERT(xfe_splash);
  364.   
  365.     D(printf ("fe_splashUpdateText('%s')\n", text);)
  366.  
  367.     PRMonitor *monitor = xfe_splash->getEventMonitor();
  368.     XFE_SplashEvent *event = XP_NEW_ZAP(XFE_SplashEvent);
  369.  
  370.     PR_InitEvent(&event->event, NULL,
  371.                  (PRHandleEventProc)XFE_Splash::update_text_handler,
  372.                  (PRDestroyEventProc)XFE_Splash::update_text_destructor);
  373.  
  374.     event->text = text;
  375.     event->splash = xfe_splash;
  376.     PR_PostEvent(xfe_splash->getEventQueue(), &event->event);
  377.     if (monitor)
  378.     {
  379.         /* wake up the processing routine */
  380.         PR_EnterMonitor(monitor);
  381.         PR_Notify(monitor);
  382.         PR_ExitMonitor(monitor);
  383.  
  384.         /* now we wait until it actually happens. */
  385.         PR_EnterMonitor(monitor);
  386.         PR_Wait(monitor, PR_INTERVAL_NO_TIMEOUT);
  387.         PR_ExitMonitor(monitor);
  388.     }
  389. }
  390.  
  391. void
  392. fe_splashStop(void)
  393. {
  394.     XP_ASSERT(xfe_splash);
  395.   
  396.     D(printf ("fe_splashStop()\n");)
  397.  
  398.     PRMonitor *monitor = xfe_splash->getStopMonitor();
  399.  
  400.     XP_ASSERT(monitor);
  401.  
  402.     /* first we tell the splash screen to stop */
  403.     PR_EnterMonitor(monitor);
  404.     xfe_splash->m_done = 1;
  405.     PR_ExitMonitor(monitor);
  406.  
  407.     /* now we wait until it actually happens. */
  408.     PR_EnterMonitor(monitor);
  409.     PR_Wait(monitor, PR_INTERVAL_NO_TIMEOUT);
  410.     PR_ExitMonitor(monitor);
  411.  
  412.     PR_DestroyMonitor(monitor);
  413. }
  414.