MidiShare version 1.80 is an Open Source Release: its source code is publicly available under the GNU Library General Public License. The kernel architecture has been slightly revised in order to facilitates porting on new platforms. A GNU/Linux version has been designed, based on this architecture.
The main change consists in removing the IO drivers from the kernel itself and in providing mechanisms to plug these drivers dynamically as external ressources. Therefore, a new manager, the Drivers Manager, is part of the MidiShare kernel architecture: it is in charge of the drivers activation, it also routes the events to their final destination according to the drivers setup.
This document describes these changes and gives the reference of the new functions and data structures introduced with this new architecture. The reader is supposed to be familiar with the MidiShare Developer Documentation.
The underlying idea of the drivers management is that a driver behaves like any MidiShare client except for a special call required to register (or unregister) as a driver. All the MidiShare API, extended by a set of new functions detailed below, are available to the drivers. Therefore, input / output operations may be performed using the standard MidiShare mecanisms:
Loading drivers in memory is a platform dependant operation (so as unloading), in charge of the Drivers Manager. It is the driver responsability to register and unregister: it may be done at any time. However, the driver should act according to the MidiShare state:
- when MidiShare is dormant, the driver should be dormant
- when MidiShare wakes up, the driver should also be woken.
Therefore, in order to be notified of the kernel state changes, a driver should provide callbacks at register time. The TDriverOperation data structure is intended to store these callbacks:
typedef struct TDriverOperation { void (* wakeup) (void); void (* sleep) (void); long reserved[3]; } TDriverOperation;The following functions are provided for drivers management :
short MidiRegisterDriver (TDriverInfos * infos, TDriverOperation *op) void MidiUnregisterDriver(short refnum) short MidiCountDrivers () short MidiGetIndDriver (short index) Boolean MidiGetDriverInfos (short refnum, TDriverInfos * infos)
Like the MidiShare application, automatically opened with the first client, a MidiShare driver is created at wakeup time: it should be considered as the driver image of the MidiShare application. As MidiShare client applications should connect to MidiShare to communicate with the drivers, the MidiShare drivers should connect to the driver image of MidiShare to communicate with the client applications.
The MidiShare reference number is 0 for the client applications and 127 for the drivers.
To differenciate between MidiShare logical ports and input / ouput ports supported by a driver (Serial ports, USB...) we'll talk about 'slots' when we'll refer to a driver port.
A driver should declare all its available slots using the MidiAddSlot function, which returns a system unique slot reference number. This reference number is composed of the driver reference number and a slot reference number unique in the driver context.typedef struct { short drvRef; /* the driver reference number */ short slotRef; /* the slot reference number */ } SlotRefNum;The following functions are provided for the slots management :
SlotRefNum MidiAddSlot (short refnum, SlotName name, SlotDirection direction) SlotRefNum MidiGetIndSlot (short refnum, short index) void MidiRemoveSlot (SlotRefNum slot) Boolean MidiGetSlotInfos(SlotRefNum slot, TSlotInfos * infos)MidiShare allows dynamic routing of the events from one port to any of the available slots. For this reason, a slot can be connected to one or several MidiShare ports. The Driver Manager is in charge of dispatching the events to or from the drivers according to the connections set between the event port and the drivers slots.
The following functions are provided for the slot connections management :void MidiConnectSlot (short port, SlotRefNum slot, Boolean state) Boolean MidiIsSlotConnected (short port, SlotRefNum slot)
The following alarm codes are defined to notify the client applications of changes concerning the drivers:
MIDIOpenDriver /* notified when a driver opens */ MIDICloseDriver /* notified when a driver closes */ MIDIAddSlot /* notified when a slot is added to the system */ MIDIRemoveSlot /* notified when a slot is removed from the system */ MIDIChgSlotConnect /* notified when the slots connections change */
Regular MidiShare clients and MidiShare drivers are considered to be part of separate communication folders. An additionnal connection rule is given : a connection is not allowed to cross a folder boundary. Therefore, connections can be made between regular clients or between drivers but NOT between a driver and a regular client. Such connections requests will be silently ignored by the kernel.
The functions below are obsolete:
Boolean MidiGetPortState (short port) void MidiSetPortState (short port, Boolean state)For compatibility, the corresponding entry points are supported in the Macintosh version but the functions do nothing and MidiGetPortState always returns true.