KeymapSwitcher: prefs.c

// PREFS.C
//#define _DEBUG_
 
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/keymap.h>
#include <proto/window.h>
#include <proto/layout.h>
#include <proto/label.h>
#include <proto/listbrowser.h>
#include <proto/string.h>
#include <proto/iffparse.h>
 
#include <classes/window.h>
#include <classes/requester.h>
#include <gadgets/string.h>
#include <prefs/prefhdr.h>
#include <prefs/input.h>
#include "dockybase.h"
#include "prefs.h"
 
#include <stdlib.h>
//#include "string.h"
 
#include "KeyMapSwitcher_rev.h"
 
Object *win;
struct List listbrowser_list;
struct Node *node = NULL;
struct ColumnInfo *columninfo;
uint32 wsigmask = 0;
 
 
void ReadInputPrefsKeymap(STRPTR keymap)
{
 struct IFFHandle *iffhandle;
 struct StoredProperty *sp;
 int32 ifferror;
 
 IUtility->Strlcpy(keymap, "usa1", 64); // default keymap
 
 if( (iffhandle = IIFFParse->AllocIFF()) )
 {
  // Open the file for reading
  if((iffhandle->iff_Stream = (int32)IDOS->Open("ENV:Sys/input.prefs", MODE_OLDFILE)) )
  {
   IIFFParse->InitIFFasDOS(iffhandle); // initialize the iff handle
   if( (ifferror = IIFFParse->OpenIFF(iffhandle, IFFF_READ)) == 0 )
   {
    IIFFParse->PropChunk(iffhandle, ID_PREF, ID_INPT);
    for(;;)
    {
     ifferror = IIFFParse->ParseIFF(iffhandle, IFFPARSE_STEP);
 
     if( (sp = IIFFParse->FindProp(iffhandle, ID_PREF, ID_INPT)) )
     {
      IUtility->Strlcpy(keymap, ((struct InputPrefs *)sp->sp_Data)->ip_KeymapName, 64);
      break;
     }
    }
 
    IIFFParse->CloseIFF(iffhandle);
   }
 
   IDOS->Close(iffhandle->iff_Stream);
   }
   else IDOS->Printf("'input.prefs' not found, using default keymap.\n");
 
   IIFFParse->FreeIFF(iffhandle);
   }
#ifdef _DEBUG_
IDOS->Printf("ReadInputPrefsKeymap(): '%s'\n",keymap);
#endif
}
 
 
void DoMessage(char *message, char reqtype, struct DockyData *dd)
{
 Object *requester = IIntuition->NewObject(NULL, "requester.class",
                                  REQ_Image, reqtype,
                                  REQ_TitleText, IDOS->FilePart(dd->filename),
                                  REQ_BodyText, message,
                                  REQ_GadgetText, "OK",
                                 TAG_DONE);
 
 IIntuition->IDoMethod(requester, RM_OPENREQ, NULL, NULL, dd->scr);
 IIntuition->DisposeObject(requester);
}
 
 
int OpenPrefsWindow(struct DockyData *dd)
{
 struct Window *window;
 STRPTR keymapdesc;
 APTR KM_handle;
 
 if( !scanfiles("KEYMAPS:") ) DoMessage("Error scanning 'KEYMAPS:'", REQIMAGE_ERROR, dd);
 
 // get keymap1 (input prefs.) description
 KM_handle = IKeymap->OpenKeyMapHandle(dd->keymap1Name, NULL);
 IKeymap->ObtainKeyMapInfo(KM_handle, KEYMAPINFO_INFOTEXT_ENGLISH,&keymapdesc,
                          TAG_END);
 IKeymap->CloseKeyMapHandle(KM_handle);
 
 columninfo = IListBrowser->AllocLBColumnInfo(2,
                             LBCIA_Column,0, LBCIA_Title," Keymap", LBCIA_AutoSort,TRUE, LBCIA_Sortable,TRUE,
                             LBCIA_Column,1, LBCIA_Title," Description",
                            TAG_DONE);
 
 win = IIntuition->NewObject(NULL, "window.class",
         WA_ScreenTitle,  VERS" "DATE,
         WA_Title,        "KeymapSwitcher: Settings",
         WA_DragBar,      TRUE,
         WA_CloseGadget,  TRUE,
         WA_SizeGadget,   TRUE,
         WA_DepthGadget,  TRUE,
         WA_Activate,     TRUE,
         WA_InnerWidth,   360,
         WA_InnerHeight,  300,
         WINDOW_Position, WPOS_CENTERSCREEN,
         WINDOW_Layout, IIntuition->NewObject(NULL, "layout.gadget",
                LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
                LAYOUT_SpaceOuter,  TRUE,
                //LAYOUT_DeferLayout, TRUE,
 
                LAYOUT_AddChild, IIntuition->NewObject(NULL, "layout.gadget",
                       LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
                       LAYOUT_SpaceOuter,  TRUE,
                       LAYOUT_BevelStyle,  BVS_GROUP,
                       LAYOUT_Label,       "Input Preferences Keymap",
                LAYOUT_AddChild, IIntuition->NewObject(NULL, "string.gadget",
                       GA_ReadOnly,     TRUE,
                       STRINGA_TextVal, dd->keymap1Name,
                      TAG_DONE),
                      CHILD_WeightedWidth, 40,
                LAYOUT_AddChild, IIntuition->NewObject(NULL, "string.gadget",
                       GA_ReadOnly,     TRUE,
                       STRINGA_TextVal, keymapdesc,
                      TAG_DONE),
                      CHILD_WeightedWidth, 60,
                TAG_DONE),
                CHILD_WeightedHeight, 0,
 
                LAYOUT_AddChild, IIntuition->NewObject(NULL, "layout.gadget",
                       LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
                       LAYOUT_SpaceOuter,  TRUE,
                       LAYOUT_BevelStyle,  BVS_GROUP,
                       LAYOUT_Label,       "Keymap2 (tooltype)",
                LAYOUT_AddChild, OBJ(OBJ_LISTBROWSER) = IIntuition->NewObject(NULL, "listbrowser.gadget",
                       GA_ID,                    OBJ_LISTBROWSER,
                       LISTBROWSER_SortColumn,   0,
                       LISTBROWSER_AutoFit,      TRUE,
                       LISTBROWSER_Labels,       &listbrowser_list,
                       LISTBROWSER_ColumnInfo,   columninfo,
                       LISTBROWSER_ColumnTitles, TRUE,
                       LISTBROWSER_ShowSelected, TRUE,
                       //LISTBROWSER_Selected,     -1,
                       LISTBROWSER_MinVisible,   6,
                       LISTBROWSER_Striping,     LBS_ROWS,
                      TAG_DONE),
                TAG_DONE),
 
                LAYOUT_AddChild, IIntuition->NewObject(NULL, "layout.gadget",
                       LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
                       LAYOUT_SpaceOuter,  TRUE,
                LAYOUT_AddChild, IIntuition->NewObject(NULL, "button.gadget",
                       GA_Text,      "_Save",
                       GA_ID,        OBJ_SAVE,
                       GA_RelVerify, TRUE,
                      TAG_DONE),
                LAYOUT_AddChild, IIntuition->NewObject(NULL, "button.gadget",
                       GA_Text,      "_Use",
                       GA_ID,        OBJ_USE,
                       GA_RelVerify, TRUE,
                      TAG_DONE),
                LAYOUT_AddChild, IIntuition->NewObject(NULL, "button.gadget",
                       GA_Text,      "_Cancel",
                       GA_ID,        OBJ_QUIT,
                       GA_RelVerify, TRUE,
                      TAG_DONE),
                TAG_DONE),
                CHILD_WeightedHeight, 0,
 
               TAG_DONE),
        TAG_END);
 
 if( (window = (struct Window *)IIntuition->IDoMethod(win, WM_OPEN)) )
 {
  IIntuition->GetAttr(WINDOW_SigMask, win, &wsigmask);
 
  while( !ProcessPrefsWindow(dd) );
 }
 
 IIntuition->DisposeObject(win);
 IListBrowser->FreeListBrowserList(&listbrowser_list);
 IListBrowser->FreeLBColumnInfo(columninfo);
 
 return(RETURN_OK);
}
 
 
BOOL ProcessPrefsWindow(struct DockyData *dd)
{
 uint32 siggot = IExec->Wait(wsigmask);
 
 if(siggot & wsigmask)
 {
  uint16 code = 0;
  uint32 result = WMHI_LASTMSG, res_node = 0;
  char *res_keymap = NULL;
 
  while( (result = IIntuition->IDoMethod(win, WM_HANDLEINPUT, &code)) != WMHI_LASTMSG )
  {
   switch(result & WMHI_CLASSMASK)
   {
    case WMHI_CLOSEWINDOW:
     return TRUE;
    break;
    case WMHI_GADGETUP:
//IDOS->Printf("[WMHI_GADGETUP] ");
     switch(result & WMHI_GADGETMASK)
     {
      case OBJ_QUIT:
#ifdef _DEBUG_
IDOS->Printf("CANCEL: %s\n",dd->keymap2Name);
#endif
       return TRUE;
      break;
 
      case OBJ_USE:
       IIntuition->GetAttr(LISTBROWSER_SelectedNode, OBJ(OBJ_LISTBROWSER), (uint32 *)&res_node);
       if(res_node)
       {
        IListBrowser->GetListBrowserNodeAttrs( (struct Node *)res_node, LBNA_Column,0, LBNCA_Text,&res_keymap, TAG_DONE );
        IUtility->Strlcpy( dd->keymap2Name, res_keymap, sizeof(dd->keymap2Name) );
       }
#ifdef _DEBUG_
IDOS->Printf("USE: '%s'\n",dd->keymap2Name);
#endif
       return TRUE;
      break;
 
      case OBJ_SAVE:
       IIntuition->GetAttr(LISTBROWSER_SelectedNode, OBJ(OBJ_LISTBROWSER), (uint32 *)&res_node); // (uint32 *)&node
       if(res_node)
       {
        IListBrowser->GetListBrowserNodeAttrs( (struct Node *)res_node, LBNA_Column,0, LBNCA_Text,&res_keymap, TAG_DONE );
        IUtility->Strlcpy( dd->keymap2Name, res_keymap, sizeof(dd->keymap2Name) );
        SaveToolType(dd, "KEYMAP2", dd->keymap2Name);
       }
#ifdef _DEBUG_
IDOS->Printf("SAVE: '%s'\n",dd->keymap2Name);
#endif
       return TRUE;
      break;
     }
    break;
   } // END switch(result & WMHI_CLASSMASK)
  } // END while( (result =..
 } // END if(siggot & wsigmask)
 
 return FALSE;
}
 
 
BOOL scanfiles(CONST_STRPTR dirname)
{
 int32 success= FALSE;
 APTR context = IDOS->ObtainDirContextTags(EX_StringNameInput, dirname,
                                           EX_DataFields, (EXF_NAME|EXF_TYPE),
                                          TAG_END);
 
 IExec->NewList(&listbrowser_list);
/* // add to listbrowser built-in usa1 (American) keymap
 node = IListBrowser->AllocListBrowserNode(2,
                                           LBNA_Column,0, LBNCA_Text,"usa1",
                                           LBNA_Column,1, LBNCA_Text,"American",
                                          TAG_DONE);
 IExec->AddTail(&listbrowser_list, node);
*/
 if(context)
 {
  struct ExamineData *dat;
 
  while( (dat = IDOS->ExamineDir(context)) )
   if( EXD_IS_FILE(dat) )
   {
    APTR KM_handle;
    STRPTR KM_desc;
 
    KM_handle = IKeymap->OpenKeyMapHandle(dat->Name, NULL);
    IKeymap->ObtainKeyMapInfo(KM_handle,
                              KEYMAPINFO_INFOTEXT_ENGLISH, &KM_desc,
                              //KEYMAPINFO_INFOTEXT_LOCAL, &KM_desc,
                             TAG_END);
 
    if( (node = IListBrowser->AllocListBrowserNode(2,
                                                   LBNA_Column,0, LBNCA_CopyText,TRUE,
                                                   LBNCA_Text, dat->Name,
                                                   LBNA_Column,1, LBNCA_CopyText,TRUE,
                                                   LBNCA_Text, KM_desc,
                                                  TAG_DONE)) )
    {
     IExec->AddTail(&listbrowser_list, node);
    }
 
    IKeymap->ReleaseKeyMapInfo(KM_handle,
                               KEYMAPINFO_INFOTEXT_ENGLISH, &KM_desc,
                               //KEYMAPINFO_INFOTEXT_LOCAL, &KM_desc,
                              TAG_END);
 
    IKeymap->CloseKeyMapHandle(KM_handle);
   }
 
  if( ERROR_NO_MORE_ENTRIES == IDOS->IoErr() ) success = TRUE;
  else IDOS->PrintFault(IDOS->IoErr(), NULL);
 
 }
 else IDOS->PrintFault(IDOS->IoErr(), NULL);
 
 IDOS->ReleaseDirContext(context);
 
 return(success);
}
 
 
#define BUFLENGTH 128
void SetKeyMapFlag(char *keymapname, char *keymapflag)
{
 char buffer[BUFLENGTH] = "", KM_buf[BUFLENGTH] = "";
 int32 pos;
 
 *keymapflag = '\0';
 IUtility->Strlcpy(keymapflag, "LOCALE:Flags/KeyMaps/", 1024);
 pos = IDOS->SplitName(keymapname, '_', KM_buf, 0, BUFLENGTH);
#ifdef _DEBUG_
IDOS->Printf("1)pos=%ld '%s'\n",pos,KM_buf);
#endif
 
 if(IUtility->Stricmp(KM_buf, "usa1") == 0) // Input prefs. using built-in American
  IUtility->Strlcpy(KM_buf, "usa", BUFLENGTH);
 
 if(IUtility->Stricmp(KM_buf, "rus") == 0) // keymap RUS_ -> flag RUS_GB
  IUtility->Strlcpy(KM_buf, "rus_gb", BUFLENGTH);
 
 if(IUtility->Stricmp(KM_buf, "srb") == 0    // keymap SRB_ -> flag SRB_xxx
    || IUtility->Stricmp(KM_buf, "pl") == 0) // keymap PL_ -> flag PL_xxx
 {
  pos = IDOS->SplitName(keymapname, '_', buffer, pos, BUFLENGTH);
  IUtility->Strlcat(KM_buf, "_", BUFLENGTH);
  IUtility->Strlcat(KM_buf, buffer, BUFLENGTH);
 }
 
 if(IUtility->Stricmp(KM_buf, "usa") == 0) // keymap USA_ -> USA
 {
  pos = IDOS->SplitName(keymapname, '_', buffer, pos, BUFLENGTH);
  if(IUtility->Stricmp(buffer, "gr") == 0
     || IUtility->Stricmp(buffer, "il") == 0) // special cases -> flag USA_xx
  {
   IUtility->Strlcat(KM_buf, "_", BUFLENGTH);
   IUtility->Strlcat(KM_buf, buffer, BUFLENGTH);
  }
 }
 
 if(IUtility->Stricmp(KM_buf, "tha") == 0) // no Thai flag image available
  IUtility->Strlcpy(KM_buf, "usa", BUFLENGTH);
 
#ifdef _DEBUG_
IDOS->Printf("2)pos=%ld '%s'\n",pos,KM_buf);
#endif
 IUtility->Strlcat(keymapflag, KM_buf, 1024);
}
 
/*
void SaveKEYMAP2(struct DockyData *dd)
{
 STRPTR *oldttp = NULL;
 int i;
 char newttp[256] = "KEYMAP2=";
 struct DiskObject *micon = NULL;
#ifdef _DEBUG_
IDOS->Printf("START SaveKEYMAP2()\n");
#endif
 micon = IIcon->GetDiskObject(dd->filename);
 if(micon)
 {
  for(i = 0; micon->do_ToolTypes[i] != NULL; i++) // parse tootlypes
  {
#ifdef _DEBUG_
IDOS->Printf("%2ld'%s'\n",i,micon->do_ToolTypes[i]);
#endif
   if( !IUtility->Strnicmp(micon->do_ToolTypes[i], "KEYMAP2=", 8) ||
       !IUtility->Strnicmp(micon->do_ToolTypes[i], "(KEYMAP2=", 9) )
   {// found KEYMAP2 tooltype
    IUtility->Strlcat( newttp, dd->keymap2Name, sizeof(newttp) );
#ifdef _DEBUG_
IDOS->Printf(" 1'%s' = '%s'\n",micon->do_ToolTypes[i],newttp );
#endif
    if( IUtility->Stricmp(micon->do_ToolTypes[i], newttp) )
    {// keymap2 loaded diffs. from KEYMAP2 tooltype -> modify tooltype and END
     oldttp = micon->do_ToolTypes;
     micon->do_ToolTypes[i] = newttp;
     IIcon->PutDiskObject(dd->filename, micon);
     micon->do_ToolTypes = oldttp;
#ifdef _DEBUG_
IDOS->Printf("(%s) modified.\n",newttp);
#endif
    }
    break;
 
   } // END if( !strncmp(micon->..
  } // END for
 
  if( !micon->do_ToolTypes[i] )
  {// no KEYMAP2 tooltype -> create tooltype entry and END
#ifdef _DEBUG_
IDOS->Printf("'%s' NOT found (i=%ld)\n",newttp,i);
#endif
   IUtility->Strlcat( newttp, dd->keymap2Name, sizeof(newttp) );
   oldttp = micon->do_ToolTypes;
   STRPTR *newtts = malloc( (i+2) * sizeof(STRPTR) );
   IExec->CopyMem(oldttp, newtts, i * sizeof(STRPTR) ); // clone tooltypes
   newtts[i] = newttp;
   newtts[i+1] = NULL;
   micon->do_ToolTypes = newtts;
   IIcon->PutDiskObject(dd->filename, micon);
   micon->do_ToolTypes = oldttp;
   free(newtts);
#ifdef _DEBUG_
IDOS->Printf("(%s) created.\n",newttp);
#endif
  }
 
  IIcon->FreeDiskObject(micon);
 }
 
#ifdef _DEBUG_
IDOS->Printf("END SaveKEYMAP2()\n");
#endif
}
*/
 
void SaveToolType(struct DockyData *dd, STRPTR ttpName, STRPTR ttpArg)
{
 STRPTR *oldttp = NULL;
 int i;
 char newttp[1024], ttpBuf1[64], ttpBuf2[64];
 struct DiskObject *micon = NULL;
#ifdef _DEBUG_
IDOS->Printf("START SaveToolType()\n");
#endif
 IUtility->SNPrintf(newttp, sizeof(newttp), "%s=",ttpName); // "<tooltype>="
 IUtility->Strlcpy( ttpBuf1, newttp, sizeof(ttpBuf1) ); // BUF1 = "<tooltype>="
 IUtility->SNPrintf(ttpBuf2, sizeof(ttpBuf2), "(%s=",ttpName); // BUF2 = "(<tooltype>="
 
 micon = IIcon->GetDiskObject(dd->filename);
 if(micon)
 {
  for(i = 0; micon->do_ToolTypes[i] != NULL; i++) // parse tootlypes
  {
#ifdef _DEBUG_
IDOS->Printf("%2ld'%s'\n",i,micon->do_ToolTypes[i]);
#endif
   if(!IUtility->Strnicmp( micon->do_ToolTypes[i], ttpBuf1, IUtility->Strlen(ttpBuf1) )
      || !IUtility->Strnicmp( micon->do_ToolTypes[i], ttpBuf2, IUtility->Strlen(ttpBuf2) ))
   {// found tooltype
    IUtility->Strlcat( newttp, ttpArg, sizeof(newttp) );
#ifdef _DEBUG_
IDOS->Printf("'%s' == '%s'?\n",micon->do_ToolTypes[i],newttp);
#endif
    if( IUtility->Stricmp(micon->do_ToolTypes[i], newttp) )
    {// tooltype loaded diffs. from icon's tooltype -> modify tooltype and END
     oldttp = micon->do_ToolTypes;
     micon->do_ToolTypes[i] = newttp;
     IIcon->PutDiskObject(dd->filename, micon);
     micon->do_ToolTypes = oldttp;
#ifdef _DEBUG_
IDOS->Printf("Tooltype (%s) modified.\n",newttp);
#endif
    }
    break;
 
   } // END if( !strncmp(micon->..
  } // END for
 
  if( !micon->do_ToolTypes[i] )
  {// no tooltype -> create tooltype entry and END
#ifdef _DEBUG_
IDOS->Printf("Tooltype '%s' NOT found (i=%ld)\n",newttp,i);
#endif
   IUtility->Strlcat( newttp, ttpArg, sizeof(newttp) );
   oldttp = micon->do_ToolTypes;
   STRPTR *newtts = malloc( (i+2) * sizeof(STRPTR) );
   IExec->CopyMem(oldttp, newtts, i * sizeof(STRPTR) ); // clone tooltypes
   newtts[i] = newttp;
   newtts[i+1] = NULL;
   micon->do_ToolTypes = newtts;
   IIcon->PutDiskObject(dd->filename, micon);
   micon->do_ToolTypes = oldttp;
   free(newtts);
#ifdef _DEBUG_
IDOS->Printf("Tooltype (%s) created.\n",newttp);
#endif
  }
 
  IIcon->FreeDiskObject(micon);
 }
 
#ifdef _DEBUG_
IDOS->Printf("END SaveToolType()\n");
#endif
}