/* * XmNap A Motif napster client * * Copyright (C) 2000 Mats Peterson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Please send any comments/bug reports to * mats_peterson@swipnet.se (Mats Peterson) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "main.h" #include "connect.h" #include "command.h" #include "search.h" #include "config.h" #include "configwin.h" #include "transfer.h" #include "shared.h" #include "hotlist.h" #include "input.h" #include "msgbox.h" #include "fsbox.h" #ifdef USE_SOUND #include "sound.h" #endif #include "util.h" static int tmpLinkType, tmpRegistered; static String tmpMinLink; static SERVER *tmpServers = NULL; static SHAREDDIR *tmpSharedDirs = NULL; static HOTLIST *tmpHotList = NULL; static AUTOCOMMAND *tmpAutoCommands = NULL; static int tmpShowPath; static int tmpTimeOut; #ifdef USE_SOUND #define LAST_PAGE 8 static String curSoundDir = NULL; #else #define LAST_PAGE 7 #endif static int configChanged; static int serverChanged; static int sharedDirChanged; static int hotListChanged; static int autoCmdChanged; static Widget configWin = NULL; static void DestroyConfigWin(void) { if (configWin) { XtUnmapWidget(XtParent(configWin)); XtDestroyWidget(XtParent(configWin)); configWin = curFocus = NULL; } } static void ConfigCB(Widget w, XtPointer clientData, XmPushButtonCallbackStruct *cbs) { SERVER *srv, *tmpSrv, *prevSrv = NULL; SHAREDDIR *dir, *tmpDir, *prevDir = NULL; SHARED *shared; HOTLIST *hot, *tmpHot, *prevHot = NULL; AUTOCOMMAND *cmd, *tmpCmd, *prevCmd = NULL; String p, tmp; Widget entry; int i; String userConfigEntryName[4] = {"*userConfig*userName", "*userConfig*passWord", "*userConfig*eMail", "*userConfig*dataPort"}; String searchConfigEntryName[3] = {"*searchConfig*minBitrate", "*searchConfig*minFreq", "*searchConfig*maxFiles"}; String *userInfoField[3] = {&userInfo.userName, &userInfo.passWord, &userInfo.eMail}; String *defSearchField[4] = {&defSearch.minBitrate, &defSearch.minFreq, &defSearch.maxFiles, &defSearch.minLink}; #ifdef USE_SOUND String soundConfigEntryName[NUM_SOUNDS] = {"*soundConfig*chanMsgSound", "*soundConfig*privMsgSound", "*soundConfig*joinSound", "*soundConfig*partSound"}; #endif switch (cbs->reason) { case XmCR_OK: for (i = 0; i < 4; i++) { entry = XtNameToWidget(w, userConfigEntryName[i]); tmp = XmTextFieldGetString(entry); if (i == 3) { if (userInfo.dataPort != atoi(tmp)) { userInfo.dataPort = atoi(tmp); SetDataPort(userInfo.dataPort, 1); configChanged = 1; } } else { if (strcmp(*userInfoField[i], tmp)) { XtFree(*userInfoField[i]); *userInfoField[i] = XtNewString(tmp); configChanged = 1; } } XtFree(tmp); } for (i = 0; i < 3; i++) { entry = XtNameToWidget(w, searchConfigEntryName[i]); tmp = XmTextFieldGetString(entry); if (strcmp(*defSearchField[i], tmp)) { XtFree(*defSearchField[i]); *defSearchField[i] = XtNewString(tmp); configChanged = 1; } XtFree(tmp); } #ifdef USE_SOUND for (i = 0; i < NUM_SOUNDS; i++) { entry = XtNameToWidget(w, soundConfigEntryName[i]); tmp = XmTextFieldGetString(entry); if (strcmp(sound[i], tmp)) { XtFree(sound[i]); sound[i] = XtNewString(tmp); configChanged = 1; } XtFree(tmp); } #endif entry = XtNameToWidget(w, "*miscConfig*timeOut"); tmp = XmTextFieldGetString(entry); if (timeOut != atoi(tmp)) { timeOut = atoi(tmp); configChanged = 1; } XtFree(tmp); entry = XtNameToWidget(w, "*miscConfig*initDlDir"); tmp = XmTextFieldGetString(entry); if (strcmp(initDlDir, tmp)) { XtFree(initDlDir); initDlDir = XtNewString(tmp); configChanged = 1; } XtFree(tmp); if (configChanged) { SimpleMsg("Saving configuration"); WriteConfig(); SimpleMsgRemove(); } break; case XmCR_CANCEL: case XmCR_PROTOCOLS: userInfo.linkType = tmpLinkType; userInfo.registered = tmpRegistered; XtFree(defSearch.minLink); defSearch.minLink = XtNewString(tmpMinLink); if (serverChanged) { while (servers) { XtFree(servers->name); p = (String)servers; servers = servers->next; XtFree(p); } for (tmpSrv = tmpServers; tmpSrv; tmpSrv = tmpSrv->next) { srv = XtNew(SERVER); srv->name = XtNewString(tmpSrv->name); srv->port = tmpSrv->port; srv->meta = tmpSrv->meta; srv->next = NULL; if (! prevSrv) servers = srv; else prevSrv->next = srv; prevSrv = srv; } } if (sharedDirChanged) { while (sharedDirs) { tmp = XtMalloc(PATH_MAX + 2); sprintf(tmp, "%s*", sharedDirs->dirName); for (shared = sharedFiles; shared; shared = shared->next) { if (! fnmatch(tmp, shared->fileName, 0)) RemoveSharedFile(shared->fileName); } XtFree(tmp); XtFree(sharedDirs->dirName); p = (String)sharedDirs; sharedDirs = sharedDirs->next; XtFree(p); } for (tmpDir = tmpSharedDirs; tmpDir; tmpDir = tmpDir->next) { dir = XtNew(SHAREDDIR); dir->dirName = XtNewString(tmpDir->dirName); dir->next = NULL; if (! prevDir) sharedDirs = dir; else prevDir->next = dir; prevDir = dir; (void)AddSharedFiles2(dir->dirName); } } if (hotListChanged) { while (hotList) RemoveHotList(hotList->nick); for (tmpHot = tmpHotList; tmpHot; tmpHot = tmpHot->next) { hot = XtNew(HOTLIST); hot->nick = XtNewString(tmpHot->nick); hot->next = NULL; if (! prevHot) hotList = hot; else prevHot->next = hot; prevHot = hot; AddHotList(hot->nick, 1); } } if (autoCmdChanged) { while (autoCommands) { XtFree(autoCommands->data); p = (String)autoCommands; autoCommands = autoCommands->next; XtFree(p); } for (tmpCmd = tmpAutoCommands; tmpCmd; tmpCmd = tmpCmd->next) { cmd = XtNew(AUTOCOMMAND); cmd->data = XtNewString(tmpCmd->data); cmd->next = NULL; if (! prevCmd) autoCommands = cmd; else prevCmd->next = cmd; prevCmd = cmd; } } showPath = tmpShowPath; timeOut = tmpTimeOut; } XtFree(tmpMinLink); while (tmpServers) { XtFree(tmpServers->name); p = (String)tmpServers; tmpServers = tmpServers->next; XtFree(p); } while (tmpSharedDirs) { XtFree(tmpSharedDirs->dirName); p = (String)tmpSharedDirs; tmpSharedDirs = tmpSharedDirs->next; XtFree(p); } while (tmpHotList) { XtFree(tmpHotList->nick); p = (String)tmpHotList; tmpHotList = tmpHotList->next; XtFree(p); } while (tmpAutoCommands) { XtFree(tmpAutoCommands->data); p = (String)tmpAutoCommands; tmpAutoCommands = tmpAutoCommands->next; XtFree(p); } DestroyConfigWin(); } static void ConfigEntryFocusCB(Widget w, XtPointer clientData, XmAnyCallbackStruct *cbs) { XtVaSetValues(w, XmNcursorPositionVisible, True, NULL); } static void ConfigEntryLosingFocusCB(Widget w, XtPointer clientData, XmTextVerifyCallbackStruct *cbs) { XtVaSetValues(w, XmNcursorPositionVisible, False, NULL); } static Widget ConfigForm(Widget parent, int page, String formName) { Widget form, title, rowCol; Arg args[20]; int n; form = XtVaCreateManagedWidget(formName, xmFormWidgetClass, parent, XmNmarginWidth, 15, XmNmarginHeight, 15, XmNnotebookChildType, XmPAGE, XmNpageNumber, page, NULL); n = 0; XtSetArg(args[n], XmNmarginHeight, 6); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; title = XmCreateLabel(form, "title", args, n); XtManageChild(title); rowCol = XtVaCreateManagedWidget("rowCol", xmRowColumnWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, title, XmNmarginWidth, 0, XmNtopOffset, 15, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); return form; } static Widget ConfigList(Widget parent, int page, String listName, XtCallbackProc callback) { Widget list; XmString xms; Arg args[20]; int n; String tmp; n = 0; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++; XtSetArg(args[n], XmNnotebookChildType, XmPAGE); n++; XtSetArg(args[n], XmNpageNumber, page); n++; list = XmCreateSelectionBox(parent, listName, args, n); XtManageChild(list); XtAddCallback (list, XmNokCallback, (XtCallbackProc)callback, NULL); XtVaGetValues(list, XmNapplyLabelString, &xms, NULL); XmStringGetLtoR(xms, XmFONTLIST_DEFAULT_TAG, &tmp); if (strlen(tmp)) { XtManageChild(XtNameToWidget(list, "Apply")); XtAddCallback (list, XmNapplyCallback, (XtCallbackProc)callback, NULL); } XtFree(tmp); XmStringFree(xms); XtAddCallback (list, XmNcancelCallback, (XtCallbackProc)callback, NULL); XtUnmanageChild(XtNameToWidget(list, "Help")); XtUnmanageChild(XtNameToWidget(list, "Text")); XtUnmanageChild(XtNameToWidget(list, "Selection")); return list; } static void UserConfigLinkCB(Widget w, XtPointer clientData, XtPointer cbs) { userInfo.linkType = (int)clientData; configChanged = 1; } static void UserConfigRegCB(Widget w, XtPointer clientData, XmToggleButtonCallbackStruct *cbs) { userInfo.registered = (cbs->set == XmSET) ? 1 : 0; configChanged = 1; } static void UserConfig(Widget parent) { String values[6]; char dataPort[10]; Widget pageForm, rowCol, form, label, entry = NULL; Widget linkMenu, regToggle; Arg args[20]; XmString toggleString; XmString optLabel[11]; int i, j, n; Dimension labelWidth, labelMaxWidth = 0; char labelName[20]; String entryName[] = {"userName", "passWord", "eMail", "dataPort"}; pageForm = ConfigForm(parent, 1, "userConfig"); rowCol = XtNameToWidget(pageForm, "rowCol"); values[0] = userInfo.userName; values[1] = userInfo.passWord; values[2] = userInfo.eMail; sprintf(dataPort, "%d", userInfo.dataPort); values[3] = dataPort; for (i = 0; i < 6; i++) { form = XtVaCreateWidget("form", xmFormWidgetClass, rowCol, NULL); sprintf(labelName, "label_%d", i); n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNmarginHeight, 6); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; label = XmCreateLabel(form, labelName, args, n); XtManageChild(label); XtVaGetValues(label, XmNwidth, &labelWidth, NULL); if (labelWidth > labelMaxWidth) labelMaxWidth = labelWidth; if (i == 4) { for (j = 0; j < 11; j++) optLabel[j] = XmStringCreateLocalized (linkStr[j]); linkMenu = XmVaCreateSimpleOptionMenu (form, "linkMenu", NULL, 0, userInfo.linkType, UserConfigLinkCB, XmVaPUSHBUTTON, optLabel[0], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[1], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[2], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[3], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[4], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[5], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[6], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[7], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[8], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[9], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[10], NULL, NULL, NULL, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, label, XmNleftOffset, 20, XmNmarginWidth, 0, XmNmarginHeight, 0, NULL); for (j = 0; j < 11; j++) XmStringFree(optLabel[j]); XtUnmanageChild(XtNameToWidget(linkMenu, "OptionLabel")); XtManageChild (linkMenu); } else if (i == 5) { toggleString = XmStringCreateLocalized(" "); regToggle = XtVaCreateManagedWidget("regToggle", xmToggleButtonWidgetClass, form, XmNlabelString, toggleString, XmNindicatorOn, XmINDICATOR_CROSS_BOX, XmNset, userInfo.registered ? XmSET : XmUNSET, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, label, XmNleftOffset, 20, NULL); XmStringFree(toggleString); XtAddCallback(regToggle, XmNvalueChangedCallback, (XtCallbackProc)UserConfigRegCB, NULL); } else { n = 0; XtSetArg(args[n], XmNcursorPositionVisible, False); n++; XtSetArg(args[n], XmNmarginWidth, 5); n++; XtSetArg(args[n], XmNmarginHeight, 2); n++; XtSetArg(args[n], XmNcolumns, 30); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, label); n++; XtSetArg(args[n], XmNleftOffset, 20); n++; entry = XmCreateTextField(form, entryName[i], args, n); XtManageChild(entry); XmTextFieldSetString(entry, values[i]); XtAddCallback(entry, XmNfocusCallback, (XtCallbackProc)ConfigEntryFocusCB, NULL); XtAddCallback(entry, XmNlosingFocusCallback, (XtCallbackProc)ConfigEntryLosingFocusCB, NULL); } XtManageChild(form); } for (i = 0; i < 6; i++) { sprintf(labelName, "form.label_%d", i); XtVaSetValues(XtNameToWidget(rowCol, labelName), XmNwidth, labelMaxWidth, NULL); } } static void SearchConfigLinkCB(Widget w, XtPointer clientData, XtPointer cbs) { XtFree(defSearch.minLink); defSearch.minLink = XtMalloc(5); sprintf(defSearch.minLink, "%d", (int)clientData); configChanged = 1; } static void SearchConfig(Widget parent) { String values[4]; Widget pageForm, rowCol, form, label, entry = NULL, linkMenu; Arg args[20]; XmString optLabel[11]; int i, j, n; Dimension labelWidth, labelMaxWidth = 0; char labelName[20]; String entryName[] = {"minBitrate", "minFreq", "maxFiles"}; pageForm = ConfigForm(parent, 2, "searchConfig"); rowCol = XtNameToWidget(pageForm, "rowCol"); values[0] = defSearch.minBitrate; values[1] = defSearch.minFreq; values[2] = defSearch.maxFiles; for (i = 0; i < 4; i++) { form = XtVaCreateWidget("form", xmFormWidgetClass, rowCol, NULL); sprintf(labelName, "label_%d", i); n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNmarginHeight, 6); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; label = XmCreateLabel(form, labelName, args, n); XtManageChild(label); XtVaGetValues(label, XmNwidth, &labelWidth, NULL); if (labelWidth > labelMaxWidth) labelMaxWidth = labelWidth; if (i == 3) { for (j = 0; j < 11; j++) optLabel[j] = XmStringCreateLocalized (linkStr[j]); linkMenu = XmVaCreateSimpleOptionMenu (form, "linkMenu", NULL, 0, atoi(defSearch.minLink), SearchConfigLinkCB, XmVaPUSHBUTTON, optLabel[0], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[1], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[2], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[3], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[4], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[5], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[6], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[7], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[8], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[9], NULL, NULL, NULL, XmVaPUSHBUTTON, optLabel[10], NULL, NULL, NULL, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, label, XmNleftOffset, 20, XmNmarginWidth, 0, XmNmarginHeight, 0, NULL); for (j = 0; j < 11; j++) XmStringFree(optLabel[j]); XtUnmanageChild(XtNameToWidget(linkMenu, "OptionLabel")); XtManageChild (linkMenu); } else { n = 0; XtSetArg(args[n], XmNcursorPositionVisible, False); n++; XtSetArg(args[n], XmNmarginWidth, 5); n++; XtSetArg(args[n], XmNmarginHeight, 2); n++; XtSetArg(args[n], XmNcolumns, 10); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, label); n++; XtSetArg(args[n], XmNleftOffset, 20); n++; entry = XmCreateTextField(form, entryName[i], args, n); XtManageChild(entry); XmTextFieldSetString(entry, values[i]); XtAddCallback(entry, XmNfocusCallback, (XtCallbackProc)ConfigEntryFocusCB, NULL); XtAddCallback(entry, XmNlosingFocusCallback, (XtCallbackProc)ConfigEntryLosingFocusCB, NULL); } XtManageChild(form); } for (i = 0; i < 4; i++) { sprintf(labelName, "form.label_%d", i); XtVaSetValues(XtNameToWidget(rowCol, labelName), XmNwidth, labelMaxWidth, NULL); } } static void UpdateServerList(Widget list) { String tmp = XtMalloc(256); int numServers, i; XmString *str; SERVER *srv; String srvType[2] = {"Normal", "Meta"}; for (numServers = 0, srv = servers; srv; numServers++, srv = srv->next); str = (XmString*)XtMalloc(numServers * sizeof(XmString)); for (i = 0, srv = servers; i < numServers; i++, srv = srv->next) { sprintf(tmp, "%-30.29s%-10d%s", srv->name, srv->port, srvType[srv->meta]); str[i] = XmStringCreateLocalized(tmp); } XtVaSetValues(list, XmNlistItems, str, XmNlistItemCount, numServers, NULL); for (i = 0; i < numServers; i++) XmStringFree (str[i]); XtFree((String)str); XtFree(tmp); } static void SrvListCB(Widget w, XtPointer clientData, XmSelectionBoxCallbackStruct *cbs) { Widget list, shell; int i, *pos; SERVER *newSrv, *srv, *prevSrv = NULL; String srvString, srvName, portString, metaString; XmPushButtonCallbackStruct cbs2; switch (cbs->reason) { case XmCR_OK: list = XtNameToWidget(w, "ItemsListSW.ItemsList"); XtVaGetValues(list, XmNselectedPositions, &pos, NULL); if (! pos) return; cbs2.reason = XmCR_OK; for (shell = w; ! XtIsShell(shell); shell = XtParent(shell)); XtCallCallbacks(XtNameToWidget(shell, "configWin"), XmNokCallback, (XtPointer)&cbs2); for (i = 0, srv = servers; i < ((*pos) - 1); i++, srv = srv->next); if (srvConn) Disconnect(""); Connect(srv->name, srv->port, srv->meta); return; case XmCR_APPLY: srvString = GetInput("Server (name:port:meta)", "", 30); if (! strlen(srvString)) return; if (! SplitServer(srvString, &srvName, &portString, &metaString)) { ErrMsg("Invalid server format"); return; } newSrv = XtNew(SERVER); newSrv->name = XtNewString(srvName); newSrv->port = atoi(portString); newSrv->meta = atoi(metaString); newSrv->next = NULL; if (! servers) servers = newSrv; else { for (srv = servers; srv->next; srv = srv->next); srv->next = newSrv; } break; case XmCR_CANCEL: list = XtNameToWidget(w, "ItemsListSW.ItemsList"); XtVaGetValues(list, XmNselectedPositions, &pos, NULL); if (! pos) return; for (i = 0, srv = servers; i < ((*pos) - 1); i++, srv = srv->next) { prevSrv = srv; } if (prevSrv) { prevSrv->next = srv->next; } else { servers = servers->next; } XtFree(srv->name); XtFree((char*)srv); } if (servers) { if (curServer.name) XtFree(curServer.name); curServer.name = XtNewString(servers->name); curServer.port = servers->port; curServer.meta = servers->meta; } UpdateServerList(w); serverChanged = 1; configChanged = 1; } static void ServerConfig(Widget parent) { Widget serverList; serverList = ConfigList(parent, 3, "serverConfig", (XtCallbackProc)SrvListCB); if (! servers) return; UpdateServerList(serverList); } static void UpdateSharedDirList(Widget list) { int numDirs, i; XmString *str; SHAREDDIR *dir; for (numDirs = 0, dir = sharedDirs; dir; numDirs++, dir = dir->next); str = (XmString*)XtMalloc(numDirs * sizeof(XmString)); for (i = 0, dir = sharedDirs; i < numDirs; i++, dir = dir->next) str[i] = XmStringCreateLocalized(dir->dirName); XtVaSetValues(list, XmNlistItems, str, XmNlistItemCount, numDirs, NULL); for (i = 0; i < numDirs; i++) XmStringFree (str[i]); XtFree((String)str); } static void SharedDirListCB(Widget w, XtPointer clientData, XmSelectionBoxCallbackStruct *cbs) { Widget list; int i, *pos; SHAREDDIR *dir; switch (cbs->reason) { case XmCR_OK: if (! AddSharedFiles()) return; break; case XmCR_CANCEL: list = XtNameToWidget(w, "ItemsListSW.ItemsList"); XtVaGetValues(list, XmNselectedPositions, &pos, NULL); if (! pos) return; for (i = 0, dir = sharedDirs; i < ((*pos) - 1); i++, dir = dir->next); if (! RemoveSharedFiles(dir->dirName)) return; } UpdateSharedDirList(w); sharedDirChanged = 1; configChanged = 1; } static void SharedDirConfig(Widget parent) { Widget sharedDirList; sharedDirList = ConfigList(parent, 4, "sharedConfig", (XtCallbackProc)SharedDirListCB); if (! sharedDirs) return; UpdateSharedDirList(sharedDirList); } static void UpdateHotList(Widget list) { int numHot, i; XmString *str; HOTLIST *hot; for (numHot = 0, hot = hotList; hot; numHot++, hot = hot->next); str = (XmString*)XtMalloc(numHot * sizeof(XmString)); for (i = 0, hot = hotList; i < numHot; i++, hot = hot->next) str[i] = XmStringCreateLocalized(hot->nick); XtVaSetValues(list, XmNlistItems, str, XmNlistItemCount, numHot, NULL); for (i = 0; i < numHot; i++) XmStringFree (str[i]); XtFree((String)str); } static void HotListCB(Widget w, XtPointer clientData, XmSelectionBoxCallbackStruct *cbs) { Widget list; int *pos; String nick; switch (cbs->reason) { case XmCR_OK: nick = GetInput("User", "", 30); if (! strlen(nick)) return; AddHotList(nick, 1); break; case XmCR_CANCEL: list = XtNameToWidget(w, "ItemsListSW.ItemsList"); XtVaGetValues(list, XmNselectedPositions, &pos, NULL); if (! pos) return; RemoveHotList2((*pos) - 1); } UpdateHotList(w); hotListChanged = 1; configChanged = 1; } static void HotListConfig(Widget parent) { Widget hotList; hotList = ConfigList(parent, 5, "hotlistConfig", (XtCallbackProc)HotListCB); if (! hotList) return; UpdateHotList(hotList); } static void UpdateAutoCmdList(Widget list) { int numCmds, i; XmString *str; AUTOCOMMAND *cmd; for (numCmds = 0, cmd = autoCommands; cmd; numCmds++, cmd = cmd->next); str = (XmString*)XtMalloc(numCmds * sizeof(XmString)); for (i = 0, cmd = autoCommands; i < numCmds; i++, cmd = cmd->next) str[i] = XmStringCreateLocalized(cmd->data); XtVaSetValues(list, XmNlistItems, str, XmNlistItemCount, numCmds, NULL); for (i = 0; i < numCmds; i++) XmStringFree (str[i]); XtFree((String)str); } static void AutoCmdListCB(Widget w, XtPointer clientData, XmSelectionBoxCallbackStruct *cbs) { Widget list; int i, *pos; AUTOCOMMAND *newCmd, *cmd, *prevCmd = NULL; String cmdString; switch (cbs->reason) { case XmCR_OK: cmdString = GetInput("Command", "", 40); if (! strlen(cmdString)) return; newCmd = XtNew(AUTOCOMMAND); newCmd->data = XtNewString(cmdString); newCmd->next = NULL; if (! autoCommands) autoCommands = newCmd; else { for (cmd = autoCommands; cmd->next; cmd = cmd->next); cmd->next = newCmd; } break; case XmCR_CANCEL: list = XtNameToWidget(w, "ItemsListSW.ItemsList"); XtVaGetValues(list, XmNselectedPositions, &pos, NULL); if (! pos) return; for (i = 0, cmd = autoCommands; i < ((*pos) - 1); i++, cmd = cmd->next) { prevCmd = cmd; } if (prevCmd) prevCmd->next = cmd->next; else autoCommands = autoCommands->next; XtFree(cmd->data); XtFree((char*)cmd); } UpdateAutoCmdList(w); autoCmdChanged = 1; configChanged = 1; } static void AutoCmdConfig(Widget parent) { Widget autoCmdList; autoCmdList = ConfigList(parent, 6, "autoCmdConfig", (XtCallbackProc)AutoCmdListCB); if (! autoCommands) return; UpdateAutoCmdList(autoCmdList); } #ifdef USE_SOUND static void SoundBtnCB(Widget w, XtPointer clientData, XmPushButtonCallbackStruct *cbs) { Widget entry = (Widget)clientData; String tmp, dir, tail, name; if (! curSoundDir) curSoundDir = XtNewString(getenv("HOME")); tmp = XmTextFieldGetString(entry); if ((tail = strrchr(tmp, '/'))) { dir = GetDir(tmp); tail += 1; } else { dir = XtNewString(curSoundDir); tail = ""; } name = OpenFile(dir, tail); if (! *name) goto exit; if (CheckWav(name) == -1) goto exit; XmTextFieldSetString(entry, name); XtFree(curSoundDir); curSoundDir = GetDir(name); exit: XtFree(tmp); XtFree(dir); } static void SoundConfig(Widget parent) { Widget pageForm, rowCol, form, label, entry = NULL, btn; Arg args[20]; int i, n; Dimension labelWidth, labelMaxWidth = 0; char labelName[20], btnName[20]; String entryName[] = {"chanMsgSound", "privMsgSound", "joinSound", "partSound"}; pageForm = ConfigForm(parent, 7, "soundConfig"); rowCol = XtNameToWidget(pageForm, "rowCol"); for (i = 0; i < NUM_SOUNDS; i++) { form = XtVaCreateWidget("form", xmFormWidgetClass, rowCol, NULL); sprintf(labelName, "label_%d", i); n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNmarginHeight, 6); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; label = XmCreateLabel(form, labelName, args, n); XtManageChild(label); XtVaGetValues(label, XmNwidth, &labelWidth, NULL); if (labelWidth > labelMaxWidth) labelMaxWidth = labelWidth; sprintf(btnName, "button_%d", i); btn = XtVaCreateManagedWidget(btnName, xmPushButtonWidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); n = 0; XtSetArg(args[n], XmNcursorPositionVisible, False); n++; XtSetArg(args[n], XmNmarginWidth, 5); n++; XtSetArg(args[n], XmNmarginHeight, 2); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, label); n++; XtSetArg(args[n], XmNleftOffset, 20); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, btn); n++; XtSetArg(args[n], XmNrightOffset, 10); n++; XtSetArg(args[n], XmNcolumns, 25); n++; entry = XmCreateTextField(form, entryName[i], args, n); XtAddCallback(btn, XmNactivateCallback, (XtCallbackProc)SoundBtnCB, (XtPointer)entry); XtAddCallback(entry, XmNfocusCallback, (XtCallbackProc)ConfigEntryFocusCB, NULL); XtAddCallback(entry, XmNlosingFocusCallback, (XtCallbackProc)ConfigEntryLosingFocusCB, NULL); XtManageChild(entry); XmTextFieldSetString(entry, sound[i]); XtManageChild(form); } for (i = 0; i < NUM_SOUNDS; i++) { sprintf(labelName, "form.label_%d", i); XtVaSetValues(XtNameToWidget(rowCol, labelName), XmNwidth, labelMaxWidth, NULL); } } #endif static void MiscConfigShowPathCB(Widget w, XtPointer clientData, XmToggleButtonCallbackStruct *cbs) { showPath = (cbs->set == XmSET) ? 1 : 0; configChanged = 1; } static void DirBtnCB(Widget w, XtPointer clientData, XmPushButtonCallbackStruct *cbs) { Widget entry = (Widget)clientData; String tmp, dir; tmp = XmTextFieldGetString(entry); dir = ChooseDir(tmp); XtFree(tmp); if (! strlen(dir)) return; XmTextFieldSetString(entry, dir); } static void MiscConfig(Widget parent) { String values[3]; char timeOutStr[5]; Widget pageForm, rowCol, form, label, entry = NULL; Widget showPathToggle, dirBtn; Arg args[20]; XmString toggleString; int i, n; Dimension labelWidth, labelMaxWidth = 0; char labelName[20]; String entryName[] = {"timeOut", "initDlDir"}; pageForm = ConfigForm(parent, LAST_PAGE, "miscConfig"); rowCol = XtNameToWidget(pageForm, "rowCol"); sprintf(timeOutStr, "%d", timeOut); values[1] = timeOutStr; values[2] = initDlDir; for (i = 0; i < 3; i++) { form = XtVaCreateWidget("form", xmFormWidgetClass, rowCol, NULL); sprintf(labelName, "label_%d", i); n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNmarginHeight, 6); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; label = XmCreateLabel(form, labelName, args, n); XtManageChild(label); XtVaGetValues(label, XmNwidth, &labelWidth, NULL); if (labelWidth > labelMaxWidth) labelMaxWidth = labelWidth; if (! i) { toggleString = XmStringCreateLocalized(" "); showPathToggle = XtVaCreateManagedWidget("showPathToggle", xmToggleButtonWidgetClass, form, XmNlabelString, toggleString, XmNindicatorOn, XmINDICATOR_CROSS_BOX, XmNset, showPath ? XmSET : XmUNSET, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, label, XmNleftOffset, 20, NULL); XmStringFree(toggleString); XtAddCallback(showPathToggle, XmNvalueChangedCallback, (XtCallbackProc)MiscConfigShowPathCB, NULL); } else { n = 0; XtSetArg(args[n], XmNcursorPositionVisible, False); n++; XtSetArg(args[n], XmNmarginWidth, 5); n++; XtSetArg(args[n], XmNmarginHeight, 2); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, label); n++; XtSetArg(args[n], XmNleftOffset, 20); n++; if (i == 2) { dirBtn = XtVaCreateManagedWidget("dirBtn", xmPushButtonWidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, dirBtn); n++; XtSetArg(args[n], XmNrightOffset, 10); n++; XtSetArg(args[n], XmNcolumns, 20); n++; entry = XmCreateTextField(form, entryName[i - 1], args, n); XtAddCallback(dirBtn, XmNactivateCallback, (XtCallbackProc)DirBtnCB, (XtPointer)entry); } else { XtSetArg(args[n], XmNcolumns, 5); n++; entry = XmCreateTextField(form, entryName[i - 1], args, n); } XtAddCallback(entry, XmNfocusCallback, (XtCallbackProc)ConfigEntryFocusCB, NULL); XtAddCallback(entry, XmNlosingFocusCallback, (XtCallbackProc)ConfigEntryLosingFocusCB, NULL); XtManageChild(entry); XmTextFieldSetString(entry, values[i]); } XtManageChild(form); } for (i = 0; i < 3; i++) { sprintf(labelName, "form.label_%d", i); XtVaSetValues(XtNameToWidget(rowCol, labelName), XmNwidth, labelMaxWidth, NULL); } } static void Backup(void) { SERVER *srv, *tmpSrv, *prevSrv = NULL; SHAREDDIR *dir, *tmpDir, *prevDir = NULL; HOTLIST *hot, *tmpHot, *prevHot = NULL; AUTOCOMMAND *cmd, *tmpCmd, *prevCmd = NULL; tmpLinkType = userInfo.linkType; tmpRegistered = userInfo.registered; tmpMinLink = XtNewString(defSearch.minLink); for (srv = servers; srv; srv = srv->next) { tmpSrv = XtNew(SERVER); tmpSrv->name = XtNewString(srv->name); tmpSrv->port = srv->port; tmpSrv->meta = srv->meta; tmpSrv->next = NULL; if (! prevSrv) tmpServers = tmpSrv; else prevSrv->next = tmpSrv; prevSrv = tmpSrv; } for (dir = sharedDirs; dir; dir = dir->next) { tmpDir = XtNew(SHAREDDIR); tmpDir->dirName = XtNewString(dir->dirName); tmpDir->next = NULL; if (! prevDir) tmpSharedDirs = tmpDir; else prevDir->next = tmpDir; prevDir = tmpDir; } for (hot = hotList; hot; hot = hot->next) { tmpHot = XtNew(HOTLIST); tmpHot->nick = XtNewString(hot->nick); tmpHot->next = NULL; if (! prevHot) tmpHotList = tmpHot; else prevHot->next = tmpHot; prevHot = tmpHot; } for (cmd = autoCommands; cmd; cmd = cmd->next) { tmpCmd = XtNew(AUTOCOMMAND); tmpCmd->data = XtNewString(cmd->data); tmpCmd->next = NULL; if (! prevCmd) tmpAutoCommands = tmpCmd; else prevCmd->next = tmpCmd; prevCmd = tmpCmd; } tmpShowPath = showPath; tmpTimeOut = timeOut; } void ConfigWin(int pageNum) { Widget shell, configNB; Arg args[20]; #ifdef USE_SOUND String pageName[] = {"userConfig", "searchConfig", "serverConfig", "sharedConfig", "hotlistConfig", "autoCmdConfig", "soundConfig", "miscConfig", NULL}; #else String pageName[] = {"userConfig", "searchConfig", "serverConfig", "sharedConfig", "hotlistConfig", "autoCmdConfig", "miscConfig", NULL}; #endif String tabName; int i, n; DestroyConfigWin(); shell = XtVaCreatePopupShell("configWin_popup", topLevelShellWidgetClass, topLevel, XmNiconPixmap, napPix, NULL); n = 0; XtSetArg(args[n], XmNautoUnmanage, False); n++; XtSetArg(args[n], XmNdefaultPosition, False); n++; XtSetArg(args[n], XmNnoResize, True); n++; XtSetArg(args[n], XmNmessageAlignment, XmALIGNMENT_CENTER); n++; configWin = XmCreateMessageBox(shell, "configWin", args, n); XtUnmanageChild(XtNameToWidget(configWin, "Help")); n = 0; XtSetArg(args[n], XmNbindingType, XmNONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; configNB = XmCreateNotebook(configWin, "configNB", args, n); XtManageChild(configNB); XtAddCallback(configWin, XmNokCallback, (XtCallbackProc)ConfigCB, NULL); XtAddCallback(configWin, XmNcancelCallback, (XtCallbackProc)ConfigCB, NULL); XmAddWMProtocolCallback(XtParent(configWin), XmInternAtom(XtDisplay(configWin), "WM_DELETE_WINDOW", False), (XtCallbackProc)ConfigCB, NULL); XtAddCallback(configWin, XmNfocusCallback, (XtCallbackProc)FocusCB, NULL); XmAddWMProtocolCallback(topLevel, XmInternAtom(XtDisplay(topLevel), "WM_DELETE_WINDOW", False), (XtCallbackProc)ConfigCB, NULL); for (i = 0; pageName[i]; i++) { tabName = XtMalloc(strlen(pageName[i]) + sizeof("Tab") + 1); sprintf(tabName, "%sTab", pageName[i]); (void)XtVaCreateManagedWidget(tabName, xmPushButtonWidgetClass, configNB, XmNnotebookChildType, XmMAJOR_TAB, XmNpageNumber, i + 1, NULL); XtFree(tabName); } Backup(); UserConfig(configNB); SearchConfig(configNB); ServerConfig(configNB); SharedDirConfig(configNB); HotListConfig(configNB); AutoCmdConfig(configNB); #ifdef USE_SOUND SoundConfig(configNB); #endif MiscConfig(configNB); serverChanged = sharedDirChanged = hotListChanged = autoCmdChanged = configChanged = 0; XtVaSetValues(configNB, XmNinitialFocus, XtNameToWidget(configNB, pageName[pageNum - 1]), NULL); XtVaSetValues(configWin, XmNinitialFocus, configNB, NULL); XtManageChild(configWin); XtPopup(shell, XtGrabNone); XtVaSetValues(configNB, XmNcurrentPageNumber, pageNum, NULL); } .