home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / Demos / DE_MesaAR1 / Examples / API / MAPIDemoCode / MesaAPI.m < prev    next >
Encoding:
Text File  |  1992-07-09  |  16.2 KB  |  649 lines

  1. /**************************************************************************
  2.  *                                                                        *
  3.  *                                                                        *
  4.  *          This code is copyright (c) 1992                               *
  5.  *                     Athena Design, Inc.                                *
  6.  *                     and David Pollak                                   *
  7.  *                                                                        *
  8.  *                ALL RIGHTS RESERVED                                     *
  9.  *                                                                        *
  10.  *                                                                        *
  11.  *                                                                        *
  12.  *                                                                        *
  13.  *                                                                        *
  14.  **************************************************************************/
  15.  
  16. #import "MesaAPI.h"
  17. #import <servers/netname.h>
  18. #import <appkit/Listener.h>
  19. #import <libc.h>
  20. #import <streams/streams.h>
  21. #import <appkit/publicWraps.h>
  22. #import <dpsclient/dpsNeXT.h>
  23. #import <appkit/NXImage.h>
  24.  
  25. @implementation MesaAPI
  26.  
  27. - initToWorksheet:(const char *)ws
  28. {
  29.     kern_return_t r;
  30.     
  31.     [super init];
  32.     port_allocate(task_self(), &myPort);
  33.     r = netname_look_up(name_server_port,"","Mesa-MAPI-1",&mesaPort);
  34.     if (r != NETNAME_SUCCESS) {
  35.         if (NXPortFromName("Mesa", "")) {
  36.             r = netname_look_up(name_server_port,"","Mesa-MAPI-1",&mesaPort);
  37.             if (r != NETNAME_SUCCESS) {
  38.                 NXBeep();
  39.                 [self free];
  40.                 return NULL;
  41.                 }
  42.             }
  43.         else {
  44.             NXBeep();
  45.             [self free];
  46.             return NULL;
  47.             }
  48.         }
  49.  
  50.     theMessage.head.msg_simple = FALSE;
  51.     theMessage.head.msg_size = sizeof(MAPIMessage);
  52.     theMessage.head.msg_type = MSG_TYPE_NORMAL;
  53.     theMessage.head.msg_local_port = myPort;
  54.     theMessage.head.msg_remote_port = mesaPort;
  55.  
  56.     theMessage.lenType.msg_type_name = MSG_TYPE_INTEGER_32;
  57.     theMessage.lenType.msg_type_size = 32;
  58.     theMessage.lenType.msg_type_number = 1;
  59.     theMessage.lenType.msg_type_inline = TRUE;
  60.     theMessage.lenType.msg_type_longform = FALSE;
  61.     theMessage.lenType.msg_type_deallocate = FALSE;
  62.  
  63.     theMessage.handleType = theMessage.lenType;
  64.     
  65.     theMessage.dataType.msg_type_header.msg_type_name = MSG_TYPE_CHAR;
  66.     theMessage.dataType.msg_type_header.msg_type_size = 8;
  67.     theMessage.dataType.msg_type_header.msg_type_number = 1;
  68.     theMessage.dataType.msg_type_header.msg_type_inline = FALSE;
  69.     theMessage.dataType.msg_type_header.msg_type_longform = TRUE;
  70.     theMessage.dataType.msg_type_header.msg_type_deallocate = FALSE;
  71.     theMessage.dataType.msg_type_long_name = MSG_TYPE_CHAR;
  72.     theMessage.dataType.msg_type_long_size = 8;
  73.     theMessage.dataType.msg_type_long_number = 1;
  74.     
  75.     theMessage.handle = 0;
  76.     
  77.     if ([self sendMessage:openSheetMesaDo :(void *)ws :strlen((char *)ws)] != MAPISuccess) {
  78.         NXBeep();
  79.         [self free];
  80.         return NULL;
  81.         }
  82.         
  83.     if ([self receiveMessage] != MAPISuccess || theMessage.head.msg_id != MAPISuccess ||
  84.         !theMessage.handle) {
  85.         NXBeep();
  86.         [self free];
  87.         return NULL;
  88.         }
  89.         
  90.     return self;
  91.     }
  92.  
  93. - initToNewWorksheet
  94. {
  95.     kern_return_t r;
  96.     
  97.     [super init];
  98.     port_allocate(task_self(), &myPort);
  99.     r = netname_look_up(name_server_port,"","Mesa-MAPI-1",&mesaPort);
  100.     if (r != NETNAME_SUCCESS) {
  101.         if (NXPortFromName("Mesa", "")) {
  102.             r = netname_look_up(name_server_port,"","Mesa-MAPI-1",&mesaPort);
  103.             if (r != NETNAME_SUCCESS) {
  104.                 NXBeep();
  105.                 [self free];
  106.                 return NULL;
  107.                 }
  108.             }
  109.         else {
  110.             NXBeep();
  111.             [self free];
  112.             return NULL;
  113.             }
  114.         }
  115.  
  116.     theMessage.head.msg_simple = FALSE;
  117.     theMessage.head.msg_size = sizeof(MAPIMessage);
  118.     theMessage.head.msg_type = MSG_TYPE_NORMAL;
  119.     theMessage.head.msg_local_port = myPort;
  120.     theMessage.head.msg_remote_port = mesaPort;
  121.  
  122.     theMessage.lenType.msg_type_name = MSG_TYPE_INTEGER_32;
  123.     theMessage.lenType.msg_type_size = 32;
  124.     theMessage.lenType.msg_type_number = 1;
  125.     theMessage.lenType.msg_type_inline = TRUE;
  126.     theMessage.lenType.msg_type_longform = FALSE;
  127.     theMessage.lenType.msg_type_deallocate = FALSE;
  128.  
  129.     theMessage.handleType = theMessage.lenType;
  130.     
  131.     theMessage.dataType.msg_type_header.msg_type_name = MSG_TYPE_CHAR;
  132.     theMessage.dataType.msg_type_header.msg_type_size = 8;
  133.     theMessage.dataType.msg_type_header.msg_type_number = 1;
  134.     theMessage.dataType.msg_type_header.msg_type_inline = FALSE;
  135.     theMessage.dataType.msg_type_header.msg_type_longform = TRUE;
  136.     theMessage.dataType.msg_type_header.msg_type_deallocate = FALSE;
  137.     theMessage.dataType.msg_type_long_name = MSG_TYPE_CHAR;
  138.     theMessage.dataType.msg_type_long_size = 8;
  139.     theMessage.dataType.msg_type_long_number = 1;
  140.     
  141.     theMessage.handle = 0;
  142.     
  143.     if ([self sendMessage:newSheetMesaDo :NULL :0] != MAPISuccess) {
  144.         NXBeep();
  145.         [self free];
  146.         return NULL;
  147.         }
  148.         
  149.     if ([self receiveMessage] != MAPISuccess || theMessage.head.msg_id != MAPISuccess ||
  150.         !theMessage.handle) {
  151.         NXBeep();
  152.         [self free];
  153.         return NULL;
  154.         }
  155.         
  156.     return self;
  157.     }
  158.  
  159. - (int)saveSheet
  160. {
  161.     int theError;
  162.     
  163.     theError = [self sendMessage:saveMesaDo :NULL :0];
  164.     if (theError == MAPISuccess) theError = [self receiveMessage];
  165.     return theError;
  166.     }
  167.     
  168. - (int)saveSheetAs:(const char *)name
  169. {
  170.     int theError;
  171.     
  172.     theError = [self sendMessage:saveAsMesaDo :(void *)name :strlen(name) + 1];
  173.     if (theError == MAPISuccess) theError = [self receiveMessage];
  174.     
  175.     return theError;
  176.     }
  177.     
  178. - (int)hide
  179. {
  180.     int theError;
  181.     
  182.     theError = [self sendMessage:hideMesaDo :NULL :0];
  183.     if (theError == MAPISuccess) theError = [self receiveMessage];
  184.     return theError;
  185.     }
  186.     
  187. - (int)makeKeyAndOrderFront
  188. {
  189.     int theError;
  190.     
  191.     theError = [self sendMessage:orderFrontMesaDo :NULL :0];
  192.     if (theError == MAPISuccess) theError = [self receiveMessage];
  193.     return theError;
  194.     }
  195.  
  196. - (int)sendMessage:(int)m :(void *)data :(int)len
  197. {
  198.     kern_return_t r;
  199.     
  200.     theMessage.head.msg_local_port = myPort;
  201.     theMessage.head.msg_remote_port = mesaPort;
  202.  
  203.     theMessage.head.msg_id = m;
  204.     theMessage.theLen = len;
  205.     theMessage.dataType.msg_type_long_number = len;
  206.     if (data) theMessage.theData = data;
  207.     else theMessage.theData = "";
  208.     
  209.     r = msg_send((msg_header_t *) &theMessage,SEND_TIMEOUT, 30000);
  210.     if (r != SEND_SUCCESS) return MAPISendError;
  211.     
  212.     return MAPISuccess;
  213.     }
  214.  
  215. - (int)receiveMessage
  216. {
  217.     kern_return_t r;
  218.  
  219.     r = msg_receive((msg_header_t *) &theMessage,RCV_TIMEOUT, 30000);
  220.     if (r != RCV_SUCCESS) return MAPIReceiveError;
  221.     
  222.     return MAPISuccess;
  223.     }
  224.         
  225. - free
  226. {
  227.     if (theMessage.handle) {
  228.         [self sendMessage:unlinkSheetMesaDo :NULL :0];
  229.         [self receiveMessage];
  230.         }
  231.         
  232.     port_deallocate(task_self(), myPort);
  233.     return [super free];
  234.     }
  235.     
  236. - (int)recalc
  237. {
  238.     if ([self sendMessage:recalcMesaDo :NULL :0] != MAPISuccess) return MAPISendError;
  239.     if ([self receiveMessage] != MAPISuccess) return MAPIReceiveError;
  240.     return theMessage.head.msg_id;
  241.     }
  242.  
  243. - (int)displaySheet
  244. {
  245.     if ([self sendMessage:displayMesaDo :NULL :0] != MAPISuccess) return MAPISendError;
  246.     if ([self receiveMessage] != MAPISuccess) return MAPIReceiveError;
  247.     return theMessage.head.msg_id;
  248.     }
  249.  
  250. void freeMAPIValue(int n,MAPIValue *v)
  251. {
  252.     int x;
  253.     MAPIValue *v1 = v;
  254.     
  255.     for (x = 0; x < n; x++,v++) if (v -> type == stringMAPIValue) free(v -> values.string);
  256.     if (v1) free(v1);
  257.     }
  258.  
  259. static void addString(NXStream *ns,const char *s)
  260. {
  261.     int x;
  262.     
  263.     if (!s) x = -1;
  264.     else x = strlen(s);
  265.     NXWrite(ns,&x,sizeof(int));
  266.     
  267.     if (x > 0) NXWrite(ns,s,x);
  268.     }
  269.  
  270. static void addValue(NXStream *ns, MAPIValue *v)
  271. {
  272.     NXWrite(ns,&(v -> type),sizeof(int));
  273.     NXWrite(ns,&(v -> row),sizeof(short));
  274.     NXWrite(ns,&(v -> col),sizeof(short));
  275.     switch (v -> type) {
  276.         case stringMAPIValue:
  277.             addString(ns,v -> values.string);
  278.             break;
  279.             
  280.         case numberMAPIValue:
  281.             NXWrite(ns,&(v -> values.number),sizeof(double));
  282.             break;
  283.         
  284.         case errorMAPIValue:
  285.             NXWrite(ns,&(v -> values.error),sizeof(double));
  286.             break;
  287.         }
  288.     }
  289.             
  290. static char *getString(NXStream *ns)
  291. {
  292.     int x;
  293.     char *s;
  294.     
  295.     NXRead(ns,&x,sizeof(int));
  296.     if (x == -1) return NULL;
  297.     s = malloc(malloc_good_size(x + 5));
  298.     if (x) NXRead(ns,s,x);
  299.     s[x] = 0;
  300.     return s;
  301.     }
  302.  
  303. static void getValue(NXStream *ns,MAPIValue *mv)
  304. {
  305.     NXRead(ns,&(mv -> type),sizeof(int));
  306.     NXRead(ns,&(mv -> row),sizeof(short));
  307.     NXRead(ns,&(mv -> col),sizeof(short));
  308.     
  309.     switch (mv -> type) {
  310.         case stringMAPIValue:
  311.             mv -> values.string = getString(ns);
  312.             break;
  313.             
  314.         case numberMAPIValue:
  315.             NXRead(ns,&(mv -> values.number),sizeof(double));
  316.             break;
  317.         
  318.         case errorMAPIValue:
  319.             NXRead(ns,&(mv -> values.error),sizeof(double));
  320.             break;
  321.         }
  322.     }
  323.         
  324. - (int)associateLabel:(const char *)l withItems:(char **)it andValues:(MAPIValue *)mv
  325.     offset:(int)off numItems:(int)ni orientation:(int)or;
  326. {
  327.     NXStream *ns;
  328.     char *ad;
  329.     int len,maxLen,theError = MAPISuccess;
  330.     int x;
  331.     
  332.     ns = NXOpenMemory(NULL,0, NX_WRITEONLY);
  333.  
  334.     NXWrite(ns, &ni, sizeof(int));
  335.     NXWrite(ns, &or, sizeof(int));
  336.     NXWrite(ns, &off, sizeof(int));
  337.     addString(ns, l);
  338.     for (x = 0; x < ni; x++) {
  339.         addString(ns, it[x]);
  340.         addValue(ns, &mv[x]);
  341.         }
  342.     
  343.     NXGetMemoryBuffer(ns, &ad, &len, &maxLen);
  344.     theError = [self sendMessage:associateMesaDo :ad :len];
  345.     NXCloseMemory(ns, NX_FREEBUFFER);
  346.     if (theError == MAPISuccess) theError = [self receiveMessage];
  347.  
  348.     if (theError == MAPISuccess) theError = theMessage.head.msg_id;
  349.      
  350.     return theError;
  351.     }
  352.  
  353. - (int)getValues:(MAPIValue **)mv num:(int *)n
  354.     upperRow:(int)ur col:(int)uc lowerRow:(int)lr col:(int)lc
  355. {
  356.     int theError;
  357.     NXStream *ns;
  358.     int x;
  359.     short range[4];
  360.     
  361.     range[0] = ur;
  362.     range[1] = uc;
  363.     range[2] = lr;
  364.     range[3] = lc;
  365.     
  366.     theError = [self sendMessage:getLabelRangeMesaDo :range :sizeof(short) * 4];
  367.     if (theError == MAPISuccess && (theError = [self receiveMessage]) == MAPISuccess &&
  368.         (theError = theMessage.head.msg_id) == MAPISuccess) {
  369.         ns = NXOpenMemory(theMessage.theData,theMessage.theLen,NX_READONLY);
  370.         
  371.         NXRead(ns,n,sizeof(int));
  372.         NXRead(ns,&x,sizeof(int));
  373.         NXRead(ns,&x,sizeof(int));
  374.         NXRead(ns,&x,sizeof(int));
  375.         NXRead(ns,&x,sizeof(int));
  376.         
  377.         if (*n) {
  378.             *mv = malloc(malloc_good_size(*n * sizeof(MAPIValue)));
  379.             for (x = 0; x < *n; x++) getValue(ns,(*mv) + x);
  380.             }
  381.         else *mv = NULL;
  382.         
  383.         NXCloseMemory(ns, NX_FREEBUFFER);
  384.         }
  385.     
  386.     if (theError == MAPISuccess && theMessage.theData) vm_deallocate(task_self(),(vm_address_t)
  387.         theMessage.theData,theMessage.theLen);
  388.     theMessage.theData = NULL;
  389.     theMessage.theLen = 0;
  390.     
  391.     return theError;
  392.     }
  393.  
  394. - (int)printReport:(char *)r
  395. {    
  396.     int theError;
  397.     
  398.     theError = [self sendMessage:printReportMesaDo :r :strlen(r) + 1];
  399.     if (theError == MAPISuccess && (theError = [self receiveMessage]) == MAPISuccess)
  400.         theError = theMessage.head.msg_id;
  401.                 
  402.     return theError;
  403.     }
  404.  
  405. - (int)getEPSForLabel:(char *)l in:(id *)vp
  406. {    
  407.     NXStream *ns;
  408.     int theError;
  409.     
  410.     *vp = NULL;
  411.     theError = [self sendMessage:getEPSForLabelMesaDo :l :strlen(l) + 1];
  412.     if (theError == MAPISuccess && (theError = [self receiveMessage]) == MAPISuccess &&
  413.         (theError = theMessage.head.msg_id) == MAPISuccess) {
  414.         ns = NXOpenMemory(theMessage.theData,theMessage.theLen,NX_READONLY);
  415.         *vp = [[NXImage alloc] initFromStream:ns];
  416.         [*vp setDataRetained:YES];
  417.         NXCloseMemory(ns, NX_FREEBUFFER);
  418.         }
  419.         
  420.     return theError;
  421.     }
  422.     
  423. - (int)getEPSForUpperRow:(int)ur col:(int)uc lowerRow:(int)lr col:(int)lc in:(id *)vp
  424. {
  425.     NXStream *ns;
  426.     short range[4];
  427.     int theError;
  428.     
  429.     range[0] = ur;
  430.     range[1] = uc;
  431.     range[2] = lr;
  432.     range[3] = lc;
  433.  
  434.     *vp = NULL;
  435.     theError = [self sendMessage:getEPSForRangeMesaDo :range :sizeof(short) * 4];
  436.     if (theError == MAPISuccess && (theError = [self receiveMessage]) == MAPISuccess &&
  437.         (theError = theMessage.head.msg_id) == MAPISuccess) {
  438.         ns = NXOpenMemory(theMessage.theData,theMessage.theLen,NX_READONLY);
  439.         *vp = [[NXImage alloc] initFromStream:ns];
  440.         [*vp setDataRetained:YES];
  441.         NXCloseMemory(ns, NX_FREEBUFFER);
  442.         }
  443.         
  444.     return theError;
  445.     }
  446.     
  447. - (int)getEPSForGraph:(char *)l in:(id *)vp
  448. {    
  449.     NXStream *ns;
  450.     int theError;
  451.  
  452.     *vp = NULL;
  453.     theError = [self sendMessage:getEPSForGraphMesaDo :l :strlen(l) + 1];
  454.     if (theError == MAPISuccess && (theError = [self receiveMessage]) == MAPISuccess &&
  455.         (theError = theMessage.head.msg_id) == MAPISuccess) {
  456.         ns = NXOpenMemory(theMessage.theData,theMessage.theLen,NX_READONLY);
  457.         *vp = [[NXImage alloc] initFromStream:ns];
  458.         [*vp setDataRetained:YES];
  459.         NXCloseMemory(ns, NX_FREEBUFFER);
  460.         }
  461.         
  462.     return theError;
  463.     }
  464.     
  465.  
  466. - (int)getValues:(MAPIValue **)mv  forLabel:(const char *)l num:(int *)n
  467.     upperRow:(int *)ur col:(int *)uc lowerRow:(int *)lr col:(int *)lc
  468. {
  469.     int theError;
  470.     NXStream *ns;
  471.     int x;
  472.     
  473.     theError = [self sendMessage:getLabelRangeMesaDo :(char *)l :strlen((char *)l) + 1];
  474.     if (theError == MAPISuccess && (theError = [self receiveMessage]) == MAPISuccess &&
  475.         (theError = theMessage.head.msg_id) == MAPISuccess) {
  476.         ns = NXOpenMemory(theMessage.theData,theMessage.theLen,NX_READONLY);
  477.         
  478.         NXRead(ns,n,sizeof(int));
  479.         NXRead(ns,ur,sizeof(int));
  480.         NXRead(ns,uc,sizeof(int));
  481.         NXRead(ns,lr,sizeof(int));
  482.         NXRead(ns,lc,sizeof(int));
  483.         
  484.         if (*n) {
  485.             *mv = malloc(malloc_good_size(*n * sizeof(MAPIValue)));
  486.             for (x = 0; x < *n; x++) getValue(ns,(*mv) + x);
  487.             }
  488.         else *mv = NULL;
  489.         
  490.         NXCloseMemory(ns, NX_FREEBUFFER);
  491.         }
  492.     
  493.     if (theError == MAPISuccess && theMessage.theData) vm_deallocate(task_self(),(vm_address_t)
  494.         theMessage.theData,theMessage.theLen);
  495.     theMessage.theData = NULL;
  496.     theMessage.theLen = 0;
  497.     
  498.     return theError;
  499.     }
  500.  
  501. - (int)getLabels:(char ***)lp ranges:(short **)r num:(int *)num
  502. {
  503.     int theError;
  504.     NXStream *ns;
  505.     int x;
  506.     char **tlp;
  507.     short *sp;
  508.     
  509.     theError = [self sendMessage:getLabelsMesaDo :NULL :0];
  510.     if (theError == MAPISuccess && (theError = [self receiveMessage]) == MAPISuccess &&
  511.         (theError = theMessage.head.msg_id) == MAPISuccess) {
  512.         ns = NXOpenMemory(theMessage.theData,theMessage.theLen,NX_READONLY);
  513.         
  514.         NXRead(ns,num,sizeof(int));
  515.         
  516.         if (*num) {
  517.             tlp = *lp = malloc(malloc_good_size(*num * sizeof(char *)));
  518.             sp = *r = malloc(malloc_good_size(*num * 4 * sizeof(short)));
  519.             
  520.             for (x = 0; x < *num; x++) {
  521.                 tlp[x] = getString(ns);
  522.                 NXRead(ns,sp++,sizeof(short));
  523.                 NXRead(ns,sp++,sizeof(short));
  524.                 NXRead(ns,sp++,sizeof(short));
  525.                 NXRead(ns,sp++,sizeof(short));
  526.                 }
  527.             }
  528.         else {
  529.             *lp = NULL;
  530.             *r = NULL;
  531.             }
  532.         
  533.         NXCloseMemory(ns, NX_FREEBUFFER);
  534.         }
  535.     
  536.     if (theError == MAPISuccess && theMessage.theData) vm_deallocate(task_self(),(vm_address_t)
  537.         theMessage.theData,theMessage.theLen);
  538.     theMessage.theData = NULL;
  539.     theMessage.theLen = 0;
  540.     
  541.     return theError;
  542.     }
  543.  
  544. - (int)putValues:(MAPIValue *)mv num:(int)n
  545.     upperRow:(int)ur col:(int)uc lowerRow:(int)lr col:(int)lc
  546. {
  547.     NXStream *ns;
  548.     char *ad;
  549.     int len,maxLen,theError = MAPISuccess;
  550.     int x;
  551.     short r,c;
  552.     
  553.     ns = NXOpenMemory(NULL,0, NX_WRITEONLY);
  554.  
  555.     NXWrite(ns, &n, sizeof(int));
  556.     r = ur;
  557.     c = uc;
  558.     NXWrite(ns, &r, sizeof(short));
  559.     NXWrite(ns, &c, sizeof(short));
  560.     r = lr;
  561.     c = lc;
  562.     NXWrite(ns, &r, sizeof(short));
  563.     NXWrite(ns, &c, sizeof(short));
  564.     
  565.     for (x = 0; x < n; x++) addValue(ns,mv + x);
  566.     
  567.     NXGetMemoryBuffer(ns, &ad, &len, &maxLen);
  568.     theError = [self sendMessage:putRangeMesaDo :ad :len];
  569.     NXCloseMemory(ns, NX_FREEBUFFER);
  570.     if (theError == MAPISuccess) theError = [self receiveMessage];
  571.  
  572.     if (theError == MAPISuccess) theError = theMessage.head.msg_id;
  573.      
  574.     return theError;
  575.     }
  576.  
  577. @end
  578.  
  579. @implementation MesaListen
  580.  
  581. void MesaListenHandler(msg_header_t *vm,id mp)
  582. {
  583.     NXStream *ns;
  584.     int num,ur,uc,lr,lc,x;
  585.     MAPIValue *mv;
  586.     
  587.     MAPIMessage *msg = (MAPIMessage *) vm;
  588.  
  589.     ns = NXOpenMemory(msg -> theData,msg -> theLen,NX_READONLY);
  590.     
  591.     NXRead(ns,&num,sizeof(int));
  592.     NXRead(ns,&ur,sizeof(int));
  593.     NXRead(ns,&uc,sizeof(int));
  594.     NXRead(ns,&lr,sizeof(int));
  595.     NXRead(ns,&lc,sizeof(int));
  596.     
  597.     if (num) {
  598.         mv = malloc(malloc_good_size(num * sizeof(MAPIValue)));
  599.         for (x = 0; x < num; x++) getValue(ns,mv + x);
  600.         }
  601.     else mv = NULL;
  602.     
  603.     NXCloseMemory(ns, NX_FREEBUFFER);
  604.     
  605.     [mp gotMessage:mv num:num forUpperRow:ur upperCol:uc lowerRow:lr lowerCol:lc];
  606.     
  607.     freeMAPIValue(num,mv);
  608.     
  609.     if (msg -> theData) vm_deallocate(task_self(),(vm_address_t) msg -> theData, msg -> theLen);
  610.     }
  611.  
  612.  
  613. - initToPort:(char *)s
  614. {
  615.     kern_return_t r;
  616.  
  617.     [super init];
  618.         
  619.     portName = malloc(malloc_good_size(strlen(s) + 5));
  620.     strcpy(portName,s);
  621.     
  622.     r = port_allocate(task_self(), &myPort);
  623.     r = netname_check_in(name_server_port,portName,PORT_NULL, myPort);
  624.     DPSAddPort(myPort,(DPSPortProc) MesaListenHandler,1024,self,30);
  625.  
  626.     return self;
  627.     }
  628.     
  629. - free
  630. {
  631.     kern_return_t r;
  632.  
  633.     DPSRemovePort(myPort);
  634.     r = netname_check_out(name_server_port,portName,PORT_NULL);
  635.     r = port_deallocate(task_self(), myPort);
  636.  
  637.     free(portName);
  638.     
  639.     return [super free];
  640.     }
  641.     
  642. - gotMessage:(MAPIValue *)mv num:(int)num forUpperRow:(int)ur upperCol:(int)uc lowerRow:(int)lr
  643.     lowerCol:(int)lc
  644. {
  645.     return self;
  646.     }
  647.  
  648. @end
  649.