Annotation of micropolis/src/sim/w_cam.c, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

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