+int IPC_Type_Datagram_GetSize(const void *Ident)
+{
+ return 4 + Net_GetAddressSize( ((const uint16_t*)Ident)[1] );
+}
+
+int IPC_Type_Datagram_Compare(const void *Ident1, const void *Ident2)
+{
+ // Pass the buck :)
+ // - No need to worry about mis-matching sizes, as the size is computed
+ // from the 3rd/4th bytes, hence it will differ before the size is hit.
+ return memcmp(Ident1, Ident2, IPC_Type_Datagram_GetSize(Ident1));
+}
+
+void IPC_Type_Datagram_Send(const void *Ident, size_t Length, const void *Data)
+{
+ int identlen = IPC_Type_Datagram_GetSize(Ident);
+ char tmpbuf[ identlen + Length ];
+ memcpy(tmpbuf, Ident, identlen); // Header
+ memcpy(tmpbuf + identlen, Data, Length); // Data
+ // TODO: Handle fragmented packets
+ write(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf));
+}
+
+int IPC_Type_Sys_GetSize(const void *Ident)
+{
+ return sizeof(pid_t);
+}
+
+int IPC_Type_Sys_Compare(const void *Ident1, const void *Ident2)
+{
+ return *(const int*)Ident1 - *(const int*)Ident2;
+}
+
+void IPC_Type_Sys_Send(const void *Ident, size_t Length, const void *Data)
+{
+ SysSendMessage( *(const tid_t*)Ident, Length, Data );
+}
+
+// --- Client -> Window Mappings
+int _CompareClientPtrs(const void *_a, const void *_b)
+{
+ tIPC_Client *a = *(tIPC_Client**)_a;
+ tIPC_Client *b = *(tIPC_Client**)_b;
+
+ if(a->IPCType < b->IPCType) return -1;
+ if(a->IPCType > b->IPCType) return 1;
+
+ return a->IPCType->CompareIdent(a->Ident, b->Ident);
+}
+
+tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident)
+{
+ int pos; // Position where the new client will be inserted
+ int ident_size;
+ tIPC_Client *ret;
+ UNIMPLEMENTED();
+
+ // - Search list of registered clients
+ {
+ tIPC_Client target;
+ int div;
+ int cmp = -1;
+
+ target.IPCType = IPCType;
+ target.Ident = Ident;
+ ret = ⌖ // Abuse ret to get a pointer
+
+ div = giIPC_ClientCount;
+ pos = div/2;
+ while(div > 0)
+ {
+ div /= 2;
+ cmp = _CompareClientPtrs(&ret, &gIPC_Clients[pos]);
+ if(cmp == 0) break;
+ if(cmp < 0)
+ pos -= div;
+ else
+ pos += div;
+ }
+
+ // - Return if found
+ if(cmp == 0)
+ return gIPC_Clients[pos];
+
+ // Adjust pos to be the index where the new client will be placed
+ if(cmp > 0) pos ++;
+ }
+
+
+ // - Create a new client entry
+ ident_size = IPCType->GetIdentSize(Ident);
+ ret = malloc( sizeof(tIPC_Client) + ident_size );
+ if(!ret) return NULL;
+ ret->IPCType = IPCType;
+ ret->Ident = &ret + 1; // Get the end of the structure
+ memcpy( (void*)ret->Ident, Ident, ident_size );
+
+ // TODO: Register some way of detecting the client disconnecting
+ // > Wait on the thread / register with kernel somehow
+ // > Sockets are easier, but UDP is harder. Might get rid of it
+
+ // - Insert
+ giIPC_ClientCount ++;
+ gIPC_Clients = realloc(gIPC_Clients, giIPC_ClientCount*sizeof(tIPC_Client*));
+ memmove(&gIPC_Clients[pos+1], &gIPC_Clients[pos], (giIPC_ClientCount-pos-1) * sizeof(tIPC_Client*));
+ gIPC_Clients[pos] = ret;
+
+ return ret;
+}
+
+tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t WindowID)