+ \r
+ // Append to open list\r
+ ret->Next = gpServers;\r
+ gpServers = ret;\r
+ \r
+ // Read some initial data\r
+ Message_Append(NULL, MSG_TYPE_SERVER, Name, "", "Connection opened");\r
+ ProcessIncoming(ret);\r
+ \r
+ // Identify\r
+ writef(ret->FD, "USER %s %s %s : %s\n", gsUsername, gsHostname, AddressString, gsRealName);\r
+ writef(ret->FD, "NICK %s\n", gsNickname);\r
+ Message_Append(NULL, MSG_TYPE_SERVER, Name, "", "Identified");\r
+ //printf("%s: Identified\n", Name);\r
+ \r
+ return ret;\r
+}\r
+\r
+tMessage *Message_AppendF(tServer *Server, int Type, const char *Source, const char *Dest, const char *Message, ...)\r
+{\r
+ va_list args;\r
+ int len;\r
+ va_start(args, Message);\r
+ len = vsnprintf(NULL, 1000, Message, args);\r
+ {\r
+ char buf[len+1];\r
+ vsnprintf(buf, len+1, Message, args);\r
+ return Message_Append(Server, Type, Source, Dest, buf);\r
+ }\r
+}\r
+\r
+tMessage *Message_Append(tServer *Server, int Type, const char *Source, const char *Dest, const char *Message)\r
+{\r
+ tMessage *ret;\r
+ tWindow *win = NULL;\r
+ int msgLen = strlen(Message);\r
+ \r
+ // NULL servers are internal messages\r
+ if( Server == NULL || Source[0] == '\0' )\r
+ {\r
+ win = &gWindow_Status;\r
+ }\r
+ // Determine if it's a channel or PM message\r
+ else if( Dest[0] == '#' || Dest[0] == '&' ) // TODO: Better determining here\r
+ {\r
+ tWindow *prev = NULL;\r
+ for(win = gpWindows; win; prev = win, win = win->Next)\r
+ {\r
+ if( win->Server == Server && strcmp(win->Name, Dest) == 0 )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ if( !win ) {\r
+ win = Window_Create(Server, Dest);\r
+ }\r
+ }\r
+ #if 0\r
+ else if( strcmp(Dest, Server->Nick) != 0 )\r
+ {\r
+ // Umm... message for someone who isn't us?\r
+ win = &gWindow_Status; // Stick it in the status window, just in case\r
+ }\r
+ #endif\r
+ // Server message?\r
+ else if( strchr(Source, '.') ) // TODO: And again, less hack please\r
+ {\r
+ #if 1\r
+ for(win = gpWindows; win; win = win->Next)\r
+ {\r
+ if( win->Server == Server && strcmp(win->Name, Source) == 0 )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ #endif\r
+ if( !win ) {\r
+ win = &gWindow_Status;\r
+ }\r
+ \r
+ }\r
+ // Private message\r
+ else\r
+ {\r
+ for(win = gpWindows; win; win = win->Next)\r
+ {\r
+ if( win->Server == Server && strcmp(win->Name, Source) == 0 )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ if( !win ) {\r
+ win = Window_Create(Server, Dest);\r
+ }\r
+ }\r
+ \r
+ ret = malloc( sizeof(tMessage) + msgLen + 1 + strlen(Source) + 1 );\r
+ ret->Source = ret->Data + msgLen + 1;\r
+ strcpy(ret->Source, Source);\r
+ strcpy(ret->Data, Message);\r
+ ret->Type = Type;\r
+ ret->Server = Server;\r
+ \r
+ // TODO: Append to window message list\r
+ ret->Next = win->Messages;\r
+ win->Messages = ret;\r
+ \r
+ //TODO: Set location\r
+ \r
+ {\r
+ int pos = SetCursorPos(giTerminal_Height-2, 0);\r
+ if( win == gpCurrentWindow ) {\r
+ int prefixlen = strlen(Source) + 3;\r
+ int avail = giTerminal_Width - prefixlen;\r
+ int msglen = strlen(Message);\r
+ printf("\x1B[T"); // Scroll down 1 (free space below)\r
+ printf("[%s] %.*s\n", Source, avail, Message);\r
+ while( msglen > avail ) {\r
+ msglen -= avail;\r
+ Message += avail;\r
+ printf("\x1B[T");\r
+ SetCursorPos(giTerminal_Height-2, prefixlen);\r
+ printf("%.*s\n", avail, Message);\r
+ }\r
+ }\r
+ SetCursorPos(-1, pos);\r