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