Annotation of researchv9/X11/src/X.V11R1/clients/puzzle/main.c, revision 1.1

1.1     ! root        1: 
        !             2: /**  Puzzle
        !             3:  **
        !             4:  ** Don Bennett, HP Labs 
        !             5:  ** 
        !             6:  ** this is the interface code for the puzzle program.
        !             7:  **/
        !             8: 
        !             9: #include <stdio.h>
        !            10: #include <X11/Xatom.h>
        !            11: #include <X11/Xlib.h>
        !            12: #include <X11/Xutil.h>
        !            13: 
        !            14: #include "ac.cursor"
        !            15: #include "ac_mask"
        !            16: 
        !            17: #define max(x,y)       (x>y?x:y)
        !            18: #define min(x,y)       (x>y?y:x)
        !            19: 
        !            20: #define PUZZLE_BORDER_WIDTH    2
        !            21: 
        !            22: #define TITLE_WINDOW_HEIGHT    25
        !            23: #define BOUNDARY_HEIGHT                3
        !            24: 
        !            25: #define BOX_WIDTH              10
        !            26: #define BOX_HEIGHT             10
        !            27: 
        !            28: #define MIN_TILE_HEIGHT                25
        !            29: #define MIN_TILE_WIDTH         25
        !            30: 
        !            31: #define MAX_STEPS              1000
        !            32: 
        !            33: int    BoxWidth  =     BOX_WIDTH;
        !            34: int    BoxHeight =     BOX_HEIGHT;
        !            35: 
        !            36: int    PuzzleSize = 4;
        !            37: int    PuzzleWidth=4, PuzzleHeight=4;
        !            38: 
        !            39: int    TileHeight, TileWidth;
        !            40: int    Tx, Ty;
        !            41: int     TitleWinHeight, BoundaryHeight, TileWinHeight;
        !            42: 
        !            43: int    FgPixel, BgPixel;
        !            44: 
        !            45: Display        *dpy;
        !            46: int            screen;
        !            47: GC             gc, rect_gc;
        !            48: Colormap       PuzzleColormap;
        !            49: 
        !            50: typedef struct {
        !            51:     Window     root;
        !            52:     int                x,y;
        !            53:     u_int      width, height;
        !            54:     u_int      border_width;
        !            55:     u_int      depth;
        !            56: } WindowGeom;
        !            57: 
        !            58: WindowGeom     PuzzleWinInfo;
        !            59: 
        !            60: Window                 PuzzleRoot, TitleWindow, TileWindow,
        !            61:                ScrambleWindow, SolveWindow;
        !            62: 
        !            63: char           *ProgName;
        !            64: 
        !            65: char           *TitleFontName    = "8x13";
        !            66: char           *TileFontName     = "vtbold";
        !            67: 
        !            68: XFontStruct    *TitleFontInfo,
        !            69:                *TileFontInfo;
        !            70: 
        !            71: extern int     OutputLogging;
        !            72: extern int     *position;
        !            73: extern int     space_x, space_y;
        !            74: 
        !            75: int    UsePicture = 0;
        !            76: int    UseDisplay = 0;
        !            77: char   *PictureFileName;
        !            78: 
        !            79: int    PictureWidth;
        !            80: int    PictureHeight;
        !            81: Pixmap PicturePixmap;
        !            82: 
        !            83: int    MoveSteps;
        !            84: int    VertStepSize[MAX_STEPS];
        !            85: int    HoriStepSize[MAX_STEPS];
        !            86: 
        !            87: #define LEFT   0
        !            88: #define RIGHT  1
        !            89: #define UP     2
        !            90: #define        DOWN    3
        !            91: 
        !            92: #define indx(x,y)      (((y)*PuzzleWidth) + (x))
        !            93: #define isdigit(x)     ((x)>= '0' && (x) <= '9')
        !            94: 
        !            95: #define ulx(x,y)       ((x)*TileWidth)
        !            96: #define llx(x,y)       ((x)*TileWidth)
        !            97: #define urx(x,y)       (((x)+1)*TileWidth - 1)
        !            98: #define lrx(x,y)       (((x)+1)*TileWidth - 1)
        !            99: #define uly(x,y)       ((y)*TileHeight)
        !           100: #define ury(x,y)       ((y)*TileHeight)
        !           101: #define lly(x,y)       (((y)+1)*TileHeight - 1)
        !           102: #define lry(x,y)       (((y)+1)*TileHeight - 1)
        !           103: 
        !           104: /*
        !           105:  * PuzzlePending - XPending entry point fo the other module.
        !           106:  */
        !           107: 
        !           108: PuzzlePending()
        !           109: {
        !           110:     return(XPending(dpy));
        !           111: }
        !           112: 
        !           113: /*
        !           114:  * SetupDisplay - eastablish the connection to the X server.
        !           115:  */
        !           116: 
        !           117: SetupDisplay(server)
        !           118: char *server;
        !           119: {
        !           120:     dpy = XOpenDisplay(server);
        !           121:     if (dpy == NULL) {
        !           122:        fprintf(stderr, "SetupDisplay: can't open display \"%s\"\n",server);
        !           123:        exit(1);
        !           124:     } 
        !           125:     screen = DefaultScreen(dpy);
        !           126: }
        !           127: 
        !           128: XQueryWindow(window,frame)
        !           129: Window window;
        !           130: WindowGeom *frame;
        !           131: {
        !           132:     XGetGeometry(dpy, window,
        !           133:                 &(frame->root),
        !           134:                 &(frame->x), &(frame->y),
        !           135:                 &(frame->width), &(frame->height),
        !           136:                 &(frame->border_width),
        !           137:                 &(frame->depth));
        !           138: }
        !           139: 
        !           140: RectSet(W,x,y,w,h,pixel)
        !           141: Window W;
        !           142: int x,y;
        !           143: u_int w,h;
        !           144: u_long pixel;
        !           145: {
        !           146:     XSetForeground(dpy, rect_gc, pixel);
        !           147:     XFillRectangle(dpy, W, rect_gc, x, y, w, h);
        !           148: }
        !           149: 
        !           150: MoveArea(W,src_x,src_y,dst_x,dst_y,w,h)
        !           151: Window W;
        !           152: int src_x, src_y, dst_x, dst_y;
        !           153: u_int w, h;
        !           154: {
        !           155:     XCopyArea(dpy,W,W,gc,src_x,src_y,w,h,dst_x,dst_y);
        !           156: }
        !           157: 
        !           158: /** RepaintTitle - puts the program title in the title bar **/
        !           159: 
        !           160: RepaintTitle()
        !           161: {
        !           162:     int Twidth,Theight, Box_x,Box_y;
        !           163: 
        !           164:     Twidth  = XTextWidth(TitleFontInfo,ProgName,strlen(ProgName));
        !           165:     Theight = TitleFontInfo->ascent + TitleFontInfo->descent;
        !           166:     Tx     = (PuzzleWinInfo.width-Twidth)/2;
        !           167:     Ty     = (TitleWinHeight-Theight)/2 + TitleFontInfo->ascent;
        !           168:     
        !           169:     XSetFont(dpy, gc, TitleFontInfo->fid);
        !           170:     XDrawString(dpy, TitleWindow, gc,
        !           171:          Tx, Ty, ProgName,strlen(ProgName));
        !           172: }
        !           173: 
        !           174: /*
        !           175:  * RepaintBar - Repaint the bar between the title window and
        !           176:  *              the tile window;
        !           177:  */
        !           178: RepaintBar()
        !           179: {
        !           180:     XFillRectangle(dpy, PuzzleRoot, gc,
        !           181:                   0, TitleWinHeight,
        !           182:                   PuzzleWinInfo.width, BoundaryHeight);
        !           183: }
        !           184: 
        !           185: /**
        !           186:  ** RepaintTiles - draw the numbers in the tiles to match the
        !           187:  **                locations array;
        !           188:  **/
        !           189: RepaintTiles()
        !           190: {
        !           191:    if (UsePicture)
        !           192:       RepaintPictureTiles();
        !           193:    else
        !           194:       RepaintNumberTiles();
        !           195: }
        !           196: 
        !           197: RepaintNumberTiles()
        !           198: {
        !           199:     int i,j,counter;
        !           200:     int width,height;
        !           201:     int x_offset,y_offset;
        !           202:     char str[30];
        !           203:     
        !           204:     /** cut the TileWindow into a grid of nxn pieces by inscribing
        !           205:      ** each rectangle with a black border;
        !           206:      ** I don't want to use subwindows for each tile so that I can
        !           207:      ** slide groups of tiles together as a single unit, rather than
        !           208:      ** being forced to move one tile at a time.
        !           209:      **/
        !           210: 
        !           211: #define line(x1,y1,x2,y2) XDrawLine(dpy,TileWindow,gc,(x1),(y1),(x2),(y2))
        !           212: 
        !           213: #define rect(x,y)      (line(ulx(x,y),uly(x,y),urx(x,y),ury(x,y)),     \
        !           214:                         line(urx(x,y),ury(x,y),lrx(x,y),lry(x,y)),     \
        !           215:                         line(lrx(x,y),lry(x,y),llx(x,y),lly(x,y)),     \
        !           216:                         line(llx(x,y),lly(x,y),ulx(x,y),uly(x,y)))
        !           217: 
        !           218: 
        !           219:     for (i=0; i<PuzzleHeight;i++)      /** iterate y values **/
        !           220:        for(j=0; j<PuzzleWidth; j++) {          /** iterate x values **/
        !           221:            RectSet(TileWindow,ulx(j,i),uly(j,i),TileWidth,TileHeight,BgPixel);
        !           222:            rect(j,i);
        !           223:        }
        !           224:     height = TileFontInfo->ascent + TileFontInfo->descent;
        !           225:     y_offset = (TileHeight - height)/2;
        !           226: 
        !           227:     XSetFont(dpy, gc, TileFontInfo->fid);
        !           228: 
        !           229:     counter = 0;
        !           230:     for (i=0; i<PuzzleHeight; i++)
        !           231:        for (j=0; j<PuzzleWidth; j++) {
        !           232:            if (position[counter] == 0) {
        !           233:                RectSet(TileWindow,ulx(j,i),uly(j,i),
        !           234:                        TileWidth,TileHeight,FgPixel);
        !           235:            }
        !           236:            else {
        !           237:                sprintf(str,"%d",position[counter]);
        !           238:                width = XTextWidth(TileFontInfo,str,strlen(str));
        !           239:                x_offset = (TileWidth - width)/2;
        !           240:                XDrawString(dpy, TileWindow, gc,
        !           241:                            ulx(j,i)+x_offset,uly(j,i)+y_offset,
        !           242:                            str,strlen(str));
        !           243:            }
        !           244:            counter++;
        !           245:        }    
        !           246: }
        !           247: 
        !           248: RepaintPictureTiles()
        !           249: {
        !           250:     int i, j, counter;
        !           251:     int tmp, orig_x,orig_y;
        !           252: 
        !           253:     counter = 0;
        !           254:     for (i=0; i<PuzzleHeight; i++)
        !           255:        for (j=0; j<PuzzleWidth; j++) {
        !           256:            if (position[counter] == 0)
        !           257:                RectSet(TileWindow,ulx(j,i),uly(j,i),
        !           258:                        TileWidth,TileHeight,FgPixel);
        !           259:            else {
        !           260:                tmp = position[counter] - 1;
        !           261:                orig_x = tmp % PuzzleWidth;
        !           262:                orig_y = tmp / PuzzleWidth;
        !           263: 
        !           264:                XCopyArea(dpy,PicturePixmap,TileWindow,gc,
        !           265:                          ulx(orig_x,orig_y), uly(orig_x,orig_y),
        !           266:                          TileWidth, TileHeight,
        !           267:                          ulx(j,i), uly(j,i));
        !           268:            }
        !           269:            counter++;
        !           270:        }    
        !           271:     
        !           272: }
        !           273: 
        !           274: /**
        !           275:  ** Setup - Perform initial window creation, etc.
        !           276:  **/
        !           277: 
        !           278: Setup(server,geom,argc,argv)
        !           279: char *server,*geom;
        !           280: int argc;
        !           281: char *argv[];
        !           282: {
        !           283:     Cursor ArrowCrossCursor;
        !           284:     int minwidth, minheight;
        !           285:     Pixmap VEGsetup();
        !           286:     Visual visual;
        !           287:     XGCValues xgcv;
        !           288:     XSetWindowAttributes xswa;
        !           289:     XSizeHints sizehints;
        !           290: 
        !           291:     /*******************************************/
        !           292:     /** let the puzzle code initialize itself **/
        !           293:     /*******************************************/
        !           294:     initialize();
        !           295:     OutputLogging = 1;
        !           296: 
        !           297:     SetupDisplay(server);
        !           298: 
        !           299:     FgPixel = BlackPixel(dpy,screen);
        !           300:     BgPixel = WhitePixel(dpy,screen);
        !           301: 
        !           302:     /*****************************************************/
        !           303:     /** if we want to use a picture file, initialize it **/
        !           304:     /*****************************************************/
        !           305:     if (UsePicture) {
        !           306: #ifdef UNDEFINED
        !           307:        /**
        !           308:         ** This was fun to do back with X10 when you could create
        !           309:         ** a pixmap from the current display contents;  Maybe eventually
        !           310:         ** I'll do the same with X11.
        !           311:         **/
        !           312:        if (UseDisplay) {
        !           313:            WindowGeom RootWinInfo;
        !           314:            int x,y;
        !           315: 
        !           316:            x = PUZZLE_BORDER_WIDTH;
        !           317:            y = TITLE_WINDOW_HEIGHT + BOUNDARY_HEIGHT + PUZZLE_BORDER_WIDTH;
        !           318:            XQueryWindow(RootWindow(dpy, screen),&RootWinInfo);
        !           319:            PictureWidth  = RootWinInfo.width  - x;
        !           320:            PictureHeight = RootWinInfo.height - y;
        !           321:            PicturePixmap = XPixmapSave(RootWindow(dpy,screen),
        !           322:                                        x,y,PictureWidth,PictureHeight);
        !           323:        }
        !           324:        else
        !           325: #endif UNDEFINED
        !           326:            PuzzleColormap = XCreateColormap(dpy,RootWindow(dpy,screen),
        !           327:                                         DefaultVisual(dpy,screen),AllocNone);
        !           328:            PicturePixmap = VEGsetup(PictureFileName,&PictureWidth,&PictureHeight);
        !           329:     }
        !           330: 
        !           331:     if (UsePicture) {
        !           332:        minwidth = PuzzleWidth;
        !           333:        minheight = PuzzleHeight + TITLE_WINDOW_HEIGHT + BOUNDARY_HEIGHT;
        !           334:     }
        !           335:     else {
        !           336:        minwidth = MIN_TILE_WIDTH * PuzzleWidth;
        !           337:        minheight = MIN_TILE_HEIGHT * PuzzleHeight + TITLE_WINDOW_HEIGHT +
        !           338:            BOUNDARY_HEIGHT;
        !           339:     }
        !           340: 
        !           341:     /*************************************/
        !           342:     /** configure the window size hints **/
        !           343:     /*************************************/
        !           344: 
        !           345:     {
        !           346:        int x, y, width, height;
        !           347:        int flags;
        !           348: 
        !           349:        sizehints.flags = PMinSize | PPosition | PSize;
        !           350:        sizehints.min_width = minwidth;
        !           351:        sizehints.min_height = minheight;
        !           352:        sizehints.width = minwidth;
        !           353:        sizehints.height = minheight;
        !           354:        sizehints.x = 100;
        !           355:        sizehints.y = 300;
        !           356: 
        !           357:        if(strlen(geom)) {
        !           358:            flags = XParseGeometry(geom, &x, &y, &width, &height);
        !           359:            if(WidthValue & flags) {
        !           360:                sizehints.flags |= USSize;
        !           361:                if (width > sizehints.min_width)
        !           362:                    sizehints.width = width;
        !           363:            }
        !           364:            if(HeightValue & flags) {
        !           365:                sizehints.flags |= USSize;
        !           366:                if (height > sizehints.min_height)
        !           367:                    sizehints.height = height;
        !           368:            }
        !           369:            if(XValue & flags) {
        !           370:                if(XNegative & flags)
        !           371:                    x = DisplayWidth(dpy, DefaultScreen(dpy)) + x 
        !           372:                        - sizehints.width;
        !           373:                sizehints.flags |= USPosition;
        !           374:                sizehints.x = x;
        !           375:            }
        !           376:            if(YValue & flags) {
        !           377:                if(YNegative & flags)
        !           378:                    y = DisplayHeight(dpy, DefaultScreen(dpy)) + y
        !           379:                        -sizehints.height;
        !           380:                sizehints.flags |= USPosition;
        !           381:                sizehints.y = y;
        !           382:            }
        !           383:        }
        !           384:     }
        !           385: 
        !           386:     /*******************************************************************/
        !           387:     /** create the puzzle main window and set its standard properties **/
        !           388:     /*******************************************************************/
        !           389: 
        !           390:     xswa.event_mask = ExposureMask;
        !           391:     visual.visualid = CopyFromParent;
        !           392: 
        !           393: #ifdef UNDEFINED
        !           394:     PuzzleRoot = XCreateWindow(dpy, RootWindow(dpy,screen),
        !           395:                               sizehints.x, sizehints.y,
        !           396:                               sizehints.width, sizehints.height,
        !           397:                               PUZZLE_BORDER_WIDTH,
        !           398:                               DefaultDepth(dpy,screen),
        !           399:                               InputOutput,
        !           400:                               &visual,
        !           401:                               CWEventMask, &xswa);
        !           402: #endif UNDEFINED
        !           403:     PuzzleRoot = XCreateSimpleWindow(dpy, RootWindow(dpy,screen),
        !           404:                               sizehints.x, sizehints.y,
        !           405:                               sizehints.width, sizehints.height,
        !           406:                               PUZZLE_BORDER_WIDTH, FgPixel,BgPixel);
        !           407: 
        !           408:     XSetStandardProperties(dpy, PuzzleRoot,"puzzle","Puzzle",
        !           409:                           None, argv, argc, &sizehints);
        !           410: 
        !           411:     xgcv.foreground = FgPixel;
        !           412:     xgcv.background = BgPixel;
        !           413:     xgcv.line_width = 1;
        !           414:     gc = XCreateGC(dpy, PuzzleRoot,
        !           415:                   GCForeground|GCBackground|GCLineWidth,
        !           416:                   &xgcv);
        !           417: 
        !           418: #ifdef UNDEFINED
        !           419:     /*********************************/
        !           420:     /** load the arrow-cross cursor **/
        !           421:     /*********************************/
        !           422:     
        !           423:     /** This code really works, but I haven't converted the cursor to the
        !           424:      ** the new format, so it looks pretty mangled;
        !           425:      **/
        !           426:     {
        !           427:        Pixmap ACPixmap, ACMask;
        !           428:        Cursor ACCursor;
        !           429:        XColor FGcolor, BGcolor;
        !           430: 
        !           431:        FGcolor.red = 0;        FGcolor.green = 0;      FGcolor.blue = 0;
        !           432:        BGcolor.red = 0xffff;   BGcolor.green = 0xffff; BGcolor.blue = 0xffff;
        !           433: 
        !           434:        ACPixmap = XCreateBitmapFromData(dpy,RootWindow(dpy,screen),
        !           435:                                 arrow_cross_bits,
        !           436:                                 arrow_cross_width, arrow_cross_height);
        !           437:        ACMask = XCreateBitmapFromData(dpy,RootWindow(dpy,screen),
        !           438:                                 arrow_cross_mask_bits,
        !           439:                                 arrow_cross_width, arrow_cross_height);
        !           440:        ACCursor = XCreatePixmapCursor(dpy,ACPixmap,ACMask,
        !           441:                                       FGcolor,BGcolor,
        !           442:                                       8,8);
        !           443:        if (ACCursor == NULL)
        !           444:            error("Unable to store ArrowCrossCursor.");
        !           445:     
        !           446:        XDefineCursor(dpy,PuzzleRoot,ACCursor);
        !           447:     }
        !           448: #endif UNDEFINED
        !           449: 
        !           450:     /*****************************************/
        !           451:     /** allocate the fonts we will be using **/
        !           452:     /*****************************************/
        !           453: 
        !           454:     TitleFontInfo    = XLoadQueryFont(dpy,TitleFontName);
        !           455:     TileFontInfo     = XLoadQueryFont(dpy,TileFontName);
        !           456: 
        !           457:     if (TitleFontInfo    == NULL) error("Opening title font.\n");
        !           458:     if (TileFontInfo     == NULL) error("Opening tile font.\n");
        !           459: 
        !           460:     XQueryWindow(PuzzleRoot,&PuzzleWinInfo);
        !           461:     Reset();
        !           462: }
        !           463: 
        !           464: static short old_height = -1;
        !           465: static short old_width = -1;
        !           466: 
        !           467: SizeChanged()
        !           468: {
        !           469:     XQueryWindow(PuzzleRoot,&PuzzleWinInfo);
        !           470:     
        !           471:     if (PuzzleWinInfo.width == old_width &&
        !           472:        PuzzleWinInfo.height == old_height)
        !           473:        return(0);
        !           474:     else
        !           475:        return(1);
        !           476: }
        !           477: 
        !           478: Reset()
        !           479: {
        !           480:     int width,height,Box_x,Box_y;
        !           481:     int i,j;
        !           482:     int TileBgPixel;
        !           483:     
        !           484:     /** TileWindow is that portion of PuzzleRoot that contains
        !           485:      ** the sliding pieces;
        !           486:      **/
        !           487: 
        !           488:     if (UsePicture)
        !           489:        TileBgPixel = BlackPixel(dpy,screen);
        !           490:     else
        !           491:        TileBgPixel = WhitePixel(dpy,screen);
        !           492:     
        !           493:     XDestroySubwindows(dpy,PuzzleRoot);
        !           494:     
        !           495:     old_width  = PuzzleWinInfo.width;
        !           496:     old_height = PuzzleWinInfo.height;
        !           497: 
        !           498:     TitleWinHeight = TITLE_WINDOW_HEIGHT;
        !           499:     BoundaryHeight = BOUNDARY_HEIGHT;
        !           500: 
        !           501:     /** fix the dimensions of PuzzleRoot so the height and width
        !           502:      ** of the TileWindow will work out to be multiples of PuzzleSize;
        !           503:      **/
        !           504: 
        !           505:     /** If we're dealing with a picture, the tile region can be no larger
        !           506:      ** than the picture!
        !           507:      **/
        !           508: 
        !           509:     if (UsePicture) {
        !           510:        int tmp;
        !           511: 
        !           512:        tmp = PuzzleWinInfo.height - TitleWinHeight - BoundaryHeight;
        !           513:        if (tmp > PictureHeight)
        !           514:            PuzzleWinInfo.height = PictureHeight+TitleWinHeight+BoundaryHeight;
        !           515:        if (PuzzleWinInfo.width > PictureWidth)
        !           516:            PuzzleWinInfo.width = PictureWidth;
        !           517:     }
        !           518: 
        !           519:     TileHeight=(PuzzleWinInfo.height-TitleWinHeight-BoundaryHeight)/PuzzleHeight;
        !           520:     PuzzleWinInfo.height = TileHeight*PuzzleHeight+TitleWinHeight+BoundaryHeight;
        !           521: 
        !           522:     TileWidth = PuzzleWinInfo.width/PuzzleWidth;
        !           523:     PuzzleWinInfo.width = TileWidth * PuzzleWidth;
        !           524: 
        !           525:     /** fixup the size of PuzzleRoot **/
        !           526: 
        !           527:     XResizeWindow(dpy,PuzzleRoot,PuzzleWinInfo.width,PuzzleWinInfo.height);
        !           528:     TileWinHeight = PuzzleWinInfo.height - TitleWinHeight;
        !           529: 
        !           530:     TitleWindow = XCreateSimpleWindow(dpy, PuzzleRoot,
        !           531:                        0,0,
        !           532:                        PuzzleWinInfo.width, TitleWinHeight,
        !           533:                        0,0,BgPixel);
        !           534: 
        !           535:     TileWindow  = XCreateSimpleWindow(dpy, PuzzleRoot,
        !           536:                        0,TitleWinHeight+BoundaryHeight,
        !           537:                        PuzzleWinInfo.width, TileWinHeight,
        !           538:                        0,0,TileBgPixel);
        !           539:    
        !           540:     rect_gc = XCreateGC(dpy,TileWindow,0,0);
        !           541:     XCopyGC(dpy, gc, -1, rect_gc);
        !           542: 
        !           543:     XMapWindow(dpy,PuzzleRoot);
        !           544:     XMapWindow(dpy,TitleWindow);
        !           545:     XMapWindow(dpy,TileWindow);
        !           546: 
        !           547:     RepaintBar();
        !           548:     RepaintTitle();
        !           549: 
        !           550:     /** locate the two check boxes **/
        !           551: 
        !           552:     Box_x = Tx/2 - BoxWidth/2;
        !           553:     Box_y = TitleWinHeight/2 - BoxHeight/2;
        !           554:     
        !           555:     ScrambleWindow = XCreateSimpleWindow(dpy, TitleWindow,
        !           556:                                 Box_x, Box_y,
        !           557:                                 BoxWidth, BoxHeight,
        !           558:                                 1,FgPixel,BgPixel);
        !           559: 
        !           560:     Box_x = PuzzleWinInfo.width - Box_x - BoxWidth;
        !           561:     
        !           562:     SolveWindow = XCreateSimpleWindow(dpy, TitleWindow,
        !           563:                                 Box_x,Box_y,
        !           564:                                 BoxWidth,BoxHeight,
        !           565:                                 1,FgPixel,BgPixel);
        !           566: 
        !           567:     XMapWindow(dpy,ScrambleWindow);
        !           568:     XMapWindow(dpy,SolveWindow);
        !           569: 
        !           570:     XSelectInput(dpy, TitleWindow,   ButtonPressMask|ExposureMask);
        !           571:     XSelectInput(dpy, TileWindow,    ButtonPressMask|ExposureMask|
        !           572:                                        VisibilityChangeMask);
        !           573:     XSelectInput(dpy, ScrambleWindow,ButtonPressMask|ExposureMask);
        !           574:     XSelectInput(dpy, SolveWindow,   ButtonPressMask|ExposureMask);
        !           575: 
        !           576:     RepaintTiles();
        !           577:     CalculateStepsize();
        !           578:     XSync(dpy,1);
        !           579: }
        !           580: 
        !           581: CalculateStepsize()
        !           582: {
        !           583:     int i, rem;
        !           584:     int error,sum;
        !           585: 
        !           586:     for (i=0; i<MoveSteps; i++)
        !           587:        VertStepSize[i] = TileHeight/MoveSteps;
        !           588:          
        !           589:     rem = TileHeight % MoveSteps;
        !           590:     error = - MoveSteps/2;
        !           591: 
        !           592:     if (rem > 0)
        !           593:        for (i=0; i<MoveSteps; i++) {
        !           594:            if (error >= 0) {
        !           595:                VertStepSize[i]++;
        !           596:                error -= MoveSteps;
        !           597:            }
        !           598:            error += rem;
        !           599:        }   
        !           600:     
        !           601:     for (i=0; i<MoveSteps; i++)
        !           602:        HoriStepSize[i] = TileWidth/MoveSteps;
        !           603:          
        !           604:     rem = TileWidth % MoveSteps;
        !           605:     error = - MoveSteps/2;
        !           606: 
        !           607:     if (rem > 0)
        !           608:        for (i=0; i<MoveSteps; i++) {
        !           609:            if (error >= 0) {
        !           610:                HoriStepSize[i]++;
        !           611:                error -= MoveSteps;
        !           612:            }
        !           613:            error += rem;
        !           614:        }   
        !           615: 
        !           616:     /** This code is a little screwed up and I don't want to fix it
        !           617:      ** right now, so just do a little hack to make sure the total
        !           618:      ** distance comes out right;
        !           619:      **/
        !           620: 
        !           621:     sum = 0;
        !           622:     for (i=0; i<MoveSteps; i++)
        !           623:        sum += HoriStepSize[i];
        !           624:     HoriStepSize[0] += TileWidth - sum;
        !           625: 
        !           626:     sum = 0;
        !           627:     for (i=0; i<MoveSteps; i++)
        !           628:        sum += VertStepSize[i];
        !           629:     VertStepSize[0] += TileHeight - sum;
        !           630: }
        !           631: 
        !           632: SlidePieces(event)
        !           633: XButtonEvent *event;
        !           634: {
        !           635:     int x,y;
        !           636: 
        !           637:     x = (*event).x / TileWidth;
        !           638:     y = (*event).y / TileHeight;
        !           639:     if (x == space_x || y == space_y)
        !           640:        move_space_to(indx(x,y));   
        !           641: }
        !           642: 
        !           643: ProcessButton(event)
        !           644: XButtonEvent *event;
        !           645: {
        !           646:     Window w;
        !           647: 
        !           648: /* printf("state: 0x%-4x\n",event->state); */
        !           649:     w = event->window;
        !           650:     if (w == TileWindow) {
        !           651:        if (SolvingStatus())
        !           652:            AbortSolving();
        !           653:        else
        !           654:            SlidePieces(event);
        !           655:     }
        !           656:     else if (w == ScrambleWindow) {
        !           657:        AbortSolving();
        !           658:        Scramble();
        !           659:        RepaintTiles();
        !           660:     }
        !           661:     else if (w == SolveWindow)
        !           662:        Solve();
        !           663:     else if (w == TitleWindow) /*  && (*event).state == MiddleButton) */
        !           664:        exit(0);
        !           665: }
        !           666: 
        !           667: ProcessEvents()
        !           668: {
        !           669:     XEvent event;
        !           670: 
        !           671:     while(XPending(dpy)) {
        !           672:        XNextEvent(dpy,&event);  
        !           673:        ProcessEvent(&event);
        !           674:     }
        !           675: }
        !           676: 
        !           677: ProcessInput()
        !           678: {
        !           679:     XEvent event;
        !           680: 
        !           681:     while(1) {
        !           682:        XNextEvent(dpy, &event);  
        !           683:        ProcessEvent(&event);
        !           684:     }
        !           685: }
        !           686: 
        !           687: ProcessEvent(event)
        !           688: XEvent *event;
        !           689: {
        !           690: /* printf("type: %d\n",event->type); */
        !           691: 
        !           692:     switch(event->type) {
        !           693:       case ButtonPress: ProcessButton(event);
        !           694:                        break;
        !           695:       case Expose:     if (SizeChanged())
        !           696:                            Reset();
        !           697:                        else {
        !           698:                            if (event->xany.window == TitleWindow)
        !           699:                                RepaintTitle();
        !           700:                            else if (event->xany.window == TileWindow)
        !           701:                                RepaintTiles();
        !           702:                            else if (event->xany.window == PuzzleRoot)
        !           703:                                RepaintBar();
        !           704:                        }
        !           705:                         break;
        !           706: #ifdef UNDEFINED
        !           707:       case Visibility:
        !           708:                        RedrawWindows();
        !           709:                        break;
        !           710: #endif
        !           711:    default:            break;
        !           712:    }
        !           713: }
        !           714: 
        !           715: main(argc,argv)
        !           716: int argc;
        !           717: char *argv[];
        !           718: {
        !           719:    int i, count;
        !           720:    char *ServerName, *Geometry;
        !           721: 
        !           722:    ServerName = "";
        !           723:    Geometry   = "";  
        !           724:    MoveSteps  = 1;
        !           725: 
        !           726:    ProgName = argv[0];
        !           727: 
        !           728:    /********************************/
        !           729:    /** parse command line options **/
        !           730:    /********************************/
        !           731: 
        !           732:    for (i=1; i<argc; i++) {
        !           733:       if (argv[i][0] == '=') 
        !           734:          Geometry = argv[i];
        !           735:       else if (strchr(argv[i],':') != NULL)
        !           736:          ServerName = argv[i];
        !           737:       else if (strchr(argv[i],'x') != NULL) {
        !           738:          sscanf(argv[i],"%dx%d",&PuzzleWidth,&PuzzleHeight);
        !           739:          if (PuzzleWidth<4 || PuzzleHeight<4) {
        !           740:             printf("Puzzle size must be at least 4x4.\n");
        !           741:             exit(1);
        !           742:         }
        !           743:         PuzzleSize = min((PuzzleWidth/2)*2,(PuzzleHeight/2)*2);
        !           744:       }
        !           745:       else if (strncmp(argv[i],"-s",2) == 0) {
        !           746:          count = sscanf(&(argv[i][2]),"%d",&MoveSteps);
        !           747:          if (count != 1) usage(ProgName);
        !           748:          if (MoveSteps > MAX_STEPS) {
        !           749:            fprintf(stderr,"max steps=%d\n",MAX_STEPS);
        !           750:            exit(1);
        !           751:          }
        !           752:       }
        !           753:       else if (strncmp(argv[i],"-p",2) == 0) {
        !           754:         if (argv[i][2] == 0) {
        !           755:            UseDisplay++;
        !           756:             UsePicture++;
        !           757:         }
        !           758:         else {
        !           759:             UsePicture++;
        !           760:             PictureFileName = &(argv[i][2]);
        !           761:         }
        !           762:       }
        !           763:       else if (isdigit(argv[i][0])) {
        !           764:          sscanf(argv[i],"%d",&PuzzleSize);
        !           765:          if (PuzzleSize<4) {
        !           766:             printf("Puzzle size must be at least 4x4.\n");
        !           767:             exit(1);
        !           768:         }
        !           769:          PuzzleWidth = PuzzleSize;
        !           770:         PuzzleHeight = PuzzleSize;
        !           771:         PuzzleSize = (PuzzleSize/2) * 2;
        !           772:       }
        !           773:       else 
        !           774:          usage(ProgName);
        !           775:    }
        !           776: 
        !           777:    Setup(ServerName,Geometry,argc,argv);
        !           778:    ProcessInput();
        !           779: }
        !           780: 
        !           781: usage(name)
        !           782: char *name;
        !           783: {
        !           784:    fprintf(stderr,"usage: %s [geometry] [display] [size]\n", name);
        !           785:    fprintf(stderr,"       [-s<move-steps>] [-p<picture-file>]\n");
        !           786:    exit(1);
        !           787: }
        !           788: 
        !           789: error(str)
        !           790: char *str;
        !           791: {
        !           792:    fprintf(stderr,"Error %s\n",str);
        !           793:    exit(1);
        !           794: }
        !           795: 
        !           796: LogMoveSpace(first_x,first_y,last_x,last_y,dir)
        !           797: int first_x,first_y,last_x,last_y,dir;
        !           798: {
        !           799:    int min_x,min_y,max_x,max_y;
        !           800:    int x,y,w,h,dx,dy,x2,y2;
        !           801:    int i, clear_x, clear_y;
        !           802: 
        !           803: 
        !           804:    max_x = max(first_x,last_x);
        !           805:    min_x = min(first_x,last_x);
        !           806:    max_y = max(first_y,last_y);
        !           807:    min_y = min(first_y,last_y);
        !           808: 
        !           809:    x = ulx(min_x,0);
        !           810:    y = uly(0,min_y);   
        !           811:    w = (max_x - min_x + 1)*TileWidth;
        !           812:    h = (max_y - min_y + 1)*TileHeight;
        !           813: 
        !           814:    dx = x;
        !           815:    dy = y;
        !           816: 
        !           817:    x2 = x;
        !           818:    y2 = y;
        !           819: 
        !           820:    switch(dir) {
        !           821:    case UP:    clear_x = llx(max_x,0);
        !           822:                 clear_y = lly(0,max_y) + 1;
        !           823: 
        !           824:                for (i=0; i<MoveSteps; i++) {
        !           825:                    dy = VertStepSize[i];
        !           826:                    y2 = y - dy;
        !           827:                    clear_y -= dy;
        !           828:                    
        !           829:                    MoveArea(TileWindow,x,y,x2,y2,w,h);
        !           830:                    RectSet(TileWindow,clear_x,clear_y,
        !           831:                           TileWidth,dy,FgPixel);
        !           832:                    y -= dy;
        !           833:                 }
        !           834:                break;
        !           835:    case DOWN:  clear_x = llx(max_x,0);
        !           836:                clear_y = uly(0,min_y);
        !           837: 
        !           838:                for (i=0; i<MoveSteps; i++) {
        !           839:                   dy = VertStepSize[i];
        !           840:                   y2 = y + dy;
        !           841: 
        !           842:                   MoveArea(TileWindow,x,y,x2,y2,w,h);
        !           843:                    RectSet(TileWindow,clear_x,clear_y,
        !           844:                           TileWidth,dy,FgPixel);
        !           845:                   y += dy;
        !           846:                   clear_y += dy;
        !           847:                }
        !           848:                break;
        !           849:    case LEFT:  clear_x = urx(max_x,0) + 1;
        !           850:                clear_y = ury(0,max_y);
        !           851: 
        !           852:                for (i=0; i<MoveSteps; i++) {
        !           853:                   dx = HoriStepSize[i];
        !           854:                   x2 = x - dx;
        !           855:                   clear_x -= dx;
        !           856: 
        !           857:                   MoveArea(TileWindow,x,y,x2,y2,w,h);
        !           858:                    RectSet(TileWindow,clear_x,clear_y,
        !           859:                           dx,TileHeight,FgPixel);
        !           860:                   x -= dx;
        !           861:                }
        !           862:                break;
        !           863:    case RIGHT: clear_x = ulx(min_x,0);
        !           864:                clear_y = uly(0,max_y);
        !           865:                
        !           866:                 for (i=0; i<MoveSteps; i++) {
        !           867:                   dx = HoriStepSize[i];
        !           868:                   x2 = x + dx;
        !           869: 
        !           870:                   MoveArea(TileWindow,x,y,x2,y2,w,h);
        !           871:                    RectSet(TileWindow,clear_x,clear_y,
        !           872:                           dx,TileHeight,FgPixel);
        !           873:                   x += dx;
        !           874:                   clear_x += dx;
        !           875:                }
        !           876:                break;
        !           877:    }
        !           878: 
        !           879:    XFlush(dpy);
        !           880: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.