1 /*
2 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
3 *
4 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5 *
6 * This file may be distributed under the terms of the Q Public License
7 * as defined by Trolltech AS of Norway and appearing in the file
8 * LICENSE.QPL included in the packaging of this file.
9 *
10 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/chat.c,v 1.8 2011/05/16 16:21:56 william Exp $
19 */
20
21 #define _INCLUDE_FROM_CHAT_C_
22
23 #include "tgifdefs.h"
24 #include "patchlvl.h"
25 #include "tidget.h"
26
27 #include "button.e"
28 #include "chat.e"
29 #include "cmd.e"
30 #include "color.e"
31 #include "choose.e"
32 #include "dialog.e"
33 #include "file.e"
34 #include "font.e"
35 #include "http.e"
36 #include "ini.e"
37 #include "inmethod.e"
38 #include "msg.e"
39 #include "menu.e"
40 #include "rect.e"
41 #include "setup.e"
42 #include "strtbl.e"
43 #include "tdgtbtn.e"
44 #include "tdgtsedt.e"
45 #include "tdgtlist.e"
46 #include "tidget.e"
47 #include "util.e"
48 #include "xpixmap.e"
49
50 #include "xbm/a1.xbm"
51 #include "xbm/bold1.xbm"
52 #include "xbm/italic1.xbm"
53
54 #define CHAT_BTN_AUTO 0
55 #define CHAT_BTN_BOLD 1
56 #define CHAT_BTN_ITALIC 2
57 #define CHAT_BTN_SEND 3
58 #define CHAT_BTN_COLOR 4
59
60 #define MAX_CHAT_BTNS 5
61
62 #define ID_CHAT_BTN_AUTO (100+CHAT_BTN_AUTO)
63 #define ID_CHAT_BTN_BOLD (100+CHAT_BTN_BOLD)
64 #define ID_CHAT_BTN_ITALIC (100+CHAT_BTN_ITALIC)
65 #define ID_CHAT_BTN_SEND (100+CHAT_BTN_SEND)
66 #define ID_CHAT_BTN_COLOR (100+CHAT_BTN_COLOR)
67 #define ID_CHAT_LIST 105
68 #define ID_CHAT_EDIT 106
69
70 typedef struct tagChatInfo {
71 SimpleWinInfo base_win_info, list_win_info, edit_win_info;
72 SimpleWinInfo btn_win_info[MAX_CHAT_BTNS];
73
74 int just_clicked;
75
76 char ini_fname[MAXPATHLENGTH];
77
78 int font_height; /* font height used for all controls */
79 int font_width;
80 int gap; /* gaps between controls */
81 int btn_width; /* width of square buttons */
82 int num_lines; /* number of visible lines in the list control */
83
84 TdgtList *list_ctl;
85 TdgtBtn *btn_ctl[MAX_CHAT_BTNS];
86 TdgtSmplEdit *edit_ctl;
87 } ChatInfo;
88
89 ChatInfo gstChatInfo;
90
91 char *cmdLineChatNickName=NULL;
92
93 static Pixmap a1Pixmap=None;
94 static Pixmap bold1Pixmap=None;
95 static Pixmap italic1Pixmap=None;
96
97 static char *gpszChatNickName=NULL;
98
RedrawChatWindow()99 void RedrawChatWindow()
100 {
101 if (PRTGIF || noChatWindow || chatWindow == None) return;
102
103 /* draw a frame around the window */
104 if (threeDLook) {
105 if (dialogboxUse3DBorder) {
106 struct BBRec bbox;
107
108 SetBBRec(&bbox, 0, 0, gstChatInfo.base_win_info.w,
109 gstChatInfo.base_win_info.h);
110 TgDrawThreeDButton(mainDisplay, chatWindow, textMenuGC, &bbox,
111 TGBS_RAISED, 2, FALSE);
112 }
113 } else {
114 XDrawRectangle(mainDisplay, chatWindow, nameGC, 0, 0,
115 gstChatInfo.base_win_info.w-1, gstChatInfo.base_win_info.h-1);
116 }
117 }
118
119 static
MoveResizeChatSubWindows()120 void MoveResizeChatSubWindows()
121 {
122 if (gstChatInfo.list_ctl != NULL) {
123 TidgetMoveResize(gstChatInfo.list_ctl->pti, gstChatInfo.list_win_info.x,
124 gstChatInfo.list_win_info.y, gstChatInfo.list_win_info.w,
125 gstChatInfo.list_win_info.h);
126 }
127 if (gstChatInfo.btn_ctl[CHAT_BTN_SEND] != NULL) {
128 TidgetMoveResize((gstChatInfo.btn_ctl[CHAT_BTN_SEND])->pti,
129 gstChatInfo.btn_win_info[CHAT_BTN_SEND].x,
130 gstChatInfo.btn_win_info[CHAT_BTN_SEND].y,
131 gstChatInfo.btn_win_info[CHAT_BTN_SEND].w,
132 gstChatInfo.btn_win_info[CHAT_BTN_SEND].h);
133 }
134 if (gstChatInfo.edit_ctl != NULL) {
135 TidgetMoveResize(gstChatInfo.edit_ctl->pti, gstChatInfo.edit_win_info.x,
136 gstChatInfo.edit_win_info.y, gstChatInfo.edit_win_info.w,
137 gstChatInfo.edit_win_info.h);
138 }
139 }
140
MoveResizeChatWindow(x,y,w,h)141 void MoveResizeChatWindow(x, y, w, h)
142 int x, y, w, h;
143 {
144 XMoveResizeWindow(mainDisplay, chatWindow, x, y, w, h);
145 MoveResizeChatSubWindows();
146 }
147
148 static
GetChatFontStyle(pnIsBold,pnIsItalic)149 int GetChatFontStyle(pnIsBold, pnIsItalic)
150 int *pnIsBold, *pnIsItalic;
151 {
152 int bold_state=TdgtBtnGetState(gstChatInfo.btn_ctl[CHAT_BTN_BOLD]);
153 int italic_state=TdgtBtnGetState(gstChatInfo.btn_ctl[CHAT_BTN_ITALIC]);
154 int is_bold=(bold_state != TGBS_NORMAL);
155 int is_italic=(italic_state != TGBS_NORMAL);
156 int font_style=INVALID;
157
158 if (is_bold) {
159 if (is_italic) {
160 font_style = STYLE_BI;
161 } else {
162 font_style = STYLE_BR;
163 }
164 } else {
165 if (is_italic) {
166 font_style = STYLE_NI;
167 } else {
168 font_style = STYLE_NR;
169 }
170 }
171 if (pnIsBold != NULL) *pnIsBold = is_bold;
172 if (pnIsItalic != NULL) *pnIsItalic = is_italic;
173
174 return font_style;
175 }
176
177 static
InitChatNickName()178 int InitChatNickName()
179 {
180 char *c_ptr=NULL;
181
182 if (cmdLineChatNickName != NULL) {
183 gpszChatNickName = UtilStrDup(cmdLineChatNickName);
184 } else {
185 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "ChatNickName")) != NULL) {
186 gpszChatNickName = UtilStrDup(c_ptr);
187 }
188 }
189 if (gpszChatNickName == NULL) {
190 c_ptr = getenv("USER");
191 if (c_ptr != NULL) {
192 gpszChatNickName = UtilStrDup(c_ptr);
193 } else {
194 gpszChatNickName = UtilStrDup(
195 TgLoadCachedString(CSTID_PARANED_UNKNOWN));
196 }
197 }
198 if (gpszChatNickName == NULL) FailAllocMessage();
199
200 return TRUE;
201 }
202
203 static
GetChatNickName(buf,buf_sz)204 void GetChatNickName(buf, buf_sz)
205 char *buf;
206 int buf_sz;
207 {
208 UtilStrCpyN(buf, buf_sz, gpszChatNickName);
209 }
210
211 static
AddChatLineToListCtl(nick_name,color_index,font_style,buf)212 int AddChatLineToListCtl(nick_name, color_index, font_style, buf)
213 char *nick_name, *buf;
214 int color_index, font_style;
215 {
216 ListItemInfo *pListItemInfo=(ListItemInfo*)malloc(sizeof(ListItemInfo));
217
218 if (pListItemInfo == NULL) FailAllocMessage();
219 memset(pListItemInfo, 0, sizeof(ListItemInfo));
220
221 UtilStrCpyN(pListItemInfo->nick_name, sizeof(pListItemInfo->nick_name),
222 nick_name);
223 pListItemInfo->color_index = color_index;
224 pListItemInfo->font_style = font_style;
225 pListItemInfo->buf = UtilStrDup(buf);
226 if (pListItemInfo->buf == NULL) FailAllocMessage();
227
228 return TdgtListInsertListItemInfo(gstChatInfo.list_ctl, pListItemInfo);
229 }
230
231 static
ChatSendClicked()232 void ChatSendClicked()
233 {
234 char *buf=TdgtSmplEditGetText(gstChatInfo.edit_ctl);
235
236 if (buf != NULL && *buf != '\0') {
237 int saved_auto_scroll=TdgtListGetAutoScrollOnInsert(gstChatInfo.list_ctl);
238 int rc=0;
239 struct SubCmdRec subcmd;
240 char *encoded_text=Base64Encode(buf);
241
242 memset(&subcmd, 0, sizeof(struct SubCmdRec));
243
244 TdgtSmplEditGetTextFormatInfo(gstChatInfo.edit_ctl,
245 &subcmd.detail.chat.tfi);
246
247 subcmd.detail.chat.type = CHAT_STATE_NORMAL;
248 GetChatNickName(subcmd.detail.chat.nick_name,
249 sizeof(subcmd.detail.chat.nick_name));
250 UtilStrCpyN(subcmd.detail.chat.encoding,
251 sizeof(subcmd.detail.chat.encoding), "base64");
252 TdgtListSetAutoScrollOnInsert(gstChatInfo.list_ctl, TRUE);
253 rc = AddChatLineToListCtl(subcmd.detail.chat.nick_name,
254 subcmd.detail.chat.tfi.color_index,
255 subcmd.detail.chat.tfi.font_style, buf);
256 TdgtListSetAutoScrollOnInsert(gstChatInfo.list_ctl, saved_auto_scroll);
257 if (rc) {
258 subcmd.detail.chat.buf = UtilStrDup(encoded_text);
259 if (subcmd.detail.chat.buf == NULL) FailAllocMessage();
260 RecordWBChatALine(&subcmd);
261 UtilFree(subcmd.detail.chat.buf);
262 }
263 TdgtSmplEditSetText(gstChatInfo.edit_ctl, "");
264 UtilFree(encoded_text);
265 }
266 }
267
ChatEventHandler(input,handling_pti)268 void ChatEventHandler(input, handling_pti)
269 XEvent *input;
270 TidgetInfo *handling_pti;
271 {
272 int keypress_event=(input->type==KeyPress), event_handled=FALSE;
273
274 if (PRTGIF || noChatWindow || chatWindow == None) return;
275
276 /*
277 * If the event is a KeyPress event, either a special key is pressed
278 * or a regular key is pressed. Special keys should be handled
279 * by the list control and regular keys should be handled by
280 * the edit control.
281 */
282 if (input->xany.window == chatWindow) {
283 TdgtNtfy tdgt_notify;
284
285 memset(&tdgt_notify, 0, sizeof(TdgtNtfy));
286 if (input->type == Expose) {
287 XEvent ev;
288
289 RedrawChatWindow();
290 while (XCheckWindowEvent(mainDisplay, chatWindow, ExposureMask, &ev)) ;
291 } else if (input->type == EnterNotify) {
292 SetMouseStatus("", "", "");
293 if (input->xcrossing.mode == NotifyNormal &&
294 (input->xcrossing.detail == NotifyAncestor ||
295 input->xcrossing.detail == NotifyNonlinear ||
296 input->xcrossing.detail == NotifyNonlinearVirtual)) {
297 TdgtSmplEditSetFocus(gstChatInfo.edit_ctl, TRUE);
298 if (gnInputMethod != TGIM_NONE) {
299 tgIMFocusIn(mainDisplay, gstChatInfo.edit_ctl->pti->tci.win);
300 }
301 }
302 } else if (input->type == LeaveNotify) {
303 if (input->xcrossing.mode == NotifyNormal &&
304 (input->xcrossing.detail == NotifyAncestor ||
305 input->xcrossing.detail == NotifyNonlinear ||
306 input->xcrossing.detail == NotifyNonlinearVirtual)) {
307 TdgtSmplEditSetFocus(gstChatInfo.edit_ctl, FALSE);
308 if (gnInputMethod != TGIM_NONE) {
309 tgIMFocusOut(mainDisplay, gstChatInfo.edit_ctl->pti->tci.win);
310 }
311 }
312 } else if (IsTdgtWindowNotifyEvent(chatWindow, input, &tdgt_notify)) {
313 switch (tdgt_notify.nf_type) {
314 case TDGTNF_EDIT_ENTERED:
315 ChatSendClicked();
316 break;
317 case TDGTNF_BTN_CLICKED:
318 switch (tdgt_notify.ctl_id) {
319 case ID_CHAT_BTN_SEND: ChatSendClicked(); break;
320
321 case ID_CHAT_BTN_BOLD:
322 case ID_CHAT_BTN_ITALIC:
323 {
324 int is_bold=FALSE, is_italic=FALSE;
325
326 /* bold or italic button changed state */
327 int font_style=GetChatFontStyle(&is_bold, &is_italic);
328
329 TdgtSmplEditSetFontStyle(gstChatInfo.edit_ctl, font_style);
330 tgWriteProfileString("User", "Bold",
331 (is_bold ? "1" : "0"), gstChatInfo.ini_fname);
332 tgWriteProfileString("User", "Italic",
333 (is_italic ? "1" : "0"), gstChatInfo.ini_fname);
334 tgWriteProfileString(NULL, NULL, NULL, gstChatInfo.ini_fname);
335 }
336 break;
337 case ID_CHAT_BTN_AUTO:
338 {
339 /* auto scroll changed state */
340 int auto_state=TdgtBtnGetState(
341 gstChatInfo.btn_ctl[CHAT_BTN_AUTO]);
342 int auto_scroll=(auto_state != TGBS_NORMAL);
343
344 TdgtListSetAutoScrollOnInsert(gstChatInfo.list_ctl,
345 auto_scroll);
346 }
347 break;
348 }
349 break;
350 case TDGTNF_MULTI_BTN_CLICKED:
351 if (tdgt_notify.ctl_id == ID_CHAT_BTN_COLOR) {
352 int color_index=INVALID;
353
354 switch (tdgt_notify.nf_arg) { /* Button[1-3] */
355 case Button1:
356 color_index = (int)(long)TdgtBtnGetText(
357 gstChatInfo.btn_ctl[CHAT_BTN_COLOR]);
358 if (++color_index >= maxColors) color_index = 0;
359 break;
360 case Button2:
361 color_index = tdgt_notify.nf_arg2;
362 break;
363 case Button3:
364 color_index = (int)(long)TdgtBtnGetText(
365 gstChatInfo.btn_ctl[CHAT_BTN_COLOR]);
366 if (--color_index < 0) color_index = maxColors-1;
367 break;
368 }
369 TdgtBtnSetText(gstChatInfo.btn_ctl[CHAT_BTN_COLOR],
370 (char*)(long)color_index, NULL);
371 TdgtSmplEditSetColorIndex(gstChatInfo.edit_ctl, color_index);
372 tgWriteProfileString("User", "Color",
373 colorMenuItems[color_index], gstChatInfo.ini_fname);
374 tgWriteProfileString(NULL, NULL, NULL, gstChatInfo.ini_fname);
375 }
376 break;
377 }
378 event_handled = TRUE;
379 }
380 } else if (gstChatInfo.list_ctl != NULL &&
381 TidgetEventHandler(gstChatInfo.list_ctl->pti, input, handling_pti)) {
382 /* this event has been handled by the list */
383 event_handled = TRUE;
384 } else if (gstChatInfo.edit_ctl != NULL &&
385 TidgetEventHandler(gstChatInfo.edit_ctl->pti, input, handling_pti)) {
386 event_handled = TRUE;
387 } else {
388 int i=0;
389
390 for (i=0; i < MAX_CHAT_BTNS; i++) {
391 if (gstChatInfo.btn_ctl[i] != NULL &&
392 TidgetEventHandler((gstChatInfo.btn_ctl[i])->pti, input,
393 handling_pti)) {
394 event_handled = TRUE;
395 }
396 }
397 }
398 if (keypress_event && !event_handled &&
399 TidgetEventHandler(gstChatInfo.edit_ctl->pti, input, handling_pti)) {
400 }
401 }
402
IsChatWindowEvent(input,ppti_handler_tidget_return)403 int IsChatWindowEvent(input, ppti_handler_tidget_return)
404 XEvent *input;
405 TidgetInfo **ppti_handler_tidget_return;
406 {
407 int i=0;
408
409 *ppti_handler_tidget_return = NULL;
410
411 if (chatWindow == None) return FALSE;
412
413 if (input->xany.window == chatWindow) return TRUE;
414 if (gstChatInfo.list_ctl != NULL && IsTidgetEvent(gstChatInfo.list_ctl->pti,
415 input, ppti_handler_tidget_return)) {
416 return TRUE;
417 }
418 for (i=0; i < MAX_CHAT_BTNS; i++) {
419 if (gstChatInfo.btn_ctl[i] != NULL &&
420 IsTidgetEvent((gstChatInfo.btn_ctl[i])->pti, input,
421 ppti_handler_tidget_return)) {
422 return TRUE;
423 }
424 }
425 if (gstChatInfo.edit_ctl != NULL && IsTidgetEvent(gstChatInfo.edit_ctl->pti,
426 input, ppti_handler_tidget_return)) {
427 return TRUE;
428 }
429 return FALSE;
430 }
431
432 #define BTN_Y_MARGIN 2
433
GetInitialChatWindowHeight()434 int GetInitialChatWindowHeight()
435 {
436 int x=0, y=0;
437
438 gstChatInfo.num_lines=6;
439 if (msgFontSet == NULL && msgFontPtr == NULL) {
440 gstChatInfo.font_height = defaultFontHeight;
441 gstChatInfo.font_width = defaultFontWidth;
442 } else {
443 gstChatInfo.font_height = msgFontHeight;
444 gstChatInfo.font_width = msgFontWidth;
445 }
446 gstChatInfo.btn_width = a1_width+(windowPadding<<1);
447
448 /* gap */
449 y = gstChatInfo.gap = 4;
450
451 /* list control */
452 gstChatInfo.list_win_info.x = gstChatInfo.gap;
453 gstChatInfo.list_win_info.y = y;
454 gstChatInfo.list_win_info.w = (-1);
455 gstChatInfo.list_win_info.h =
456 (gstChatInfo.num_lines*ROW_HEIGHT)+2+(windowPadding<<1);
457 y += gstChatInfo.list_win_info.h;
458
459 /* gap */
460 y += gstChatInfo.gap;
461
462 /* other controls */
463 x = gstChatInfo.list_win_info.x;
464 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].x = x;
465 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].y = y;
466 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].w = gstChatInfo.btn_width;
467 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].h = gstChatInfo.btn_width;
468 x += gstChatInfo.btn_width + (gstChatInfo.btn_width>>1);
469 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].x = x;
470 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].y = y;
471 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].w = gstChatInfo.btn_width;
472 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].h = gstChatInfo.btn_width;
473 x += gstChatInfo.btn_width + 2;
474 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].x = x;
475 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].y = y;
476 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].w = gstChatInfo.btn_width;
477 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].h = gstChatInfo.btn_width;
478 x += gstChatInfo.btn_width + 2;
479 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].x = x;
480 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].y = y;
481 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].w = gstChatInfo.btn_width;
482 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].h = gstChatInfo.btn_width;
483 x += gstChatInfo.btn_width + (gstChatInfo.btn_width>>1);
484 gstChatInfo.edit_win_info.x = x;
485 gstChatInfo.edit_win_info.y = y;
486 gstChatInfo.edit_win_info.w = (-1);
487 gstChatInfo.edit_win_info.h = gstChatInfo.btn_width;
488 x += gstChatInfo.btn_width + (gstChatInfo.btn_width>>1);
489 gstChatInfo.btn_win_info[CHAT_BTN_SEND].x = (-1);
490 gstChatInfo.btn_win_info[CHAT_BTN_SEND].y = y;
491 gstChatInfo.btn_win_info[CHAT_BTN_SEND].w =
492 ButtonWidth("Send", 4, NULL);
493 gstChatInfo.btn_win_info[CHAT_BTN_SEND].h =
494 (gstChatInfo.font_height+(BTN_Y_MARGIN<<1)+(windowPadding<<1));
495 y += gstChatInfo.btn_width;
496
497 /* gap */
498 y += gstChatInfo.gap;
499
500 return y;
501 }
502
SetChatWindowGeom()503 void SetChatWindowGeom()
504 {
505 int x=0, y=0;
506
507 gstChatInfo.base_win_info.x = (-1);
508 gstChatInfo.base_win_info.y = (-1);
509 gstChatInfo.base_win_info.w = chatWindowW;
510 gstChatInfo.base_win_info.h = chatWindowH;
511
512 /* gap */
513 y = gstChatInfo.gap;
514
515 /* list control */
516 gstChatInfo.list_win_info.x = gstChatInfo.gap;
517 gstChatInfo.list_win_info.y = y;
518 gstChatInfo.list_win_info.w =
519 gstChatInfo.base_win_info.w - (gstChatInfo.gap<<1);
520 gstChatInfo.list_win_info.h =
521 (gstChatInfo.num_lines*ROW_HEIGHT)+2+(windowPadding<<1);
522
523 y += gstChatInfo.list_win_info.h;
524
525 /* gap */
526 y += gstChatInfo.gap;
527
528 /* other controls */
529 x = gstChatInfo.list_win_info.x;
530 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].x = x;
531 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].y = y;
532 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].w = gstChatInfo.btn_width;
533 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].h = gstChatInfo.btn_width;
534 x += gstChatInfo.btn_width + (gstChatInfo.btn_width>>1);
535 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].x = x;
536 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].y = y;
537 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].w = gstChatInfo.btn_width;
538 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].h = gstChatInfo.btn_width;
539 x += gstChatInfo.btn_width + 2;
540 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].x = x;
541 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].y = y;
542 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].w = gstChatInfo.btn_width;
543 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].h = gstChatInfo.btn_width;
544 x += gstChatInfo.btn_width + 2;
545 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].x = x;
546 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].y = y;
547 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].w = gstChatInfo.btn_width;
548 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].h = gstChatInfo.btn_width;
549 x += gstChatInfo.btn_width + (gstChatInfo.btn_width>>1);
550 gstChatInfo.edit_win_info.x = x;
551 gstChatInfo.edit_win_info.y = y;
552 gstChatInfo.edit_win_info.w = (-1);
553 gstChatInfo.edit_win_info.h = gstChatInfo.btn_width;
554 x += gstChatInfo.btn_width + (gstChatInfo.btn_width>>1);
555 gstChatInfo.btn_win_info[CHAT_BTN_SEND].x = (-1);
556 gstChatInfo.btn_win_info[CHAT_BTN_SEND].y = y;
557 gstChatInfo.btn_win_info[CHAT_BTN_SEND].w =
558 ButtonWidth("Send", 4, NULL);
559 gstChatInfo.btn_win_info[CHAT_BTN_SEND].h = gstChatInfo.btn_width;
560 y += gstChatInfo.btn_width;
561
562 gstChatInfo.btn_win_info[CHAT_BTN_SEND].x =
563 gstChatInfo.base_win_info.w - gstChatInfo.gap -
564 (windowPadding<<1) - gstChatInfo.btn_win_info[CHAT_BTN_SEND].w;
565 gstChatInfo.edit_win_info.w = gstChatInfo.btn_win_info[CHAT_BTN_SEND].x -
566 (gstChatInfo.btn_width>>1) - gstChatInfo.edit_win_info.x;
567
568 /* gap */
569 y += gstChatInfo.gap;
570 }
571
MapChatSubWindows()572 void MapChatSubWindows()
573 {
574 int i=0;
575
576 if (gstChatInfo.list_ctl != NULL) MapTidget(gstChatInfo.list_ctl->pti);
577 for (i=0; i < MAX_CHAT_BTNS; i++) {
578 if (gstChatInfo.btn_ctl[i] != NULL) {
579 MapTidget((gstChatInfo.btn_ctl[i])->pti);
580 }
581 }
582 if (gstChatInfo.edit_ctl != NULL) MapTidget(gstChatInfo.edit_ctl->pti);
583 }
584
CreateChatSubWindows()585 int CreateChatSubWindows()
586 {
587 MouseOverStatusInfo mosi;
588 char *buf=NULL;
589 int new_alloc=FALSE, ival=0, font_style=STYLE_NR;
590 int is_bold=FALSE, is_italic=FALSE, color_index=colorIndex;
591
592 if ((buf=tgGetProfileString("User", "Color", gstChatInfo.ini_fname)) !=
593 NULL) {
594 color_index = QuickFindColorIndex(NULL, buf, &new_alloc, TRUE);
595 tgFreeProfileString(buf);
596 }
597 if ((buf=tgGetProfileString("User", "Bold", gstChatInfo.ini_fname)) !=
598 NULL) {
599 if (sscanf(buf, "%d", &ival) == 1) {
600 is_bold = ival;
601 } else {
602 tgWriteProfileString("User", "Bold", "0", gstChatInfo.ini_fname);
603 tgWriteProfileString(NULL, NULL, NULL, gstChatInfo.ini_fname);
604 }
605 tgFreeProfileString(buf);
606 }
607 if ((buf=tgGetProfileString("User", "Italic", gstChatInfo.ini_fname)) !=
608 NULL) {
609 if (sscanf(buf, "%d", &ival) == 1) {
610 is_italic = ival;
611 } else {
612 tgWriteProfileString("User", "Italic", "0", gstChatInfo.ini_fname);
613 tgWriteProfileString(NULL, NULL, NULL, gstChatInfo.ini_fname);
614 }
615 tgFreeProfileString(buf);
616 }
617 if (is_bold) {
618 if (is_italic) {
619 font_style = STYLE_BI;
620 } else {
621 font_style = STYLE_BR;
622 }
623 } else {
624 if (is_italic) {
625 font_style = STYLE_NI;
626 } else {
627 font_style = STYLE_NR;
628 }
629 }
630 memset(&mosi, 0, sizeof(MouseOverStatusInfo));
631 mosi.one_line_status = TRUE;
632
633 a1Pixmap = XCreateBitmapFromData(mainDisplay, mainWindow,
634 (char*)a1_bits, a1_width, a1_height);
635 bold1Pixmap = XCreateBitmapFromData(mainDisplay, mainWindow,
636 (char*)bold1_bits, bold1_width, bold1_height);
637 italic1Pixmap = XCreateBitmapFromData(mainDisplay, mainWindow,
638 (char*)italic1_bits, italic1_width, italic1_height);
639
640 gstChatInfo.list_ctl = CreateTdgtList(chatWindow, NULL, ID_CHAT_LIST,
641 gstChatInfo.list_win_info.x, gstChatInfo.list_win_info.y,
642 gstChatInfo.list_win_info.w, TDGTLIST_DEF_H_PAD, TDGTLIST_DEF_V_PAD,
643 gstChatInfo.num_lines, FALSE, TRUE, TRUE);
644 if (gstChatInfo.list_ctl == NULL) return FALSE;
645
646 UtilStrCpyN(mosi.one_line_str, sizeof(mosi.one_line_str),
647 TgLoadString(STID_TOGGLE_AUTO_SCR_IN_CHAT));
648 gstChatInfo.btn_ctl[CHAT_BTN_AUTO] = CreateTdgtBtn(chatWindow, NULL,
649 ID_CHAT_BTN_AUTO, gstChatInfo.btn_win_info[CHAT_BTN_AUTO].x,
650 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].y,
651 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].w,
652 gstChatInfo.btn_win_info[CHAT_BTN_AUTO].h,
653 0, 0, TGMUTYPE_BITMAP, TDGTBTN_STICKY, TGBS_LOWRED, STYLE_NR,
654 (char*)(&a1Pixmap), &mosi);
655
656 UtilStrCpyN(mosi.one_line_str, sizeof(mosi.one_line_str),
657 TgLoadString(STID_TOGGLE_BOLD_IN_CHAT));
658 gstChatInfo.btn_ctl[CHAT_BTN_BOLD] = CreateTdgtBtn(chatWindow, NULL,
659 ID_CHAT_BTN_BOLD, gstChatInfo.btn_win_info[CHAT_BTN_BOLD].x,
660 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].y,
661 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].w,
662 gstChatInfo.btn_win_info[CHAT_BTN_BOLD].h,
663 0, 0, TGMUTYPE_BITMAP, TDGTBTN_STICKY,
664 (is_bold ? TGBS_LOWRED : TGBS_NORMAL), STYLE_BR,
665 (char*)(&bold1Pixmap), &mosi);
666
667 UtilStrCpyN(mosi.one_line_str, sizeof(mosi.one_line_str),
668 TgLoadString(STID_TOGGLE_ITALIC_IN_CHAT));
669 gstChatInfo.btn_ctl[CHAT_BTN_ITALIC] = CreateTdgtBtn(chatWindow, NULL,
670 ID_CHAT_BTN_ITALIC, gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].x,
671 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].y,
672 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].w,
673 gstChatInfo.btn_win_info[CHAT_BTN_ITALIC].h,
674 0, 0, TGMUTYPE_BITMAP, TDGTBTN_STICKY,
675 (is_italic ? TGBS_LOWRED : TGBS_NORMAL), STYLE_NI,
676 (char*)(&italic1Pixmap), &mosi);
677
678 UtilStrCpyN(mosi.one_line_str, sizeof(mosi.one_line_str),
679 TgLoadString(STID_SEND_CHAT_TEXT));
680 gstChatInfo.btn_ctl[CHAT_BTN_SEND] = CreateTdgtBtn(chatWindow, NULL,
681 ID_CHAT_BTN_SEND, gstChatInfo.btn_win_info[CHAT_BTN_SEND].x,
682 gstChatInfo.btn_win_info[CHAT_BTN_SEND].y,
683 gstChatInfo.btn_win_info[CHAT_BTN_SEND].w,
684 gstChatInfo.btn_win_info[CHAT_BTN_SEND].h,
685 0, 0, TGMUTYPE_TEXT, TDGTBTN_CLICK, TGBS_NORMAL, STYLE_NR, "Send",
686 &mosi);
687
688 mosi.one_line_status = FALSE;
689 UtilStrCpyN(mosi.btn_str[0], sizeof(mosi.btn_str[0]), colorMouseStatus[0].l);
690 UtilStrCpyN(mosi.btn_str[1], sizeof(mosi.btn_str[1]), colorMouseStatus[0].m);
691 UtilStrCpyN(mosi.btn_str[2], sizeof(mosi.btn_str[2]), colorMouseStatus[0].r);
692 gstChatInfo.btn_ctl[CHAT_BTN_COLOR] = CreateTdgtBtn(chatWindow, NULL,
693 ID_CHAT_BTN_COLOR, gstChatInfo.btn_win_info[CHAT_BTN_COLOR].x,
694 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].y,
695 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].w,
696 gstChatInfo.btn_win_info[CHAT_BTN_COLOR].h,
697 0, 0, TGMUTYPE_COLOR, TDGTBTN_CLICK, TGBS_NORMAL, INVALID,
698 (char*)(long)color_index, &mosi);
699
700 gstChatInfo.edit_ctl = CreateTdgtSmplEdit(chatWindow, NULL, ID_CHAT_EDIT,
701 gstChatInfo.edit_win_info.x, gstChatInfo.edit_win_info.y,
702 gstChatInfo.edit_win_info.w, TDGTSEDT_DEF_H_PAD, TDGTSEDT_DEF_V_PAD,
703 "", font_style, color_index);
704 if (gstChatInfo.edit_ctl == NULL) return FALSE;
705
706 return TRUE;
707 }
708
709 /* --------------------- ChatInsertChatLine --------------------- */
710
ChatAppendChatLine(ptfi,nick_name,encoding,buf)711 void ChatAppendChatLine(ptfi, nick_name, encoding, buf)
712 TextFormatInfo *ptfi;
713 char *nick_name, *encoding, *buf;
714 {
715 char *clear_text=NULL;
716 ListItemInfo *pListItemInfo=(ListItemInfo*)malloc(sizeof(ListItemInfo));
717
718 if (pListItemInfo == NULL) FailAllocMessage();
719 memset(pListItemInfo, 0, sizeof(ListItemInfo));
720
721 if (*encoding == '\0') {
722 clear_text = buf;
723 } else if (strcmp(encoding, "base64") == 0) {
724 clear_text = Base64Decode(buf);
725 } else {
726 /* reject */
727 }
728 UtilStrCpyN(pListItemInfo->nick_name, sizeof(pListItemInfo->nick_name),
729 nick_name);
730 pListItemInfo->color_index = ptfi->color_index;
731 pListItemInfo->font_style = ptfi->font_style;
732 pListItemInfo->buf = UtilStrDup(clear_text);
733 if (pListItemInfo->buf == NULL) FailAllocMessage();
734
735 TdgtListInsertListItemInfo(gstChatInfo.list_ctl, pListItemInfo);
736
737 UtilFree(clear_text);
738 }
739
740 /* --------------------- ChatAddUser --------------------- */
741
ChatAddUser(buf)742 void ChatAddUser(buf)
743 char *buf;
744 {
745 }
746
747 /* --------------------- Init & Clean Up --------------------- */
748
InitChat()749 int InitChat()
750 {
751 memset(&gstChatInfo, 0, sizeof(ChatInfo));
752
753 sprintf(gstChatInfo.ini_fname, "%s%cchat.ini", tgifDir, DIR_SEP);
754 return InitChatNickName();
755 }
756
CleanUpChat()757 void CleanUpChat()
758 {
759 int i=0;
760
761 UtilFree(gpszChatNickName);
762 gpszChatNickName = NULL;
763
764 if (a1Pixmap != None) XFreePixmap(mainDisplay, a1Pixmap);
765 if (bold1Pixmap != None) XFreePixmap(mainDisplay, bold1Pixmap);
766 if (italic1Pixmap != None) XFreePixmap(mainDisplay, italic1Pixmap);
767 a1Pixmap = bold1Pixmap = italic1Pixmap = None;
768
769 if (gstChatInfo.list_ctl != NULL) {
770 TidgetInfo *pti=((gstChatInfo.list_ctl)->pti);
771
772 DestroyTidget(&pti);
773 }
774 for (i=0; i < MAX_CHAT_BTNS; i++) {
775 if (gstChatInfo.btn_ctl[i] != NULL) {
776 TidgetInfo *pti=((gstChatInfo.btn_ctl[i])->pti);
777
778 DestroyTidget(&pti);
779 }
780 }
781 if (gstChatInfo.edit_ctl != NULL) {
782 TidgetInfo *pti=((gstChatInfo.edit_ctl)->pti);
783
784 DestroyTidget(&pti);
785 }
786 }
787
788