There are no guarantees of what thread any call may be made in. If a particular protocol needs to have everything running in a single thread, then it must provide the necessary messaging and synchronization stuff under the IM-API.
In general, all of the calls are blocking. For example, it is expected that a call to connect() might take a long time. It is up to the user of IM-API to call create an extra thread if it can not afford to block on a call.
One of the fundamental strengths of the browser has always been the ability to hide the messy details of diverse network protocols under a simple user interface. The same client can go talk to servers speaking HTTP, FTP, Gopher, etc., and provide a fairly consistent interface to them all.
We would like to make Mozilla be able to do chatting and "instant messaging". However, we don't want to limit ourselves to a single server, or a single protocol. People today are chatting using a variety of different protocols and servers. We would like Mozilla to be able to usefully talk to all of these protocols, and hide most of the differences from the user.
On the other hand, we also don't want to hard-code knowledge of every known chat protocol into the code base. We would like to have a "pluggable" architecture, where it would be possible at any time to write up a new module for a new protocol, and Mozilla would just work with it.
IM-API defines the API for people wanting to make Mozilla speak a new chat protocol.
The big picture
[Insert cool diagram here.]
The whole IM/Chat module will be an separate module from the rest of the Mozilla client; it will be possible to build the client without any IM/Chat support at all.
The IM/Chat module will include lots of UI code and stuff. But to actually speak a chat protocol, it will look in the registry for classes that provide the nsIMServer interface. Each of those classes represent a different protocol. When the client wishes to connect to a chat protocol, it will create an instance of the appropriate nsIMServer object, connect() to the service, and start calling getService() to get the Service objects it needs. The client will implement the corresponding Listener interfaces defined below for any Service objects it needs.
So, for a new protocol, you need to define which of the below services make sense for your protocol. You will define an object that implements nsIMServer, and make its GetService() method return objects you define for the services you support. You do not have to define any of the Listener classes; those are generally defined by the client.
As things get further flushed out, and actual UI code gets added, we plan to add stuff so that a particular protocol can add things to the UI to support protocol-specific stuff. The additional UI will probably end up calling additional interfaces provided by the protocol. We do not expect that all calls to the protocol module will go through this IM-API, but we do hope that most of them do.
The API
Random notes about the API:
Any interface whose name ends with "Listener" is generally implemented by the main client code, not by a protocol module. The stuff in IM_APIExt.h is optional. This is the place for features that some implementations of a service will have, and some will not. The user of a service will be able to QueryInterface to determine if a given feature is supported.
Details about this API that I know are wrong and need to be fixed:
I need to #define the NS_IIM* constants properly. Where do these magic numbers come from? Do I need to port this to IDL? I don't talk about how objects get constructed. Factories, mumble, mumble. The unpickle() calls are pretty constructor-ish, though. The names are all currently prefixed with the string "nsIM". I'm not sure if that's a sufficiently unique prefix. There is no RDF in here. I think it likely that much of the pickle/unpickle awkwardness may get replaced with something RDFish. Appropriate experts need to be consulted. Some other questionable things are called out in green italic text. Everywhere we pass HTML text, we might also need to pass some other info (like, maybe, encoding information for proper i18n support)?
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* The contents of this file are subject to the Mozilla Public License Version 1.0 (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 IM-API.
The Initial Developer of the Original Code is Netscape Communications Corporation. Portions created by Netscape are Copyright (C) 1999 Netscape Communications Corporation. All Rights Reserved.
Contributor(s): */
// This file defines the core IM_API functionality: the main services // that a protocol module is likely to want to implement, and the // associated Listener and other interfaces.
// This lists the different availability states a person can be in. // I'm not yet certain if this is the appropriate // generic list.
enum nsIMAvailability { Present,// The person is alive and on-line Gone,// The person is not connected Away,// The person is on-line but is not at his // computer. Unknown,// The protocol is not actively tracking the // presence of this user, and so his state // is not known. };
// The nsIMServer interface represents the main connection to a server. // One instantiation of it will be created for each connection to a // chat server. Thus, if the user wishes to speak to 3 different IRC // servers, there will be three instances of the IRC implementation of // nsIMServer. // // The nsIMServer interface only deals with things having to do with the entire // server connection; basically, whether it is actually connected or not. To // actually do something using the server, you must use the getService() method // to get a service object for the service you want.
class nsIIMServer : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMSERVEROBJECT_I ID)
// setServerListener() sets the object this server should use to // report asynchronous events and messages. PRStatus getServerListener(nsIIMServerListener*);
// getServerListener() returns the listener object. nsIIMServerListener* getServerListener();
// getShortDescription() returns a short name for this server, suitable for // use in a list of server names. If you can have multiple instantiations // of the same kind of server (for example, to do multiple IRC hosts, or to // allow people to have multiple AIM screennames for themselves), then the // string for each instantiation ought to be unique. const char* getShortDescription();
// configure() causes this server instantiation to pop up a dialog box // allowing the user to configure all options about the server in general // (hostname, port number, screenname, password, etc.) // It is undefined whether this will return immediately or wait until the // user has finished the operation. PRStatus configure();
// connect() causes a connection to be made to the server. This call // blocks until a connection is firmly established. PRStatus connect();
// disconnect() causes any connection with the server to be dropped. // This call blocks until the connection has been dropped. PRStatus disconnect();
// isConnected() returns whether there is a current connection to the // server. PRBool isConnected()
// GetService() returns a pointer to the object that implements the // given service (which should be on of NS_IIMIMSERVICE_IID, // NS_IIMCHATSERVICE_IID, NS_IIMPRESENCESERVICE_IID, etc.) If the // given service can be found, the pointer is set; if the service // is not supported, an error code is returned and the pointer is // set to NULL.
// The nsIIMServerListener interface gets called with asynchronous events that // relate to the whole server (not particular to any service within it).
class nsIIMServerListener : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMSERVERLISTENER _IID)
// If we ever lose the connection to the server, then this function will // be called. "why" is an error message that can be displayed to the user, // explaining what happened. Is passing this as a // string the right I18N thing to do here? PRStatus lostConnection(const char* why); };
// The nsIIMIMService interface (and I really *hate* that name, but // everything else is either too long or too inconsistant with other // names here) provides the instant messaging service.
class nsIIMIMService : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMIMSERVICE_IID)
// setIMListener() sets the object this server should use to // report asynchronous events and messages. PRStatus setIMListener(nsIIMIMListener*);
// getIMListener() returns the listener object. nsIIMIMListener* getIMListener();
// sendMessage() causes an instant message to be delievered to the given // user. This call blocks until the message has been delivered. PRStatus sendMessage(nsIIMIndividual* dest, const char* html); };
// The nsIIMIMListener interface gets called with asynchronous events that // relate to the instant messaging service.
class nsIIMIMListener : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMIMLISTENER_IID )
// receiveMessage() gets called whenever someone out on the network sends // us an instant message. PRStatus receiveMessage(nsIIMIndividual* source, const char* html); };
// The nsIIMChatService interface provides support for the chat service.
class nsIIMChatService : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATSERVICE_II D)
// setChatListener() sets the object this server should use to // report asynchronous events and messages. PRStatus setChatListener(nsIIMChatListener*);
// getChatListener() returns the listener object. nsIIMChatListener* getChatListener();
// listKnownRooms() returns a list of room names that are known to exist // with this chat service. It does not necessarily return every room that // is actually out there, just the ones that are currently known to exist. // This ListOfStrings return type is just a // placeholder; I hope such a class does exist. ListOfStrings* listKnownRooms();
// getRoom() returns the room object corresponding to the given name, or // NULL if no such room exists and can't it can't created. nsIIMChatRoom* getRoom(const char* name); };
// The nsIIMChatListener interface gets called with asynchronous events that // relate to the chat service.
class nsIIMChatListener : public nsISupports { NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATLISTENER_I ID)
// roomChanged() gets called whenever a room appears or disappears from // the list of known rooms. It is legal for listKnownRooms() to return // a different list on two successive calls without any intervening calls // to roomChanged() happening; that is, some protocols may only support // polling on the list of rooms and will not provide asynchronous // updates. PRStatus roomChanged(const char* name, PRBool added// True if added, False if removed. );
// receiveInvitation() gets called when the user has received an invitation // to join a room. PRStatus receiveInvitation(nsIIMIndividual* who,// Who sent the invitation const char* roomname,// What room we're // invited to const char* extratext// Any extra text to // display as part of the // invitation. This is // HTML. ); };
// The nsIIMPresenceService intervening provides support for the presence // indication service, the service that lets you track a list of individuals // on the network and report whether they are currently on-line.
class nsIIMPresenceService : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMPRESENCESERVIC E_IID)
// setPresenceListener() sets the object this server should use to // report asynchronous events and messages. PRStatus setPresenceListener(nsIIMPresenceListener*);
// getPresenceListener() returns the listener object. nsIIMPresenceListener* getPresenceListener();
// addUser() causes us to start watching for presence of the given user. PRStatus addUser(nsIIMIndividual*);
// removeUser() causes us to stop watching for the given user. PRStatus removeUser(nsIIMIndividual*);
// removeAll() clears the list of all users that we are watching. PRStatus removeAll();
// getWatchList() returns the list of all users that we are watching. // The nsIIMIndividualList class is a placeholder; // I hope we have a standard easy way of doing this. nsIIMIndividualList* getWatchList(); };
// The nsIIMPresenceListener interface gets called with asynchronous events // that relate to the presence service.
class nsIIMPresenceListener : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMPRESENCELISTEN ER_IID)
// userAvailabilityChange() gets called whenever the given user goes // online, offline, or otherwise changes.
// The nsIIMIndividual interface represents a person out on the network.
class nsIIMIndividual : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMINDIVIDUAL_IID )
// getAvailability() returns the current availability information for // the given user. If block is True, then the caller is willing to wait // in order to get the most accurate information; if False, then the // call should return immediately (which may very well lead to a result // of Unknown.) Actually, the caller should always be ready for a result // of Unknown; some protocols may not be able to determine availability // in some circumstances. nsIMAvailability getAvailability(PRBool block);
// getIDString() returns a short identifying string used by the protocol // to identify this person. Note that some protocols may change this // string over time; it is best for callers to remember people by their // pointer, not by their idstring. const char* getIDString(); };
// The nsIIMChatRoom interface represents a chat room. This acts much like // a service, in that it has a corresponding listening class. However, unlike // most services, there can be multiple instantiations of this for a single // protocol, one per chat room that we are connected to. The existance of // a nsIIMChatRoom object implies that the user is connected to it; to // disconnect from a chat room, the client should drop its references to // the nsIIMChatRoom object.
class nsIIMChatRoom : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATROOM_IID)
// setChatRoomListener() sets the object this server should use to // report asynchronous events and messages. PRStatus setChatRoomListener(nsIIMChatRoomListener*);
// getChatRoomListener() returns the listener object. nsIIMChatRoomListener* getChatRoomListener();
// getDisplayName() returns a brief name for this room. const char* getDisplayName();
// getDescription() returns a description or "topic" for this room. const char* getDescription();
// sendMessage() sends a message to the chat room. It is assumed that the // listener's receiveMessage() will get called soon thereafter with this // same message. If that doesn't happen as a side effect of the network // protocol, then the protocol module must call receiveMessage() itself. PRStatus sendMessage(char* html);
// sendInvitation() invites someone to join this chat room. extratext is // extra HTML text to explain the invitation. If the underlying protocol // doesn't support extra text with an invitation, then it should try to // get that text to the receiving user somehow (i.e., send an instant // message with that text just ahead of the invitation). PRStatus sendInvitation(nsIIMIndividual* who, const char* extratext);
// listMembers() lists who is currently connected to this room. nsIIMIndividualList* listMembers(); };
// The nsIIMChatRoomListener interface gets calle with asynchronous events // that relate to a specific chat room.
class nsIIMChatRoomListener : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATROOMLISTEN ER_IID)
// receiveMessage() gets called whenever a person sends a message to the // chat room.
// memberChange() gets called whenever someone leaves or enters the room. PRStatus memberChange(nsIIMIndividual* who, PRBool added// True if entered, False if left ); };
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* The contents of this file are subject to the Mozilla Public License Version 1.0 (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 IM-API.
The Initial Developer of the Original Code is Netscape Communications Corporation. Portions created by Netscape are Copyright (C) 1999 Netscape Communications Corporation. All Rights Reserved.
Contributor(s): */
// This file defines strictly optional interfaces for features that // are known to be supported only by some protocols.
// ########## EMOTE SUPPORT Some protocols allow for messages that are // "emoted". ("emoting" refers to the ability to express emotions instead of // just sending text -- the ability to say in a chat room "terry feels sick", // rather than having to do "terry: I feel sick".) If a protocol supports // emoting in instant messages, then the objects supporting the nsIIMIMService // and nsIIMIMListener interfaces need to also support the nsIIMIMEmoteService // and nsIIMIMEmoteListener interfaces, respectively. Similarly, if the // protocol supports emoting in chat messages, then the objects supporting the // nsIIMChatRoom and nsIIMChatRoomListener interfaces need to also support // the nsIIMChatRoomEmote and nsIIMChatRoomEmoteListener interfaces, // respectively. // // This is an annoying number of extra interfaces to support a simple thing // like "emote". However, we don't have a better idea. It does give the // most flexibility, and makes things simple for the simpler protocols that // do not do emote.
class nsIIMIMEmoteService : public nsISupports { NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMIMEMOTESERVICE _IID)
// sendEmote() is just like sendMessage() in nsIIMIMService, but the // message is sent emote-style. PRStatus sendEmote(nsIIMIndividual* dest, const char* html); };
class nsIIMIMEmoteListener : public nsISupports { NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMIMEMOTELISTENE R_IID)
// receiveEmote() is just like receiveMessage() in nsIIMIMListener, but // the message is sent emote-style.
i took a lakoff class at berkeley (intro to cogsci) and his position boils down to this: the mind is embodied i.e. abstract thought is based on image schemas that arise from our physical interaction with the world. these basic schemas (see mark johnson's book the body in the mind) are NON-MODULAR in that they need to be seen as a gestalt to be understood i.e. the containment schema only makes sense when there is a containing structure and a contained/noncontained structure. these schemas are extended up via metaphor to form abstract thought. the levels are physical, social, epistemic, then speech-action. programmers tend to operate in the epistemic realm. metaphor is not just something from shakespeare, but is how we extend ALL knowledge from one realm to another. a list of the common metaphors in the western world is found here . This stuff is interesting because it turns out that artificial intelligence is not possible. lakoff and crew are doing interesting work called the neural theory of language project (NTL) where they are building software models of thought this is the page. more metaphor stuff is found here . lakoff and mark johnson have a new book called philosophy in the flesh , the premise is that western philosophy is based on the false premise that the mind exists independently of the body, that there is a gods-eye view. this stuff is NOT post modern however, as social facts can impact life etc. okay i need to get back to work, this is internet after all
imho apple has a GREAT opportunity in consumer devices/appliances...wintel vendors will see incredible margins pressure (as they now are). eckhair's way to get out of this was to "emphasize" ecommerce but this is a played-out strategy and they should really be looking at new computing appliances and other directions for growth. (and cater to IT as well at the high end, which can also have good marigns)
this is the thing that really bugs me about the deal is that the record industry is a choke point on good musicians, i mean shit is so mass-marketed and contrived that they wouldnt know a good artist if they fell on them. the internet is all about CHOICE and hopefully this digital music scene will allow artists to make a buck without pandering to the lowest common denominator...
is is possible to have a version of an os, say linux, running on transmeta silicon that can DYNAMICALLY load libraries and run Java, i386, etc. etc. etc. at near-native speed without rebooting? if so that would be kewllllll
look, most apps are now being ported to a web interface. namely, ERP including baan, jd edwards, SAP....so any terminal with a 4.x browser can serve as a nice corporate desktop
another interpretation here is that gates is simply stating what the whole POINT of linux is - the os is a commodity, "innovation" (i.e. what you can charge for) has moved up a layer, to things like app servers, xml integration tools, knowledge mgmt, etc.
nothing better than news created by news...and blaming the internet for sex and violence as well.
only outlaws will have trenchcoats
john vranesovic (sp?) WISHES his sites were as cool as /. or freshmeat.
but its got a really cool name!
if it aint oss i aint interested, dont tell me about it!!!!
Threading
There are no guarantees of what thread any call may be made in. If a particular protocol needs to have everything running in a single
thread, then it must provide the necessary messaging and synchronization stuff under the IM-API.
In general, all of the calls are blocking. For example, it is expected that a call to connect() might take a long time. It is up to the user
of IM-API to call create an extra thread if it can not afford to block on a call.
IM-API -- Instant Messaging API
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
// This file defines the core IM_API functionality: the main services
// that a protocol module is likely to want to implement, and the
// associated Listener and other interfaces.
// This lists the different availability states a person can be in.
// I'm not yet certain if this is the appropriate
// generic list.
// The person is alive and on-line // The person is not connected // The person is on-line but is not at his
// computer. // The protocol is not actively tracking the
// presence of this user, and so his state
// is not known.
// The nsIMServer interface represents the main connection to a server.
// One instantiation of it will be created for each connection to a
// chat server. Thus, if the user wishes to speak to 3 different IRC
// servers, there will be three instances of the IRC implementation of
// nsIMServer.
//
// The nsIMServer interface only deals with things having to do with the entire
// server connection; basically, whether it is actually connected or not. To
// actually do something using the server, you must use the getService() method
// to get a service object for the service you want.
I ID)
// setServerListener() sets the object this server should use to
// report asynchronous events and messages.
// getServerListener() returns the listener object.
// getShortDescription() returns a short name for this server, suitable for
// use in a list of server names. If you can have multiple instantiations
// of the same kind of server (for example, to do multiple IRC hosts, or to
// allow people to have multiple AIM screennames for themselves), then the
// string for each instantiation ought to be unique.
// configure() causes this server instantiation to pop up a dialog box
// allowing the user to configure all options about the server in general
// (hostname, port number, screenname, password, etc.)
// It is undefined whether this will return immediately or wait until the
// user has finished the operation.
// connect() causes a connection to be made to the server. This call
// blocks until a connection is firmly established.
// disconnect() causes any connection with the server to be dropped.
// This call blocks until the connection has been dropped.
// isConnected() returns whether there is a current connection to the
// server.
// GetService() returns a pointer to the object that implements the
// given service (which should be on of NS_IIMIMSERVICE_IID,
// NS_IIMCHATSERVICE_IID, NS_IIMPRESENCESERVICE_IID, etc.) If the
// given service can be found, the pointer is set; if the service
// is not supported, an error code is returned and the pointer is
// set to NULL.
// The nsIIMServerListener interface gets called with asynchronous events that
// relate to the whole server (not particular to any service within it).
R _IID)
// If we ever lose the connection to the server, then this function will
// be called. "why" is an error message that can be displayed to the user,
// explaining what happened. Is passing this as a
// string the right I18N thing to do here?
// The nsIIMIMService interface (and I really *hate* that name, but
// everything else is either too long or too inconsistant with other
// names here) provides the instant messaging service.
)
// setIMListener() sets the object this server should use to
// report asynchronous events and messages.
// getIMListener() returns the listener object.
// sendMessage() causes an instant message to be delievered to the given
// user. This call blocks until the message has been delivered.
// The nsIIMIMListener interface gets called with asynchronous events that
// relate to the instant messaging service.
D )
// receiveMessage() gets called whenever someone out on the network sends
// us an instant message.
// The nsIIMChatService interface provides support for the chat service.
I D)
// setChatListener() sets the object this server should use to
// report asynchronous events and messages.
// getChatListener() returns the listener object.
// listKnownRooms() returns a list of room names that are known to exist
// with this chat service. It does not necessarily return every room that
// is actually out there, just the ones that are currently known to exist.
// This ListOfStrings return type is just a
// placeholder; I hope such a class does exist.
// getRoom() returns the room object corresponding to the given name, or
// NULL if no such room exists and can't it can't created.
// The nsIIMChatListener interface gets called with asynchronous events that
// relate to the chat service.
I ID)
// roomChanged() gets called whenever a room appears or disappears from
// the list of known rooms. It is legal for listKnownRooms() to return
// a different list on two successive calls without any intervening calls
// to roomChanged() happening; that is, some protocols may only support
// polling on the list of rooms and will not provide asynchronous
// updates. // True if added, False if removed.
// receiveInvitation() gets called when the user has received an invitation
// to join a room. // Who sent the invitation // What room we're
// invited to // Any extra text to
// display as part of the
// invitation. This is
// HTML.
// The nsIIMPresenceService intervening provides support for the presence
// indication service, the service that lets you track a list of individuals
// on the network and report whether they are currently on-line.
C E_IID)
// setPresenceListener() sets the object this server should use to
// report asynchronous events and messages.
// getPresenceListener() returns the listener object.
// addUser() causes us to start watching for presence of the given user.
// removeUser() causes us to stop watching for the given user.
// removeAll() clears the list of all users that we are watching.
// getWatchList() returns the list of all users that we are watching.
// The nsIIMIndividualList class is a placeholder;
// I hope we have a standard easy way of doing this.
// The nsIIMPresenceListener interface gets called with asynchronous events
// that relate to the presence service.
N ER_IID)
// userAvailabilityChange() gets called whenever the given user goes
// online, offline, or otherwise changes.
// The nsIIMIndividual interface represents a person out on the network.
D )
// getAvailability() returns the current availability information for
// the given user. If block is True, then the caller is willing to wait
// in order to get the most accurate information; if False, then the
// call should return immediately (which may very well lead to a result
// of Unknown.) Actually, the caller should always be ready for a result
// of Unknown; some protocols may not be able to determine availability
// in some circumstances.
// getIDString() returns a short identifying string used by the protocol
// to identify this person. Note that some protocols may change this
// string over time; it is best for callers to remember people by their
// pointer, not by their idstring.
// The nsIIMChatRoom interface represents a chat room. This acts much like
// a service, in that it has a corresponding listening class. However, unlike
// most services, there can be multiple instantiations of this for a single
// protocol, one per chat room that we are connected to. The existance of
// a nsIIMChatRoom object implies that the user is connected to it; to
// disconnect from a chat room, the client should drop its references to
// the nsIIMChatRoom object.
// setChatRoomListener() sets the object this server should use to
// report asynchronous events and messages.
// getChatRoomListener() returns the listener object.
// getDisplayName() returns a brief name for this room.
// getDescription() returns a description or "topic" for this room.
// sendMessage() sends a message to the chat room. It is assumed that the
// listener's receiveMessage() will get called soon thereafter with this
// same message. If that doesn't happen as a side effect of the network
// protocol, then the protocol module must call receiveMessage() itself.
// sendInvitation() invites someone to join this chat room. extratext is
// extra HTML text to explain the invitation. If the underlying protocol
// doesn't support extra text with an invitation, then it should try to
// get that text to the receiving user somehow (i.e., send an instant
// message with that text just ahead of the invitation).
// listMembers() lists who is currently connected to this room.
// The nsIIMChatRoomListener interface gets calle with asynchronous events
// that relate to a specific chat room.
N ER_IID)
// receiveMessage() gets called whenever a person sends a message to the
// chat room.
// memberChange() gets called whenever someone leaves or enters the room. // True if entered, False if left
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
// This file defines strictly optional interfaces for features that
// are known to be supported only by some protocols.
// ########## EMOTE SUPPORT Some protocols allow for messages that are
// "emoted". ("emoting" refers to the ability to express emotions instead of
// just sending text -- the ability to say in a chat room "terry feels sick",
// rather than having to do "terry: I feel sick".) If a protocol supports
// emoting in instant messages, then the objects supporting the nsIIMIMService
// and nsIIMIMListener interfaces need to also support the nsIIMIMEmoteService
// and nsIIMIMEmoteListener interfaces, respectively. Similarly, if the
// protocol supports emoting in chat messages, then the objects supporting the
// nsIIMChatRoom and nsIIMChatRoomListener interfaces need to also support
// the nsIIMChatRoomEmote and nsIIMChatRoomEmoteListener interfaces,
// respectively.
//
// This is an annoying number of extra interfaces to support a simple thing
// like "emote". However, we don't have a better idea. It does give the
// most flexibility, and makes things simple for the simpler protocols that
// do not do emote.
E _IID)
// sendEmote() is just like sendMessage() in nsIIMIMService, but the
// message is sent emote-style.
E R_IID)
// receiveEmote() is just like receiveMessage() in nsIIMIMListener, but
// the message is sent emote-style.
_ IID)
// sendEmote() is just like sendMessage() in nsIIMChatRoom, but the
// message is sent emote-style.
L ISTENER_IID)
// receiveEmote() is just like receiveMessage() in nsIIMChatRoomListener,
// but the message is sent emote-style.
Terry Weissman
Travis Bogard
Sudharshan Srinivasan
Goals
One of the fundamental strengths of the browser has always been the ability to hide the messy details of diverse network protocols
under a simple user interface. The same client can go talk to servers speaking HTTP, FTP, Gopher, etc., and provide a fairly
consistent interface to them all.
We would like to make Mozilla be able to do chatting and "instant messaging". However, we don't want to limit ourselves to a single
server, or a single protocol. People today are chatting using a variety of different protocols and servers. We would like Mozilla to be
able to usefully talk to all of these protocols, and hide most of the differences from the user.
On the other hand, we also don't want to hard-code knowledge of every known chat protocol into the code base. We would like to
have a "pluggable" architecture, where it would be possible at any time to write up a new module for a new protocol, and Mozilla
would just work with it.
IM-API defines the API for people wanting to make Mozilla speak a new chat protocol.
The big picture
[Insert cool diagram here.]
The whole IM/Chat module will be an separate module from the rest of the Mozilla client; it will be possible to build the client
without any IM/Chat support at all.
The IM/Chat module will include lots of UI code and stuff. But to actually speak a chat protocol, it will look in the registry for
classes that provide the nsIMServer interface. Each of those classes represent a different protocol. When the client wishes to
connect to a chat protocol, it will create an instance of the appropriate nsIMServer object, connect() to the service, and start calling
getService() to get the Service objects it needs. The client will implement the corresponding Listener interfaces defined below for
any Service objects it needs.
So, for a new protocol, you need to define which of the below services make sense for your protocol. You will define an object that
implements nsIMServer, and make its GetService() method return objects you define for the services you support. You do not have
to define any of the Listener classes; those are generally defined by the client.
As things get further flushed out, and actual UI code gets added, we plan to add stuff so that a particular protocol can add things to
the UI to support protocol-specific stuff. The additional UI will probably end up calling additional interfaces provided by the
protocol. We do not expect that all calls to the protocol module will go through this IM-API, but we do hope that most of them do.
The API
Random notes about the API:
Any interface whose name ends with "Listener" is generally implemented by the main client code, not by a protocol module.
The stuff in IM_APIExt.h is optional. This is the place for features that some implementations of a service will have, and some
will not. The user of a service will be able to QueryInterface to determine if a given feature is supported.
Details about this API that I know are wrong and need to be fixed:
I need to #define the NS_IIM* constants properly. Where do these magic numbers come from?
Do I need to port this to IDL?
I don't talk about how objects get constructed. Factories, mumble, mumble. The unpickle() calls are pretty constructor-ish,
though.
The names are all currently prefixed with the string "nsIM". I'm not sure if that's a sufficiently unique prefix.
There is no RDF in here. I think it likely that much of the pickle/unpickle awkwardness may get replaced with something
RDFish. Appropriate experts need to be consulted.
Some other questionable things are called out in green italic text.
Everywhere we pass HTML text, we might also need to pass some other info (like, maybe, encoding information for proper
i18n support)?
************************ IM_APIBase.h ************************
The contents of this file are subject to the Mozilla Public License
Version 1.0 (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 IM-API.
The Initial Developer of the Original Code is Netscape Communications
Corporation. Portions created by Netscape are Copyright (C) 1999
Netscape Communications Corporation. All Rights Reserved.
Contributor(s):
*/
enum nsIMAvailability {
Present,
Gone,
Away,
Unknown,
};
class nsIIMServer : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMSERVEROBJECT_
PRStatus getServerListener(nsIIMServerListener*);
nsIIMServerListener* getServerListener();
const char* getShortDescription();
PRStatus configure();
PRStatus connect();
PRStatus disconnect();
PRBool isConnected()
NS_IMETHOD GetService(REFNSIID iid, void** instancePtr);
};
class nsIIMServerListener : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMSERVERLISTENE
PRStatus lostConnection(const char* why);
};
class nsIIMIMService : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMIMSERVICE_IID
PRStatus setIMListener(nsIIMIMListener*);
nsIIMIMListener* getIMListener();
PRStatus sendMessage(nsIIMIndividual* dest, const char* html);
};
class nsIIMIMListener : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMIMLISTENER_II
PRStatus receiveMessage(nsIIMIndividual* source, const char* html);
};
class nsIIMChatService : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATSERVICE_I
PRStatus setChatListener(nsIIMChatListener*);
nsIIMChatListener* getChatListener();
ListOfStrings* listKnownRooms();
nsIIMChatRoom* getRoom(const char* name);
};
class nsIIMChatListener : public nsISupports {
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATLISTENER_
PRStatus roomChanged(const char* name,
PRBool added
);
PRStatus receiveInvitation(nsIIMIndividual* who,
const char* roomname,
const char* extratext
);
};
class nsIIMPresenceService : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMPRESENCESERVI
PRStatus setPresenceListener(nsIIMPresenceListener*);
nsIIMPresenceListener* getPresenceListener();
PRStatus addUser(nsIIMIndividual*);
PRStatus removeUser(nsIIMIndividual*);
PRStatus removeAll();
nsIIMIndividualList* getWatchList();
};
class nsIIMPresenceListener : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMPRESENCELISTE
PRStatus userAvailabilityChange(nsIIMIndividual* who);
};
class nsIIMIndividual : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMINDIVIDUAL_II
nsIMAvailability getAvailability(PRBool block);
const char* getIDString();
};
class nsIIMChatRoom : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATROOM_IID)
PRStatus setChatRoomListener(nsIIMChatRoomListener*);
nsIIMChatRoomListener* getChatRoomListener();
const char* getDisplayName();
const char* getDescription();
PRStatus sendMessage(char* html);
PRStatus sendInvitation(nsIIMIndividual* who, const char* extratext);
nsIIMIndividualList* listMembers();
};
class nsIIMChatRoomListener : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATROOMLISTE
PRStatus receiveMessage(nsIIMIndividualList* who, const char* html);
PRStatus memberChange(nsIIMIndividual* who,
PRBool added
);
};
************************ IM_APIExt.h ************************
The contents of this file are subject to the Mozilla Public License
Version 1.0 (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 IM-API.
The Initial Developer of the Original Code is Netscape Communications
Corporation. Portions created by Netscape are Copyright (C) 1999
Netscape Communications Corporation. All Rights Reserved.
Contributor(s):
*/
class nsIIMIMEmoteService : public nsISupports {
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMIMEMOTESERVIC
PRStatus sendEmote(nsIIMIndividual* dest, const char* html);
};
class nsIIMIMEmoteListener : public nsISupports {
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMIMEMOTELISTEN
PRStatus receiveEmote(nsIIMIMListener* source, const char* html);
};
class nsIIMChatRoomEmote : public nsISupports {
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATROOMEMOTE
PRStatus sendEmote(const char* html);
};
class nsIIMChatRoomEmoteListener : public nsISupports {
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IIMCHATROOMEMOTE
PRStatus receiveEmote(nsIIMIMListener* who, const char* html);
};
Threading
There are no guarantees of what thread any call may be made in. If a particular protocol needs to have everything running in a single
i took a lakoff class at berkeley (intro to cogsci) and his position boils down to this: the mind is embodied i.e. abstract thought is based on image schemas that arise from our physical interaction with the world. these basic schemas (see mark johnson's book the body in the mind) are NON-MODULAR in that they need to be seen as a gestalt to be understood i.e. the containment schema only makes sense when there is a containing structure and a contained/noncontained structure. these schemas are extended up via metaphor to form abstract thought. the levels are physical, social, epistemic, then speech-action. programmers tend to operate in the epistemic realm. metaphor is not just something from shakespeare, but is how we extend ALL knowledge from one realm to another. a list of the common metaphors in the western world is found here . This stuff is interesting because it turns out that artificial intelligence is not possible. lakoff and crew are doing interesting work called the neural theory of language project (NTL) where they are building software models of thought this is the page. more metaphor stuff is found here . lakoff and mark johnson have a new book called philosophy in the flesh , the premise is that western philosophy is based on the false premise that the mind exists independently of the body, that there is a gods-eye view. this stuff is NOT post modern however, as social facts can impact life etc. okay i need to get back to work, this is internet after all
does anyone have technical info on aim - is it purely text based, i.e. can anyone implement their own clone of it etc....
since when did lying make you a bad ceo?
imho apple has a GREAT opportunity in consumer devices/appliances...wintel vendors will see incredible margins pressure (as they now are). eckhair's way to get out of this was to "emphasize" ecommerce but this is a played-out strategy and they should really be looking at new computing appliances and other directions for growth. (and cater to IT as well at the high end, which can also have good marigns)
debian install was pretty easy for me and i basically knew nothing at the time, just spent an hour and a half reading howtos
pj said hi.
that hiphop has been copying cutting and pasting since like 1979 - if you think about it its the perfect music for the information age...
this is the thing that really bugs me about the deal is that the record industry is a choke point on good musicians, i mean shit is so mass-marketed and contrived that they wouldnt know a good artist if they fell on them. the internet is all about CHOICE and hopefully this digital music scene will allow artists to make a buck without pandering to the lowest common denominator...
is is possible to have a version of an os, say linux, running on transmeta silicon that can DYNAMICALLY load libraries and run Java, i386, etc. etc. etc. at near-native speed without rebooting? if so that would be kewllllll
of course it hasnt been up for years!
maybe they like scifi
hooray for css! xml too, they rock.
look, most apps are now being ported to a web interface. namely, ERP including baan, jd edwards, SAP....so any terminal with a 4.x browser can serve as a nice corporate desktop
another interpretation here is that gates is simply stating what the whole POINT of linux is - the os is a commodity, "innovation" (i.e. what you can charge for) has moved up a layer, to things like app servers, xml integration tools, knowledge mgmt, etc.
all you linux weenies...if linux is better, take a system that is configured EXACTLY as the box in the test and put the lie to methodcraft.
come on...that profile isnt that off the mark...
there is some precedent here - every tape recorder sold, a percentage goes to some of the big record companies...
some people here have no sense of humor!