|
|
1.1 ! root 1: /* w_cam.c ! 2: * ! 3: * Micropolis, Unix Version. This game was released for the Unix platform ! 4: * in or about 1990 and has been modified for inclusion in the One Laptop ! 5: * Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If ! 6: * you need assistance with this program, you may contact: ! 7: * http://wiki.laptop.org/go/Micropolis or email [email protected]. ! 8: * ! 9: * This program is free software: you can redistribute it and/or modify ! 10: * it under the terms of the GNU General Public License as published by ! 11: * the Free Software Foundation, either version 3 of the License, or (at ! 12: * your option) any later version. ! 13: * ! 14: * This program is distributed in the hope that it will be useful, but ! 15: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 17: * General Public License for more details. You should have received a ! 18: * copy of the GNU General Public License along with this program. If ! 19: * not, see <http://www.gnu.org/licenses/>. ! 20: * ! 21: * ADDITIONAL TERMS per GNU GPL Section 7 ! 22: * ! 23: * No trademark or publicity rights are granted. This license does NOT ! 24: * give you any right, title or interest in the trademark SimCity or any ! 25: * other Electronic Arts trademark. You may not distribute any ! 26: * modification of this program using the trademark SimCity or claim any ! 27: * affliation or association with Electronic Arts Inc. or its employees. ! 28: * ! 29: * Any propagation or conveyance of this program must include this ! 30: * copyright notice and these terms. ! 31: * ! 32: * If you convey this program (or any modifications of it) and assume ! 33: * contractual liability for the program to recipients of it, you agree ! 34: * to indemnify Electronic Arts for any liability that those contractual ! 35: * assumptions impose on Electronic Arts. ! 36: * ! 37: * You may not misrepresent the origins of this program; modified ! 38: * versions of the program must be marked as such and not identified as ! 39: * the original program. ! 40: * ! 41: * This disclaimer supplements the one included in the General Public ! 42: * License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS ! 43: * PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY ! 44: * OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF ! 45: * SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS ! 46: * DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES, ! 47: * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY, ! 48: * FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY ! 49: * RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING, ! 50: * USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST ! 51: * INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL ! 52: * MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE ! 53: * UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE ! 54: * WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE ! 55: * CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR ! 56: * ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME ! 57: * JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED ! 58: * WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A ! 59: * CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY ! 60: * NOT APPLY TO YOU. ! 61: */ ! 62: #include "sim.h" ! 63: ! 64: ! 65: #ifdef CAM ! 66: ! 67: ! 68: Tk_ConfigSpec SimCamConfigSpecs[] = { ! 69: {TK_CONFIG_PIXELS, "-width", "width", "Width", ! 70: 0, Tk_Offset(SimCam, w_width), 0}, ! 71: {TK_CONFIG_PIXELS, "-height", "height", "Height", ! 72: 0, Tk_Offset(SimCam, w_height), 0}, ! 73: {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, ! 74: (char *) NULL, 0, 0} ! 75: }; ! 76: ! 77: ! 78: Tk_ConfigSpec CamConfigSpecs[] = { ! 79: {TK_CONFIG_PIXELS, "-wrap", "wrap", "Wrap", ! 80: 0, Tk_Offset(Cam, wrap), 0}, ! 81: {TK_CONFIG_PIXELS, "-steps", "steps", "Steps", ! 82: 0, Tk_Offset(Cam, steps), 0}, ! 83: {TK_CONFIG_PIXELS, "-frob", "frob", "Frob", ! 84: 0, Tk_Offset(Cam, frob), 0}, ! 85: {TK_CONFIG_PIXELS, "-x", "x", "X", ! 86: 0, Tk_Offset(Cam, x), 0}, ! 87: {TK_CONFIG_PIXELS, "-y", "y", "Y", ! 88: 0, Tk_Offset(Cam, y), 0}, ! 89: {TK_CONFIG_PIXELS, "-width", "width", "Width", ! 90: 0, Tk_Offset(Cam, width), 0}, ! 91: {TK_CONFIG_PIXELS, "-height", "height", "Height", ! 92: 0, Tk_Offset(Cam, height), 0}, ! 93: {TK_CONFIG_PIXELS, "-dx", "dx", "Dx", ! 94: 0, Tk_Offset(Cam, dx), 0}, ! 95: {TK_CONFIG_PIXELS, "-dy", "dy", "Dy", ! 96: 0, Tk_Offset(Cam, dy), 0}, ! 97: {TK_CONFIG_PIXELS, "-gx", "gx", "Gx", ! 98: 0, Tk_Offset(Cam, gx), 0}, ! 99: {TK_CONFIG_PIXELS, "-gy", "gy", "Gy", ! 100: 0, Tk_Offset(Cam, gy), 0}, ! 101: {TK_CONFIG_PIXELS, "-dragging", "dragging", "Dragging", ! 102: 0, Tk_Offset(Cam, dragging), 0}, ! 103: {TK_CONFIG_PIXELS, "-setx", "setx", "SetX", ! 104: "-1", Tk_Offset(Cam, set_x), 0}, ! 105: {TK_CONFIG_PIXELS, "-sety", "sety", "SetY", ! 106: "-1", Tk_Offset(Cam, set_y), 0}, ! 107: {TK_CONFIG_PIXELS, "-setwidth", "setwidth", "SetWidth", ! 108: "-1", Tk_Offset(Cam, set_width), 0}, ! 109: {TK_CONFIG_PIXELS, "-setheight", "setheight", "SetHeight", ! 110: "-1", Tk_Offset(Cam, set_height), 0}, ! 111: {TK_CONFIG_PIXELS, "-setx0", "setx0", "SetX0", ! 112: "-1", Tk_Offset(Cam, set_x0), 0}, ! 113: {TK_CONFIG_PIXELS, "-sety0", "sety0", "SetY0", ! 114: "-1", Tk_Offset(Cam, set_y0), 0}, ! 115: {TK_CONFIG_PIXELS, "-setx1", "setx1", "SetX1", ! 116: "-1", Tk_Offset(Cam, set_x1), 0}, ! 117: {TK_CONFIG_PIXELS, "-sety1", "sety1", "SetY1", ! 118: "-1", Tk_Offset(Cam, set_y1), 0}, ! 119: {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, ! 120: (char *) NULL, 0, 0} ! 121: }; ! 122: ! 123: ! 124: Tcl_HashTable CamCmds; ! 125: ! 126: int next_cam_id = 1; ! 127: ! 128: ! 129: static void ! 130: DisplaySimCam(ClientData clientData) ! 131: { ! 132: SimCam *scam = (SimCam *) clientData; ! 133: Tk_Window tkwin = scam->tkwin; ! 134: Pixmap pm = None; ! 135: Drawable d; ! 136: ! 137: scam->flags &= ~VIEW_REDRAW_PENDING; ! 138: if (scam->visible && (tkwin != NULL) && Tk_IsMapped(tkwin)) { ! 139: DoUpdateCam(scam); ! 140: } ! 141: } ! 142: ! 143: ! 144: void ! 145: DestroyCam(SimCam *scam, Cam *cam) ! 146: { ! 147: Cam **cp; ! 148: ! 149: for (cp = &scam->cam_list; ! 150: (*cp) != NULL; ! 151: cp = &((*cp)->next)) { ! 152: if ((*cp) == cam) { ! 153: (*cp) = cam->next; ! 154: scam->cam_count--; ! 155: if (cam->front != NULL) { ! 156: ckfree(cam->front); ! 157: } ! 158: if (cam->back != NULL) { ! 159: if (cam->back->mem != NULL) { ! 160: ckfree(cam->back->mem); ! 161: } ! 162: ckfree(cam->back); ! 163: } ! 164: if (cam->rule != NULL) { ! 165: ckfree(cam->rule); ! 166: } ! 167: if (cam->name != NULL) { ! 168: ckfree(cam->name); ! 169: } ! 170: ckfree(cam); ! 171: break; ! 172: } ! 173: } ! 174: } ! 175: ! 176: ! 177: void ! 178: DestroyScam(ClientData cdata) ! 179: { ! 180: SimCam *scam = (SimCam *)cdata; ! 181: SimCam **cp; ! 182: ! 183: CancelRedrawView(scam); ! 184: ! 185: while (scam->cam_list) { ! 186: DestroyCam(scam, scam->cam_list); ! 187: } ! 188: ! 189: for (cp = &sim->scam; ! 190: (*cp) != NULL; ! 191: cp = &((*cp)->next)) { ! 192: if ((*cp) == scam) { ! 193: (*cp) = scam->next; ! 194: sim->scams--; ! 195: break; ! 196: } ! 197: } ! 198: ! 199: if (scam->shminfo != NULL) { ! 200: XShmDetach(scam->x->dpy, scam->shminfo); ! 201: shmdt(scam->shminfo->shmaddr); ! 202: shmctl(scam->shminfo->shmid, IPC_RMID, 0); ! 203: ckfree(scam->shminfo); ! 204: scam->shminfo = NULL; ! 205: if (scam->image) { ! 206: scam->image->data = NULL; ! 207: scam->data = NULL; ! 208: XDestroyImage(scam->image); ! 209: scam->image = NULL; ! 210: } ! 211: } else { ! 212: if (scam->image) { ! 213: if (scam->image->data) { ! 214: ckfree(scam->image->data); ! 215: scam->image->data = NULL; ! 216: } ! 217: scam->data = NULL; ! 218: XDestroyImage(scam->image); ! 219: scam->image = NULL; ! 220: } ! 221: } ! 222: ! 223: DecRefDisplay(scam->x); ! 224: ! 225: ckfree((char *) scam); ! 226: } ! 227: ! 228: ! 229: void ! 230: CamEventProc(ClientData clientData, XEvent *eventPtr) ! 231: { ! 232: SimCam *scam = (SimCam *) clientData; ! 233: ! 234: if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { ! 235: scam->visible = 1; ! 236: EventuallyRedrawCam(scam); ! 237: } else if (eventPtr->type == MapNotify) { ! 238: scam->visible = 1; ! 239: } else if (eventPtr->type == UnmapNotify) { ! 240: scam->visible = 0; ! 241: } else if (eventPtr->type == VisibilityNotify) { ! 242: if (eventPtr->xvisibility.state == VisibilityFullyObscured) ! 243: scam->visible = 0; ! 244: else ! 245: scam->visible = 1; ! 246: } else if (eventPtr->type == ConfigureNotify) { ! 247: DoResizeCam(scam, ! 248: eventPtr->xconfigure.width, ! 249: eventPtr->xconfigure.height); ! 250: EventuallyRedrawCam(scam); ! 251: } else if (eventPtr->type == DestroyNotify) { ! 252: Tcl_DeleteCommand(scam->interp, Tk_PathName(scam->tkwin)); ! 253: scam->tkwin = NULL; ! 254: if (scam->flags & VIEW_REDRAW_PENDING) { ! 255: Tk_CancelIdleCall(DisplaySimCam, (ClientData) scam); ! 256: } ! 257: Tk_EventuallyFree((ClientData) scam, DestroyScam); ! 258: } ! 259: } ! 260: ! 261: ! 262: int ! 263: DoCamCmd(CLIENT_ARGS) ! 264: { ! 265: SimCam *scam = (SimCam *) clientData; ! 266: Tcl_HashEntry *ent; ! 267: int result = TCL_OK; ! 268: int (*cmd)(); ! 269: ! 270: if (argc < 2) { ! 271: return TCL_ERROR; ! 272: } ! 273: ! 274: if (ent = Tcl_FindHashEntry(&CamCmds, argv[1])) { ! 275: cmd = (int (*)())ent->clientData; ! 276: Tk_Preserve((ClientData) scam); ! 277: result = cmd(scam, interp, argc, argv); ! 278: Tk_Release((ClientData) scam); ! 279: } else { ! 280: Tcl_AppendResult(interp, "unknown command name: \"", ! 281: argv[0], " ", argv[1], "\".", (char *) NULL); ! 282: result = TCL_ERROR; ! 283: } ! 284: return result; ! 285: } ! 286: ! 287: ! 288: int ! 289: CamCmd(CLIENT_ARGS) ! 290: { ! 291: Tk_Window tkwin = (Tk_Window) clientData; ! 292: SimCam *scam; ! 293: ! 294: if (argc < 2) { ! 295: Tcl_AppendResult(interp, "wrong # args: should be \"", ! 296: argv[0], " pathName ?options?\"", (char *) NULL); ! 297: return TCL_ERROR; ! 298: } ! 299: ! 300: tkwin = Tk_CreateWindowFromPath(interp, tkwin, ! 301: argv[1], (char *) NULL); ! 302: if (tkwin == NULL) { ! 303: return TCL_ERROR; ! 304: } ! 305: ! 306: scam = (SimCam *)ckalloc(sizeof (SimCam)); ! 307: ! 308: scam->w_x = 0; ! 309: scam->w_y = 0; ! 310: scam->w_width = 0; ! 311: scam->w_height = 0; ! 312: scam->visible = 0; ! 313: scam->invalid = 1; ! 314: scam->skips = 0; ! 315: scam->skip = 0; ! 316: scam->tkwin = tkwin; ! 317: scam->interp = interp; ! 318: scam->flags = 0; ! 319: scam->x = NULL; ! 320: scam->image = NULL; ! 321: scam->shminfo = NULL; ! 322: scam->line_bytes = 0; ! 323: scam->data = NULL; ! 324: scam->cam_count = 0; ! 325: scam->cam_list = NULL; ! 326: ! 327: Tk_SetClass(scam->tkwin, "Cam"); ! 328: ! 329: Tk_CreateEventHandler(scam->tkwin, ! 330: VisibilityChangeMask | ! 331: ExposureMask | ! 332: StructureNotifyMask | ! 333: EnterWindowMask | ! 334: LeaveWindowMask | ! 335: PointerMotionMask, ! 336: CamEventProc, (ClientData) scam); ! 337: Tcl_CreateCommand(interp, Tk_PathName(scam->tkwin), ! 338: DoCamCmd, (ClientData) scam, (void (*)()) NULL); ! 339: ! 340: Tk_MakeWindowExist(scam->tkwin); ! 341: ! 342: if (getenv("XSYNCHRONIZE") != NULL) { ! 343: XSynchronize(Tk_Display(tkwin), 1); ! 344: } ! 345: ! 346: InitNewCam(scam); ! 347: DoNewCam(scam); ! 348: ! 349: if (ConfigureCam(interp, scam, argc-2, argv+2, 0) != TCL_OK) { ! 350: /* XXX: destroy scam */ ! 351: Tk_DestroyWindow(scam->tkwin); ! 352: return TCL_ERROR; ! 353: } ! 354: ! 355: scam->invalid = 1; ! 356: ! 357: interp->result = Tk_PathName(scam->tkwin); ! 358: return TCL_OK; ! 359: } ! 360: ! 361: ! 362: int ! 363: ConfigureCam(Tcl_Interp *interp, SimCam *scam, ! 364: int argc, char **argv, int flags) ! 365: { ! 366: if (Tk_ConfigureWidget(interp, scam->tkwin, SimCamConfigSpecs, ! 367: argc, argv, (char *) scam, flags) != TCL_OK) { ! 368: return TCL_ERROR; ! 369: } ! 370: ! 371: if (scam->w_width || scam->w_height) { ! 372: Tk_GeometryRequest(scam->tkwin, scam->w_width, scam->w_height); ! 373: } ! 374: ! 375: EventuallyRedrawCam(scam); ! 376: ! 377: return TCL_OK; ! 378: } ! 379: ! 380: ! 381: EventuallyRedrawCam(SimCam *scam) ! 382: { ! 383: if (!(scam->flags & VIEW_REDRAW_PENDING)) { ! 384: Tk_DoWhenIdle(DisplaySimCam, (ClientData) scam); ! 385: scam->flags |= VIEW_REDRAW_PENDING; ! 386: } ! 387: } ! 388: ! 389: ! 390: CamCmdconfigure(CAM_ARGS) ! 391: { ! 392: int result = TCL_OK; ! 393: ! 394: if (argc == 2) { ! 395: result = Tk_ConfigureInfo(interp, scam->tkwin, SimCamConfigSpecs, ! 396: (char *) scam, (char *) NULL, 0); ! 397: } else if (argc == 3) { ! 398: result = Tk_ConfigureInfo(interp, scam->tkwin, SimCamConfigSpecs, ! 399: (char *) scam, argv[2], 0); ! 400: } else { ! 401: result = ConfigureCam(interp, scam, argc-2, argv+2, ! 402: TK_CONFIG_ARGV_ONLY); ! 403: } ! 404: return result; ! 405: } ! 406: ! 407: ! 408: CamCmdposition(CAM_ARGS) ! 409: { ! 410: if ((argc != 2) && (argc != 4)) { ! 411: return TCL_ERROR; ! 412: } ! 413: if (argc == 4) { ! 414: int x, y; ! 415: ! 416: if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ! 417: || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) { ! 418: return TCL_ERROR; ! 419: } ! 420: scam->w_x = x; ! 421: scam->w_y = y; ! 422: } ! 423: sprintf(interp->result, "%d %d", scam->w_x, scam->w_y); ! 424: return TCL_OK; ! 425: } ! 426: ! 427: ! 428: CamCmdsize(CAM_ARGS) ! 429: { ! 430: if ((argc != 2) && (argc != 4)) { ! 431: return TCL_ERROR; ! 432: } ! 433: if (argc == 4) { ! 434: int w, h; ! 435: ! 436: if (Tcl_GetInt(interp, argv[2], &w) != TCL_OK) { ! 437: return TCL_ERROR; ! 438: } ! 439: if (Tcl_GetInt(interp, argv[3], &h) != TCL_OK) { ! 440: return TCL_ERROR; ! 441: } ! 442: scam->w_width = w; ! 443: scam->w_height = h; ! 444: } ! 445: sprintf(interp->result, "%d %d", scam->w_width, scam->w_height); ! 446: return TCL_OK; ! 447: } ! 448: ! 449: ! 450: CamCmdVisible(CAM_ARGS) ! 451: { ! 452: int visible; ! 453: ! 454: if ((argc != 2) && (argc != 3)) { ! 455: return TCL_ERROR; ! 456: } ! 457: ! 458: if (argc == 3) { ! 459: if ((Tcl_GetInt(interp, argv[2], &visible) != TCL_OK) || ! 460: (visible < 0) || (visible > 1)) { ! 461: return TCL_ERROR; ! 462: } ! 463: ! 464: visible = visible && Tk_IsMapped(scam->tkwin); ! 465: scam->visible = visible; ! 466: } ! 467: ! 468: sprintf(interp->result, "%d", scam->visible); ! 469: return TCL_OK; ! 470: } ! 471: ! 472: ! 473: CamCmdStoreColor(CAM_ARGS) ! 474: { ! 475: int index, r, g, b, err; ! 476: XColor color; ! 477: ! 478: if (argc != 6) { ! 479: return TCL_ERROR; ! 480: } ! 481: ! 482: if ((Tcl_GetInt(interp, argv[2], &index) != TCL_OK) || ! 483: (Tcl_GetInt(interp, argv[2], &r) != TCL_OK) || ! 484: (Tcl_GetInt(interp, argv[2], &g) != TCL_OK) || ! 485: (Tcl_GetInt(interp, argv[2], &b) != TCL_OK)) { ! 486: return TCL_ERROR; ! 487: } ! 488: ! 489: color.pixel = index; ! 490: color.red = r; ! 491: color.green = g; ! 492: color.blue = b; ! 493: color.flags = DoRed | DoGreen | DoBlue; ! 494: err = XStoreColor(scam->x->dpy, scam->x->colormap, &color); ! 495: ! 496: sprintf(interp->result, "%d", err); ! 497: return TCL_OK; ! 498: } ! 499: ! 500: ! 501: CamCmdNewCam(CAM_ARGS) ! 502: { ! 503: Cam *cam; ! 504: char *name; ! 505: char *rule_name = NULL; ! 506: int rule_number = 0; ! 507: int x, y, w, h; ! 508: ! 509: if (argc < 8) { ! 510: return TCL_ERROR; ! 511: } ! 512: ! 513: name = argv[2]; ! 514: ! 515: if ((Tcl_GetInt(interp, argv[3], &rule_number) != TCL_OK) || ! 516: (rule_number == 0)) { ! 517: rule_name = argv[3]; ! 518: } ! 519: ! 520: if ((Tcl_GetInt(interp, argv[4], &x) != TCL_OK) || ! 521: (Tcl_GetInt(interp, argv[5], &y) != TCL_OK) || ! 522: (Tcl_GetInt(interp, argv[6], &w) != TCL_OK) || ! 523: (Tcl_GetInt(interp, argv[7], &h) != TCL_OK)) { ! 524: return TCL_ERROR; ! 525: } ! 526: ! 527: cam = (Cam *)find_cam_by_name(scam, name); ! 528: ! 529: if (cam != NULL) { ! 530: DestroyCam(scam, cam); ! 531: } ! 532: ! 533: cam = (Cam *)new_cam(scam, x, y, w, h, 0, 0, NULL); ! 534: cam->name = (char *)malloc(strlen(name) + 1); ! 535: strcpy(cam->name, name); ! 536: ! 537: if (rule_name != NULL) { ! 538: cam_load_rule(cam, rule_name); ! 539: } else { ! 540: cam_set_neighborhood(cam, rule_number); ! 541: } ! 542: ! 543: return Tk_ConfigureWidget(interp, scam->tkwin, CamConfigSpecs, ! 544: argc - 8, argv + 8, (char *) cam, 0); ! 545: } ! 546: ! 547: ! 548: CamCmdDeleteCam(CAM_ARGS) ! 549: { ! 550: Cam *cam; ! 551: char *name; ! 552: ! 553: if (argc != 3) { ! 554: return TCL_ERROR; ! 555: } ! 556: ! 557: name = argv[2]; ! 558: ! 559: cam = (Cam *)find_cam_by_name(scam, name); ! 560: ! 561: if (cam != NULL) { ! 562: DestroyCam(scam, cam); ! 563: } ! 564: ! 565: return TCL_OK; ! 566: } ! 567: ! 568: ! 569: CamCmdRandomizeCam(CAM_ARGS) ! 570: { ! 571: Cam *cam; ! 572: char *name; ! 573: ! 574: if (argc != 3) { ! 575: return TCL_ERROR; ! 576: } ! 577: ! 578: name = argv[2]; ! 579: ! 580: cam = (Cam *)find_cam_by_name(scam, name); ! 581: ! 582: if (cam != NULL) { ! 583: cam_randomize(cam); ! 584: } ! 585: ! 586: return TCL_OK; ! 587: } ! 588: ! 589: ! 590: CamCmdConfigCam(CAM_ARGS) ! 591: { ! 592: Cam *cam; ! 593: int result = TCL_OK; ! 594: ! 595: if (argc < 3) { ! 596: return TCL_ERROR; ! 597: } ! 598: ! 599: cam = (Cam *)find_cam_by_name(scam, argv[2]); ! 600: ! 601: if (cam == NULL) { ! 602: return TCL_ERROR; ! 603: } ! 604: ! 605: if (argc == 3) { ! 606: result = Tk_ConfigureInfo(interp, scam->tkwin, CamConfigSpecs, ! 607: (char *) cam, (char *) NULL, 0); ! 608: } else if (argc == 4) { ! 609: result = Tk_ConfigureInfo(interp, scam->tkwin, CamConfigSpecs, ! 610: (char *) cam, argv[3], 0); ! 611: } else { ! 612: result = Tk_ConfigureWidget(interp, scam->tkwin, CamConfigSpecs, ! 613: argc - 3, argv + 3, (char *) cam, 0); ! 614: } ! 615: ! 616: return result; ! 617: } ! 618: ! 619: ! 620: CamCmdFindCam(CAM_ARGS) ! 621: { ! 622: Cam *cam; ! 623: int x, y; ! 624: ! 625: if (argc != 4) { ! 626: return TCL_ERROR; ! 627: } ! 628: ! 629: if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) || ! 630: (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) { ! 631: return TCL_ERROR; ! 632: } ! 633: ! 634: cam = (Cam *)find_cam(scam, x, y); ! 635: sprintf(interp->result, "%s", (cam == NULL) ? "" : cam->name); ! 636: ! 637: return TCL_OK; ! 638: } ! 639: ! 640: ! 641: CamCmdFindSomeCam(CAM_ARGS) ! 642: { ! 643: Cam *cam; ! 644: int x, y; ! 645: ! 646: if (argc != 4) { ! 647: return TCL_ERROR; ! 648: } ! 649: ! 650: if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) || ! 651: (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) { ! 652: return TCL_ERROR; ! 653: } ! 654: ! 655: cam = (Cam *)find_cam(scam, x, y); ! 656: if (cam == NULL) { ! 657: cam = scam->cam_list; ! 658: } ! 659: ! 660: sprintf(interp->result, "%s", (cam == NULL) ? "" : cam->name); ! 661: ! 662: return TCL_OK; ! 663: } ! 664: ! 665: /*************************************************************************/ ! 666: ! 667: InitNewCam(SimCam *scam) ! 668: { ! 669: scam->x = (XDisplay *)FindXDisplay(scam->tkwin); ! 670: IncRefDisplay(scam->x); ! 671: ! 672: DoResizeCam(scam, 512, 512); ! 673: ! 674: init_scam(scam); ! 675: } ! 676: ! 677: ! 678: DoResizeCam(SimCam *scam, int w, int h) ! 679: { ! 680: Cam *cam; ! 681: ! 682: for (cam = scam->cam_list; cam != NULL; cam = cam->next) { ! 683: if (cam->front->width > w) w = cam->front->width; ! 684: if (cam->front->height > h) h = cam->front->height; ! 685: } ! 686: ! 687: scam->w_width = w; ! 688: scam->w_height = h; ! 689: ! 690: if (scam->shminfo != NULL) { ! 691: XShmDetach(scam->x->dpy, scam->shminfo); ! 692: shmdt(scam->shminfo->shmaddr); ! 693: shmctl(scam->shminfo->shmid, IPC_RMID, 0); ! 694: ckfree(scam->shminfo); ! 695: scam->shminfo = NULL; ! 696: if (scam->image) { ! 697: scam->image->data = NULL; ! 698: scam->data = NULL; ! 699: XDestroyImage(scam->image); ! 700: scam->image = NULL; ! 701: } ! 702: } else { ! 703: if (scam->image) { ! 704: if (scam->image->data) { ! 705: ckfree(scam->image->data); ! 706: scam->image->data = NULL; ! 707: } ! 708: scam->data = NULL; ! 709: XDestroyImage(scam->image); ! 710: scam->image = NULL; ! 711: } ! 712: } ! 713: ! 714: if (scam->x->shared) { ! 715: scam->shminfo = (XShmSegmentInfo *)ckalloc(sizeof (XShmSegmentInfo)); ! 716: ! 717: scam->image = ! 718: XShmCreateImage(scam->x->dpy, scam->x->visual, scam->x->depth, ! 719: scam->x->color ? ZPixmap : XYBitmap, ! 720: NULL, scam->shminfo, ! 721: scam->w_width, scam->w_height); ! 722: ! 723: scam->line_bytes = scam->image->bytes_per_line; ! 724: scam->shminfo->readOnly = False; ! 725: scam->shminfo->shmid = shmget(IPC_PRIVATE, ! 726: (scam->line_bytes * ! 727: scam->w_height), ! 728: (IPC_CREAT | 0777)); ! 729: if (scam->shminfo->shmid < 0) { ! 730: perror("shmget"); ! 731: fprintf(stderr, ! 732: "Drat, Micropolis can't share memory with X display \"%s\".\n", ! 733: scam->x->display); ! 734: goto FALL_BACK; ! 735: } ! 736: ! 737: scam->data = (unsigned char *)shmat(scam->shminfo->shmid, 0, 0); ! 738: scam->image->data = (char *)scam->data; ! 739: if ((int)scam->data == -1) { ! 740: perror("shmat"); ! 741: fprintf(stderr, ! 742: "Drat, Micropolis can't find any memory to share with display \"%s\".\n", ! 743: scam->x->display); ! 744: goto FALL_BACK; ! 745: } ! 746: ! 747: scam->shminfo->shmaddr = (char *)scam->data; ! 748: scam->shminfo->readOnly = False; ! 749: ! 750: ! 751: { int (*old)(); ! 752: int CatchXError(); ! 753: ! 754: GotXError = 0; ! 755: old = XSetErrorHandler(CatchXError); ! 756: ! 757: if (XShmAttach(scam->x->dpy, scam->shminfo) == 0) { ! 758: fprintf(stderr, ! 759: "Drat, the X display \"%s\" can't access Micropolis's shared memory.\n", ! 760: scam->x->display); ! 761: GotXError = 1; ! 762: } ! 763: ! 764: XSync(scam->x->dpy, False); ! 765: ! 766: XSetErrorHandler(old); ! 767: ! 768: if (GotXError) { ! 769: goto FALL_BACK; ! 770: } ! 771: } ! 772: } else { ! 773: goto SPRING_FORWARD; ! 774: FALL_BACK: ! 775: fprintf(stderr, ! 776: "Falling back to the X network protocol on display \"%s\"...\n", ! 777: scam->x->display); ! 778: SPRING_FORWARD: ! 779: scam->x->shared = 0; ! 780: if (scam->shminfo) { ! 781: if (scam->shminfo->shmid >= 0) { ! 782: if (scam->shminfo->shmaddr) { ! 783: shmdt(scam->shminfo->shmaddr); ! 784: } ! 785: shmctl(scam->shminfo->shmid, IPC_RMID, 0); ! 786: } ! 787: ckfree((char *)scam->shminfo); ! 788: scam->shminfo = NULL; ! 789: } ! 790: if (scam->image) { ! 791: scam->image->data = NULL; ! 792: XDestroyImage(scam->image); ! 793: scam->image = NULL; ! 794: } ! 795: scam->data = NULL; ! 796: scam->line_bytes = scam->w_width; ! 797: scam->data = (Byte *)ckalloc(scam->line_bytes * scam->w_height); ! 798: scam->image = ! 799: XCreateImage(scam->x->dpy, scam->x->visual, ! 800: scam->x->depth, ! 801: scam->x->color ? ZPixmap : XYBitmap, ! 802: 0, (char *)scam->data, ! 803: scam->w_width, scam->w_height, ! 804: 8, scam->line_bytes); /* XXX: handle other depths */ ! 805: } ! 806: ! 807: for (cam = scam->cam_list; cam != NULL; cam = cam->next) { ! 808: if (cam->x + cam->front->width > scam->w_width) { ! 809: cam->x = scam->w_width - cam->front->width; ! 810: } ! 811: if (cam->y + cam->front->height > scam->w_height) { ! 812: cam->y = scam->w_height - cam->front->height; ! 813: } ! 814: cam->front->line_bytes = scam->line_bytes; ! 815: cam->front->mem = /* XXX: handle other depths */ ! 816: (Byte *)scam->data + cam->x + (scam->line_bytes * cam->y); ! 817: } ! 818: } ! 819: ! 820: ! 821: DoNewCam(SimCam *scam) ! 822: { ! 823: sim->scams++; scam->next = sim->scam; sim->scam = scam; ! 824: scam->invalid = 1; ! 825: } ! 826: ! 827: ! 828: DoUpdateCam(SimCam *scam) ! 829: { ! 830: if (!scam->visible) { ! 831: return; ! 832: } ! 833: ! 834: if (scam->invalid) { ! 835: scam->invalid = 0; ! 836: } ! 837: ! 838: if (scam->x->shared) { ! 839: XShmPutImage(scam->x->dpy, Tk_WindowId(scam->tkwin), scam->x->gc, ! 840: scam->image, 0, 0, ! 841: 0, 0, scam->w_width, scam->w_height, ! 842: False); ! 843: } else { ! 844: XPutImage(scam->x->dpy, Tk_WindowId(scam->tkwin), scam->x->gc, ! 845: scam->image, 0, 0, ! 846: 0, 0, scam->w_width, scam->w_height); ! 847: } ! 848: } ! 849: ! 850: ! 851: cam_command_init() ! 852: { ! 853: int new; ! 854: extern int TileCamCmd(CLIENT_ARGS); ! 855: ! 856: Tcl_CreateCommand(tk_mainInterp, "camview", CamCmd, ! 857: (ClientData)MainWindow, (void (*)()) NULL); ! 858: ! 859: Tcl_InitHashTable(&CamCmds, TCL_STRING_KEYS); ! 860: ! 861: #define CAM_CMD(name) HASHED_CMD(Cam, name) ! 862: ! 863: CAM_CMD(configure); ! 864: CAM_CMD(position); ! 865: CAM_CMD(size); ! 866: CAM_CMD(Visible); ! 867: CAM_CMD(StoreColor); ! 868: CAM_CMD(NewCam); ! 869: CAM_CMD(DeleteCam); ! 870: CAM_CMD(RandomizeCam); ! 871: CAM_CMD(ConfigCam); ! 872: CAM_CMD(FindCam); ! 873: CAM_CMD(FindSomeCam); ! 874: } ! 875: ! 876: ! 877: #endif /* CAM */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.