Annotation of researchv9/X11/src/X.V11R1/server/dix/property.c, revision 1.1.1.1

1.1       root        1: /***********************************************************
                      2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                      3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                      4: 
                      5:                         All Rights Reserved
                      6: 
                      7: Permission to use, copy, modify, and distribute this software and its 
                      8: documentation for any purpose and without fee is hereby granted, 
                      9: provided that the above copyright notice appear in all copies and that
                     10: both that copyright notice and this permission notice appear in 
                     11: supporting documentation, and that the names of Digital or MIT not be
                     12: used in advertising or publicity pertaining to distribution of the
                     13: software without specific, written prior permission.  
                     14: 
                     15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     21: SOFTWARE.
                     22: 
                     23: ******************************************************************/
                     24: /* $Header: property.c,v 1.55 87/09/03 03:04:04 newman Exp $ */
                     25: 
                     26: #include "X.h"
                     27: #define NEED_REPLIES
                     28: #define NEED_EVENTS
                     29: #include "Xproto.h"
                     30: #include "windowstr.h"
                     31: #include "propertyst.h"
                     32: #include "dixstruct.h"
                     33: 
                     34: extern void (*ReplySwapVector[]) ();
                     35: extern void CopySwap16Write(), CopySwap32Write(), Swap32Write(), WriteToClient();
                     36: 
                     37: /*****************************************************************
                     38:  * Property Stuff
                     39:  *
                     40:  *    ChangeProperty, DeleteProperty, GetProperties,
                     41:  *    ListProperties
                     42:  *
                     43:  *   Properties below to windows.  A allocate slots each time
                     44:  *   a property is added.  No fancy searching done.
                     45:  *
                     46:  *****************************************************************/
                     47: 
                     48: static void
                     49: PrintPropertys(pWin)
                     50:     WindowPtr pWin;
                     51: {
                     52:     PropertyPtr pProp;
                     53:     register int j;
                     54: 
                     55:     pProp = pWin->userProps;
                     56:     while (pProp)
                     57:     {
                     58:         ErrorF(  "%x %x\n", pProp->propertyName, pProp->type);
                     59:         ErrorF("property format: %d\n", pProp->format);
                     60:         ErrorF("property data: \n");
                     61:         for (j=0; j<(pProp->format/8)*pProp->size; j++)
                     62:            ErrorF("%c\n", pProp->data[j]);
                     63:         pProp = pProp->next;
                     64:     }
                     65: }
                     66: 
                     67: 
                     68: int
                     69: ProcRotateProperties(client)
                     70:     ClientPtr client;
                     71: {
                     72:     int     i, j, delta;
                     73:     REQUEST(xRotatePropertiesReq);
                     74:     WindowPtr pWin;
                     75:     register    Atom * atoms;
                     76:     PropertyPtr * props;               /* array of pointer */
                     77:     PropertyPtr pProp;
                     78:     xEvent event;
                     79: 
                     80:     REQUEST_AT_LEAST_SIZE(xRotatePropertiesReq);
                     81:     if (stuff->length != ((sizeof(xRotatePropertiesReq) >> 2) + stuff->nAtoms))
                     82:         return BadLength;
                     83:     pWin = (WindowPtr) LookupWindow(stuff->window, client);
                     84:     if (!pWin)
                     85:         return(BadWindow);
                     86:     atoms = (Atom *) & stuff[1];
                     87:     props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
                     88:     for (i = 0; i < stuff->nAtoms; i++)
                     89:     {
                     90:         if (!ValidAtom(atoms[i]))
                     91:         {
                     92:             DEALLOCATE_LOCAL(props);
                     93:             return BadAtom;
                     94:         }
                     95:         for (j = i + 1; j < stuff->nAtoms; j++)
                     96:             if (atoms[j] == atoms[i])
                     97:             {
                     98:                 DEALLOCATE_LOCAL(props);
                     99:                 return BadMatch;
                    100:             }
                    101:         pProp = pWin->userProps;
                    102:         while (pProp)
                    103:         {
                    104:             if (pProp->propertyName == atoms[i])
                    105:                 goto found;
                    106:            pProp = pProp->next;
                    107:         }
                    108:         DEALLOCATE_LOCAL(props);
                    109:         return BadMatch;
                    110: found: 
                    111:         props[i] = pProp;
                    112:     }
                    113:     delta = stuff->nPositions;
                    114: 
                    115:     /* If the rotation is a complete 360 degrees, then moving the properties
                    116:        around and generating PropertyNotify events should be skipped. */
                    117: 
                    118:     if ( (stuff->nAtoms > 0) && (abs(delta) % stuff->nAtoms) != 0 ) 
                    119:     {
                    120:        while (delta < 0)                  /* faster if abs value is small */
                    121:             delta += stuff->nAtoms;
                    122:        for (i = 0; i < stuff->nAtoms; i++)
                    123:        {
                    124:            /* Generate a PropertyNotify event for each property whose value
                    125:                is changed in the order in which they appear in the request. */
                    126:  
                    127:            event.u.u.type = PropertyNotify;
                    128:             event.u.property.window = pWin->wid;
                    129:            event.u.property.state = PropertyNewValue;
                    130:            event.u.property.atom = props[i]->propertyName;     
                    131:            event.u.property.time = currentTime.milliseconds;
                    132:            DeliverEvents(pWin, &event, 1);
                    133:        
                    134:             props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
                    135:        }
                    136:     }
                    137:     DEALLOCATE_LOCAL(props);
                    138:     return Success;
                    139: }
                    140: 
                    141: int 
                    142: ProcChangeProperty(client)
                    143:     ClientPtr client;
                    144: {            
                    145:     WindowPtr pWin;
                    146:     char format, mode;
                    147:     int len;
                    148:     PropertyPtr pProp;
                    149:     xEvent event;
                    150:     int sizeInBytes;
                    151:     REQUEST(xChangePropertyReq);
                    152: 
                    153:     REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
                    154:     format = stuff->format;
                    155:     mode = stuff->mode;
                    156:     if (((mode != PropModeReplace) && (mode != PropModeAppend) &&
                    157:         (mode != PropModePrepend)) 
                    158:     || ((format != 8) && (format != 16) && (format != 32)))
                    159:         return BadValue;
                    160: 
                    161:     pWin = (WindowPtr)LookupWindow(stuff->window, client);
                    162:     if (!pWin)
                    163:        return(BadWindow);
                    164:     if (!(ValidAtom(stuff->property)  && ValidAtom(stuff->type)))
                    165:        return(BadAtom);
                    166: 
                    167:     /* first see if property already exists */
                    168: 
                    169:     len = stuff->nUnits;
                    170:     sizeInBytes = format/8;
                    171:     pProp = pWin->userProps;
                    172:     while (pProp)
                    173:     {
                    174:        if (pProp->propertyName ==stuff->property) 
                    175:            break;
                    176:        pProp = pProp->next;
                    177:     }
                    178:     if (!pProp)   /* just add to list */
                    179:     {
                    180:         pProp = (PropertyPtr)Xalloc(sizeof(PropertyRec));
                    181:         pProp->propertyName = stuff->property;
                    182:         pProp->type = stuff->type;
                    183:         pProp->format = format;
                    184:         pProp->data = (pointer)Xalloc(sizeInBytes  * len);
                    185:         bcopy(&stuff[1], pProp->data, len * sizeInBytes);
                    186:        pProp->size = len;
                    187:         pProp->next = pWin->userProps;
                    188:         pWin->userProps = pProp;
                    189:     }
                    190:     else
                    191:     {
                    192:     
                    193:        /* To append or prepend to a property the request format and type
                    194:                must match those of the already defined property.  The
                    195:                existing format and type are irrelevant when using the mode
                    196:                "PropModeReplace" since they will be written over. */
                    197: 
                    198:         if ((format != pProp->format) && (mode != PropModeReplace))
                    199:            return(BadMatch);
                    200:         if ((pProp->type != stuff->type) && (mode != PropModeReplace))
                    201:             return(BadMatch);
                    202:                                /* XXX should check length too */
                    203:         if (mode == PropModeReplace) 
                    204:         {
                    205:             pProp->data = (pointer)Xrealloc((char *) pProp->data,
                    206:                                            sizeInBytes * len);
                    207:            bcopy(&stuff[1], pProp->data, len * sizeInBytes);    
                    208:            pProp->size = len;
                    209:            pProp->type = stuff->type;
                    210:            pProp->format = stuff->format;
                    211:        }
                    212:         else if (mode == PropModeAppend)
                    213:         {
                    214:             pProp->data = (pointer)Xrealloc((char *) pProp->data,
                    215:                                            sizeInBytes * (len + pProp->size));
                    216:            bcopy(&stuff[1], &pProp->data[pProp->size * sizeInBytes], 
                    217:                  len * sizeInBytes);
                    218:             pProp->size += len;
                    219:        }
                    220:         else if (mode == PropModePrepend)
                    221:         {
                    222:             pointer tstr = pProp->data;
                    223:             pProp->data = (pointer)Xalloc(sizeInBytes * (len + pProp->size));
                    224:            bcopy(tstr, &pProp->data[len * sizeInBytes], 
                    225:                  pProp->size * sizeInBytes);
                    226:             bcopy(&stuff[1], pProp->data, len * sizeInBytes);
                    227:             pProp->size += len;
                    228:            Xfree(tstr);
                    229:        }
                    230:     }
                    231:     event.u.u.type = PropertyNotify;
                    232:     event.u.property.window = pWin->wid;
                    233:     event.u.property.state = PropertyNewValue;
                    234:     event.u.property.atom = pProp->propertyName;
                    235:     event.u.property.time = currentTime.milliseconds;
                    236:     DeliverEvents(pWin, &event, 1);
                    237: 
                    238:     return(client->noClientException);
                    239: }
                    240: 
                    241: DeleteProperty(pWin, propName)
                    242:     WindowPtr pWin;
                    243:     ATOM propName;
                    244: {
                    245:     PropertyPtr pProp, prevProp;
                    246:     xEvent event;
                    247: 
                    248:     if (!(pProp = pWin->userProps))
                    249:        return(BadAtom);
                    250:     prevProp = (PropertyPtr)NULL;
                    251:     while (pProp)
                    252:     {
                    253:        if (pProp->propertyName == propName)
                    254:            break;
                    255:         prevProp = pProp;
                    256:        pProp = pProp->next;
                    257:     }
                    258:     if (pProp) 
                    259:     {              
                    260:         if (prevProp == (PropertyPtr)NULL)      /* takes care of head */
                    261:         {
                    262:             pWin->userProps = pProp->next;
                    263:         }
                    264:        else
                    265:         {
                    266:             prevProp->next = pProp->next;
                    267:         }
                    268:        Xfree(pProp->data);
                    269:         Xfree(pProp);
                    270: 
                    271:        event.u.u.type = PropertyNotify;
                    272:        event.u.property.window = pWin->wid;
                    273:        event.u.property.state = PropertyDelete;
                    274:         event.u.property.atom = pProp->propertyName;
                    275:        event.u.property.time = currentTime.milliseconds;
                    276:        DeliverEvents(pWin, &event, 1);
                    277: 
                    278:         return(Success);
                    279:     }
                    280:     else 
                    281:        return(BadAtom);
                    282: }
                    283: 
                    284: DeleteAllWindowProperties(pWin)
                    285:     WindowPtr pWin;
                    286: {
                    287:     PropertyPtr pProp, pNextProp;
                    288:     xEvent event;
                    289: 
                    290:     pProp = pWin->userProps;
                    291:     while (pProp)
                    292:     {
                    293:        event.u.u.type = PropertyNotify;
                    294:        event.u.property.window = pWin->wid;
                    295:        event.u.property.state = PropertyDelete;
                    296:        event.u.property.atom = pProp->propertyName;
                    297:        event.u.property.time = currentTime.milliseconds;
                    298:        DeliverEvents(pWin, &event, 1);
                    299:        pNextProp = pProp->next;
                    300:         Xfree(pProp->data);
                    301:         Xfree(pProp);
                    302:        pProp = pNextProp;
                    303:     }
                    304: }
                    305: 
                    306: /*****************
                    307:  * GetProperty
                    308:  *    If type Any is specified, returns the property from the specified
                    309:  *    window regardless of its type.  If a type is specified, returns the
                    310:  *    property only if its type equals the specified type.
                    311:  *    If delete is True and a property is returned, the property is also
                    312:  *    deleted from the window and a PropertyNotify event is generated on the
                    313:  *    window.
                    314:  *****************/
                    315: 
                    316: int
                    317: ProcGetProperty(client)
                    318:     ClientPtr client;
                    319: {
                    320:     PropertyPtr pProp, prevProp;
                    321:     int n, len, ind;
                    322:     WindowPtr pWin;
                    323:     xGetPropertyReply reply;
                    324:     REQUEST(xGetPropertyReq);
                    325: 
                    326:     REQUEST_SIZE_MATCH(xGetPropertyReq);
                    327:     pWin = (WindowPtr)LookupWindow(stuff->window, client);
                    328:     client->errorValue = stuff->window;
                    329:     if (pWin)
                    330:     {
                    331:        if (ValidAtom(stuff->property) && 
                    332:            ((stuff->type == AnyPropertyType) || ValidAtom(stuff->type)))
                    333:        {
                    334:            pProp = pWin->userProps;
                    335:             prevProp = (PropertyPtr)NULL;
                    336:             while (pProp)
                    337:             {
                    338:                if (pProp->propertyName == stuff->property) 
                    339:                    break;
                    340:                prevProp = pProp;
                    341:                pProp = pProp->next;
                    342:             }
                    343:            reply.type = X_Reply;
                    344:            reply.sequenceNumber = client->sequence;
                    345:             if (pProp) 
                    346:             {
                    347: 
                    348:                /* If the request type and actual type don't match. Return the
                    349:                property information, but not the data. */
                    350: 
                    351:                 if ((stuff->type != pProp->type) &&
                    352:                    (stuff->type != AnyPropertyType))
                    353:                {
                    354:                    reply.bytesAfter = pProp->size;
                    355:                    reply.format = pProp->format;
                    356:                    reply.length = 0;
                    357:                    reply.nItems = 0;
                    358:                    reply.propertyType = pProp->type;
                    359:                    WriteReplyToClient(client, sizeof(xGenericReply), &reply);
                    360:                    return(Success);
                    361:                }
                    362: 
                    363:            /*
                    364:              *  Return type, format, value to client
                    365:              */
                    366:                n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
                    367:                ind = stuff->longOffset << 2;        
                    368: 
                    369:                /* If longOffset is invalid such that it causes "len" to
                    370:                         be negative, it's a value error. */
                    371: 
                    372:                if ((n - ind) < 0)
                    373:                    return BadValue;
                    374: 
                    375:                len = min(n - ind, 4 * stuff->longLength);
                    376: 
                    377:                reply.bytesAfter = n - (ind + len);
                    378:                reply.format = pProp->format;
                    379:                reply.length = len >> 2;
                    380:                reply.nItems = len / (pProp->format / 8 );
                    381:                reply.propertyType = pProp->type;
                    382:                WriteReplyToClient(client, sizeof(xGenericReply), &reply);
                    383:                switch (reply.format) {
                    384:                case 32: client->pSwapReplyFunc = CopySwap32Write; break;
                    385:                case 16: client->pSwapReplyFunc = CopySwap16Write; break;
                    386:                default: client->pSwapReplyFunc = WriteToClient; break;
                    387:                }
                    388:                WriteSwappedDataToClient(client, len, pProp->data + ind);
                    389: 
                    390:                 if (stuff->delete && (reply.bytesAfter == 0))
                    391:                 { /* delete the Property */
                    392:                    xEvent event;
                    393:                
                    394:                     if (prevProp == (PropertyPtr)NULL) /* takes care of head */
                    395:                         pWin->userProps = pProp->next;
                    396:                    else
                    397:                         prevProp->next = pProp->next;
                    398:                    Xfree(pProp->data);
                    399:                     Xfree(pProp);
                    400:                    event.u.u.type = PropertyNotify;
                    401:                    event.u.property.window = pWin->wid;
                    402:                    event.u.property.state = PropertyDelete;
                    403:                    event.u.property.atom = pProp->propertyName;
                    404:                    event.u.property.time = currentTime.milliseconds;
                    405:                    DeliverEvents(pWin, &event, 1);
                    406:                }
                    407:            }
                    408:             else 
                    409:            {   
                    410:                 reply.nItems = 0;
                    411:                reply.length = 0;
                    412:                reply.bytesAfter = 0;
                    413:                reply.propertyType = None;
                    414:                reply.format = 0;
                    415:                WriteReplyToClient(client, sizeof(xGenericReply), &reply);
                    416:            }
                    417:             return(client->noClientException);
                    418: 
                    419:        }
                    420:         else
                    421:             return(BadAtom);
                    422:     }
                    423:     else            
                    424:         return (BadWindow); 
                    425: }
                    426: 
                    427: int
                    428: ProcListProperties(client)
                    429:     ClientPtr client;
                    430: {
                    431:     Atom *pAtoms, *temppAtoms;
                    432:     xListPropertiesReply xlpr;
                    433:     int        numProps = 0;
                    434:     WindowPtr pWin;
                    435:     PropertyPtr pProp;
                    436:     REQUEST(xResourceReq);
                    437: 
                    438:     REQUEST_SIZE_MATCH(xResourceReq);
                    439:     pWin = (WindowPtr)LookupWindow(stuff->id, client);
                    440:     if (!pWin)
                    441:         return(BadWindow);
                    442: 
                    443:     pProp = pWin->userProps;
                    444:     while (pProp)
                    445:     {        
                    446:         pProp = pProp->next;
                    447:        numProps++;
                    448:     }
                    449:     if (numProps)
                    450:         if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
                    451:             return(client->noClientException = BadAlloc);
                    452: 
                    453:     xlpr.type = X_Reply;
                    454:     xlpr.nProperties = numProps;
                    455:     xlpr.length = (numProps * sizeof(Atom)) >> 2;
                    456:     xlpr.sequenceNumber = client->sequence;
                    457:     pProp = pWin->userProps;
                    458:     temppAtoms = pAtoms;
                    459:     while (pProp)
                    460:     {
                    461:        *temppAtoms++ = pProp->propertyName;
                    462:        pProp = pProp->next;
                    463:     }
                    464:     WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
                    465:     if (numProps)
                    466:     {
                    467:         client->pSwapReplyFunc = Swap32Write;
                    468:         WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
                    469:         DEALLOCATE_LOCAL(pAtoms);
                    470:     }
                    471:     return(client->noClientException);
                    472: }

unix.superglobalmegacorp.com

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