📄 xhamster.c
字号:
|| (psh_additem(psh_speed, "speed", PSH_EDIT, 0) != 0)) { psh_delete(psh_speed); error(E_WIDGET); } } /* set browse button callback */ mn_enable(menu, MN_MENU, 0); /* disable menu bar */ sprintf(buf, "%g", appdata.speed); psh_setval(psh_speed, "speed", buf); psh_handle(psh_speed, dcb_speed); /* set values and handle dialog */} /* speed() *//*--------------------------------------------------------------------*/static void clear (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- Actions > Clear Maze */ if (running) return; /* if a hamster is running, abort */ mz_init(maze, 0, 0.0, 0, 0); /* clear and redraw maze */ redraw(NULL, NULL, NULL, NULL);} /* clear() *//*--------------------------------------------------------------------*/static void exec (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- Actions > Start/Stop Hamster */ if (running) stop(E_NONE); /* if hamster is running, stop it, */ else start(); /* otherwise start hamster */} /* exec() *//*--------------------------------------------------------------------*/static void about (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- 'About' dialog box */ mn_enable(menu, MN_MENU, 0); /* disable menu bar */ if (db_about(w_top, dcb_nop) != 0) error(E_DIALOG); /* show `about' dialog box */} /* about() *//*--------------------------------------------------------------------*/static void wall (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- toggle wall/remove walls */ int x, y, dx, dy; /* coordinates and distances */ short t; /* temporary buffer */ if (running || (*c != 1) /* if running or wrong arguments */ || !XtIsSensitive(mn_menubar(menu))) /* or menu bar disabled, */ return; /* abort function */ if (!gc) { /* if graphics context not created */ gc = XCreateGC(display, window, 0, NULL); if (!gc) { error(E_GRAPH); return; } } /* create a graphics context */ x = e->xbutton.x -xoff; /* compute coordinates relative */ y = yoff -e->xbutton.y; /* to lower left maze corner */ if (strcmp(*s, "0") == 0) { /* if to remove all walls, */ x /= FIELDWD; y /= FIELDWD; /* clear all wall flags */ if (x >= appdata.xext) return; mz_setfld(maze, x, y, MZ_WALLS, 0); } else if (strcmp(*s, "1") == 0) { dx = x % FIELDWD; /* compute coordinates relative */ dy = y % FIELDWD; t = 0; /* to lower left field corner */ if (dx >= FIELDWD/2) { t |= MZ_EAST; dx = FIELDWD-1 -dx; } else { t |= MZ_WEST; } if (dy >= FIELDWD/2) { t |= MZ_NORTH; dy = FIELDWD-1 -dy; } else { t |= MZ_SOUTH; } t &= (dx <= dy) ? MZ_WEST|MZ_EAST : MZ_SOUTH|MZ_NORTH; x /= FIELDWD; y /= FIELDWD; /* determine wall flag */ if (x >= appdata.xext) return; t ^= mz_getfld(maze, x, y); /* get field contents */ mz_setfld(maze, x, y, MZ_WALLS, t); } /* toggle wall flag */ draw_field(x, y); /* redraw changed field */ mn_info(menu, ""); /* clear info field in menu bar */} /* wall() *//*--------------------------------------------------------------------*/static void heap (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- change corn heap size */ int x, y, sx, sy; /* maze coordinates */ short heap, chg; /* size of corn heap and change */ if (running || (*c != 1) /* if running or wrong arguments */ || !XtIsSensitive(mn_menubar(menu))) /* or menu bar disabled, */ return; /* abort function */ if (!gc) { /* if graphics context not created */ gc = XCreateGC(display, window, 0, NULL); if (!gc) { error(E_GRAPH); return; } } /* create a graphics context */ x = (e->xbutton.x -xoff) /FIELDWD; /* compute maze */ y = (yoff -e->xbutton.y) /FIELDWD; /* coordinates */ mz_getpos(maze, &sx, &sy); /* get coord. of start position */ if ((x == sx) && (y == sy)) /* do not allow to place */ return; /* corn on the home field */ heap = mz_getfld(maze, x, y) & MZ_ITEMS; chg = (short)atoi(*s); /* get heap size and change */ heap = (chg == 0) ? 0 : ((heap +chg +(MAXHEAP+1)) %(MAXHEAP+1)); mz_setfld(maze, x, y, MZ_ITEMS, heap); draw_field(x, y); /* set new heap size and redraw field */ sprintf(buf, "%d", heap); /* show new heap size */ mn_info(menu, buf); /* in info field in menu bar */} /* heap() *//*--------------------------------------------------------------------*/static void position (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- change start position */ int ox, oy, nx, ny; /* old and new start position */ if (running || (*c != 0) /* if running or wrong arguments */ || !XtIsSensitive(mn_menubar(menu))) /* or menu bar disabled, */ return; /* abort function */ if (!gc) { /* if graphics context not created */ gc = XCreateGC(display, window, 0, NULL); if (!gc) { error(E_GRAPH); return; } } /* create a graphics context */ nx = (e->xbutton.x -xoff) /FIELDWD; /* compute maze */ ny = (yoff -e->xbutton.y) /FIELDWD; /* coordinates */ mz_getpos(maze, &ox, &oy); /* get old start position */ mz_setpos(maze, nx, ny); /* and then set new */ draw_field(ox, oy); /* redraw fields of old */ draw_field(nx, ny); /* and new start position */ mn_info(menu, ""); /* clear info field in menu bar */} /* position() *//*---------------------------------------------------------------------- Main Function----------------------------------------------------------------------*/int main (int argc, char *argv[]){ /* --- main program */ Arg args[8]; /* widget arguments */ int n; /* argument counter */ Dimension wd, ht; /* width and height of window */ Colormap colmap; /* color map of display */ XColor xc[5]; /* buffer for colors */ XtSetLanguageProc(NULL, (XtLanguageProc)NULL, NULL); /* --- create a maze --- */ srand((unsigned int)time(NULL)); maze = mz_create(appdata.xext, appdata.yext); if (!maze) error(E_NOMEM); /* create a maze and */ wd = appdata.xext *FIELDWD; /* compute initial */ ht = appdata.yext *FIELDWD; /* widget size */ /* --- create main window --- */ w_top = XtAppInitialize(&appctx, "XHamster", NULL, 0, &argc, argv, fallback, NULL, 0); if (!w_top) error(E_INIT); /* create toplevel widget */ n = 0; /* build argument list */ XtSetArg(args[n], XtNdefaultDistance, 0); n++; XtSetArg(args[n], XtNresizable, True); n++; w_main = XtCreateManagedWidget("main", formWidgetClass, w_top, args, n); /* create main widget */ if (!w_main) error(E_WIDGET); /* --- create menu bar --- */ menu = mn_create(w_main); /* create a menu bar and */ if (!menu) error(E_NOMEM); /* add titles and items */ if ((mn_addtitle(menu, "file", 0, mcb_menu, (void*)0) != 0) || (mn_additem (menu, "reload", 1, mcb_load, "0") != 0) || (mn_additem (menu, "load", 1, mcb_load, "1") != 0) || (mn_additem (menu, NULL, 0, 0, (void*)0) != 0) || (mn_additem (menu, "save", 1, mcb_save, "0") != 0) || (mn_additem (menu, "saveas", 1, mcb_save, "1") != 0) || (mn_additem (menu, NULL, 0, 0, (void*)0) != 0) || (mn_additem (menu, "select", 1, mcb_select, (void*)0) != 0) || (mn_additem (menu, NULL, 0, 0, (void*)0) != 0) || (mn_additem (menu, "quit", 0, mcb_quit, (void*)0) != 0) || (mn_addtitle(menu, "actions", 0, mcb_menu, (void*)0) != 0) || (mn_additem (menu, "redraw", 0, mcb_redraw, (void*)0) != 0) || (mn_additem (menu, NULL, 0, 0, (void*)0) != 0) || (mn_additem (menu, "size", 1, mcb_size, (void*)0) != 0) || (mn_additem (menu, "random", 1, mcb_random, (void*)0) != 0) || (mn_additem (menu, "clear", 1, mcb_clear, (void*)0) != 0) || (mn_additem (menu, NULL, 0, 0, (void*)0) != 0) || (mn_additem (menu, "speed", 0, mcb_speed, (void*)0) != 0) || (mn_additem (menu, "start", 2, mcb_start, (void*)0) != 0) || (mn_additem (menu, "stop", 4, mcb_start, (void*)0) != 0) || (mn_addtitle(menu, "help", 0, mcb_menu, (void*)0) != 0) || (mn_additem (menu, "about", 0, mcb_about, (void*)0) != 0) || (mn_addtitle(menu, NULL, 0, 0, (void*)0) != 0)) error(E_WIDGET); mn_visible(menu, MN_ITEMS, 3);/* show/hide menu items */ mn_enable (menu, MN_ITEMS, 3);/* enable/disable menu items */ /* --- create maze view --- */ n = 0; /* build argument list */ XtSetArg(args[n], XtNfromVert, mn_menubar(menu)); n++; XtSetArg(args[n], XtNleft, XtChainLeft); n++; XtSetArg(args[n], XtNtop, XtChainTop); n++; XtSetArg(args[n], XtNright, XtChainRight); n++; XtSetArg(args[n], XtNbottom, XtChainBottom); n++; XtSetArg(args[n], XtNresizable, True); n++; w_view = XtCreateManagedWidget("view", viewportWidgetClass, w_main, args, n); if (!w_view) error(E_WIDGET); /* create viewport */ /* --- create maze widget --- */ n = 0; /* build argument list */ XtSetArg(args[n], XtNborderWidth, 0); n++; XtSetArg(args[n], XtNleft, XtChainLeft); n++; XtSetArg(args[n], XtNtop, XtChainTop); n++; XtSetArg(args[n], XtNright, XtChainLeft); n++; XtSetArg(args[n], XtNbottom, XtChainTop); n++; XtSetArg(args[n], XtNresizable, True); n++; w_maze = XtCreateManagedWidget("maze", coreWidgetClass, w_view, args, n); if (!w_maze) error(E_WIDGET); /* create box for maze and */ xoff = 0; yoff = ht-2; /* compute offsets for drawing */ XtVaSetValues(w_maze, XtNwidth, wd-1, XtNheight, ht-1, NULL); XtOverrideTranslations(w_maze,/* install redraw function */ XtParseTranslationTable("<Expose>: redraw()")); wd = HMS_MINXEXT*FIELDWD+1; /* compute minimal width and height */ ht = HMS_MINYEXT*FIELDWD+1 +mn_height(menu); n = mn_minwidth(menu); /* get the minimal menu width */ if (n > wd) wd = n; /* and adapt the minimal width */ n = 0; /* inhibit undersizing */ XtSetArg(args[n], XtNminWidth, wd); n++; XtSetArg(args[n], XtNminHeight, ht); n++; XtSetValues(w_top, args, n); /* set minimal width and height */ /* --- install actions and accelerators --- */ XtAppAddActions(appctx, actions, XtNumber(actions)); XtInstallAllAccelerators(w_main, w_main); /* --- show window --- */ XtRealizeWidget(w_top); /* show window on display */ display = XtDisplay(w_top); /* get display of top window */ window = XtWindow(w_maze); /* and drawable for window */ resize(appdata.xext, appdata.yext); if (db_alert(w_top, dcb_alert, NULL) != 0) error(E_WIDGET); /* create alert dialog box */ /* --- allocate colors --- */ screen = DefaultScreen(display); colmap = DefaultColormap(display, screen); white = WhitePixel(display, screen); black = BlackPixel(display, screen); if ((XAllocNamedColor(display, colmap, "grey", xc+1, xc) == 0) || (XAllocNamedColor(display, colmap, "yellow", xc+2, xc) == 0) || (XAllocNamedColor(display, colmap, "orange", xc+3, xc) == 0) || (XAllocNamedColor(display, colmap, "red", xc+4, xc) == 0)) error(E_COLOR); /* allocate colors and */ grey = xc[1].pixel; /* note their pixel values */ yellow = xc[2].pixel; orange = xc[3].pixel; red = xc[4].pixel; /* --- create hamster sprite bitmap --- */ hms_bmap = XCreateBitmapFromData(display, window, (char*)hms_bits, hms_width, hms_height); if (hms_bmap == None) error(E_NOMEM); /* --- override window manager delete --- */ XtOverrideTranslations(w_top, /* override window manager delete */ XtParseTranslationTable("<Message>WM_PROTOCOLS: quit()")); wm_delwin = XInternAtom(XtDisplay(w_top), "WM_DELETE_WINDOW", False); XSetWMProtocols(XtDisplay(w_top), XtWindow(w_top), &wm_delwin, 1); /* --- start event loop --- */ XtAppMainLoop(appctx); /* enter main event loop */ return 0; /* return `ok' */} /* main() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -