1 /*--------------------------------------------------------------
11 * Added Color, RootWindow Capability and Quit Ability:
12 * Dan Checkoway, 7-12-94
14 * Converted to use ANSI C and XCB by:
17 *--------------------------------------------------------------*/
21 #include <X11/Xutil.h>
22 #include <X11/keysym.h>
24 #define X_H /* make sure we aren't using symbols from X.h */
25 #include <X11/XCB/xcb.h>
26 /*#include <X11/XCB/xcb_image.h>*/
27 #include <X11/XCB/xcb_aux.h> /* XCBAuxGetScreen */
28 #include <X11/XCB/xcb_icccm.h>
29 #include <X11/XCB/xcb_atom.h> /* STRING atom */
30 #include <X11/XCB/xcb_keysyms.h>
32 typedef enum { False, True } Bool;
40 #include <unistd.h> /* pause() */
45 #include "bitmaps/icon.xbm"
46 #include "bitmaps/cursor.xbm"
47 #include "bitmaps/cursor_mask.xbm"
49 #include "bitmaps/space.xbm"
51 #include "bitmaps/mati2.xbm"
52 #include "bitmaps/jare2.xbm"
53 #include "bitmaps/kaki1.xbm"
54 #include "bitmaps/kaki2.xbm"
55 #include "bitmaps/mati3.xbm"
56 #include "bitmaps/sleep1.xbm"
57 #include "bitmaps/sleep2.xbm"
59 #include "bitmaps/awake.xbm"
61 #include "bitmaps/up1.xbm"
62 #include "bitmaps/up2.xbm"
63 #include "bitmaps/down1.xbm"
64 #include "bitmaps/down2.xbm"
65 #include "bitmaps/left1.xbm"
66 #include "bitmaps/left2.xbm"
67 #include "bitmaps/right1.xbm"
68 #include "bitmaps/right2.xbm"
69 #include "bitmaps/upright1.xbm"
70 #include "bitmaps/upright2.xbm"
71 #include "bitmaps/upleft1.xbm"
72 #include "bitmaps/upleft2.xbm"
73 #include "bitmaps/dwleft1.xbm"
74 #include "bitmaps/dwleft2.xbm"
75 #include "bitmaps/dwright1.xbm"
76 #include "bitmaps/dwright2.xbm"
78 #include "bitmaps/utogi1.xbm"
79 #include "bitmaps/utogi2.xbm"
80 #include "bitmaps/dtogi1.xbm"
81 #include "bitmaps/dtogi2.xbm"
82 #include "bitmaps/ltogi1.xbm"
83 #include "bitmaps/ltogi2.xbm"
84 #include "bitmaps/rtogi1.xbm"
85 #include "bitmaps/rtogi2.xbm"
87 #define BITMAP_WIDTH 32
88 #define BITMAP_HEIGHT 32
89 #define WINDOW_WIDTH 320
90 #define WINDOW_HEIGHT 256
91 #define DEFAULT_BORDER 2
92 #define DEFAULT_WIN_X 1
93 #define DEFAULT_WIN_Y 1
94 #define AVAIL_KEYBUF 255
96 #define EVENT_MASK ( XCBEventMaskKeyPress | XCBEventMaskButtonPress | \
97 XCBEventMaskExposure | XCBEventMaskStructureNotify )
99 #define EVENT_MASK_ROOT ( XCBEventMaskKeyPress | XCBEventMaskExposure )
101 #define MAX_TICK 9999 /* Odd Only! */
102 #define INTERVAL 125000L
103 #define NEKO_SPEED 16
105 #define NORMAL_STATE 1
115 #define NEKO_U_MOVE 6
116 #define NEKO_D_MOVE 7
117 #define NEKO_L_MOVE 8
118 #define NEKO_R_MOVE 9
119 #define NEKO_UL_MOVE 10
120 #define NEKO_UR_MOVE 11
121 #define NEKO_DL_MOVE 12
122 #define NEKO_DR_MOVE 13
123 #define NEKO_U_TOGI 14
124 #define NEKO_D_TOGI 15
125 #define NEKO_L_TOGI 16
126 #define NEKO_R_TOGI 17
128 #define NEKO_STOP_TIME 4
129 #define NEKO_JARE_TIME 10
130 #define NEKO_KAKI_TIME 4
131 #define NEKO_AKUBI_TIME 3
132 #define NEKO_AWAKE_TIME 3
133 #define NEKO_TOGI_TIME 10
135 #define PI_PER8 ((double)3.1415926535/(double)8)
137 #define DIRNAMELEN 255
140 char *fgColor, *bgColor;
142 static char *ProgramName;
145 XCBSCREEN *theScreen; /* instead of macro(theDisplay, int theScreen) */
146 unsigned long theFgPixel;
147 unsigned long theBgPixel;
150 XCBKeySymbols *theKeySyms;
151 XCBATOM deleteWindowAtom;
153 static unsigned int WindowWidth;
154 static unsigned int WindowHeight;
155 static int WindowPointX;
156 static int WindowPointY;
158 static unsigned int BorderWidth = DEFAULT_BORDER;
160 long IntervalTime = INTERVAL;
182 XCBGCONTEXT NekoLastGC;
184 double NekoSpeed = (double)NEKO_SPEED;
186 double SinPiPer8Times3;
209 XCBPIXMAP UpLeft1Xbm;
210 XCBPIXMAP UpLeft2Xbm;
211 XCBPIXMAP UpRight1Xbm;
212 XCBPIXMAP UpRight2Xbm;
213 XCBPIXMAP DownLeft1Xbm;
214 XCBPIXMAP DownLeft2Xbm;
215 XCBPIXMAP DownRight1Xbm;
216 XCBPIXMAP DownRight2Xbm;
218 XCBPIXMAP UpTogi1Xbm;
219 XCBPIXMAP UpTogi2Xbm;
220 XCBPIXMAP DownTogi1Xbm;
221 XCBPIXMAP DownTogi2Xbm;
222 XCBPIXMAP LeftTogi1Xbm;
223 XCBPIXMAP LeftTogi2Xbm;
224 XCBPIXMAP RightTogi1Xbm;
225 XCBPIXMAP RightTogi2Xbm;
234 XCBGCONTEXT Sleep1GC;
235 XCBGCONTEXT Sleep2GC;
245 XCBGCONTEXT Right1GC;
246 XCBGCONTEXT Right2GC;
247 XCBGCONTEXT UpLeft1GC;
248 XCBGCONTEXT UpLeft2GC;
249 XCBGCONTEXT UpRight1GC;
250 XCBGCONTEXT UpRight2GC;
251 XCBGCONTEXT DownLeft1GC;
252 XCBGCONTEXT DownLeft2GC;
253 XCBGCONTEXT DownRight1GC;
254 XCBGCONTEXT DownRight2GC;
256 XCBGCONTEXT UpTogi1GC;
257 XCBGCONTEXT UpTogi2GC;
258 XCBGCONTEXT DownTogi1GC;
259 XCBGCONTEXT DownTogi2GC;
260 XCBGCONTEXT LeftTogi1GC;
261 XCBGCONTEXT LeftTogi2GC;
262 XCBGCONTEXT RightTogi1GC;
263 XCBGCONTEXT RightTogi2GC;
266 XCBGCONTEXT *GCCreatePtr;
267 XCBPIXMAP *BitmapCreatePtr;
269 unsigned int PixelWidth;
270 unsigned int PixelHeight;
273 BitmapGCData BitmapGCDataTable[] = {
274 { &SpaceGC, &SpaceXbm, space_bits, space_width, space_height },
275 { &Mati2GC, &Mati2Xbm, mati2_bits, mati2_width, mati2_height },
276 { &Jare2GC, &Jare2Xbm, jare2_bits, jare2_width, jare2_height },
277 { &Kaki1GC, &Kaki1Xbm, kaki1_bits, kaki1_width, kaki1_height },
278 { &Kaki2GC, &Kaki2Xbm, kaki2_bits, kaki2_width, kaki2_height },
279 { &Mati3GC, &Mati3Xbm, mati3_bits, mati3_width, mati3_height },
280 { &Sleep1GC, &Sleep1Xbm, sleep1_bits, sleep1_width, sleep1_height },
281 { &Sleep2GC, &Sleep2Xbm, sleep2_bits, sleep2_width, sleep2_height },
282 { &AwakeGC, &AwakeXbm, awake_bits, awake_width, awake_height },
283 { &Up1GC, &Up1Xbm, up1_bits, up1_width, up1_height },
284 { &Up2GC, &Up2Xbm, up2_bits, up2_width, up2_height },
285 { &Down1GC, &Down1Xbm, down1_bits, down1_width, down1_height },
286 { &Down2GC, &Down2Xbm, down2_bits, down2_width, down2_height },
287 { &Left1GC, &Left1Xbm, left1_bits, left1_width, left1_height },
288 { &Left2GC, &Left2Xbm, left2_bits, left2_width, left2_height },
289 { &Right1GC, &Right1Xbm, right1_bits, right1_width, right1_height },
290 { &Right2GC, &Right2Xbm, right2_bits, right2_width, right2_height },
291 { &UpLeft1GC, &UpLeft1Xbm, upleft1_bits, upleft1_width, upleft1_height },
292 { &UpLeft2GC, &UpLeft2Xbm, upleft2_bits, upleft2_width, upleft2_height },
294 &UpRight1Xbm, upright1_bits, upright1_width, upright1_height },
296 &UpRight2Xbm, upright2_bits, upright2_width, upright2_height },
297 { &DownLeft1GC, &DownLeft1Xbm, dwleft1_bits, dwleft1_width, dwleft1_height },
298 { &DownLeft2GC, &DownLeft2Xbm, dwleft2_bits, dwleft2_width, dwleft2_height },
300 &DownRight1Xbm, dwright1_bits, dwright1_width, dwright1_height },
302 &DownRight2Xbm, dwright2_bits, dwright2_width, dwright2_height },
303 { &UpTogi1GC, &UpTogi1Xbm, utogi1_bits, utogi1_width, utogi1_height },
304 { &UpTogi2GC, &UpTogi2Xbm, utogi2_bits, utogi2_width, utogi2_height },
305 { &DownTogi1GC, &DownTogi1Xbm, dtogi1_bits, dtogi1_width, dtogi1_height },
306 { &DownTogi2GC, &DownTogi2Xbm, dtogi2_bits, dtogi2_width, dtogi2_height },
307 { &LeftTogi1GC, &LeftTogi1Xbm, ltogi1_bits, ltogi1_width, ltogi1_height },
308 { &LeftTogi2GC, &LeftTogi2Xbm, ltogi2_bits, ltogi2_width, ltogi2_height },
310 &RightTogi1Xbm, rtogi1_bits, rtogi1_width, rtogi1_height },
312 &RightTogi2Xbm, rtogi2_bits, rtogi2_width, rtogi2_height },
313 { NULL, NULL, NULL, 0, 0 }
317 XCBGCONTEXT *TickEvenGCPtr;
318 XCBGCONTEXT *TickOddGCPtr;
321 Animation AnimationPattern[] = {
322 { &Mati2GC, &Mati2GC }, /* NekoState == NEKO_STOP */
323 { &Jare2GC, &Mati2GC }, /* NekoState == NEKO_JARE */
324 { &Kaki1GC, &Kaki2GC }, /* NekoState == NEKO_KAKI */
325 { &Mati3GC, &Mati3GC }, /* NekoState == NEKO_AKUBI */
326 { &Sleep1GC, &Sleep2GC }, /* NekoState == NEKO_SLEEP */
327 { &AwakeGC, &AwakeGC }, /* NekoState == NEKO_AWAKE */
328 { &Up1GC, &Up2GC } , /* NekoState == NEKO_U_MOVE */
329 { &Down1GC, &Down2GC }, /* NekoState == NEKO_D_MOVE */
330 { &Left1GC, &Left2GC }, /* NekoState == NEKO_L_MOVE */
331 { &Right1GC, &Right2GC }, /* NekoState == NEKO_R_MOVE */
332 { &UpLeft1GC, &UpLeft2GC }, /* NekoState == NEKO_UL_MOVE */
333 { &UpRight1GC, &UpRight2GC }, /* NekoState == NEKO_UR_MOVE */
334 { &DownLeft1GC, &DownLeft2GC }, /* NekoState == NEKO_DL_MOVE */
335 { &DownRight1GC, &DownRight2GC }, /* NekoState == NEKO_DR_MOVE */
336 { &UpTogi1GC, &UpTogi2GC }, /* NekoState == NEKO_U_TOGI */
337 { &DownTogi1GC, &DownTogi2GC }, /* NekoState == NEKO_D_TOGI */
338 { &LeftTogi1GC, &LeftTogi2GC }, /* NekoState == NEKO_L_TOGI */
339 { &RightTogi1GC, &RightTogi2GC }, /* NekoState == NEKO_R_TOGI */
343 /* PutImage.c: format/unit/order conversion should move out to a library */
344 static unsigned char const _reverse_byte[0x100] = {
345 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
346 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
347 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
348 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
349 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
350 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
351 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
352 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
353 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
354 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
355 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
356 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
357 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
358 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
359 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
360 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
361 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
362 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
363 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
364 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
365 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
366 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
367 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
368 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
369 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
370 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
371 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
372 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
373 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
374 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
375 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
376 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
379 /* convert 1Ll <--> 4Mm */
382 register unsigned char *src,
383 register unsigned char *dest,
384 long srclen, long srcinc, long destinc,
388 register const unsigned char *rev = _reverse_byte;
392 for (h = height; --h >= 0; src += srcinc, dest += destinc)
393 for (n = srclen; --n >= 0; )
394 *dest++ = rev[*src++];
397 /* assumes pad is a power of 2 */
398 #define ROUNDUP(nbytes, pad) (((nbytes) + ((pad) - 1)) & ~(long)((pad) - 1))
400 /* CrPFBData.c and CrBFData.c (very similar) */
401 /* if depth==1, behaves like CreateBitmapFromData */
402 XCBPIXMAP CreatePixmapFromBitmapData( XCBConnection *c,
403 XCBWINDOW window, char *data, CARD16 w, CARD16 h,
404 CARD32 fg, CARD32 bg, CARD32 depth)
406 XCBDRAWABLE drawable;
407 XCBPIXMAP bitmap = XCBPIXMAPNew( c );
409 drawable.window = window;
410 XCBCreatePixmap( c, depth, bitmap, drawable, w, h );
412 XCBGCONTEXT gc = XCBGCONTEXTNew( c );
414 CARD32 mask = (depth==1 ? 0 : XCBGCForeground | XCBGCBackground);
415 CARD32 values[] = { fg, bg };
417 drawable.pixmap = bitmap;
418 XCBCreateGC( c, gc, drawable, mask, values );
420 /* XImage attributes: bpp=1, xoffset=0,
421 byte_order=bit_order=LSB, unit=8, pad=8, bpl=(w+7/8) */
423 /* must swap and pad the data if bit/byte_order isn't LSB (Mac) */
425 /* Mac X Server: byte_order=bit_order=MSB, unit=32, padding=32 */
427 long pad = XCBGetSetup(c)->bitmap_format_scanline_pad;
428 long bpd = ROUNDUP(w, pad)>>3;
429 long bufLen = bpd * h;
431 if (XCBGetSetup(c)->bitmap_format_scanline_unit == 32 &&
432 XCBGetSetup(c)->bitmap_format_bit_order == XCBImageOrderMSBFirst &&
433 XCBGetSetup(c)->image_byte_order == XCBImageOrderMSBFirst)
435 SwapBits((unsigned char *)data, buf, bpl, bpl, bpd, h);
440 BYTE *src = (BYTE *)data, *dest = buf;
441 for (i=0; i<h; i++, dest += bpd, src += bpl)
442 memcpy(dest, src, bpl);
445 memcpy(buf, data, bufLen);
447 /* note: CBfD uses XYPixmap, but CPfBD uses XYBitmap
448 there shouldn't be a difference when depth==1,
449 but the neko images are corrupt if using XYPixmap */
450 CARD8 format = (depth==1 ? XCBImageFormatXYPixmap : XCBImageFormatXYBitmap);
452 /* PutImage.c: left_pad = (image->xoffset + req->xoffset) & (dpy->bitmap_unit-1)
453 screen->bitmap_format_scanline_unit
454 left_pad = (0 + 0) & (32 - 1) = 0 */
456 XCBPutImage( c, format, drawable, gc,
458 0, 1, /* left_pad, depth */
462 XCBGenericError *error = NULL;
463 XCBSync( c, &error );
465 printf("error code %d", (int)error->error_code);
472 /* later: XCBFreePixmap( c, bitmap ); */
476 XCBPIXMAP CreateBitmapFromData(XCBConnection *c, XCBWINDOW window,
477 char *data, CARD16 w, CARD16 h)
480 return CreatePixmapFromBitmapData(c, window, data, w, h, 0, 0, depth);
483 void InitBitmapAndGCs(void) {
484 BitmapGCData *BitmapGCDataTablePtr;
485 CARD32 theGCValues[5];
486 XCBDRAWABLE drawable; drawable.window = theWindow;
488 theGCValues[0] = XCBGXcopy;
490 theGCValues[1] = theFgPixel;
491 theGCValues[2] = theBgPixel;
493 theGCValues[3] = XCBFillStyleTiled;
495 /* TODO: latency: make all the bitmaps, then all the contexts? */
497 for ( BitmapGCDataTablePtr = BitmapGCDataTable;
498 BitmapGCDataTablePtr->GCCreatePtr != NULL;
499 BitmapGCDataTablePtr++ ) {
501 *(BitmapGCDataTablePtr->BitmapCreatePtr)
502 = CreatePixmapFromBitmapData( xc, theScreen->root,
503 BitmapGCDataTablePtr->PixelPattern,
504 BitmapGCDataTablePtr->PixelWidth,
505 BitmapGCDataTablePtr->PixelHeight,
506 theFgPixel, theBgPixel, theScreen->root_depth);
508 theGCValues[4] = BitmapGCDataTablePtr->BitmapCreatePtr->xid; /* tile */
510 *(BitmapGCDataTablePtr->GCCreatePtr) = XCBGCONTEXTNew( xc );
511 XCBCreateGC( xc, *(BitmapGCDataTablePtr->GCCreatePtr), drawable,
512 XCBGCFunction | XCBGCForeground | XCBGCBackground |
513 XCBGCFillStyle | XCBGCTile,
517 /* later: XCBFreePixmap( c, bitmap ); */
518 /* later: XCBFreeGC( c, gc ); */
522 GetAtom(XCBConnection *c, const char *atomName)
524 XCBATOM atom = { XCBNone };
525 XCBInternAtomRep *r = XCBInternAtomReply(c,
526 XCBInternAtom(c, 0, strlen(atomName), atomName), NULL);
535 InitScreen( char *DisplayName, char *theGeometry, char *theTitle, Bool iconicState )
537 XCBPIXMAP theCursorSource;
538 XCBPIXMAP theCursorMask;
539 unsigned int theDepth;
540 XCBCOLORMAP theColormap;
543 if ( ( xc = XCBConnect( DisplayName, &screen ) ) == NULL ) {
544 fprintf( stderr, "%s: Can't open connection", ProgramName );
545 if ( DisplayName != NULL )
546 fprintf( stderr, " %s.\n", DisplayName );
548 fprintf( stderr, ".\n" );
552 theScreen = XCBAuxGetScreen(xc, screen);
553 if (theScreen == NULL) {
554 fprintf( stderr, "%s: Can't get default screen", ProgramName );
558 theDepth = theScreen->root_depth; /* DefaultDepth */
559 theColormap = theScreen->default_colormap;
561 WindowPointX = DEFAULT_WIN_X;
562 WindowPointY = DEFAULT_WIN_Y;
563 WindowWidth = WINDOW_WIDTH;
564 WindowHeight = WINDOW_HEIGHT;
568 GeometryStatus = XParseGeometry( theGeometry,
569 &WindowPointX, &WindowPointY,
570 &WindowWidth, &WindowHeight );
573 theCursorSource = CreateBitmapFromData( xc,
579 theCursorMask = CreateBitmapFromData( xc,
583 cursor_mask_height );
586 if ( bgColor == NULL) bgColor = "white";
587 if ( fgColor == NULL) fgColor = "black";
589 XCBAllocNamedColorCookie bgCookie = XCBAllocNamedColor ( xc,
590 theColormap, strlen(bgColor), bgColor );
592 XCBAllocNamedColorCookie fgCookie = XCBAllocNamedColor ( xc,
593 theColormap, strlen(fgColor), fgColor );
595 /* mouse cursor is always black and white */
596 XCBAllocNamedColorCookie blackCookie = XCBAllocNamedColor ( xc,
597 theColormap, strlen("black"), "black" );
598 XCBAllocNamedColorCookie whiteCookie = XCBAllocNamedColor ( xc,
599 theColormap, strlen("white"), "white" );
601 XCBAllocNamedColorRep *bgRep = XCBAllocNamedColorReply( xc, bgCookie, 0 );
604 "%s: Can't allocate the background color %s.\n", ProgramName, bgColor );
607 theBgPixel = bgRep->pixel;
609 XCBAllocNamedColorRep *fgRep = XCBAllocNamedColorReply( xc, fgCookie, 0 );
612 "%s: Can't allocate the foreground color %s.\n", ProgramName, fgColor );
615 theFgPixel = fgRep->pixel;
617 XCBAllocNamedColorRep *blackRep = XCBAllocNamedColorReply( xc, blackCookie, 0 );
620 "%s: Can't allocate the black color.\n", ProgramName );
623 XCBAllocNamedColorRep *whiteRep = XCBAllocNamedColorReply( xc, whiteCookie, 0 );
626 "%s: Can't allocate the white color.\n", ProgramName );
630 theCursor = XCBCURSORNew( xc );
631 XCBCreateCursor ( xc, theCursor, theCursorSource, theCursorMask,
632 blackRep->visual_red, blackRep->visual_green, blackRep->visual_blue,
633 whiteRep->visual_red, whiteRep->visual_green, whiteRep->visual_blue,
634 cursor_x_hot, cursor_y_hot );
642 CARD32 rootAttributes[] = { theBgPixel, EVENT_MASK_ROOT, theCursor.xid };
643 theWindow = theScreen->root;
644 XCBChangeWindowAttributes(xc, theWindow,
645 XCBCWBackPixel | XCBCWEventMask | XCBCWCursor, rootAttributes );
647 /* XClearWindow: clear area with all dimensions 0 */
648 XCBClearArea( xc, False, theWindow, 0, 0, 0, 0 );
650 XCBDRAWABLE d = { theWindow };
651 XCBGetGeometryRep *geometry = XCBGetGeometryReply( xc,
652 XCBGetGeometry( xc, d ), NULL);
654 /* only width & height are used by the program */
655 WindowWidth = geometry->width;
656 WindowHeight = geometry->height;
660 /* TODO: grab key Alt-Q to quit gracefully? */
663 XCBPIXMAP theIconPixmap;
665 CARD32 theWindowAttributes[] = {
666 theBgPixel, /* background */
667 theFgPixel, /* border */
668 False, /* override_redirect */
672 unsigned long theWindowMask = XCBCWBackPixel | XCBCWBorderPixel |
673 XCBCWOverrideRedirect | XCBCWEventMask | XCBCWCursor;
675 theWindow = XCBWINDOWNew( xc );
680 WindowPointX, WindowPointY,
681 WindowWidth, WindowHeight,
683 XCBWindowClassInputOutput,
684 theScreen->root_visual, /* CopyFromParent */
685 theWindowMask, theWindowAttributes );
687 /* new: obey the window-delete protocol, look for XCBClientMessage */
688 deleteWindowAtom = GetAtom(xc, "WM_DELETE_WINDOW");
689 SetWMProtocols( xc, theWindow, 1, &deleteWindowAtom );
691 theIconPixmap = CreateBitmapFromData( xc, theWindow,
692 icon_bits, icon_width, icon_height );
694 WMHints *theWMHints = AllocWMHints();
696 WMHintsSetIconPixmap( theWMHints, theIconPixmap );
699 WMHintsSetIconic( theWMHints );
701 WMHintsSetNormal( theWMHints );
703 SetWMHints( xc, theWindow, theWMHints);
707 /* why hide the structure? */
708 SizeHints *theSizeHints = AllocSizeHints();
710 /* need enum for second param (user specified) */
711 SizeHintsSetPosition(theSizeHints, 0, WindowPointX, WindowPointY);
712 SizeHintsSetSize(theSizeHints, 0, WindowWidth, WindowHeight);
714 SetWMNormalHints(xc, theWindow, theSizeHints);
716 FreeSizeHints(theSizeHints);
718 /* Um, why do I have to specify the encoding in this API? */
719 SetWMName( xc, theWindow, STRING, strlen(theTitle), theTitle );
720 SetWMIconName( xc, theWindow, STRING, strlen(theTitle), theTitle );
722 XCBMapWindow( xc, theWindow );
730 /* latency: ask for keysyms now, and receive them later */
731 theKeySyms = XCBKeySymbolsAlloc( xc );
733 /* later: XCBKeySymbolsFree( keysyms ); */
734 /* later: XCBRefreshKeyboardMapping ( keysyms, mappingEvent ); */
738 void Interval(void) {
743 void TickCount(void) {
744 if ( ++NekoTickCount >= MAX_TICK )
747 if ( NekoTickCount % 2 == 0 )
748 if ( NekoStateCount < MAX_TICK )
754 SetNekoState( int SetValue )
759 NekoState = SetValue;
762 switch ( NekoState ) {
772 NekoMoveDx = NekoMoveDy = 0;
781 /* Xlib does merging of requests, but the Flush and frequent DrawGC changes
782 defeat this mechanism */
785 DrawNeko( int x, int y, XCBGCONTEXT DrawGC )
787 XCBDRAWABLE drawable; drawable.window = theWindow;
788 XCBRECTANGLE rect = { NekoLastX, NekoLastY, BITMAP_WIDTH, BITMAP_HEIGHT };
790 if ( (x != NekoLastX || y != NekoLastY) && (EventState != DEBUG_LIST) )
792 XCBPolyFillRectangle( xc, drawable, SpaceGC, 1, &rect );
793 rect.x = x; rect.y = y;
797 CARD32 originMask = XCBGCTileStippleOriginX | XCBGCTileStippleOriginY;
798 CARD32 origin[2] = { x, y };
799 XCBChangeGC( xc, DrawGC, originMask, origin );
800 /* XSetTSOrigin( theDisplay, DrawGC, x, y ); */
802 XCBPolyFillRectangle( xc, drawable, DrawGC, 1, &rect );
813 void RedrawNeko(void) {
814 XCBDRAWABLE drawable; drawable.window = theWindow;
815 XCBRECTANGLE rect = { NekoLastX, NekoLastY, BITMAP_WIDTH, BITMAP_HEIGHT };
817 XCBPolyFillRectangle( xc, drawable, NekoLastGC, 1, &rect );
824 void NekoDirection(void) {
826 double LargeX, LargeY;
830 if ( NekoMoveDx == 0 && NekoMoveDy == 0 ) {
831 NewState = NEKO_STOP;
833 LargeX = (double)NekoMoveDx;
834 LargeY = (double)(-NekoMoveDy);
835 Length = sqrt( LargeX * LargeX + LargeY * LargeY );
836 SinTheta = LargeY / Length;
838 if ( NekoMoveDx > 0 ) {
839 if ( SinTheta > SinPiPer8Times3 ) {
840 NewState = NEKO_U_MOVE;
841 } else if ( ( SinTheta <= SinPiPer8Times3 )
842 && ( SinTheta > SinPiPer8 ) ) {
843 NewState = NEKO_UR_MOVE;
844 } else if ( ( SinTheta <= SinPiPer8 )
845 && ( SinTheta > -( SinPiPer8 ) ) ) {
846 NewState = NEKO_R_MOVE;
847 } else if ( ( SinTheta <= -( SinPiPer8 ) )
848 && ( SinTheta > -( SinPiPer8Times3 ) ) ) {
849 NewState = NEKO_DR_MOVE;
851 NewState = NEKO_D_MOVE;
854 if ( SinTheta > SinPiPer8Times3 ) {
855 NewState = NEKO_U_MOVE;
856 } else if ( ( SinTheta <= SinPiPer8Times3 )
857 && ( SinTheta > SinPiPer8 ) ) {
858 NewState = NEKO_UL_MOVE;
859 } else if ( ( SinTheta <= SinPiPer8 )
860 && ( SinTheta > -( SinPiPer8 ) ) ) {
861 NewState = NEKO_L_MOVE;
862 } else if ( ( SinTheta <= -( SinPiPer8 ) )
863 && ( SinTheta > -( SinPiPer8Times3 ) ) ) {
864 NewState = NEKO_DL_MOVE;
866 NewState = NEKO_D_MOVE;
871 if ( NekoState != NewState ) {
872 SetNekoState( NewState );
877 Bool IsWindowOver(void) {
878 Bool ReturnValue = False;
883 } else if ( NekoY >= WindowHeight - BITMAP_HEIGHT ) {
884 NekoY = WindowHeight - BITMAP_HEIGHT;
890 } else if ( NekoX >= WindowWidth - BITMAP_WIDTH ) {
891 NekoX = WindowWidth - BITMAP_WIDTH;
895 return( ReturnValue );
899 Bool IsNekoDontMove(void) {
900 return( NekoX == NekoLastX && NekoY == NekoLastY );
904 Bool IsNekoMoveStart(void) {
906 if ( (PrevMouseX >= MouseX - IDLE_SPACE
907 && PrevMouseX <= MouseX + IDLE_SPACE) &&
908 (PrevMouseY >= MouseY - IDLE_SPACE
909 && PrevMouseY <= MouseY + IDLE_SPACE) )
914 if ( NekoMoveDx == 0 && NekoMoveDy == 0 )
922 void CalcDxDy(void) {
923 int RelativeX, RelativeY;
924 double LargeX, LargeY;
925 double DoubleLength, Length;
927 /* TODO: replace query with pointer motion notification? */
929 XCBQueryPointerRep *reply = XCBQueryPointerReply( xc,
930 XCBQueryPointer( xc, theWindow ), NULL);
932 RelativeX = reply->win_x;
933 RelativeY = reply->win_y;
943 LargeX = (double)( MouseX - NekoX - BITMAP_WIDTH / 2 );
944 LargeY = (double)( MouseY - NekoY - BITMAP_HEIGHT );
946 DoubleLength = LargeX * LargeX + LargeY * LargeY;
948 if ( DoubleLength != (double)0 ) {
949 Length = sqrt( DoubleLength );
950 if ( Length <= NekoSpeed ) {
951 NekoMoveDx = (int)LargeX;
952 NekoMoveDy = (int)LargeY;
954 NekoMoveDx = (int)( ( NekoSpeed * LargeX ) / Length );
955 NekoMoveDy = (int)( ( NekoSpeed * LargeY ) / Length );
958 NekoMoveDx = NekoMoveDy = 0;
963 void NekoThinkDraw(void) {
968 if ( NekoState != NEKO_SLEEP ) {
969 DrawNeko( NekoX, NekoY,
970 NekoTickCount % 2 == 0 ?
971 *(AnimationPattern[ NekoState ].TickEvenGCPtr) :
972 *(AnimationPattern[ NekoState ].TickOddGCPtr) );
974 DrawNeko( NekoX, NekoY,
975 NekoTickCount % 8 <= 3 ?
976 *(AnimationPattern[ NekoState ].TickEvenGCPtr) :
977 *(AnimationPattern[ NekoState ].TickOddGCPtr) );
982 switch ( NekoState ) {
984 if ( IsNekoMoveStart() ) {
985 SetNekoState( NEKO_AWAKE );
988 if ( NekoStateCount < NEKO_STOP_TIME ) {
991 if ( NekoMoveDx < 0 && NekoX <= 0 ) {
992 SetNekoState( NEKO_L_TOGI );
993 } else if ( NekoMoveDx > 0 && NekoX >= WindowWidth - BITMAP_WIDTH ) {
994 SetNekoState( NEKO_R_TOGI );
995 } else if ( NekoMoveDy < 0 && NekoY <= 0 ) {
996 SetNekoState( NEKO_U_TOGI );
997 } else if ( NekoMoveDy > 0 && NekoY >= WindowHeight - BITMAP_HEIGHT ) {
998 SetNekoState( NEKO_D_TOGI );
1000 SetNekoState( NEKO_JARE );
1004 if ( IsNekoMoveStart() ) {
1005 SetNekoState( NEKO_AWAKE );
1008 if ( NekoStateCount < NEKO_JARE_TIME ) {
1011 SetNekoState( NEKO_KAKI );
1014 if ( IsNekoMoveStart() ) {
1015 SetNekoState( NEKO_AWAKE );
1018 if ( NekoStateCount < NEKO_KAKI_TIME ) {
1021 SetNekoState( NEKO_AKUBI );
1024 if ( IsNekoMoveStart() ) {
1025 SetNekoState( NEKO_AWAKE );
1028 if ( NekoStateCount < NEKO_AKUBI_TIME ) {
1031 SetNekoState( NEKO_SLEEP );
1034 if ( IsNekoMoveStart() ) {
1035 SetNekoState( NEKO_AWAKE );
1040 if ( NekoStateCount < NEKO_AWAKE_TIME ) {
1053 NekoX += NekoMoveDx;
1054 NekoY += NekoMoveDy;
1056 if ( IsWindowOver() ) {
1057 if ( IsNekoDontMove() ) {
1058 SetNekoState( NEKO_STOP );
1066 if ( IsNekoMoveStart() ) {
1067 SetNekoState( NEKO_AWAKE );
1070 if ( NekoStateCount < NEKO_TOGI_TIME ) {
1073 SetNekoState( NEKO_KAKI );
1076 /* Internal Error */
1077 SetNekoState( NEKO_STOP );
1086 void DisplayCharacters() {
1090 for ( Index = 0, x = 0, y = 0;
1091 BitmapGCDataTable[ Index ].GCCreatePtr != NULL; Index++ ) {
1093 DrawNeko( x, y, *(BitmapGCDataTable[ Index ].GCCreatePtr) );
1094 XFlush( theDisplay );
1098 if ( x > WindowWidth - BITMAP_WIDTH ) {
1101 if ( y > WindowHeight - BITMAP_HEIGHT) {
1111 ProcessKeyPress( XCBKeyPressEvent *theKeyEvent )
1113 Bool ReturnState = True;
1115 /* quit on Meta-Q (Alt-Q) */
1116 XCBKEYSYM theKeySym;
1118 /* last param is "int col". What? add enumeration to xcb_keysyms.h */
1119 theKeySym = XCBKeyPressLookupKeysym( theKeySyms, theKeyEvent, 1 );
1121 /* KeySym XK_Q == 'Q' */
1122 if (theKeySym.id == 'Q' && (theKeyEvent->state & XCBModMask1))
1123 ReturnState = False;
1126 if ( EventState == DEBUG_MOVE ) {
1127 switch ( theKeySym ) {
1129 NekoMoveDx = -(int)( NekoSpeed / sqrt( (double)2 ) );
1130 NekoMoveDy = -NekoMoveDx;
1134 NekoMoveDy = (int)NekoSpeed;
1137 NekoMoveDx = (int)( NekoSpeed / sqrt( (double)2 ) );
1138 NekoMoveDy = NekoMoveDx;
1141 NekoMoveDx = -(int)NekoSpeed;
1149 NekoMoveDx = (int)NekoSpeed;
1153 NekoMoveDx = -(int)( NekoSpeed / sqrt( (double)2 ) );
1154 NekoMoveDy = NekoMoveDx;
1158 NekoMoveDy = -(int)NekoSpeed;
1161 NekoMoveDx = (int)( NekoSpeed / sqrt( (double)2 ) );
1162 NekoMoveDy = -NekoMoveDx;
1168 return( ReturnState );
1172 void NekoAdjust(void) {
1175 else if ( NekoX > WindowWidth - BITMAP_WIDTH )
1176 NekoX = WindowWidth - BITMAP_WIDTH;
1180 else if ( NekoY > WindowHeight - BITMAP_HEIGHT )
1181 NekoY = WindowHeight - BITMAP_HEIGHT;
1184 int IsDeleteMessage(XCBClientMessageEvent *msg)
1186 return msg->data.data32[0] == deleteWindowAtom.xid;
1189 Bool ProcessEvent(void) {
1190 XCBGenericEvent *theEvent;
1191 XCBConfigureNotifyEvent *theConfigureNotification;
1192 XCBExposeEvent *theExposure;
1193 XCBButtonPressEvent *theButtonPress;
1194 Bool ContinueState = True;
1197 switch ( EventState ) {
1199 while ( ContinueState &&
1200 NULL != (theEvent = XCBPollForEvent( xc, &error )) ) { /*while ( XCheckMaskEvent( theDisplay, EVENT_MASK, &theEvent ) ) {*/
1201 switch ( theEvent->response_type & 0x7f ) {
1202 case XCBConfigureNotify:
1203 theConfigureNotification = (XCBConfigureNotifyEvent *)theEvent;
1204 WindowWidth = theConfigureNotification->width;
1205 WindowHeight = theConfigureNotification->height;
1206 WindowPointX = theConfigureNotification->x;
1207 WindowPointY = theConfigureNotification->y;
1208 BorderWidth = theConfigureNotification->border_width;
1212 theExposure = (XCBExposeEvent *)theEvent;
1213 if ( theExposure->count == 0 )
1220 ContinueState = ProcessKeyPress( (XCBKeyPressEvent *)theEvent );
1222 case XCBButtonPress:
1223 theButtonPress = (XCBButtonPressEvent *)theEvent;
1224 ContinueState = ( theButtonPress->detail.id != 3 ); /* xbutton.button */
1226 /* new: handle ClientMessage */
1227 case XCBClientMessage:
1228 ContinueState = !IsDeleteMessage((XCBClientMessageEvent *)theEvent);
1232 /*printf("event type:%x\n", (int)theEvent->response_type);*/
1242 XNextEvent( theDisplay, &theEvent );
1243 switch ( theEvent.type ) {
1244 case ConfigureNotify:
1245 WindowWidth = theEvent.xconfigure.width;
1246 WindowHeight = theEvent.xconfigure.height;
1247 WindowPointX = theEvent.xconfigure.x;
1248 WindowPointY = theEvent.xconfigure.y;
1249 BorderWidth = theEvent.xconfigure.border_width;
1252 if ( theEvent.xexpose.count == 0 )
1253 DisplayCharacters();
1256 DisplayCharacters();
1259 ContinueState = ProcessKeyPress( &theEvent );
1262 if ( theEvent.xbutton.button == 3 )
1271 while ( XCheckMaskEvent( theDisplay, EVENT_MASK, &theEvent ) ) {
1272 switch ( theEvent.type ) {
1273 case ConfigureNotify:
1274 WindowWidth = theEvent.xconfigure.width;
1275 WindowHeight = theEvent.xconfigure.height;
1276 WindowPointX = theEvent.xconfigure.x;
1277 WindowPointY = theEvent.xconfigure.y;
1278 BorderWidth = theEvent.xconfigure.border_width;
1282 if ( theEvent.xexpose.count == 0 )
1289 ContinueState = ProcessKeyPress( &theEvent );
1290 if ( !ContinueState ) {
1291 return( ContinueState );
1295 if ( theEvent.xbutton.button == 3 )
1306 /* Internal Error */
1310 return( ContinueState );
1314 void ProcessNeko(void) {
1315 struct itimerval Value;
1317 EventState = NORMAL_STATE;
1319 NekoX = ( WindowWidth - BITMAP_WIDTH / 2 ) / 2;
1320 NekoY = ( WindowHeight - BITMAP_HEIGHT / 2 ) / 2;
1325 SetNekoState( NEKO_STOP );
1327 timerclear( &Value.it_interval );
1328 timerclear( &Value.it_value );
1330 Value.it_interval.tv_usec = IntervalTime;
1331 Value.it_value.tv_usec = IntervalTime;
1333 setitimer( ITIMER_REAL, &Value, 0 );
1337 } while ( ProcessEvent() );
1343 EventState = DEBUG_LIST;
1345 fprintf( stderr, "\n" );
1346 fprintf( stderr, "G-0lMw$rI=<($7$^$9!#(Quit !D Alt-Q)\n" );
1347 fprintf( stderr, "\n" );
1349 XSelectInput( theDisplay, theWindow, EVENT_MASK );
1351 while ( ProcessEvent() );
1355 void NekoMoveTest() {
1356 struct itimerval Value;
1358 EventState = DEBUG_MOVE;
1360 NekoX = ( WindowWidth - BITMAP_WIDTH / 2 ) / 2;
1361 NekoY = ( WindowHeight - BITMAP_HEIGHT / 2 ) / 2;
1366 SetNekoState( NEKO_STOP );
1368 timerclear( &Value.it_interval );
1369 timerclear( &Value.it_value );
1371 Value.it_interval.tv_usec = IntervalTime;
1372 Value.it_value.tv_usec = IntervalTime;
1374 setitimer( ITIMER_REAL, &Value, 0 );
1376 fprintf( stderr, "\n" );
1377 fprintf( stderr, "G-$N0\F0%F%9%H$r9T$$$^$9!#(Quit !D Alt-Q)\n" );
1378 fprintf( stderr, "\n" );
1379 fprintf( stderr, "\t%-!<%Q%C%I>e$N%F%s%-!<$GG-$r0\F0$5$;$F2<$5$$!#\n" );
1380 fprintf( stderr, "\t(M-8z$J%-!<$O#1!A#9$G$9!#)\n" );
1381 fprintf( stderr, "\n" );
1385 } while ( ProcessEvent() );
1389 void ProcessDebugMenu() {
1390 int UserSelectNo = 0;
1391 char UserAnswer[ BUFSIZ ];
1393 fprintf( stderr, "\n" );
1394 fprintf( stderr, "!Zxneko %G%P%C%0%a%K%e!<![\n" );
1396 while ( !( UserSelectNo >= 1 && UserSelectNo <= 2 ) ) {
1397 fprintf( stderr, "\n" );
1398 fprintf( stderr, "\t1)!!G-%-%c%i%/%?!<0lMwI=<(\n" );
1399 fprintf( stderr, "\t2)!!G-0\F0%F%9%H\n" );
1400 fprintf( stderr, "\n" );
1401 fprintf( stderr, "Select: " );
1403 fgets( UserAnswer, sizeof( UserAnswer ), stdin );
1405 UserSelectNo = atoi( UserAnswer );
1407 if ( !( UserSelectNo >= 1 && UserSelectNo <= 2 ) ) {
1408 fprintf( stderr, "\n" );
1409 fprintf( stderr, "@5$7$$HV9f$rA*Br$7$F2<$5$$!#\n" );
1413 switch ( UserSelectNo ) {
1421 /* Internal Error */
1425 fprintf( stderr, "%F%9%H=*N;!#\n" );
1426 fprintf( stderr, "\n" );
1431 void NullFunction(int ignored)
1433 /* signal( SIGALRM, NullFunction ); */
1439 "Usage: %s [-display <display>] [-geometry <geometry>] \\\n",
1441 fprintf( stderr, "\t[-bg <background>] [-fg <foreground>] \\\n" );
1442 fprintf( stderr, "\t[-title <title>] [-name <title>] [-iconic] \\\n" );
1443 fprintf( stderr, "\t[-speed <speed>] [-time <time>] [-root] [-help]\n" );
1448 GetArguments( int argc, char *argv[],
1449 char *theDisplayName, char *theGeometry, char **theTitle,
1450 double *NekoSpeed, long *IntervalTime )
1455 theDisplayName[ 0 ] = '\0';
1456 theGeometry[ 0 ] = '\0';
1458 iconicState = False;
1460 for ( ArgCounter = 0; ArgCounter < argc; ArgCounter++ ) {
1461 if ( strncmp( argv[ ArgCounter ], "-h", 2 ) == 0 ) {
1464 } else if ( strcmp( argv[ ArgCounter ], "-display" ) == 0 ) {
1466 if ( ArgCounter < argc ) {
1467 strcpy( theDisplayName, argv[ ArgCounter ] );
1469 fprintf( stderr, "%s: -display option error.\n", ProgramName );
1472 } else if ( strncmp( argv[ ArgCounter ], "-geom", 5 ) == 0 ) {
1474 if ( ArgCounter < argc ) {
1475 strcpy( theGeometry, argv[ ArgCounter ] );
1478 "%s: -geometry option error.\n", ProgramName );
1481 } else if ( ( strcmp( argv[ ArgCounter ], "-title" ) == 0 )
1482 || ( strcmp( argv[ ArgCounter ], "-name" ) == 0 ) ) {
1484 if ( ArgCounter < argc ) {
1485 *theTitle = argv[ ArgCounter ];
1487 fprintf( stderr, "%s: -title option error.\n", ProgramName );
1490 } else if ( strcmp( argv[ ArgCounter ], "-iconic" ) == 0 ) {
1492 } else if ( strcmp( argv[ ArgCounter ], "-speed" ) == 0 ) {
1494 if ( ArgCounter < argc ) {
1495 *NekoSpeed = atof( argv[ ArgCounter ] );
1497 fprintf( stderr, "%s: -speed option error.\n", ProgramName );
1500 } else if ( strcmp( argv[ ArgCounter ], "-fg" ) == 0 ) {
1502 if ( ArgCounter < argc ) {
1503 fgColor = argv[ArgCounter];
1505 fprintf( stderr, "%s: -fg option error.\n", ProgramName );
1508 } else if ( strcmp( argv[ ArgCounter ], "-bg" ) == 0 ) {
1510 if ( ArgCounter < argc ) {
1511 bgColor = argv[ArgCounter];
1513 fprintf( stderr, "%s: -bg option error.\n", ProgramName );
1516 } else if ( strcmp( argv[ ArgCounter ], "-time" ) == 0 ) {
1518 if ( ArgCounter < argc ) {
1519 *IntervalTime = atol( argv[ ArgCounter ] );
1521 fprintf( stderr, "%s: -time option error.\n", ProgramName );
1524 } else if ( strcmp( argv[ ArgCounter ], "-root" ) == 0 ) {
1528 "%s: Unknown option \"%s\".\n", ProgramName,
1529 argv[ ArgCounter ] );
1535 return( iconicState );
1538 void UndefineCursor( XCBConnection *c, XCBWINDOW w)
1540 CARD32 none[] = { XCBNone };
1541 XCBChangeWindowAttributes( c, w, XCBCWCursor, none );
1545 main( int argc, char *argv[] )
1548 char theDisplayName[ DIRNAMELEN ];
1549 char theGeometry[ DIRNAMELEN ];
1550 char *theTitle = "";
1552 ProgramName = argv[ 0 ];
1558 fgColor = bgColor = (char *) NULL;
1560 iconicState = GetArguments( argc, argv, theDisplayName, theGeometry,
1561 &theTitle, &NekoSpeed, &IntervalTime );
1563 if (theTitle[0] == 0) theTitle = ProgramName;
1564 InitScreen( theDisplayName, theGeometry, theTitle, iconicState );
1566 signal( SIGALRM, NullFunction );
1568 SinPiPer8Times3 = sin( PI_PER8 * (double)3 );
1569 SinPiPer8 = sin( PI_PER8 );
1577 UndefineCursor( xc, theWindow );
1578 XCBDisconnect( xc );