Platon Technologies
not logged in Login Registration
EnglishSlovak
open source software development celebrating 10 years of open source development! Saturday, April 20, 2024

File: [Platon] / tucniak / cuchar / cc_user.c (download)

Revision 1.7, Sat Dec 10 21:24:55 2005 UTC (18 years, 4 months ago) by misosud


Changes since 1.6: +50 -44 lines

Changed calling conventions for standard dialog boxes functions.

/*
  Name: cc_user.c
  Author: Michal Sudolsky <michals@sulysoft.com>
  Date: 22.09.2005 15:13
*/
// modified by Juraj Kolesar <koli@koli.sk>

#include "cc.h"

Cc_Win *cc_file_open_dialog(Cc_Win *parent,
                            void (*action)(Cc_Win *sender,char *filename),
                            bool modal,char *caption,char *filename,char *mask)
{
  if((caption==NULL)||(filename==NULL)||(mask==NULL))return NULL;
  const cback=CC_C_CYAN;
  long x,y,i,j,oldi,act,len,vx=_cc_fobvx,vy=_cc_fobvy;
  GList *disklines,*masklines,*mmlines;
  x=(_cc_screenx-vx)/2;
  y=(_cc_screeny-vy)/2;
  cc_screen_to_client(parent,&x,&y);
  Cc_Win *di,*diskcombo,*filelist,*nameedit,*maskcombo;
  char *lin;
  TUFOB *tufob;
  Cc_Dialog_P pdialog;
  pdialog.type=CC_TP_DIALOG;
  pdialog.style=CC_ST_DI_SIZEABLE;
  pdialog.caption=caption;
  pdialog.cback=cback;
  pdialog.cbactive=CC_C_DEFAULT;
  pdialog.cbinactive=CC_C_DEFAULT;
  pdialog.cbuttext[0]=CC_C_DEFAULT;
  pdialog.cbuttext[1]=CC_C_DEFAULT;
  pdialog.cbuttext[2]=CC_C_DEFAULT;
  pdialog.modal=modal;
  pdialog.menu=NULL;
  pdialog.resize=NULL;
  pdialog.sizeok=_cc_fobsizeokproc;
  pdialog.close=_cc_fobcloseproc;
  di=cc_create_win(parent,x,y,vx,vy,(Cc_Union_P*)&pdialog,0,
                   _cc_fobdialogacelproc);
  di->user=malloc(sizeof(TUFOB));
  tufob=((TUFOB*)(di->user));
  tufob->action=action;
  Cc_Combo_P pcombo;
  Cc_Button_P pbutton;
  Cc_List_P plist;
  Cc_Edit_P pedit;
  disklines=NULL;
  disklines=g_list_append(disklines,"/");
  disklines=g_list_append(disklines,"/root/");
  disklines=g_list_append(disklines,"/home/");
  pbutton.type=CC_TP_BUTTON;
  pbutton.style=CC_BT_NORMAL;
  pbutton.checked=false;
  pbutton.cback[0]=cback;
  pbutton.cback[1]=cback;
  pbutton.cback[2]=cback;
  pbutton.ctext[0]=CC_C_BLACK;
  pbutton.ctext[1]=CC_C_BLACK;
  pbutton.ctext[2]=CC_C_BLACK;
  pbutton.cutext[0]=CC_C_BLUE;
  pbutton.cutext[1]=CC_C_BLUE;
  pbutton.cutext[2]=CC_C_BLUE;
  pbutton.cfocus[0]=CC_C_DEFAULT;
  pbutton.cfocus[1]=CC_C_DEFAULT;
  pbutton.cfocus[2]=CC_C_DEFAULT;
  pbutton.hasfocus=false;
  pbutton.push=_cc_fobdiskbuttonproc;
  pbutton.text="Look &in:";
  cc_create_win(di,3,2,strlen(pbutton.text),1,(Cc_Union_P*)&pbutton,
                CC_ST_VISIBLE,NULL);
  pcombo.type=CC_TP_COMBO;
  pcombo.activeline=0;
  pcombo.cback=CC_C_DEFAULT;
  pcombo.cbutback[0]=CC_C_BLUE;
  pcombo.cbutback[1]=CC_C_DEFAULT;
  pcombo.cbutfront[0]=CC_C_DEFAULT;
  pcombo.cbutfront[1]=CC_C_DEFAULT;
  pcombo.change=_cc_fobdiskcombochangeproc;
  pcombo.maxvisitems=8;
  pcombo.lstvy=0;
  pcombo.lstcback=CC_C_DEFAULT;
  pcombo.lstcborder=CC_C_DEFAULT;
  pcombo.lstctext=CC_C_DEFAULT;
  pcombo.lstcselected=CC_C_DEFAULT;
  pcombo.lstcseltext=CC_C_DEFAULT;
  pcombo.lstcactive=CC_C_DEFAULT;
  pcombo.lstcactivetext=CC_C_DEFAULT;
  pcombo.lstscrcback=CC_C_DEFAULT;
  pcombo.lstscrcmark=CC_C_DEFAULT;
  pcombo.lstscrcbar=CC_C_DEFAULT;
  pcombo.lstscrcarrowup=CC_C_DEFAULT;
  pcombo.lstscrcarrowdown=CC_C_DEFAULT;
  pcombo.lstlines=disklines;
  pcombo.edistyle=CC_ED_READONLY;
  pcombo.edicbmask=CC_C_WHITE;
  pcombo.edicfmask=CC_C_BLACK;
  diskcombo=cc_create_win(di,12,2,vx-3-12,1,(Cc_Union_P*)&pcombo,
                          CC_ST_VISIBLE|CC_ST_A_HFIXED|CC_ST_CO_WITH_EDIT,NULL);
  tufob->diskcombo=diskcombo;
  plist.type=CC_TP_LIST;
  plist.activeline=0;
  plist.lines=NULL;
  plist.combotyp=CC_LI_NORMAL;
  plist.cback=CC_C_DEFAULT;
  plist.cborder=CC_C_DEFAULT;
  plist.ctext=CC_C_DEFAULT;
  plist.cselected=CC_C_DEFAULT;
  plist.cseltext=CC_C_DEFAULT;
  plist.cactive=CC_C_DEFAULT;
  plist.cactivetext=CC_C_DEFAULT;
  plist.change=NULL;
  plist.dblclk=_cc_fobfilelistdblclkproc;
  plist.scrcmark=CC_C_DEFAULT;
  plist.scrcbar=CC_C_DEFAULT;
  plist.scrcarrowup=CC_C_DEFAULT;
  plist.scrcarrowdown=CC_C_DEFAULT;
  plist.scrcback=CC_C_DEFAULT;
  filelist=cc_create_win(di,3,4,vx-5-10-3,vy-6-4,(Cc_Union_P*)&plist,
                         CC_ST_VISIBLE|CC_ST_A_FIXED,_cc_fobfilelistacelproc);
  tufob->filelist=filelist;
  pbutton.push=_cc_fobnamebuttonproc;
  pbutton.text="File &name:    ";
  cc_create_win(di,3,vy-5,strlen(pbutton.text),1,(Cc_Union_P*)&pbutton,
                CC_ST_VISIBLE|CC_ST_AD_FIXED,NULL);
  pedit.type=CC_TP_EDIT;
  pedit.cback=CC_C_DEFAULT;
  pedit.cbmask=CC_C_WHITE;
  pedit.cfmask=CC_C_BLACK;
  pedit.style=CC_ED_NORMAL;
  pedit.ctext=CC_C_DEFAULT;
  pedit.change=NULL;
  nameedit=cc_create_win(di,18,vy-5,vx-21,1,(Cc_Union_P*)&pedit,
                         CC_ST_VISIBLE|CC_ST_AD_FIXED|CC_ST_A_HFIXED,NULL);
  tufob->nameedit=nameedit;
  pbutton.push=_cc_fobmaskbuttonproc;
  pbutton.text="Files of &type:";
  cc_create_win(di,3,vy-3,strlen(pbutton.text),1,(Cc_Union_P*)&pbutton,
                CC_ST_VISIBLE|CC_ST_AD_FIXED,NULL);
  masklines=NULL;
  mmlines=NULL;
  act=0;
  len=strlen(mask);
  oldi=0;
  for(i=0;i<=len;i++)
  {
    if((i==len)||(mask[i]=='|'))
    {
      lin=malloc(i-oldi+1);
      for(j=0;j<i-oldi;j++)lin[j]=mask[oldi+j];
      lin[i-oldi]='\0';
      if(act==0){masklines=g_list_append(masklines,lin);act=1;}
      else {mmlines=g_list_append(mmlines,lin);act=0;}
      oldi=i+1;
    }
  }
  pcombo.change=_cc_fobdiskcombochangeproc;
  pcombo.lstlines=masklines;
  maskcombo=cc_create_win(di,18,vy-3,vx-21,1,(Cc_Union_P*)&pcombo,
                          CC_ST_VISIBLE|CC_ST_AD_FIXED|CC_ST_A_HFIXED,NULL);
  tufob->maskcombo=maskcombo;  
  pbutton.cback[0]=CC_C_DEFAULT;
  pbutton.cback[1]=CC_C_DEFAULT;
  pbutton.cback[2]=CC_C_DEFAULT;
  pbutton.ctext[0]=CC_C_DEFAULT;
  pbutton.ctext[1]=CC_C_DEFAULT;
  pbutton.ctext[2]=CC_C_DEFAULT;
  pbutton.cutext[0]=CC_C_DEFAULT;
  pbutton.cutext[1]=CC_C_DEFAULT;
  pbutton.cutext[2]=CC_C_DEFAULT;
  pbutton.hasfocus=true;
  pbutton.push=_cc_fobopenbuttonproc;
  pbutton.text="&Open";
  cc_create_win(di,vx-13,4,10,1,(Cc_Union_P*)&pbutton,
                CC_ST_VISIBLE|CC_ST_AR_FIXED,NULL);
  pbutton.push=_cc_fobcancelbuttonproc;
  pbutton.text="&Cancel";
  cc_create_win(di,vx-13,6,10,1,(Cc_Union_P*)&pbutton,
                CC_ST_VISIBLE|CC_ST_AR_FIXED,NULL);
  cc_set_focus(filelist);
  tufob->mmlines=mmlines;
  tufob->filename=filename;
  _cc_fobsetnameedit(di);
  _cc_fobsetfilelist(di,mmlines!=NULL?mmlines->data:NULL);
  _cc_fobsetdiskcombo(di);
  cc_show_win(di,true);
  return di;  
}

Cc_Win *cc_color_dialog(Cc_Win *parent,void (*action)(Cc_Win *sender,long i),
                        bool modal,char *caption,long color)
{
  if(caption==NULL)return NULL;
  long x,y,i;
  const vx=34,vy=10,cback=CC_C_CYAN;
  Cc_Win *di,*p,*combo,*p1,*p2;
  x=(_cc_screenx-vx)/2;
  y=(_cc_screeny-vy)/2;
  cc_screen_to_client(parent,&x,&y);
  TUCB *tucb;
  Cc_Dialog_P pdialog;
  Cc_Button_P pbutton;
  Cc_Paint_P ppaint;
  Cc_Combo_P pcombo;
  GList *lines;
  pdialog.type=CC_TP_DIALOG;
  pdialog.style=0;
  pdialog.caption=caption;
  pdialog.cback=cback;
  pdialog.cbactive=CC_C_DEFAULT;
  pdialog.cbinactive=CC_C_DEFAULT;
  pdialog.cbuttext[0]=CC_C_DEFAULT;
  pdialog.cbuttext[1]=CC_C_DEFAULT;
  pdialog.cbuttext[2]=CC_C_DEFAULT;
  pdialog.modal=modal;
  pdialog.menu=NULL;
  pdialog.resize=NULL;
  pdialog.sizeok=NULL;
  pdialog.close=_cc_cbcloseproc;
  di=cc_create_win(parent,x,y,vx,vy,(Cc_Union_P*)&pdialog,0,
                   _cc_cbdialogacelproc);
  di->user=malloc(sizeof(TUCB));
  tucb=((TUCB*)(di->user));
  tucb->action=action;
  ppaint.type=CC_TP_PAINT;
  ppaint.style=CC_PA_PATTERN;
  for(y=0;y<4;y++)
    for(x=0;x<4;x++)
    {
      i=y*4+x;
      ppaint.cback=i;
      ppaint.color=i;
      p=cc_create_win(di,2*x+5,y+3,2,1,(Cc_Union_P*)&ppaint,CC_ST_VISIBLE,
                      _cc_cbpaintacelproc);
      p->user=(void*)i;
    }
  lines=NULL;
  lines=g_list_append(lines,_cc_getcolorname(CC_C_BLACK));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_RED));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_GREEN));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_YELLOW));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_BLUE));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_MAGENTA));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_CYAN));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_WHITE));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_LBLACK));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_LRED));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_LGREEN));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_LYELLOW));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_LBLUE));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_LMAGENTA));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_LCYAN));
  lines=g_list_append(lines,_cc_getcolorname(CC_C_LWHITE));
  pcombo.type=CC_TP_COMBO;
  pcombo.activeline=color;
  pcombo.cback=CC_C_DEFAULT;
  pcombo.cbutback[0]=CC_C_BLUE;
  pcombo.cbutback[1]=CC_C_DEFAULT;
  pcombo.cbutfront[0]=CC_C_DEFAULT;
  pcombo.cbutfront[1]=CC_C_DEFAULT;
  pcombo.change=_cc_cbcombochangeproc;
  pcombo.maxvisitems=8;
  pcombo.lstvy=10;
  pcombo.lstcback=CC_C_DEFAULT;
  pcombo.lstcborder=CC_C_DEFAULT;
  pcombo.lstctext=CC_C_DEFAULT;
  pcombo.lstcselected=CC_C_DEFAULT;
  pcombo.lstcseltext=CC_C_DEFAULT;
  pcombo.lstcactive=CC_C_DEFAULT;
  pcombo.lstcactivetext=CC_C_DEFAULT;
  pcombo.lstscrcback=CC_C_DEFAULT;
  pcombo.lstscrcmark=CC_C_DEFAULT;
  pcombo.lstscrcbar=CC_C_DEFAULT;
  pcombo.lstscrcarrowup=CC_C_DEFAULT;
  pcombo.lstscrcarrowdown=CC_C_DEFAULT;
  pcombo.lstlines=lines;
  combo=cc_create_win(di,17,2,MAXLEN_COLOR_STRING-1,1,(Cc_Union_P*)&pcombo,
                      CC_ST_VISIBLE,NULL);
  tucb->combo=combo;
  ppaint.cback=CC_C_BLUE;
  ppaint.color=CC_C_WHITE;
  p1=cc_create_win(di,(color%4)*2+5,2,2,1,(Cc_Union_P*)&ppaint,
                   CC_ST_VISIBLE,NULL);
  cc_create_win(p1,0,5,2,1,(Cc_Union_P*)&ppaint,CC_ST_VISIBLE,NULL);
  tucb->p1=p1;
  p2=cc_create_win(di,3,(color/4)+3,2,1,(Cc_Union_P*)&ppaint,CC_ST_VISIBLE,
                   NULL);
  cc_create_win(p2,10,0,2,1,(Cc_Union_P*)&ppaint,CC_ST_VISIBLE,NULL);
  tucb->p2=p2;
  pbutton.type=CC_TP_BUTTON;
  pbutton.style=CC_BT_NORMAL;
  pbutton.checked=false;
  pbutton.cback[0]=CC_C_DEFAULT;
  pbutton.cback[1]=CC_C_DEFAULT;
  pbutton.cback[2]=CC_C_DEFAULT;
  pbutton.ctext[0]=CC_C_DEFAULT;
  pbutton.ctext[1]=CC_C_DEFAULT;
  pbutton.ctext[2]=CC_C_DEFAULT;
  pbutton.cutext[0]=CC_C_DEFAULT;
  pbutton.cutext[1]=CC_C_DEFAULT;
  pbutton.cutext[2]=CC_C_DEFAULT;
  pbutton.cfocus[0]=CC_C_DEFAULT;
  pbutton.cfocus[1]=CC_C_DEFAULT;
  pbutton.cfocus[2]=CC_C_DEFAULT;
  pbutton.hasfocus=true;
  pbutton.push=_cc_cbpushproc;
  pbutton.text="  &Ok  ";
  p=cc_create_win(di,19,5,1,1,(Cc_Union_P*)&pbutton,
                  CC_ST_VISIBLE|CC_ST_AUTOXSIZE,NULL);
  p->user=(void*)true;
  pbutton.text="&Cancel";
  p=cc_create_win(di,19,7,1,1,(Cc_Union_P*)&pbutton,
                  CC_ST_VISIBLE|CC_ST_AUTOXSIZE,NULL);
  p->user=(void*)false;
  cc_show_win(di,true);
  return di;
}

Cc_Win *cc_message_box(Cc_Win *parent,void (*action)(Cc_Win *sender,long i),
                       bool modal,char *caption,char *text,
                       long style)
{
  if((caption==NULL)||(text==NULL))return NULL;
  long x,y,bx,lastwh,i,j,l,line,vx,vy,len=strlen(text),nlen;
  const bxok=2+4+2,bxyes=3+4+2,bxno=2+4+2,bxcancel=6+4+2;
  char *st;
  Cc_Win *but;
  bool nonext;
  Cc_Dialog_P pdialog;
  Cc_Text_P ptext;
  Cc_Button_P pbutton;
  Cc_Win *di;
  nlen=len;
  vx=6;
  vy=3;
  bx=0;
  if(style!=CC_MB_DEFAULT)vy+=2;
  if(style&CC_MB_OK)bx+=bxok;
  if(style&CC_MB_YES)bx+=bxyes;
  if(style&CC_MB_NO)bx+=bxno;
  if(style&CC_MB_CANCEL)bx+=bxcancel;
  if(bx>0)bx-=2;
  vx+=bx;
  st=malloc(nlen+1);
  if(st==NULL)return NULL;
  line=1;
  lastwh=-1;
  for(i=0,l=0,j=0;i<len;i++,l++,j++)
  {
    nonext=false;
    if(text[i]==' ')lastwh=l;
    if((text[i]=='\n')||(j>=MAX_MB_VX-6))
    {
      if(j>=MAX_MB_VX-6)
      {
        if((lastwh!=-1)&&(i-lastwh<=MAX_MB_VX-6))
        {
          st[lastwh]='\0';
          j=l-lastwh-1;
          if(j==-1)nonext=true;
          lastwh=-1;
        }
        else
        {
          st[l]='\0';
          l++;
          nlen++;
          st=realloc(st,nlen+1);
          if(st==NULL)return NULL;
          j=0;
        }
      }
      else
      {
        st[l]='\0';
        j=0;
      }
      vx=MAX_MB_VX;
      line++;
    }
    if((text[i]!='\n')&&(!nonext))st[l]=text[i];
  }
  if(j+6>vx)vx=j+6;
  st[nlen]='\0';
  vy+=line+1;
  if(vx<MIN_MB_VX)vx=MIN_MB_VX;
  if(vy<MIN_MB_VY)vy=MIN_MB_VY;
  x=(_cc_screenx-vx)/2;
  y=(_cc_screeny-vy)/2;
  cc_screen_to_client(parent,&x,&y);
  pdialog.type=CC_TP_DIALOG;
  pdialog.style=0;
  pdialog.caption=caption;
  pdialog.cback=CC_C_RED;
  pdialog.cbactive=CC_C_DEFAULT;
  pdialog.cbinactive=CC_C_DEFAULT;
  pdialog.cbuttext[0]=CC_C_DEFAULT;
  pdialog.cbuttext[1]=CC_C_DEFAULT;
  pdialog.cbuttext[2]=CC_C_DEFAULT;
  pdialog.modal=modal;
  pdialog.menu=NULL;
  pdialog.resize=NULL;
  pdialog.sizeok=NULL;
  pdialog.close=_cc_mbcloseproc;
  di=cc_create_win(parent,x,y,vx,vy,(Cc_Union_P*)&pdialog,0,
                   _cc_mbdialogacelproc);
  TUMB *tumb;
  tumb=malloc(sizeof(TUMB));
  di->user=tumb;
  tumb->action=action;
  tumb->st=st;
  ptext.type=CC_TP_TEXT;
  ptext.cback=pdialog.cback;
  ptext.ctext=CC_C_LWHITE;
  for(i=0,j=0;j<nlen;j++)
  {
    if((j==0)||(st[j-1]=='\0'))
    {
      ptext.text=&st[j];
      cc_create_win(di,3,2+i,1,1,(Cc_Union_P*)&ptext,
                    CC_ST_VISIBLE|CC_ST_AUTOXSIZE,NULL);
      i++;
    }
  }
  pbutton.type=CC_TP_BUTTON;
  pbutton.style=CC_BT_NORMAL;
  pbutton.checked=false;
  pbutton.cback[0]=CC_C_DEFAULT;
  pbutton.cback[1]=CC_C_DEFAULT;
  pbutton.cback[2]=CC_C_DEFAULT;
  pbutton.ctext[0]=CC_C_DEFAULT;
  pbutton.ctext[1]=CC_C_DEFAULT;
  pbutton.ctext[2]=CC_C_DEFAULT;
  pbutton.cutext[0]=CC_C_DEFAULT;
  pbutton.cutext[1]=CC_C_DEFAULT;
  pbutton.cutext[2]=CC_C_DEFAULT;
  pbutton.cfocus[0]=CC_C_DEFAULT;
  pbutton.cfocus[1]=CC_C_DEFAULT;
  pbutton.cfocus[2]=CC_C_DEFAULT;
  pbutton.hasfocus=true;
  pbutton.push=_cc_mbpushproc;
  j=(vx-bx)/2;
  if(style&CC_MB_OK)
  {
    pbutton.text="&Ok";
    but=cc_create_win(di,j,vy-3,10,1,(Cc_Union_P*)&pbutton,
                      CC_ST_VISIBLE|CC_ST_AUTOXSIZE,NULL);
    but->user=(void*)CC_MB_OK;
    j+=bxok;
  }
  if(style&CC_MB_YES)
  {
    pbutton.text="&Yes";
    but=cc_create_win(di,j,vy-3,10,1,(Cc_Union_P*)&pbutton,
                      CC_ST_VISIBLE|CC_ST_AUTOXSIZE,NULL);
    but->user=(void*)CC_MB_YES;
    j+=bxyes;
  }
  if(style&CC_MB_NO)
  {
    pbutton.text="&No";
    but=cc_create_win(di,j,vy-3,10,1,(Cc_Union_P*)&pbutton,
                      CC_ST_VISIBLE|CC_ST_AUTOXSIZE,NULL);
    but->user=(void*)CC_MB_NO;
    j+=bxno;
  }
  if(style&CC_MB_CANCEL)
  {
    pbutton.text="&Cancel";
    but=cc_create_win(di,j,vy-3,10,1,(Cc_Union_P*)&pbutton,
                      CC_ST_VISIBLE|CC_ST_AUTOXSIZE,NULL);
    but->user=(void*)CC_MB_CANCEL;
    j+=bxcancel;
  }
  cc_show_win(di,true);
  return di;
}

void cc_edit_copy(Cc_Win *edit)
{
  if(edit==NULL)return;
  if(edit->extra->type!=CC_TP_EDIT)return;
  EDIT *ed=&edit->extra->edit;
  if(ed->maskpos==-1)return;
  long len=strlen(ed->text);
  if(ed->maskpos<0)ed->maskpos=0;
  if(ed->maskpos>len-1)ed->maskpos=len-1;
  if(ed->curpos<0)ed->curpos=0;
  if(ed->curpos>len-1)ed->curpos=len-1;
  long i=ed->curpos,j=ed->maskpos,l;
  if(j<i)
  {
    l=i-j;
    i=j;
  }
  else l=j-i;
  l++;
  _cc_clipboard=realloc(_cc_clipboard,l+1);
  for(j=0;j<l;j++)_cc_clipboard[j]=ed->text[j+i];
  _cc_clipboard[j]='\0';
}

void cc_edit_paste(Cc_Win *edit)
{
  if(_cc_clipboard==NULL)return;
  if(edit==NULL)return;
  if(edit->extra->type!=CC_TP_EDIT)return;
  EDIT *ed=&edit->extra->edit;
  if(ed->style==CC_ED_READONLY)return;
  long i,j,l,len=strlen(ed->text),clen=strlen(_cc_clipboard);
  if(ed->curpos<0)ed->curpos=0;
  if(ed->maskpos!=-1)
  {
    if(ed->maskpos<0)ed->maskpos=0;
    if(ed->maskpos>len-1)ed->maskpos=len-1;
    if(ed->curpos>len-1)ed->curpos=len-1;
    i=ed->curpos;
    j=ed->maskpos;
    if(j<i)
    {
      l=i-j;
      i=j;
    }
    else l=j-i;
    l++;
  }
  else
  {
    if(ed->curpos>len)ed->curpos=len;
    i=ed->curpos;
    l=0;
  }
  if(clen>l)
  {
    ed->text=realloc(ed->text,len+clen-l+1);
    for(j=len+clen-l-1;j>=i+clen;j--)ed->text[j]=ed->text[j+l-clen];
  }
  else if(clen<l)
  {
    for(j=i+clen;j<len-l+clen;j++)ed->text[j]=ed->text[j+l-clen];
    ed->text=realloc(ed->text,len+clen-l+1);
  }
  ed->text[len+clen-l]='\0';
  for(j=0;j<clen;j++)ed->text[j+i]=_cc_clipboard[j];
  ed->maskpos=-1;
  ed->curpos=i+clen;
  _cc_redrawclientwin(edit);
}

void cc_edit_delete(Cc_Win *edit)
{
  if(edit==NULL)return;
  if(edit->extra->type!=CC_TP_EDIT)return;
  EDIT *ed=&edit->extra->edit;
  if(ed->style==CC_ED_READONLY)return;
  if(ed->maskpos==-1)return;
  long i,j,l,len=strlen(ed->text);
  if(ed->curpos<0)ed->curpos=0;
  if(ed->maskpos<0)ed->maskpos=0;
  if(ed->maskpos>len-1)ed->maskpos=len-1;
  if(ed->curpos>len-1)ed->curpos=len-1;
  i=ed->curpos;
  j=ed->maskpos;
  if(j<i)
  {
    l=i-j;
    i=j;
  }
  else l=j-i;
  l++;
  for(j=i;j<len-l;j++)ed->text[j]=ed->text[j+l];
  ed->text=realloc(ed->text,len-l+1);
  ed->text[len-l]='\0';
  ed->maskpos=-1;
  ed->curpos=i;
  _cc_redrawclientwin(edit);
}

void cc_edit_cut(Cc_Win *edit)
{
  cc_edit_copy(edit);
  cc_edit_delete(edit);
}

void cc_edit_select(Cc_Win *edit,long sta,long end)
{
  if(edit==NULL)return;
  if(edit->extra->type!=CC_TP_EDIT)return;
  EDIT *ed=&edit->extra->edit;
  long len=strlen(ed->text);
  if(sta<-1)sta=-1;
  if(sta>len-1)sta=len-1;
  if(end<0)end=0;
  if(sta!=-1)
  {
    if(end>len-1)end=len-1;
  }
  else
    if(end>len)end=len;
  ed->maskpos=sta;
  ed->curpos=end;
  _cc_redrawclientwin(edit);
}

void cc_edit_get_selection(Cc_Win *edit,long *sta,long *end)
{
  if(edit==NULL)return;
  if(edit->extra->type!=CC_TP_EDIT)return;
  EDIT *ed=&edit->extra->edit;
  *sta=ed->maskpos;
  *end=ed->curpos;
}

void cc_set_clipboard(char *text)
{
  if(text==NULL)
  {
    free(_cc_clipboard);
    _cc_clipboard=NULL;
  }
  _cc_clipboard=realloc(_cc_clipboard,strlen(text)+1);
  strcpy(_cc_clipboard,text);
}

char *cc_get_clipboard()
{
  return _cc_clipboard;
}

void cc_track_popup_menu(Cc_Win *menu,long x,long y)
{
  if(menu==NULL)return;
  cc_screen_to_client(menu->parent,&x,&y);
  menu->extra->menu.activeline=-1;
  menu->x=x;
  menu->y=y;
  cc_show_win(menu,true);
  _cc_focuswin=menu;
  _cc_capturewin=menu;
}

Cc_Win *cc_create_menu(Cc_Win *parent,Cc_Menu_P *menu,
                 bool (*acel)(Cc_Win *win,long x,long y,unsigned short key))
{
  if(menu==NULL)return;
  menu->lines=NULL;
  return cc_create_win(parent,0,0,0,0,(Cc_Union_P*)menu,
                       menu->vert?0:CC_ST_VISIBLE,acel);
}

Cc_Win *cc_create_submenu(Cc_Win *menu)
{
  if(menu==NULL)return;
  Cc_Menu_P pmenu;
  cc_get_win_params(menu,(Cc_Union_P*)&pmenu);
  pmenu.vert=true;
  pmenu.lines=NULL;
  return cc_create_win(menu,0,0,0,0,(Cc_Union_P*)&pmenu,0,(void*)menu->acel);
}

void cc_add_menu_item(Cc_Win *menu,Cc_Menu_I *cmenu)
{
  if((menu==NULL)||(cmenu==NULL))return;
  Cc_Menu_I *p=malloc(sizeof(Cc_Menu_I));
  p->id=cmenu->id;
  p->checked=cmenu->checked;
  p->text=cmenu->text;
  p->shortcut=cmenu->shortcut;
  p->submenu=cmenu->submenu;
  menu->extra->menu.lines=g_list_append(menu->extra->menu.lines,p);
  _cc_redraw();
}

void cc_ins_menu_item(Cc_Win *menu,long pos,Cc_Menu_I *cmenu)
{
  if((menu==NULL)||(cmenu==NULL))return;
  Cc_Menu_I *p=malloc(sizeof(Cc_Menu_I));
  p->id=cmenu->id;
  p->checked=cmenu->checked;
  p->text=cmenu->text;
  p->shortcut=cmenu->shortcut;
  p->submenu=cmenu->submenu;
  menu->extra->menu.lines=g_list_insert(menu->extra->menu.lines,p,pos);
  _cc_redraw();
}

void cc_set_menu_item(Cc_Win *menu,long pos,Cc_Menu_I *cmenu)
{
  if((menu==NULL)||(cmenu==NULL))return;
  MENU *pmenu=&menu->extra->menu;
  if(pmenu->lines==NULL)return;
  GList *lines=g_list_nth(pmenu->lines,pos);
  if(lines==NULL)return;
  Cc_Menu_I *p;
  p=(Cc_Menu_I*)lines->data;
  p->id=cmenu->id;
  p->checked=cmenu->checked;
  p->text=cmenu->text;
  p->shortcut=cmenu->shortcut;
  p->submenu=cmenu->submenu;
  _cc_redrawclientwin(menu);
}

void cc_get_menu_item(Cc_Win *menu,long pos,Cc_Menu_I *cmenu)
{
  if((menu==NULL)||(cmenu==NULL))return;
  MENU *pmenu=&menu->extra->menu;
  if(pmenu->lines==NULL)return;
  GList *lines=g_list_nth(pmenu->lines,pos);
  if(lines==NULL)return;
  Cc_Menu_I *p;
  p=(Cc_Menu_I*)lines->data;
  cmenu->id=p->id;
  cmenu->checked=p->checked;
  cmenu->text=p->text;
  cmenu->shortcut=p->shortcut;
  cmenu->submenu=p->submenu;
}

void cc_del_menu_item(Cc_Win *menu,long pos)
{
  if(menu==NULL)return;
  MENU *pmenu=&menu->extra->menu;
  if(pmenu->lines==NULL)return;
  GList *lines=g_list_nth(pmenu->lines,pos);
  if(lines==NULL)return;
  pmenu->lines=g_list_remove(pmenu->lines,lines->data);
  free(lines->data);
  _cc_redraw();
}

void cc_set_api_run(bool run)
{
  _cc_apprun=run;
}

bool cc_is_api_run()
{
  return _cc_apprun;
}

void cc_set_capture(Cc_Win *win)
{
  _cc_capturewin=win;
  if(win!=NULL)_cc_usekeys=false;else _cc_usekeys=true;
}

Cc_Win *cc_get_capture()
{
  return _cc_capturewin;
}

bool cc_set_focus(Cc_Win *win)
{
  if(win==NULL)
  {
    Cc_Win *p=_cc_focuswin;
    _cc_focuswin=NULL;
    _cc_redrawclientwin(p);
    return false;
  }
  while(win!=NULL)
  {
    if(_cc_isactive(win)&&((win->extra->type==CC_TP_EDIT)||
       ((win->extra->type==CC_TP_BUTTON)&&(win->extra->button.hasfocus))||
      (win->extra->type==CC_TP_LIST)||(win->extra->type==CC_TP_COMBO)||
      (win->extra->type==CC_TP_MENU)||(win->extra->type==CC_TP_DIALOG)))
    {
      Cc_Win *temp=_cc_focuswin;
      _cc_focuswin=win;
      if(win->parent!=NULL)win->parent->lastfocus=win;
      _cc_bringwintotop(win);
      return true;
    }
    win=win->parent;
  }
  return false;
}

Cc_Win *cc_get_focus()
{
  return _cc_focuswin;
}

bool cc_show_win(Cc_Win *win,bool visible)
{
  bool _cc_doredraw=false;
  Cc_Win *p;
  if(win==NULL){_cc_hlvisible=visible;_cc_redraw();return true;}
  if((win->active)||(_cc_isactive(win->parent)))
  {
    if(win->active!=visible)_cc_doredraw=true;
    win->active=visible;
    if(visible)
    {
      p=_cc_findchild(win);      
      if(p!=NULL)if(cc_set_focus(p))_cc_doredraw=false;
    }
    if((win->extra->type==CC_TP_DIALOG)&&win->extra->dialog.modal)
    {
      if(win->parent!=NULL)win->parent->hasmodal=_cc_isvisible(win);
      else _cc_hasmodal=_cc_isvisible(win);
    }
    if(!_cc_isactive(_cc_focuswin))
      {_cc_focuswin=NULL;cc_set_focus(_cc_findchild(win->parent));}
    if(!_cc_isactive(_cc_capturewin))_cc_capturewin=NULL;
  }
  win->active=visible;
  if(_cc_doredraw)_cc_redraw();
  return _cc_doredraw;
}

void cc_get_mouse_pos(long *x,long *y)
{
  if(x!=NULL)*x=_cc_gpmev.x;
  if(y!=NULL)*y=_cc_gpmev.y;
}

void cc_sleep(long milisec)
{
  nanosleep(&(struct timespec){milisec/1000,(milisec%1000)*1000000},NULL);
}

long cc_get_tick()
{
  struct timeb times;
  long time;
  ftime(&times);
  time=times.time;
  time=time*1000+times.millitm;
  return time;
}

void cc_client_to_screen(Cc_Win *p,long *x,long *y)
{
  Cc_Win *n=p;
  while(n!=NULL)
  {
    if(x!=NULL)*x+=n->x;
    if(y!=NULL)*y+=n->y;
    n=n->parent;
  }
}

void cc_screen_to_client(Cc_Win *p,long *x,long *y)
{
  Cc_Win *n=p;
  while(n!=NULL)
  {
    if(x!=NULL)*x-=n->x;
    if(y!=NULL)*y-=n->y;
    n=n->parent;
  }
}

bool cc_get_menu_pos(Cc_Win *win,long id,Cc_Win **submenu,long *pos)
{
  if(win==NULL)return false;
  if(win->extra->type==CC_TP_MENU)
  {
    MENU *menu=&win->extra->menu;
    GList *lines=menu->lines;
    long npos=0;
    while(lines!=NULL)
    {
      if(((Cc_Menu_I*)lines->data)->id==id)
      {
        if(submenu!=NULL)*submenu=win;
        if(pos!=NULL)*pos=npos;
        return true;
      }
      Cc_Win *nsubmenu=((Cc_Menu_I*)lines->data)->submenu;
      if(nsubmenu!=NULL)
      {
        if(cc_get_menu_pos(nsubmenu,id,submenu,pos))return true;
      }
      npos++;
      lines=g_list_next(lines);
    }
  }
  return false;
}

void cc_set_user(Cc_Win *win,void *user)
{
  if(win==NULL)return;
  win->user=user;
}

void *cc_get_user(Cc_Win *win)
{
  if(win==NULL)return NULL;
  return win->user;
}

void cc_set_checked(Cc_Win *win,long pos,bool status)
{
  if(win==NULL)return;
  if(win->extra->type==CC_TP_BUTTON)
  {
    win->extra->button.checked=status;  
  }
  else if(win->extra->type==CC_TP_MENU)
  {
    MENU *menu=&win->extra->menu;
    GList *lines=menu->lines;
    if(lines!=NULL)
    {
      lines=g_list_nth(lines,pos);
      if(lines!=NULL)
      {
        ((Cc_Menu_I*)lines->data)->checked=status;
      }
    }
  }
}

bool cc_get_checked(Cc_Win *win,long pos)
{
  if(win==NULL)return false;
  if(win->extra->type==CC_TP_BUTTON)
  {
    return win->extra->button.checked;  
  }
  else if(win->extra->type==CC_TP_MENU)
  {
    MENU *menu=&win->extra->menu;
    GList *lines=menu->lines;
    if(lines!=NULL)
    {
      lines=g_list_nth(lines,pos);
      if(lines!=NULL)
      {
        return((Cc_Menu_I*)lines->data)->checked;
      }
    }
  }
  return false;
}

void cc_set_text(Cc_Win *win,char *text)
{
  if(win==NULL)return;
  if(win->extra->type==CC_TP_EDIT)
  {
    char *er;
    er=(char*)realloc(win->extra->edit.text,strlen((const char*)text)+1);
    if(er==NULL)return;
    win->extra->edit.text=er;
    win->extra->edit.maskpos=-1;
    strcpy((char*)win->extra->edit.text,(const char*)text);
    _cc_redrawclientwin(win);
  }
  else if(win->extra->type==CC_TP_TEXT)
  {
    win->extra->text.text=text;
    _cc_redrawclientwin(win);
  }
  else if((win->extra->type==CC_TP_COMBO)&&(win->extra->combo.edit!=NULL))
  {
    cc_set_text(win->extra->combo.edit,text);
  }
  else if(win->extra->type==CC_TP_DIALOG)
  {
    win->extra->dialog.caption=text;
    _cc_redrawclientwin(win);
  }
}

char *cc_get_text(Cc_Win *win)
{
  if(win==NULL)return;
  if(win->extra->type==CC_TP_EDIT)
  {
    return win->extra->edit.text;
  }
  else if(win->extra->type==CC_TP_TEXT)
  {
    return win->extra->text.text;
  }
  else if(win->extra->type==CC_TP_DIALOG)
  {
    return win->extra->dialog.caption;
  }
}

void cc_set_pos(Cc_Win *win,long pos)
{
  if(win==NULL);
  if(win->extra->type==CC_TP_EDIT)
  {
    win->extra->edit.curpos=pos;
    _cc_redrawclientwin(win);
  }
  else if(win->extra->type==CC_TP_SCROLL)
  {
    win->extra->scroll.pos=pos;
    _cc_redrawclientwin(win);
    if(win->extra->scroll.change!=NULL)win->extra->scroll.change(win);
  }
  else if(win->extra->type==CC_TP_COMBO)
  {
    _cc_setcomboactiveitem(&win->extra->combo,win->extra->combo.activeline,pos);
    win->extra->combo.activeline=pos;
    _cc_redrawclientwin(win);
    if(win->extra->combo.change!=NULL)win->extra->combo.change(win);
  }
  else if(win->extra->type==CC_TP_LIST)
  {
    SCROLL *vscroll=&win->extra->list.vscroll->extra->scroll;
    if(pos<vscroll->pos)vscroll->pos=pos;
    if(pos-win->vy+3>vscroll->pos)vscroll->pos=pos-win->vy+3;
    long actline=win->extra->list.activeline;
    win->extra->list.activeline=pos;
    _cc_setlistactiveitem(&win->extra->list,actline,
                          win->extra->list.activeline);
    _cc_redrawclientwin(win);
    if(win->extra->list.change!=NULL)win->extra->list.change(win);
  }
  else if(win->extra->type==CC_TP_STATUS)
  {
    win->extra->status.pos=pos;
    _cc_redrawclientwin(win);
  }
}

long cc_get_pos(Cc_Win *win)
{
  if(win==NULL)return CC_NOCHANGE;
  if(win->extra->type==CC_TP_EDIT)
  {
    return win->extra->edit.curpos;
  }
  else if(win->extra->type==CC_TP_SCROLL)
  {
    return win->extra->scroll.pos;
  }
  else if(win->extra->type==CC_TP_COMBO)
  {
    return win->extra->combo.activeline;
  }
  else if(win->extra->type==CC_TP_LIST)
  {
    return win->extra->list.activeline;
  }
  else if(win->extra->type==CC_TP_STATUS)
  {
    return win->extra->status.pos;
  }
  else if(win->extra->type==CC_TP_MENU)
  {
    return win->extra->menu.activeline;
  }
  return CC_NOCHANGE;
}

void cc_set_list(Cc_Win *win,GList *list)
{
  if(win==NULL)return;
  if(win->extra->type==CC_TP_LIST)
  {
    LIST *llist=&win->extra->list;
    llist->lines=list;
    _cc_setuplistparams(win);
    _cc_redrawclientwin(win);
  }
  else if(win->extra->type==CC_TP_COMBO)
  {
    win->extra->combo.list->extra->list.lines=list;
    _cc_redrawclientwin(win);
  }
  else if(win->extra->type==CC_TP_MENU)
  {
    win->extra->menu.lines=list;
    _cc_redraw();
  }
}

GList *cc_get_list(Cc_Win *win)
{
  if(win==NULL)return;
  if(win->extra->type==CC_TP_LIST)
  {
    return win->extra->list.lines;
  }
  else if(win->extra->type==CC_TP_COMBO)
  {
    return win->extra->combo.list->extra->list.lines;
  }
  else if(win->extra->type==CC_TP_MENU)
  {
    return win->extra->menu.lines;
  }
}

void cc_set_hl_downtext(Cc_Win *text)
{
  if(text!=NULL)
    if(text->extra->type!=CC_TP_TEXT)return;
  _cc_hldowntext=text;
}

Cc_Win *cc_get_hl_downtext()
{
  return _cc_hldowntext;
}

void cc_set_menu(Cc_Win *win,Cc_Win *menu)
{
  if(menu!=NULL)
  {
    if((menu->extra->type!=CC_TP_MENU)||(menu->extra->menu.vert))return;
    if(menu->parent!=NULL)
    {
      Cc_Win *parent=menu->parent;
      if(parent->extra->type==CC_TP_DIALOG)
      {
        DIALOG *dialog=&parent->extra->dialog;
        if(dialog->menu==menu)dialog->menu=NULL;
      }
    }
    else if(_cc_hlmenu==menu)_cc_hlmenu=NULL;
  }
  if(win==NULL)
  {
    _cc_hlmenu=menu;
  }
  else if(win->extra->type==CC_TP_DIALOG)
  {
    win->extra->dialog.menu=menu;
    if(menu!=NULL)if(menu->parent!=win)_cc_setparent(menu,win);
  }
}

Cc_Win *cc_get_menu(Cc_Win *win)
{
  if(win==NULL)
  {
    return _cc_hlmenu;
  }
  else if(win->extra->type==CC_TP_DIALOG)
  {
    return win->extra->dialog.menu;
  }
}

void cc_set_acel(Cc_Win *win,bool (*acel)(Cc_Win *win,long x,long y,
                 unsigned short key))
{
  if(win!=NULL)win->acel=(void*)acel;else _cc_acelproc=(void*)acel;
}

void *cc_get_acel(Cc_Win *win)
{
  if(win!=NULL)return win->acel;else return _cc_acelproc;
}

void cc_set_resize_proc(Cc_Win *win,void (*resize)(Cc_Win *win))
{
  if(win!=NULL)
  {
    if(win->extra->type==CC_TP_DIALOG)win->extra->dialog.resize=(void*)resize;
  }
  else _cc_resizescreen=(void*)resize;
}

void *cc_get_resize_proc(Cc_Win *win)
{
  if(win!=NULL)
  {
    if(win->extra->type==CC_TP_DIALOG)return win->extra->dialog.resize;
  }
  else return _cc_resizescreen;
}

void cc_set_parent(Cc_Win *win,Cc_Win *parent)
{
  long x=0,y=0;
  cc_client_to_screen(win,&x,&y);
  _cc_setparent(win,parent);
  cc_screen_to_client(win,&x,&y);
  if(!cc_move_win(win,win->x+x,win->y+y,CC_NOCHANGE,CC_NOCHANGE,CC_NOCHANGE))
    _cc_redraw();
}

Cc_Win *cc_get_parent(Cc_Win *win)
{
  return win->parent;
}

long cc_create_thread(void *(*proc)())
{
  pthread_t res;
  pthread_create(&res,NULL,proc,NULL);
  return res;
}

Cc_Timer *cc_set_timer(Cc_Win *win,long msec,char prior,
                       void (*timer)(Cc_Timer*))
{
  Cc_Timer *time;
  time=malloc(sizeof(Cc_Timer));
  time->next=_cc_hltimer;
  time->win=win;
  time->period=msec;
  time->prior=prior;
  time->tminus=cc_get_tick();
  time->timer=timer;
  _cc_hltimer=time;
  return time;
}

void cc_del_timer_for_win(Cc_Win *win)
{
  Cc_Timer *tprev,*timer;
  if((win==NULL)||(_cc_hltimer==NULL))return;
  tprev=NULL;
  timer=_cc_hltimer;
  while(timer!=NULL)
  {
    if(timer->win==win)
    {
      if(tprev!=NULL)tprev->next=timer->next;
      else _cc_hltimer=timer->next;
      free(timer);
    }
    else tprev=timer;
    if(tprev!=NULL)timer=tprev->next;
    else timer=_cc_hltimer; 
  }
}

void cc_del_timer(Cc_Timer *timer)
{
  Cc_Timer *p;
  if((timer==NULL)||(_cc_hltimer==NULL))return;
  if(timer==_cc_hltimer)
  {
    _cc_hltimer=timer->next;
    free(timer);
  }
  else
  {
    for(p=_cc_hltimer;(p!=NULL)&&(p->next!=timer);p=p->next);  
    if(p!=NULL)
    {
      p->next=timer->next;
      free(timer);
    }
  }
}

long cc_get_timer_clock(Cc_Timer *timer)
{
  if(timer==NULL)return -1;
  return cc_get_tick()-timer->tminus;
}

void cc_set_timer_params(Cc_Timer *timer,Cc_Timer_P *params)
{
  if((timer==NULL)||(params==NULL))return;
  timer->win=params->win;
  timer->period=params->period;
  timer->prior=params->prior;
  timer->timer=params->timer;
}

void cc_get_timer_params(Cc_Timer *timer,Cc_Timer_P *params)
{
  if((timer==NULL)||(params==NULL))return;
  params->win=timer->win;
  params->period=timer->period;
  params->prior=timer->prior;
  params->timer=timer->timer;
}

bool cc_is_timer_run(Cc_Timer *timer)
{
  if(timer==NULL)return -1;
  return cc_get_timer_clock(timer)<=timer->period*timer->prior/100;
}

void cc_get_client_size(Cc_Win *win,long *x,long *y,long *vx,long *vy)
{
  if(win!=NULL)
  { 
    long dy=0;
    if(win->extra->type==CC_TP_DIALOG)
    {
      dy++;
      if(win->extra->dialog.menu!=NULL)dy++;
    }
    if(vx!=NULL)*vx=win->vx-(win->extra->type!=CC_TP_DIALOG?0:2);
    if(vy!=NULL)*vy=win->vy-dy-1;
    if(x!=NULL)*x=win->extra->type!=CC_TP_DIALOG?0:1;
    if(y!=NULL)*y=dy;
  }
  else
  {
    if(vx!=NULL)*vx=_cc_screenx;
    if(vy!=NULL)*vy=_cc_screeny-(_cc_hlmenu==NULL?0:1)-
                    (_cc_hldowntext==NULL?0:1);
    if(x!=NULL)*x=0;
    if(y!=NULL)*y=_cc_hlmenu==NULL?0:1;
  }
}

bool cc_send_message(Cc_Win *win,long x,long y,unsigned short key)
{
  if(!_cc_isactive(win))return false;
  if(((key&CC_MASK_KEY)>=CC_OFFSET_CHAR)&&
     ((key&CC_MASK_KEY)<CC_OFFSET_KEY))
    return _cc_dosendkeymessage(win,key);
  else if(((key&CC_MASK_KEY)>=CC_OFFSET_KEY)&&
          ((key&CC_MASK_KEY)<CC_OFFSET_MOUSE))
         return _cc_dosendsyskeymessage(win,key);
  else if(((key&CC_MASK_KEY)>=CC_OFFSET_MOUSE)&&
          ((key&CC_MASK_KEY)<CC_OFFSET_END))
         return _cc_dosendmousemessage(win,x,y,key);
}

void cc_delete_win(Cc_Win *win)
{
  cc_show_win(win,false);
  _cc_dodeletewin(win);  
}

char cc_get_win_type(Cc_Win *win)
{
  return win->extra->type;
}

bool cc_move_win(Cc_Win *win,long x,long y,long vx,long vy,long state)
{
  if(win==NULL)return false;
  if(x==CC_NOCHANGE)x=win->x;
  if(y==CC_NOCHANGE)y=win->y;
  if(vx==CC_NOCHANGE)vx=win->vx;
  if(vy==CC_NOCHANGE)vy=win->vy;
  if((win->extra->type==CC_TP_DIALOG)&&
     (win->extra->dialog.sizeok!=NULL))
    win->extra->dialog.sizeok(win,&x,&y,&vx,&vy);
  if(win->extra->type==CC_TP_DIALOG)
  {
    if(state==CC_NOCHANGE)state=win->extra->dialog.state;
    if((state<0)||(state>CC_SV_IN_MAXSTATE))return false;
    if(state==CC_SV_MAXIMIZED)
    {
      if(win->extra->dialog.state!=CC_SV_MAXIMIZED)
      {
        cc_get_client_size(win->parent,&x,&y,&vx,&vy);
      }
      else
      {
        x=win->x;
        y=win->y;
        vx=win->vx;
        vy=win->vy;
      }
    }
    else if(state==CC_SV_MINIMIZED)
    {
      if(win->extra->dialog.state==CC_SV_MAXIMIZED)
      {  
        vx=win->extra->dialog.tmpvx;
        x=win->extra->dialog.tmpx;
        y=win->extra->dialog.tmpy;
      }
      vy=1;
    }
    else if(state==CC_SV_NORMAL)
    {
      if(win->extra->dialog.state==CC_SV_MAXIMIZED)
      {
        vx=win->extra->dialog.tmpvx;
        vy=win->extra->dialog.tmpvy;
        x=win->extra->dialog.tmpx;
        y=win->extra->dialog.tmpy;
      }
      else if(win->extra->dialog.state==CC_SV_MINIMIZED)
      {
        vy=win->extra->dialog.tmpvy;
      }
    }
    if(vx<10)vx=10;
  }
  if(vx<1)vx=1;
  if(vy<1)vy=1;
  if((win->vx==vx)&&(win->vy==vy)&&(win->x==x)&&(win->y==y)&&
     (win->extra->type==CC_TP_DIALOG?win->extra->dialog.state==state:true))
    return false;
  if(win->extra->type==CC_TP_DIALOG)
  {  
    if(win->extra->dialog.state==CC_SV_NORMAL)
    {
      if(state==CC_SV_MAXIMIZED)
      {  
        win->extra->dialog.tmpvx=win->vx;
        win->extra->dialog.tmpvy=win->vy;
        win->extra->dialog.tmpx=win->x;
        win->extra->dialog.tmpy=win->y;
      }
      else if(state==CC_SV_MINIMIZED)
      {  
        win->extra->dialog.tmpvy=win->vy;
      }
    }
    if(win->extra->dialog.state==CC_SV_MINIMIZED)
    {
      if(state==CC_SV_MAXIMIZED)
      {  
        win->extra->dialog.tmpvx=win->vx;
        win->extra->dialog.tmpx=win->x;
        win->extra->dialog.tmpy=win->y;
      }
    }
  }
  win->x=x;
  win->y=y;  
  win->vx=vx;
  win->vy=vy;
  long px,py,pvx,pvy;
  cc_get_client_size(win->parent,&px,&py,&pvx,&pvy);
  win->flx=x;
  win->fly=y;
  win->frx=pvx+px-x-vx;
  win->fry=pvy+py-y-vy;
  if(win->extra->type==CC_TP_DIALOG)
  { 
    win->extra->dialog.state=state;
    if(state==CC_SV_NORMAL)
    {
      if((win->extra->dialog.style&CC_ST_DI_HASMAXIMIZE)==CC_ST_DI_HASMAXIMIZE)  
        win->extra->dialog.bmaximize->extra->button.text="O";
      if((win->extra->dialog.style&CC_ST_DI_HASMINIMIZE)==CC_ST_DI_HASMINIMIZE)  
        win->extra->dialog.bminimize->extra->button.text=".";
    }
    else if(state==CC_SV_MAXIMIZED)
    {
      if((win->extra->dialog.style&CC_ST_DI_HASMAXIMIZE)==CC_ST_DI_HASMAXIMIZE)  
        win->extra->dialog.bmaximize->extra->button.text="o";
      if((win->extra->dialog.style&CC_ST_DI_HASMINIMIZE)==CC_ST_DI_HASMINIMIZE)  
        win->extra->dialog.bminimize->extra->button.text=".";
    }
    else if(state==CC_SV_MINIMIZED)
    {
      if((win->extra->dialog.style&CC_ST_DI_HASMAXIMIZE)==CC_ST_DI_HASMAXIMIZE)  
        win->extra->dialog.bmaximize->extra->button.text="O";
      if((win->extra->dialog.style&CC_ST_DI_HASMINIMIZE)==CC_ST_DI_HASMINIMIZE)  
        win->extra->dialog.bminimize->extra->button.text="o";
    }
    if(win->extra->dialog.resize!=NULL)win->extra->dialog.resize(win);
  }
  if(_cc_isvisible(win))_cc_redraw();
  return true;
}

Cc_Win *cc_create_win(Cc_Win *parent,long x,long y,long vx,long vy,
                      Cc_Union_P *extra,long style,bool (*acel)(Cc_Win *win,
                      long x,long y,unsigned short key))
{
  Cc_Win *ne,*p;
  long size,px,py,pvx,pvy;
  ne=(Cc_Win*)malloc(sizeof(Cc_Win));
  ne->parent=parent;
  ne->x=x;
  ne->y=y;
  ne->vx=vx;
  ne->vy=vy;
  ne->svx=-1;
  ne->svy=-1;
  cc_get_client_size(parent,&px,&py,&pvx,&pvy);
  ne->flx=x;
  ne->fly=y;
  ne->frx=pvx+px-x-vx;
  ne->fry=pvy+py-y-vy;
  ne->style=style;
  ne->hasmodal=false;
  ne->acel=(void*)acel;
  ne->active=false;
  ne->lastfocus=NULL;
  ne->windata=malloc(0);
  ne->stat=0;
  ne->user=NULL;
  switch(extra->type)
  {
    case CC_TP_TEXT:size=sizeof(TEXT);break;
    case CC_TP_EDIT:size=sizeof(EDIT);break;
    case CC_TP_BUTTON:size=sizeof(BUTTON);break;
    case CC_TP_COMBO:size=sizeof(COMBO);break;
    case CC_TP_LIST:size=sizeof(LIST);break;
    case CC_TP_STATUS:size=sizeof(STATUS);break;
    case CC_TP_SCROLL:size=sizeof(SCROLL);break;
    case CC_TP_PAINT:size=sizeof(PAINT);break;
    case CC_TP_MENU:size=sizeof(MENU);break;
    case CC_TP_DIALOG:size=sizeof(DIALOG);break;
    case TP_FADE:size=sizeof(FADE);break;
  }
  ne->extra=(UNION*)malloc(size);
  ne->next=NULL;
  ne->child=NULL;
  ne->childend=NULL;
  if(_cc_hlwin==NULL)
  {
    _cc_hlwin=ne;
    _cc_hlendwin=ne;
  }
  else
  {
    if(parent==NULL)
    {
      _cc_hlendwin->next=ne;
      _cc_hlendwin=ne;
    }
    else
    {
      if(parent->child==NULL)
      {
        parent->child=ne;
        parent->childend=ne;
      }
      else
      {
        parent->childend->next=ne;
        parent->childend=ne;
      }
    }
  }
  if(extra->type==CC_TP_TEXT)
  {
    if(ne->vy>1)ne->vy=1;
  }
  else if(extra->type==CC_TP_EDIT)
  {
    ne->extra->edit.curpos=0;
    ne->extra->edit.maskpos=-1;
    ne->extra->edit.scroll=0;
    ne->extra->edit.text=(unsigned char*)malloc(1);
    ne->extra->edit.text[0]='\0';
  }
  else if(extra->type==CC_TP_SCROLL)
  {
    SCROLL *scroll;
    scroll=&ne->extra->scroll;
    scroll->smooth=false;
    scroll->smoothpos=0;
    scroll->sup=SC_UP;
    scroll->sdown=SC_UP;
    scroll->spageup=SC_UP;
    scroll->spagedown=SC_UP;
    if(extra->scroll.vert)
    {
      if(ne->vx>1)ne->vx=1;
    }
    else
    {
      if(ne->vy>1)ne->vy=1;
    }
  }
  else if(extra->type==CC_TP_BUTTON)
  {
    BUTTON *button;
    button=&ne->extra->button;
    button->status=TS_UP;
  }
  else if(extra->type==CC_TP_LIST)
  {
    Cc_Scroll_P scroll;
    LIST *list=&ne->extra->list;
    scroll.type=CC_TP_SCROLL;
    scroll.pos=0;
    scroll.cnt=1;
    scroll.change=_cc_scrollincombochangeproc;
    list->exvscroll=EX_NONE;
    list->exhscroll=EX_NONE;
    list->lencells=NULL;
    list->numlines=0;
    list->maxitemlen=0;
    list->oldscrollpos=-1;
    list->activeitem=NULL;
    list->scrollupitem=NULL;
    scroll.vert=true;
    list->vscroll=cc_create_win(ne,ne->vx-1,1,1,ne->vy-2,(Cc_Union_P*)&scroll,0,
                                NULL);
    scroll.vert=false;
    list->hscroll=cc_create_win(ne,1,ne->vy-1,ne->vx-2,1,(Cc_Union_P*)&scroll,0,
                                NULL);
    if(extra->list.combotyp==CC_LI_COMBO)
    {
      Cc_Union_P fade;
      fade.type=TP_FADE;
      list->hfade=cc_create_win(ne,2,ne->vy,ne->vx,1,(Cc_Union_P*)&fade,
                                CC_ST_VISIBLE,NULL);
      list->vfade=cc_create_win(ne,ne->vx>1?ne->vx:ne->vx+1,1,ne->vx>1?2:1,
                                ne->vy-1,(Cc_Union_P*)&fade,CC_ST_VISIBLE,NULL);
    }
    else
    {
      list->hfade=NULL;
      list->vfade=NULL;
    }
  }
  else if(extra->type==CC_TP_COMBO)
  {
    Cc_List_P list;
    COMBO *combo=&ne->extra->combo;
    long x,y;
    if(ne->vy>1)ne->vy=1;
    x=-1;y=ne->vy;
    list.type=CC_TP_LIST;
    list.activeline=0;
    list.lines=NULL;
    list.combotyp=CC_LI_COMBO;
    list.change=NULL;
    list.dblclk=_cc_combodblclkproc;
    combo->pushed=SC_UP;
    combo->scroll=0;
    combo->activeitem=NULL;
    combo->list=cc_create_win(ne,x,y,ne->vx+2,ne->extra->combo.lstvy,
                              (Cc_Union_P*)&list,CC_ST_TOP_WIN,NULL);
    if((style&CC_ST_CO_WITH_EDIT)==CC_ST_CO_WITH_EDIT)
    {
      Cc_Edit_P edit;
      edit.type=CC_TP_EDIT;
      combo->edit=cc_create_win(ne,0,0,ne->vx-1,1,(Cc_Union_P*)&edit,
                                CC_ST_VISIBLE,_cc_claeditacel);
    }
    else
      combo->edit=NULL;
  }
  else if(extra->type==CC_TP_STATUS)
  {
    Cc_Status_P *status=&extra->status;
    if(extra->status.vert)
    {
      if(ne->vx>1)ne->vx=1;
    }
    else
    {
      if(ne->vy>1)ne->vy=1;
    }
  }
  else if(extra->type==CC_TP_MENU)
  {
    MENU *menu=&ne->extra->menu;
    menu->activeline=-1;
    if(extra->menu.vert)
    {
      Cc_Union_P fade;
      fade.type=TP_FADE;
      ne->style|=CC_ST_TOP_WIN;
      menu->hfade=cc_create_win(ne,2,ne->vy,ne->vx,1,(Cc_Union_P*)&fade,
                                CC_ST_VISIBLE,NULL);
      menu->vfade=cc_create_win(ne,ne->vx>1?ne->vx:ne->vx+1,1,ne->vx>1?2:1,
                                ne->vy-1,(Cc_Union_P*)&fade,CC_ST_VISIBLE,NULL);
    }
  }
  else if(extra->type==CC_TP_DIALOG)
  {
    DIALOG *dialog=&ne->extra->dialog;
    dialog->state=CC_SV_NORMAL;
    Cc_Button_P button;
    button.type=CC_TP_BUTTON;
    button.style=CC_BT_NORMAL;
    button.checked=false;
    button.hasfocus=false;
    long n=3;
    button.text="X";
    button.push=_cc_bclosepush;
    dialog->bclose=cc_create_win(ne,ne->vx-n,0,1,1,(Cc_Union_P*)&button,0,NULL);
    n++;
    if((extra->dialog.style&CC_ST_DI_HASMAXIMIZE)==CC_ST_DI_HASMAXIMIZE)  
    {
      button.text="O";
      button.push=_cc_bmaximizepush;
      dialog->bmaximize=cc_create_win(ne,ne->vx-n,0,1,1,(Cc_Union_P*)&button,0,
                                      NULL);
      n++;
    }
    else dialog->bmaximize=NULL;
    if((extra->dialog.style&CC_ST_DI_HASMINIMIZE)==CC_ST_DI_HASMINIMIZE)  
    {
      button.text=".";
      button.push=_cc_bminimizepush;
      dialog->bminimize=cc_create_win(ne,ne->vx-n,0,1,1,(Cc_Union_P*)&button,0,
                                      NULL);
    }
    else dialog->bminimize=NULL;
    FADE fade;
    fade.type=TP_FADE;
    dialog->hfade=cc_create_win(ne,2,ne->vy,ne->vx,1,(Cc_Union_P*)&fade,
                                CC_ST_VISIBLE,NULL);
    dialog->vfade=cc_create_win(ne,ne->vx>1?ne->vx:ne->vx+1,1,ne->vx>1?2:1,
                                ne->vy-1,(Cc_Union_P*)&fade,CC_ST_VISIBLE,NULL);
  }
  cc_set_win_params(ne,extra);
  if((style&CC_ST_VISIBLE)==CC_ST_VISIBLE)cc_show_win(ne,true);
  return ne;
}

void cc_set_win_params(Cc_Win *win,Cc_Union_P *params)
{
  if((win==NULL)||(params==NULL))return;
  win->extra->type=params->type;
  switch(params->type)
  {
    case CC_TP_TEXT:_cc_settextparams(win,params);break;
    case CC_TP_EDIT:_cc_seteditparams(win,params);break;
    case CC_TP_BUTTON:_cc_setbuttonparams(win,params);break;
    case CC_TP_SCROLL:_cc_setscrollparams(win,params);break;
    case CC_TP_COMBO:_cc_setcomboparams(win,params);break;
    case CC_TP_LIST:_cc_setlistparams(win,params);break;
    case CC_TP_STATUS:_cc_setstatusparams(win,params);break;
    case CC_TP_PAINT:_cc_setpaintparams(win,params);break;
    case CC_TP_MENU:_cc_setmenuparams(win,params);break;
    case CC_TP_DIALOG:_cc_setdialogparams(win,params);break;
  }
  _cc_redrawclientwin(win);
}

void cc_get_win_params(Cc_Win *win,Cc_Union_P *params)
{
  if((win==NULL)||(params==NULL))return;
  params->type=win->extra->type;
  switch(params->type)
  {
    case CC_TP_TEXT:_cc_gettextparams(win,params);break;
    case CC_TP_EDIT:_cc_geteditparams(win,params);break;
    case CC_TP_BUTTON:_cc_getbuttonparams(win,params);break;
    case CC_TP_SCROLL:_cc_getscrollparams(win,params);break;
    case CC_TP_COMBO:_cc_getcomboparams(win,params);break;
    case CC_TP_LIST:_cc_getlistparams(win,params);break;
    case CC_TP_STATUS:_cc_getstatusparams(win,params);break;
    case CC_TP_PAINT:_cc_getpaintparams(win,params);break;
    case CC_TP_MENU:_cc_getmenuparams(win,params);break;
    case CC_TP_DIALOG:_cc_getdialogparams(win,params);break;
  }
}

#include <term.h>
#undef buttons

bool cc_message_pump()
{
  Cc_Timer *p,*pnext;
  long time;
  Gpm_Event ev;
  static MEVENT event;
  if(!_cc_apprun)return false;  
  while(_cc_waitkeyevent);
  _cc_waitevent=true;
  if(_cc_gpmgetevent(&ev))
  {
    event.x=ev.x;
    event.y=ev.y;
    event.bstate=0;
    if((ev.buttons&GPM_B_LEFT)==GPM_B_LEFT)
    {
      if((ev.type&GPM_DOWN)==GPM_DOWN)event.bstate|=BUTTON1_PRESSED;
      else if((ev.type&GPM_UP)==GPM_UP)event.bstate|=BUTTON1_RELEASED;
    }
    if((ev.buttons&GPM_B_RIGHT)==GPM_B_RIGHT)
    {
      if((ev.type&GPM_DOWN)==GPM_DOWN)event.bstate|=BUTTON3_PRESSED;
      else if((ev.type&GPM_UP)==GPM_UP)event.bstate|=BUTTON3_RELEASED;
    }
    if((ev.modifiers&SHIFT_PRESSED)==SHIFT_PRESSED)event.bstate|=BUTTON_SHIFT;
    if((ev.modifiers&CTRL_PRESSED)==CTRL_PRESSED)event.bstate|=BUTTON_CTRL;
    if(((ev.modifiers&ALTL_PRESSED)==ALTL_PRESSED)||
       ((ev.modifiers&ALTR_PRESSED)==ALTR_PRESSED))
      event.bstate|=BUTTON_ALT;
    _cc_domouseevent(&event);
    if(!_cc_waitevent)return _cc_apprun;
  }
  if((_cc_screenx!=columns)||(_cc_screeny!=lines))
  {
    _cc_screenx=columns;
    _cc_screeny=lines;
    _cc_mainwin.vx=_cc_screenx;
    _cc_mainwin.vy=_cc_screeny;
    _cc_mainwin.windata=realloc(_cc_mainwin.windata,
                                _cc_screenx*_cc_screeny*sizeof(attr_t));
    _cc_cmap=realloc(_cc_cmap,_cc_screenx*_cc_screeny*sizeof(CMAP));
    if(_cc_resizescreen!=NULL)_cc_resizescreen(NULL);
    _cc_redraw();
  }
  if(_cc_redrawmouse<2)
  {
    Gpm_DrawPointer(_cc_gpmev.x,_cc_gpmev.y,gpm_consolefd);
    _cc_redrawmouse++;
  }
  refresh();
  for(p=_cc_hltimer;p!=NULL;p=pnext)
  {
    time=cc_get_tick();
    pnext=p->next;
    if(time-p->tminus>=p->period)
    {
      p->tminus=time; 
      p->timer(p);
    }
  }
  _cc_waitevent=false;
  nanosleep(&(struct timespec){0,TIMER_GRANULATE},NULL);
  return _cc_apprun;
}

void cc_init(int argc,char *argv[])
{
  long i;
  struct sigaction act;
  Gpm_Event ev;
  act.sa_handler=SIG_IGN;
  act.sa_flags=0;
  sigemptyset(&act.sa_mask);
  sigaction(SIGINT,&act,NULL);
  sigaction(SIGQUIT,&act,NULL);
  initscr();
  start_color();
  _cc_oldattr=attrset(0);
  ESCDELAY=0;
  _cc_uglycharset=false;
  for(i=1;i<argc;i++)if(strcmp(argv[i],"-a")==0){_cc_uglycharset=true;break;}
  if(_cc_uglycharset)_cc_mapsymbol=_cc_ugmsymbol;  
  _cc_hascolors=has_colors();
  intrflush(stdscr,false);
  keypad(stdscr,true);
  cbreak();
  noecho();
  nodelay(stdscr,false);
  curs_set(0);
  _cc_mousex=-1;
  _cc_mousey=-1;
  pthread_create(&_cc__cc_getchthreadp,NULL,_cc_getchthread,NULL);
  Gpm_Connect conn;
  conn.eventMask=GPM_MOVE|GPM_DRAG|GPM_DOWN|GPM_UP;
  conn.defaultMask=0;
  conn.minMod=0;
  conn.maxMod=-1;
  gpm_zerobased=true;
  if((Gpm_Open(&conn,0)!=-1)&&(Gpm_GetEvent(&ev)!=-1))
  {  
    _cc_gpmev.x=_cc_mousex=ev.x;
    _cc_gpmev.y=_cc_mousey=ev.y;
    _cc_mouseactive=MOUSE_GPM;
    Gpm_Repeat(0);
    GPM_XTERM_ON;
    pthread_create(&_cc_gpmthreadp,NULL,_cc_gpmthread,NULL);
  }
  else
  {
    _cc_mouseactive=MOUSE_XTERM;
    mousemask(ALL_MOUSE_EVENTS|REPORT_MOUSE_POSITION,NULL);
    mouseinterval(0);
  }
  _cc_screenx=columns;
  _cc_screeny=lines;
  _cc_mainwin.x=0;
  _cc_mainwin.y=0;
  _cc_mainwin.vx=_cc_screenx;
  _cc_mainwin.vy=_cc_screeny;
  _cc_mainwin.parent=NULL;
  _cc_mainwin.windata=malloc(_cc_screenx*_cc_screeny*sizeof(attr_t));
  _cc_cmap=malloc(_cc_screenx*_cc_screeny*sizeof(CMAP));
  Cc_Menu_P menu;
  menu.type=CC_TP_MENU;
  menu.cback=CC_C_DEFAULT;
  menu.cborder=CC_C_DEFAULT;
  menu.ctext=CC_C_DEFAULT;
  menu.cutext=CC_C_DEFAULT;
  menu.cactive=CC_C_DEFAULT;
  menu.cactivetext=CC_C_DEFAULT;
  menu.cactiveutext=CC_C_DEFAULT;
  menu.change=NULL;
  menu.select=_cc_clipboardmenuproc;
  menu.vert=true;
  _cc_clipboardmenu=cc_create_menu(NULL,&menu,NULL);
  cc_add_menu_item(_cc_clipboardmenu,&(Cc_Menu_I){0,false,"Cu&t",
                   CC_MOD_CTRL|'X',NULL});
  cc_add_menu_item(_cc_clipboardmenu,&(Cc_Menu_I){1,false,"&Copy",
                   CC_MOD_CTRL|'C',NULL});
  cc_add_menu_item(_cc_clipboardmenu,&(Cc_Menu_I){2,false,"&Paste",
                   CC_MOD_CTRL|'V',NULL});
  cc_add_menu_item(_cc_clipboardmenu,&(Cc_Menu_I){3,false,"&Delete",0,NULL});
  cc_add_menu_item(_cc_clipboardmenu,&(Cc_Menu_I){4,false,"Select &All",0,
                   NULL});
  _cc_redraw();
}

void cc_done()
{
  while(_cc_waitevent);_cc_waitevent=true;
  while(_cc_waitkeyevent);_cc_waitkeyevent=true;
  struct sigaction act;
  bkgd(_cc_oldattr);
  clear();
  refresh();
  if(_cc_mouseactive==MOUSE_GPM)
  {
    GPM_XTERM_OFF;
    Gpm_Close();
  }
  noecho();
  cbreak();
  free(_cc_mainwin.windata);
  free(_cc_cmap);
  endwin();
  mousemask(0,NULL);
  curs_set(1);
  act.sa_handler=SIG_DFL;
  act.sa_flags=0;
  sigemptyset(&act.sa_mask);
  sigaction(SIGINT,&act,NULL);
  sigaction(SIGQUIT,&act,NULL);
}

Platon Group <platon@platon.org> http://platon.org/
Copyright © 2002-2006 Platon Group
Site powered by Metafox CMS
Go to Top