Annotation of researchv9/X11/src/X.V11R1/clients/puzzle/main.c, revision 1.1.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.