Bugzilla Bug 111508 [xlib] Xlib timer code is scary

by Roland.Mainz@informatik.med.uni-giessen.de (xlib peer)
r=timeless


git-svn-id: svn://10.0.0.236/trunk@108892 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
timeless%mac.com 2001-11-26 10:18:14 +00:00
parent 535b6f20f2
commit 11936d43d6
13 changed files with 294 additions and 1018 deletions

View File

@ -17,6 +17,7 @@
# Rights Reserved.
#
# Contributor(s):
# Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
#
DEPTH = ../../..
@ -30,7 +31,7 @@ MODULE = widget
LIBRARY_NAME = widget_xlib
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
MODULE_NAME = nsWidgetXLIBModule
MODULE_NAME = nsWidgetXLibModule
REQUIRES = xpcom \
string \
appshell \
@ -50,8 +51,6 @@ REQUIRES = xpcom \
gfx2 \
$(NULL)
DIRS = window_service
CPPSRCS = \
nsAppShell.cpp \
nsBidiKeyboard.cpp \

View File

@ -24,7 +24,7 @@
* Ken Faulkner <faulkner@igelaus.com.au>
* Tony Tsui <tony@igelaus.com.au>
* Caspian Maclean <caspian@igelaus.com.au>
* Roland.Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -63,26 +63,16 @@
#include "nsIDragSessionXlib.h"
#include "nsITimer.h"
#include "nsIXlibWindowService.h"
#include "xlibrgb.h"
#define CHAR_BUF_SIZE 40
#define CHAR_BUF_SIZE 80
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
static NS_DEFINE_CID(kCmdLineServiceCID, NS_COMMANDLINE_SERVICE_CID);
static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
static NS_DEFINE_IID(kWindowServiceCID,NS_XLIB_WINDOW_SERVICE_CID);
static NS_DEFINE_IID(kWindowServiceIID,NS_XLIB_WINDOW_SERVICE_IID);
// // this is so that we can get the timers in the base. most widget
// // toolkits do this through some set of globals. not here though. we
// // don't have that luxury
extern "C" int NS_TimeToNextTimeout(struct timeval *);
extern "C" void NS_ProcessTimeouts(void);
/* nsAppShell static members */
Display *nsAppShell::mDisplay = nsnull;
XlibRgbHandle *nsAppShell::mXlib_rgb_handle = nsnull;
XtAppContext nsAppShell::mAppContext;
@ -97,6 +87,9 @@ PRPackedBool nsAppShell::mCtrlDown = PR_FALSE;
PRPackedBool nsAppShell::mMetaDown = PR_FALSE;
PRPackedBool nsAppShell::DieAppShellDie = PR_FALSE;
static PLHashTable *sQueueHashTable = nsnull;
static PLHashTable *sCountHashTable = nsnull;
static nsVoidArray *sEventQueueList = nsnull;
// For debugging.
@ -139,104 +132,6 @@ static const char *event_names[] =
"MappingNotify"
};
static nsXlibTimeToNextTimeoutFunc GetTimeToNextTimeoutFunc(void)
{
static nsXlibTimeToNextTimeoutFunc sFunc = nsnull;
if (!sFunc)
{
nsIXlibWindowService * xlibWindowService = nsnull;
nsresult rv = nsServiceManager::GetService(kWindowServiceCID,
kWindowServiceIID,
(nsISupports **)&xlibWindowService);
NS_ASSERTION(NS_SUCCEEDED(rv),"Couldn't obtain window service.");
if (NS_SUCCEEDED(rv) && nsnull != xlibWindowService)
{
xlibWindowService->GetTimeToNextTimeoutFunc(&sFunc);
#ifdef DEBUG_ramiro
printf("Time to next timeout func is null - for now.\n");
static int once = 1;
if (once && sFunc)
{
once = 0;
printf("YES! Time to next timeout func is good.\n");
}
#endif
NS_RELEASE(xlibWindowService);
}
}
return sFunc;
}
static nsXlibProcessTimeoutsProc GetProcessTimeoutsProc(void)
{
static nsXlibProcessTimeoutsProc sProc = nsnull;
if (!sProc)
{
nsIXlibWindowService * xlibWindowService = nsnull;
nsresult rv = nsServiceManager::GetService(kWindowServiceCID,
kWindowServiceIID,
(nsISupports **)&xlibWindowService);
NS_ASSERTION(NS_SUCCEEDED(rv),"Couldn't obtain window service.");
if (NS_SUCCEEDED(rv) && nsnull != xlibWindowService)
{
xlibWindowService->GetProcessTimeoutsProc(&sProc);
#ifdef DEBUG_ramiro
printf("Process timeout proc is null - for now.\n");
static int once = 1;
if (once && sProc)
{
once = 0;
printf("YES! Process timeout proc is good.\n");
}
#endif
NS_RELEASE(xlibWindowService);
}
}
return sProc;
}
static int CallTimeToNextTimeoutFunc(struct timeval * aTimeval)
{
nsXlibTimeToNextTimeoutFunc func = GetTimeToNextTimeoutFunc();
if (func)
{
return (*func)(aTimeval);
}
return 0;
}
static void CallProcessTimeoutsProc(XtAppContext app_context)
{
nsXlibProcessTimeoutsProc proc = GetProcessTimeoutsProc();
if (proc)
{
(*proc)(app_context);
}
}
#define COMPARE_FLAG1( a,b) ((b)[0]=='-' && !strcmp((a), &(b)[1]))
#define COMPARE_FLAG2( a,b) ((b)[0]=='-' && (b)[1]=='-' && !strcmp((a), &(b)[2]))
#define COMPARE_FLAG12(a,b) ((b)[0]=='-' && !strcmp((a), (b)[1]=='-'?&(b)[2]:&(b)[1]))
@ -257,8 +152,10 @@ nsAppShell::nsAppShell()
NS_INIT_ISUPPORTS();
mDispatchListener = 0;
if (!sEventQueueList)
sEventQueueList = new nsVoidArray();
mEventQueue = nsnull;
xlib_fd = -1;
}
NS_IMPL_ISUPPORTS1(nsAppShell, nsIAppShell)
@ -374,70 +271,55 @@ NS_METHOD nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListener)
return NS_OK;
}
NS_METHOD nsAppShell::Spinup()
NS_IMETHODIMP nsAppShell::Spinup()
{
nsresult rv;
nsresult rv = NS_OK;
NS_ADDREF_THIS();
#ifdef DEBUG_APPSHELL
printf("nsAppShell::Spinup()\n");
#endif
/* Get the event queue service */
nsCOMPtr<nsIEventQueueService> eventQService = do_GetService(kEventQueueServiceCID, &rv);
// get the event queue service
rv = nsServiceManager::GetService(kEventQueueServiceCID,
kIEventQueueServiceIID,
(nsISupports **) &mEventQueueService);
if (NS_FAILED(rv)) {
NS_WARNING("Could not obtain event queue service");
return rv;
}
rv = mEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, &mEventQueue); // If a queue already present use it.
if (mEventQueue)
return NS_OK;
// Create the event queue for the thread
rv = mEventQueueService->CreateThreadEventQueue();
if (NS_FAILED(rv)) {
NS_WARNING("Could not create the thread event queue");
return rv;
}
//Get the event queue for the thread
rv = mEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, &mEventQueue);
if (NS_FAILED(rv)) {
NS_WARNING("Could not obtain the thread event queue");
/* Get the event queue for the thread.*/
rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue));
/* If we got an event queue, use it. */
if (!mEventQueue) {
/* otherwise create a new event queue for the thread */
rv = eventQService->CreateThreadEventQueue();
if (NS_FAILED(rv)) {
NS_WARNING("Could not create the thread event queue");
return rv;
}
return NS_OK;
}
/* Ask again nicely for the event queue now that we have created one. */
rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue));
}
ListenToEventQueue(mEventQueue, PR_TRUE);
return rv;
}
/* XtTimerCallbackProc!! */
static
void CallProcessTimeoutsXtProc( XtPointer dummy1, XtIntervalId *dummy2 )
{
XtAppContext *app_context = (XtAppContext *) dummy1;
CallProcessTimeoutsProc(*app_context);
// Flush the nsWindow's drawing queue
nsWindow::UpdateIdle(nsnull);
// reset timer
#define CALLPROCESSTIMEOUTSVAL (10)
XtAppAddTimeOut(*app_context,
CALLPROCESSTIMEOUTSVAL,
CallProcessTimeoutsXtProc,
app_context);
}
/* XtInputCallbackProc */
/* must be a |XtInputCallbackProc| !! */
PR_BEGIN_EXTERN_C
static
void HandleQueueXtProc(XtPointer ptr, int *source_fd, XtInputId* id)
{
nsIEventQueue *queue = (nsIEventQueue *)ptr;
queue->ProcessPendingEvents();
}
PR_END_EXTERN_C
nsresult nsAppShell::Run()
{
nsresult rv = NS_OK;
XtInputMask mask;
if (mEventQueue == nsnull)
Spinup();
@ -445,112 +327,157 @@ nsresult nsAppShell::Run()
NS_WARNING("Cannot initialize the Event Queue");
return NS_ERROR_NOT_INITIALIZED;
}
// set up our fds callbacks
XtAppAddInput(mAppContext,
mEventQueue->GetEventQueueSelectFD(),
(XtPointer)(long)(XtInputReadMask),
HandleQueueXtProc,
(XtPointer)mEventQueue);
// set initial timer
XtAppAddTimeOut(mAppContext,
CALLPROCESSTIMEOUTSVAL,
CallProcessTimeoutsXtProc,
&mAppContext);
// process events.
XEvent xevent;
/* process events. */
while (!DieAppShellDie)
{
XEvent event;
XtAppNextEvent(mAppContext, &event);
if (XtDispatchEvent(&event) == False)
DispatchXEvent(&event);
XtAppNextEvent(mAppContext, &xevent);
if (XtDispatchEvent(&xevent) == False)
DispatchXEvent(&xevent);
if (XEventsQueued(mDisplay, QueuedAlready) == 0)
{
/* Flush the nsWindow's drawing queue */
nsWindow::UpdateIdle(nsnull);
}
}
DieAppShellDie = PR_FALSE;
Spindown();
return rv;
return NS_OK;
}
NS_METHOD nsAppShell::Spindown()
{
NS_IF_RELEASE(mEventQueueService);
Release();
if (mEventQueue) {
ListenToEventQueue(mEventQueue, PR_FALSE);
mEventQueue->ProcessPendingEvents();
NS_IF_RELEASE(mEventQueue);
mEventQueue = nsnull;
}
return NS_OK;
}
#define NUMBER_HASH_KEY(_num) ((PLHashNumber) _num)
static PLHashNumber
IntHashKey(PRInt32 key)
{
return NUMBER_HASH_KEY(key);
}
// wrapper so we can call a macro
PR_BEGIN_EXTERN_C
static unsigned long getNextRequest (void *aClosure) {
return XNextRequest(nsAppShell::mDisplay);
}
PR_END_EXTERN_C
NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue *aQueue,
PRBool aListen)
{
#ifdef DEBUG_APPSHELL
printf("ListenToEventQueue(%p, %d) this=%p\n", aQueue, aListen, this);
#endif
if (!sQueueHashTable) {
sQueueHashTable = PL_NewHashTable(3, (PLHashFunction)IntHashKey,
PL_CompareValues, PL_CompareValues, 0, 0);
}
if (!sCountHashTable) {
sCountHashTable = PL_NewHashTable(3, (PLHashFunction)IntHashKey,
PL_CompareValues, PL_CompareValues, 0, 0);
}
int queue_fd = aQueue->GetEventQueueSelectFD();
void *key = aQueue;
if (aListen) {
/* Add listener -
* but only if we arn't already in the table... */
if (!PL_HashTableLookup(sQueueHashTable, key)) {
int tag;
/* set up our fds callbacks */
tag = (int)XtAppAddInput(mAppContext,
queue_fd,
(XtPointer)(long)(XtInputReadMask),
HandleQueueXtProc,
(XtPointer)mEventQueue);
/* This hack would not be neccesary if we would have a hashtable function
* which returns success/failure in a seperate var ...
*/
#define NEVER_BE_ZERO_MAGIC (54321)
tag += NEVER_BE_ZERO_MAGIC; /* be sure that |tag| is _never_ 0 */
NS_ASSERTION(tag!=0, "tag is 0 while adding");
if (tag) {
PL_HashTableAdd(sQueueHashTable, key, (void *)tag);
}
PLEventQueue *plqueue;
aQueue->GetPLEventQueue(&plqueue);
PL_RegisterEventIDFunc(plqueue, getNextRequest, 0);
sEventQueueList->AppendElement(plqueue);
}
} else {
/* Remove listener... */
PLEventQueue *plqueue;
aQueue->GetPLEventQueue(&plqueue);
PL_UnregisterEventIDFunc(plqueue);
sEventQueueList->RemoveElement(plqueue);
int tag = int(PL_HashTableLookup(sQueueHashTable, key));
if (tag) {
tag -= NEVER_BE_ZERO_MAGIC;
XtRemoveInput((XtInputId)tag);
PL_HashTableRemove(sQueueHashTable, key);
}
}
return NS_OK;
}
/* Does nothing. Used by xp code with non-gtk expectations.
* this method will be removed once xp eventloops are working.
*/
NS_METHOD
nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent)
{
fd_set select_set;
int select_retval;
int max_fd;
struct timeval DelayTime;
XEvent *event;
int queue_fd = mEventQueue->GetEventQueueSelectFD();
if (xlib_fd == -1)
xlib_fd = XConnectionNumber(mDisplay);
if (xlib_fd >= queue_fd) {
max_fd = xlib_fd + 1;
} else {
max_fd = queue_fd + 1;
}
FD_ZERO(&select_set);
FD_SET(queue_fd, &select_set);
FD_SET(xlib_fd, &select_set);
DelayTime.tv_sec = 0;
DelayTime.tv_usec = 100;
select_retval = select(max_fd, &select_set, nsnull, nsnull, &DelayTime);
if (select_retval == -1)
return NS_ERROR_FAILURE;
if (XPending(mDisplay)) {
event = (XEvent *)malloc(sizeof(XEvent));
XNextEvent(mDisplay, event);
aRealEvent = PR_TRUE;
aEvent = event;
return NS_OK;
}
aRealEvent = PR_FALSE;
aEvent = nsnull;
aEvent = nsnull;
return NS_OK;
}
nsresult nsAppShell::DispatchNativeEvent(PRBool aRealEvent, void *aEvent)
{
nsresult rv;
XEvent *event;
if (mEventQueue == nsnull) {
XEvent xevent;
if (!mEventQueue)
return NS_ERROR_NOT_INITIALIZED;
#if 1
/* gisburn: Why do we have to call this explicitly ?
* I have registered a callback via XtAddAppInput() above...
*/
mEventQueue->ProcessPendingEvents();
#endif
XtAppNextEvent(mAppContext, &xevent);
if (XtDispatchEvent(&xevent) == False)
DispatchXEvent(&xevent);
if (XEventsQueued(mDisplay, QueuedAlready) == 0)
{
/* Flush the nsWindow's drawing queue */
nsWindow::UpdateIdle(nsnull);
}
rv = mEventQueue->ProcessPendingEvents();
if (aRealEvent) {
event = (XEvent *)aEvent;
DispatchXEvent(event);
free(event);
}
CallProcessTimeoutsProc(mAppContext);
nsWindow::UpdateIdle(nsnull);
return rv;
return NS_OK;
}
NS_METHOD nsAppShell::Exit()
@ -574,7 +501,6 @@ nsAppShell::DispatchXEvent(XEvent *event)
nsWidget *widget;
widget = nsWidget::GetWidgetForWindow(event->xany.window);
// did someone pass us an x event for a window we don't own?
// bad! bad!
if (widget == nsnull)
@ -885,8 +811,9 @@ PRUint32 nsConvertCharCodeToUnicode(XKeyEvent* xkey)
unsigned char string_buf[CHAR_BUF_SIZE];
int len = 0;
len = XLookupString(xkey, (char *)string_buf, CHAR_BUF_SIZE, &keysym, &compose);
if (0 == len) return 0;
len = XLookupString(xkey, (char *)string_buf, CHAR_BUF_SIZE-1, &keysym, &compose);
if (0 == len)
return 0;
if (xkey->state & ControlMask) {
if (xkey->state & ShiftMask) {
@ -909,12 +836,12 @@ nsAppShell::HandleKeyPressEvent(XEvent *event, nsWidget *aWidget)
{
char string_buf[CHAR_BUF_SIZE];
int len = 0;
Window focusWindow = 0;
Window focusWindow = None;
nsWidget *focusWidget = 0;
// figure out where the real focus should go...
focusWindow = nsWidget::GetFocusWindow();
if (focusWindow) {
if (focusWindow != None) {
focusWidget = nsWidget::GetWidgetForWindow(focusWindow);
}
@ -961,7 +888,7 @@ nsAppShell::HandleKeyPressEvent(XEvent *event, nsWidget *aWidget)
XComposeStatus compose;
len = XLookupString(&event->xkey, string_buf, CHAR_BUF_SIZE, &keysym, &compose);
len = XLookupString(&event->xkey, string_buf, CHAR_BUF_SIZE-1, &keysym, &compose);
string_buf[len] = '\0';
keyEvent.keyCode = nsKeyCode::ConvertKeySymToVirtualKey(keysym);

View File

@ -48,7 +48,7 @@
class nsAppShell : public nsIAppShell
{
public:
public:
nsAppShell();
virtual ~nsAppShell();
@ -60,10 +60,9 @@ class nsAppShell : public nsIAppShell
virtual nsresult Run();
NS_IMETHOD Spinup();
NS_IMETHOD Spindown();
NS_IMETHOD ListenToEventQueue(nsIEventQueue *aQueue, PRBool aListen)
{ return NS_OK; }
NS_IMETHOD ListenToEventQueue(nsIEventQueue *aQueue, PRBool aListen);
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void *aEvent);
NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener);
NS_IMETHOD Exit();
@ -77,8 +76,8 @@ class nsAppShell : public nsIAppShell
static Display *mDisplay;
private:
static XlibRgbHandle *mXlib_rgb_handle;
int xlib_fd;
nsDispatchListener* mDispatchListener;
nsDispatchListener* mDispatchListener;
static void HandleButtonEvent(XEvent *event, nsWidget *aWidget);
static void HandleMotionNotifyEvent(XEvent *event, nsWidget *aWidget);
static void HandleExposeEvent(XEvent *event, nsWidget *aWidget);
@ -111,8 +110,7 @@ class nsAppShell : public nsIAppShell
static PRPackedBool DieAppShellDie;
protected:
nsIEventQueueService *mEventQueueService;
nsIEventQueue *mEventQueue;
nsCOMPtr<nsIEventQueue> mEventQueue;
};
#endif /* !nsAppShell_h__ */

View File

@ -75,18 +75,6 @@ nsHashtable *nsWidget::gsWindowList = nsnull; // WEAK references to nsWidget*
// cursors hash table
Cursor nsWidget::gsXlibCursorCache[eCursor_count_up_down + 1];
// this is a class for generating keys for
// the list of windows managed by mozilla.
// this is possibly the class impl that will be
// called whenever a new window is created/destroyed
//nsXlibWindowCallback *nsWidget::mWindowCallback = nsnull;
nsXlibWindowCallback nsWidget::gsWindowCreateCallback = nsnull;
nsXlibWindowCallback nsWidget::gsWindowDestroyCallback = nsnull;
nsXlibEventDispatcher nsWidget::gsEventDispatcher = nsnull;
// this is for implemention the WM_PROTOCOL code
PRBool nsWidget::WMProtocolsInitialized = PR_FALSE;
Atom nsWidget::WMDeleteWindow = 0;
@ -252,9 +240,6 @@ NS_IMETHODIMP nsWidget::Create(nsNativeWidget aParent,
aParent));
}
static NS_DEFINE_IID(kWindowServiceCID,NS_XLIB_WINDOW_SERVICE_CID);
static NS_DEFINE_IID(kWindowServiceIID,NS_XLIB_WINDOW_SERVICE_IID);
nsresult
nsWidget::StandardWidgetCreate(nsIWidget *aParent,
const nsRect &aRect,
@ -853,13 +838,6 @@ nsWidget::AddWindowCallback(Window aWindow, nsWidget *aWidget)
}
nsWindowKey window_key(aWindow);
gsWindowList->Put(&window_key, aWidget);
// make sure that if someone is listening that we inform
// them of the new window
if (gsWindowCreateCallback)
{
(*gsWindowCreateCallback)(aWindow);
}
}
void
@ -880,12 +858,6 @@ nsWidget::DeleteWindowCallback(Window aWindow)
if (gsXlibCursorCache[i])
XFreeCursor(nsAppShell::mDisplay, gsXlibCursorCache[i]);
}
if (gsWindowDestroyCallback)
{
(*gsWindowDestroyCallback)(aWindow);
}
}
#undef TRACE_PAINT
@ -1503,34 +1475,6 @@ Cursor nsWidget::XlibCreateCursor(nsCursor aCursorType)
return xcursor;
}
// nsresult
// nsWidget::SetXlibWindowCallback(nsXlibWindowCallback *aCallback)
// {
// if (aCallback == nsnull) {
// return NS_ERROR_FAILURE;
// }
// else {
// mWindowCallback = aCallback;
// }
// return NS_OK;
// }
// nsresult
// nsWidget::XWindowCreated(Window aWindow) {
// if (mWindowCallback) {
// mWindowCallback->WindowCreated(aWindow);
// }
// return NS_OK;
// }
// nsresult
// nsWidget::XWindowDestroyed(Window aWindow) {
// if (mWindowCallback) {
// mWindowCallback->WindowDestroyed(aWindow);
// }
// return NS_OK;
// }
void
nsWidget::SetUpWMHints(void) {
// check to see if we need to get the atoms for the protocols

View File

@ -47,7 +47,6 @@
#include "nsHashtable.h"
#include "prlog.h"
#include "nsIRegion.h"
#include "nsIXlibWindowService.h"
#include "nsIRollupListener.h"
#include "xlibrgb.h"
@ -159,10 +158,6 @@ public:
PRBool DispatchWindowEvent(nsGUIEvent & aEvent);
// static nsresult SetXlibWindowCallback(nsXlibWindowCallback *aCallback);
// static nsresult XWindowCreated(Window aWindow);
// static nsresult XWindowDestroyed(Window aWindow);
// these are for the wm protocols
static Atom WMDeleteWindow;
static Atom WMTakeFocus;
@ -246,10 +241,6 @@ protected:
static nsHashtable * gsWindowList;
static Cursor gsXlibCursorCache[eCursor_count_up_down + 1];
static nsXlibWindowCallback gsWindowCreateCallback;
static nsXlibWindowCallback gsWindowDestroyCallback;
static nsXlibEventDispatcher gsEventDispatcher;
// Variables for infomation about the current popup window and its listener
static nsCOMPtr<nsIRollupListener> gRollupListener;
static nsWeakPtr gRollupWidget;

View File

@ -1,49 +0,0 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = widget
LIBRARY_NAME = xlib_window_service
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
REQUIRES = xpcom
CPPSRCS = \
nsXlibWindowService.cpp \
nsXlibWindowServiceFactory.cpp \
$(NULL)
EXPORTS = nsIXlibWindowService.h
EXTRA_DSO_LDOPTS = $(TOOLKIT_TK_LIBS) $(MOZ_COMPONENT_LIBS)
include $(topsrcdir)/config/rules.mk
DEFINES += -D_IMPL_NS_TIMER
CXXFLAGS += $(TK_CFLAGS)
INCLUDES += $(TK_CFLAGS) -I$(srcdir)/.. -I$(srcdir)/../../xpwidgets

View File

@ -1,81 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are
* Copyright (C) 1999 Christopher Blizzard. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsIXlibWindowService_h__
#define nsIXlibWindowService_h__
#include "nsISupports.h"
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
// Interface id for the XlibWindow service
// { bd39ccb0-3f08-11d3-b419-00805f6d4c2a }
#define NS_XLIB_WINDOW_SERVICE_IID \
{ 0xbd39ccb0, \
0x3f08, \
0x11d3, \
{ 0xb4, 0x19, 0x00, 0x80, 0x5f, 0x6d, 0x4c, 0x2a } }
// Class ID for our implementation
// { 285fb550-3af4-11d3-aeb9-0000f8e25c06 }
#define NS_XLIB_WINDOW_SERVICE_CID \
{ 0x285fb550, \
0x3af4, \
0x11d3, \
{ 0xae, 0xb9, 0x00, 0x00, 0xf8, 0xe2, 0x5c, 0x06 } }
#define NS_XLIB_WINDOW_SERVICE_CONTRACTID "@mozilla.org/widget/xlib/window_service;1"
typedef void (*nsXlibWindowCallback)(PRUint32 aWindowID);
typedef void * nsXlibNativeEvent;
typedef void (*nsXlibEventDispatcher)(nsXlibNativeEvent aNativeEvent);
typedef int (*nsXlibTimeToNextTimeoutFunc)(struct timeval *aTimer);
typedef void (*nsXlibProcessTimeoutsProc)(XtAppContext app_context);
class nsIXlibWindowService : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_XLIB_WINDOW_SERVICE_IID);
NS_IMETHOD SetWindowCreateCallback(nsXlibWindowCallback aCallback) = 0;
NS_IMETHOD SetWindowDestroyCallback(nsXlibWindowCallback aCallback) = 0;
NS_IMETHOD GetWindowCreateCallback(nsXlibWindowCallback * aCallbackOut) = 0;
NS_IMETHOD GetWindowDestroyCallback(nsXlibWindowCallback * aCallbackOut) = 0;
NS_IMETHOD SetEventDispatcher(nsXlibEventDispatcher aDispatcher) = 0;
NS_IMETHOD GetEventDispatcher(nsXlibEventDispatcher * aDispatcherOut) = 0;
NS_IMETHOD SetTimeToNextTimeoutFunc(nsXlibTimeToNextTimeoutFunc aFunc) = 0;
NS_IMETHOD GetTimeToNextTimeoutFunc(nsXlibTimeToNextTimeoutFunc * aFuncOut) = 0;
NS_IMETHOD SetProcessTimeoutsProc(nsXlibProcessTimeoutsProc aProc) = 0;
NS_IMETHOD GetProcessTimeoutsProc(nsXlibProcessTimeoutsProc * aProcOut) = 0;
};
#endif /* nsIXlibWindowService_h__ */

View File

@ -1,142 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are
* Copyright (C) 1999 Christopher Blizzard. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsXlibWindowService.h"
nsXlibWindowService::nsXlibWindowService()
{
NS_INIT_REFCNT();
}
nsXlibWindowService::~nsXlibWindowService()
{
}
NS_IMPL_ISUPPORTS1(nsXlibWindowService, nsIXlibWindowService)
nsXlibWindowCallback nsXlibWindowService::gsWindowCreateCallback = nsnull;
nsXlibWindowCallback nsXlibWindowService::gsWindowDestroyCallback = nsnull;
nsXlibEventDispatcher nsXlibWindowService::gsEventDispatcher = nsnull;
nsXlibTimeToNextTimeoutFunc nsXlibWindowService::gsTimeToNextTimeoutFunc = nsnull;
nsXlibProcessTimeoutsProc nsXlibWindowService::gsProcessTimeoutsProc = nsnull;
NS_IMETHODIMP
nsXlibWindowService::SetWindowCreateCallback(nsXlibWindowCallback aCallback)
{
NS_ASSERTION(nsnull != aCallback,"null in ptr.");
gsWindowCreateCallback = aCallback;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsXlibWindowService::SetWindowDestroyCallback(nsXlibWindowCallback aCallback)
{
NS_ASSERTION(nsnull != aCallback,"null in ptr.");
gsWindowDestroyCallback = aCallback;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsXlibWindowService::SetEventDispatcher(nsXlibEventDispatcher aDispatcher)
{
NS_ASSERTION(nsnull != aDispatcher,"null in ptr.");
gsEventDispatcher = aDispatcher;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsXlibWindowService::GetWindowCreateCallback(nsXlibWindowCallback * aCallbackOut)
{
NS_ASSERTION(nsnull != aCallbackOut,"null out ptr.");
*aCallbackOut = gsWindowCreateCallback;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsXlibWindowService::GetWindowDestroyCallback(nsXlibWindowCallback * aCallbackOut)
{
NS_ASSERTION(nsnull != aCallbackOut,"null out ptr.");
*aCallbackOut = gsWindowDestroyCallback;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsXlibWindowService::GetEventDispatcher(nsXlibEventDispatcher * aDispatcherOut)
{
NS_ASSERTION(nsnull != aDispatcherOut,"null out ptr.");
*aDispatcherOut = gsEventDispatcher;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsXlibWindowService::SetTimeToNextTimeoutFunc(nsXlibTimeToNextTimeoutFunc aFunc)
{
NS_ASSERTION(nsnull != aFunc,"null in ptr.");
gsTimeToNextTimeoutFunc = aFunc;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsXlibWindowService::GetTimeToNextTimeoutFunc(nsXlibTimeToNextTimeoutFunc * aFuncOut)
{
NS_ASSERTION(nsnull != aFuncOut,"null out ptr.");
*aFuncOut = gsTimeToNextTimeoutFunc;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsXlibWindowService::SetProcessTimeoutsProc(nsXlibProcessTimeoutsProc aProc)
{
NS_ASSERTION(nsnull != aProc,"null in ptr.");
gsProcessTimeoutsProc = aProc;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsXlibWindowService::GetProcessTimeoutsProc(nsXlibProcessTimeoutsProc * aProcOut)
{
NS_ASSERTION(nsnull != aProcOut,"null out ptr.");
*aProcOut = gsProcessTimeoutsProc;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////

View File

@ -1,55 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are
* Copyright (C) 1999 Christopher Blizzard. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIXlibWindowService.h"
class nsXlibWindowService : public nsIXlibWindowService
{
public:
nsXlibWindowService();
virtual ~nsXlibWindowService();
NS_DECL_ISUPPORTS
NS_IMETHOD SetWindowCreateCallback(nsXlibWindowCallback aCallback);
NS_IMETHOD SetWindowDestroyCallback(nsXlibWindowCallback aCallback);
NS_IMETHOD GetWindowCreateCallback(nsXlibWindowCallback * aCallbackOut);
NS_IMETHOD GetWindowDestroyCallback(nsXlibWindowCallback * aCallbackOut);
NS_IMETHOD SetEventDispatcher(nsXlibEventDispatcher aDispatcher);
NS_IMETHOD GetEventDispatcher(nsXlibEventDispatcher * aDispatcherOut);
NS_IMETHOD SetTimeToNextTimeoutFunc(nsXlibTimeToNextTimeoutFunc aFunc);
NS_IMETHOD GetTimeToNextTimeoutFunc(nsXlibTimeToNextTimeoutFunc * aFuncOut);
NS_IMETHOD SetProcessTimeoutsProc(nsXlibProcessTimeoutsProc aProc);
NS_IMETHOD GetProcessTimeoutsProc(nsXlibProcessTimeoutsProc * aProcOut);
private:
static nsXlibWindowCallback gsWindowCreateCallback;
static nsXlibWindowCallback gsWindowDestroyCallback;
static nsXlibEventDispatcher gsEventDispatcher;
static nsXlibTimeToNextTimeoutFunc gsTimeToNextTimeoutFunc;
static nsXlibProcessTimeoutsProc gsProcessTimeoutsProc;
};

View File

@ -1,163 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are
* Copyright (C) 1999 Christopher Blizzard. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Peter Hartshorn <peter@igelaus.com.au>
*/
#include "nsIXlibWindowService.h"
#include "nsIFactory.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
#include "nsXlibWindowService.h"
static NS_DEFINE_CID(kCXlibWindowServiceCID, NS_XLIB_WINDOW_SERVICE_CID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
class nsXlibWindowServiceFactory : public nsIFactory
{
public:
NS_DECL_ISUPPORTS
NS_IMETHOD CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
nsXlibWindowServiceFactory(const nsCID &aClass);
virtual ~nsXlibWindowServiceFactory();
private:
nsCID mClassID;
};
nsXlibWindowServiceFactory::nsXlibWindowServiceFactory(const nsCID &aClass) :
mRefCnt(0),
mClassID(aClass)
{
}
nsXlibWindowServiceFactory::~nsXlibWindowServiceFactory()
{
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsXlibWindowServiceFactory, nsIFactory)
NS_IMETHODIMP
nsXlibWindowServiceFactory::CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult)
{
if (aResult == nsnull)
return NS_ERROR_NULL_POINTER;
*aResult = nsnull;
nsISupports *inst = nsnull;
if (mClassID.Equals(kCXlibWindowServiceCID)) {
inst = (nsISupports *)(nsXlibWindowService *) new nsXlibWindowService();
}
if (inst == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = inst->QueryInterface(aIID, aResult);
if (NS_FAILED(rv))
delete inst;
return rv;
}
nsresult nsXlibWindowServiceFactory::LockFactory(PRBool aLock)
{
// Not implemented in simplest case.
return NS_OK;
}
extern "C" NS_EXPORT nsresult
NSGetFactory(nsISupports *servMgr,
const nsCID &aClass,
const char *aClassName,
const char *aContractID,
nsIFactory **aFactory)
{
if (nsnull == aFactory) {
return NS_ERROR_NULL_POINTER;
}
*aFactory = new nsXlibWindowServiceFactory(aClass);
if (nsnull == aFactory) {
return NS_ERROR_OUT_OF_MEMORY;
}
return (*aFactory)->QueryInterface(NS_GET_IID(nsIFactory),
(void **)aFactory);
}
extern "C" NS_EXPORT PRBool
NSCanUnload(nsISupports *aServMgr)
{
return PR_FALSE;
}
extern "C" NS_EXPORT nsresult
NSRegisterSelf(nsISupports* aServMgr, const char *fullpath)
{
nsresult rv;
#ifdef NS_DEBUG
printf("*** Registering XlibWindowService\n");
#endif
nsCOMPtr<nsIServiceManager>
serviceManager(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIComponentManager> compMgr =
do_GetService(kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->RegisterComponent(kCXlibWindowServiceCID,
"Xlib Window Service",
NS_XLIB_WINDOW_SERVICE_CONTRACTID,
fullpath,
PR_TRUE,
PR_TRUE);
return rv;
}
extern "C" NS_EXPORT nsresult
NSUnregisterSelf(nsISupports *aServMgr, const char *fullpath)
{
nsresult rv;
nsCOMPtr<nsIServiceManager>
serviceManager(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIComponentManager> compMgr =
do_GetService(kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
compMgr->UnregisterComponent(kCXlibWindowServiceCID, fullpath);
return NS_OK;
}

View File

@ -31,6 +31,7 @@ LIBRARY_NAME = timer_$(TIMER_SUFFIX)
REQUIRES = xpcom \
string \
widget \
xlibrgb \
$(NULL)
CPPSRCS = nsTimerXlib.cpp
@ -49,7 +50,7 @@ endif
include $(topsrcdir)/config/rules.mk
EXTRA_DSO_LDOPTS += -lXt
EXTRA_DSO_LDOPTS += -lXt -lxlibrgb
INCLUDES += $(MOZ_XLIB_CFLAGS) -I$(srcdir)/..

View File

@ -39,73 +39,57 @@
#include "nsTimerXlib.h"
#include "nsIXlibWindowService.h"
#include "nsIServiceManager.h"
#include "nsVoidArray.h"
#include <unistd.h>
#include <stdio.h>
#include "prlog.h"
#include <X11/Xlib.h>
#include <xlibrgb.h>
static NS_DEFINE_IID(kITimerIID, NS_ITIMER_IID);
static int NS_TimeToNextTimeout(struct timeval *aTimer);
static void NS_ProcessTimeouts(XtAppContext app_context);
nsVoidArray *nsTimerXlib::gHighestList = (nsVoidArray *)nsnull;
nsVoidArray *nsTimerXlib::gHighList = (nsVoidArray *)nsnull;
nsVoidArray *nsTimerXlib::gNormalList = (nsVoidArray *)nsnull;
nsVoidArray *nsTimerXlib::gLowList = (nsVoidArray *)nsnull;
nsVoidArray *nsTimerXlib::gLowestList = (nsVoidArray *)nsnull;
PRBool nsTimerXlib::gTimeoutAdded = PR_FALSE;
PRBool nsTimerXlib::gProcessingTimer = PR_FALSE;
nsVoidArray *nsTimerXlib::gHighList = (nsVoidArray *)nsnull;
nsVoidArray *nsTimerXlib::gNormalList = (nsVoidArray *)nsnull;
nsVoidArray *nsTimerXlib::gLowList = (nsVoidArray *)nsnull;
nsVoidArray *nsTimerXlib::gLowestList = (nsVoidArray *)nsnull;
PRPackedBool nsTimerXlib::gTimeoutAdded = PR_FALSE;
Display *nsTimerXlib::mDisplay = nsnull;
nsTimerXlib::nsTimerXlib()
/* Interval how controlls how often we visit the timer queues ...*/
#define CALLPROCESSTIMEOUTSVAL (10)
/* local prototypes */
PR_BEGIN_EXTERN_C
static void CallProcessTimeoutsXtProc( XtPointer dummy1, XtIntervalId *dummy2 );
PR_END_EXTERN_C
nsTimerXlib::nsTimerXlib() :
mFunc(nsnull),
mCallback(nsnull),
mDelay(0),
mClosure(nsnull),
mPriority(0),
mType(NS_TYPE_ONE_SHOT),
mQueued(PR_FALSE)
{
#ifdef TIMER_DEBUG
fprintf(stderr, "nsTimerXlib::nsTimerXlib (%p) called.\n", this);
#endif
NS_INIT_REFCNT();
mFunc = nsnull;
mCallback = nsnull;
mDelay = 0;
mClosure = nsnull;
mPriority = 0;
mType = NS_TYPE_ONE_SHOT;
}
nsTimerXlib::~nsTimerXlib()
{
#ifdef TIMER_DEBUG
fprintf(stderr, "nsTimerXlib::~nsTimerXlib (%p) called.\n", this);
#endif
{
Cancel();
NS_IF_RELEASE(mCallback);
}
/*static*/ void nsTimerXlib::Shutdown()
void nsTimerXlib::Shutdown()
{
delete nsTimerXlib::gHighestList;
nsTimerXlib::gHighestList = nsnull;
if (gHighestList) delete gHighestList; gHighestList = nsnull;
if (gHighList) delete gHighList; gHighList = nsnull;
if (gNormalList) delete gNormalList; gNormalList = nsnull;
if (gLowList) delete gLowList; gLowList = nsnull;
if (gLowestList) delete gLowestList; gLowestList = nsnull;
delete nsTimerXlib::gHighList;
nsTimerXlib::gHighList = nsnull;
delete nsTimerXlib::gNormalList;
nsTimerXlib::gNormalList = nsnull;
delete nsTimerXlib::gLowList;
nsTimerXlib::gLowList = nsnull;
delete nsTimerXlib::gLowestList;
nsTimerXlib::gLowestList = nsnull;
nsTimerXlib::gTimeoutAdded = PR_FALSE;
gTimeoutAdded = PR_FALSE;
}
NS_IMPL_ISUPPORTS1(nsTimerXlib, nsITimer)
@ -163,37 +147,56 @@ nsTimerXlib::Init(PRUint32 aDelay, PRUint32 aPriority)
if (!gTimeoutAdded)
{
nsTimerXlib::gHighestList = new nsVoidArray;
nsTimerXlib::gHighList = new nsVoidArray;
nsTimerXlib::gNormalList = new nsVoidArray;
nsTimerXlib::gLowList = new nsVoidArray;
nsTimerXlib::gLowestList = new nsVoidArray;
mDisplay = xxlib_rgb_get_display(xxlib_find_handle(XXLIBRGB_DEFAULT_HANDLE));
NS_ASSERTION(mDisplay!=nsnull, "xxlib_rgb_get_display() returned nsnull display. BAD.");
XtAppContext app_context = XtDisplayToApplicationContext(mDisplay);
NS_ASSERTION(app_context!=nsnull, "XtDisplayToApplicationContext() returned nsnull Xt app context. BAD.");
if (!app_context)
return NS_ERROR_OUT_OF_MEMORY;
gHighestList = new nsVoidArray(64);
gHighList = new nsVoidArray(64);
gNormalList = new nsVoidArray(64);
gLowList = new nsVoidArray(64);
gLowestList = new nsVoidArray(64);
if (!(gHighestList && gHighList && gNormalList && gLowList && gLowestList)) {
NS_WARNING("nsTimerXlib initalisation failed. DIE!");
return NS_ERROR_OUT_OF_MEMORY;
}
nsTimerXlib::gTimeoutAdded = PR_TRUE;
// start timers
XtAppAddTimeOut(app_context,
CALLPROCESSTIMEOUTSVAL,
CallProcessTimeoutsXtProc,
app_context);
gTimeoutAdded = PR_TRUE;
}
switch (aPriority)
{
case NS_PRIORITY_HIGHEST:
nsTimerXlib::gHighestList->InsertElementAt(this, 0);
mQueued = gHighestList->AppendElement(this);
break;
case NS_PRIORITY_HIGH:
nsTimerXlib::gHighList->InsertElementAt(this, 0);
mQueued = gHighList->AppendElement(this);
break;
case NS_PRIORITY_NORMAL:
nsTimerXlib::gNormalList->InsertElementAt(this, 0);
mQueued = gNormalList->AppendElement(this);
break;
case NS_PRIORITY_LOW:
nsTimerXlib::gLowList->InsertElementAt(this, 0);
mQueued = gLowList->AppendElement(this);
break;
default:
case NS_PRIORITY_LOWEST:
nsTimerXlib::gLowestList->InsertElementAt(this, 0);
break;
mQueued = gLowestList->AppendElement(this);
break;
}
EnsureWindowService();
return NS_OK;
NS_ASSERTION(mQueued, "can't add timer to queue list!");
return (mQueued)?(NS_OK):(NS_ERROR_OUT_OF_MEMORY);
}
PRBool
@ -201,18 +204,6 @@ nsTimerXlib::Fire()
{
nsCOMPtr<nsITimer> kungFuDeathGrip = this;
#ifdef TIMER_DEBUG
fprintf(stderr, "*** PRIORITY is %x ***\n", mPriority);
#endif
timeval aNow;
gettimeofday(&aNow, nsnull);
#ifdef TIMER_DEBUG
fprintf(stderr, "nsTimerXlib::Fire (%p) called at %ld / %ld\n",
this, aNow.tv_sec, aNow.tv_usec);
#endif
if (mFunc != nsnull) {
(*mFunc)(this, mClosure);
}
@ -226,22 +217,25 @@ nsTimerXlib::Fire()
void
nsTimerXlib::Cancel()
{
if (!mQueued)
return;
switch(mPriority)
{
case NS_PRIORITY_HIGHEST:
nsTimerXlib::gHighestList->RemoveElement(this);
gHighestList->RemoveElement(this);
break;
case NS_PRIORITY_HIGH:
nsTimerXlib::gHighList->RemoveElement(this);
gHighList->RemoveElement(this);
break;
case NS_PRIORITY_NORMAL:
nsTimerXlib::gNormalList->RemoveElement(this);
gNormalList->RemoveElement(this);
break;
case NS_PRIORITY_LOW:
nsTimerXlib::gLowList->RemoveElement(this);
gLowList->RemoveElement(this);
break;
case NS_PRIORITY_LOWEST:
nsTimerXlib::gLowestList->RemoveElement(this);
gLowestList->RemoveElement(this);
break;
}
}
@ -320,134 +314,41 @@ void nsTimerXlib::SetType(PRUint32 aType)
{
mType = aType;
}
static NS_DEFINE_IID(kWindowServiceCID,NS_XLIB_WINDOW_SERVICE_CID);
static NS_DEFINE_IID(kWindowServiceIID,NS_XLIB_WINDOW_SERVICE_IID);
nsresult
nsTimerXlib::EnsureWindowService()
void nsTimerXlib::CallProcessTimeouts(XtAppContext app_context)
{
nsIXlibWindowService * xlibWindowService = nsnull;
nsresult rv = nsServiceManager::GetService(kWindowServiceCID,
kWindowServiceIID,
(nsISupports **)&xlibWindowService);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't obtain window service.");
if (NS_SUCCEEDED(rv) && (nsnull != xlibWindowService))
ProcessTimeouts(gHighestList);
ProcessTimeouts(gHighList);
ProcessTimeouts(gNormalList);
/* no X events anymore ? then crawl the low priority timers ...
* Smallish hack: |if ((XtAppPending(app_context) & XtIMXEvent) == 0)|
* would be the correct way in libXt apps. - but I want to avoid any
* possible call to XFlush() ...
*/
if (XEventsQueued(mDisplay, QueuedAlready) == 0)
{
xlibWindowService->SetTimeToNextTimeoutFunc(NS_TimeToNextTimeout);
xlibWindowService->SetProcessTimeoutsProc(NS_ProcessTimeouts);
NS_RELEASE(xlibWindowService);
ProcessTimeouts(gLowList);
ProcessTimeouts(gLowestList);
}
return NS_OK;
}
/* must be a |XtInputCallbackProc| !! */
PR_BEGIN_EXTERN_C
static
int NS_TimeToNextTimeout(struct timeval *aTimer)
void CallProcessTimeoutsXtProc( XtPointer dummy1, XtIntervalId *dummy2 )
{
#ifdef DEBUG
static int once = 1;
XtAppContext app_context = (XtAppContext) dummy1;
if (once)
{
once = 0;
printf("NS_TimeToNextTimeout() lives!\n");
}
#endif /* DEBUG */
nsTimerXlib::CallProcessTimeouts(app_context);
nsTimerXlib *timer;
// Find the next timeout.
if (nsTimerXlib::gHighestList->Count() > 0)
timer = (nsTimerXlib*)nsTimerXlib::gHighestList->ElementAt(0);
else
if (nsTimerXlib::gHighList->Count() > 0)
timer = (nsTimerXlib*)nsTimerXlib::gHighList->ElementAt(0);
else
if (nsTimerXlib::gNormalList->Count() > 0)
timer = (nsTimerXlib*)nsTimerXlib::gNormalList->ElementAt(0);
else
if (nsTimerXlib::gLowList->Count() > 0)
timer = (nsTimerXlib*)nsTimerXlib::gLowList->ElementAt(0);
else
if (nsTimerXlib::gLowestList->Count() > 0)
timer = (nsTimerXlib*)nsTimerXlib::gLowestList->ElementAt(0);
else
timer = nsnull;
if (timer) {
if ((timer->mFireTime.tv_sec < aTimer->tv_sec) ||
((timer->mFireTime.tv_sec == aTimer->tv_sec) &&
(timer->mFireTime.tv_usec <= aTimer->tv_usec))) {
aTimer->tv_sec = 0;
aTimer->tv_usec = 0;
return 1;
}
else {
if (aTimer->tv_sec < timer->mFireTime.tv_sec)
aTimer->tv_sec = timer->mFireTime.tv_sec - aTimer->tv_sec;
else
aTimer->tv_sec = 0;
// handle the overflow case
if (aTimer->tv_usec < timer->mFireTime.tv_usec) {
aTimer->tv_usec = timer->mFireTime.tv_usec - aTimer->tv_usec;
// make sure we don't go past zero when we decrement
if (aTimer->tv_sec)
aTimer->tv_sec--;
}
else {
aTimer->tv_usec -= timer->mFireTime.tv_usec;
}
return 1;
}
}
else {
return 0;
}
/* reset timer */
XtAppAddTimeOut(app_context,
CALLPROCESSTIMEOUTSVAL,
CallProcessTimeoutsXtProc,
app_context);
}
PR_END_EXTERN_C
static
void
NS_ProcessTimeouts(XtAppContext app_context)
{
#ifdef DEBUG
static int once = 1;
if (once)
{
once = 0;
printf("NS_ProcessTimeouts() lives!\n");
}
#endif /* DEBUG */
nsTimerXlib::gProcessingTimer = PR_TRUE;
nsTimerXlib::ProcessTimeouts(nsTimerXlib::gHighestList);
nsTimerXlib::ProcessTimeouts(nsTimerXlib::gHighList);
nsTimerXlib::ProcessTimeouts(nsTimerXlib::gNormalList);
/* no X events anymore ? then crawl the low priority timers ... */
if ((XtAppPending(app_context) & XtIMXEvent) == 0)
{
#ifdef TIMER_DEBUG
fprintf(stderr, "\n Handling Low Priority Stuff!!! Display is 0x%x\n", aDisplay);
#endif
nsTimerXlib::ProcessTimeouts(nsTimerXlib::gLowList);
nsTimerXlib::ProcessTimeouts(nsTimerXlib::gLowestList);
}
#ifdef TIMER_DEBUG
else
fprintf(stderr, "\n Handling Event Stuff!!!", aDisplay);
#endif
nsTimerXlib::gProcessingTimer = PR_FALSE;
}

View File

@ -20,7 +20,8 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Tony Tsui <tony@igelaus.com.au>
* Tony Tsui <tony@igelaus.com.au>
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -44,6 +45,8 @@
#include <sys/time.h>
#include <X11/Intrinsic.h>
class nsVoidArray;
class nsTimerXlib : public nsITimer
@ -83,26 +86,28 @@ public:
virtual void *GetClosure() { return mClosure; }
static nsVoidArray *gHighestList;
static nsVoidArray *gHighList;
static nsVoidArray *gNormalList;
static nsVoidArray *gLowList;
static nsVoidArray *gLowestList;
/* semi-private, only for |CallProcessTimeoutsXtProc()| !! */
static void CallProcessTimeouts(XtAppContext app_context);
static PRBool gTimeoutAdded;
static PRBool gProcessingTimer;
struct timeval mFireTime;
PRUint32 mDelay;
private:
nsresult Init(PRUint32 aDelay, PRUint32 aPriority);
nsresult EnsureWindowService();
void * mClosure;
nsITimerCallback * mCallback;
nsTimerCallbackFunc mFunc;
PRUint32 mPriority;
PRUint32 mType;
struct timeval mFireTime;
PRUint32 mDelay;
PRPackedBool mQueued; /* queued in list ? */
static Display *mDisplay;
static nsVoidArray *gHighestList,
*gHighList,
*gNormalList,
*gLowList,
*gLowestList;
static PRPackedBool gTimeoutAdded;
};
#endif // __nsTimerXlib_h
#endif /* !__nsTimerXlib_h */