1 /*
2 * biff.c
3 * Yet Another Osuwari Multi for X11
4 * (Biff Module)
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <pwd.h> /* for passwd */
12 #include <sys/stat.h> /* for stat, needs types.h */
13
14 #include <X11/Xlib.h>
15 #include <X11/Xutil.h>
16
17 #include <X11/bitmaps/flagup>
18 /*
19 | ��뤬���äѤ��ΤȤ��Υӥåȥޥåס�
20 | char* flagup_bits;
21 | int flagup_width;
22 | int flagup_height;
23 | ���ޤޤ�Ƥ��롣
24 | �������γ����ؤ������Ȥ��ˤϡ����Υӥåȥޥåפ��ѹ����٤���
25 */
26
27 /******** ��롦���ס���ǥ��쥯�ȥ������ ********
28 *
29 * ��롦���ס���ǥ��쥯�ȥ�ϥޥ���Ķ��ˤ�äưۤʤ롣
30 * ����� "/usr/spool/mail" �� "/usr/mail" ������ˤ���Τ�����
31 * �⤷��äƤ������ˤϡ���ʬ�δĶ��˹�碌��
32 * MAILBOX_DIRECTRY �����ꤹ��ɬ�פ����롣
33 */
34
35 #ifndef MAILBOX_DIRECTORY
36
37 #ifdef SYSV
38 #define MAILBOX_DIRECTORY "/usr/mail"
39 #endif
40
41 #ifdef SVR4
42 #define MAILBOX_DIRECTORY "/var/mail"
43 #endif
44
45 #ifdef CSRG_BASED
46 #include <paths.h>
47 #ifdef _PATH_MAILDIR
48 #define MAILBOX_DIRECTOR _PATH_MAILDIR
49 #endif
50 #endif
51
52 #endif
53
54 #ifndef MAILBOX_DIRECTORY
55 #define MAILBOX_DIRECTORY "/usr/spool/mail" /* <- �ǥե���Ȥ����� */
56 #endif
57
58 /******** External Value ********/
59
60 /* in xosmulti.c */
61
62 extern Display *Disp;
63 extern Window RootWin;
64
65 extern unsigned long FgPixel, BgPixel;
66
67 extern XFontStruct *theFont;
68 extern int FontHeight;
69 extern Bool isKanji;
70
71 /* in message.c */
72
73 extern char *BiffMsg;
74
75 /******** Global Value ********/
76
77 static Window BiffWin;
78 static int BiffWidth, BiffHeight;
79 static Bool isBiffMapped = False;
80
81 static char *MBoxFileName = NULL;
82
83 /******** External Function ********/
84
85 /* in xosmulti.c */
86 extern void TalkShape( );
87 extern XChar2b *Str2bCpy( );
88
89 /******** Functions Prototype ********/
90
91 void CreateBiff();
92 static char *GetMailFile();
93 void MoveBiff();
94 void UpBiff();
95 void DownBiff();
96 void CheckBiff();
97 void DestroyBiff();
98 static Pixmap CreateBiffPixmap();
99
100 /******** CreateBiff ********
101 * Biff������ɥ�����������
102 */
CreateBiff()103 void CreateBiff()
104 {
105 XSetWindowAttributes xswa;
106 int biff_width = 120, biff_height = 64;
107
108 BiffWin = XCreateSimpleWindow( Disp, RootWin,
109 0, 0, biff_width, biff_height, 1,
110 FgPixel, BgPixel );
111
112 xswa.override_redirect = True;
113
114 xswa.background_pixmap = CreateBiffPixmap( &biff_width, &biff_height );
115
116 XChangeWindowAttributes( Disp, BiffWin,
117 CWOverrideRedirect | CWBackPixmap, &xswa );
118
119 /* �դ����������ڤ� */
120 TalkShape( Disp, BiffWin, biff_width, biff_height, 1 );
121
122 /* �����⤵���ݻ����� */
123 BiffWidth = biff_width;
124 BiffHeight = biff_height;
125
126 /* ������֤Ǥ���ɽ�� */
127 DownBiff();
128
129 /* ��륹�ס���ե���������� */
130 MBoxFileName = GetMailFile();
131 }
132
133 /******** GetMailFile ********
134 * ��롦���ס���ե�����̾������
135 * �ե�����̾���Ǽ�������� malloc ���Ƥ���
136 */
GetMailFile()137 static char *GetMailFile()
138 {
139 char *username;
140 char *fname_return;
141
142 username = (char*)getlogin();
143 if( username == NULL )
144 {
145 struct passwd *pw = getpwuid( getuid() );
146
147 if( pw == NULL )
148 {
149 fprintf( stderr,"ERROR: unable to find a username for you.\n" );
150 return NULL ;
151 }
152 username = pw->pw_name;
153 }
154
155 fname_return = (char*)malloc(
156 strlen(MAILBOX_DIRECTORY) + 1 + strlen(username) + 1 );
157 if( fname_return == NULL )
158 return NULL ;
159
160 sprintf( fname_return, "%s/%s", MAILBOX_DIRECTORY, username );
161
162 return fname_return ;
163 }
164
165 /******** MoveBiff ********/
MoveBiff(x,y)166 void MoveBiff( x, y )
167 int x, y;
168 {
169 y -= BiffHeight; /* ������ɥ��β��̤���Ȥ��� */
170 XMoveWindow( Disp, BiffWin, x, y );
171 }
172
173 /******** UpBiff ********/
UpBiff(x,y)174 void UpBiff( x, y )
175 int x, y;
176 {
177 MoveBiff( x, y );
178
179 XMapWindow( Disp, BiffWin );
180 isBiffMapped = True;
181
182 XRaiseWindow( Disp, BiffWin ); /* �����̤˽Ф� */
183
184 }
185
186 /******** DownBiff ********/
DownBiff()187 void DownBiff()
188 {
189 XUnmapWindow( Disp, BiffWin );
190 isBiffMapped = False;
191 }
192
193 /******** CheckBiff ********/
194 #define BIFF_COUNT 30 /* �ºݤ˥��ܥå���������å�����ֳ� */
195
CheckBiff(x,y)196 void CheckBiff( x, y )
197 int x, y;
198 {
199 long mailboxsize;
200 static long LastSize = 0;
201
202 Bool sizeChanged;
203 Bool readSinceLastWrite;
204
205 /* �����������դˤʤ�ޤDz��⤷�ʤ� */
206 { static int BiffCount = BIFF_COUNT;
207
208 if( ++BiffCount <= BIFF_COUNT )
209 return;
210 BiffCount = 0;
211 }
212
213 /* ���ܥå���������å����� */
214 mailboxsize = 0;
215 sizeChanged = False;
216 readSinceLastWrite = False;
217
218 { struct stat st;
219
220 if( stat( MBoxFileName, &st ) == 0 )
221 {
222 mailboxsize = st.st_size;
223 sizeChanged = (Bool)( mailboxsize != LastSize );
224 readSinceLastWrite = (Bool)(st.st_atime > st.st_mtime);
225 }
226 }
227 LastSize = mailboxsize;
228
229 /* ���ܥå������ʤ����⤷���϶� */
230 if( mailboxsize == 0 )
231 {
232 DownBiff();
233 }
234
235 /* �����ɤ�� */
236 else if( readSinceLastWrite )
237 {
238 if( isBiffMapped )
239 {
240 DownBiff();
241 }
242 }
243
244 /* ���������ۤʤäƤ��� */
245 else if( sizeChanged )
246 {
247 if( ! isBiffMapped )
248 {
249 XBell( Disp, 33/*volume*/ ); /* Beep! */
250 UpBiff( x, y );
251 }
252 }
253 }
254
255 /******** CreateBiffPixmap ********/
CreateBiffPixmap(w_ret,h_ret)256 Pixmap CreateBiffPixmap( w_ret, h_ret )
257 int *w_ret;
258 int *h_ret;
259 {
260 Pixmap bitmap;
261 Pixmap mailmap;
262 int width, height;
263 #define MARGIN 8
264 GC gc_temp;
265
266 /* �ޤ����ȹ⤵����� */
267 if( isKanji )
268 { XChar2b kstr[ 128 ];
269 Str2bCpy( kstr, BiffMsg );
270 width = XTextWidth16( theFont,
271 kstr, strlen(BiffMsg)/2 );
272 }else
273 { width = XTextWidth( theFont, BiffMsg, strlen(BiffMsg) );
274 }
275
276 if( flagup_width > width ){ width = flagup_width; }
277 height = flagup_height + FontHeight;
278
279 width += 2 * MARGIN;
280 height += 3 * MARGIN;
281
282 /* �ӥåȥޥåפκ��� */
283 bitmap = XCreatePixmap( Disp, BiffWin, width, height,
284 DefaultDepth(Disp,DefaultScreen(Disp)) );
285
286 gc_temp = XCreateGC( Disp, bitmap, 0, NULL );
287 XSetFont( Disp, gc_temp, theFont->fid );
288 XSetBackground( Disp, gc_temp, BgPixel );
289
290 /* �ޤ����̥��ꥢ������ */
291 XSetForeground( Disp, gc_temp, BgPixel );
292 XFillRectangle( Disp, bitmap, gc_temp, 0, 0, width, height );
293
294 /* ���γ��Υӥåȥޥåפ���� */
295 XSetForeground( Disp, gc_temp, FgPixel );
296 mailmap = XCreatePixmapFromBitmapData( Disp, BiffWin,
297 flagup_bits, flagup_width, flagup_height,
298 FgPixel, BgPixel,
299 /* BlackPixel(Disp,0), WhitePixel(Disp,0), /* DEBUG */
300 DefaultDepth(Disp,DefaultScreen(Disp)) );
301
302 /* �ӥåȥޥåפԡ����� */
303 XCopyArea( Disp, mailmap, bitmap, gc_temp,
304 0, 0, flagup_width, flagup_height,
305 (width - flagup_width) / 2, MARGIN );
306
307 /* ��å�������ɽ������ */
308 if( isKanji )
309 { XChar2b kstr[ 128 ];
310 Str2bCpy( kstr, BiffMsg );
311 XDrawString16( Disp, bitmap, gc_temp,
312 MARGIN, flagup_height + 3 * MARGIN,
313 kstr, strlen(BiffMsg)/2
314 );
315 }else
316 {
317 XDrawString( Disp, bitmap, gc_temp,
318 MARGIN, flagup_height + 3 * MARGIN,
319 BiffMsg, strlen(BiffMsg)
320 );
321 }
322
323 XFreePixmap( Disp, mailmap );
324 XFreeGC( Disp, gc_temp );
325
326 /* �ͤ��֤� */
327 *w_ret = width;
328 *h_ret = height;
329 return bitmap ;
330 }
331
332 /******** DestroyBiff ********/
DestroyBiff()333 void DestroyBiff()
334 {
335 if( MBoxFileName != NULL ){ free( MBoxFileName ); }
336 XDestroyWindow( Disp, BiffWin );
337 }
338
339 /******** End of File ********/
340