/* CLI utility library interface routines */!!

inherit(ProvidedLibs, #CLIULibrary, #(counter), 2, nil)!!

now(class(CLIULibrary))!!

/* semiPRIVATE -- should only be called via require(CLIULibrary)
   Define entry points and load library.  Define any structs required.
*/
Def provide(self, path)
{
  ^initialise( new(self:ancestor), path )
}
!!

now(CLIULibrary)!!


/* 12/12/1995 18:29 */
/* Write text to the login screen */
Def writeTextToLogin(self, text)
{
  if pcallLock(self)
    lastError := pcall(procs[#SETLOADINGDLLNAME], asciiz(text));
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
}!!

/* get powerviews version info */
Def getPVVersionString(self | array)
{
  array := getPVVersion(self);
  if not(array) cor (size(array) <> 5)
    ^nil;
  endif;
  
  /* return "<major>.<minor><bug> <string> build <build>" */
  ^(asString(array[0]) + "." + asString(array[1]) + asString(array[2]) +
    " " + asString(array[3]) + " build " + asString(array[4])); 
}!!

/* get powerviews version info */
Def getPVVersion(self | w1 w2 b1 s1 w3 return)
{
  w1 := new(Struct, 2); /* major */
  w2 := new(Struct, 2); /* minor */
  b1 := new(Struct, 1); /* bug */
  s1 := new(Struct, 256);  /* string */
  w3 := new(Struct, 2); /* build */
  if pcallLock(self)
    lastError := pcall(procs[#GETPOWERVIEWSVERSION], w1, w2, b1, s1, w3);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  
  if (lastError = 0)
    return := new(Array, 5);
    return[0] := wordAt(w1, 0);
    return[1] := wordAt(w2, 0);
    return[2] := asChar(byteAt(b1, 0));
    /* make sure it is not a NULL string */
    if (longAt(s1, 0) = 0)
      return[3] := "";
    else
      return[3] := removeNulls(physicalString(s1)); 
    endif;
    return[4] := wordAt(w3, 0);
    ^return;
  else
    ^nil
  endif;
}!!

/* 6/28/1994 14:44 - PUBLIC 
  return fileName string from the OPENFILE/SAVEFILE dialog box
  if error return nil;
  
  Usage:
     getFileName(CLIULibraryClass$Inst, self, HE_xxxx_xxxx,
                 IDS_xxx_FILTER, "c:\*.*", FILE_OPEN|FILE_SAVE);
                    
  For <filterId> - see /res/wdlgrsc.h for more information.
                 
*/
Def getFileName(self, parent, helpId, filterId, initPath, openDlg 
  | fileNameRef)
{ 
  if not(initPath)
    initPath := "";
  endif;
  /* allocate string buffer */
  fileNameRef := new(Struct, 256);

  lastError := GOOD;
  if pcallLock(self)
    lastError := pcall(procs[#COMMDLGGETFILENAME], 
      asLong(getHWnd(parent)), helpId, filterId, 
      asciiz(initPath),
      asInt(openDlg), 
      fileNameRef);     
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  
  if (lastError <> GOOD)
    if (lastError <> ER_USER_ABORT) 
      displayError(ErrorTextLibClass$Inst,lastError, CHECK_MODE);
    endif;  
    ^nil;
  endif;
  /* make sure it is not a NULL string */
  if (longAt(fileNameRef, 0) = 0) then
    ^nil;
  endif;     
  /* return the string */
  ^removeNulls(physicalString(fileNameRef)); 
}
!!

/* 2/4/1992 17:06 */
Def addImportProcs(self)
{
  add(self, #INITCSERVER,        1, #(0, 0));
  add(self, #CLIRIGHTSHIFT,      1, #(1, 1, 1));
  add(self, #CLILEFTSHIFT,       1, #(1, 1, 1));
  add(self, #CLIBITWISENEGATION, 1, #(1, 1));
  add(self, #CLISETACTIVE,       1, #(0));
  add(self, #CLICLEARACTIVE,     1, nil);
  add(self, #CLIGETACTIVE,       1, #(1));
  add(self, #UNIXOPENFILE,       1, #(1, 1));
  add(self, #ABOUTBOX,           1, #(1));
  add(self, #OPENLOGIN,          1, #());
  add(self, #CLOSELOGIN,         1, #());
  add(self, #HOOKF1FILTER,       1, #());
  add(self, #UNHOOKF1FILTER,     1, #());
  add(self, #REGISTERHELPENTRY,  1, #(0, 1, 0));
  add(self, #SAVETOOLBARHANDLE,  1, #(1));
  add(self, #COMMDLGGETFILENAME, 1, #(1, 0, 0, 1, 0, 1));
  add(self, #GETPOWERVIEWSVERSION, 1, #(1, 1, 1, 1, 1));
  add(self, #SETLOADINGDLLNAME,   1, #(1));
}!!

/* bitwise negation; ~a */
Def bitwiseNegation(self, a | a2Ref)
{
  a2Ref := new(Struct, 4);
  if pcallLock(self)
    lastError := pcall(procs[#CLIBITWISENEGATION], asLong(a), a2Ref);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);

  if (lastError = 0)
    ^longAt(a2Ref, 0);
  else
    ^nil
  endif;
}!!

/* CLI is inactive*/
Def clearCliActive(self)
{
  if pcallLock(self)
    lastError := pcall(procs[#CLICLEARACTIVE]);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  
  if (lastError = 0)
    ^0;
  else
    ^nil
  endif;
}!!

/* get CLI active value */
Def getCliActive(self | wordRef)
{
  wordRef := new(Struct, 2);
  if pcallLock(self)
    lastError := pcall(procs[#CLIGETACTIVE], wordRef);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  
  if (lastError = 0)
    ^wordAt(wordRef, 0);
  else
    ^nil
  endif;
}!!

/* left shift; a1 << a2 */
Def leftShift(self, a1, a2 | a3Ref)
{
  a3Ref := new(Struct, 4);
  if pcallLock(self)
    lastError := pcall(procs[#CLILEFTSHIFT], asLong(a1), asLong(a2), a3Ref);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);

  if (lastError = 0)
    ^longAt(a3Ref, 0);
  else
    ^nil
  endif;
}!!

/* right shift; a1 >> a2 */
Def rightShift(self, a1, a2 | a3Ref)
{
  a3Ref := new(Struct, 4);
  if pcallLock(self)
    lastError := pcall(procs[#CLIRIGHTSHIFT], asLong(a1), asLong(a2), a3Ref);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);

  if (lastError = 0)
    ^longAt(a3Ref, 0);
  else
    ^nil
  endif;
}!!

/* CLI is active*/
Def setCliActive(self)
{
  if pcallLock(self)
    lastError := pcall(procs[#CLISETACTIVE], getCliServerHandle(CliServer));
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;

  if (lastError = 0)
    ^0;
  else
    ^nil
  endif;
}!!

/* Open the UNIX file; return the hand */
Def unixOpenFile(self, fileName |
      dummyFile dummyTextFile handleRef dummyFile count)
{
  handleRef := new(Struct, 2);
  if pcallLock(self)
    lastError := pcall(procs[#UNIXOPENFILE], asciiz(fileName), handleRef);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  displayError(ErrorTextLibClass$Inst, lastError, CHECK_MODE);

  if (lastError = 0)
    /* create a File object in order to fill TextFile buffer */
    dummyFile := new(File);
    dummyFile.handle := wordAt(handleRef, 0);  /* DOS handle */
    /* create text file */
    dummyTextFile := new(TextFile);
    setDelimiter(dummyTextFile, asString(asChar(10)));  /* UNIX newline */
    setName(dummyTextFile, fileName);  /* stuff name */
    dummyTextFile.handle := wordAt(handleRef, 0);  /* DOS handle */
    dummyTextFile.readable := 0;    /* readable */
    dummyTextFile.writeable := nil;  /* not writable */
    /* initialize buffer with nulls, then read in up to 512 bytes */
    dummyTextFile.buffer :=
      replicate(asString(asChar(0)), dummyTextFile.bufLen);
    count :=
      bRead(dummyFile, dummyTextFile.buffer, dummyTextFile.bufLen);
    ^dummyTextFile;
  else
    ^nil;
  endif;
}!!

/* display About Box */
Def showAboutBox(self | parent)
{
  lastError := GOOD;
  if (not(TheToolBarPresenter)) then
     parent := getHWnd(ThePort);
  else
     parent := getHWnd(TheToolBarPresenter);
  endif;
  if pcallLock(self)
    lastError := pcall(procs[#ABOUTBOX], asLong(parent));
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  ^lastError;
}!!

/* display Login bitmap */
Def openLogin(self)
{
  lastError := GOOD;
  if pcallLock(self)
    lastError := pcall(procs[#OPENLOGIN]);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  ^lastError;
}!!

/* remove Login bitmap */
Def closeLogin(self)
{
  lastError := GOOD;
  if pcallLock(self)
    lastError := pcall(procs[#CLOSELOGIN]);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  ^lastError;
}!!

/* Install F1 Windows Hook */
Def f1hook(self)
{
  lastError := GOOD;
  if pcallLock(self)
    lastError := pcall(procs[#HOOKF1FILTER]);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  ^lastError;
}!!

/* Un-Install F1 Windows Hook */
Def f1unhook(self)
{
  lastError := GOOD;
  if pcallLock(self)
    lastError := pcall(procs[#UNHOOKF1FILTER]);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  ^lastError;
}!!

/* Register a help entry for the F1 hook */
Def registerF1Help(self, hInd, hWnd, helpEntry)
{
  lastError := GOOD;
  if pcallLock(self)
    lastError := pcall(procs[#REGISTERHELPENTRY], hInd, asLong(hWnd), helpEntry);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  ^lastError;
}!!

/* save the tool bar handle, for DLLs to send messages to */
Def saveToolBarHandle(self, hToolBar)
{
  lastError := GOOD;
  if pcallLock(self)
    lastError := pcall(procs[#SAVETOOLBARHANDLE], asLong(hToolBar));
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;
  ^lastError;
}!!
