objsupport 4.68 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/* Copyright 1996 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* File:        objsupport.c
 * Purpose:     Support Library for object modules
 * Author:      Neil Kelleher
 * History:     1-Jul-1994:  NK: created
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include "kernel.h"
#include "swis.h"

#include "debug.h"
29 30
#include "objects/toolbox.h"
#include "objects/window.h"
Neil Turton's avatar
Neil Turton committed
31 32
#include "mem.h"
#include "objsupport.h"
33
#include "string32.h"
Neil Turton's avatar
Neil Turton committed
34 35 36

static _kernel_oserror *extract_gadget_info(char *tm,ComponentID id,void **p,int *l)
{
Stewart Brodie's avatar
Stewart Brodie committed
37
   return _swix(Window_ExtractGadgetInfo, _INR(0,2) | _OUTR(0,1), 0,tm,id, p,l);
Neil Turton's avatar
Neil Turton committed
38 39 40 41 42 43
}

char *copy_template(char *name)
{
  char *tm;
  ObjectTemplateHeader *obj;
Stewart Brodie's avatar
Stewart Brodie committed
44
  if(_swix(Toolbox_TemplateLookUp, _INR(0,1) | _OUT(0),0,name,&obj)) tm = NULL;
Neil Turton's avatar
Neil Turton committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
  else {
    tm = mem_allocate(obj->total_size,"template copy");
    if(tm) {
      memcpy(tm,obj,obj->total_size);
      ((ObjectTemplateHeader *)tm)->body =
         (WindowTemplate *) (tm + ((int) ((WindowTemplate *) obj->body)) - ((int) obj));
      ((WindowTemplate *) (((ObjectTemplateHeader *)tm)->body))-> gadgets =
         (Gadget *) (tm + ((int) ((WindowTemplate *) obj->body)->gadgets) - ((int) obj));

    }
  }
  return tm;
}

_kernel_oserror *__zap_gadget(char *tm,ComponentID id,int off,int val)
{
   _kernel_oserror *e=NULL;
   int *p,l;
   e=extract_gadget_info(tm,id,(void **) &p,&l);
   if(!e) *(p+ off/sizeof(int)) = val;
   return e;

}

69 70 71 72 73 74 75 76 77 78
_kernel_oserror *__zap_gadget_string(char *tm,ComponentID id,int off,const char* val,int offlen)
{
   /* Zaps the string into the gadget template and checks the length against a length field
    * in the same template, increasing the value if necessary
    */
   int *p,l;
   _kernel_oserror *e=__zap_gadget(tm,id,off,(int)val);
   if (e) return e;
   e=extract_gadget_info(tm,id,(void **) &p,&l);
   if(!e) {
Stewart Brodie's avatar
Stewart Brodie committed
79
      int cl=*(p+ offlen/sizeof(int));
80 81 82 83 84 85 86
      int rl=string_length((char *)val)+1;
      if (cl<rl) e=__zap_gadget(tm,id,offlen,rl);
   }
   return e;

}

Neil Turton's avatar
Neil Turton committed
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
int *__read_gadget(char *tm,ComponentID id,int off)
{
   int *p,l;
   if (extract_gadget_info(tm,id,(void **)&p,&l) == NULL)
      return (p+ off/sizeof(int));
   else return 0;
}

_kernel_oserror *__zap_window(char *tm,int off,int val)
{
   char *p = (char *)((WindowTemplate *) (((ObjectTemplateHeader *)tm)->body));
   DEBUG debug_output("objsupport","zapping word +%x with %x\n",off,val);
   if ((((ObjectTemplateHeader *)tm)->version == 101) && (off >= offsetof(WindowTemplate,default_focus))) off -=24;
   * ((int *) (p+off)) =val;
   return NULL;
}

104
_kernel_oserror *create_from_template(char *template_id, ObjectID *handle)
Neil Turton's avatar
Neil Turton committed
105 106
{
   _kernel_oserror *er=NULL;
Stewart Brodie's avatar
Stewart Brodie committed
107
   if ((er=_swix(Toolbox_CreateObject, _INR(0,1) | _OUT(0),
Neil Turton's avatar
Neil Turton committed
108
       1,       /* flags */
109
       template_id,
Neil Turton's avatar
Neil Turton committed
110
       handle)) != NULL) {
111
           mem_free(template_id,"freeing template copy");
Neil Turton's avatar
Neil Turton committed
112 113 114
           return er;
       }

115
   mem_free(template_id,"freeing template copy");
Neil Turton's avatar
Neil Turton committed
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
   return NULL;
}

/* for word aligned overlapping areas */

static void _mem_cpy(char *a,char *b,int size)
{
  int *c=(int *)a;
  int *d=(int *)b;
  size = size/(sizeof(int));

  DEBUG debug_output("objsupport","Copying %d words from %x to %x\n",size,b,a);

  while (size>0) {
    size--;
    *c++ = *d++;
  }

}

_kernel_oserror *delete_gadget(char *tm,ComponentID id)
{
   _kernel_oserror *e=NULL;
   char *p;
   int l;
   ObjectTemplateHeader *obj = (ObjectTemplateHeader *)tm;

   e=extract_gadget_info(tm,id,(void **)&p,&l);
   if(!e) {
      DEBUG debug_output("objsupport","Deleting gadget from template: Template size %d, Gadget size %d\n",obj->total_size,l);
      DEBUG debug_output("objsupport","about to copy %d bytes\n",(obj->total_size) - (((int)p) - ((int)tm)) -l);
      _mem_cpy(p,p+l,(obj->total_size) - (((int)p) - ((int)tm)) -l);
      (obj->total_size) -= l;
      (((WindowTemplate *)obj->body)->num_gadgets) -= 1;
   }
   return e;

}

int *__read_window(char *tm,int off)
{
   char *p = (char *)((WindowTemplate *) (((ObjectTemplateHeader *)tm)->body));
   DEBUG debug_output("objsupport","reading word +%x \n",off);
   if ((((ObjectTemplateHeader *)tm)->version == 101) && (off >= offsetof(WindowTemplate,default_focus))) off -=24;
   return ((int *) (p+off));

}