1 /* per-channel/dialog settings :: /CHANOPT */
21 static GSList
*chanopt_list
= NULL
;
22 static gboolean chanopt_open
= FALSE
;
23 static gboolean chanopt_changed
= FALSE
;
29 char *alias
; /* old names from 2.8.4 */
33 #define S_F(xx) STRUCT_OFFSET_STR(struct session,xx)
35 static const channel_options chanopt
[] =
37 {"alert_beep", "BEEP", S_F(alert_beep
)},
38 {"alert_taskbar", NULL
, S_F(alert_taskbar
)},
39 {"alert_tray", "TRAY", S_F(alert_tray
)},
41 {"text_hidejoinpart", "CONFMODE", S_F(text_hidejoinpart
)},
42 {"text_logging", NULL
, S_F(text_logging
)},
43 {"text_scrollback", NULL
, S_F(text_scrollback
)},
49 chanopt_value (guint8 val
)
62 /* handle the /CHANOPT command */
65 chanopt_command (session
*sess
, char *tbuf
, char *word
[], char *word_eol
[])
67 int dots
, i
= 0, j
, p
= 0;
71 gboolean quiet
= FALSE
;
74 if (!strcmp (word
[2], "-quiet"))
80 find
= word
[offset
++];
84 if (!strcasecmp (word
[offset
], "ON"))
86 else if (!strcasecmp (word
[offset
], "OFF"))
88 else if (word
[offset
][0] == 'u')
91 newval
= atoi (word
[offset
]);
95 PrintTextf (sess
, "\002Network\002: %s \002Channel\002: %s\n",
96 sess
->server
->network
? server_get_network (sess
->server
, TRUE
) : _("<none>"),
97 sess
->channel
[0] ? sess
->channel
: _("<none>"));
99 while (i
< sizeof (chanopt
) / sizeof (channel_options
))
101 if (find
[0] == 0 || match (find
, chanopt
[i
].name
) || (chanopt
[i
].alias
&& match (find
, chanopt
[i
].alias
)))
103 if (newval
!= -1) /* set new value */
105 *(guint8
*)G_STRUCT_MEMBER_P(sess
, chanopt
[i
].offset
) = newval
;
108 if (!quiet
) /* print value */
110 strcpy (tbuf
, chanopt
[i
].name
);
116 dots
= 20 - strlen (chanopt
[i
].name
);
118 for (j
= 0; j
< dots
; j
++)
122 val
= G_STRUCT_MEMBER (guint8
, sess
, chanopt
[i
].offset
);
123 PrintTextf (sess
, "%s\0033:\017 %s", tbuf
, chanopt_value (val
));
132 /* is a per-channel setting set? Or is it UNSET and
133 * the global version is set? */
136 chanopt_is_set (unsigned int global
, guint8 per_chan_setting
)
138 if (per_chan_setting
== SET_DEFAULT
)
141 return per_chan_setting
;
144 /* additive version */
147 chanopt_is_set_a (unsigned int global
, guint8 per_chan_setting
)
149 if (per_chan_setting
== SET_DEFAULT
)
152 return per_chan_setting
|| global
;
155 /* === below is LOADING/SAVING stuff only === */
159 /* Per-Channel Alerts */
160 /* use a byte, because we need a pointer to each element */
162 guint8 alert_taskbar
;
165 /* Per-Channel Settings */
166 guint8 text_hidejoinpart
;
168 guint8 text_scrollback
;
176 static chanopt_in_memory
*
177 chanopt_find (char *network
, char *channel
, gboolean add_new
)
180 chanopt_in_memory
*co
;
183 for (list
= chanopt_list
; list
; list
= list
->next
)
186 if (!strcasecmp (co
->channel
, channel
) &&
187 !strcasecmp (co
->network
, network
))
194 /* allocate a new one */
195 co
= g_malloc0 (sizeof (chanopt_in_memory
));
196 co
->channel
= g_strdup (channel
);
197 co
->network
= g_strdup (network
);
199 /* set all values to SET_DEFAULT */
201 while (i
< sizeof (chanopt
) / sizeof (channel_options
))
203 *(guint8
*)G_STRUCT_MEMBER_P(co
, chanopt
[i
].offset
) = SET_DEFAULT
;
207 chanopt_list
= g_slist_prepend (chanopt_list
, co
);
208 chanopt_changed
= TRUE
;
214 chanopt_add_opt (chanopt_in_memory
*co
, char *var
, int new_value
)
219 while (i
< sizeof (chanopt
) / sizeof (channel_options
))
221 if (!strcmp (var
, chanopt
[i
].name
))
223 *(guint8
*)G_STRUCT_MEMBER_P(co
, chanopt
[i
].offset
) = new_value
;
230 /* load chanopt.conf from disk into our chanopt_list GSList */
233 chanopt_load_all (void)
238 char *network
= NULL
;
239 chanopt_in_memory
*current
= NULL
;
241 /* 1. load the old file into our GSList */
242 fh
= xchat_open_file ("chanopt.conf", O_RDONLY
, 0, 0);
245 while (waitline (fh
, buf
, sizeof buf
, FALSE
) != -1)
247 eq
= strchr (buf
, '=');
252 if (eq
!= buf
&& eq
[-1] == ' ')
255 if (!strcmp (buf
, "network"))
258 network
= g_strdup (eq
+ 2);
260 else if (!strcmp (buf
, "channel"))
262 current
= chanopt_find (network
, eq
+ 2, TRUE
);
263 chanopt_changed
= FALSE
;
268 chanopt_add_opt (current
, buf
, atoi (eq
+ 2));
278 chanopt_load (session
*sess
)
282 chanopt_in_memory
*co
;
285 if (sess
->channel
[0] == 0)
288 network
= server_get_network (sess
->server
, FALSE
);
298 co
= chanopt_find (network
, sess
->channel
, FALSE
);
302 /* fill in all the sess->xxxxx fields */
304 while (i
< sizeof (chanopt
) / sizeof (channel_options
))
306 val
= G_STRUCT_MEMBER(guint8
, co
, chanopt
[i
].offset
);
307 *(guint8
*)G_STRUCT_MEMBER_P(sess
, chanopt
[i
].offset
) = val
;
313 chanopt_save (session
*sess
)
318 chanopt_in_memory
*co
;
321 if (sess
->channel
[0] == 0)
324 network
= server_get_network (sess
->server
, FALSE
);
328 /* 2. reconcile sess with what we loaded from disk */
330 co
= chanopt_find (network
, sess
->channel
, TRUE
);
333 while (i
< sizeof (chanopt
) / sizeof (channel_options
))
335 vals
= G_STRUCT_MEMBER(guint8
, sess
, chanopt
[i
].offset
);
336 valm
= G_STRUCT_MEMBER(guint8
, co
, chanopt
[i
].offset
);
340 *(guint8
*)G_STRUCT_MEMBER_P(co
, chanopt
[i
].offset
) = vals
;
341 chanopt_changed
= TRUE
;
349 chanopt_save_one_channel (chanopt_in_memory
*co
, int fh
)
355 snprintf (buf
, sizeof (buf
), "%s = %s\n", "network", co
->network
);
356 write (fh
, buf
, strlen (buf
));
358 snprintf (buf
, sizeof (buf
), "%s = %s\n", "channel", co
->channel
);
359 write (fh
, buf
, strlen (buf
));
362 while (i
< sizeof (chanopt
) / sizeof (channel_options
))
364 val
= G_STRUCT_MEMBER (guint8
, co
, chanopt
[i
].offset
);
365 if (val
!= SET_DEFAULT
)
367 snprintf (buf
, sizeof (buf
), "%s = %d\n", chanopt
[i
].name
, val
);
368 write (fh
, buf
, strlen (buf
));
375 chanopt_save_all (void)
381 chanopt_in_memory
*co
;
384 if (!chanopt_list
|| !chanopt_changed
)
389 fh
= xchat_open_file ("chanopt.conf", O_TRUNC
| O_WRONLY
| O_CREAT
, 0600, XOF_DOMODE
);
395 for (num_saved
= 0, list
= chanopt_list
; list
; list
= list
->next
)
400 while (i
< sizeof (chanopt
) / sizeof (channel_options
))
402 val
= G_STRUCT_MEMBER (guint8
, co
, chanopt
[i
].offset
);
403 /* not using global/default setting, must save */
404 if (val
!= SET_DEFAULT
)
409 chanopt_save_one_channel (co
, fh
);
417 g_free (co
->network
);
418 g_free (co
->channel
);
424 /* we're quiting, no need to free */
426 /*g_slist_free (chanopt_list);
429 chanopt_open = FALSE;
430 chanopt_changed = FALSE;*/