diff --git a/programs/develop/libraries/libGUI/SRC/compilation/MinGW/build.bat b/programs/develop/libraries/libGUI/SRC/compilation/MinGW/build.bat new file mode 100644 index 0000000000..809b235287 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/compilation/MinGW/build.bat @@ -0,0 +1,3 @@ +gcc -c -O2 -nostdinc -nostdlib -march=pentium -fomit-frame-pointer -fno-builtin -o libGUI.obj libGUI.c +strip -X --strip-unneeded libGUI.obj +@pause diff --git a/programs/develop/libraries/libGUI/SRC/compilation/cygwin/Makefile b/programs/develop/libraries/libGUI/SRC/compilation/cygwin/Makefile new file mode 100644 index 0000000000..d0359c3ca2 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/compilation/cygwin/Makefile @@ -0,0 +1,11 @@ +SRC = libGUI.c +TARGET = libGUI.obj +CFLAGS = -O2 -nostdinc -nostdlib -march=pentium -fomit-frame-pointer -fno-builtin -fno-builtin-printf +CC = gcc + +all: + $(CC) -c $(SRC) $(CFLAGS) -o $(TARGET) + strip -x -S $(TARGET) + $(CC) -S $(SRC) $(CFLAGS) +clean: + rm $(TARGET) diff --git a/programs/develop/libraries/libGUI/SRC/control_button.h b/programs/develop/libraries/libGUI/SRC/control_button.h new file mode 100644 index 0000000000..1c1434f79f --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_button.h @@ -0,0 +1,11 @@ +/* + control button data +*/ + +#define FLAG_INSERT_BUTTON_ON 0x1; +#define FLAG_INSERT_BUTTON_OFF 0xfe; +#define FLAG_PRESSED_BUTTON_ON 0x2 +#define FLAG_PRESSED_BUTTON_OFF 0xfd +#define FLAG_RELEASED_BUTTON_ON 0x4 +#define FLAG_RELEASED_BUTTON_OFF 0xfb + diff --git a/programs/develop/libraries/libGUI/SRC/control_button.inc b/programs/develop/libraries/libGUI/SRC/control_button.inc new file mode 100644 index 0000000000..8cbaef1e31 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_button.inc @@ -0,0 +1,414 @@ +/* + control Button +*/ + +void DrawFocuseForButton(struct ControlButton *Button) +{ + int x; + int y; + int sizex; + int sizey; + struct FINITION *fin; + + x=Button->ctrl_x; + y=Button->ctrl_y; + sizex=Button->ctrl_sizex; + sizey=Button->ctrl_sizey; + fin=(struct FINITION*)Button->finition; + + Draw(fin,TOOL_RECTANGLE,x,y,sizex,sizey,0xbfff); +} + +void DrawPressedButton(struct ControlButton *Button) +{ + int x; + int y; + int sizex; + int sizey; + struct FINITION *fin; + gui_message_t message; + + x=Button->ctrl_x; + y=Button->ctrl_y; + sizex=Button->ctrl_sizex; + sizey=Button->ctrl_sizey; + fin=(struct FINITION*)Button->finition; + + Draw(fin,TOOL_GRADIENT_DOWN_FILLED_RECTANGLE,x,y,sizex,sizey/2,COLOR_FON,COLOR_MIDDLE_LIGHT); + Draw(fin,TOOL_GRADIENT_DOWN_FILLED_RECTANGLE,x,y+sizey/2,sizex,sizey/2,COLOR_MIDDLE_LIGHT,COLOR_FON); + + + Draw(fin,TOOL_HORIZONTAL_LINE,x,x+sizex-1,y,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_VERTICAL_LINE,x,y,y+sizey-1,COLOR_LIGHT); + Draw(fin,TOOL_HORIZONTAL_LINE,x,x+sizex-1,y+sizey-1,COLOR_LIGHT); + Draw(fin,TOOL_VERTICAL_LINE,x,y,y+sizey-1,COLOR_ABSOLUTE_DARK); + + if (fin->flags & FINITION_ON) + { + message.type=MESSAGE_FULL_REDRAW_ALL_WITH_FINITION; + message.arg1=fin->x; + message.arg2=fin->y; + message.arg3=fin->sizex; + message.arg4=fin->sizey; + } + else + { + message.type=MESSAGE_FULL_REDRAW_ALL; + } + + SendMessage((struct HEADER*)Button,&message); + + if (Button->flags & FLAG_FOCUSE_INPUT_ON) DrawFocuseForButton(Button); +} + +void DrawInsertButton(struct ControlButton *Button) +{ + int x; + int y; + int sizex; + int sizey; + struct FINITION *fin; + + x=Button->ctrl_x; + y=Button->ctrl_y; + sizex=Button->ctrl_sizex; + sizey=Button->ctrl_sizey; + fin=(struct FINITION*)Button->finition; + Draw(fin,TOOL_RECTANGLE,x,y,sizex,sizey,COLOR_INSERT); +} + +void DrawButton(struct ControlButton *Button) +{ + int x; + int y; + int sizex; + int sizey; + struct FINITION *fin; + gui_message_t message; + + x=Button->ctrl_x; + y=Button->ctrl_y; + sizex=Button->ctrl_sizex; + sizey=Button->ctrl_sizey; + fin=(struct FINITION*)Button->finition; + + Draw(fin,TOOL_GRADIENT_UP_FILLED_RECTANGLE,x,y,sizex,sizey,COLOR_FON,COLOR_MIDDLE_LIGHT); + //Draw(fin,TOOL_GRADIENT_DOWN_FILLED_RECTANGLE,x,y+sizey/2,sizex,sizey/2,COLOR_FON,COLOR_MIDDLE_LIGHT); + + + Draw(fin,TOOL_RECTANGLE,x,y,sizex,sizey,COLOR_ABSOLUTE_DARK); + + Draw(fin,TOOL_HORIZONTAL_LINE,x+1,x+sizex-2,y+1,COLOR_LIGHT); + Draw(fin,TOOL_VERTICAL_LINE,x+sizex-2,y+1,y+sizey-2,COLOR_MIDDLE_LIGHT); + Draw(fin,TOOL_HORIZONTAL_LINE,x+1,x+sizex-2,y+sizey-2,COLOR_MIDDLE_LIGHT); + Draw(fin,TOOL_VERTICAL_LINE,x+1,y+1,y+sizey-2,COLOR_LIGHT); + + if (Button->child_bk!=NULL) + { + if (fin->flags & FINITION_ON) + { + message.type=MESSAGE_FULL_REDRAW_ALL_WITH_FINITION; + message.arg1=fin->x; + message.arg2=fin->y; + message.arg3=fin->sizex; + message.arg4=fin->sizey; + } + else + { + message.type=MESSAGE_FULL_REDRAW_ALL; + } + SendMessage((struct HEADER*)Button,&message); + } + if (Button->flags & FLAG_FOCUSE_INPUT_ON) DrawFocuseForButton(Button); +} + +//--------------------------------------------------------------------------------- +// control Button +//--------------------------------------------------------------------------------- +void ButtonProc(struct ControlButton *button,struct MESSAGE *message) +{ + int x,y,btn_state; + char v; + struct TIMER *timer; + struct FINITION *fin; + parent_t *main_parent; + + switch(message->type) + { + case MESSAGE_FULL_REDRAW_ALL: + { + //draw button + if (button->flags & FLAG_SHOW_CONTROL) DrawButton(button); + break; + } + case MESSAGE_FULL_REDRAW_ALL_WITH_FINITION: + { + fin=(struct FINITION*)button->finition; + fin->flags=fin->flags | FINITION_ON; + fin->x=message->arg1; + fin->y=message->arg2; + fin->sizex=message->arg3; + fin->sizey=message->arg4; + DrawButton(button); + break; + } + case MESSAGE_KEYS_EVENT: + { + main_parent=(parent_t*)button->main_parent; + //not relazed yet + if (button->flags & FLAG_FOCUSE_INPUT_ON) + { + if (message->arg1==KEY_DOWN) + { + if (message->arg2==SC_SPACE) + { + button->btn_flags=button->btn_flags | FLAG_PRESSED_BUTTON_ON; + + if (ControlCheckCallbackEvent(button,(DWORD)BUTTON_PRESSED_EVENT)!=NULL) + { + button->flags=button->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)button; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(button,(DWORD)BUTTON_PRESSED_EVENT); + main_parent->number_callbacks++; + } + if (button->flags & FLAG_SHOW_CONTROL) DrawPressedButton(button); + } + } + else + { + if (message->arg2==SC_SPACE) + { + button->btn_flags=button->btn_flags | FLAG_RELEASED_BUTTON_ON; + button->btn_flags=button->btn_flags & FLAG_PRESSED_BUTTON_OFF; + + if (ControlCheckCallbackEvent(button,(DWORD)BUTTON_RELEASED_EVENT)!=NULL) + { + button->flags=button->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)button; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(button,(DWORD)BUTTON_RELEASED_EVENT); + main_parent->number_callbacks++; + } + if (button->flags & FLAG_SHOW_CONTROL) DrawButton(button); + } + } + } + break; + } + case MESSAGE_SPECIALIZED: + { + if (button->flags & FLAG_GET_SPECIALIZED_MESSAGE_ON) + { + if (button->flags & FLAG_SHOW_CONTROL) DrawButton(button); + button->flags=button->flags & FLAG_GET_SPECIALIZED_MESSAGE_OFF; + } + break; + } + case MESSAGE_MOUSE_EVENT: + { //check press of mouse buttons + x=message->arg1; + y=message->arg2; + main_parent=(parent_t*)button->main_parent; + + if (message->arg3==MOUSE_LEFT_BUTTON_UP) + { + //insert of button + if (CheckCrossBox((struct HEADER*)button,x,y)==TRUE) + { + v=button->btn_flags & FLAG_INSERT_BUTTON_ON; + if ((ControlCheckCallbackEvent(button,(DWORD)BUTTON_ENTER_EVENT)!=NULL) && (v==FALSE)) + { + button->flags=button->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)button; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(button,(DWORD)BUTTON_ENTER_EVENT); + main_parent->number_callbacks++; + } + button->btn_flags=button->btn_flags | FLAG_INSERT_BUTTON_ON; + + if (button->flags & FLAG_SHOW_CONTROL) DrawInsertButton(button); + } + else + { + v=button->btn_flags & FLAG_INSERT_BUTTON_ON; + if (v==TRUE) + { + if (ControlCheckCallbackEvent(button,(DWORD)BUTTON_LEAVE_EVENT)!=NULL) + { + button->flags=button->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)button; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(button,(DWORD)BUTTON_LEAVE_EVENT); + main_parent->number_callbacks++; + } + button->btn_flags=button->btn_flags & FLAG_INSERT_BUTTON_OFF; + if (button->flags & FLAG_SHOW_CONTROL) DrawButton(button); + } + } + + if (button->btn_flags & FLAG_PRESSED_BUTTON_ON) + { + button->btn_flags=button->btn_flags & FLAG_PRESSED_BUTTON_OFF; + button->btn_flags=button->btn_flags | FLAG_RELEASED_BUTTON_ON; + + if (ControlCheckCallbackEvent(button,(DWORD)BUTTON_RELEASED_EVENT)!=NULL) + { + button->flags=button->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)button; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(button,(DWORD)BUTTON_RELEASED_EVENT); + main_parent->number_callbacks++; + } + if (button->flags & FLAG_SHOW_CONTROL) DrawButton(button); + } + + + } + else + { + if (CheckCrossBox((struct HEADER*)button,x,y)==TRUE) + { + if (message->arg3==MOUSE_LEFT_BUTTON_DOWN) + { + if ((button->btn_flags & FLAG_PRESSED_BUTTON_ON)==FALSE) + {if (button->flags & FLAG_SHOW_CONTROL) + DrawPressedButton(button);} + button->btn_flags=button->btn_flags | FLAG_PRESSED_BUTTON_ON; + } + } + + if ((message->arg3==MOUSE_LEFT_BUTTON_DOWN) && (button->btn_flags & FLAG_PRESSED_BUTTON_ON)) + { + if (ControlCheckCallbackEvent(button,(DWORD)BUTTON_PRESSED_EVENT)!=NULL) + { + button->flags=button->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)button; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(button,(DWORD)BUTTON_PRESSED_EVENT); + main_parent->number_callbacks++; + } + } + } + break; + } + case MESSAGE_CHANGE_POSITION_EVENT: + { + button->ctrl_x=button->ctrl_x+message->arg1; + button->ctrl_y=button->ctrl_y+message->arg2; + break; + } + case MESSAGE_CALL_TIMER_EVENT: + { + if (button->timer!=(DWORD*)NULL) + { + timer=(struct TIMER*)button->timer; + if (timer->flags & FLAG_TIMER_ON) Timer(timer); + } + break; + } + case MESSAGE_SET_FOCUSE: + { + button->flags=button->flags | FLAG_FOCUSE_INPUT_ON; + if (button->flags & FLAG_SHOW_CONTROL) DrawButton(button); + break; + } + case MESSAGE_CHANGE_FOCUSE: + { + button->flags=button->flags & FLAG_FOCUSE_INPUT_OFF; + if (button->flags & FLAG_SHOW_CONTROL) DrawButton(button); + break; + } + case MESSAGE_DESTROY_CONTROL: + { + if (button->timer!=(DWORD*)NULL) free(button->timer); + free(button->finition); + break; + } + case MESSAGE_SET_MAIN_PARENT: + { + SendMessage((struct HEADER*)button,message); + button->main_parent=(DWORD*)message->arg1; + break; + } + default: break; + } + //send message to child controls(if there is) + SendMessage((struct HEADER*)button,message); +} + +//--------------------------------------------------------------------------------- +// create control Button +//--------------------------------------------------------------------------------- +void* CreateButton(struct ButtonData *info_for_control) +{ + struct ControlButton *Button; + struct FINITION *fin; + + Button=malloc(sizeof(struct ControlButton)); + Button->finition=malloc(sizeof(struct FINITION)); + fin=(struct FINITION*)Button->finition; + fin->flags=0; + + ID++; +#ifdef DEBUG + printf("\ncreated button with ID=%d",(int)ID); +#endif + Button->child_bk=(DWORD*)NULL; + Button->child_fd=(DWORD*)NULL; + Button->active_control_for_keys=(DWORD*)NULL; + Button->active_control_for_mouse=(DWORD*)NULL; + Button->callback=(DWORD*)NULL; + Button->timer=(DWORD*)NULL; + + Button->ctrl_proc=(DWORD*)&ButtonProc; + Button->ctrl_x=info_for_control->x; + Button->ctrl_y=info_for_control->y; + Button->ctrl_sizex=info_for_control->width; + Button->ctrl_sizey=info_for_control->height; + Button->ctrl_ID=ID; + Button->flags=0; + Button->flags=Button->flags | FLAG_SHOW_CONTROL; + Button->flags=Button->flags | FLAG_FOCUSE_INPUT_SUPPOROTE; + + Button->btn_flags=0; + + return(Button); +} + +void* CreateButtonWithText(gui_button_data_t *info,char *txt) +{ + gui_button_t *Button; + gui_text_t *text; + gui_text_data_t txtdata; + int len; + + Button=CreateButton(info); + len=strlen(txt)+1;//one byte for simbol end of string + + txtdata.x=0; + txtdata.y=0; + txtdata.font=NULL; + txtdata.background=FALSE; + txtdata.color=0; + txtdata.text=malloc(len); + memmove(txtdata.text,txt,len); + txtdata.text[len]='\0'; + text=CreateText(&txtdata); + + if (text->ctrl_sizex>Button->ctrl_sizex) Button->ctrl_sizex=text->ctrl_sizex+10; + if (text->ctrl_sizey>Button->ctrl_sizey) Button->ctrl_sizey=text->ctrl_sizey+6; + + text->ctrl_x=(Button->ctrl_sizex/2)-(text->ctrl_sizex/2); + text->ctrl_y=(Button->ctrl_sizey/2)-(text->ctrl_sizey/2); + PackControls(Button,text); + + return(Button); +} + diff --git a/programs/develop/libraries/libGUI/SRC/control_image.h b/programs/develop/libraries/libGUI/SRC/control_image.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/programs/develop/libraries/libGUI/SRC/control_image.inc b/programs/develop/libraries/libGUI/SRC/control_image.inc new file mode 100644 index 0000000000..7201112c4b --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_image.inc @@ -0,0 +1,162 @@ +/* + control Image +*/ + +void DisplayImage(gui_image_t *Image) +{ + int x; + int y; + int sizex; + int sizey; + struct FINITION *fin; + + x=Image->ctrl_x; + y=Image->ctrl_y; + sizex=Image->ctrl_sizex; + sizey=Image->ctrl_sizey; + fin=(struct FINITION*)Image->finition; + + Draw(fin,TOOL_IMAGE,x,y,sizex,sizey,Image->bits_per_pixel,Image->img); +} + +//--------------------------------------------------------------------------------- +// control Image +//--------------------------------------------------------------------------------- +void ImageProc(gui_image_t *Image,gui_message_t *message) +{ + finition_t *fin; + + switch(message->type) + { + case MESSAGE_FULL_REDRAW_ALL: + { + //draw Image + if (Image->flags & FLAG_SHOW_CONTROL) DisplayImage(Image); + break; + } + case MESSAGE_FULL_REDRAW_ALL_WITH_FINITION: + { + fin=(struct FINITION*)Image->finition; + fin->flags=fin->flags | FINITION_ON; + fin->x=message->arg1; + fin->y=message->arg2; + fin->sizex=message->arg3; + fin->sizey=message->arg4; + DisplayImage(Image); + break; + } + case MESSAGE_SPECIALIZED: + { + if (Image->flags & FLAG_GET_SPECIALIZED_MESSAGE_ON) + { + if (Image->flags & FLAG_SHOW_CONTROL) DisplayImage(Image); + Image->flags=Image->flags & FLAG_GET_SPECIALIZED_MESSAGE_OFF; + } + break; + } + case MESSAGE_CHANGE_POSITION_EVENT: + { + Image->ctrl_x=Image->ctrl_x+message->arg1; + Image->ctrl_y=Image->ctrl_y+message->arg2; + break; + } + case MESSAGE_DESTROY_CONTROL: + { + free(Image->finition); + free(Image->img); + break; + } + case MESSAGE_SET_MAIN_PARENT: + { + SendMessage((struct HEADER*)Image,message); + Image->main_parent=(DWORD*)message->arg1; + break; + } + + default: break; + } + //send message to child controls(if there is) + SendMessage((struct HEADER*)Image,message); +} + +//--------------------------------------------------------------------------------- +// create control Image +//--------------------------------------------------------------------------------- +void* CreateImage(struct ImageData *info_for_control) +{ + gui_image_t *Image; + finition_t *fin; + DWORD sizemem; + + Image=malloc(sizeof(struct ControlImage)); + Image->finition=malloc(sizeof(struct FINITION)); + fin=(struct FINITION*)Image->finition; + fin->flags=0; + + ID++; +#ifdef DEBUG + printf("\ncreated image with ID=%d",(int)ID); +#endif + Image->child_bk=(DWORD*)NULL; + Image->child_fd=(DWORD*)NULL; + Image->active_control_for_keys=(DWORD*)NULL; + Image->active_control_for_mouse=(DWORD*)NULL; + Image->callback=(DWORD*)NULL; + Image->timer=(DWORD*)NULL; + + Image->ctrl_proc=(DWORD*)&ImageProc; + Image->ctrl_x=(DWORD)info_for_control->x; + Image->ctrl_y=(DWORD)info_for_control->y; + Image->ctrl_sizex=(DWORD)info_for_control->width; + Image->ctrl_sizey=(DWORD)info_for_control->height; + Image->bits_per_pixel=info_for_control->bits_per_pixel; + Image->ctrl_ID=ID; + Image->flags=0; + Image->flags=Image->flags | FLAG_SHOW_CONTROL; + + switch(Image->bits_per_pixel) + { + case 32: + { + sizemem=(Image->ctrl_sizex*Image->ctrl_sizey)*4; + Image->bytes_per_pixel=4; + break; + } + case 24: + { + sizemem=(Image->ctrl_sizex*Image->ctrl_sizey)*3; + Image->bytes_per_pixel=3; + break; + } + case 16: + { + sizemem=(Image->ctrl_sizex*Image->ctrl_sizey)*2; + Image->bytes_per_pixel=2; + break; + } + case 15: + { + sizemem=(Image->ctrl_sizex*Image->ctrl_sizey)*2; + Image->bytes_per_pixel=2; + break; + } + case 8: + { + sizemem=Image->ctrl_sizex*Image->ctrl_sizey; + Image->bytes_per_pixel=1; + break; + } + case 4: + { + sizemem=((Image->ctrl_sizex*Image->ctrl_sizey)>>1)+1; + Image->bytes_per_pixel=0; + break; + } + default: return(NULL); + } + + Image->img=malloc(sizemem); + + return(Image); +} + diff --git a/programs/develop/libraries/libGUI/SRC/control_progress_bar.h b/programs/develop/libraries/libGUI/SRC/control_progress_bar.h new file mode 100644 index 0000000000..d8e8f46110 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_progress_bar.h @@ -0,0 +1,16 @@ +#define FLAG_PB_VERTICAL_ORIENTATION_ON 0x1 +#define FLAG_PB_HORIZONTAL_ORIENTATION_ON 0x2 +#define FLAG_PB_FROM_LEFT_TO_RIGHT_ON 0x4 +#define FLAG_PB_FROM_RIGHT_TO_LEFT_ON 0x8 +#define FLAG_PB_FROM_DOWN_TO_UP_ON 0x10 +#define FLAG_PB_FROM_UP_TO_DOWN_ON 0x20 +#define FLAG_PB_TEXT_ON 0x40 + +#define FLAG_PB_VERTICAL_ORIENTATION_OFF 0xfe +#define FLAG_PB_HORIZONTAL_ORIENTATION_OFF 0xfd +#define FLAG_PB_FROM_LEFT_TO_RIGHT_OFF 0xfb +#define FLAG_PB_FROM_RIGHT_TO_LEFT_OFF 0xf7 +#define FLAG_PB_FROM_DOWN_TO_UP_OFF 0xef +#define FLAG_PB_FROM_UP_TO_DOWN_OFF 0xdf +#define FLAG_PB_TEXT_OFF 0xbf + diff --git a/programs/develop/libraries/libGUI/SRC/control_progress_bar.inc b/programs/develop/libraries/libGUI/SRC/control_progress_bar.inc new file mode 100644 index 0000000000..b774bcd7e2 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_progress_bar.inc @@ -0,0 +1,320 @@ +/* + control ProgressBar +*/ + +void ProgressBarDrawProgress(struct ControlProgressBar *ProgressBar) +{ + int x; + int y; + int pos_progress; + int sizex; + int sizey; + char v; + struct FINITION *fin; + gui_message_t message; + gui_text_size_t size; + gui_text_t *Text; + + if ((ProgressBar->flags & FLAG_SHOW_CONTROL)==FALSE) return; + + x=ProgressBar->ctrl_x; + y=ProgressBar->ctrl_y; + sizex=ProgressBar->ctrl_sizex; + sizey=ProgressBar->ctrl_sizey; + fin=(struct FINITION*)ProgressBar->finition; + + if (ProgressBar->progress<0.0) ProgressBar->progress=0.0; + if (ProgressBar->progress>1.0) ProgressBar->progress=1.0; + + v=ProgressBar->prb_flags & FLAG_PB_HORIZONTAL_ORIENTATION_ON; + if (v!=FALSE) + { + pos_progress=(int)(ProgressBar->progress*(sizex-2)); + + if (ProgressBar->prb_flags & FLAG_PB_FROM_LEFT_TO_RIGHT_ON) + { + Draw(fin,TOOL_GRADIENT_UP_FILLED_RECTANGLE,x+1,y+1,pos_progress,sizey-2,COLOR_FON,COLOR_MIDDLE_LIGHT); + Draw(fin,TOOL_GRADIENT_UP_FILLED_RECTANGLE,x+1+pos_progress,y+1,sizex-2-pos_progress, + sizey-2,COLOR_MIDDLE_LIGHT,COLOR_LIGHT); + if (ProgressBar->prb_flags & FLAG_PB_TEXT_ON) + { + if (fin->flags & FINITION_ON) + { + message.type=MESSAGE_FULL_REDRAW_ALL_WITH_FINITION; + message.arg1=fin->x; + message.arg2=fin->y; + message.arg3=fin->sizex; + message.arg4=fin->sizey; + } + else + { + message.type=MESSAGE_FULL_REDRAW_ALL; + } + Text=(gui_text_t*)ProgressBar->child_bk; + size=GetStringSize((font_t*)Text->font,Text->text); + Text->ctrl_sizex=(DWORD)size.sizex; + Text->ctrl_sizey=(DWORD)size.sizey; + Text->ctrl_x=x+(sizex/2)-(Text->ctrl_sizex/2); + Text->ctrl_y=y+(sizey/2)-(Text->ctrl_sizey/2); + + SendMessage((struct HEADER*)ProgressBar,&message); + } + } + + if (ProgressBar->prb_flags & FLAG_PB_FROM_RIGHT_TO_LEFT_ON) + { + //Draw(fin,"filled_rectangle",x+sizex-pos_progress-1,y+1,x+sizex-1,sizey-2,0xff0000); + } + + } +} + +void DrawProgressBar(struct ControlProgressBar *ProgressBar) +{ + int x,y,sizex,sizey; + char c; + char *save_buf,*buf; + int save_size_x,save_size_y; + DWORD draw_output,flags; + finition_t *fin; + + x=ProgressBar->ctrl_x; + y=ProgressBar->ctrl_y; + sizex=ProgressBar->ctrl_sizex; + sizey=ProgressBar->ctrl_sizey; + fin=(struct FINITION*)ProgressBar->finition; + + //alocate a buffer for draw text + c=screen.bits_per_pixel >> 3; + buf=malloc(sizex*sizey*c); + + //save current screen parameters + save_buf=screen.buffer; + save_size_x=screen.size_x; + save_size_y=screen.size_y; + draw_output=screen.draw_output; + + //load parameters of local buffer + screen.buffer=buf; + screen.size_x=sizex; + screen.size_y=sizey; + screen.draw_output=DRAW_OUTPUT_BUFFER; + + //move control + SetControlNewPosition(ProgressBar,0,0); + //save finition parameters + flags=fin->flags; + fin->flags &=FINITION_OFF; + + //draw progress bar in buffer + Draw(fin,TOOL_RECTANGLE,0,0,sizex,sizey,COLOR_ABSOLUTE_DARK); + ProgressBarDrawProgress(ProgressBar); + + //restore last position of control + SetControlNewPosition(ProgressBar,x,y); + //restore finition + fin->flags=flags; + + //restore screen parameters + screen.buffer=save_buf; + screen.size_x=save_size_x; + screen.size_y=save_size_y; + screen.draw_output=draw_output; + + //move rendered objects from local buffer to screen + if (fin->flags & FINITION_ON) + DrawImageFinit(fin,x,y,sizex,sizey,screen.bits_per_pixel,buf); + else + DrawImage(x,y,sizex,sizey,screen.bits_per_pixel,buf); + + //free local buffer + free(buf); +} + +void SetProgressBarPulse(struct ControlProgressBar *ProgressBar,int time_tick) +{ + struct TIMER *timer; + struct HEADERPARENT *main_parent; + + main_parent=(struct HEADERPARENT*)ProgressBar->main_parent; + if (main_parent!=(struct HEADERPARENT*)NULL) + { + main_parent->number_timers_for_controls++; + + ProgressBar->timer=(DWORD*)SetTimerCallbackForControl(time_tick,&DrawProgressBar,ProgressBar); + timer=(struct TIMER*)ProgressBar->timer; + timer->flags=timer->flags | FLAG_TIMER_ON; + } +} + +//--------------------------------------------------------------------------------- +// control ProgressBar +//--------------------------------------------------------------------------------- +void ProgressBarProc(struct ControlProgressBar *ProgressBar,struct MESSAGE *message) +{ + int btn_state; + char v; + struct TIMER *timer; + struct FINITION *fin; + + switch(message->type) + { + case MESSAGE_FULL_REDRAW_ALL: + { + //draw ProgressBar + if (ProgressBar->flags & FLAG_SHOW_CONTROL) DrawProgressBar(ProgressBar); + break; + } + case MESSAGE_FULL_REDRAW_ALL_WITH_FINITION: + { + fin=(struct FINITION*)ProgressBar->finition; + fin->flags=fin->flags | FINITION_ON; + fin->x=message->arg1; + fin->y=message->arg2; + fin->sizex=message->arg3; + fin->sizey=message->arg4; + DrawProgressBar(ProgressBar); + break; + } + case MESSAGE_SPECIALIZED: + { //redraw bar of progress + if (ProgressBar->flags & FLAG_GET_SPECIALIZED_MESSAGE_ON) + { + if (ProgressBar->flags & FLAG_SHOW_CONTROL) ProgressBarDrawProgress(ProgressBar); + ProgressBar->flags=ProgressBar->flags & FLAG_GET_SPECIALIZED_MESSAGE_OFF; + } + break; + } + case MESSAGE_CHANGE_POSITION_EVENT: + { + ProgressBar->ctrl_x=ProgressBar->ctrl_x+message->arg1; + ProgressBar->ctrl_y=ProgressBar->ctrl_y+message->arg2; + SendMessage((struct HEADER*)ProgressBar,message); + break; + } + case MESSAGE_CALL_TIMER_EVENT: + { + if (ProgressBar->timer!=(DWORD*)NULL) + { + timer=(struct TIMER*)ProgressBar->timer; + if (timer->flags & FLAG_TIMER_ON) Timer(timer); + } + SendMessage((struct HEADER*)ProgressBar,message); + break; + } + case MESSAGE_DESTROY_CONTROL: + { + if (ProgressBar->timer!=(DWORD*)NULL) free(ProgressBar->timer); + free(ProgressBar->finition); + SendMessage((struct HEADER*)ProgressBar,message); + break; + } + case MESSAGE_SET_MAIN_PARENT: + { + SendMessage((struct HEADER*)ProgressBar,message); + ProgressBar->main_parent=(DWORD*)message->arg1; + SendMessage((struct HEADER*)ProgressBar,message); + break; + } + + default: break; + } +} + +//--------------------------------------------------------------------------------- +// create control ProgressBar +//--------------------------------------------------------------------------------- +void* CreateProgressBarEmpty(struct ProgressBarData *info_for_control) +{ + struct ControlProgressBar *ProgressBar; + struct FINITION *fin; + + ProgressBar=malloc(sizeof(struct ControlProgressBar)); + ProgressBar->finition=malloc(sizeof(struct FINITION)); + fin=(struct FINITION*)ProgressBar->finition; + fin->flags=0; + + ID++; +#ifdef DEBUG + printf("\ncreated progress bar with ID=%d",(int)ID); +#endif + ProgressBar->child_bk=(DWORD*)NULL; + ProgressBar->child_fd=(DWORD*)NULL; + ProgressBar->active_control_for_keys=(DWORD*)NULL; + ProgressBar->active_control_for_mouse=(DWORD*)NULL; + ProgressBar->callback=(DWORD*)NULL; + ProgressBar->timer=(DWORD*)NULL; + ProgressBar->ctrl_proc=(DWORD*)&ProgressBarProc; + ProgressBar->ctrl_x=(DWORD)info_for_control->x; + ProgressBar->ctrl_y=(DWORD)info_for_control->y; + ProgressBar->ctrl_sizex=(DWORD)info_for_control->width; + ProgressBar->ctrl_sizey=(DWORD)info_for_control->height; + ProgressBar->ctrl_ID=ID; + ProgressBar->progress=info_for_control->progress; + ProgressBar->flags=0; + ProgressBar->flags=ProgressBar->flags | FLAG_SHOW_CONTROL; + + ProgressBar->prb_flags=0; + ProgressBar->prb_flags=ProgressBar->prb_flags | FLAG_PB_HORIZONTAL_ORIENTATION_ON; + ProgressBar->prb_flags=ProgressBar->prb_flags | FLAG_PB_FROM_LEFT_TO_RIGHT_ON; + + return(ProgressBar); +} + +void* CreateProgressBar(gui_progress_bar_data_t *info) +{ + gui_text_t *text; + gui_text_data_t txtdata; + gui_progress_bar_t *pbar; + + pbar=CreateProgressBarEmpty(info); + + txtdata.x=0; + txtdata.y=0; + txtdata.font=NULL; + txtdata.background=FALSE; + txtdata.color=0; + txtdata.text=malloc(16); + txtdata.text[0]='\0'; + text=CreateText(&txtdata); + + text->ctrl_x=pbar->ctrl_sizex/2; + text->ctrl_y=pbar->ctrl_sizey/2; + PackControls(pbar,text); + + text->flags &=FLAG_HIDE_CONTROL; + + return(pbar); +} + +void ProgressBarSetText(gui_progress_bar_t *pbar,char *txt) +{ + gui_text_t *text; + long len1,len2; + + text=(gui_text_t*)pbar->child_bk; + + if (*txt!='\0') + { + len1=strlen(text->text); + len2=strlen(txt); + if (len1text); + text->text=malloc(len2+1);//one byte for simbol end of string + } + memmove(text->text,txt,len2); + text->text[len2]='\0'; + pbar->prb_flags|=FLAG_PB_TEXT_ON; + text->flags |=FLAG_SHOW_CONTROL; + } +} + +char *ProgressBarGetText(gui_progress_bar_t *pbar) +{ + gui_text_t *text; + + text=(gui_text_t*)pbar->child_bk; + + return(text->text); +} diff --git a/programs/develop/libraries/libGUI/SRC/control_scroll_bar.h b/programs/develop/libraries/libGUI/SRC/control_scroll_bar.h new file mode 100644 index 0000000000..a24327e6ce --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_scroll_bar.h @@ -0,0 +1,6 @@ +#define FLAG_SCROLL_BAR_ORIENTATION_HORIZONTAL_ON 0x1 +#define FLAG_SCROLL_BAR_ORIENTATION_HORIZONTAL_OFF 0xfe +#define FLAG_SCROLL_BAR_ORIENTATION_VERTICAL_ON 0x2 +#define FLAG_SCROLL_BAR_ORIENTATION_VERTICAL_OFF 0xfd +#define FLAG_SCROLL_RULLER_PRESSED 0x4 +#define FLAG_SCROLL_RULLER_RELEASED 0xfb diff --git a/programs/develop/libraries/libGUI/SRC/control_scroll_bar.inc b/programs/develop/libraries/libGUI/SRC/control_scroll_bar.inc new file mode 100644 index 0000000000..e97e1b3160 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_scroll_bar.inc @@ -0,0 +1,801 @@ +/* + control ScrollBar +*/ + +//////////////////////////////////////////////////////////////////////////////// +// Draw Ruller +//////////////////////////////////////////////////////////////////////////////// +void DrawRuller(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + int scrollbar_size,ruller_size,ruller_pos; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + if (ScrollBar->scb_flags & FLAG_SCROLL_BAR_ORIENTATION_HORIZONTAL_ON) + { + scrollbar_size=sizex-sizey*2; + ruller_size=(int)(scrollbar_size*ScrollBar->ruller_size); + if (ruller_size<5) ruller_size=5; + if (ruller_size>sizex) ruller_size=sizex-2*sizey; + + ruller_pos=x+sizey+(int)((scrollbar_size-ruller_size)*ScrollBar->ruller_pos); + //left bar + Draw(fin,TOOL_FILLED_RECTANGLE,x+sizey,y+1,ruller_pos-x-sizey,sizey-2,COLOR_FON); + //right bar + Draw(fin,TOOL_FILLED_RECTANGLE,ruller_pos+ruller_size,y+1,x+sizex-sizey-ruller_pos-ruller_size,sizey-2,COLOR_FON); + //roller + Draw(fin,TOOL_RECTANGLE,ruller_pos,y,ruller_size,sizey,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,ruller_pos+1,y+1,ruller_size-2,sizey-2,COLOR_MIDDLE_LIGHT); + Draw(fin,TOOL_VERTICAL_LINE,ruller_pos+(ruller_size/2)-2,y+sizey/4,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_VERTICAL_LINE,ruller_pos+(ruller_size/2),y+sizey/4,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_VERTICAL_LINE,ruller_pos+(ruller_size/2)+2,y+sizey/4,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + } + + if (ScrollBar->scb_flags & FLAG_SCROLL_BAR_ORIENTATION_VERTICAL_ON) + { + scrollbar_size=sizey-sizex*2; + ruller_size=(int)(scrollbar_size*ScrollBar->ruller_size); + if (ruller_size<5) ruller_size=5; + if (ruller_size>sizey) ruller_size=sizey-2*sizex; + + ruller_pos=y+sizex+(int)((scrollbar_size-ruller_size)*ScrollBar->ruller_pos); + //up bar + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+sizex,sizex-2,ruller_pos-y-sizex,COLOR_FON); + //down bar + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,ruller_pos+ruller_size,sizex-2,y+sizey-sizex-ruller_pos-ruller_size,COLOR_FON); + //roller + Draw(fin,TOOL_RECTANGLE,x,ruller_pos,sizex,ruller_size,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,ruller_pos+1,sizex-2,ruller_size-2,COLOR_MIDDLE_LIGHT); + Draw(fin,TOOL_HORIZONTAL_LINE,x+sizex/4,x+(3*sizex)/4,ruller_pos+(ruller_size/2)-2,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_HORIZONTAL_LINE,x+sizex/4,x+(3*sizex)/4,ruller_pos+(ruller_size/2),COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_HORIZONTAL_LINE,x+sizex/4,x+(3*sizex)/4,ruller_pos+(ruller_size/2)+2,COLOR_ABSOLUTE_DARK); + } + +} + +//////////////////////////////////////////////////////////////////////////////// +// Draw full Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void DrawScrollBar(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + if (ScrollBar->scb_flags & FLAG_SCROLL_BAR_ORIENTATION_HORIZONTAL_ON) + { + + //draw child buttons and roller + Draw(fin,TOOL_RECTANGLE,x,y,sizex,sizey,COLOR_ABSOLUTE_DARK); + //left button + Draw(fin,TOOL_RECTANGLE,x,y,sizey,sizey,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+1,sizey-2,sizey-2,COLOR_MIDDLE_LIGHT); + //left arrow of left button + Draw(fin,TOOL_LINE,x+sizey/3,y+sizey/2,x+(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizey/3,y+sizey/2,x+(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+1+(sizey/3),y+sizey/2,x+1+(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+1+(sizey/3),y+sizey/2,x+1+(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + //right button + Draw(fin,TOOL_RECTANGLE,x+sizex-sizey,y,sizey,sizey,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,x+sizex-sizey+1,y+1,sizey-2,sizey-2,COLOR_MIDDLE_LIGHT); + //right arrow of right button + Draw(fin,TOOL_LINE,x+sizex-sizey/3,y+sizey/2,x+sizex-(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex-sizey/3,y+sizey/2,x+sizex-(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex-1-(sizey/3),y+sizey/2,x+sizex-1-(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex-1-(sizey/3),y+sizey/2,x+sizex-1-(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + //roller + DrawRuller(ScrollBar); + } + + if (ScrollBar->scb_flags & FLAG_SCROLL_BAR_ORIENTATION_VERTICAL_ON) + { + //draw child buttons and roller + Draw(fin,TOOL_RECTANGLE,x,y,sizex,sizey,COLOR_ABSOLUTE_DARK); + //up button + Draw(fin,TOOL_RECTANGLE,x,y,sizex,sizex,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+1,sizex-2,sizex-2,COLOR_MIDDLE_LIGHT); + //up arrow of up button + Draw(fin,TOOL_LINE,x+sizex/2,y+sizex/3,x+sizex/4,y+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizex/3,x+(3*sizex)/4,y+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+1+(sizex/3),x+sizex/4,y+1+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+1+(sizex/3),x+(3*sizex)/4,y+1+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + //down button + Draw(fin,TOOL_RECTANGLE,x,y+sizey-sizex,sizex,sizex,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+sizey-sizex+1,sizex-2,sizex-2,COLOR_MIDDLE_LIGHT); + //down arrow of down button + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-sizex/3,x+sizex/4,y+sizey-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-sizex/3,x+(3*sizex)/4,y+sizey-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-1-(sizex/3),x+sizex/4,y+sizey-1-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-1-(sizex/3),x+(3*sizex)/4,y+sizey-1-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + //roller + DrawRuller(ScrollBar); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Vertical Scroll Bar +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// animation of up button of Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void ScrollBar_DrawPressedUpButton(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + //up button + Draw(fin,TOOL_RECTANGLE,x,y,sizex,sizex,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+1,sizex-2,sizex-2,COLOR_FON); + //up arrow of up button + Draw(fin,TOOL_LINE,x+sizex/2,y+sizex/3,x+sizex/4,y+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizex/3,x+(3*sizex)/4,y+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+1+(sizex/3),x+sizex/4,y+1+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+1+(sizex/3),x+(3*sizex)/4,y+1+(2*sizex)/3,COLOR_ABSOLUTE_DARK); +} + +void ScrollBar_DrawReleasedUpButton(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + //up button + Draw(fin,TOOL_RECTANGLE,x,y,sizex,sizex,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+1,sizex-2,sizex-2,COLOR_MIDDLE_LIGHT); + //up arrow of up button + Draw(fin,TOOL_LINE,x+sizex/2,y+sizex/3,x+sizex/4,y+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizex/3,x+(3*sizex)/4,y+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+1+(sizex/3),x+sizex/4,y+1+(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+1+(sizex/3),x+(3*sizex)/4,y+1+(2*sizex)/3,COLOR_ABSOLUTE_DARK); +} + +//////////////////////////////////////////////////////////////////////////////// +// animation of down button of Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void ScrollBar_DrawPressedDownButton(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + //down button + Draw(fin,TOOL_RECTANGLE,x,y+sizey-sizex,sizex,sizex,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+sizey-sizex+1,sizex-2,sizex-2,COLOR_FON); + //down arrow of down button + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-sizex/3,x+sizex/4,y+sizey-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-sizex/3,x+(3*sizex)/4,y+sizey-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-1-(sizex/3),x+sizex/4,y+sizey-1-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-1-(sizex/3),x+(3*sizex)/4,y+sizey-1-(2*sizex)/3,COLOR_ABSOLUTE_DARK); +} + +void ScrollBar_DrawReleasedDownButton(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + //down button + Draw(fin,TOOL_RECTANGLE,x,y+sizey-sizex,sizex,sizex,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+sizey-sizex+1,sizex-2,sizex-2,COLOR_MIDDLE_LIGHT); + //down arrow of down button + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-sizex/3,x+sizex/4,y+sizey-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-sizex/3,x+(3*sizex)/4,y+sizey-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-1-(sizex/3),x+sizex/4,y+sizey-1-(2*sizex)/3,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex/2,y+sizey-1-(sizex/3),x+(3*sizex)/4,y+sizey-1-(2*sizex)/3,COLOR_ABSOLUTE_DARK); +} + +//////////////////////////////////////////////////////////////////////////////// +// callback function for up button of Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void ScrollBar_FuncCallbackForUpButton_Pressed(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + struct HEADERPARENT *main_parent; + + ScrollBar=(struct ControlScrollBar*)data; + if (ScrollBar->ruller_size!=1.0) + { + ScrollBar->ruller_pos=ScrollBar->ruller_pos-ScrollBar->ruller_step; + } + if (ScrollBar->ruller_pos<0.0) ScrollBar->ruller_pos=0.0; + ScrollBar_DrawPressedUpButton(ScrollBar); + + if (ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT)!=NULL) + { + main_parent=(struct HEADERPARENT*)ScrollBar->main_parent; + ScrollBar->flags=ScrollBar->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)ScrollBar; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT); + main_parent->number_callbacks++; + } + DrawRuller(ScrollBar); +} + +void ScrollBar_FuncCallbackForUpButton_Released(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + + ScrollBar=(struct ControlScrollBar*)data; + ScrollBar_DrawReleasedUpButton(ScrollBar); +} + +//////////////////////////////////////////////////////////////////////////////// +// callback function for down button of Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void ScrollBar_FuncCallbackForDownButton_Pressed(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + struct HEADERPARENT *main_parent; + + ScrollBar=(struct ControlScrollBar*)data; + if (ScrollBar->ruller_size!=1.0) + { + ScrollBar->ruller_pos=ScrollBar->ruller_pos+ScrollBar->ruller_step; + } + if (ScrollBar->ruller_pos>1.0) ScrollBar->ruller_pos=1.0; + ScrollBar_DrawPressedDownButton(ScrollBar); + + if (ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT)!=NULL) + { + main_parent=(struct HEADERPARENT*)ScrollBar->main_parent; + ScrollBar->flags=ScrollBar->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)ScrollBar; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT); + main_parent->number_callbacks++; + } + DrawRuller(ScrollBar); +} + +void ScrollBar_FuncCallbackForDownButton_Released(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + + ScrollBar=(struct ControlScrollBar*)data; + ScrollBar_DrawReleasedDownButton(ScrollBar); + DrawRuller(ScrollBar); +} + +//////////////////////////////////////////////////////////////////////////////// +// Horizontal Scroll Bar +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// animation of left button of Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void ScrollBar_DrawPressedLeftButton(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + //left button + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+1,sizey-2,sizey-2,COLOR_FON); + //left arrow of left button + Draw(fin,TOOL_LINE,x+sizey/3,y+sizey/2,x+(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizey/3,y+sizey/2,x+(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+1+(sizey/3),y+sizey/2,x+1+(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+1+(sizey/3),y+sizey/2,x+1+(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); +} + +void ScrollBar_DrawReleasedLeftButton(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + //left button + Draw(fin,TOOL_FILLED_RECTANGLE,x+1,y+1,sizey-2,sizey-2,COLOR_MIDDLE_LIGHT); + //left arrow of left button + Draw(fin,TOOL_LINE,x+sizey/3,y+sizey/2,x+(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizey/3,y+sizey/2,x+(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+1+(sizey/3),y+sizey/2,x+1+(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+1+(sizey/3),y+sizey/2,x+1+(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); +} + +//////////////////////////////////////////////////////////////////////////////// +// animation of right button of Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void ScrollBar_DrawPressedRightButton(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + //right button + Draw(fin,TOOL_FILLED_RECTANGLE,x+sizex-sizey+1,y+1,sizey-2,sizey-2,COLOR_FON); + //right arrow of right button + Draw(fin,TOOL_LINE,x+sizex-sizey/3,y+sizey/2,x+sizex-(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex-sizey/3,y+sizey/2,x+sizex-(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex-1-(sizey/3),y+sizey/2,x+sizex-1-(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex-1-(sizey/3),y+sizey/2,x+sizex-1-(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); +} + +void ScrollBar_DrawReleasedRightButton(struct ControlScrollBar *ScrollBar) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + fin=(struct FINITION*)ScrollBar->finition; + + //right button + Draw(fin,TOOL_FILLED_RECTANGLE,x+sizex-sizey+1,y+1,sizey-2,sizey-2,COLOR_MIDDLE_LIGHT); + //right arrow of right button + Draw(fin,TOOL_LINE,x+sizex-sizey/3,y+sizey/2,x+sizex-(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex-sizey/3,y+sizey/2,x+sizex-(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex-1-(sizey/3),y+sizey/2,x+sizex-1-(2*sizey)/3,y+sizey/4,COLOR_ABSOLUTE_DARK); + Draw(fin,TOOL_LINE,x+sizex-1-(sizey/3),y+sizey/2,x+sizex-1-(2*sizey)/3,y+(3*sizey)/4,COLOR_ABSOLUTE_DARK); +} +//////////////////////////////////////////////////////////////////////////////// +// callback function for left button of Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void ScrollBar_FuncCallbackForLeftButton_Pressed(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + struct HEADERPARENT *main_parent; + + ScrollBar=(struct ControlScrollBar*)data; + if (ScrollBar->ruller_size!=1.0) + { + ScrollBar->ruller_pos=ScrollBar->ruller_pos-ScrollBar->ruller_step; + } + if (ScrollBar->ruller_pos<0.0) ScrollBar->ruller_pos=0.0; + ScrollBar_DrawPressedLeftButton(ScrollBar); + + if (ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT)!=NULL) + { + main_parent=(struct HEADERPARENT*)ScrollBar->main_parent; + ScrollBar->flags=ScrollBar->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)ScrollBar; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT); + main_parent->number_callbacks++; + } + DrawRuller(ScrollBar); +} + +void ScrollBar_FuncCallbackForLeftButton_Released(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + + ScrollBar=(struct ControlScrollBar*)data; + ScrollBar_DrawReleasedLeftButton(ScrollBar); +} + +//////////////////////////////////////////////////////////////////////////////// +// callback function for right button of Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void ScrollBar_FuncCallbackForRightButton_Pressed(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + struct HEADERPARENT *main_parent; + + ScrollBar=(struct ControlScrollBar*)data; + if (ScrollBar->ruller_size!=1.0) + { + ScrollBar->ruller_pos=ScrollBar->ruller_pos+ScrollBar->ruller_step; + } + if (ScrollBar->ruller_pos>1.0) ScrollBar->ruller_pos=1.0; + ScrollBar_DrawPressedRightButton(ScrollBar); + + if (ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT)!=NULL) + { + main_parent=(struct HEADERPARENT*)ScrollBar->main_parent; + ScrollBar->flags=ScrollBar->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)ScrollBar; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT); + main_parent->number_callbacks++; + } + DrawRuller(ScrollBar); +} + +void ScrollBar_FuncCallbackForRightButton_Released(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + + ScrollBar=(struct ControlScrollBar*)data; + ScrollBar_DrawReleasedRightButton(ScrollBar); + DrawRuller(ScrollBar); +} + +//////////////////////////////////////////////////////////////////////////////// +// callback function for ruller bar button of Scroll Bar +//////////////////////////////////////////////////////////////////////////////// +void ScrollBar_FuncCallbackForScrollRullerPressed(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + + ScrollBar=(struct ControlScrollBar*)data; + ScrollBar->scb_flags=ScrollBar->scb_flags | FLAG_SCROLL_RULLER_PRESSED; +} + +void ScrollBar_FuncCallbackForScrollRullerReleased(struct HEADER *control,void *data) +{ + struct ControlScrollBar *ScrollBar; + + ScrollBar=(struct ControlScrollBar*)data; + ScrollBar->scb_flags=ScrollBar->scb_flags & FLAG_SCROLL_RULLER_RELEASED; +} + +//--------------------------------------------------------------------------------- +// control ScrollBar +//--------------------------------------------------------------------------------- +void ScrollBarProc(struct ControlScrollBar *ScrollBar,struct MESSAGE *message) +{ + int mx,my; + char mouse_buttons_state; + int x,y,sizex,sizey; + int scrollbar_size,ruller_size,ruller_pos; + int ruller_min,ruller_max; + float max_pos,current_pos,last_ruller_pos; + struct FINITION *fin; + struct TIMER *timer; + struct HEADERPARENT *main_parent; + + x=ScrollBar->ctrl_x; + y=ScrollBar->ctrl_y; + sizex=ScrollBar->ctrl_sizex; + sizey=ScrollBar->ctrl_sizey; + + switch(message->type) + { + case MESSAGE_FULL_REDRAW_ALL: + { + //draw ScrollBar + if (ScrollBar->flags & FLAG_SHOW_CONTROL) DrawScrollBar(ScrollBar); + break; + } + case MESSAGE_FULL_REDRAW_ALL_WITH_FINITION: + { + fin=(struct FINITION*)ScrollBar->finition; + fin->flags=fin->flags | FINITION_ON; + fin->x=message->arg1; + fin->y=message->arg2; + fin->sizex=message->arg3; + fin->sizey=message->arg4; + DrawScrollBar(ScrollBar); + break; + } + case MESSAGE_SPECIALIZED: + { + if (ScrollBar->flags & FLAG_GET_SPECIALIZED_MESSAGE_ON) + { + if (ScrollBar->flags & FLAG_SHOW_CONTROL) DrawScrollBar(ScrollBar); + ScrollBar->flags=ScrollBar->flags & FLAG_GET_SPECIALIZED_MESSAGE_OFF; + } + break; + } + case MESSAGE_MOUSE_EVENT: + { + mx=message->arg1; + my=message->arg2; + mouse_buttons_state=message->arg3; + main_parent=(struct HEADERPARENT*)ScrollBar->main_parent; + + //check ruller state + if (ScrollBar->scb_flags & FLAG_SCROLL_RULLER_PRESSED) + { // horizontal ScrollBar + if (ScrollBar->scb_flags & FLAG_SCROLL_BAR_ORIENTATION_HORIZONTAL_ON) + { + scrollbar_size=sizex-sizey*2; + ruller_size=scrollbar_size*ScrollBar->ruller_size; + if (ruller_size<5) ruller_size=5; + + ruller_min=x+sizey; //minimum x + ruller_max=ruller_min+scrollbar_size-ruller_size; + ruller_pos=mx-(ruller_size/2);//ruller centred under mouse pointer + + if (ruller_posruller_max) ruller_pos=ruller_max; + + if (ruller_max!=ruller_min) + { + max_pos=(float)(ruller_max-ruller_min); + current_pos=(float)(ruller_pos-ruller_min); + last_ruller_pos=ScrollBar->ruller_pos; + ScrollBar->ruller_pos=current_pos/max_pos; + } + else {ScrollBar->ruller_pos=0.0;} + + if (ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT)!=NULL) + { + if (ScrollBar->ruller_pos!=last_ruller_pos) + { + ScrollBar->flags=ScrollBar->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)ScrollBar; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT); + main_parent->number_callbacks++; + } + } + if (ScrollBar->ruller_pos!=last_ruller_pos) DrawRuller(ScrollBar); + break; + } + // vertical ScrollBar + if (ScrollBar->scb_flags & FLAG_SCROLL_BAR_ORIENTATION_VERTICAL_ON) + { + scrollbar_size=sizey-sizex*2; + ruller_size=scrollbar_size*ScrollBar->ruller_size; + if (ruller_size<5) ruller_size=5; + + ruller_min=y+sizex; //minimum x + ruller_max=ruller_min+scrollbar_size-ruller_size; + ruller_pos=my-(ruller_size/2);//ruller centred under mouse pointer + + if (ruller_posruller_max) ruller_pos=ruller_max; + + if (ruller_max!=ruller_min) + { + max_pos=(float)(ruller_max-ruller_min); + current_pos=(float)(ruller_pos-ruller_min); + last_ruller_pos=ScrollBar->ruller_pos; + ScrollBar->ruller_pos=current_pos/max_pos; + } + else {ScrollBar->ruller_pos=0.0;} + + if (ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT)!=NULL) + { + if (ScrollBar->ruller_pos!=last_ruller_pos) + { + ScrollBar->flags=ScrollBar->flags | FLAG_CONNECT_EVENT_ON; + main_parent->control_for_callback_function[main_parent->number_callbacks]= + (DWORD*)ScrollBar; + main_parent->callback_for_control_callback[main_parent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(ScrollBar,SCROLLBAR_CHANGED_EVENT); + main_parent->number_callbacks++; + } + } + if (ScrollBar->ruller_pos!=last_ruller_pos) DrawRuller(ScrollBar); + } + } + break; + } + case MESSAGE_CHANGE_POSITION_EVENT: + { + ScrollBar->ctrl_x=ScrollBar->ctrl_x+message->arg1; + ScrollBar->ctrl_y=ScrollBar->ctrl_y+message->arg2; + break; + } + case MESSAGE_CALL_TIMER_EVENT: + { + if (ScrollBar->timer!=(DWORD*)NULL) + { + timer=(struct TIMER*)ScrollBar->timer; + if (timer->flags & FLAG_TIMER_ON) Timer(timer); + } + break; + } + case MESSAGE_DESTROY_CONTROL: + { + if (ScrollBar->timer!=(DWORD*)NULL) free(ScrollBar->timer); + free(ScrollBar->finition); + break; + } + case MESSAGE_SET_MAIN_PARENT: + { + SendMessage((struct HEADER*)ScrollBar,message); + ScrollBar->main_parent=(DWORD*)message->arg1; + break; + } + + default: break; + } + //send message to child controls(if there is) + SendMessage((struct HEADER*)ScrollBar,message); +} + +//--------------------------------------------------------------------------------- +// create control ScrollBar +//--------------------------------------------------------------------------------- +void* CreateScrollBar(struct ScrollBarData *info_for_control) +{ + struct ControlScrollBar *ScrollBar; + struct FINITION *fin; + + ScrollBar=malloc(sizeof(struct ControlScrollBar)); + ScrollBar->finition=malloc(sizeof(struct FINITION)); + fin=(struct FINITION*)ScrollBar->finition; + fin->flags=0; + + ID++; +#ifdef DEBUG + printf("\ncreated scroll bar with ID=%d",(int)ID); +#endif + ScrollBar->child_bk=(DWORD*)NULL; + ScrollBar->child_fd=(DWORD*)NULL; + ScrollBar->active_control_for_keys=(DWORD*)NULL; + ScrollBar->active_control_for_mouse=(DWORD*)NULL; + ScrollBar->callback=(DWORD*)NULL; + ScrollBar->timer=(DWORD*)NULL; + + ScrollBar->ctrl_proc=(DWORD*)&ScrollBarProc; + ScrollBar->ctrl_x=(DWORD)info_for_control->x; + ScrollBar->ctrl_y=(DWORD)info_for_control->y; + ScrollBar->ctrl_sizex=(DWORD)info_for_control->width; + ScrollBar->ctrl_sizey=(DWORD)info_for_control->height; + ScrollBar->ctrl_ID=ID; + ScrollBar->ruller_size=info_for_control->ruller_size; + ScrollBar->ruller_pos=info_for_control->ruller_pos; + ScrollBar->ruller_step=info_for_control->ruller_step; + ScrollBar->flags=0; + ScrollBar->flags=ScrollBar->flags | FLAG_SHOW_CONTROL; + + return(ScrollBar); +} + +void* CreateHorizontalScrollBar(struct ScrollBarData *info_for_control) +{ + struct ControlScrollBar *ScrollBar; + struct ControlButton *ChildButton1; + struct ControlButton *ChildButton2; + struct ControlButton *ScrollRuller; + struct ButtonData ChildButton1Data; + struct ButtonData ChildButton2Data; + struct ButtonData ScrollRullerData; + + ScrollBar=CreateScrollBar(info_for_control); + //set horizontal orientation + ScrollBar->scb_flags=0; + ScrollBar->scb_flags=ScrollBar->scb_flags | FLAG_SCROLL_BAR_ORIENTATION_HORIZONTAL_ON; + + //fill data for first child button of scroller + ChildButton1Data.x=0; + ChildButton1Data.y=0; + ChildButton1Data.width=ScrollBar->ctrl_sizey; + ChildButton1Data.height=ChildButton1Data.width; + + //fill data for second child button of scroller + ChildButton2Data.x=ScrollBar->ctrl_sizex-ScrollBar->ctrl_sizey; + ChildButton2Data.y=0; + ChildButton2Data.width=ScrollBar->ctrl_sizey; + ChildButton2Data.height=ChildButton2Data.width; + + //fill data for scroll ruller button of scroller + ScrollRullerData.x=ScrollBar->ctrl_sizey; + ScrollRullerData.y=0; + ScrollRullerData.width=ScrollBar->ctrl_sizex-2*ScrollBar->ctrl_sizey; + ScrollRullerData.height=ScrollBar->ctrl_sizey; + + ChildButton1=CreateButton(&ChildButton1Data); + ChildButton2=CreateButton(&ChildButton2Data); + ScrollRuller=CreateButton(&ScrollRullerData); + + ChildButton1->flags=ChildButton1->flags & FLAG_HIDE_CONTROL; + ChildButton2->flags=ChildButton2->flags & FLAG_HIDE_CONTROL; + ScrollRuller->flags=ScrollRuller->flags & FLAG_HIDE_CONTROL; + + SetCallbackFunction(ChildButton1,BUTTON_PRESSED_EVENT,&ScrollBar_FuncCallbackForLeftButton_Pressed,ScrollBar); + SetCallbackFunction(ChildButton1,BUTTON_RELEASED_EVENT,&ScrollBar_FuncCallbackForLeftButton_Released,ScrollBar); + + SetCallbackFunction(ChildButton2,BUTTON_PRESSED_EVENT,&ScrollBar_FuncCallbackForRightButton_Pressed,ScrollBar); + SetCallbackFunction(ChildButton2,BUTTON_RELEASED_EVENT,&ScrollBar_FuncCallbackForRightButton_Released,ScrollBar); + + SetCallbackFunction(ScrollRuller,BUTTON_PRESSED_EVENT,&ScrollBar_FuncCallbackForScrollRullerPressed,ScrollBar); + SetCallbackFunction(ScrollRuller,BUTTON_RELEASED_EVENT,&ScrollBar_FuncCallbackForScrollRullerReleased,ScrollBar); + + //pack button in control ScrollBar + PackControls(ScrollBar,ChildButton1); + PackControls(ScrollBar,ChildButton2); + PackControls(ScrollBar,ScrollRuller); + + return(ScrollBar); +} + +void* CreateVerticalScrollBar(struct ScrollBarData *info_for_control) +{ + struct ControlScrollBar *ScrollBar; + struct ControlButton *ChildButton1; + struct ControlButton *ChildButton2; + struct ControlButton *ScrollRuller; + struct ButtonData ChildButton1Data; + struct ButtonData ChildButton2Data; + struct ButtonData ScrollRullerData; + + ScrollBar=CreateScrollBar(info_for_control); + //set vertical orientation + ScrollBar->scb_flags=0; + ScrollBar->scb_flags=ScrollBar->scb_flags | FLAG_SCROLL_BAR_ORIENTATION_VERTICAL_ON; + + //fill data for first child button of scroller + ChildButton1Data.x=0; + ChildButton1Data.y=0; + ChildButton1Data.width=ScrollBar->ctrl_sizex; + ChildButton1Data.height=ChildButton1Data.width; + + //fill data for second child button of scroller + ChildButton2Data.x=0; + ChildButton2Data.y=ScrollBar->ctrl_sizey-ScrollBar->ctrl_sizex; + ChildButton2Data.width=ScrollBar->ctrl_sizex; + ChildButton2Data.height=ChildButton2Data.width; + + //fill data for scroll ruller button of scroller + ScrollRullerData.x=0; + ScrollRullerData.y=ScrollBar->ctrl_sizex; + ScrollRullerData.width=ScrollBar->ctrl_sizex; + ScrollRullerData.height=ScrollBar->ctrl_sizey-2*ScrollBar->ctrl_sizex; + + ChildButton1=CreateButton(&ChildButton1Data); + ChildButton2=CreateButton(&ChildButton2Data); + ScrollRuller=CreateButton(&ScrollRullerData); + + ChildButton1->flags=ChildButton1->flags & FLAG_HIDE_CONTROL; + ChildButton2->flags=ChildButton2->flags & FLAG_HIDE_CONTROL; + ScrollRuller->flags=ScrollRuller->flags & FLAG_HIDE_CONTROL; + + SetCallbackFunction(ChildButton1,BUTTON_PRESSED_EVENT,&ScrollBar_FuncCallbackForUpButton_Pressed,ScrollBar); + SetCallbackFunction(ChildButton1,BUTTON_RELEASED_EVENT,&ScrollBar_FuncCallbackForUpButton_Released,ScrollBar); + + SetCallbackFunction(ChildButton2,BUTTON_PRESSED_EVENT,&ScrollBar_FuncCallbackForDownButton_Pressed,ScrollBar); + SetCallbackFunction(ChildButton2,BUTTON_RELEASED_EVENT,&ScrollBar_FuncCallbackForDownButton_Released,ScrollBar); + + SetCallbackFunction(ScrollRuller,BUTTON_PRESSED_EVENT,&ScrollBar_FuncCallbackForScrollRullerPressed,ScrollBar); + SetCallbackFunction(ScrollRuller,BUTTON_RELEASED_EVENT,&ScrollBar_FuncCallbackForScrollRullerReleased,ScrollBar); + + //pack button in control ScrollBar + PackControls(ScrollBar,ChildButton1); + PackControls(ScrollBar,ChildButton2); + PackControls(ScrollBar,ScrollRuller); + + return(ScrollBar); +} + diff --git a/programs/develop/libraries/libGUI/SRC/control_scrolled_window.h b/programs/develop/libraries/libGUI/SRC/control_scrolled_window.h new file mode 100644 index 0000000000..b7581ac60a --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_scrolled_window.h @@ -0,0 +1,6 @@ +#define FLAG_SCROLL_WIN_HORIZONTAL_SCROLL_ON 0x1 +#define FLAG_SCROLL_WIN_VERTICAL_SCROLL_ON 0x2 + +#define FLAG_SCROLL_WIN_HORIZONTAL_SCROLL_OFF 0xfe +#define FLAG_SCROLL_WIN_VERTICAL_SCROLL_OFF 0xfd + diff --git a/programs/develop/libraries/libGUI/SRC/control_scrolled_window.inc b/programs/develop/libraries/libGUI/SRC/control_scrolled_window.inc new file mode 100644 index 0000000000..175700a5e3 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_scrolled_window.inc @@ -0,0 +1,530 @@ +/* + control ScrolledWindow +*/ + + +//////////////////////////////////////////////////////////////////////// +// pack controls in ScrolledWindow +//////////////////////////////////////////////////////////////////////// +void ScrolledWindowPackControls(void *parent,void *Control) +{ + struct HEADER *control; + struct ControlScrolledWindow *ScrolledWindow; + struct ControlScrollBar *HorizontalScrollBar; + struct ControlScrollBar *VerticalScrollBar; + struct FINITION *fin; + int x,y; + + ScrolledWindow=(struct ControlScrolledWindow*)parent; + control=(struct HEADER *)Control; + + if (control->ctrl_x+control->ctrl_sizex>ScrolledWindow->virtual_sizex) + { + ScrolledWindow->virtual_sizex=control->ctrl_x+control->ctrl_sizex; + } + if (control->ctrl_y+control->ctrl_sizey>ScrolledWindow->virtual_sizey) + { + ScrolledWindow->virtual_sizey=control->ctrl_y+control->ctrl_sizey; + } + + PackControls(ScrolledWindow,control); + + //calculate new control coordinates + x=control->ctrl_x+1;//add border width + y=control->ctrl_y+1;//add border heght + SetControlNewPosition(control,x,y); + + //save coordinates of control in arrea + ScrolledWindow->virtual_controls_x[ScrolledWindow->number_virtual_controls]=x; + ScrolledWindow->virtual_controls_y[ScrolledWindow->number_virtual_controls]=y; + ScrolledWindow->number_virtual_controls++; + + x=ScrolledWindow->ctrl_x+1; + y=ScrolledWindow->ctrl_y+1; + + //check cross control with scroll arrea + if (CheckCrossRectangles(x,y,ScrolledWindow->scroll_arrea_sizex,ScrolledWindow->scroll_arrea_sizey, + control->ctrl_x,control->ctrl_y,control->ctrl_sizex,control->ctrl_sizey)==TRUE) + { + control->flags=control->flags | FLAG_SHOW_CONTROL; + control->flags=control->flags & FLAG_MOUSE_BLOCKED_OFF; + } + else + { + control->flags=control->flags & FLAG_HIDE_CONTROL; + control->flags=control->flags | FLAG_MOUSE_BLOCKED_ON; + } + + if (ScrolledWindow->virtual_sizex>ScrolledWindow->scroll_arrea_sizex) + { + HorizontalScrollBar=(struct ControlScrollBar*)ScrolledWindow->horizontal_scroll; + + if ((ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_HORIZONTAL_SCROLL_ON)==FALSE) + { + ScrolledWindow->scroll_arrea_sizey=ScrolledWindow->ctrl_sizey-16-2; + ScrolledWindow->scw_flags=ScrolledWindow->scw_flags | FLAG_SCROLL_WIN_HORIZONTAL_SCROLL_ON; + HorizontalScrollBar->flags=HorizontalScrollBar->flags | FLAG_SHOW_CONTROL; + HorizontalScrollBar->flags=HorizontalScrollBar->flags & FLAG_MOUSE_BLOCKED_OFF; + } + } + + if (ScrolledWindow->virtual_sizey>ScrolledWindow->scroll_arrea_sizey) + { + VerticalScrollBar=(struct ControlScrollBar*)ScrolledWindow->vertical_scroll; + + if ((ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_VERTICAL_SCROLL_ON)==FALSE) + { + ScrolledWindow->scroll_arrea_sizex=ScrolledWindow->ctrl_sizex-16-2; + ScrolledWindow->scw_flags=ScrolledWindow->scw_flags | FLAG_SCROLL_WIN_VERTICAL_SCROLL_ON; + VerticalScrollBar->flags=VerticalScrollBar->flags | FLAG_SHOW_CONTROL; + VerticalScrollBar->flags=VerticalScrollBar->flags & FLAG_MOUSE_BLOCKED_OFF; + } + } + + if (ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_HORIZONTAL_SCROLL_ON) + { + HorizontalScrollBar->ruller_size=(float)ScrolledWindow->scroll_arrea_sizex; + HorizontalScrollBar->ruller_size=HorizontalScrollBar->ruller_size/((float)ScrolledWindow->virtual_sizex); + } + + if (ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_VERTICAL_SCROLL_ON) + { + VerticalScrollBar->ruller_size=(float)ScrolledWindow->scroll_arrea_sizey; + VerticalScrollBar->ruller_size=VerticalScrollBar->ruller_size/((float)ScrolledWindow->virtual_sizey); + } + + //finit draw arrea for control + fin=(struct FINITION*)control->finition; + fin->x=ScrolledWindow->ctrl_x+1; + fin->y=ScrolledWindow->ctrl_y+1; + fin->sizex=ScrolledWindow->scroll_arrea_sizex; + fin->sizey=ScrolledWindow->scroll_arrea_sizey; + fin->flags=fin->flags | FINITION_ON; + +} +//////////////////////////////////////////////////////////////////////////////// +// Draw full Scrolled Window +//////////////////////////////////////////////////////////////////////////////// +void ScrollWin_FuncCallback_HVScroll(struct HEADER* control,void *data) +{ + struct ControlScrollBar *Hscrollbar,*Vscrollbar; + struct ControlScrolledWindow *ScrolledWindow; + struct HEADER *seek_control,*exchange_control; + struct MESSAGE local_message; + struct FINITION *fin; + int i,new_x,new_y,x,y,sizex,sizey; + char c; + char *save_buf,*buf; + int save_size_x,save_size_y; + DWORD draw_output; + + ScrolledWindow=(gui_scrolled_window_t*)data; + Hscrollbar=(gui_scroll_bar_t*)ScrolledWindow->horizontal_scroll; + Vscrollbar=(gui_scroll_bar_t*)ScrolledWindow->vertical_scroll; + ScrolledWindow->virtual_x=(ScrolledWindow->virtual_sizex-ScrolledWindow->scroll_arrea_sizex)*Hscrollbar->ruller_pos; + ScrolledWindow->virtual_y=(ScrolledWindow->virtual_sizey-ScrolledWindow->scroll_arrea_sizey)*Vscrollbar->ruller_pos; + + x=ScrolledWindow->ctrl_x+1; + y=ScrolledWindow->ctrl_y+1; + sizex=ScrolledWindow->scroll_arrea_sizex; + sizey=ScrolledWindow->scroll_arrea_sizey; + + //alocate a buffer for draw text + c=screen.bits_per_pixel >> 3; + i=sizex*sizey*c; + buf=malloc(i); + + //save current screen parameters + save_buf=screen.buffer; + save_size_x=screen.size_x; + save_size_y=screen.size_y; + draw_output=screen.draw_output; + + //load parameters of local buffer + screen.buffer=buf; + screen.size_x=sizex; + screen.size_y=sizey; + screen.draw_output=DRAW_OUTPUT_BUFFER; + + //fill buffer by background color + FillArrea(buf,i,screen.bits_per_pixel,COLOR_LIGHT); + + local_message.type=MESSAGE_FULL_REDRAW_ALL_WITH_FINITION; + local_message.arg1=0; + local_message.arg2=0; + local_message.arg3=sizex; + local_message.arg4=sizey; + + seek_control=(struct HEADER*)Vscrollbar->ctrl_fd; + //move controls in new position + for(i=0;inumber_virtual_controls;i++) + { + new_x=ScrolledWindow->virtual_controls_x[i]-ScrolledWindow->virtual_x; + new_y=ScrolledWindow->virtual_controls_y[i]-ScrolledWindow->virtual_y; + + SetControlNewPosition(seek_control,new_x,new_y); + + if (CheckCrossRectangles(x,y,sizex,sizey,new_x,new_y, + seek_control->ctrl_sizex, + seek_control->ctrl_sizey)==TRUE) + { + seek_control->flags=seek_control->flags | FLAG_SHOW_CONTROL; + seek_control->flags=seek_control->flags & FLAG_MOUSE_BLOCKED_OFF; + + //move control + SetControlNewPosition(seek_control,new_x-x,new_y-y); + //call draw control in buffer + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,&local_message); + //restore last position of control + SetControlNewPosition(seek_control,new_x,new_y); + //restore coordinates of last finition of control + fin=(finition_t*)seek_control->finition; + fin->x=x; + fin->y=y; + } + else + { + seek_control->flags=seek_control->flags & FLAG_HIDE_CONTROL; + seek_control->flags=seek_control->flags | FLAG_MOUSE_BLOCKED_ON; + } + + exchange_control=(struct HEADER*)seek_control->ctrl_fd; + seek_control=exchange_control; + } + //restore screen parameters + screen.buffer=save_buf; + screen.size_x=save_size_x; + screen.size_y=save_size_y; + screen.draw_output=draw_output; + + //move rendered objects from local buffer to screen + fin=(finition_t*)ScrolledWindow->finition; + if (fin->flags & FINITION_ON) + DrawImageFinit(fin,x,y,sizex,sizey,screen.bits_per_pixel,buf); + else + DrawImage(x,y,sizex,sizey,screen.bits_per_pixel,buf); + + //free local buffer + free(buf); +} + +void DrawScrolledWindow(struct ControlScrolledWindow *ScrolledWindow) +{ + int x,y,sizex,sizey; + struct FINITION *fin; + + x=ScrolledWindow->ctrl_x; + y=ScrolledWindow->ctrl_y; + sizex=ScrolledWindow->ctrl_sizex; + sizey=ScrolledWindow->ctrl_sizey; + fin=(struct FINITION*)ScrolledWindow->finition; + + if ((ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_HORIZONTAL_SCROLL_ON) || + (ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_VERTICAL_SCROLL_ON)) + { + Draw(fin,TOOL_RECTANGLE,x,y,ScrolledWindow->scroll_arrea_sizex+2, + ScrolledWindow->scroll_arrea_sizey+2,COLOR_ABSOLUTE_DARK); + } + else + Draw(fin,TOOL_RECTANGLE,x,y,sizex,sizey,COLOR_ABSOLUTE_DARK); + + ScrollWin_FuncCallback_HVScroll(NULL,ScrolledWindow); +} + +void ScrlWinCheckActivatedForKeysControl(struct ControlScrolledWindow *ScrolledWindow) +{ + struct HEADER *control,*seek_control,*exchange_control; + struct MESSAGE local_message; + struct FINITION *fin; + struct ControlScrollBar *Vscrollbar,*Hscrollbar; + int i,x,y,sizex,sizey; + int sx,sy; + + control=(struct HEADER*)ScrolledWindow->active_control_for_keys; + + x=ScrolledWindow->ctrl_x+1; + y=ScrolledWindow->ctrl_y+1; + sizex=ScrolledWindow->scroll_arrea_sizex; + sizey=ScrolledWindow->scroll_arrea_sizey; + + if (CheckFullCrossRectangles(x,y,sizex,sizey, + control->ctrl_x,control->ctrl_y,control->ctrl_sizex,control->ctrl_sizey)==TRUE) return; + + //calculate new x and y coordinates + if (ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_HORIZONTAL_SCROLL_ON) + { + sx=(control->ctrl_x-x); + + if (sx<0) sx=x; + else + { + if (control->ctrl_sizexctrl_sizex; + else sx=x; + } + } + + if (ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_VERTICAL_SCROLL_ON) + { + sy=(control->ctrl_y-y); + + if (sy<0) sy=y; + else + { + if (control->ctrl_sizeyctrl_sizey; + else sy=y; + } + } + + Vscrollbar=(struct ControlScrollBar*)ScrolledWindow->vertical_scroll; + Hscrollbar=(struct ControlScrollBar*)ScrolledWindow->horizontal_scroll; + //find active control and virtual control coordinates + seek_control=(struct HEADER*)Vscrollbar->ctrl_fd; + + for(i=0;inumber_virtual_controls;i++) + { + if (seek_control==control) + { + if (ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_HORIZONTAL_SCROLL_ON) + ScrolledWindow->virtual_x=ScrolledWindow->virtual_controls_x[i]-sx; + if (ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_VERTICAL_SCROLL_ON) + ScrolledWindow->virtual_y=ScrolledWindow->virtual_controls_y[i]-sy; + break; + } + + exchange_control=(struct HEADER*)seek_control->ctrl_fd; + seek_control=exchange_control; + } + + if (ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_HORIZONTAL_SCROLL_ON) + { + Hscrollbar->ruller_pos=(float)ScrolledWindow->virtual_x; + Hscrollbar->ruller_pos=Hscrollbar->ruller_pos/((float)(ScrolledWindow->virtual_sizex-ScrolledWindow->scroll_arrea_sizex)); + SpecialRedrawControl(Hscrollbar); + } + if (ScrolledWindow->scw_flags & FLAG_SCROLL_WIN_VERTICAL_SCROLL_ON) + { + Vscrollbar->ruller_pos=(float)ScrolledWindow->virtual_y; + Vscrollbar->ruller_pos=Vscrollbar->ruller_pos/((float)(ScrolledWindow->virtual_sizey-ScrolledWindow->scroll_arrea_sizey)); + SpecialRedrawControl(Vscrollbar); + } + ScrollWin_FuncCallback_HVScroll(NULL,ScrolledWindow); +} + +//--------------------------------------------------------------------------------- +// control ScrolledWindowScrolledWindow->virtual_sizex +//--------------------------------------------------------------------------------- +void ScrolledWindowProc(struct ControlScrolledWindow *ScrolledWindow,struct MESSAGE *message) +{ + int i,x,y,sizex,sizey; + struct HEADER *seek_control,*exchange_control; + struct ControlScrollBar *Hscrollbar,*Vscrollbar; + struct MESSAGE local_message; + struct FINITION *fin; + struct TIMER *timer; + + x=ScrolledWindow->ctrl_x; + y=ScrolledWindow->ctrl_y; + sizex=ScrolledWindow->ctrl_sizex; + sizey=ScrolledWindow->ctrl_sizey; + + switch(message->type) + { + case MESSAGE_FULL_REDRAW_ALL: + { + //draw ScrolledWindow + if (ScrolledWindow->flags & FLAG_SHOW_CONTROL) + { + DrawScrolledWindow(ScrolledWindow); + Hscrollbar=(gui_scroll_bar_t*)ScrolledWindow->horizontal_scroll; + Vscrollbar=(gui_scroll_bar_t*)ScrolledWindow->vertical_scroll; + //draw scroll bars + ControlProc=(void (*)(void *Control,gui_message_t *message))Hscrollbar->ctrl_proc; + ControlProc(Hscrollbar,message); + ControlProc=(void (*)(void *Control,gui_message_t *message))Vscrollbar->ctrl_proc; + ControlProc(Vscrollbar,message); + } + break; + } + case MESSAGE_FULL_REDRAW_ALL_WITH_FINITION: + { + fin=(struct FINITION*)ScrolledWindow->finition; + fin->flags=fin->flags | FINITION_ON; + fin->x=message->arg1; + fin->y=message->arg2; + fin->sizex=message->arg3; + fin->sizey=message->arg4; + DrawScrolledWindow(ScrolledWindow); + SendMessage((struct HEADER*)ScrolledWindow,message);//<<<<<<---------------------------------- + break; + } + case MESSAGE_SPECIALIZED: + { + if (ScrolledWindow->flags & FLAG_SHOW_CONTROL) SendMessage((struct HEADER*)ScrolledWindow,message); + ScrolledWindow->flags=ScrolledWindow->flags & FLAG_GET_SPECIALIZED_MESSAGE_OFF; + break; + } + + case MESSAGE_KEYS_EVENT: + { + if (ScrolledWindow->active_control_for_keys!=NULL) ScrlWinCheckActivatedForKeysControl(ScrolledWindow); + SendMessage((struct HEADER*)ScrolledWindow,message); + break; + } + case MESSAGE_MOUSE_EVENT: + { + SendMessage((struct HEADER*)ScrolledWindow,message); + break; + } + case MESSAGE_CHANGE_POSITION_EVENT: + { + ScrolledWindow->ctrl_x=ScrolledWindow->ctrl_x+message->arg1; + ScrolledWindow->ctrl_y=ScrolledWindow->ctrl_y+message->arg2; + + //change virtual coordinates of controls + Vscrollbar=(struct ControlScrollBar*)ScrolledWindow->vertical_scroll; + seek_control=(struct HEADER *)Vscrollbar->ctrl_fd; + for(i=0;inumber_virtual_controls;i++) + { + ScrolledWindow->virtual_controls_x[i]+=message->arg1; + ScrolledWindow->virtual_controls_y[i]+=message->arg2; + + fin=(struct FINITION*)seek_control->finition; + fin->x=ScrolledWindow->ctrl_x+1; + fin->y=ScrolledWindow->ctrl_y+1; + fin->sizex=ScrolledWindow->scroll_arrea_sizex; + fin->sizey=ScrolledWindow->scroll_arrea_sizey; + + exchange_control=(struct HEADER*)seek_control->ctrl_fd; + seek_control=exchange_control; + } + + SendMessage((struct HEADER*)ScrolledWindow,message); + break; + } + case MESSAGE_CALL_TIMER_EVENT: + { + if (ScrolledWindow->timer!=(DWORD*)NULL) + { + timer=(struct TIMER*)ScrolledWindow->timer; + if (timer->flags & FLAG_TIMER_ON) Timer(timer); + } + SendMessage((struct HEADER*)ScrolledWindow,message); + break; + } + case MESSAGE_SET_FOCUSE: + { + //SendMessage((struct HEADER*)ScrolledWindow,message); + break; + } + case MESSAGE_CHANGE_FOCUSE: + { + //SendMessage((struct HEADER*)ScrolledWindow,message); + break; + } + case MESSAGE_DESTROY_CONTROL: + { + if (ScrolledWindow->timer!=(DWORD*)NULL) free(ScrolledWindow->timer); + free(ScrolledWindow->finition); + SendMessage((struct HEADER*)ScrolledWindow,message); + break; + } + case MESSAGE_SET_MAIN_PARENT: + { + SendMessage((struct HEADER*)ScrolledWindow,message); + ScrolledWindow->main_parent=(DWORD*)message->arg1; + break; + } + + default: break; + } +} + +//--------------------------------------------------------------------------------- +// create control ScrolledWindow +//--------------------------------------------------------------------------------- +void* CreateScrolledWindow(struct ScrolledWindowData *info_for_control) +{ + struct ControlScrolledWindow *ScrolledWindow; + struct FINITION *fin; + struct ControlScrollBar *HorizontalScrollBar; + struct ControlScrollBar *VerticalScrollBar; + struct ScrollBarData HorizontalScrollData; + struct ScrollBarData VerticalScrollData; + + + ScrolledWindow=malloc(sizeof(struct ControlScrolledWindow)); + ScrolledWindow->finition=malloc(sizeof(struct FINITION)); + fin=(struct FINITION*)ScrolledWindow->finition; + fin->flags=0; + ScrolledWindow->scw_flags=0; + + ID++; +#ifdef DEBUG + printf("\ncreated scrollet window with ID=%d",(int)ID); +#endif + ScrolledWindow->child_bk=(DWORD*)NULL; + ScrolledWindow->child_fd=(DWORD*)NULL; + ScrolledWindow->active_control_for_keys=(DWORD*)NULL; + ScrolledWindow->active_control_for_mouse=(DWORD*)NULL; + ScrolledWindow->callback=(DWORD*)NULL; + ScrolledWindow->timer=(DWORD*)NULL; + + ScrolledWindow->ctrl_proc=(DWORD*)&ScrolledWindowProc; + ScrolledWindow->ctrl_x=(DWORD)info_for_control->x; + ScrolledWindow->ctrl_y=(DWORD)info_for_control->y; + ScrolledWindow->ctrl_sizex=(DWORD)info_for_control->width; + ScrolledWindow->ctrl_sizey=(DWORD)info_for_control->height; + ScrolledWindow->ctrl_ID=ID; + ScrolledWindow->virtual_x=0; + ScrolledWindow->virtual_y=0; + ScrolledWindow->virtual_controls_x=malloc(1024*sizeof(DWORD)); + ScrolledWindow->virtual_controls_y=malloc(1024*sizeof(DWORD)); + ScrolledWindow->virtual_sizex=0; + ScrolledWindow->virtual_sizey=0; + ScrolledWindow->number_virtual_controls=0; + ScrolledWindow->flags=0; + ScrolledWindow->flags=ScrolledWindow->flags | FLAG_SHOW_CONTROL; + ScrolledWindow->flags=ScrolledWindow->flags | FLAG_FOCUSE_INPUT_SUPPOROTE; + + //calculate default scroll arrea size + ScrolledWindow->scroll_arrea_sizex=ScrolledWindow->ctrl_sizex-2; + ScrolledWindow->scroll_arrea_sizey=ScrolledWindow->ctrl_sizey-2; + + //create child scroll bars + HorizontalScrollData.x=0; + HorizontalScrollData.y=ScrolledWindow->ctrl_sizey-16; + HorizontalScrollData.width=ScrolledWindow->ctrl_sizex-16; + HorizontalScrollData.height=16; + HorizontalScrollData.ruller_size=1.0; + HorizontalScrollData.ruller_pos=0.0; + HorizontalScrollData.ruller_step=0.05; + + VerticalScrollData.x=ScrolledWindow->ctrl_sizex-16; + VerticalScrollData.y=0; + VerticalScrollData.width=16; + VerticalScrollData.height=ScrolledWindow->ctrl_sizey-16; + VerticalScrollData.ruller_size=1.0; + VerticalScrollData.ruller_pos=0.0; + VerticalScrollData.ruller_step=0.05; + + HorizontalScrollBar=CreateHorizontalScrollBar(&HorizontalScrollData); + VerticalScrollBar=CreateVerticalScrollBar(&VerticalScrollData); + + SetCallbackFunction(HorizontalScrollBar,SCROLLBAR_CHANGED_EVENT,&ScrollWin_FuncCallback_HVScroll,ScrolledWindow); + SetCallbackFunction(VerticalScrollBar,SCROLLBAR_CHANGED_EVENT,&ScrollWin_FuncCallback_HVScroll,ScrolledWindow); + + PackControls(ScrolledWindow,HorizontalScrollBar); + PackControls(ScrolledWindow,VerticalScrollBar); + + ScrolledWindow->horizontal_scroll=(DWORD*)HorizontalScrollBar; + ScrolledWindow->vertical_scroll=(DWORD*)VerticalScrollBar; + //disable show scrollers and block mouse for them + HorizontalScrollBar->flags=HorizontalScrollBar->flags & FLAG_HIDE_CONTROL; + HorizontalScrollBar->flags=HorizontalScrollBar->flags | FLAG_MOUSE_BLOCKED_ON; + VerticalScrollBar->flags=VerticalScrollBar->flags & FLAG_HIDE_CONTROL; + VerticalScrollBar->flags=VerticalScrollBar->flags | FLAG_MOUSE_BLOCKED_ON; + + return(ScrolledWindow); +} + diff --git a/programs/develop/libraries/libGUI/SRC/control_text.h b/programs/develop/libraries/libGUI/SRC/control_text.h new file mode 100644 index 0000000000..c38be2dd25 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_text.h @@ -0,0 +1,16 @@ + +#define TEXT_ORIENTATION_FROM_LEFT_TO_RIGHT_ON 0x1 +#define TEXT_ORIENTATION_FROM_LEFT_TO_RIGHT_OFF 0xfe + +#define TEXT_BACKGROUND_ON 0x2; +#define TEXT_BACKGROUND_OFF 0xfd; + +struct TextSize +{ + int sizex; + int sizey; +}; + +typedef struct TextSize gui_text_size_t; + + diff --git a/programs/develop/libraries/libGUI/SRC/control_text.inc b/programs/develop/libraries/libGUI/SRC/control_text.inc new file mode 100644 index 0000000000..b581857943 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/control_text.inc @@ -0,0 +1,182 @@ +/* + control Text +*/ + + +gui_text_size_t GetStringSize(font_t *font,char *s) +{ + long len; + gui_text_size_t size; + + len=strlen(s); + if (font->size==FONT_CONSTANT_SIZE) + { + if (font->flags & FONT_FLAG_ORIENTATION_HORIZONTAL_FROM_LEFT_TO_RIGHT_ON) + { + size.sizex=len*font->sizex; + size.sizey=font->sizey; + } + } + + return(size); +} + +void TextBackgroundOn(gui_text_t *Text) +{ + Text->txt_flags |=TEXT_BACKGROUND_ON; +} + +void TextBackgroundOff(gui_text_t *Text) +{ + Text->txt_flags &=TEXT_BACKGROUND_ON; +} + +void DisplayText(gui_text_t *Text) +{ + int x; + int y; + int sizex; + int sizey; + char v; + font_t *font; + gui_text_size_t size; + struct FINITION *fin; + + x=Text->ctrl_x; + y=Text->ctrl_y; + fin=(struct FINITION*)Text->finition; + font=(font_t*)Text->font; + + v=Text->txt_flags & TEXT_BACKGROUND_ON; + if (v) font->flags|=FONT_FLAG_DRAW_BACKGROUND_ON; + else font->flags&=FONT_FLAG_DRAW_BACKGROUND_OFF; + + v=Text->txt_flags & TEXT_ORIENTATION_FROM_LEFT_TO_RIGHT_ON; + if (v) font->flags|=FONT_FLAG_ORIENTATION_HORIZONTAL_FROM_LEFT_TO_RIGHT_ON; + else font->flags&=FONT_FLAG_ORIENTATION_HORIZONTAL_FROM_LEFT_TO_RIGHT_OFF; + + //recalculate size of control text befor draw + size=GetStringSize((font_t*)Text->font,Text->text); + Text->ctrl_sizex=(DWORD)size.sizex; + Text->ctrl_sizey=(DWORD)size.sizey; + + DrawFont=(void(*)(finition_t *fin,int fx,int fy,DWORD color, + DWORD background_color,font_t *font,BYTE *s))font->fnt_draw; + DrawFont(fin,x,y,Text->color,Text->background_color,font,Text->text); +} + +//--------------------------------------------------------------------------------- +// control Text +//--------------------------------------------------------------------------------- +void TextProc(gui_text_t *Text,gui_message_t *message) +{ + finition_t *fin; + + switch(message->type) + { + case MESSAGE_FULL_REDRAW_ALL: + { + //draw Text + if (Text->flags & FLAG_SHOW_CONTROL) DisplayText(Text); + break; + } + case MESSAGE_FULL_REDRAW_ALL_WITH_FINITION: + { + fin=(struct FINITION*)Text->finition; + fin->flags=fin->flags | FINITION_ON; + fin->x=message->arg1; + fin->y=message->arg2; + fin->sizex=message->arg3; + fin->sizey=message->arg4; + DisplayText(Text); + break; + } + case MESSAGE_SPECIALIZED: + { + if (Text->flags & FLAG_GET_SPECIALIZED_MESSAGE_ON) + { + if (Text->flags & FLAG_SHOW_CONTROL) DisplayText(Text); + Text->flags=Text->flags & FLAG_GET_SPECIALIZED_MESSAGE_OFF; + } + break; + } + case MESSAGE_CHANGE_POSITION_EVENT: + { + Text->ctrl_x=Text->ctrl_x+message->arg1; + Text->ctrl_y=Text->ctrl_y+message->arg2; + break; + } + case MESSAGE_DESTROY_CONTROL: + { + free(Text->finition); + break; + } + case MESSAGE_SET_MAIN_PARENT: + { + SendMessage((struct HEADER*)Text,message); + Text->main_parent=(DWORD*)message->arg1; + break; + } + + default: break; + } + //send message to child controls(if there is) + SendMessage((struct HEADER*)Text,message); +} + +//--------------------------------------------------------------------------------- +// create control Text +//--------------------------------------------------------------------------------- +void* CreateText(gui_text_data_t *info_for_control) +{ + gui_text_t *Text; + finition_t *fin; + gui_text_size_t size; + + Text=malloc(sizeof(struct ControlText)); + Text->finition=malloc(sizeof(struct FINITION)); + fin=(struct FINITION*)Text->finition; + fin->flags=0; + + if (info_for_control->font==(DWORD*)NULL) Text->font=FontsMeneger.default_font; + else Text->font=info_for_control->font; + + size=GetStringSize((font_t*)Text->font,info_for_control->text); + + ID++; +#ifdef DEBUG + printf("\ncreated text with ID=%d",(int)ID); +#endif + Text->child_bk=(DWORD*)NULL; + Text->child_fd=(DWORD*)NULL; + Text->active_control_for_keys=(DWORD*)NULL; + Text->active_control_for_mouse=(DWORD*)NULL; + Text->callback=(DWORD*)NULL; + Text->timer=(DWORD*)NULL; + + Text->ctrl_proc=(DWORD*)&TextProc; + Text->ctrl_x=(DWORD)info_for_control->x; + Text->ctrl_y=(DWORD)info_for_control->y; + Text->ctrl_sizex=(DWORD)size.sizex; + Text->ctrl_sizey=(DWORD)size.sizey; + Text->ctrl_ID=ID; + Text->color=info_for_control->color; + Text->background_color=info_for_control->background_color; + Text->text=info_for_control->text; + Text->txt_flags=0; + Text->txt_flags|=TEXT_ORIENTATION_FROM_LEFT_TO_RIGHT_ON; + + if (info_for_control->background) + { + Text->txt_flags|=TEXT_BACKGROUND_ON; + } + else + { + Text->txt_flags&=TEXT_BACKGROUND_OFF; + } + + Text->flags=0; + Text->flags=Text->flags | FLAG_SHOW_CONTROL; + + return(Text); +} diff --git a/programs/develop/libraries/libGUI/SRC/draw_controls.h b/programs/develop/libraries/libGUI/SRC/draw_controls.h new file mode 100644 index 0000000000..ac5c2ff547 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/draw_controls.h @@ -0,0 +1,31 @@ + +#define FINITION_ON 0x1 +#define FINITION_OFF 0xfe + +#define COLOR_FON 0x924900 +#define COLOR_DARK 0x5a5a5a +#define COLOR_ABSOLUTE_DARK 0x0 +#define COLOR_MIDDLE_LIGHT 0xffff00 +#define COLOR_LIGHT 0xffffff + +#define COLOR_INSERT 0x71ff30//0xffff10 + +///////////////////////////////////////////////////////////////////////////////////////// +// tool's names +///////////////////////////////////////////////////////////////////////////////////////// +#define TOOL_PIXEL 128 +#define TOOL_LINE 129 +#define TOOL_VERTICAL_LINE 130 +#define TOOL_HORIZONTAL_LINE 131 +#define TOOL_RECTANGLE 132 +#define TOOL_FILLED_RECTANGLE 133 +#define TOOL_GRADIENT_UP_FILLED_RECTANGLE 134 +#define TOOL_GRADIENT_DOWN_FILLED_RECTANGLE 135 +#define TOOL_GRADIENT_LEFT_FILLED_RECTANGLE 136 +#define TOOL_GRADIENT_RIGHT_FILLED_RECTANGLE 137 +#define TOOL_CIRCLE 138 +#define TOOL_FILLED_CIRCLE 139 +#define TOOL_ELLIPSE 140 +#define TOOL_FILLED_ELLIPSE 141 +#define TOOL_IMAGE 142 + diff --git a/programs/develop/libraries/libGUI/SRC/draw_controls.inc b/programs/develop/libraries/libGUI/SRC/draw_controls.inc new file mode 100644 index 0000000000..f282d96745 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/draw_controls.inc @@ -0,0 +1,2149 @@ +/* + functions for draw controls +*/ + +//--------------------------------------------------------------------------------- +// fill buffer by value +//--------------------------------------------------------------------------------- +void FillArrea(void *buf,DWORD size,BYTE bits_per_pixel,DWORD value) +{ + DWORD i,j; + char r,g,b; + + switch(bits_per_pixel) + { + case 32: + { + j=(size >> 2); + for(i=0;i> 8; + g=value & 0xff; + value=value >> 8; + r=value & 0xff; + + j=(size/3); + for(i=0;iscreen.size_x-1) {x=screen.size_x-1;} + if (y>screen.size_y-1) {y=screen.size_y-1;} + if (x<0) {x=0;} + if (y<0) {y=0;} + + switch(screen.draw_output) + { + case DRAW_OUTPUT_SCREEN: + { + x+=screen.x; + y+=screen.y; + gui_ksys_put_pixel_window(x,y,color); + break; + } + case DRAW_OUTPUT_BUFFER: + { + ptr=screen.buffer; + switch(screen.bits_per_pixel) + { + case 24: + { + ptr=ptr+(y*screen.size_x+x)*3; + b=color & 0xff; + color=color >>8; + g=color & 0xff; + color=color >>8; + r=color & 0xff; + + ptr[0]=b; + ptr[1]=g; + ptr[2]=r; + break; + } + case 32: + { + ptr2=(DWORD*)ptr+y*screen.size_x+x; + *ptr2=color; + break; + } + default: break; + } + break; + } + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing pixels on screen with finition +//--------------------------------------------------------------------------------- +void DrawPixelFinit(struct FINITION *fin,int x,int y,DWORD color) +{ + if (x>=fin->x && x<=fin->x+fin->sizex-1 && + y>=fin->y && y<=fin->y+fin->sizey-1) DrawPixel(x,y,color); +} + + +//--------------------------------------------------------------------------------- +// get color of pixel inc coordinates x,y +//--------------------------------------------------------------------------------- +DWORD GetColorPixel(int x,int y) +{ + char r,g,b; + char *ptr; + DWORD color,coordinates; + DWORD *ptr2; + + if (x>screen.size_x-1) {x=screen.size_x-1;} + if (y>screen.size_y-1) {y=screen.size_y-1;} + if (x<0) {x=0;} + if (y<0) {y=0;} + + switch(screen.draw_output) + { + case DRAW_OUTPUT_SCREEN: + { + x+=screen.x; + y+=screen.y; + coordinates=x; + coordinates=coordinates << 16; + coordinates +=y; + color=gui_ksys_get_color_pixel_window(coordinates); + break; + } + case DRAW_OUTPUT_BUFFER: + { + ptr=screen.buffer; + switch(screen.bits_per_pixel) + { + case 24: + { + ptr=ptr+(y*screen.size_x+x)*3; + color=*ptr; + color=color & 0xffffff; + break; + } + case 32: + { + ptr2=(DWORD*)ptr+y*screen.size_x+x; + color=*ptr2; + break; + } + default: break; + } + } + } + return(color); +} + +//--------------------------------------------------------------------------------- +// draw vertical line on screen +//--------------------------------------------------------------------------------- +void DrawVerticalLine(int x,int y1,int y2,DWORD color) +{ + char r,g,b; + char *ptr; + DWORD *ptr2; + int a,i,count; + + if (x>screen.size_x-1) {x=screen.size_x-1;} + if (y1>screen.size_y-1) {y1=screen.size_y-1;} + if (y2>screen.size_y-1) {y2=screen.size_y-1;} + if (x<0) {x=0;} + if (y1<0) {y1=0;} + if (y2<0) {y2=0;} + + switch(screen.draw_output) + { + case DRAW_OUTPUT_SCREEN: + { + x+=screen.x; + y1+=screen.y; + y2+=screen.y; + gui_ksys_draw_line_window(x,y1,x,y2,color); + break; + } + case DRAW_OUTPUT_BUFFER: + { + if (y1>8; + g=color & 0xff; + color=color >>8; + r=color & 0xff; + + a=screen.size_x*3; + for(i=0;i<=count;i++) + { + ptr[0]=b; + ptr[1]=g; + ptr[2]=r; + ptr+=a; + } + break; + } + case 32: + { + ptr2=(DWORD*)ptr+a*screen.size_x+x; + a=screen.size_x; + for(i=0;i<=count;i++) + { + *ptr2=color; + ptr2+=a; + } + break; + } + default: break; + } + } + } +} + +//--------------------------------------------------------------------------------- +// draw finited vertical line on screen +//--------------------------------------------------------------------------------- +void DrawVerticalLineFinit(struct FINITION *fin,int x,int y1,int y2,DWORD color) +{ + int xmin,xmax,ymin,ymax,v,sy; + + xmin=fin->x; + xmax=fin->x+fin->sizex-1; + ymin=fin->y; + ymax=fin->y+fin->sizey-1; + + if (y2xmax) return; + if (y2ymax) return; + + //finit x coordinates and sizex + sy=y1-ymin; + + if (sy>=0) + { + if (y2>ymax) y2=ymax; + } + else + { + y1=ymin; + if (y2>ymax) y2=ymax; + } + DrawVerticalLine(x,y1,y2,color); +} + +//--------------------------------------------------------------------------------- +// draw horizontal line on screen +//--------------------------------------------------------------------------------- +void DrawHorizontalLine(int x1,int x2,int y,DWORD color) +{ + char r,g,b; + char *ptr; + int a,i,count; + DWORD *ptr2; + + if (y>screen.size_y-1) {y=screen.size_y-1;} + if (x1>screen.size_x-1) {x1=screen.size_x-1;} + if (x2>screen.size_x-1) {x2=screen.size_x-1;} + if (y<0) {y=0;} + if (x1<0) {x1=0;} + if (x2<0) {x2=0;} + + switch(screen.draw_output) + { + case DRAW_OUTPUT_SCREEN: + { + x1+=screen.x; + x2+=screen.x; + y+=screen.y; + gui_ksys_draw_line_window(x1,y,x2,y,color); + break; + } + case DRAW_OUTPUT_BUFFER: + { + if (x1>8; + g=color & 0xff; + color=color >>8; + r=color & 0xff; + + for(i=0;i<=count;i++) + { + ptr[0]=b; + ptr[1]=g; + ptr[2]=r; + ptr=ptr+3; + } + break; + } + case 32: + { + ptr2=(DWORD*)ptr+y*screen.size_x+a; + + for(i=0;i<=count;i++) + { + *ptr2=color;ptr2++; + } + break; + } + default:break; + } + } + } +} + +//--------------------------------------------------------------------------------- +// draw finited vertical line on screen +//--------------------------------------------------------------------------------- +void DrawHorizontalLineFinit(struct FINITION *fin,int x1,int x2,int y,DWORD color) +{ + int xmin,xmax,ymin,ymax,v,sx; + + xmin=fin->x; + xmax=fin->x+fin->sizex-1; + ymin=fin->y; + ymax=fin->y+fin->sizey-1; + + if (x2ymax) return; + if (x2xmax) return; + + //finit x coordinates and sizex + sx=x1-xmin; + + if (sx>=0) + { + if (x2>xmax) x2=xmax; + } + else + { + x1=xmin; + if (x2>xmax) x2=xmax; + } + DrawHorizontalLine(x1,x2,y,color); +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing line on screen +//--------------------------------------------------------------------------------- +int sign(int value) +{ + if (value==0) return(0); + if (value<0) {return(-1);} + else {return(1);} +} + +int abs(int value) +{ + if (value<0) {value=-value;} + + return(value); +} + +void DrawLine(int x1, int y1, int x2, int y2,DWORD color) +{ + int x; + int y; + int dx; + int dy; + int sx; + int sy; + int z; + int e; + int i; + char ch; + + switch(screen.draw_output) + { + case DRAW_OUTPUT_SCREEN: + { + if (y1>screen.size_y-1) {y1=screen.size_y-1;} + if (y2>screen.size_y-1) {y2=screen.size_y-1;} + if (x1>screen.size_x-1) {x1=screen.size_x-1;} + if (x2>screen.size_x-1) {x2=screen.size_x-1;} + if (y1<0) {y1=0;} + if (y2<0) {y2=0;} + if (x1<0) {x1=0;} + if (x2<0) {x2=0;} + + x1+=screen.x; + x2+=screen.x; + y1+=screen.y; + y2+=screen.y; + gui_ksys_draw_line_window(x1,y1,x2,y2,color); + break; + } + case DRAW_OUTPUT_BUFFER: + { + + x = x1; + y = y1; + dx = abs(x2-x1); + dy = abs(y2-y1); + sx = sign(x2-x1); + sy = sign(y2-y1); + + if( dx==0 && dy==0 ) + { + DrawPixel(x1, y1,color); + return; + } + if( dy>dx ) + { + z = dx; + dx = dy; + dy = z; + ch = 1; + } + else + { + ch = 0; + } + e = 2*dy-dx; + i = 1; + + do + { + DrawPixel(x,y,color); + while(e>=0) + { + if( ch==1 ) x = x+sx; + else y = y+sy; + + if( ch==1 ) y = y+sy; + else x = x+sx; + + e = e-2*dx; + } + if( ch==1 ) y = y+sy; + else x = x+sx; + + e = e+2*dy; + i++; + } + while(i<=dx); + DrawPixel(x, y,color); + break; + } + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing rectangle on screen +//--------------------------------------------------------------------------------- +void DrawRectangle(int x,int y,int size_x,int size_y,DWORD color) +{ + + if (size_x==0 || size_y==0) return; + + DrawHorizontalLine(x,x+size_x-1,y,color); + DrawVerticalLine(x+size_x-1,y,y+size_y-1,color); + DrawHorizontalLine(x,x+size_x-1,y+size_y-1,color); + DrawVerticalLine(x,y,y+size_y-1,color); +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing finited rectangle on screen +//--------------------------------------------------------------------------------- +void DrawRectangleFinit(struct FINITION *fin,int x,int y,int size_x,int size_y,DWORD color) +{ + + if (size_x==0 || size_y==0) return; + + DrawHorizontalLineFinit(fin,x,x+size_x-1,y,color); + DrawVerticalLineFinit(fin,x+size_x-1,y,y+size_y-1,color); + DrawHorizontalLineFinit(fin,x,x+size_x-1,y+size_y-1,color); + DrawVerticalLineFinit(fin,x,y,y+size_y-1,color); +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing filled rectangle on screen +//--------------------------------------------------------------------------------- +void DrawFilledRectangle(int x,int y,int size_x,int size_y,DWORD color) +{ + int i,j; + int x1,y1,x2,y2; + + if (size_x==0 || size_y==0) return; + + switch(screen.draw_output) + { + case DRAW_OUTPUT_SCREEN: + { + x1=x; + y1=y; + x2=x+size_x-1; + y2=y+size_y-1; + if (y1>screen.size_y-1) {y1=screen.size_y-1;} + if (y2>screen.size_y-1) {y2=screen.size_y-1;} + if (x1>screen.size_x-1) {x1=screen.size_x-1;} + if (x2>screen.size_x-1) {x2=screen.size_x-1;} + if (y1<0) {y1=0;} + if (y2<0) {y2=0;} + if (x1<0) {x1=0;} + if (x2<0) {x2=0;} + + size_x=x2-x1+1; + size_y=y2-y1+1; + x1+=screen.x; + y1+=screen.y; + + gui_ksys_draw_filled_rectangle_window(x1,y1,size_x,size_y,color); + break; + } + case DRAW_OUTPUT_BUFFER: + { + j=y; + for(i=0;i> 8; + g_f=color & 0xff; + color=color >> 8; + r_f=color & 0xff; + + color=color_to; + b_t=color & 0xff; + color=color >> 8; + g_t=color & 0xff; + color=color >> 8; + r_t=color & 0xff; + + div=sizey-1; + d_r=(float)(r_t-r_f); + d_r=d_r/div; + d_g=(float)(g_t-g_f); + d_g=d_g/div; + d_b=(float)(b_t-b_f); + d_b=d_b/div; + + f_r=r_f; + f_g=g_f; + f_b=b_f; + + r=r_f; + g=g_f; + b=b_f; + + if (flag_up==TRUE) + { + j=y+sizey-1; + dj=-1; + } + else + { + j=y; + dj=1; + } + + + for(i=0;i> 8; + g_f=color & 0xff; + color=color >> 8; + r_f=color & 0xff; + + color=color_to; + b_t=color & 0xff; + color=color >> 8; + g_t=color & 0xff; + color=color >> 8; + r_t=color & 0xff; + + div=sizex-1; + d_r=(float)(r_t-r_f); + d_r=d_r/div; + d_g=(float)(g_t-g_f); + d_g=d_g/div; + d_b=(float)(b_t-b_f); + d_b=d_b/div; + + f_r=r_f; + f_g=g_f; + f_b=b_f; + + r=r_f; + g=g_f; + b=b_f; + + if (flag_left==TRUE) + { + j=x; + dj=1; + } + else + { + j=x+sizex-1; + dj=-1; + } + + for(i=0;i=x) + { + DrawPixel(x+xc,y+yc,color); + DrawPixel(x+xc,-y+yc,color); + DrawPixel(-x+xc,y+yc,color); + DrawPixel(-x+xc,-y+yc,color); + DrawPixel(y+xc,x+yc,color); + DrawPixel(y+xc,-x+yc,color); + DrawPixel(-y+xc,x+yc,color); + DrawPixel(-y+xc,-x+yc,color); + if( d<0 ) + { + d = d+4*x+6; + } + else + { + d = d+4*(x-y)+10; + y--; + } + x++; + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing circle on screen with finition +//--------------------------------------------------------------------------------- +void DrawCircleFinit(struct FINITION *fin,int xc, int yc, int r,DWORD color) +{ + int x; + int y; + int d; + + x = 0; + y = r; + d = 3-2*r; + while(y>=x) + { + DrawPixelFinit(fin,x+xc,y+yc,color); + DrawPixelFinit(fin,x+xc,-y+yc,color); + DrawPixelFinit(fin,-x+xc,y+yc,color); + DrawPixelFinit(fin,-x+xc,-y+yc,color); + DrawPixelFinit(fin,y+xc,x+yc,color); + DrawPixelFinit(fin,y+xc,-x+yc,color); + DrawPixelFinit(fin,-y+xc,x+yc,color); + DrawPixelFinit(fin,-y+xc,-x+yc,color); + if( d<0 ) + { + d = d+4*x+6; + } + else + { + d = d+4*(x-y)+10; + y--; + } + x++; + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing filled circle on screen +//--------------------------------------------------------------------------------- +void DrawFilledCircle(int xc, int yc, int r,DWORD color) +{ + int xl,yu,xr,yd; + int i,j; + DWORD pixcolor; + + DrawCircle(xc,yc,r,color); + + yu=yc; + yd=yc; + for(i=0;ir) break; + } + j=0; + //fill right up + while((pixcolor=GetColorPixel(xr,yu))!=color) + { + DrawPixel(xr,yu,color); + xr++; + j++; + if (j>r) break; + } + + xl=xc; + xr=xc+1; + j=0; + //fill left down + while((pixcolor=GetColorPixel(xl,yd))!=color) + { + DrawPixel(xl,yd,color); + xl--; + j++; + if (j>r) break; + } + j=0; + //fill right down + while((pixcolor=GetColorPixel(xr,yd))!=color) + { + DrawPixel(xr,yd,color); + xr++; + j++; + if (j>r) break; + } + yu--; + yd++; + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing filled circle on screen with finition +//--------------------------------------------------------------------------------- +void DrawFilledCircleFinit(struct FINITION *fin,int xc, int yc, int r,DWORD color) +{ + int xl,yu,xr,yd; + int i,j; + DWORD pixcolor; + + DrawCircleFinit(fin,xc,yc,r,color); + + yu=yc; + yd=yc; + for(i=0;i=fin->x && xl<=fin->x+fin->sizex && + yu>=fin->y && yu<=fin->y+fin->sizey) + { + pixcolor=GetColorPixel(xl,yu); + if (pixcolor!=color) DrawPixel(xl,yu,color); + else break; + } + xl--; + } + //fill right up + for(j=0;j=fin->x && xr<=fin->x+fin->sizex && + yu>=fin->y && yu<=fin->y+fin->sizey) + { + pixcolor=GetColorPixel(xr,yu); + if (pixcolor!=color) DrawPixel(xr,yu,color); + else break; + } + xr++; + } + + xl=xc; + xr=xc+1; + //fill left down + for(j=0;j=fin->x && xl<=fin->x+fin->sizex && + yd>=fin->y && yd<=fin->y+fin->sizey) + { + pixcolor=GetColorPixel(xl,yd); + if (pixcolor!=color) DrawPixel(xl,yd,color); + else break; + } + xl--; + } + //fill right down + for(j=0;j=fin->x && xr<=fin->x+fin->sizex && + yd>=fin->y && yd<=fin->y+fin->sizey) + { + pixcolor=GetColorPixel(xr,yd); + if (pixcolor!=color) DrawPixel(xr,yd,color); + else break; + } + xr++; + } + yu--; + yd++; + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing ellipse on screen +//--------------------------------------------------------------------------------- +void DrawEllipse(int x,int y,int a,int b,DWORD color) +{ + int col,i,row,bnew; + long a_square,b_square,two_a_square,two_b_square,four_a_square,four_b_square,d; + + b_square=b*b; + a_square=a*a; + row=b; + col=0; + two_a_square=a_square<<1; + four_a_square=a_square<<2; + four_b_square=b_square<<2; + two_b_square=b_square<<1; + d=two_a_square*((row-1)*(row))+a_square+two_b_square*(1-a_square); + while(a_square*(row)>b_square*(col)) + { + DrawPixel(col+x,row+y,color); + DrawPixel(col+x,y-row,color); + DrawPixel(x-col,row+y,color); + DrawPixel(x-col,y-row,color); + + if (d>=0) + { + row--; + d-=four_a_square*(row); + } + d+=two_b_square*(3+(col<<1)); + col++; + } + + d=two_b_square*(col+1)*col+two_a_square*(row*(row-2)+1)+(1-two_a_square)*b_square; + while ((row) + 1) + { + DrawPixel(col+x, row+y, color); + DrawPixel(col+x, y-row, color); + DrawPixel(x-col, row+y, color); + DrawPixel(x-col, y-row, color); + + if (d<=0) + { + col++; + d+=four_b_square*col; + } + row--; + d+=two_a_square*(3-(row <<1)); + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing ellipse on screen with finition +//--------------------------------------------------------------------------------- +void DrawEllipseFinit(struct FINITION *fin,int x,int y,int a,int b,DWORD color) +{ + int col,i,row,bnew; + long a_square,b_square,two_a_square,two_b_square,four_a_square,four_b_square,d; + + b_square=b*b; + a_square=a*a; + row=b; + col=0; + two_a_square=a_square<<1; + four_a_square=a_square<<2; + four_b_square=b_square<<2; + two_b_square=b_square<<1; + d=two_a_square*((row-1)*(row))+a_square+two_b_square*(1-a_square); + + while(a_square*(row)>b_square*(col)) + { + DrawPixelFinit(fin,col+x,row+y,color); + DrawPixelFinit(fin,col+x,y-row,color); + DrawPixelFinit(fin,x-col,row+y,color); + DrawPixelFinit(fin,x-col,y-row,color); + + if (d>=0) + { + row--; + d-=four_a_square*(row); + } + d+=two_b_square*(3+(col<<1)); + col++; + } + + d=two_b_square*(col+1)*col+two_a_square*(row*(row-2)+1)+(1-two_a_square)*b_square; + while ((row) + 1) + { + DrawPixelFinit(fin,col+x, row+y, color); + DrawPixelFinit(fin,col+x, y-row, color); + DrawPixelFinit(fin,x-col, row+y, color); + DrawPixelFinit(fin,x-col, y-row, color); + + if (d<=0) + { + col++; + d+=four_b_square*col; + } + row--; + d+=two_a_square*(3-(row <<1)); + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing filled ellips on screen +//--------------------------------------------------------------------------------- +void DrawFilledEllipse(int xc, int yc, int a,int b,DWORD color) +{ + int xl,yu,xr,yd; + int i,j; + DWORD pixcolor; + + DrawEllipse(xc,yc,a,b,color); + + yu=yc; + yd=yc; + for(i=0;ia) break; + } + j=0; + //fill right up + while((pixcolor=GetColorPixel(xr,yu))!=color) + { + DrawPixel(xr,yu,color); + xr++; + j++; + if (j>a) break; + } + + xl=xc; + xr=xc+1; + j=0; + //fill left down + while((pixcolor=GetColorPixel(xl,yd))!=color) + { + DrawPixel(xl,yd,color); + xl--; + j++; + if (j>a) break; + } + j=0; + //fill right down + while((pixcolor=GetColorPixel(xr,yd))!=color) + { + DrawPixel(xr,yd,color); + xr++; + j++; + if (j>a) break; + } + yu--; + yd++; + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing filled circle on screen with finition +//--------------------------------------------------------------------------------- +void DrawFilledEllipseFinit(struct FINITION *fin,int xc, int yc, int a,int b,DWORD color) +{ + int xl,yu,xr,yd; + int i,j; + DWORD pixcolor; + + DrawEllipseFinit(fin,xc,yc,a,b,color); + + yu=yc; + yd=yc; + for(i=0;i=fin->x && xl<=fin->x+fin->sizex && + yu>=fin->y && yu<=fin->y+fin->sizey) + { + pixcolor=GetColorPixel(xl,yu); + if (pixcolor!=color) DrawPixel(xl,yu,color); + else break; + } + xl--; + } + //fill right up + for(j=0;j=fin->x && xr<=fin->x+fin->sizex && + yu>=fin->y && yu<=fin->y+fin->sizey) + { + pixcolor=GetColorPixel(xr,yu); + if (pixcolor!=color) DrawPixel(xr,yu,color); + else break; + } + xr++; + } + + xl=xc; + xr=xc+1; + //fill left down + for(j=0;j=fin->x && xl<=fin->x+fin->sizex && + yd>=fin->y && yd<=fin->y+fin->sizey) + { + pixcolor=GetColorPixel(xl,yd); + if (pixcolor!=color) DrawPixel(xl,yd,color); + else break; + } + xl--; + } + //fill right down + for(j=0;j=fin->x && xr<=fin->x+fin->sizex && + yd>=fin->y && yd<=fin->y+fin->sizey) + { + pixcolor=GetColorPixel(xr,yd); + if (pixcolor!=color) DrawPixel(xr,yd,color); + else break; + } + xr++; + } + yu--; + yd++; + } +} + +//--------------------------------------------------------------------------------- +// libGUI function drawing image on screen +//--------------------------------------------------------------------------------- +void DrawImage(int x,int y,int sizex,int sizey,char bits_per_pixel,char *img) +{ + char r,g,b; + int i,j,countx,county; + int x2,y2; + DWORD pitch_src,pitch_screen,add_src,add_screen; + char *ptr_src,*ptr_screen,ptr_max; + char *ptr_src2,*ptr_screen2; + DWORD *ptr_src3; + + if (img==NULL) return; + if (x>screen.size_x-1) return; + if (y>screen.size_y-1) return; + + x2=x+sizex-1; + y2=y+sizey-1; + + + if (y2>screen.size_y-1) {y2=screen.size_y-1;} + if (x2>screen.size_x-1) {x2=screen.size_x-1;} + if (y<0) y=0; + if (y2<0) y2=0; + if (x<0) x=0; + if (x2<0) x2=0; + + countx=x2-x+1; + county=y2-y+1; + + switch(screen.draw_output) + { + case DRAW_OUTPUT_SCREEN: + { + x+=screen.x; + y+=screen.y; + + switch(screen.bits_per_pixel) + { + case 32: + case 24: + { + switch(bits_per_pixel) + {//check bits per pixel in picture + case 32: + {//convert 32 bit image to 24 bit image + j=sizex*sizey; + ptr_src=img; + ptr_screen=malloc(j*3); + ptr_screen2=ptr_screen; + for(i=0;ix; + xmax=fin->x+fin->sizex-1; + ymin=fin->y; + ymax=fin->y+fin->sizey-1; + + x1=x; + y1=y; + x2=x1+sizex-1; + y2=y1+sizey-1; + + if (x2xmax) return; + if (y2ymax) return; + + if (x1>=xmin && x2<=xmax && y1>=ymin && y2<=ymax) + { + DrawImage(x,y,sizex,sizey,bits_per_pixel,img); + return; + } + + //finit x coordinates and sizex + sx=x1-xmin; + + if (sx>=0) + { + if (x2>xmax) x2=xmax; + } + else + { + x1=xmin; + if (x2>xmax) x2=xmax; + } + + //finit y coordinates and sizey + sy=y1-ymin; + + if (sy>=0) + { + if (y2>ymax) y2=ymax; + } + else + { + y1=ymin; + if (y2>ymax) y2=ymax; + } + countx=x2-x1+1; + county=y2-y1+1; + + //cut finited rectangle from image and move them into buffer + + bytes_per_pixel=bits_per_pixel >> 3; + buf=malloc(countx*county*bytes_per_pixel); + ptr_dest=buf; + + pitch_src=sizex*bytes_per_pixel; + ptr_src=img+pitch_src*(y1-y)+(x1-x)*bytes_per_pixel; + add_src=sizex*bytes_per_pixel; + countline=countx*bytes_per_pixel; + + switch(bits_per_pixel) + { + case 32: + case 24: + case 16: + case 8: + { + for(i=0;ix; + xmax=finition->x+finition->sizex-1; + ymin=finition->y; + ymax=finition->y+finition->sizey-1; + + switch(tool_name) + { + //tool Pixel + case TOOL_PIXEL: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + if (x>=finition->x && x<=finition->x+finition->sizex + && y>=finition->y && y<=finition->y+finition->sizey) + { //pixel inside finition arrea + DrawPixel(x,y,color); + } + } + else + { //no finition + DrawPixel(x,y,color); + } + break; + } + //tool Line + case TOOL_LINE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + x2=va_arg(arguments,int); + y2=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + sizex=abs(x2-x); + sizey=abs(y2-y); + + if (CheckCrossRectangles(finition->x,finition->y,finition->sizex, + finition->sizey,x,y,sizex,sizey)==FALSE) break; + + if (x>=finition->x && x<=finition->x+finition->sizex && + y>=finition->y && y<=finition->y+finition->sizey && + x2>=finition->x && x2<=finition->x+finition->sizex && + y2>=finition->y && y2<=finition->y+finition->sizey) + { + //line inside finition arrea + DrawLine(x,y,x2,y2,color); + break; + } + + + if (x==x2) break; + + //find coefficients of line + x_l1=x; + y_l1=y; + x_l2=x2; + y_l2=y2; + k=(y_l1-y_l2)/(x_l1-x_l2); + b=(y_l2*x_l1-y_l1*x_l2)/(x_l1-x_l2); + + sx=x2-x;//vectore x + sy=y2-y;//vectore y + + if (x>=finition->x && x<=finition->x+finition->sizex && + y>=finition->y && y<=finition->y+finition->sizey) + { //point x,y inside finition arrea + //check cross with left vertical line of finition + y_l1=k*finition->x+b; + y_i=(int)y_l1; + if (y_i>=finition->y && y_i<=finition->y+finition->sizey && sx<0) + { //first point for finited line + x2=finition->x; + y2=y_i; + DrawLine(x,y,x2,y2,color); + break; + } + //check cross with up horizontal line of finition + x_l1=(finition->y-b)/k; + x_i=(int)x_l1; + if (x_i>=finition->x && x_i<=finition->x+finition->sizex && sy<0) + { + x2=x_i; + y2=finition->y; + DrawLine(x,y,x2,y2,color); + break; + } + //check cross with right vertical line of finition + y_l1=k*(finition->x+finition->sizex)+b; + y_i=(int)y_l1; + if (y_i>=finition->y && y_i<=finition->y+finition->sizey && sx>0) + { + x2=finition->x+finition->sizex; + y2=y_i; + DrawLine(x,y,x2,y2,color); + break; + } + //check cross with down horizontal line of finition + x_l1=((finition->y+finition->sizey)-b)/k; + x_i=(int)x_l1; + if (x_i>=finition->x && x_i<=finition->x+finition->sizex && sy>0) + { + x2=x_i; + y2=finition->y+finition->sizey; + DrawLine(x,y,x2,y2,color); + break; + } + } + + if (x2>=finition->x && x2<=finition->x+finition->sizex && + y2>=finition->y && y2<=finition->y+finition->sizey) + { //point x,y inside finition arrea + //check cross with left vertical line of finition + y_l1=k*finition->x+b; + y_i=(int)y_l1; + if (y_i>=finition->y && y_i<=finition->y+finition->sizey && sx>0) + { //first point for finited line + x=finition->x; + y=y_i; + DrawLine(x,y,x2,y2,color); + break; + } + //check cross with up horizontal line of finition + x_l1=(finition->y-b)/k; + x_i=(int)x_l1; + if (x_i>=finition->x && x_i<=finition->x+finition->sizex && sy>0) + { + x=x_i; + y=finition->y; + DrawLine(x,y,x2,y2,color); + break; + } + //check cross with right vertical line of finition + y_l1=k*(finition->x+finition->sizex)+b; + y_i=(int)y_l1; + if (y_i>=finition->y && y_i<=finition->y+finition->sizey && sx<0) + { + x=finition->x+finition->sizex; + y=y_i; + DrawLine(x,y,x2,y2,color); + break; + } + //check cross with down horizontal line of finition + x_l1=((finition->y+finition->sizey)-b)/k; + x_i=(int)x_l1; + if (x_i>=finition->x && x_i<=finition->x+finition->sizex && sy<0) + { + x=x_i; + y=finition->y+finition->sizey; + DrawLine(x,y,x2,y2,color); + break; + } + } + + first=FALSE; + second=FALSE; + //check cross with left vertical line of finition + y_l1=k*finition->x+b; + y_i=(int)y_l1; + if (y_i>=finition->y && y_i<=finition->y+finition->sizey) + { //first point for finited line + x=finition->x; + y=y_i; + first=TRUE; + } + //check cross with up horizontal line of finition + x_l1=(finition->y-b)/k; + x_i=(int)x_l1; + if (x_i>=finition->x && x_i<=finition->x+finition->sizex) + { + if (first==FALSE) + { + x=x_i; + y=finition->y; + } + else + { + x2=x_i; + y2=finition->y; + second=TRUE; + } + } + //check cross with right vertical line of finition + y_l1=k*(finition->x+finition->sizex)+b; + y_i=(int)y_l1; + if (y_i>=finition->y && y_i<=finition->y+finition->sizey) + { + if (first==FALSE) + { + x=finition->x+finition->sizex; + y=y_i; + } + else + { + x2=finition->x+finition->sizex; + y2=y_i; + second=TRUE; + } + } + //check cross with down horizontal line of finition + x_l1=((finition->y+finition->sizey)-b)/k; + x_i=(int)x_l1; + if (x_i>=finition->x && x_i<=finition->x+finition->sizex) + { + if (first==FALSE) + { + x=x_i; + y=finition->y+finition->sizey; + } + else + { + x2=x_i; + y2=finition->y+finition->sizey; + second=TRUE; + } + } + + if (first==TRUE && second==TRUE) + { + //draw finited line + DrawLine(x,y,x2,y2,color); + } + break; + + } + else + { //no finition + DrawLine(x,y,x2,y2,color); + } + break; + } + //tool VerticalLine + case TOOL_VERTICAL_LINE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + y2=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + DrawVerticalLineFinit(finition,x,y,y2,color); + } + else + { + DrawVerticalLine(x,y,y2,color); + } + break; + } + //tool HorizontalLine + case TOOL_HORIZONTAL_LINE: + { + x=va_arg(arguments,int); + x2=va_arg(arguments,int); + y=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + DrawHorizontalLineFinit(finition,x,x2,y,color); + } + else + { + DrawHorizontalLine(x,x2,y,color); + } + break; + } + + //tool Rectangle + case TOOL_RECTANGLE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + sizex=va_arg(arguments,int); + sizey=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + x2=x+sizex-1; + y2=y+sizey-1; + + if (x2xmax) return; + if (y2ymax) return; + + DrawRectangleFinit(finition,x,y,sizex,sizey,color); + } + else + { + DrawRectangle(x,y,sizex,sizey,color); + } + break; + } + //tool FilledRectangle + case TOOL_FILLED_RECTANGLE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + sizex=va_arg(arguments,int); + sizey=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + x2=x+sizex-1; + y2=y+sizey-1; + + if (x2xmax) return; + if (y2ymax) return; + + //finit x coordinates and sizex + sx=x-xmin; + + if (sx>=0) + { + if (x2>xmax) x2=xmax; + } + else + { + x=xmin; + if (x2>xmax) x2=xmax; + } + + //finit y coordinates and sizey + sy=y-ymin; + + if (sy>=0) + { + if (y2>ymax) y2=ymax; + } + else + { + y=ymin; + if (y2>ymax) y2=ymax; + } + + sizex=x2-x+1; + sizey=y2-y+1; + + DrawFilledRectangle(x,y,sizex,sizey,color); + } + else + { + DrawFilledRectangle(x,y,sizex,sizey,color); + } + break; + } + //tool GradientUpFilledRectangle + case TOOL_GRADIENT_UP_FILLED_RECTANGLE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + sizex=va_arg(arguments,int); + sizey=va_arg(arguments,int); + color_from=va_arg(arguments,DWORD); + color_to=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + x2=x+sizex-1; + y2=y+sizey-1; + + if (x2xmax) return; + if (y2ymax) return; + + //finit x coordinates and sizex + sx=x-xmin; + + if (sx>=0) + { + if (x2>xmax) x2=xmax; + } + else + { + x=xmin; + if (x2>xmax) x2=xmax; + } + + //finit y coordinates and sizey + sy=y-ymin; + + if (sy>=0) + { + if (y2>ymax) y2=ymax; + } + else + { + y=ymin; + if (y2>ymax) y2=ymax; + } + + sizex=x2-x+1; + sizey=y2-y+1; + + DrawGradientUpDownFilledRectangle(TRUE,x,y,sizex,sizey,color_from,color_to); + } + else + { + DrawGradientUpDownFilledRectangle(TRUE,x,y,sizex,sizey,color_from,color_to); + } + break; + } + //tool GradientDownFilledRectangle + case TOOL_GRADIENT_DOWN_FILLED_RECTANGLE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + sizex=va_arg(arguments,int); + sizey=va_arg(arguments,int); + color_from=va_arg(arguments,DWORD); + color_to=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + x2=x+sizex-1; + y2=y+sizey-1; + + if (x2xmax) return; + if (y2ymax) return; + + //finit x coordinates and sizex + sx=x-xmin; + + if (sx>=0) + { + if (x2>xmax) x2=xmax; + } + else + { + x=xmin; + if (x2>xmax) x2=xmax; + } + + //finit y coordinates and sizey + sy=y-ymin; + + if (sy>=0) + { + if (y2>ymax) y2=ymax; + } + else + { + y=ymin; + if (y2>ymax) y2=ymax; + } + + sizex=x2-x+1; + sizey=y2-y+1; + + DrawGradientUpDownFilledRectangle(FALSE,x,y,sizex,sizey,color_from,color_to); + } + else + { + DrawGradientUpDownFilledRectangle(FALSE,x,y,sizex,sizey,color_from,color_to); + } + break; + } + //tool GradientLeftFilledRectangle + case TOOL_GRADIENT_LEFT_FILLED_RECTANGLE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + sizex=va_arg(arguments,int); + sizey=va_arg(arguments,int); + color_from=va_arg(arguments,DWORD); + color_to=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + x2=x+sizex-1; + y2=y+sizey-1; + + if (x2xmax) return; + if (y2ymax) return; + + //finit x coordinates and sizex + sx=x-xmin; + + if (sx>=0) + { + if (x2>xmax) x2=xmax; + } + else + { + x=xmin; + if (x2>xmax) x2=xmax; + } + + //finit y coordinates and sizey + sy=y-ymin; + + if (sy>=0) + { + if (y2>ymax) y2=ymax; + } + else + { + y=ymin; + if (y2>ymax) y2=ymax; + } + + sizex=x2-x+1; + sizey=y2-y+1; + + DrawGradientLeftRightFilledRectangle(TRUE,x,y,sizex,sizey,color_from,color_to); + } + else + { + DrawGradientLeftRightFilledRectangle(TRUE,x,y,sizex,sizey,color_from,color_to); + } + break; + } + //tool GradientRightFilledRectangle + case TOOL_GRADIENT_RIGHT_FILLED_RECTANGLE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + sizex=va_arg(arguments,int); + sizey=va_arg(arguments,int); + color_from=va_arg(arguments,DWORD); + color_to=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + x2=x+sizex-1; + y2=y+sizey-1; + + if (x2xmax) return; + if (y2ymax) return; + + //finit x coordinates and sizex + sx=x-xmin; + + if (sx>=0) + { + if (x2>xmax) x2=xmax; + } + else + { + x=xmin; + if (x2>xmax) x2=xmax; + } + + //finit y coordinates and sizey + sy=y-ymin; + + if (sy>=0) + { + if (y2>ymax) y2=ymax; + } + else + { + y=ymin; + if (y2>ymax) y2=ymax; + } + + sizex=x2-x+1; + sizey=y2-y+1; + + DrawGradientLeftRightFilledRectangle(FALSE,x,y,sizex,sizey,color_from,color_to); + } + else + { + DrawGradientLeftRightFilledRectangle(FALSE,x,y,sizex,sizey,color_from,color_to); + } + break; + } + //tool Circle + case TOOL_CIRCLE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + radius=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + DrawCircleFinit(finition,x,y,radius,color); + } + else + { + DrawCircle(x,y,radius,color); + } + break; + } + //tool FilledCircle + case TOOL_FILLED_CIRCLE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + radius=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + DrawFilledCircleFinit(finition,x,y,radius,color); + } + else + { + DrawFilledCircle(x,y,radius,color); + } + break; + } + //tool Ellipse + case TOOL_ELLIPSE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + sizex=va_arg(arguments,int); + sizey=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + DrawEllipseFinit(finition,x,y,sizex,sizey,color); + } + else + { + DrawEllipse(x,y,sizex,sizey,color); + } + break; + } + //tool FilledEllipse + case TOOL_FILLED_ELLIPSE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + sizex=va_arg(arguments,int); + sizey=va_arg(arguments,int); + color=va_arg(arguments,DWORD); + + if (finition->flags & FINITION_ON) + { + DrawFilledEllipseFinit(finition,x,y,sizex,sizey,color); + } + else + { + DrawFilledEllipse(x,y,sizex,sizey,color); + } + break; + } + //tool Image + case TOOL_IMAGE: + { + x=va_arg(arguments,int); + y=va_arg(arguments,int); + sizex=va_arg(arguments,int); + sizey=va_arg(arguments,int); + bits_per_pixel=(char)va_arg(arguments,int); + img=va_arg(arguments,char*); + + if (finition->flags & FINITION_ON) + { + DrawImageFinit(finition,x,y,sizex,sizey,bits_per_pixel,img); + } + else + { + DrawImage(x,y,sizex,sizey,bits_per_pixel,img); + } + break; + } + } + va_end(arguments); +} + + diff --git a/programs/develop/libraries/libGUI/SRC/fonts_meneger.h b/programs/develop/libraries/libGUI/SRC/fonts_meneger.h new file mode 100644 index 0000000000..d2fc3ad650 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/fonts_meneger.h @@ -0,0 +1,63 @@ +/* + font meneger header structure + */ + +#define FONT_FLAG_DEFAULT_FONT_ON 0x1 +#define FONT_FLAG_DEFAULT_FONT_OFF 0xfe +#define FONT_FLAG_DRAW_BACKGROUND_ON 0x2 +#define FONT_FLAG_DRAW_BACKGROUND_OFF 0xfd +#define FONT_FLAG_ORIENTATION_HORIZONTAL_FROM_LEFT_TO_RIGHT_ON 0x4 +#define FONT_FLAG_ORIENTATION_HORIZONTAL_FROM_LEFT_TO_RIGHT_OFF 0xfb + +#define FONT_CONSTANT_SIZE -1 + +//some types encoding characters +#define FONT_TYPE_ASCII 0x1 +#define FONT_TYPE_UNICODE 0x2 + +/////////////////////////////////////////////////////////// +// some ASCII encodings +/////////////////////////////////////////////////////////// + +//cyrillic encodings +#define FONT_ENCODING_CYRILLIC_IBM866 0x1 +#define FONT_ENCODING_CYRILLIC_IBM437 0x2 +#define FONT_ENCODING_CYRILLIC_KOI8R 0x4 +#define FONT_ENCODING_CYRILLIC_ISO8859_5 0x8 +#define FONT_ENCODING_CYRILLIC_CP1251 0x10 + +#pragma pack(push,1) +static struct +{ + DWORD *fnt_fd; + DWORD *fnt_bk; + DWORD *default_font; + DWORD number_fonts; +}FontsMeneger; +#pragma pack(pop) + +#pragma pack(push,1) +struct FONT +{ + DWORD *fnt_draw; + DWORD *fnt_unpacker; + DWORD *fnt_fd; + DWORD *fnt_bk; + int sizex; + int sizey; + int size; + int encoding_type; + char *font; + char *fnt_name; + DWORD type; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct FONT font_t; + +static char *default_fonts_path="/sys/fonts/"; + +void (*DrawFont)(finition_t *fin,int fx,int fy,DWORD color,DWORD background_color,font_t *font,BYTE *s); + + diff --git a/programs/develop/libraries/libGUI/SRC/fonts_meneger.inc b/programs/develop/libraries/libGUI/SRC/fonts_meneger.inc new file mode 100644 index 0000000000..b16b2a0234 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/fonts_meneger.inc @@ -0,0 +1,373 @@ +/* + menegement of fonts + */ + +//--------------------------------------------------------------------------------- +// destroy font +//--------------------------------------------------------------------------------- +void DestroyFont(font_t *font) +{ + font_t *seek_font; + font_t *exchange_font; + font_t *last_font; + font_t *next_font; + + if (font==(font_t*)NULL) return; + + if (FontsMeneger.fnt_bk==FontsMeneger.fnt_fd) + { + //parent have got alone font + if (FontsMeneger.fnt_bk==(DWORD*)font) + { +#ifdef DEBUG + printf("\ndestroyed font %d font name=%s",(int)font,(char*)font->fnt_name); +#endif + free(font); + FontsMeneger.fnt_bk=(DWORD*)NULL; + FontsMeneger.fnt_fd=(DWORD*)NULL; + } + return; + } + + seek_font=(font_t*)FontsMeneger.fnt_bk; + while(seek_font!=(font_t*)NULL) + { + if (seek_font==font) + { + //delete font from fonts's cash + last_font=(font_t*)seek_font->fnt_bk; + next_font=(font_t*)seek_font->fnt_fd; + + if ((last_font!=(font_t*)NULL) && (next_font!=(font_t*)NULL)) + {//deliting font isn't first font and isn't endest + next_font->fnt_bk=(DWORD*)last_font; + last_font->fnt_fd=(DWORD*)next_font; + } + else + { + if (last_font==(font_t*)NULL) + {//deliting font is first font of Parend + FontsMeneger.fnt_bk=(DWORD*)next_font; + next_font->fnt_bk=(DWORD*)NULL; + if (next_font->fnt_fd==(DWORD*)NULL) + { + FontsMeneger.fnt_fd=(DWORD*)next_font; + FontsMeneger.fnt_bk=(DWORD*)next_font; + } + } + + if (next_font==(font_t*)NULL) + { + //there isn't next fonts + last_font->fnt_fd=(DWORD*)NULL; + FontsMeneger.fnt_fd=(DWORD*)last_font; + } + } +#ifdef DEBUG + printf("\ndestroyed font %d font name=%s",(int)font,(char*)font->fnt_name); +#endif + free(font); + break; + } + exchange_font=(font_t*)seek_font->fnt_fd; + seek_font=exchange_font; + } +} + +void *CreateFont(void) +{ + font_t *font; + font_t *backward_font; + + font=malloc(sizeof(struct FONT)); + + if (FontsMeneger.fnt_bk==(DWORD*)NULL) + {//not yet fonts + FontsMeneger.fnt_bk=(DWORD*)font; + FontsMeneger.fnt_fd=(DWORD*)font; + font->fnt_bk=(DWORD*)NULL; + font->fnt_fd=(DWORD*)NULL; + } + else + { + backward_font=(font_t*)FontsMeneger.fnt_fd; + FontsMeneger.fnt_fd=(DWORD*)font; + backward_font->fnt_fd=(DWORD*)font; + font->fnt_bk=(DWORD*)backward_font; + font->fnt_fd=(DWORD*)NULL; + } + return(font); +} +//////////////////////////////////////////////////////////////////////////////// +// CHAR.MT and CHAR2.MT fonts unpacker +//////////////////////////////////////////////////////////////////////////////// +void CHAR_MT_FontsUnpacker(unsigned char *loaded_font,font_t *font,char font_type) +{ + int i,j,k; + unsigned char c; + unsigned char *p; + + if (font_type==FALSE) + {//CHAR.MT + font->font=malloc(6*9*256); + p=(unsigned char*)font->font; + + for(j=0;j<256;j++) + { + for(i=0;i<9;i++) + { + c=(unsigned char)(*loaded_font); + p[5]=(unsigned char)(c & 0x20); + p[4]=(unsigned char)(c & 0x10); + p[3]=(unsigned char)(c & 0x8); + p[2]=(unsigned char)(c & 0x4); + p[1]=(unsigned char)(c & 0x2); + p[0]=(unsigned char)(c & 0x1); + + p+=6; + loaded_font++; + } + } + font->sizex=6; + font->sizey=9; + } + else + {//CHAR2.MT + font->font=malloc(8*10*256); + p=(unsigned char*)font->font; + + for(j=0;j<256;j++) + { + for(i=0;i<10;i++) + { + c=(unsigned char)(*loaded_font); + p[7]=(unsigned char)(c & 0x80); + p[6]=(unsigned char)(c & 0x40); + p[5]=(unsigned char)(c & 0x20); + p[4]=(unsigned char)(c & 0x10); + p[3]=(unsigned char)(c & 0x8); + p[2]=(unsigned char)(c & 0x4); + p[1]=(unsigned char)(c & 0x2); + p[0]=(unsigned char)(c & 0x1); + + p+=8; + loaded_font++; + } + } + font->sizex=8; + font->sizey=10; + } + + font->size=FONT_CONSTANT_SIZE; + font->type=FONT_TYPE_ASCII; + font->encoding_type=FONT_ENCODING_CYRILLIC_IBM866; +} + +//////////////////////////////////////////////////////////////////////////////// +// CHAR.MT and CHAR2.MT fonts draw +//////////////////////////////////////////////////////////////////////////////// +void MonofontDraw(finition_t *fin,int fx,int fy, + DWORD color,DWORD background_color, + font_t *font,unsigned char *s) +{ + unsigned int i,j,k,step,len; + int x,y,size_x,save_size_x,save_size_y; + unsigned char *p,*buf,*save_buf; + unsigned char c; + DWORD draw_output; + + step=font->sizex*font->sizey; + len=strlen(s); + + if (font->flags & FONT_FLAG_ORIENTATION_HORIZONTAL_FROM_LEFT_TO_RIGHT_ON) + { + if (font->flags & FONT_FLAG_DRAW_BACKGROUND_ON) + {//there is a fon and not finition for draw + //alocate a buffer for draw text + size_x=font->sizex*len; + + c=screen.bits_per_pixel >> 3; + i=step*c*len; + buf=malloc(i); + + //save current screen parameters + save_buf=screen.buffer; + save_size_x=screen.size_x; + save_size_y=screen.size_y; + draw_output=screen.draw_output; + + //load parameters of local buffer + screen.buffer=buf; + screen.size_x=size_x; + screen.size_y=font->sizey; + screen.draw_output=DRAW_OUTPUT_BUFFER; + + //fill buffer by background color + FillArrea(buf,i,screen.bits_per_pixel,background_color); + + //draw text + x=0; + for(k=0;kfont+step*c; + for(j=0;jsizey;j++) + { + + for(i=0;isizex;i++) + { + if (*p) DrawPixel(x+i,j,color); + p++; + } + } + x=x+font->sizex; + } + + //restore screen parameters + screen.buffer=save_buf; + screen.size_x=save_size_x; + screen.size_y=save_size_y; + screen.draw_output=draw_output; + + //move text from local buffer to screen + if (fin->flags & FINITION_ON) + DrawImageFinit(fin,fx,fy,size_x,font->sizey,screen.bits_per_pixel,buf); + else + DrawImage(fx,fy,size_x,font->sizey,screen.bits_per_pixel,buf); + + //free local buffer + free(buf); + } + else + { + if (fin->flags & FINITION_ON) + {//not background and finition for draw + x=fx; + y=fy; + for(k=0;kfont+step*c; + for(j=0;jsizey;j++) + { + + for(i=0;isizex;i++) + { + if (*p) DrawPixelFinit(fin,x+i,y+j,color); + p++; + } + } + x=x+font->sizex; + } + } + else + {//not background and not finition for draw + x=fx; + y=fy; + for(k=0;kfont+step*c; + for(j=0;jsizey;j++) + { + + for(i=0;isizex;i++) + { + if (*p) DrawPixel(x+i,y+j,color); + p++; + } + } + x=x+font->sizex; + } + } + + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// fonts loader +//////////////////////////////////////////////////////////////////////////////// +font_t *LoadFont(char *fullfontname) +{ + char *path; + char *c; + BYTE *buf; + long filesize; + int len1,len2,i; + font_t *font; + static DWORD buf_for_size[2]; + static DWORD buf_for_pos[2]; + + path=malloc(263); + if (strchr(fullfontname,'/')==NULL) + { + len1=strlen(default_fonts_path); + len2=strlen(fullfontname); + memmove(path,default_fonts_path,len1); + memmove(path+len1,fullfontname,len2); + *(path+len1+len2)='\0'; + } + else + memmove(path,fullfontname,strlen(fullfontname)); + + if (gui_get_file_size(path,buf_for_size)==KOLIBRIOS_SYS_FILE_ACCESS_SUCCESSFULLY) + { + filesize=buf_for_size[0]; + buf=malloc(filesize); + //load fonts in buffer + gui_read_file(path,buf_for_pos,filesize,buf); + + free(path); + //register font + font=CreateFont(); + c=strrchr(fullfontname,'/'); + if(c==NULL) font->fnt_name=fullfontname; + else + font->fnt_name=(char*)(c+1); + + //check font type + c=strstr(font->fnt_name,"CHAR.MT");//check standart type of fonts + if (c!=NULL) + { + font->fnt_unpacker=(DWORD*)&CHAR_MT_FontsUnpacker; + font->fnt_draw=(DWORD*)&MonofontDraw; + CHAR_MT_FontsUnpacker(buf,font,FALSE);//CHAR.MT + free(buf); + font->flags=0; + font->flags|=FONT_FLAG_ORIENTATION_HORIZONTAL_FROM_LEFT_TO_RIGHT_ON; + } + + c=strstr(font->fnt_name,"CHAR2.MT");//check standart type of fonts + if (c!=NULL) + { + font->fnt_unpacker=(DWORD*)&CHAR_MT_FontsUnpacker; + font->fnt_draw=(DWORD*)&MonofontDraw; + CHAR_MT_FontsUnpacker(buf,font,TRUE);//CHAR2.MT + free(buf); + font->flags=0; + font->flags|=FONT_FLAG_ORIENTATION_HORIZONTAL_FROM_LEFT_TO_RIGHT_ON; + } + //not other fonts yet + + } + else + { +#ifdef DEBUG + printf("\ncannot load font %s",path); +#endif + free(path); + return(NULL); + } + + FontsMeneger.number_fonts++; + return(font); +} + +void FreeFont(font_t *font) +{ + if (font==(font_t*)FontsMeneger.default_font) return; + + free(font->font); + DestroyFont(font); +} diff --git a/programs/develop/libraries/libGUI/SRC/keys.h b/programs/develop/libraries/libGUI/SRC/keys.h new file mode 100644 index 0000000000..75136e256c --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/keys.h @@ -0,0 +1,8 @@ +/* + scan codes of keys +*/ + +//Scan Codes of some keys in pressed state + #define SC_TAB 15 + #define SC_ENTER 28 + #define SC_SPACE 57 diff --git a/programs/develop/libraries/libGUI/SRC/kolibri_system.h b/programs/develop/libraries/libGUI/SRC/kolibri_system.h new file mode 100644 index 0000000000..84d3e31613 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/kolibri_system.h @@ -0,0 +1,657 @@ +/* + some system function of KolibriOS +*/ + +#define KOLIBRIOS_SYS_EVENT_REDRAW 1 +#define KOLIBRIOS_SYS_EVENT_KEYS 2 +#define KOLIBRIOS_SYS_EVENT_BUTTON_PRESSED 3 +#define KOLIBRIOS_SYS_EVENT_REDRAW_BACKGROUND 5 +#define KOLIBRIOS_SYS_EVENT_MOUSE 6 +#define KOLIBRIOS_SYS_EVENT_IPC 7 +#define KOLIBRIOS_SYS_EVENT_NET 8 +#define KOLIBRIOS_SYS_EVENT_DEBUG 9 + +#define KOLIBRIOS_SYS_MOUSE_BUTTON_LEFT_DOWN 0x1 +#define KOLIBRIOS_SYS_MOUSE_BUTTON_RIGHT_DOWN (0x1<<1) +#define KOLIBRIOS_SYS_MOUSE_BUTTON_MIDDLE_DOWN (0x1 <<2) +#define KOLIBRIOS_SYS_MOUSE_BUTTON_4_DOWN (0x1 <<3) +#define KOLIBRIOS_SYS_MOUSE_BUTTON_5_DOWN (0x1 <<4) + +#define KOLIBRIOS_SYS_FILE_ACCESS_SUCCESSFULLY 0 +#define KOLIBRIOS_SYS_FILE_UNDEFINED_PARTITION_OR_HARDDRIVE_BASE 1 +#define KOLIBRIOS_SYS_FILE_FUNCTION_DONT_SUPPOROTE_FOR_CURRENT_FILE_SYSTEM 2 +#define KOLIBRIOS_SYS_FILE_UNKNOWN_FILE_SYSTEM 3 +#define KOLIBRIOS_SYS_FILE_NOT_FOUND 5 +#define KOLIBRIOS_SYS_FILE_FINISHED 6 +#define KOLIBRIOS_SYS_FILE_POINTER_OUTOFMEMORY_APPLICATION 7 +#define KOLIBRIOS_SYS_FILE_MEMORY_OF_DEVICE_FILLED 8 +#define KOLIBRIOS_SYS_FILE_TABLE_DESTROYED 9 +#define KOLIBRIOS_SYS_FILE_ACCESS_DENITED 10 +#define KOLIBRIOS_SYS_FILE_DEVICE_ERROR 11 + +#pragma pack(push,1) +struct KOLIBRIOS_FILEIO +{ + DWORD number_subfunction; + DWORD offset_in_file_low; + DWORD offset_in_file_hight; + DWORD size; + DWORD *data; + BYTE null; + char *full_file_path; +}; +#pragma pack(pop) + +typedef struct KOLIBRIOS_FILEIO fileio_t; + +#pragma pack(push,1) +struct BLOCK_DATA_ENTRY_DIRECTORY +{ + DWORD attributes; + DWORD types_data_of_name; + DWORD time_created_file; + DWORD date_created_file; + DWORD time_last_access; + DWORD date_last_access; + DWORD time_last_modification; + DWORD date_last_modification; + DWORD file_size_low; + DWORD file_size_hight; + DWORD *filename; +}; +#pragma pack(pop) + +typedef struct BLOCK_DATA_ENTRY_DIRECTORY bded_t; + +#pragma pack(push,1) +struct PROCESS_TABLE +{ + int cpu_usage; //+0 + int window_pos_info; //+4 + short int reserved1; //+8 + char name[12]; //+10 + int memstart; //+22 + int memused; //+26 + int pid; //+30 + int winx_start; //+34 + int winy_start; //+38 + int winx_size; //+42 + int winy_size; //+46 + short int slot_info; //+50 + short int reserved2; //+52 + int clientx; //+54 + int clienty; //+58 + int clientwidth; //+62 + int clientheight; //+66 + unsigned char window_state; //+70 + char reserved3[1024-71]; //+71 +}; +#pragma pack(pop) + +typedef struct PROCESS_TABLE process_table_t; + +#pragma pack(push,1) +struct IMPORT +{ + char *name; + void *data; +}; +#pragma pack(pop) + +typedef struct IMPORT import_t; + +static DWORD gui_get_file_size(char *filename,DWORD *buf_for_size); +static DWORD gui_read_file(char *filename,DWORD *buf_pos_size,DWORD size_read,char *buf); +static DWORD gui_create_rewrite_file(char *filename,DWORD *buf_pos_size,DWORD size_write,char *buf); +static DWORD gui_append_to_file(char *filename,DWORD *buf_pos_size,DWORD size_write,char *buf); +static void gui_debug_out_str(char *s); +static void* gui_cofflib_getproc(import_t *lib, char *name); + +#define alwinline __attribute__((always_inline)) +//------------------------------------------------------------------------------------------ +// draw window +//------------------------------------------------------------------------------------------ +extern inline void __attribute__((always_inline)) gui_ksys_draw_window(DWORD x,DWORD y,DWORD sizex,DWORD sizey,DWORD flags) +{ + __asm__ __volatile__( + "xorl %%eax,%%eax\n\t" + "movl %0,%%ebx\n\t" + "movl %1,%%ecx\n\t" + "movl %4,%%edx\n\t" + "shll $16,%%ebx\n\t" + "shll $16,%%ecx\n\t" + "addl %2,%%ebx\n\t" + "addl %3,%%ecx\n\t" + "int $0x40" + :/*no output*/ + :"g"(x),"g"(y),"g"(sizex),"g"(sizey),"g"(flags) + :"eax","ebx","ecx","edx"); +} + +//------------------------------------------------------------------------------------------ +// begin redraw window +//------------------------------------------------------------------------------------------ +extern inline void __attribute__((always_inline)) gui_ksys_begin_draw_window(void) +{ + __asm__ __volatile__( + "int $0x40" + :/*no output*/ + :"a"(12),"b"(1)); +} + +//------------------------------------------------------------------------------------------ +// finish redraw window +//------------------------------------------------------------------------------------------ +extern inline void __attribute__((always_inline)) gui_ksys_finish_draw_window(void) +{ + __asm__ __volatile__( + "int $0x40" + :/*no output*/ + :"a"(12),"b"(2)); +} + +//------------------------------------------------------------------------------------------ +// set new position and new size of window +//------------------------------------------------------------------------------------------ +extern inline void alwinline gui_ksys_set_position_and_size_window(DWORD new_x, + DWORD new_y,DWORD new_sizex,DWORD new_sizey) +{ + __asm__ __volatile__( + "int $0x40" + :/*no output*/ + :"a"(67),"b"(new_x),"c"(new_y),"d"(new_sizex),"S"(new_sizey)); +} + +//------------------------------------------------------------------------------------------ +// set title of window +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_set_title_window(char *title) +{ + __asm__ __volatile__( + "int $0x40" + :/*no output*/ + :"a"(71),"b"(1),"c"(title)); +} + +//------------------------------------------------------------------------------------------ +// delete title of window +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_delete_title_window(void) +{ + __asm__ __volatile__( + "int $0x40" + :/*no output*/ + :"a"(71),"b"(1),"c"(0)); +} + +//------------------------------------------------------------------------------------------ +// get information about current process +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_get_current_process_information(void *mem) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(9),"b"(mem),"c"(-1)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// delete title of window +//------------------------------------------------------------------------------------------ +extern inline int __attribute__((always_inline)) gui_ksys_get_skin_height(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(48),"b"(4)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// get pressed key +//------------------------------------------------------------------------------------------ +extern inline int __attribute__((always_inline)) gui_ksys_get_key(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(2)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// set keyboard input mode +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_set_keyboard_input_mode(int mode) +{ + __asm__ __volatile__( + "int $0x40" + :/*no output*/ + :"a"(66),"b"(1),"c"(mode)); + +} + +//------------------------------------------------------------------------------------------ +// get keyboard input mode +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_get_keyboard_input_mode(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(66),"b"(2)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// get state of menegers keys +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_get_state_menegers_keys(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(66),"b"(3)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// set events mask +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_set_events_mask(DWORD mask) +{ + __asm__ __volatile__( + "int $0x40" + :/*no output*/ + :"a"(40),"b"(mask)); +} + +//------------------------------------------------------------------------------------------ +// wait event +//------------------------------------------------------------------------------------------ +extern inline int __attribute__((always_inline)) gui_ksys_wait_event(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(10)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// check for event +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_check_event(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(11)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// wait event while not timeout +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_wait_event_with_timeout(DWORD timeout) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(23),"b"(timeout)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// get code of pressed button +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_get_code_pressed_button(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(17)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// get window mouse coordinates +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_get_window_mouse_coordinates(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(37),"b"(1)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// get screen mouse coordinates +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_get_screen_mouse_coordinates(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(37),"b"(0)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// get mouse buttons state +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_get_mouse_buttons_state(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(37),"b"(2)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// get mouse ruler state +//------------------------------------------------------------------------------------------ +extern inline int gui_ksys_get_mouse_ruler_state(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(37),"b"(7)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// put pixel in window +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_put_pixel_window(int x,int y,DWORD color) +{ + __asm__ __volatile__( + "int $0x40" + :/*no output*/ + :"a"(1),"b"(x),"c"(y),"d"(color)); +} + +//------------------------------------------------------------------------------------------ +// put image in window +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_put_image_window(char *p,int x,int y,int sizex,int sizey) +{ + __asm__ __volatile__( + "shll $16,%%ecx\n\t" + "shll $16,%%edx\n\t" + "addl %%esi,%%ecx\n\t" + "addl %%edi,%%edx\n\t" + "int $0x40" + :/*no output*/ + :"a"(7),"b"(p),"c"(sizex),"d"(x),"S"(sizey),"D"(y)); +} + +//------------------------------------------------------------------------------------------ +// draw filled rectangle in window +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_draw_filled_rectangle_window(int x,int y,int sizex,int sizey,DWORD color) +{ + __asm__ __volatile__( + "shll $16,%%ebx\n\t" + "shll $16,%%ecx\n\t" + "addl %%esi,%%ebx\n\t" + "addl %%edi,%%ecx\n\t" + "int $0x40" + :/*no output*/ + :"a"(13),"b"(x),"c"(y),"d"(color),"S"(sizex),"D"(sizey)); +} + +//------------------------------------------------------------------------------------------ +// get screen size +//------------------------------------------------------------------------------------------ +extern inline DWORD gui_ksys_get_screen_size(void) +{ + DWORD value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(14)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// get color of pixel in coordinates (x,y) +//------------------------------------------------------------------------------------------ +extern inline DWORD gui_ksys_get_color_pixel_window(DWORD coordinates) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(35),"b"(coordinates)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// get bits per pixel on the screen +//------------------------------------------------------------------------------------------ +extern inline DWORD gui_ksys_get_screen_bits_per_pixel(void) +{ + int value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(61),"b"(2)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// draw line in window +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_draw_line_window(int x1,int y1,int x2,int y2,DWORD color) +{ + __asm__ __volatile__( + "shll $16,%%ebx\n\t" + "shll $16,%%ecx\n\t" + "addl %%esi,%%ebx\n\t" + "addl %%edi,%%ecx\n\t" + "int $0x40" + :/*no output*/ + :"a"(38),"b"(x1),"c"(y1),"d"(color),"S"(x2),"D"(y2)); +} + +//------------------------------------------------------------------------------------------ +// get standart colors table +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_get_standart_colors_table(char *buf) +{ + __asm__ __volatile__( + "int $0x40" + :/*no output*/ + :"a"(48),"b"(3),"c"(buf),"d"(40)); +} + +//------------------------------------------------------------------------------------------ +// get time from start system to current in 1/100 sec. +//------------------------------------------------------------------------------------------ +extern inline DWORD gui_ksys_get_ticks(void) +{ + DWORD value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(26),"b"(9)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// initialize heap of memory +//------------------------------------------------------------------------------------------ +extern inline DWORD gui_ksys_init_user_heap(void) +{ + DWORD value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(68),"b"(11)); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// alloctae size bytes of user memory +//------------------------------------------------------------------------------------------ +extern inline void* gui_ksys_malloc(DWORD size) +{ + void *value; + + __asm__ __volatile__( + "int $0x40" :"=a"(value) + :"a"(68),"b"(12),"c"(size) + :"memory"); + + return(value); +} + +//------------------------------------------------------------------------------------------ +// free pointer of memory +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_free(void *mem) +{ + __asm__ __volatile__( + "int $0x40" + : + :"a"(68),"b"(13),"c"(mem) + :"memory"); +} + +//------------------------------------------------------------------------------------------ +// reallocate of memory +//------------------------------------------------------------------------------------------ +extern inline void* gui_ksys_realloc(DWORD new_size,void *old_mem) +{ + void *new_mem; + __asm__ __volatile__( + "int $0x40" + :"=a"(new_mem) + :"a"(68),"b"(20),"c"(new_size),"d"(old_mem) + :"memory"); + + return(new_mem); +} + + +//------------------------------------------------------------------------------------------ +// load user mode DLL +//------------------------------------------------------------------------------------------ +extern inline void* gui_ksys_load_dll(char *path) +{ + void *dll_export; + + __asm__ __volatile__( + "int $0x40" + :"=a"(dll_export) + :"a"(68),"b"(19),"c"(path)); + + return(dll_export); +} + +//------------------------------------------------------------------------------------------ +// create thred +//------------------------------------------------------------------------------------------ +extern inline void* gui_ksys_create_thread(DWORD *thread_eip,DWORD *thread_esp) +{ + void *thread_TID; + + __asm__ __volatile__( + "int $0x40" + :"=a"(thread_TID) + :"a"(51),"b"(1),"c"(thread_eip),"d"(thread_esp) + :"memory"); + + return(thread_TID); +} + +//------------------------------------------------------------------------------------------ +// acces to files input output +//------------------------------------------------------------------------------------------ +extern inline DWORD gui_ksys_files_io(fileio_t *f,DWORD value) +{ + DWORD err_status; + + __asm__ __volatile__( + "int $0x40" + :"=a"(err_status),"=b"(value) + :"a"(70),"b"(f)); + + return(err_status); +} + +//------------------------------------------------------------------------------------------ +// debug board output +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_debug_out(int c) +{ + __asm__ __volatile__( + "int $0x40" + : + :"a"(63),"b"(1),"c"(c)); +} + +//------------------------------------------------------------------------------------------ +// KolibriOS system exit program +//------------------------------------------------------------------------------------------ +extern inline void gui_ksys_exit(int value) +{ + __asm__ __volatile__( + "int $0x40" + : + :"a"(-1),"b"(value)); +} + diff --git a/programs/develop/libraries/libGUI/SRC/kolibri_system.inc b/programs/develop/libraries/libGUI/SRC/kolibri_system.inc new file mode 100644 index 0000000000..24dcce0670 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/kolibri_system.inc @@ -0,0 +1,67 @@ +/* + some system function of KolibriOS and founded of them functions +*/ + +static DWORD gui_get_file_size(char *filename,DWORD *buf_for_size) +{ + static char buf[44]; + static fileio_t f; + bded_t *bded; + DWORD status,value; + + f.number_subfunction=5; + f.data=(DWORD*)buf; + f.full_file_path=filename; + + status=gui_ksys_files_io(&f,value); + + if (status==KOLIBRIOS_SYS_FILE_ACCESS_SUCCESSFULLY) + { + bded=(bded_t*)buf; + *buf_for_size=bded->file_size_low; + buf_for_size++; + *buf_for_size=bded->file_size_hight; + } + + return(status); +} + +static DWORD gui_read_file(char *filename,DWORD *buf_pos_size,DWORD size_read,char *buf) +{ + static fileio_t f; + DWORD status,value; + + f.number_subfunction=0; + f.offset_in_file_low=(DWORD)*buf_pos_size;buf_pos_size++; + f.offset_in_file_hight=(DWORD)*buf_pos_size; + f.size=size_read; + f.data=(DWORD*)buf; + f.full_file_path=filename; + + status=gui_ksys_files_io(&f,value); + + return(status); +} + +static void gui_debug_out_str(char *s) +{ + + while(*s) + { + if (*s=='\n') gui_ksys_debug_out(13); + + gui_ksys_debug_out(*s); + s++; + } +} + +static void* gui_cofflib_getproc(import_t *lib, char *name) +{ + int i; + + for(i = 0; lib[i].name && strcmp(name, lib[i].name); i++); + + if(lib[i].name) return lib[i].data; + else return NULL; +} + diff --git a/programs/develop/libraries/libGUI/SRC/libGUI.c b/programs/develop/libraries/libGUI/SRC/libGUI.c new file mode 100644 index 0000000000..c093cacbd7 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/libGUI.c @@ -0,0 +1,168 @@ +/* + libGUI dinamic library + (c) andrew_programmer 2009 + */ + +//service libGUI types of data,functions and constants +#include "types.h" +#include "libGUI.h" +#include "kolibri_system.h" +#include "draw_controls.h" +#include "fonts_meneger.h" +#include "keys.h" + +//controls +#include "control_button.h" +#include "control_image.h" +#include "control_progress_bar.h" +#include "control_scroll_bar.h" +#include "control_scrolled_window.h" +#include "control_text.h" + +//some libC functions +#include "stdarg.h" +#include "stdio.h" +#include "string.h" +#include "stdlib.h" + +#include "stdio.inc" +#include "string.inc" +#include "malloc.inc" +#include "stdlib.inc" +#include "kolibri_system.inc" +#include "draw_controls.inc" +#include "fonts_meneger.inc" +#include "libGUI_menegement.inc" +#include "parent_window.inc" +#include "main_libGUI.inc" +#include "control_text.inc" +#include "control_image.inc" +#include "control_button.inc" +#include "control_progress_bar.inc" +#include "control_scroll_bar.inc" +#include "control_scrolled_window.inc" + + +typedef struct +{ + char *name; + void *function; +}export_t; + +//char szSTART[] = "START"; +char szLibGUIversion[] = "LibGUIversion"; +char szInitLibGUI[] = "InitLibGUI"; +char szLibGUImain[] = "LibGUImain"; +char szQuitLibGUI[] = "QuitLibGUI"; + +char szCreateWindow[] = "CreateWindow"; +char szSetWindowSizeRequest[] = "SetWindowSizeRequest"; + +char szPackControls[] = "PackControls"; +char szDestroyControl[] = "DestroyControl"; +char szSetControlSizeRequest[] = "SetControlSizeRequest"; +char szGetControlSizeX[] = "GetControlSizeX"; +char szGetControlSizeY[] = "GetControlSizeY"; +char szSetControlNewPosition[] = "SetControlNewPosition"; +char szGetControlPositionX[] = "GetControlPositionX"; +char szGetControlPositionY[] = "GetControlPositionY"; +char szSetFocuse[] = "SetFocuse"; +char szRedrawControl[] = "RedrawControl"; +char szSpecialRedrawControl[] = "SpecialRedrawControl"; + +char szSetCallbackFunction[] = "SetCallbackFunction"; +char szBlockCallbackFunction[] = "BlockCallbackFunction"; +char szUnblockCallbackFunction[] = "UnblockCallbackFunction"; + +char szSetIDL_Function[] = "SetIDL_Function"; +char szDestroyIDL_Function[] = "DestroyIDL_Function"; + +char szSetTimerCallbackForFunction[] = "SetTimerCallbackForFunction"; +char szDestroyTimerCallbackForFunction[] = "DestroyTimerCallbackForFunction"; + +char szSetCallbackFunctionForEvent[] = "SetCallbackFunctionForEvent"; +char szDestroyCallbackFunctionForEvent[] = "DestroyCallbackFunctionForEvent"; + +char szCreateButton[] = "CreateButton"; +char szCreateButtonWithText[] = "CreateButtonWithText"; + +char szCreateProgressBar[] = "CreateProgressBar"; +char szSetProgressBarPulse[] = "SetProgressBarPulse"; +char szProgressBarSetText[] = "ProgressBarSetText"; +char szProgressBarGetText[] = "ProgressBarGetText"; + +char szCreateHorizontalScrollBar[] = "CreateHorizontalScrollBar"; +char szCreateVerticalScrollBar[] = "CreateVerticalScrollBar"; + +char szCreateScrolledWindow[] = "CreateScrolledWindow"; +char szScrolledWindowPackControls[] = "ScrolledWindowPackControls"; + +char szCreateImage[] = "CreateImage"; + +char szCreateText[] = "CreateText"; +char szTextBackgroundOn[] = "TextBackgroundOn"; +char szTextBackgroundOff[] = "TextBackgroundOff"; + +char szLoadFont[] = "LoadFont"; +char szFreeFont[] = "FreeFont"; + +export_t EXPORTS[]__asm__("EXPORTS") = + { + {szLibGUIversion, LibGUIversion }, + {szInitLibGUI, InitLibGUI }, + {szLibGUImain, LibGUImain }, + {szQuitLibGUI, QuitLibGUI }, + + {szCreateWindow, CreateWindow }, + {szSetWindowSizeRequest, SetWindowSizeRequest }, + + {szPackControls, PackControls }, + {szDestroyControl, DestroyControl }, + {szSetControlSizeRequest, SetControlSizeRequest }, + {szGetControlSizeX, GetControlSizeX }, + {szGetControlSizeY, GetControlSizeY }, + {szSetControlNewPosition, SetControlNewPosition }, + {szGetControlPositionX, GetControlPositionX }, + {szGetControlPositionY, GetControlPositionY }, + {szSetFocuse, SetFocuse }, + {szRedrawControl, RedrawControl }, + {szSpecialRedrawControl, SpecialRedrawControl }, + + {szSetCallbackFunction, SetCallbackFunction }, + {szBlockCallbackFunction, BlockCallbackFunction }, + {szUnblockCallbackFunction, UnblockCallbackFunction }, + + {szSetIDL_Function, SetIDL_Function }, + {szDestroyIDL_Function, DestroyIDL_Function }, + + {szSetTimerCallbackForFunction, SetTimerCallbackForFunction }, + {szDestroyTimerCallbackForFunction, DestroyTimerCallbackForFunction }, + + {szSetCallbackFunctionForEvent, SetCallbackFunctionForEvent }, + {szDestroyCallbackFunctionForEvent, DestroyCallbackFunctionForEvent }, + + {szCreateButton, CreateButton }, + {szCreateButtonWithText, CreateButtonWithText }, + + {szCreateProgressBar, CreateProgressBar }, + {szSetProgressBarPulse, SetProgressBarPulse }, + {szProgressBarSetText, ProgressBarSetText }, + {szProgressBarGetText, ProgressBarGetText }, + + {szCreateHorizontalScrollBar, CreateHorizontalScrollBar }, + {szCreateVerticalScrollBar, CreateVerticalScrollBar }, + + {szCreateScrolledWindow, CreateScrolledWindow }, + {szScrolledWindowPackControls, ScrolledWindowPackControls }, + + {szCreateImage, CreateImage }, + + {szCreateText, CreateText }, + {szTextBackgroundOn, TextBackgroundOn }, + {szTextBackgroundOff, TextBackgroundOff }, + + {szLoadFont, LoadFont }, + {szFreeFont, FreeFont }, + + {NULL,NULL}, + }; diff --git a/programs/develop/libraries/libGUI/SRC/libGUI.h b/programs/develop/libraries/libGUI/SRC/libGUI.h new file mode 100644 index 0000000000..58a3882279 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/libGUI.h @@ -0,0 +1,580 @@ +/* + service structures of libGUI +*/ + +static DWORD ID; + +//screen's parameters +#define BYTES_PER_PIXEL 4 + +//platform parameters +#define KOLIBRIOS 1 +//#define DEBUG + +//boolean constants +#define TRUE 0x1 +#define FALSE 0x0 + +//maximum callbacks for one check of callback +#define MAX_CALLBACKS 255 + +///////////////////////////////////////////////////////////////////////// +// libGUI sysyem messages types +///////////////////////////////////////////////////////////////////////// +#define MESSAGE_FULL_REDRAW_ALL 1 +#define MESSAGE_KEYS_EVENT 2 +#define MESSAGE_SPECIALIZED 3 +#define MESSAGE_SET_FOCUSE 4 +#define MESSAGE_CHANGE_FOCUSE 5 +#define MESSAGE_MOUSE_EVENT 6 +#define MESSAGE_CHANGE_POSITION_EVENT 7 +#define MESSAGE_CHANGESIZE_EVENT 8 +#define MESSAGE_CALL_TIMER_EVENT 9 +#define MESSAGE_FULL_REDRAW_ALL_WITH_FINITION 10 +#define MESSAGE_SET_MAIN_PARENT 11 +#define MESSAGE_DESTROY_CONTROL -1 + +///////////////////////////////////////////////////////////////////////// +// system flags of controls +///////////////////////////////////////////////////////////////////////// +#define FLAG_SHOW_CONTROL 0x1 +#define FLAG_HIDE_CONTROL 0xfffe +#define FLAG_FOCUSE_INPUT_SUPPOROTE 0x2 +#define FLAG_FOCUSE_INPUT_NOTSUPPOROTE 0xfffd +#define FLAG_FOCUSE_INPUT_ON 0x4 +#define FLAG_FOCUSE_INPUT_OFF 0xfffb +#define FLAG_CONNECT_EVENT_ON 0x8 +#define FLAG_CONNECT_EVENT_OFF 0xfff7 +#define FLAG_MOUSE_BLOCKED_ON 0x10 +#define FLAG_MOUSE_BLOCKED_OFF 0xffef +#define FLAG_GET_SPECIALIZED_MESSAGE_ON 0x20 +#define FLAG_GET_SPECIALIZED_MESSAGE_OFF 0xffdf + +///////////////////////////////////////////////////////////////////////// +// system flags of callback functions +///////////////////////////////////////////////////////////////////////// +#define FLAG_BLOCK_CALLBACK_ON 0x1 +#define FLAG_BLOCK_CALLBACK_OFF 0xfe + +///////////////////////////////////////////////////////////////////////// +// system flags of main wondow for timers +///////////////////////////////////////////////////////////////////////// +#define FLAG_TIMER_ON 0x1 +#define FLAG_TIMER_OFF 0xfe + +///////////////////////////////////////////////////////////////////////// +// system keys states +///////////////////////////////////////////////////////////////////////// +#define KEY_DOWN 16 +#define KEY_UP 17 +#define KEY_HOTKEY 18 +///////////////////////////////////////////////////////////////////////// +// system mouse buttons states +///////////////////////////////////////////////////////////////////////// +#define MOUSE_LEFT_BUTTON_DOWN 19 +#define MOUSE_LEFT_BUTTON_UP 20 +#define MOUSE_RIGHT_BUTTON_DOWN 21 +#define MOUSE_RIGHT_BUTTON_UP 22 +#define MOUSE_MIDDLE_BUTTON_DOWN 23 +#define MOUSE_MIDDLE_BUTTON_UP 24 +#define MOUSE_4_BUTTON_DOWN 25 +#define MOUSE_4_BUTTON_UP 26 +#define MOUSE_5_BUTTON_DOWN 27 +#define MOUSE_5_BUTTON_UP 28 + + +///////////////////////////////////////////////////////////////// +// CONNECT EVENTS FOR CALLBACKs +///////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////// +// connect events for button +//////////////////////////////////////////////////////////////// +#define BUTTON_ENTER_EVENT 29 +#define BUTTON_LEAVE_EVENT 30 +#define BUTTON_PRESSED_EVENT 31 +#define BUTTON_RELEASED_EVENT 32 + +//////////////////////////////////////////////////////////////// +// connect events for button +//////////////////////////////////////////////////////////////// +#define SCROLLBAR_CHANGED_EVENT 33 + +//////////////////////////////////////////////////////////////// +// connect events for main parent window +//////////////////////////////////////////////////////////////// +#define DELETE_EVENT 36 + +//////////////////////////////////////////////////////////////////// +//screen buffer parameters +//////////////////////////////////////////////////////////////////// +#define DRAW_OUTPUT_SCREEN 0 +#define DRAW_OUTPUT_BUFFER 1 + + +static struct SCREEN +{ + DWORD bits_per_pixel; + DWORD bytes_per_pixel; + DWORD draw_output; + int x; + int y; + int size_x; + int size_y; + int skin_height; + int display_size_x; + int display_size_y; + char *buffer; +}screen; + +//////////////////////////////////////////////////////////////// +// header of parent of control +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct HEADERPARENT +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD **control_for_callback_function; + DWORD **callback_for_control_callback; + DWORD number_callbacks; + DWORD *global_active_control_for_keys; + DWORD *message; + DWORD *timer_bk; + DWORD *timer_fd; + DWORD number_timers_for_controls; + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *IDL_func; + DWORD *IDL_func_data; +}; +#pragma pack(pop) + +typedef struct HEADERPARENT parent_t; + +//////////////////////////////////////////////////////////////// +// header of control +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct HEADER +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct HEADER header_t; +//////////////////////////////////////////////////////////////// +// callback structure for callback function of control +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct CALLBACK +{ + DWORD *clb_bk; + DWORD *clb_fd; + DWORD *clb_control; + DWORD *func; + DWORD *func_data; + DWORD connect_event; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct CALLBACK gui_callback_t; +//////////////////////////////////////////////////////////////// +// timer +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct TIMER +{ + DWORD *tmr_bk; + DWORD *tmr_fd; + DWORD *tmr_parent; + DWORD *func; + DWORD *func_data; + DWORD last_time; + DWORD time_tick; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct TIMER gui_timer_t; +//////////////////////////////////////////////////////////////// +// structure for callback events +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct CALLBACKEVENT +{ + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *calev_parent; + DWORD *func; + DWORD *func_data; + DWORD event_type; +}; +#pragma pack(pop) + +typedef struct CALLBACKEVENT gui_callbackevent_t; +//////////////////////////////////////////////////////////////// +// structure for callback events +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct FINITION +{ + DWORD x; + DWORD y; + DWORD sizex; + DWORD sizey; + char flags; +}; +#pragma pack(pop) + +typedef struct FINITION finition_t; +//////////////////////////////////////////////////////////////// +// type of data - structure message +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct MESSAGE +{ + DWORD type; + DWORD arg1; + DWORD arg2; + DWORD arg3; + DWORD arg4; +}; +#pragma pack(pop) + +typedef struct MESSAGE gui_message_t; +//////////////////////////////////////////////////////////////// +// prototype of functions +//////////////////////////////////////////////////////////////// +void (*ControlProc)(void *Control,gui_message_t *message); +void (*CallbackFunction)(header_t *Control,void *data); +void (*TimerCallbackFunction)(void *data); +void (*CallbackFunctionForEvent)(gui_message_t *message,void *data); +void (*IDL_Function)(void *data); + +//////////////////////////////////////////////////////////////// +// button +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlButton +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //button's data + unsigned char btn_flags; }; +#pragma pack(pop) + +typedef struct ControlButton gui_button_t; +// information for creating control Button +#pragma pack(push,1) +struct ButtonData +{ + int x; + int y; + int width; + int height; +}; +#pragma pack(pop) + +typedef struct ButtonData gui_button_data_t; +//////////////////////////////////////////////////////////////// +// scroller +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlScrollBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scroll bar's data + float ruller_size; + float ruller_pos; + float ruller_step; + unsigned char scb_flags; +}; +#pragma pack(pop) + +typedef struct ControlScrollBar gui_scroll_bar_t; + +#pragma pack(push,1) +struct ScrollBarData +{ + int x; + int y; + int width; + int height; + float ruller_size; + float ruller_pos; + float ruller_step; +}; +#pragma pack(pop) + +typedef struct ScrollBarData gui_scroll_bar_data_t; +//////////////////////////////////////////////////////////////// +// progressbar +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlProgressBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //progress bar's data + float progress; + unsigned char prb_flags; +}; +#pragma pack(pop) + +typedef struct ControlProgressBar gui_progress_bar_t; + +#pragma pack(push,1) +struct ProgressBarData +{ + int x; + int y; + int width; + int height; + float progress; +}; +#pragma pack(pop) + +typedef struct ProgressBarData gui_progress_bar_data_t; +//////////////////////////////////////////////////////////////// +// scrolled window +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlScrolledWindow +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scrolled windows's data + DWORD virtual_x; + DWORD virtual_y; + DWORD virtual_sizex; + DWORD virtual_sizey; + DWORD *virtual_controls_x; + DWORD *virtual_controls_y; + DWORD number_virtual_controls; + DWORD scroll_arrea_sizex; + DWORD scroll_arrea_sizey; + DWORD *horizontal_scroll; + DWORD *vertical_scroll; + unsigned char scw_flags; +}; +#pragma pack(pop) + +typedef struct ControlScrolledWindow gui_scrolled_window_t; + +#pragma pack(push,1) +struct ScrolledWindowData +{ + int x; + int y; + int width; + int height; +}; +#pragma pack(pop) + +typedef struct ScrolledWindowData gui_scrolled_window_data_t; + +//////////////////////////////////////////////////////////////// +// image +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlImage +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + char bits_per_pixel; + char bytes_per_pixel; + char *img; +}; +#pragma pack(pop) + +typedef struct ControlImage gui_image_t; + +#pragma pack(push,1) +struct ImageData +{ + int x; + int y; + int width; + int height; + char bits_per_pixel; +}; +#pragma pack(pop) + +typedef struct ImageData gui_image_data_t; + +//////////////////////////////////////////////////////////////// +// text +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlText +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD *font; + DWORD color; + DWORD background_color; + char *text; + BYTE txt_flags; +}; +#pragma pack(pop) + +typedef struct ControlText gui_text_t; + +#pragma pack(push,1) +struct TextData +{ + int x; + int y; + DWORD *font; + DWORD color; + DWORD background_color; + char background; + char *text; +}; +#pragma pack(pop) + +typedef struct TextData gui_text_data_t; +///////////////////////////////////////////////////////////////////////////// +// prototips of some service functions +///////////////////////////////////////////////////////////////////////////// + +char CheckCrossRectangles(int x1,int y1,int sizex1,int sizey1,int x2,int y2,int sizex2,int sizey2); diff --git a/programs/develop/libraries/libGUI/SRC/libGUI_menegement.inc b/programs/develop/libraries/libGUI/SRC/libGUI_menegement.inc new file mode 100644 index 0000000000..be22868a77 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/libGUI_menegement.inc @@ -0,0 +1,1657 @@ +/* + libGUI main part of code +*/ + +//--------------------------------------------------------------------------------- +// destroy_control for libGUI +//--------------------------------------------------------------------------------- +void DestroyControl(void *control_ptr) +{ + struct HEADER *Parent; + struct HEADER *control; + struct HEADER *seek_control; + struct HEADER *exchange_control; + struct HEADER *last_control; + struct HEADER *next_control; + + if (control_ptr==NULL) return; + + control=control_ptr; + Parent=(struct HEADER *)control->parent; + + if (Parent->child_bk==Parent->child_fd) + { + //parent have got alone child control + if (Parent->child_bk==(DWORD*)control) + { + //current control is child control of parent +#ifdef DEBUG + printf("\ndestroyed control=%d parent=%d ID=%d",(int)control,(int)Parent,(int)control->ctrl_ID); +#endif + free(control); + Parent->child_bk=(DWORD*)NULL; + Parent->child_fd=(DWORD*)NULL; + } + return; + } + + seek_control=(struct HEADER*)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + if (seek_control==control) + { + //delete control from control's stack + last_control=(struct HEADER*)seek_control->ctrl_bk; + next_control=(struct HEADER*)seek_control->ctrl_fd; + + if ((last_control!=Parent) && (next_control!=NULL)) + {//deliting control isn't first control and isn't endest of parent + next_control->ctrl_bk=(DWORD*)last_control; + last_control->ctrl_fd=(DWORD*)next_control; + } + else + { + if (last_control==Parent) + {//deliting control is first control of Parend + Parent->child_bk=(DWORD*)next_control; + next_control->ctrl_bk=(DWORD*)Parent; + if (next_control->ctrl_fd==(DWORD*)NULL) + { + Parent->child_fd=(DWORD*)next_control; + Parent->child_bk=(DWORD*)next_control; + } + } + + if (next_control==(struct HEADER*)NULL) + { + //there isn't next controls + last_control->ctrl_fd=(DWORD*)NULL; + Parent->ctrl_fd=(DWORD*)last_control; + } + } +#ifdef DEBUG + printf("\ndestroyed control=%d parent=%d ID=%d",(int)control,(int)Parent,(int)control->ctrl_ID); +#endif + free(control); + break; + } + exchange_control=(struct HEADER*)seek_control->ctrl_fd; + seek_control=exchange_control; + } +} + +//--------------------------------------------------------------------------------- +// create new timer for parent window +//--------------------------------------------------------------------------------- +void *CreateTimerForParentWindow(parent_t *parent) +{ + struct TIMER *timer; + struct TIMER *backward_timer; + + timer=malloc(sizeof(struct TIMER)); + timer->tmr_parent=(DWORD*)parent; + + if (parent->timer_bk==(DWORD*)NULL) + {//not yet timers + parent->timer_bk=(DWORD*)timer; + parent->timer_fd=(DWORD*)timer; + timer->tmr_bk=(DWORD*)parent; + timer->tmr_fd=(DWORD*)NULL; + } + else + { + backward_timer=(struct TIMER*)parent->timer_fd; + parent->timer_fd=(DWORD*)timer; + backward_timer->tmr_fd=(DWORD*)timer; + timer->tmr_bk=(DWORD*)backward_timer; + timer->tmr_fd=(DWORD*)NULL; + } + return(timer); +} + +//--------------------------------------------------------------------------------- +// destroy timer for parent window +//--------------------------------------------------------------------------------- +void DestroyTimerCallbackForFunction(struct TIMER *timer) +{ + struct HEADERPARENT *Parent; + struct TIMER *seek_timer; + struct TIMER *exchange_timer; + struct TIMER *last_timer; + struct TIMER *next_timer; + + if (timer==(struct TIMER*)NULL) return; + + Parent=(struct HEADERPARENT *)timer->tmr_parent; + + if (Parent->timer_bk==Parent->timer_fd) + { + //parent have got alone timer + if (Parent->timer_bk==(DWORD*)timer) + { + Parent->timer_bk=(DWORD*)NULL; + Parent->timer_fd=(DWORD*)NULL; +#ifdef DEBUG + printf("\ndestroyed timer %d parent window %d",(int)timer,(int)timer->tmr_parent); +#endif + free(timer); + return; + } + return; + } + + seek_timer=(struct TIMER*)Parent->timer_bk; + while(seek_timer!=(struct TIMER*)NULL) + { + if (seek_timer==timer) + { + //delete timer from timers's stack + last_timer=(struct TIMER*)seek_timer->tmr_bk; + next_timer=(struct TIMER*)seek_timer->tmr_fd; + + if ((last_timer!=(struct TIMER*)Parent) && (next_timer!=(struct TIMER*)NULL)) + {//deliting timer isn't first timer and isn't endest + next_timer->tmr_bk=(DWORD*)last_timer; + last_timer->tmr_fd=(DWORD*)next_timer; + } + else + { + if (last_timer==(struct TIMER*)Parent) + {//deliting timer is first timer of Parend + Parent->timer_bk=(DWORD*)next_timer; + next_timer->tmr_bk=(DWORD*)Parent; + if (next_timer->tmr_fd==(DWORD*)NULL) + { + Parent->timer_fd=(DWORD*)next_timer; + Parent->timer_bk=(DWORD*)next_timer; + } + } + + if (next_timer==(struct TIMER*)NULL) + { + //there isn't next controls + last_timer->tmr_fd=(DWORD*)NULL; + Parent->timer_fd=(DWORD*)last_timer; + } + } +#ifdef DEBUG + printf("\ndestroyed timer %d parent window %d",(int)timer,(int)timer->tmr_parent); +#endif + free(timer); + break; + } + exchange_timer=(struct TIMER*)seek_timer->tmr_fd; + seek_timer=exchange_timer; + } +} + +//--------------------------------------------------------------------------------- +// create timer for function of parent window +//--------------------------------------------------------------------------------- +void *SetTimerCallbackForFunction(parent_t *parent_window,int time_tick,void *func,void *func_data) +{ + struct TIMER *timer; + + timer=CreateTimerForParentWindow(parent_window); + timer->func=(DWORD*)func; + timer->func_data=(DWORD*)func_data; + timer->time_tick=(DWORD)time_tick; + timer->last_time=gui_ksys_get_ticks(); + timer->flags=timer->flags | FLAG_TIMER_ON; + + return(timer); +} + +//--------------------------------------------------------------------------------- +// create timer for control +//--------------------------------------------------------------------------------- +void *SetTimerCallbackForControl(int time_tick,void *func,void *func_data) +{ + struct TIMER *timer; + + timer=malloc(sizeof(struct TIMER)); + timer->func=(DWORD*)func; + timer->func_data=(DWORD*)func_data; + timer->time_tick=(DWORD)time_tick; + timer->last_time=gui_ksys_get_ticks(); + timer->flags=timer->flags & FLAG_TIMER_OFF; + + return(timer); +} + +//--------------------------------------------------------------------------------- +// call timer +//--------------------------------------------------------------------------------- +void Timer(struct TIMER *timer) +{ + DWORD time,delta_time; + + time=gui_ksys_get_ticks(); + delta_time=time-timer->last_time; + if (delta_time>=timer->time_tick) + { + TimerCallbackFunction=(void(*)(void *data))timer->func; + TimerCallbackFunction(timer->func_data); + timer->last_time=gui_ksys_get_ticks(); + } +} + +//--------------------------------------------------------------------------------- +// create new callback for event +//--------------------------------------------------------------------------------- +void *CreateCallbackForEvent(parent_t *parent) +{ + gui_callbackevent_t *calev; + gui_callbackevent_t *backward_calev; + + calev=malloc(sizeof(gui_callbackevent_t)); + calev->calev_parent=(DWORD*)parent; + + if (parent->calev_bk==(DWORD*)NULL) + {//not yet timers + parent->calev_bk=(DWORD*)calev; + parent->calev_fd=(DWORD*)calev; + calev->calev_bk=(DWORD*)parent; + calev->calev_fd=(DWORD*)NULL; + } + else + { + backward_calev=(gui_callbackevent_t*)parent->calev_fd; + parent->calev_fd=(DWORD*)calev; + backward_calev->calev_fd=(DWORD*)calev; + calev->calev_bk=(DWORD*)backward_calev; + calev->calev_fd=(DWORD*)NULL; + } + return(calev); +} + +//--------------------------------------------------------------------------------- +// destroy callback function for eventcalev +//--------------------------------------------------------------------------------- +void DestroyCallbackFunctionForEvent(gui_callbackevent_t *calev) +{ + struct HEADERPARENT *Parent; + struct CALLBACKEVENT *seek_calev; + struct CALLBACKEVENT *exchange_calev; + struct CALLBACKEVENT *last_calev; + struct CALLBACKEVENT *next_calev; + + if (calev==(gui_callbackevent_t*)NULL) return; + + Parent=(parent_t*)calev->calev_parent; + + if (Parent->calev_bk==Parent->calev_fd) + { + //parent have got alone timer + if (Parent->calev_bk==(DWORD*)calev) + { + free(calev); + Parent->calev_bk=(DWORD*)NULL; + Parent->calev_fd=(DWORD*)NULL; + } + return; + } + + seek_calev=(struct CALLBACKEVENT*)Parent->calev_bk; + while(seek_calev!=(struct CALLBACKEVENT*)NULL) + { + if (seek_calev==calev) + { + //delete timer from timers's stack + last_calev=(struct CALLBACKEVENT*)seek_calev->calev_bk; + next_calev=(struct CALLBACKEVENT*)seek_calev->calev_fd; + + if ((last_calev!=(struct CALLBACKEVENT*)Parent) && (next_calev!=(struct CALLBACKEVENT*)NULL)) + {//deliting timer isn't first timer and isn't endest + next_calev->calev_bk=(DWORD*)last_calev; + last_calev->calev_fd=(DWORD*)next_calev; + } + else + { + if (last_calev==(struct CALLBACKEVENT*)Parent) + {//deliting timer is first timer of Parend + Parent->calev_bk=(DWORD*)next_calev; + next_calev->calev_bk=(DWORD*)Parent; + if (next_calev->calev_fd==(DWORD*)NULL) + { + Parent->calev_fd=(DWORD*)next_calev; + Parent->calev_bk=(DWORD*)next_calev; + } + } + + if (next_calev==(struct CALLBACKEVENT*)NULL) + { + //there isn't next controls + last_calev->calev_fd=(DWORD*)NULL; + Parent->calev_fd=(DWORD*)last_calev; + } + } + free(calev); + break; + } + exchange_calev=(struct CALLBACKEVENT*)seek_calev->calev_fd; + seek_calev=exchange_calev; + } +} + +//--------------------------------------------------------------------------------- +// create callback for messenger of events +//--------------------------------------------------------------------------------- +void *SetCallbackFunctionForEvent(parent_t *parent_window,int event_type,void *func,void *func_data) +{ + gui_callbackevent_t *calev; + + calev=CreateCallbackForEvent(parent_window); + calev->func=(DWORD*)func; + calev->func_data=(DWORD*)func_data; + calev->event_type=(DWORD)event_type; + + return(calev); +} + +//--------------------------------------------------------------------------------- +// check cross control and mouse +//--------------------------------------------------------------------------------- +char CheckCrossBox(struct HEADER *control,int mouse_x,int mouse_y) +{ + struct FINITION *fin; + int x,y,x2,y2; + int xmin,xmax,ymin,ymax,sx,sy; + + fin=(struct FINITION*)control->finition; + + if (fin->flags & FINITION_ON) + { + xmin=fin->x; + xmax=fin->x+fin->sizex-1; + ymin=fin->y; + ymax=fin->y+fin->sizey-1; + + x=control->ctrl_x; + y=control->ctrl_y; + x2=x+control->ctrl_sizex-1; + y2=y+control->ctrl_sizey-1; + + if (x2xmax) return(FALSE); + if (y2ymax) return(FALSE); + + //finit x coordinates and sizex + sx=x-xmin; + + if (sx>=0) + { + if (x2>xmax) x2=xmax; + } + else + { + x=xmin; + if (x2>xmax) x2=xmax; + } + + //finit y coordinates and sizey + sy=y-ymin; + + if (sy>=0) + { + if (y2>ymax) y2=ymax; + } + else + { + y=ymin; + if (y2>ymax) y2=ymax; + } + //check cross finited control with mouse + if ((mouse_x>=x) && (mouse_x<=x2) && (mouse_y>=y) && (mouse_y<=y2)) + return(TRUE); + else + return(FALSE); + } + else + { + if ((mouse_x>=control->ctrl_x) && (mouse_x<=control->ctrl_x+control->ctrl_sizex) && + (mouse_y>=control->ctrl_y) && (mouse_y<=control->ctrl_y+control->ctrl_sizey)) + return(TRUE); + else + return(FALSE); + } +} + +//--------------------------------------------------------------------------------- +// check cross two rectaangles +//--------------------------------------------------------------------------------- +char CheckCrossRectangles(int x1,int y1,int sizex1,int sizey1,int x2,int y2,int sizex2,int sizey2) +{ + int s; + int xmax,ymax; + + xmax=x1+sizex1-1; + ymax=y1+sizey1-1; + + //check x cross + s=x2-x1; + if (s>0) + {//second rectangle have right position + if (x2>xmax) return(FALSE); + } + if (s<0) + {//second rectangle have left position + s=-s; + if (s>=sizex2) return(FALSE); + } + + //check y cross + s=y2-y1; + if (s>0) + {//second rectangle have down position + if (y2>ymax) return(FALSE); + } + if (s<0) + {//second rectangle have up position + s=-s; + if (s>=sizey2) return(FALSE); + } + return(TRUE); +} + +//--------------------------------------------------------------------------------- +// check full cross two rectaangles +//--------------------------------------------------------------------------------- +char CheckFullCrossRectangles(int x1,int y1,int sizex1,int sizey1,int x2,int y2,int sizex2,int sizey2) +{ + int s; + int xmax,ymax; + + xmax=x1+sizex1-1; + ymax=y1+sizey1-1; + + if (x2>=x1 && x2+sizex2-1<=xmax && y2>=y1 && y2+sizey2-1<=ymax) return(TRUE); + else return(FALSE); +} + +//--------------------------------------------------------------------------------- +// send message to controls +//--------------------------------------------------------------------------------- +void SendMessage(struct HEADER *Parent,struct MESSAGE *message) +{ + struct HEADER *seek_control; + struct HEADER *exchange_control; + struct HEADER *parent; + struct HEADERPARENT *main_parent; + struct MESSAGE local_service_message; + struct HEADER *active_control_for_keys; + struct HEADER *active_control_for_mouse; + char cross; + + //Parent haven't got child controls + if ((Parent->child_bk==NULL) && (Parent->child_fd==NULL)) return; + + //load main parent + main_parent=(struct HEADERPARENT*)Parent->main_parent; + + //load active controls from Parent + active_control_for_keys=(struct HEADER*)Parent->active_control_for_keys; + active_control_for_mouse=(struct HEADER*)Parent->active_control_for_mouse; + + //Parent have got alon child control + if (Parent->child_bk==Parent->child_fd) + { + seek_control=(struct HEADER *)Parent->child_bk; + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + + switch(message->type) + { + case MESSAGE_FULL_REDRAW_ALL: + { + //send message redraw to all child controls + if (seek_control->flags & FLAG_SHOW_CONTROL) ControlProc(seek_control,message); + break; + } + case MESSAGE_FULL_REDRAW_ALL_WITH_FINITION: + { + //send message finited redraw to all child controls + if (seek_control->flags & FLAG_SHOW_CONTROL) ControlProc(seek_control,message); + break; + } + case MESSAGE_KEYS_EVENT: + { //change active control for keyboard by TAB press + if ((message->arg1==KEY_DOWN) && (message->arg2==SC_TAB)) + { + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + if (active_control_for_keys==seek_control) + {//focuse of input set for current control + ControlProc=(void (*)(void *Control,struct MESSAGE *message))active_control_for_keys->ctrl_proc; + local_service_message.type=MESSAGE_CHANGE_FOCUSE; + local_service_message.arg1=FALSE; + active_control_for_keys->flags=active_control_for_keys->flags & FLAG_FOCUSE_INPUT_OFF; + ControlProc(active_control_for_keys,&local_service_message); + + parent=(struct HEADER*)active_control_for_keys->parent; + + seek_control=parent; + do + { + if (parent==(struct HEADER*)main_parent) break; + //if next control NULL go to parent + if (seek_control==(struct HEADER*)NULL) seek_control=parent; + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + if (seek_control==(struct HEADER*)NULL) + parent=(struct HEADER*)parent->parent; + } + while((seek_control==(struct HEADER*)NULL) || + ((seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE)==FALSE)); + + if (parent==(struct HEADER*)main_parent) + { + //find first control of main parent with focuse of input supporote + seek_control=(struct HEADER *)main_parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) break; + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + main_parent->active_control_for_keys=(DWORD*)seek_control; + main_parent->global_active_control_for_keys=(DWORD*)seek_control; + + //send message enable focuse of input to control + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + local_service_message.arg1=FALSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + active_control_for_keys=(struct HEADER*)NULL; + break; + } + if (seek_control!=(struct HEADER*)NULL) + { + parent=(struct HEADER*)seek_control->parent; + parent->active_control_for_keys=(DWORD*)seek_control; + main_parent->global_active_control_for_keys=(DWORD*)seek_control; + + //send message enable focuse of input to control + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + local_service_message.arg1=FALSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + active_control_for_keys=(struct HEADER*)NULL; + Parent->active_control_for_keys=(DWORD*)active_control_for_keys; + break; + } + } + else + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + local_service_message.arg1=FALSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + active_control_for_keys=seek_control; + Parent->active_control_for_keys=(DWORD*)active_control_for_keys; + main_parent->global_active_control_for_keys=(DWORD*)seek_control; + } + } + } + + //send message of keys only to active control + if (active_control_for_keys!=NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))active_control_for_keys->ctrl_proc; + ControlProc(active_control_for_keys,message); + } + break; + } + case MESSAGE_SPECIALIZED: + { + //send specialized message to all child controls + ControlProc(seek_control,message); + break; + } + case MESSAGE_MOUSE_EVENT: + { + if (seek_control->flags & FLAG_MOUSE_BLOCKED_ON) break; + + if (message->arg3==MOUSE_LEFT_BUTTON_DOWN) + { + if (active_control_for_mouse!=NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))active_control_for_mouse->ctrl_proc; + ControlProc(active_control_for_mouse,message); + break; + } + } + else + { + if (active_control_for_mouse!=NULL) {active_control_for_mouse=NULL;} + } + + cross=FALSE; + if (CheckCrossBox(seek_control,message->arg1,message->arg2)==TRUE) + { + if (message->arg3==MOUSE_LEFT_BUTTON_DOWN) + { + cross=TRUE; + active_control_for_mouse=seek_control; + + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + parent=(struct HEADER*)seek_control->parent; + if (parent->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + active_control_for_keys=(struct HEADER*)main_parent->global_active_control_for_keys; + if (active_control_for_keys!=(struct HEADER*)NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + active_control_for_keys->ctrl_proc; + + local_service_message.type=MESSAGE_CHANGE_FOCUSE; + active_control_for_keys->flags= + active_control_for_keys->flags & FLAG_FOCUSE_INPUT_OFF; + ControlProc(active_control_for_keys,&local_service_message); + } + + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + main_parent->global_active_control_for_keys=(DWORD*)seek_control; + Parent->active_control_for_keys=(DWORD*)seek_control; + } + } + } + } + + if ((cross==FALSE) && (message->arg3==MOUSE_LEFT_BUTTON_DOWN)) + { + if (active_control_for_keys!=NULL) + {//disable focuse of input for active control of keys + ControlProc=(void (*)(void *Control,struct MESSAGE *message))active_control_for_keys->ctrl_proc; + + local_service_message.type=MESSAGE_CHANGE_FOCUSE; + active_control_for_keys->flags=active_control_for_keys->flags & FLAG_FOCUSE_INPUT_OFF; + ControlProc(active_control_for_keys,&local_service_message); + } + } + + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,message); + break; + } + case MESSAGE_CHANGE_POSITION_EVENT: + { + ControlProc(seek_control,message); + break; + } + case MESSAGE_CALL_TIMER_EVENT: + { + ControlProc(seek_control,message); + break; + } + case MESSAGE_DESTROY_CONTROL: + { + //send message to control for destroing child controls + ControlProc(seek_control,message); + DestroyControl(seek_control); + break; + } + case MESSAGE_SET_MAIN_PARENT: + { + ControlProc(seek_control,message); + break; + } + default:break; + } + } + else + { + switch(message->type) + { + case MESSAGE_FULL_REDRAW_ALL: + { + //send message redraw to all child controls of Parent + seek_control=(struct HEADER *)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + if (seek_control->flags & FLAG_SHOW_CONTROL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,message); + } + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + break; + } + case MESSAGE_FULL_REDRAW_ALL_WITH_FINITION: + { + //send message redraw to all child controls of Parent + seek_control=(struct HEADER *)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + if (seek_control->flags & FLAG_SHOW_CONTROL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,message); + } + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + break; + } + case MESSAGE_KEYS_EVENT: + { + if ((message->arg1==KEY_DOWN) && (message->arg2==SC_TAB)) + { //change active control for keyboard by TAB press + if (active_control_for_keys==NULL) + { + seek_control=(struct HEADER *)Parent->child_bk; + + if ((seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE)==FALSE) + { //find first control of parend with supporote of input + while(seek_control->ctrl_fd!=(DWORD*)NULL) + { + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + active_control_for_keys=seek_control; + main_parent->global_active_control_for_keys= + (DWORD*)active_control_for_keys; + Parent->active_control_for_keys=(DWORD*)active_control_for_keys; + break; + } + } + if (active_control_for_keys!=NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + } + } + else + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + active_control_for_keys=seek_control; + main_parent->global_active_control_for_keys=(DWORD*)active_control_for_keys; + Parent->active_control_for_keys=(DWORD*)active_control_for_keys; + } + } + else + { + if (active_control_for_keys==(struct HEADER*)main_parent->global_active_control_for_keys) + { + seek_control=active_control_for_keys; + while(seek_control!=(struct HEADER*)NULL) + { + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + + if (seek_control==(struct HEADER*)NULL) + { //send message disable focuse of input to current control + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + active_control_for_keys->ctrl_proc; + local_service_message.type=MESSAGE_CHANGE_FOCUSE; + active_control_for_keys->flags= + active_control_for_keys->flags & FLAG_FOCUSE_INPUT_OFF; + ControlProc(active_control_for_keys,&local_service_message); + + //back into main parent of tree and find next not NULL control + parent=(struct HEADER*)active_control_for_keys->parent; + do + { + if (parent==(struct HEADER*)main_parent) break; + + //if next control NULL go to parent + if (seek_control==(struct HEADER*)NULL) seek_control=parent; + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + if (seek_control==(struct HEADER*)NULL) + parent=(struct HEADER*)parent->parent; + + } + while((seek_control==(struct HEADER*)NULL) || + ((seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE)==FALSE)); + + if (parent==(struct HEADER*)main_parent) + { + //find first control of main parent with focuse of input supporote + seek_control=(struct HEADER *)main_parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + break; + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + + main_parent->active_control_for_keys=(DWORD*)seek_control; + main_parent->global_active_control_for_keys=(DWORD*)seek_control; + + //send message enable focuse of input to control + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + active_control_for_keys=(struct HEADER*)NULL; + break; + + } + if (seek_control!=(struct HEADER*)NULL) + { + parent=(struct HEADER*)seek_control->parent; + parent->active_control_for_keys=(DWORD*)seek_control; + main_parent->global_active_control_for_keys=(DWORD*)seek_control; + + //send message enable focuse of input to control + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + active_control_for_keys=(struct HEADER*)NULL; + Parent->active_control_for_keys=(DWORD*)active_control_for_keys; + break; + } + } + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + active_control_for_keys->ctrl_proc; + local_service_message.type=MESSAGE_CHANGE_FOCUSE; + active_control_for_keys->flags= + active_control_for_keys->flags & FLAG_FOCUSE_INPUT_OFF; + ControlProc(active_control_for_keys,&local_service_message); + + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + active_control_for_keys=seek_control; + main_parent->global_active_control_for_keys= + (DWORD*)active_control_for_keys; + Parent->active_control_for_keys=(DWORD*)active_control_for_keys; + break; + } + } + } + } + } + + //send message of keys only to active control + if (active_control_for_keys!=NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))active_control_for_keys->ctrl_proc; + ControlProc(active_control_for_keys,message); + } + break; + } + case MESSAGE_SPECIALIZED: + { + //send specialized message to all child controls + seek_control=(struct HEADER *)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,message); + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + break; + } + case MESSAGE_MOUSE_EVENT: + { + if (message->arg3==MOUSE_LEFT_BUTTON_DOWN) + { + if (active_control_for_mouse!=NULL) + { + if (active_control_for_mouse->flags & FLAG_MOUSE_BLOCKED_ON) break; + + ControlProc=(void (*)(void *Control,struct MESSAGE *message))active_control_for_mouse->ctrl_proc; + ControlProc(active_control_for_mouse,message); + break; + } + } + else + { + if (active_control_for_mouse!=NULL) {active_control_for_mouse=NULL;} + } + + cross=FALSE; + seek_control=(struct HEADER*)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + if (CheckCrossBox(seek_control,message->arg1,message->arg2)==TRUE && + (seek_control->flags & FLAG_MOUSE_BLOCKED_ON)==FALSE) + { + if (message->arg3==MOUSE_LEFT_BUTTON_DOWN) + { + cross=TRUE; + active_control_for_mouse=seek_control; + + if (active_control_for_mouse->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + //set focuse of input for new active control + active_control_for_mouse->flags=active_control_for_mouse->flags | FLAG_FOCUSE_INPUT_ON; + + if (active_control_for_keys!=NULL) + { + if (active_control_for_keys!=seek_control) + { + //check seek control for supporote focuse of input + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + //check parent for supporote focuse of input + parent=(struct HEADER*)seek_control->parent; + if (parent->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + active_control_for_keys->ctrl_proc; + + local_service_message.type=MESSAGE_CHANGE_FOCUSE; + local_service_message.arg1=FALSE; + active_control_for_keys->flags= + active_control_for_keys->flags & + FLAG_FOCUSE_INPUT_OFF; + ControlProc(active_control_for_keys,&local_service_message); + + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + local_service_message.arg1=FALSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + active_control_for_keys=seek_control; + main_parent->global_active_control_for_keys= + (DWORD*)active_control_for_keys; + Parent->active_control_for_keys= + (DWORD*)active_control_for_keys; + } + } + } + } + else + { + //check seek control for supporote focuse of input + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + //check parent for supporote focuse of input + parent=(struct HEADER*)seek_control->parent; + if (parent->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + active_control_for_keys=(struct HEADER*)main_parent->global_active_control_for_keys; + if (active_control_for_keys!=NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + active_control_for_keys->ctrl_proc; + + local_service_message.type=MESSAGE_CHANGE_FOCUSE; + active_control_for_keys->flags= + active_control_for_keys->flags & FLAG_FOCUSE_INPUT_OFF; + ControlProc(active_control_for_keys,&local_service_message); + } + + ControlProc=(void (*)(void *Control,struct MESSAGE *message)) + seek_control->ctrl_proc; + local_service_message.type=MESSAGE_SET_FOCUSE; + seek_control->flags=seek_control->flags | FLAG_FOCUSE_INPUT_ON; + ControlProc(seek_control,&local_service_message); + + main_parent->global_active_control_for_keys=(DWORD*)seek_control; + Parent->active_control_for_keys=(DWORD*)seek_control; + } + } + } + } + } + } + + if ((seek_control->flags & FLAG_MOUSE_BLOCKED_ON)==FALSE) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,message); + } + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + + if ((cross==FALSE) && (message->arg3==MOUSE_LEFT_BUTTON_DOWN)) + { + if (active_control_for_keys!=NULL) + {//disable focuse of input for active control of keys + ControlProc=(void (*)(void *Control,struct MESSAGE *message))active_control_for_keys->ctrl_proc; + + local_service_message.type=MESSAGE_CHANGE_FOCUSE; + active_control_for_keys->flags=active_control_for_keys->flags & FLAG_FOCUSE_INPUT_OFF; + ControlProc(active_control_for_keys,&local_service_message); + + main_parent->global_active_control_for_keys=(DWORD*)NULL; + Parent->active_control_for_keys=(DWORD*)NULL; + } + } + + break; + } + case MESSAGE_CHANGE_POSITION_EVENT: + { + seek_control=(struct HEADER *)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,message); + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + break; + } + case MESSAGE_CALL_TIMER_EVENT: + { + seek_control=(struct HEADER *)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,message); + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + break; + } + case MESSAGE_SET_FOCUSE: + { + seek_control=(struct HEADER *)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,message); + break; + } + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + break; + } + case MESSAGE_CHANGE_FOCUSE: + { + seek_control=(struct HEADER *)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + if (seek_control->flags & FLAG_FOCUSE_INPUT_SUPPOROTE) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + ControlProc(seek_control,message); + break; + } + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + break; + } + case MESSAGE_DESTROY_CONTROL: + { + seek_control=(struct HEADER *)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { //befor delet control get next control of parent + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + //send message to control for destroyng child controls + ControlProc(seek_control,message); + DestroyControl(seek_control); + + seek_control=exchange_control; + } + break; + } + case MESSAGE_SET_MAIN_PARENT: + { + seek_control=(struct HEADER *)Parent->child_bk; + while(seek_control!=(struct HEADER*)NULL) + { + ControlProc=(void (*)(void *Control,struct MESSAGE *message))seek_control->ctrl_proc; + //send message to control for destroyng child controls + ControlProc(seek_control,message); + + seek_control->main_parent=(DWORD*)message->arg1; + + exchange_control=(struct HEADER *)seek_control->ctrl_fd; + seek_control=exchange_control; + } + break; + } + default:break; + } + } + Parent->active_control_for_mouse=(DWORD*)active_control_for_mouse; +} + +//--------------------------------------------------------------------------------- +// pack control_child in control_parent for libGUI +//--------------------------------------------------------------------------------- +//add new control for Parent +void PackControls(void *parent,void *Control) +{ + struct HEADER *Parent; + struct HEADER *last_control; + struct HEADER *control; + struct MESSAGE message; + + Parent=(struct HEADER *)parent; + control=(struct HEADER *)Control; + //set control's dependeces + + if (Parent->child_bk==NULL) + { + //create first child control for parent + Parent->child_bk=(DWORD*)control; + Parent->child_fd=(DWORD*)control; + + //init control + control->parent=(DWORD*)Parent; + control->ctrl_bk=(DWORD*)Parent;//last control is parent + control->ctrl_fd=(DWORD*)NULL;//haven't next control + } + else + { + //set new control as endest child control of parent + last_control=(struct HEADER*)Parent->child_fd; + Parent->child_fd=(DWORD*)control; + + last_control->ctrl_fd=(DWORD*)control; + control->ctrl_bk=(DWORD*)last_control; + control->ctrl_fd=(DWORD*)NULL; + control->parent=(DWORD*)Parent; + } + + //finite control's coordinates and size + control->ctrl_x=control->ctrl_x+Parent->ctrl_x; + control->ctrl_y=control->ctrl_y+Parent->ctrl_y; + + if (control->ctrl_sizex<=1) {control->ctrl_sizex=1;} + if (control->ctrl_sizey<=1) {control->ctrl_sizey=1;} + + message.type=(DWORD)MESSAGE_CHANGE_POSITION_EVENT; + message.arg1=Parent->ctrl_x; + message.arg2=Parent->ctrl_y; + //send message change position to child controls + SendMessage(control,&message); + + if (Parent->main_parent!=(DWORD*)NULL) + { + //tell all child controls of main parent who is main parent + message.type=MESSAGE_SET_MAIN_PARENT; + message.arg1=(DWORD)Parent->main_parent; + SendMessage((struct HEADER *)Parent,&message); + } +} + +//--------------------------------------------------------------------------------- +// show/hide controls +//--------------------------------------------------------------------------------- +void ShowControl(void *Control) +{ + struct HEADER *control; + control=(struct HEADER *)Control; + control->flags=control->flags | FLAG_SHOW_CONTROL; +} + +void HideControl(void *Control) +{ + struct HEADER *control; + control=(struct HEADER *)Control; + control->flags=control->flags & FLAG_HIDE_CONTROL; +} + +//--------------------------------------------------------------------------------- +// redraw control +//--------------------------------------------------------------------------------- +void RedrawControl(void *Control) +{ + struct HEADER *control; + struct MESSAGE message; + + control=(struct HEADER*)Control; + ControlProc=(void (*)(void *Control,struct MESSAGE *message))control->ctrl_proc; + message.type=MESSAGE_FULL_REDRAW_ALL; + ControlProc(control,&message); +} + +//--------------------------------------------------------------------------------- +// special redraw of control +//--------------------------------------------------------------------------------- +void SpecialRedrawControl(void *Control) +{ + struct HEADER *control; + struct MESSAGE message; + struct HEADERPARENT *main_parent; + + control=(struct HEADER*)Control; + main_parent=(struct HEADERPARENT*)control->main_parent; + control->flags=control->flags | FLAG_GET_SPECIALIZED_MESSAGE_ON; + + ControlProc=(void (*)(void *Control,struct MESSAGE *message))control->ctrl_proc; + + message.type=MESSAGE_SPECIALIZED; + ControlProc((struct HEADER*)main_parent,&message); +} + +//--------------------------------------------------------------------------------- +// set new size for control +//--------------------------------------------------------------------------------- +void SetControlSizeRequest(void *Control,int new_size_x,int new_size_y) +{ + struct HEADER *control; + struct HEADER *Parent; + + control=(struct HEADER*)Control; + Parent=(struct HEADER*)control->parent; + + control->ctrl_sizex=(DWORD)new_size_x; + control->ctrl_sizey=(DWORD)new_size_y; + + if ((control->ctrl_x+control->ctrl_sizex)>Parent->ctrl_sizex) + {control->ctrl_sizex=Parent->ctrl_sizex-control->ctrl_x;} + + if ((control->ctrl_y+control->ctrl_sizey)>Parent->ctrl_sizey) + {control->ctrl_sizey=Parent->ctrl_sizey-control->ctrl_y;} + + if (control->ctrl_sizex<=1) {control->ctrl_sizex=1;} + if (control->ctrl_sizey<=1) {control->ctrl_sizey=1;} + +} + +//--------------------------------------------------------------------------------- +// get size x of control +//--------------------------------------------------------------------------------- +int GetControlSizeX(void *Control) +{ + struct HEADER *control; + + control=(struct HEADER *)Control; + + return ((int)control->ctrl_sizex); +} + +//--------------------------------------------------------------------------------- +// get size y of control +//--------------------------------------------------------------------------------- +int GetControlSizeY(void *Control) +{ + struct HEADER *control; + + control=(struct HEADER *)Control; + + return ((int)control->ctrl_sizey); +} + +//--------------------------------------------------------------------------------- +// set new size for control +//--------------------------------------------------------------------------------- +void SetControlNewPosition(void *Control,int new_x,int new_y) +{ + struct HEADER *control; + struct HEADER *Parent; + struct MESSAGE message; + parent_t *main_parent; + int old_x; + int old_y; + + control=(struct HEADER*)Control; + /* + main_parent=(parent_t*)control->main_parent; + if (control->parent==(DWORD*)main_parent) + {//check position of child control of main parent + if (new_x+control->ctrl_sizex-1>screen.size_x) return; + if (new_y+control->ctrl_sizey-1>screen.size_y) return; + }*/ + + message.type=(DWORD)MESSAGE_CHANGE_POSITION_EVENT; + message.arg1=(DWORD)(new_x-control->ctrl_x); + message.arg2=(DWORD)(new_y-control->ctrl_y); + + ControlProc=(void (*)(void *Control,struct MESSAGE *message))control->ctrl_proc; + ControlProc(control,&message); +} + +//--------------------------------------------------------------------------------- +// get x position of control +//--------------------------------------------------------------------------------- +int GetControlPositionX(void *Control) +{ + struct HEADER *control; + + control=(struct HEADER *)Control; + + return ((int)control->ctrl_x); +} + +//--------------------------------------------------------------------------------- +// get y position of control +//--------------------------------------------------------------------------------- +int GetControlPositionY(void *Control) +{ + struct HEADER *control; + + control=(struct HEADER *)Control; + + return ((int)control->ctrl_y); +} + +//--------------------------------------------------------------------------------- +// set focuse of input for control +//--------------------------------------------------------------------------------- +void *SetFocuse(void *Control) +{ + struct HEADER *control; + struct HEADERPARENT *main_parent; + struct HEADER *old_control; + struct MESSAGE *message; + + //new active control with focuse + control=(struct HEADER*)Control; + main_parent=(struct HEADERPARENT*)control->main_parent; + + if (main_parent==(struct HEADERPARENT*)NULL) return; + + //old control with focuse + old_control=(struct HEADER*)main_parent->global_active_control_for_keys; + + if (old_control!=(struct HEADER*)NULL) + { + message->type=MESSAGE_CHANGE_FOCUSE; + message->arg1=FALSE; + message->arg2=FALSE; + message->arg3=FALSE; + ControlProc=(void (*)(void *Control,struct MESSAGE *message))old_control->ctrl_proc; + ControlProc(old_control,message); + } + + message->type=MESSAGE_SET_FOCUSE; + message->arg1=FALSE; + message->arg2=FALSE; + message->arg3=FALSE;; + ControlProc=(void (*)(void *Control,struct MESSAGE *message))control->ctrl_proc; + ControlProc(control,message); + + return(old_control); +} + +//--------------------------------------------------------------------------------- +// set callback function for control +//--------------------------------------------------------------------------------- +void *SetCallbackFunction(void *Control,int event_name,void *callback_func,void *callback_func_data) +{ + struct HEADER *control; + struct CALLBACK *seek_callback; + struct CALLBACK *exchange_callback; + struct CALLBACK *new_callback; + + control=(struct HEADER *)Control; + seek_callback=(struct CALLBACK*)control->callback; + + if (seek_callback==(struct CALLBACK *)NULL) + { //callback function creating at first + new_callback=malloc(sizeof(struct CALLBACK)); + control->callback=(DWORD*)new_callback; + new_callback->clb_bk=(DWORD*)control; + new_callback->clb_fd=(DWORD*)NULL; + new_callback->clb_control=(DWORD*)control; + new_callback->connect_event=(DWORD)event_name; + new_callback->func=(DWORD*)callback_func; + new_callback->func_data=(DWORD*)callback_func_data; + new_callback->flags=0x0; + } + else + { + while(seek_callback!=(struct CALLBACK*)NULL) + { + if (seek_callback->clb_fd==(DWORD*)NULL) + {//create new callback control for callback function + new_callback=malloc(sizeof(struct CALLBACK)); + seek_callback->clb_fd=(DWORD*)new_callback; + new_callback->clb_bk=(DWORD*)seek_callback; + new_callback->clb_fd=(DWORD*)NULL; + new_callback->clb_control=(DWORD*)control; + new_callback->connect_event=(DWORD)event_name; + new_callback->func=(DWORD*)callback_func; + new_callback->func_data=(DWORD*)callback_func_data; + new_callback->flags=0x0; + break; + } + exchange_callback=(struct CALLBACK*)seek_callback->clb_fd; + seek_callback=exchange_callback; + } + } +#ifdef DEBUG + printf("\ncreated callback %d for function %d data %d", + (DWORD)new_callback, + (DWORD)callback_func, + (DWORD)callback_func_data); +#endif + + return(new_callback); +} + +//--------------------------------------------------------------------------------- +// block current callback function for control +//--------------------------------------------------------------------------------- +void BlockCallbackFunction(void *Control,void *callback_ID) +{ + struct HEADER *control; + struct CALLBACK *seek_callback; + struct CALLBACK *exchange_callback; + struct CALLBACK *unknown_callback; + + control=(struct HEADER *)Control; + + seek_callback=(struct CALLBACK *)control->callback; + unknown_callback=(struct CALLBACK*)callback_ID; + + while(seek_callback!=(struct CALLBACK*)NULL) + { + if (seek_callback==unknown_callback) + { + unknown_callback->flags=unknown_callback->flags | FLAG_BLOCK_CALLBACK_ON; + break; + } + exchange_callback=(struct CALLBACK*)seek_callback->clb_fd; + seek_callback=exchange_callback; + } + +} + +//--------------------------------------------------------------------------------- +// unblock current callback function for control +//--------------------------------------------------------------------------------- +void UnblockCallbackFunction(void *Control,void *callback_ID) +{ + struct HEADER *control; + struct CALLBACK *seek_callback; + struct CALLBACK *exchange_callback; + struct CALLBACK *unknown_callback; + + control=(struct HEADER *)Control; + + seek_callback=(struct CALLBACK *)control->callback; + unknown_callback=(struct CALLBACK*)callback_ID; + + while(seek_callback!=(struct CALLBACK*)NULL) + { + if (seek_callback==unknown_callback) + { + unknown_callback->flags=unknown_callback->flags & FLAG_BLOCK_CALLBACK_OFF; + break; + } + exchange_callback=(struct CALLBACK*)seek_callback->clb_fd; + seek_callback=exchange_callback; + } +} + +//--------------------------------------------------------------------------------- +// check callback event for control +//--------------------------------------------------------------------------------- +void *ControlCheckCallbackEvent(void *Control,DWORD event) +{ + struct HEADER *control; + struct CALLBACK *seek_callback; + struct CALLBACK *exchange_callback; + + control=(struct HEADER *)Control; + seek_callback=(struct CALLBACK *)control->callback; + + while(seek_callback!=(struct CALLBACK*)NULL) + { + if ((seek_callback->flags & FLAG_BLOCK_CALLBACK_ON)==FALSE) + { + if (seek_callback->connect_event==event) return (seek_callback); + } + exchange_callback=(struct CALLBACK*)seek_callback->clb_fd; + seek_callback=exchange_callback; + } + return(NULL); +} + +//--------------------------------------------------------------------------------- +// set IDL function for libGUI +//--------------------------------------------------------------------------------- +void SetIDL_Function(parent_t *parent,void *function,void *function_data) +{ + parent->IDL_func=(DWORD*)function; + parent->IDL_func_data=(DWORD*)function_data; +} + +//--------------------------------------------------------------------------------- +// destroy IDL function for libGUI +//--------------------------------------------------------------------------------- +void DestroyIDL_Function(parent_t *parent) +{ + parent->IDL_func=(DWORD*)NULL; +} + +//--------------------------------------------------------------------------------- +// initialize libGUI +//--------------------------------------------------------------------------------- +char InitLibGUI() +{ + font_t *font; +//--------------------------------------------------------------------------------- +//---------------------------platform depended part of code------------------------ +//--------------------------------------------------------------------------------- + //set new events mask + gui_ksys_set_events_mask(119); + //set scan codes input mode for keyboard + gui_ksys_set_keyboard_input_mode(1); +//------------------------------------------------------------------------------------ + FontsMeneger.fnt_fd=(DWORD*)NULL; + FontsMeneger.fnt_bk=(DWORD*)NULL; + FontsMeneger.number_fonts=0; + //load default fonts + font=LoadFont("CHAR.MT"); + + if (font==NULL) return (TRUE); + else FontsMeneger.default_font=(DWORD*)font; + + font->flags=font->flags | FONT_FLAG_DEFAULT_FONT_ON; + + return(FALSE); +} + +//--------------------------------------------------------------------------------- +// quit from libGUI loop and destroy all GUI objects +//--------------------------------------------------------------------------------- +void QuitLibGUI(parent_t *window) +{ + font_t *font,*seek_font,*exchange_font; + gui_timer_t *seek_timer,*exchange_timer; + gui_message_t message; + +#ifdef DEBUG + printf("\nbegin free libGUI..."); +#endif + + //destroy controls of parent window + message.type=MESSAGE_DESTROY_CONTROL; + SendMessage((header_t*)window,&message); +#ifdef DEBUG + printf("\ncontrols destroyed"); +#endif + //destroy timers for callback functions + seek_timer=(gui_timer_t*)window->timer_bk; + while(seek_timer!=(gui_timer_t*)NULL) + { + exchange_timer=(gui_timer_t*)seek_timer->tmr_fd; + + DestroyTimerCallbackForFunction(seek_timer); + + seek_timer=exchange_timer; + } +#ifdef DEBUG + printf("\ntimers destroyed"); +#endif + //free arrays of parent window + free(window->message); + free(window->control_for_callback_function); + free(window->callback_for_control_callback); +#ifdef DEBUG + printf("\narrays destroyed"); +#endif + //destroy parent window + free(window); +#ifdef DEBUG + printf("\nparent window destroyed"); +#endif + //destroy fonts cash + + seek_font=(font_t*)FontsMeneger.fnt_bk; + while(seek_font!=(font_t*)NULL) + { + exchange_font=(font_t*)seek_font->fnt_fd; + + free(seek_font->font); + DestroyFont(seek_font); + + seek_font=exchange_font; + } +#ifdef DEBUG + printf("\nfonts destroyed"); + printf("\nexit program..."); +#endif + exit(0); +} + +DWORD LibGUIversion(void) +{ //25.10.09 + return(91025); +} diff --git a/programs/develop/libraries/libGUI/SRC/main_libGUI.inc b/programs/develop/libraries/libGUI/SRC/main_libGUI.inc new file mode 100644 index 0000000000..84d773e0e2 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/main_libGUI.inc @@ -0,0 +1,233 @@ +/* + main meneger loop libGUI library +*/ + +void LibGUImain(parent_t *WindowParent) +{ + DWORD event,key,value; + header_t *control; + gui_message_t *events_message; + gui_timer_t *seek_timer,*exchange_timer; + gui_callbackevent_t *seek_calev,*calev,*exchange_calev; + int i; + char quit; + + + events_message=(struct MESSAGE*)WindowParent->message; + + //tell all child controls of main parent who is main parent + events_message->type=MESSAGE_SET_MAIN_PARENT; + events_message->arg1=(DWORD)WindowParent; + SendMessage((struct HEADER *)WindowParent,events_message); + + //display all created controls in window + gui_draw_window(WindowParent); + events_message->type=MESSAGE_FULL_REDRAW_ALL; + SendMessage((struct HEADER *)WindowParent,events_message); + + events_message->type=0; + + quit=FALSE; + WindowParent->number_callbacks=0; + + while (quit==FALSE) + { + //check for timers + if ((WindowParent->timer_bk!=(DWORD*)NULL) || + (WindowParent->number_timers_for_controls!=0)) {event=gui_ksys_wait_event_with_timeout(1);} + else {event=gui_ksys_wait_event();} + + //get and chack system events + switch(event) + { + case KOLIBRIOS_SYS_EVENT_BUTTON_PRESSED: + { + if (ControlCheckCallbackEvent(WindowParent,DELETE_EVENT)!=NULL) + { + WindowParent->flags |= FLAG_CONNECT_EVENT_ON; + WindowParent->control_for_callback_function[WindowParent->number_callbacks]= + (DWORD*)WindowParent; + WindowParent->callback_for_control_callback[WindowParent->number_callbacks]= + (DWORD*)ControlCheckCallbackEvent(WindowParent,(DWORD)DELETE_EVENT); + WindowParent->number_callbacks++; + } + + quit=TRUE; + break; + } + + case KOLIBRIOS_SYS_EVENT_REDRAW: + { + GetNewWindowSizePos(WindowParent); + SetWindowSizeRequest(WindowParent,WindowParent->ctrl_sizex,WindowParent->ctrl_sizey); + gui_draw_window(WindowParent); + + events_message->type=MESSAGE_FULL_REDRAW_ALL; + SendMessage((struct HEADER *)WindowParent,events_message); + break; + } + + case KOLIBRIOS_SYS_EVENT_KEYS: + { + key=gui_ksys_get_key(); + + + key=key>>8; + + if (key & 128) + { + events_message->arg1=KEY_UP; + events_message->arg2=key & 127; + } + else + { + events_message->arg1=KEY_DOWN; + events_message->arg2=key; + } + + events_message->type=MESSAGE_KEYS_EVENT; + SendMessage((struct HEADER *)WindowParent,events_message); + break; + } + + case KOLIBRIOS_SYS_EVENT_MOUSE: + { + value=gui_ksys_get_window_mouse_coordinates(); + + events_message->type=MESSAGE_MOUSE_EVENT; + events_message->arg2=(value & 0xffff)-screen.y;//y + value=value >>16; + events_message->arg1=value-screen.x;//x + + value=gui_ksys_get_mouse_buttons_state(); + + switch(value) + { + case KOLIBRIOS_SYS_MOUSE_BUTTON_LEFT_DOWN: + { + events_message->arg3=MOUSE_LEFT_BUTTON_DOWN; + break; + } + case KOLIBRIOS_SYS_MOUSE_BUTTON_RIGHT_DOWN: + { + events_message->arg3=MOUSE_RIGHT_BUTTON_DOWN; + break; + } + case KOLIBRIOS_SYS_MOUSE_BUTTON_MIDDLE_DOWN: + { + events_message->arg3=MOUSE_MIDDLE_BUTTON_DOWN; + break; + } + case KOLIBRIOS_SYS_MOUSE_BUTTON_4_DOWN: + { + events_message->arg3=MOUSE_4_BUTTON_DOWN; + break; + } + case KOLIBRIOS_SYS_MOUSE_BUTTON_5_DOWN: + { + events_message->arg3=MOUSE_5_BUTTON_DOWN; + break; + } + default: + { + if (events_message->arg3==MOUSE_LEFT_BUTTON_DOWN) + { + events_message->arg3=MOUSE_LEFT_BUTTON_UP; + break; + } + if (events_message->arg3==MOUSE_RIGHT_BUTTON_DOWN) + { + events_message->arg3=MOUSE_RIGHT_BUTTON_UP; + break; + } + if (events_message->arg3==MOUSE_MIDDLE_BUTTON_DOWN) + { + events_message->arg3=MOUSE_MIDDLE_BUTTON_UP; + break; + } + if (events_message->arg3==MOUSE_4_BUTTON_DOWN) + { + events_message->arg3=MOUSE_4_BUTTON_UP; + break; + } + if (events_message->arg3==MOUSE_5_BUTTON_DOWN) + { + events_message->arg3=MOUSE_5_BUTTON_UP; + break; + } + + break; + } + } + SendMessage((struct HEADER *)WindowParent,events_message); + break; + } + } + + //call functions for events + seek_calev=(struct CALLBACKEVENT*)WindowParent->calev_bk; + while(seek_calev!=(struct CALLBACKEVENT*)NULL) + { + if (seek_calev->event_type==events_message->type) + { + CallbackFunctionForEvent=(void(*)(struct MESSAGE *message,void *data))seek_calev->func; + CallbackFunctionForEvent(events_message,seek_calev->func_data); + } + exchange_calev=(struct CALLBACKEVENT*)seek_calev->calev_fd; + seek_calev=exchange_calev; + } + + + //call timers of controls + if (WindowParent->number_timers_for_controls!=0) + { + events_message->type=(char)MESSAGE_CALL_TIMER_EVENT; + SendMessage((struct HEADER *)WindowParent,events_message); + } + + //call callback functions + for(i=0;inumber_callbacks;i++) + { + control=(struct HEADER*)WindowParent->control_for_callback_function[i]; + //check callback control + if (control!=(header_t*)NULL) + { + if (control->flags & FLAG_CONNECT_EVENT_ON) + { + calev=(struct CALLBACKEVENT*) + WindowParent->callback_for_control_callback[i]; +#ifdef DEBUG + printf("\ntry to call callback %d for function %d data %d", + (DWORD)calev, + (DWORD)calev->func, + (DWORD)calev->func_data); +#endif + + CallbackFunction=(void (*)(header_t *Control,void *data))calev->func; + CallbackFunction(control,calev->func_data); + + control->flags=control->flags & FLAG_CONNECT_EVENT_OFF; + } + } + } + WindowParent->number_callbacks=0; + + //call timers of parent window + seek_timer=(struct TIMER*)WindowParent->timer_bk; + while(seek_timer!=(struct TIMER*)NULL) + { + if (seek_timer->flags & FLAG_TIMER_ON) Timer(seek_timer); + + exchange_timer=(struct TIMER*)seek_timer->tmr_fd; + seek_timer=exchange_timer; + } + + //check for IDL function and call it if enabled + if (WindowParent->IDL_func!=(DWORD*)NULL) + { + IDL_Function=(void(*)(void *data))WindowParent->IDL_func; + IDL_Function(WindowParent->IDL_func_data); + } + + } +} diff --git a/programs/develop/libraries/libGUI/SRC/malloc.inc b/programs/develop/libraries/libGUI/SRC/malloc.inc new file mode 100644 index 0000000000..652a451960 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/malloc.inc @@ -0,0 +1,3994 @@ +/* + This is a version (aka dlmalloc) of malloc/free/realloc written by + Doug Lea and released to the public domain, as explained at + http://creativecommons.org/licenses/publicdomain. Send questions, + comments, complaints, performance data, etc to dl@cs.oswego.edu + +* Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) + + Note: There may be an updated version of this malloc obtainable at + ftp://gee.cs.oswego.edu/pub/misc/malloc.c + Check before installing! + +* Quickstart + + This library is all in one file to simplify the most common usage: + ftp it, compile it (-O3), and link it into another program. All of + the compile-time options default to reasonable values for use on + most platforms. You might later want to step through various + compile-time and dynamic tuning options. + + For convenience, an include file for code using this malloc is at: + ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h + You don't really need this .h file unless you call functions not + defined in your system include files. The .h file contains only the + excerpts from this file needed for using this malloc on ANSI C/C++ + systems, so long as you haven't changed compile-time options about + naming and tuning parameters. If you do, then you can create your + own malloc.h that does include all settings by cutting at the point + indicated below. Note that you may already by default be using a C + library containing a malloc that is based on some version of this + malloc (for example in linux). You might still want to use the one + in this file to customize settings or to avoid overheads associated + with library versions. + +* Vital statistics: + + Supported pointer/size_t representation: 4 or 8 bytes + size_t MUST be an unsigned type of the same width as + pointers. (If you are using an ancient system that declares + size_t as a signed type, or need it to be a different width + than pointers, you can use a previous release of this malloc + (e.g. 2.7.2) supporting these.) + + Alignment: 8 bytes (default) + This suffices for nearly all current machines and C compilers. + However, you can define MALLOC_ALIGNMENT to be wider than this + if necessary (up to 128bytes), at the expense of using more space. + + Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) + 8 or 16 bytes (if 8byte sizes) + Each malloced chunk has a hidden word of overhead holding size + and status information, and additional cross-check word + if FOOTERS is defined. + + Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) + 8-byte ptrs: 32 bytes (including overhead) + + Even a request for zero bytes (i.e., malloc(0)) returns a + pointer to something of the minimum allocatable size. + The maximum overhead wastage (i.e., number of extra bytes + allocated than were requested in malloc) is less than or equal + to the minimum size, except for requests >= mmap_threshold that + are serviced via mmap(), where the worst case wastage is about + 32 bytes plus the remainder from a system page (the minimal + mmap unit); typically 4096 or 8192 bytes. + + Security: static-safe; optionally more or less + The "security" of malloc refers to the ability of malicious + code to accentuate the effects of errors (for example, freeing + space that is not currently malloc'ed or overwriting past the + ends of chunks) in code that calls malloc. This malloc + guarantees not to modify any memory locations below the base of + heap, i.e., static variables, even in the presence of usage + errors. The routines additionally detect most improper frees + and reallocs. All this holds as long as the static bookkeeping + for malloc itself is not corrupted by some other means. This + is only one aspect of security -- these checks do not, and + cannot, detect all possible programming errors. + + If FOOTERS is defined nonzero, then each allocated chunk + carries an additional check word to verify that it was malloced + from its space. These check words are the same within each + execution of a program using malloc, but differ across + executions, so externally crafted fake chunks cannot be + freed. This improves security by rejecting frees/reallocs that + could corrupt heap memory, in addition to the checks preventing + writes to statics that are always on. This may further improve + security at the expense of time and space overhead. (Note that + FOOTERS may also be worth using with MSPACES.) + + By default detected errors cause the program to abort (calling + "abort()"). You can override this to instead proceed past + errors by defining PROCEED_ON_ERROR. In this case, a bad free + has no effect, and a malloc that encounters a bad address + caused by user overwrites will ignore the bad address by + dropping pointers and indices to all known memory. This may + be appropriate for programs that should continue if at all + possible in the face of programming errors, although they may + run out of memory because dropped memory is never reclaimed. + + If you don't like either of these options, you can define + CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything + else. And if if you are sure that your program using malloc has + no errors or vulnerabilities, you can define INSECURE to 1, + which might (or might not) provide a small performance improvement. + + Thread-safety: NOT thread-safe unless USE_LOCKS defined + When USE_LOCKS is defined, each public call to malloc, free, + etc is surrounded with either a pthread mutex or a win32 + spinlock (depending on WIN32). This is not especially fast, and + can be a major bottleneck. It is designed only to provide + minimal protection in concurrent environments, and to provide a + basis for extensions. If you are using malloc in a concurrent + program, consider instead using ptmalloc, which is derived from + a version of this malloc. (See http://www.malloc.de). + + System requirements: Any combination of MORECORE and/or MMAP/MUNMAP + This malloc can use unix sbrk or any emulation (invoked using + the CALL_MORECORE macro) and/or mmap/munmap or any emulation + (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system + memory. On most unix systems, it tends to work best if both + MORECORE and MMAP are enabled. On Win32, it uses emulations + based on VirtualAlloc. It also uses common C library functions + like memset. + + Compliance: I believe it is compliant with the Single Unix Specification + (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably + others as well. + +* Overview of algorithms + + This is not the fastest, most space-conserving, most portable, or + most tunable malloc ever written. However it is among the fastest + while also being among the most space-conserving, portable and + tunable. Consistent balance across these factors results in a good + general-purpose allocator for malloc-intensive programs. + + In most ways, this malloc is a best-fit allocator. Generally, it + chooses the best-fitting existing chunk for a request, with ties + broken in approximately least-recently-used order. (This strategy + normally maintains low fragmentation.) However, for requests less + than 256bytes, it deviates from best-fit when there is not an + exactly fitting available chunk by preferring to use space adjacent + to that used for the previous small request, as well as by breaking + ties in approximately most-recently-used order. (These enhance + locality of series of small allocations.) And for very large requests + (>= 256Kb by default), it relies on system memory mapping + facilities, if supported. (This helps avoid carrying around and + possibly fragmenting memory used only for large chunks.) + + All operations (except malloc_stats and mallinfo) have execution + times that are bounded by a constant factor of the number of bits in + a size_t, not counting any clearing in calloc or copying in realloc, + or actions surrounding MORECORE and MMAP that have times + proportional to the number of non-contiguous regions returned by + system allocation routines, which is often just 1. + + The implementation is not very modular and seriously overuses + macros. Perhaps someday all C compilers will do as good a job + inlining modular code as can now be done by brute-force expansion, + but now, enough of them seem not to. + + Some compilers issue a lot of warnings about code that is + dead/unreachable only on some platforms, and also about intentional + uses of negation on unsigned types. All known cases of each can be + ignored. + + For a longer but out of date high-level description, see + http://gee.cs.oswego.edu/dl/html/malloc.html + +* MSPACES + If MSPACES is defined, then in addition to malloc, free, etc., + this file also defines mspace_malloc, mspace_free, etc. These + are versions of malloc routines that take an "mspace" argument + obtained using create_mspace, to control all internal bookkeeping. + If ONLY_MSPACES is defined, only these versions are compiled. + So if you would like to use this allocator for only some allocations, + and your system malloc for others, you can compile with + ONLY_MSPACES and then do something like... + static mspace mymspace = create_mspace(0,0); // for example + #define mymalloc(bytes) mspace_malloc(mymspace, bytes) + + (Note: If you only need one instance of an mspace, you can instead + use "USE_DL_PREFIX" to relabel the global malloc.) + + You can similarly create thread-local allocators by storing + mspaces as thread-locals. For example: + static __thread mspace tlms = 0; + void* tlmalloc(size_t bytes) { + if (tlms == 0) tlms = create_mspace(0, 0); + return mspace_malloc(tlms, bytes); + } + void tlfree(void* mem) { mspace_free(tlms, mem); } + + Unless FOOTERS is defined, each mspace is completely independent. + You cannot allocate from one and free to another (although + conformance is only weakly checked, so usage errors are not always + caught). If FOOTERS is defined, then each chunk carries around a tag + indicating its originating mspace, and frees are directed to their + originating spaces. + + ------------------------- Compile-time options --------------------------- + +Be careful in setting #define values for numerical constants of type +size_t. On some systems, literal values are not automatically extended +to size_t precision unless they are explicitly casted. + +WIN32 default: defined if _WIN32 defined + Defining WIN32 sets up defaults for MS environment and compilers. + Otherwise defaults are for unix. + +MALLOC_ALIGNMENT default: (size_t)8 + Controls the minimum alignment for malloc'ed chunks. It must be a + power of two and at least 8, even on machines for which smaller + alignments would suffice. It may be defined as larger than this + though. Note however that code and data structures are optimized for + the case of 8-byte alignment. + +MSPACES default: 0 (false) + If true, compile in support for independent allocation spaces. + This is only supported if HAVE_MMAP is true. + +ONLY_MSPACES default: 0 (false) + If true, only compile in mspace versions, not regular versions. + +USE_LOCKS default: 0 (false) + Causes each call to each public routine to be surrounded with + pthread or WIN32 mutex lock/unlock. (If set true, this can be + overridden on a per-mspace basis for mspace versions.) + +FOOTERS default: 0 + If true, provide extra checking and dispatching by placing + information in the footers of allocated chunks. This adds + space and time overhead. + +INSECURE default: 0 + If true, omit checks for usage errors and heap space overwrites. + +USE_DL_PREFIX default: NOT defined + Causes compiler to prefix all public routines with the string 'dl'. + This can be useful when you only want to use this malloc in one part + of a program, using your regular system malloc elsewhere. + +ABORT default: defined as abort() + Defines how to abort on failed checks. On most systems, a failed + check cannot die with an "assert" or even print an informative + message, because the underlying print routines in turn call malloc, + which will fail again. Generally, the best policy is to simply call + abort(). It's not very useful to do more than this because many + errors due to overwriting will show up as address faults (null, odd + addresses etc) rather than malloc-triggered checks, so will also + abort. Also, most compilers know that abort() does not return, so + can better optimize code conditionally calling it. + +PROCEED_ON_ERROR default: defined as 0 (false) + Controls whether detected bad addresses cause them to bypassed + rather than aborting. If set, detected bad arguments to free and + realloc are ignored. And all bookkeeping information is zeroed out + upon a detected overwrite of freed heap space, thus losing the + ability to ever return it from malloc again, but enabling the + application to proceed. If PROCEED_ON_ERROR is defined, the + static variable malloc_corruption_error_count is compiled in + and can be examined to see if errors have occurred. This option + generates slower code than the default abort policy. + +DEBUG default: NOT defined + The DEBUG setting is mainly intended for people trying to modify + this code or diagnose problems when porting to new platforms. + However, it may also be able to better isolate user errors than just + using runtime checks. The assertions in the check routines spell + out in more detail the assumptions and invariants underlying the + algorithms. The checking is fairly extensive, and will slow down + execution noticeably. Calling malloc_stats or mallinfo with DEBUG + set will attempt to check every non-mmapped allocated and free chunk + in the course of computing the summaries. + +ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) + Debugging assertion failures can be nearly impossible if your + version of the assert macro causes malloc to be called, which will + lead to a cascade of further failures, blowing the runtime stack. + ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), + which will usually make debugging easier. + +MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 + The action to take before "return 0" when malloc fails to be able to + return memory because there is none available. + +HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES + True if this system supports sbrk or an emulation of it. + +MORECORE default: sbrk + The name of the sbrk-style system routine to call to obtain more + memory. See below for guidance on writing custom MORECORE + functions. The type of the argument to sbrk/MORECORE varies across + systems. It cannot be size_t, because it supports negative + arguments, so it is normally the signed type of the same width as + size_t (sometimes declared as "intptr_t"). It doesn't much matter + though. Internally, we only call it with arguments less than half + the max value of a size_t, which should work across all reasonable + possibilities, although sometimes generating compiler warnings. See + near the end of this file for guidelines for creating a custom + version of MORECORE. + +MORECORE_CONTIGUOUS default: 1 (true) + If true, take advantage of fact that consecutive calls to MORECORE + with positive arguments always return contiguous increasing + addresses. This is true of unix sbrk. It does not hurt too much to + set it true anyway, since malloc copes with non-contiguities. + Setting it false when definitely non-contiguous saves time + and possibly wasted space it would take to discover this though. + +MORECORE_CANNOT_TRIM default: NOT defined + True if MORECORE cannot release space back to the system when given + negative arguments. This is generally necessary only if you are + using a hand-crafted MORECORE function that cannot handle negative + arguments. + +HAVE_MMAP default: 1 (true) + True if this system supports mmap or an emulation of it. If so, and + HAVE_MORECORE is not true, MMAP is used for all system + allocation. If set and HAVE_MORECORE is true as well, MMAP is + primarily used to directly allocate very large blocks. It is also + used as a backup strategy in cases where MORECORE fails to provide + space from system. Note: A single call to MUNMAP is assumed to be + able to unmap memory that may have be allocated using multiple calls + to MMAP, so long as they are adjacent. + +HAVE_MREMAP default: 1 on linux, else 0 + If true realloc() uses mremap() to re-allocate large blocks and + extend or shrink allocation spaces. + +MMAP_CLEARS default: 1 on unix + True if mmap clears memory so calloc doesn't need to. This is true + for standard unix mmap using /dev/zero. + +USE_BUILTIN_FFS default: 0 (i.e., not used) + Causes malloc to use the builtin ffs() function to compute indices. + Some compilers may recognize and intrinsify ffs to be faster than the + supplied C version. Also, the case of x86 using gcc is special-cased + to an asm instruction, so is already as fast as it can be, and so + this setting has no effect. (On most x86s, the asm version is only + slightly faster than the C version.) + +malloc_getpagesize default: derive from system includes, or 4096. + The system page size. To the extent possible, this malloc manages + memory from the system in page-size units. This may be (and + usually is) a function rather than a constant. This is ignored + if WIN32, where page size is determined using getSystemInfo during + initialization. + +USE_DEV_RANDOM default: 0 (i.e., not used) + Causes malloc to use /dev/random to initialize secure magic seed for + stamping footers. Otherwise, the current time is used. + +NO_MALLINFO default: 0 + If defined, don't compile "mallinfo". This can be a simple way + of dealing with mismatches between system declarations and + those in this file. + +MALLINFO_FIELD_TYPE default: size_t + The type of the fields in the mallinfo struct. This was originally + defined as "int" in SVID etc, but is more usefully defined as + size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set + +REALLOC_ZERO_BYTES_FREES default: not defined + This should be set if a call to realloc with zero bytes should + be the same as a call to free. Some people think it should. Otherwise, + since this malloc returns a unique pointer for malloc(0), so does + realloc(p, 0). + +LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H +LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H +LACKS_STDLIB_H default: NOT defined unless on WIN32 + Define these if your system does not have these header files. + You might need to manually insert some of the declarations they provide. + +DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, + system_info.dwAllocationGranularity in WIN32, + otherwise 64K. + Also settable using mallopt(M_GRANULARITY, x) + The unit for allocating and deallocating memory from the system. On + most systems with contiguous MORECORE, there is no reason to + make this more than a page. However, systems with MMAP tend to + either require or encourage larger granularities. You can increase + this value to prevent system allocation functions to be called so + often, especially if they are slow. The value must be at least one + page and must be a power of two. Setting to 0 causes initialization + to either page size or win32 region size. (Note: In previous + versions of malloc, the equivalent of this option was called + "TOP_PAD") + +DEFAULT_TRIM_THRESHOLD default: 2MB + Also settable using mallopt(M_TRIM_THRESHOLD, x) + The maximum amount of unused top-most memory to keep before + releasing via malloc_trim in free(). Automatic trimming is mainly + useful in long-lived programs using contiguous MORECORE. Because + trimming via sbrk can be slow on some systems, and can sometimes be + wasteful (in cases where programs immediately afterward allocate + more large chunks) the value should be high enough so that your + overall system performance would improve by releasing this much + memory. As a rough guide, you might set to a value close to the + average size of a process (program) running on your system. + Releasing this much memory would allow such a process to run in + memory. Generally, it is worth tuning trim thresholds when a + program undergoes phases where several large chunks are allocated + and released in ways that can reuse each other's storage, perhaps + mixed with phases where there are no such chunks at all. The trim + value must be greater than page size to have any useful effect. To + disable trimming completely, you can set to MAX_SIZE_T. Note that the trick + some people use of mallocing a huge space and then freeing it at + program startup, in an attempt to reserve system memory, doesn't + have the intended effect under automatic trimming, since that memory + will immediately be returned to the system. + +DEFAULT_MMAP_THRESHOLD default: 256K + Also settable using mallopt(M_MMAP_THRESHOLD, x) + The request size threshold for using MMAP to directly service a + request. Requests of at least this size that cannot be allocated + using already-existing space will be serviced via mmap. (If enough + normal freed space already exists it is used instead.) Using mmap + segregates relatively large chunks of memory so that they can be + individually obtained and released from the host system. A request + serviced through mmap is never reused by any other request (at least + not directly; the system may just so happen to remap successive + requests to the same locations). Segregating space in this way has + the benefits that: Mmapped space can always be individually released + back to the system, which helps keep the system level memory demands + of a long-lived program low. Also, mapped memory doesn't become + `locked' between other chunks, as can happen with normally allocated + chunks, which means that even trimming via malloc_trim would not + release them. However, it has the disadvantage that the space + cannot be reclaimed, consolidated, and then used to service later + requests, as happens with normal chunks. The advantages of mmap + nearly always outweigh disadvantages for "large" chunks, but the + value of "large" may vary across systems. The default is an + empirically derived value that works well in most systems. You can + disable mmap by setting to MAX_SIZE_T. + +*/ + +//typedef unsigned int size_t; + +#define MALLOC_ALIGNMENT ((size_t)8U) +#define DEFAULT_MMAP_THRESHOLD ((size_t)32U * (size_t)1024U) +#define NO_MALLINFO 1 +#define HAVE_MMAP 1 +#define MORECORE_CANNOT_TRIM +#define FOOTERS 0 +#define ABORT + + +//#ifndef WIN32 +//#ifdef _WIN32 +//#define WIN32 1 +//#endif /* _WIN32 */ +//#endif /* WIN32 */ +//#ifdef WIN32 +//#define WIN32_LEAN_AND_MEAN +//#include +//#endif /* WIN32 */ +//default settings for compilation for KolibriOS +#define HAVE_MMAP 1 +#define HAVE_MORECORE 0 +#define LACKS_UNISTD_H +#define LACKS_SYS_PARAM_H +#define LACKS_SYS_MMAN_H +#define LACKS_STRING_H +#define LACKS_STRINGS_H +#define LACKS_SYS_TYPES_H +#define LACKS_STDLIB_H +#define LACKS_ERRNO_H +#define LACKS_FCNTL_H +#define MALLOC_FAILURE_ACTION +#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */ +//#endif /* WIN32 */ + +//#if defined(DARWIN) || defined(_DARWIN) +/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ +//#ifndef HAVE_MORECORE +//#define HAVE_MORECORE 0 +//#define HAVE_MMAP 1 +//#endif /* HAVE_MORECORE */ +//#endif /* DARWIN */ + +#ifndef LACKS_SYS_TYPES_H +#include /* For size_t */ +#endif /* LACKS_SYS_TYPES_H */ + +/* The maximum possible size_t value has all bits set */ +#define MAX_SIZE_T (~(size_t)0) + +#ifndef ONLY_MSPACES +#define ONLY_MSPACES 0 +#endif /* ONLY_MSPACES */ +#ifndef MSPACES +#if ONLY_MSPACES +#define MSPACES 1 +#else /* ONLY_MSPACES */ +#define MSPACES 0 +#endif /* ONLY_MSPACES */ +#endif /* MSPACES */ +#ifndef MALLOC_ALIGNMENT +#define MALLOC_ALIGNMENT ((size_t)8U) +#endif /* MALLOC_ALIGNMENT */ +#ifndef FOOTERS +#define FOOTERS 0 +#endif /* FOOTERS */ +#ifndef ABORT +#define ABORT abort() +#endif /* ABORT */ +#ifndef ABORT_ON_ASSERT_FAILURE +#define ABORT_ON_ASSERT_FAILURE 1 +#endif /* ABORT_ON_ASSERT_FAILURE */ +#ifndef PROCEED_ON_ERROR +#define PROCEED_ON_ERROR 0 +#endif /* PROCEED_ON_ERROR */ +#ifndef USE_LOCKS +#define USE_LOCKS 0 +#endif /* USE_LOCKS */ +#ifndef INSECURE +#define INSECURE 0 +#endif /* INSECURE */ +#ifndef HAVE_MMAP +#define HAVE_MMAP 1 +#endif /* HAVE_MMAP */ +#ifndef MMAP_CLEARS +#define MMAP_CLEARS 1 +#endif /* MMAP_CLEARS */ + +//#ifndef HAVE_MREMAP +//#ifdef linux +//#define HAVE_MREMAP 1 +//#else /* linux */ +//#define HAVE_MREMAP 0 +//#endif /* linux */ +//#endif /* HAVE_MREMAP */ + +#ifndef MALLOC_FAILURE_ACTION +#define MALLOC_FAILURE_ACTION errno = ENOMEM; +#endif /* MALLOC_FAILURE_ACTION */ +#ifndef HAVE_MORECORE +#if ONLY_MSPACES +#define HAVE_MORECORE 0 +#else /* ONLY_MSPACES */ +#define HAVE_MORECORE 1 +#endif /* ONLY_MSPACES */ +#endif /* HAVE_MORECORE */ +#if !HAVE_MORECORE +#define MORECORE_CONTIGUOUS 0 +#else /* !HAVE_MORECORE */ +#ifndef MORECORE +#define MORECORE sbrk +#endif /* MORECORE */ +#ifndef MORECORE_CONTIGUOUS +#define MORECORE_CONTIGUOUS 1 +#endif /* MORECORE_CONTIGUOUS */ +#endif /* HAVE_MORECORE */ +#ifndef DEFAULT_GRANULARITY +#if MORECORE_CONTIGUOUS +#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ +#else /* MORECORE_CONTIGUOUS */ +#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) +#endif /* MORECORE_CONTIGUOUS */ +#endif /* DEFAULT_GRANULARITY */ +#ifndef DEFAULT_TRIM_THRESHOLD +#ifndef MORECORE_CANNOT_TRIM +#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) +#else /* MORECORE_CANNOT_TRIM */ +#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T +#endif /* MORECORE_CANNOT_TRIM */ +#endif /* DEFAULT_TRIM_THRESHOLD */ +#ifndef DEFAULT_MMAP_THRESHOLD +#if HAVE_MMAP +#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) +#else /* HAVE_MMAP */ +#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T +#endif /* HAVE_MMAP */ +#endif /* DEFAULT_MMAP_THRESHOLD */ +#ifndef USE_BUILTIN_FFS +#define USE_BUILTIN_FFS 0 +#endif /* USE_BUILTIN_FFS */ +#ifndef USE_DEV_RANDOM +#define USE_DEV_RANDOM 0 +#endif /* USE_DEV_RANDOM */ +#ifndef NO_MALLINFO +#define NO_MALLINFO 0 +#endif /* NO_MALLINFO */ +#ifndef MALLINFO_FIELD_TYPE +#define MALLINFO_FIELD_TYPE size_t +#endif /* MALLINFO_FIELD_TYPE */ + + +/* + mallopt tuning options. SVID/XPG defines four standard parameter + numbers for mallopt, normally defined in malloc.h. None of these + are used in this malloc, so setting them has no effect. But this + malloc does support the following options. +*/ + +#define M_TRIM_THRESHOLD (-1) +#define M_GRANULARITY (-2) +#define M_MMAP_THRESHOLD (-3) + +/* ------------------------ Mallinfo declarations ------------------------ */ + +#if !NO_MALLINFO +#endif /* NO_MALLINFO */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if !ONLY_MSPACES + +/* ------------------- Declarations of public routines ------------------- */ + +#ifndef USE_DL_PREFIX +#define dlcalloc calloc +//#define dlfree free +//#define dlmalloc malloc +#define dlmemalign memalign +#define dlrealloc realloc +#define dlvalloc valloc +#define dlpvalloc pvalloc +#define dlmallinfo mallinfo +#define dlmallopt mallopt +#define dlmalloc_trim malloc_trim +#define dlmalloc_stats malloc_stats +#define dlmalloc_usable_size malloc_usable_size +#define dlmalloc_footprint malloc_footprint +#define dlmalloc_max_footprint malloc_max_footprint +#define dlindependent_calloc independent_calloc +#define dlindependent_comalloc independent_comalloc +#endif /* USE_DL_PREFIX */ + + +/* + malloc(size_t n) + Returns a pointer to a newly allocated chunk of at least n bytes, or + null if no space is available, in which case errno is set to ENOMEM + on ANSI C systems. + + If n is zero, malloc returns a minimum-sized chunk. (The minimum + size is 16 bytes on most 32bit systems, and 32 bytes on 64bit + systems.) Note that size_t is an unsigned type, so calls with + arguments that would be negative if signed are interpreted as + requests for huge amounts of space, which will often fail. The + maximum supported value of n differs across systems, but is in all + cases less than the maximum representable value of a size_t. +*/ +static void* dlmalloc(size_t); + +/* + free(void* p) + Releases the chunk of memory pointed to by p, that had been previously + allocated using malloc or a related routine such as realloc. + It has no effect if p is null. If p was not malloced or already + freed, free(p) will by default cause the current program to abort. +*/ +static void dlfree(void*); + +/* + calloc(size_t n_elements, size_t element_size); + Returns a pointer to n_elements * element_size bytes, with all locations + set to zero. +*/ +static void* dlcalloc(size_t, size_t); + +/* + realloc(void* p, size_t n) + Returns a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. + + The returned pointer may or may not be the same as p. The algorithm + prefers extending p in most cases when possible, otherwise it + employs the equivalent of a malloc-copy-free sequence. + + If p is null, realloc is equivalent to malloc. + + If space is not available, realloc returns null, errno is set (if on + ANSI) and p is NOT freed. + + if n is for fewer bytes than already held by p, the newly unused + space is lopped off and freed if possible. realloc with a size + argument of zero (re)allocates a minimum-sized chunk. + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is not supported. +*/ + +static void* dlrealloc(void*, size_t); + +/* + memalign(size_t alignment, size_t n); + Returns a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument. + + The alignment argument should be a power of two. If the argument is + not a power of two, the nearest greater power is used. + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. +*/ +static void* dlmemalign(size_t, size_t); + +/* + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system. If the pagesize is unknown, 4096 is used. +*/ +static void* dlvalloc(size_t); + +/* + mallopt(int parameter_number, int parameter_value) + Sets tunable parameters The format is to provide a + (parameter-number, parameter-value) pair. mallopt then sets the + corresponding parameter to the argument value if it can (i.e., so + long as the value is meaningful), and returns 1 if successful else + 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, + normally defined in malloc.h. None of these are use in this malloc, + so setting them has no effect. But this malloc also supports other + options in mallopt. See below for details. Briefly, supported + parameters are as follows (listed defaults are for "typical" + configurations). + + Symbol param # default allowed param values + M_TRIM_THRESHOLD -1 2*1024*1024 any (MAX_SIZE_T disables) + M_GRANULARITY -2 page size any power of 2 >= page size + M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) +*/ +static int dlmallopt(int, int); + +/* + malloc_footprint(); + Returns the number of bytes obtained from the system. The total + number of bytes allocated by malloc, realloc etc., is less than this + value. Unlike mallinfo, this function returns only a precomputed + result, so can be called frequently to monitor memory consumption. + Even if locks are otherwise defined, this function does not use them, + so results might not be up to date. +*/ +static size_t dlmalloc_footprint(void); + +/* + malloc_max_footprint(); + Returns the maximum number of bytes obtained from the system. This + value will be greater than current footprint if deallocated space + has been reclaimed by the system. The peak number of bytes allocated + by malloc, realloc etc., is less than this value. Unlike mallinfo, + this function returns only a precomputed result, so can be called + frequently to monitor memory consumption. Even if locks are + otherwise defined, this function does not use them, so results might + not be up to date. +*/ +static size_t dlmalloc_max_footprint(void); + +#if !NO_MALLINFO +#endif /* NO_MALLINFO */ + +/* + independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); + + independent_calloc is similar to calloc, but instead of returning a + single cleared space, it returns an array of pointers to n_elements + independent elements that can hold contents of size elem_size, each + of which starts out cleared, and can be independently freed, + realloc'ed etc. The elements are guaranteed to be adjacently + allocated (this is not guaranteed to occur with multiple callocs or + mallocs), which may also improve cache locality in some + applications. + + The "chunks" argument is optional (i.e., may be null, which is + probably the most typical usage). If it is null, the returned array + is itself dynamically allocated and should also be freed when it is + no longer needed. Otherwise, the chunks array must be of at least + n_elements in length. It is filled in with the pointers to the + chunks. + + In either case, independent_calloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and "chunks" + is null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be individually freed when it is no longer + needed. If you'd like to instead be able to free all at once, you + should instead use regular calloc and assign pointers into this + space to represent elements. (In this case though, you cannot + independently free elements.) + + independent_calloc simplifies and speeds up implementations of many + kinds of pools. It may also be useful when constructing large data + structures that initially have a fixed number of fixed-sized nodes, + but the number is not known at compile time, and some of the nodes + may later need to be freed. For example: + + struct Node { int item; struct Node* next; }; + + struct Node* build_list() { + struct Node** pool; + int n = read_number_of_nodes_needed(); + if (n <= 0) return 0; + pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); + if (pool == 0) die(); + // organize into a linked list... + struct Node* first = pool[0]; + for (i = 0; i < n-1; ++i) + pool[i]->next = pool[i+1]; + free(pool); // Can now free the array (or not, if it is needed later) + return first; + } +*/ +static void** dlindependent_calloc(size_t, size_t, void**); + +/* + independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); + + independent_comalloc allocates, all at once, a set of n_elements + chunks with sizes indicated in the "sizes" array. It returns + an array of pointers to these elements, each of which can be + independently freed, realloc'ed etc. The elements are guaranteed to + be adjacently allocated (this is not guaranteed to occur with + multiple callocs or mallocs), which may also improve cache locality + in some applications. + + The "chunks" argument is optional (i.e., may be null). If it is null + the returned array is itself dynamically allocated and should also + be freed when it is no longer needed. Otherwise, the chunks array + must be of at least n_elements in length. It is filled in with the + pointers to the chunks. + + In either case, independent_comalloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and chunks is + null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be individually freed when it is no longer + needed. If you'd like to instead be able to free all at once, you + should instead use a single regular malloc, and assign pointers at + particular offsets in the aggregate space. (In this case though, you + cannot independently free elements.) + + independent_comallac differs from independent_calloc in that each + element may have a different size, and also that it does not + automatically clear elements. + + independent_comalloc can be used to speed up allocation in cases + where several structs or objects must always be allocated at the + same time. For example: + + struct Head { ... } + struct Foot { ... } + + void send_message(char* msg) { + int msglen = strlen(msg); + size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; + void* chunks[3]; + if (independent_comalloc(3, sizes, chunks) == 0) + die(); + struct Head* head = (struct Head*)(chunks[0]); + char* body = (char*)(chunks[1]); + struct Foot* foot = (struct Foot*)(chunks[2]); + // ... + } + + In general though, independent_comalloc is worth using only for + larger values of n_elements. For small values, you probably won't + detect enough difference from series of malloc calls to bother. + + Overuse of independent_comalloc can increase overall memory usage, + since it cannot reuse existing noncontiguous small chunks that + might be available for some of the elements. +*/ +static void** dlindependent_comalloc(size_t, size_t*, void**); + + +/* + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + */ +static void* dlpvalloc(size_t); + +/* + malloc_trim(size_t pad); + + If possible, gives memory back to the system (via negative arguments + to sbrk) if there is unused memory at the `high' end of the malloc + pool or in unused MMAP segments. You can call this after freeing + large blocks of memory to potentially reduce the system-level memory + requirements of a program. However, it cannot guarantee to reduce + memory. Under some allocation patterns, some large free blocks of + memory will be locked between two used chunks, so they cannot be + given back to the system. + + The `pad' argument to malloc_trim represents the amount of free + trailing space to leave untrimmed. If this argument is zero, only + the minimum amount of memory to maintain internal data structures + will be left. Non-zero arguments can be supplied to maintain enough + trailing space to service future expected allocations without having + to re-obtain memory from the system. + + Malloc_trim returns 1 if it actually released any memory, else 0. +*/ +static int dlmalloc_trim(size_t); + +/* + malloc_usable_size(void* p); + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. malloc_usable_size can be more useful in + debugging and assertions, for example: + + p = malloc(n); + assert(malloc_usable_size(p) >= 256); +*/ +static size_t dlmalloc_usable_size(void*); + +/* + malloc_stats(); + Prints on stderr the amount of space obtained from the system (both + via sbrk and mmap), the maximum amount (which may be more than + current if malloc_trim and/or munmap got called), and the current + number of bytes allocated via malloc (or realloc, etc) but not yet + freed. Note that this is the number of bytes allocated, not the + number requested. It will be larger than the number requested + because of alignment and bookkeeping overhead. Because it includes + alignment wastage as being in use, this figure may be greater than + zero even when no user-level chunks are allocated. + + The reported current and maximum system memory can be inaccurate if + a program makes other calls to system memory allocation functions + (normally sbrk) outside of malloc. + + malloc_stats prints only the most commonly interesting statistics. + More information can be obtained by calling mallinfo. +*/ +static void dlmalloc_stats(void); + +#endif /* ONLY_MSPACES */ + +////////////////////////////////////////////////////////////////////////// +// declaration of melloc,free,realloc +////////////////////////////////////////////////////////////////////////// +void* malloc(size_t size) +{ + void *mem; + + mem=dlmalloc(size); + if (mem!=0) memset(mem,0,size);//cleare befor use + return(mem); +} + +void free(void *mem) +{ + dlfree(mem); +} + +#if MSPACES +#endif /* MSPACES */ + +#ifdef __cplusplus +}; /* end of extern "C" */ +#endif /* __cplusplus */ + +/* + ======================================================================== + To make a fully customizable malloc.h header file, cut everything + above this line, put into file malloc.h, edit to suit, and #include it + on the next line, as well as in programs that use this malloc. + ======================================================================== +*/ + +/* #include "malloc.h" */ + +/*------------------------------ internal #includes ---------------------- */ + +#ifdef WIN32 +#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ +#endif /* WIN32 */ + +//#include /* for printing in malloc_stats */ + +#ifndef LACKS_ERRNO_H +#include /* for MALLOC_FAILURE_ACTION */ +#endif /* LACKS_ERRNO_H */ +#if FOOTERS +#include /* for magic initialization */ +#endif /* FOOTERS */ +#ifndef LACKS_STDLIB_H +#include /* for abort() */ +#endif /* LACKS_STDLIB_H */ + +//#ifdef DEBUG +//#if ABORT_ON_ASSERT_FAILURE +//#define assert(x) if(!(x)) ABORT +//#else /* ABORT_ON_ASSERT_FAILURE */ +//#include +//#endif /* ABORT_ON_ASSERT_FAILURE */ +//#else /* DEBUG */ +#define assert(x) +//#endif /* DEBUG */ + +#ifndef LACKS_STRING_H +#include /* for memset etc */ +#endif /* LACKS_STRING_H */ +#if USE_BUILTIN_FFS +#ifndef LACKS_STRINGS_H +#include /* for ffs */ +#endif /* LACKS_STRINGS_H */ +#endif /* USE_BUILTIN_FFS */ +#if HAVE_MMAP +#ifndef LACKS_SYS_MMAN_H +#include /* for mmap */ +#endif /* LACKS_SYS_MMAN_H */ +#ifndef LACKS_FCNTL_H +#include +#endif /* LACKS_FCNTL_H */ +#endif /* HAVE_MMAP */ +#if HAVE_MORECORE +#endif /* HAVE_MMAP */ + +#ifndef WIN32 +#endif + +/* ------------------- size_t and alignment properties -------------------- */ + +/* The byte and bit size of a size_t */ +#define SIZE_T_SIZE (sizeof(size_t)) +#define SIZE_T_BITSIZE (sizeof(size_t) << 3) + +/* Some constants coerced to size_t */ +/* Annoying but necessary to avoid errors on some plaftorms */ +#define SIZE_T_ZERO ((size_t)0) +#define SIZE_T_ONE ((size_t)1) +#define SIZE_T_TWO ((size_t)2) +#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) +#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) +#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) +#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) + +/* The bit mask value corresponding to MALLOC_ALIGNMENT */ +#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) + +/* True if address a has acceptable alignment */ +#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) + +/* the number of bytes to offset an address to align it */ +#define align_offset(A)\ + ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ + ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) + +/* -------------------------- MMAP preliminaries ------------------------- */ + +/* + If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and + checks to fail so compiler optimizer can delete code rather than + using so many "#if"s. +*/ + + +/* MORECORE and MMAP must return MFAIL on failure */ +#define MFAIL ((void*)(MAX_SIZE_T)) +#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ + +/* HAVE_MMAP */ +#define IS_MMAPPED_BIT (SIZE_T_ONE) +#define USE_MMAP_BIT (SIZE_T_ONE) + + +//////////////////////////////////////////////////////////////// +// KolibriOS specifik +//////////////////////////////////////////////////////////////// +void* gui_ksys_mem_alloc(size_t size) +{ + void *value; + + __asm__ __volatile__( + "int $0x40" + :"=a"(value) + :"a"(68),"b"(12),"c"(size) + :"memory"); + + return (value != 0)? value: MFAIL; +} + +int gui_ksys_mem_free(void *mem,size_t size) +{ + __asm__ __volatile__( + "int $0x40" + : + :"a"(68),"b"(13),"c"(mem) + :"memory"); + + return(0); +} + +//#define gui_ksys_mem_alloc(s) win32mmap(s) +//#define CALL_MUNMAP(a, s) win32munmap((a), (s)) +//#define DIRECT_MMAP(s) win32direct_mmap(s) + + +#if HAVE_MMAP && HAVE_MREMAP +#else /* HAVE_MMAP && HAVE_MREMAP */ +#define CALL_MREMAP(addr, osz, nsz, mv) MFAIL +#endif /* HAVE_MMAP && HAVE_MREMAP */ + +#if HAVE_MORECORE +#else /* HAVE_MORECORE */ +#define CALL_MORECORE(S) MFAIL +#endif /* HAVE_MORECORE */ + +/* mstate bit set if continguous morecore disabled or failed */ +#define USE_NONCONTIGUOUS_BIT (4U) + +/* segment bit set in create_mspace_with_base */ +#define EXTERN_BIT (8U) + + +/* --------------------------- Lock preliminaries ------------------------ */ + +#if USE_LOCKS +#else /* USE_LOCKS */ +#define USE_LOCK_BIT (0U) +#define INITIAL_LOCK(l) +#endif /* USE_LOCKS */ + +#if USE_LOCKS && HAVE_MORECORE +#define ACQUIRE_MORECORE_LOCK() ACQUIRE_LOCK(&morecore_mutex); +#define RELEASE_MORECORE_LOCK() RELEASE_LOCK(&morecore_mutex); +#else /* USE_LOCKS && HAVE_MORECORE */ +#define ACQUIRE_MORECORE_LOCK() +#define RELEASE_MORECORE_LOCK() +#endif /* USE_LOCKS && HAVE_MORECORE */ + +#if USE_LOCKS +#define ACQUIRE_MAGIC_INIT_LOCK() ACQUIRE_LOCK(&magic_init_mutex); +#define RELEASE_MAGIC_INIT_LOCK() RELEASE_LOCK(&magic_init_mutex); +#else /* USE_LOCKS */ +#define ACQUIRE_MAGIC_INIT_LOCK() +#define RELEASE_MAGIC_INIT_LOCK() +#endif /* USE_LOCKS */ + + +/* ----------------------- Chunk representations ------------------------ */ + +/* + (The following includes lightly edited explanations by Colin Plumb.) + + The malloc_chunk declaration below is misleading (but accurate and + necessary). It declares a "view" into memory allowing access to + necessary fields at known offsets from a given base. + + Chunks of memory are maintained using a `boundary tag' method as + originally described by Knuth. (See the paper by Paul Wilson + ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such + techniques.) Sizes of free chunks are stored both in the front of + each chunk and at the end. This makes consolidating fragmented + chunks into bigger chunks fast. The head fields also hold bits + representing whether chunks are free or in use. + + Here are some pictures to make it clearer. They are "exploded" to + show that the state of a chunk can be thought of as extending from + the high 31 bits of the head field of its header through the + prev_foot and PINUSE_BIT bit of the following chunk header. + + A chunk that's in use looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk (if P = 1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 1| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + +- -+ + | | + +- -+ + | : + +- size - sizeof(size_t) available payload bytes -+ + : | + chunk-> +- -+ + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| + | Size of next chunk (may or may not be in use) | +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + And if it's free, it looks like this: + + chunk-> +- -+ + | User payload (must be in use, or we would have merged!) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 0| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Prev pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- size - sizeof(struct chunk) unused bytes -+ + : | + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| + | Size of next chunk (must be in use, or we would have merged)| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- User payload -+ + : | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |0| + +-+ + Note that since we always merge adjacent free chunks, the chunks + adjacent to a free chunk must be in use. + + Given a pointer to a chunk (which can be derived trivially from the + payload pointer) we can, in O(1) time, find out whether the adjacent + chunks are free, and if so, unlink them from the lists that they + are on and merge them with the current chunk. + + Chunks always begin on even word boundaries, so the mem portion + (which is returned to the user) is also on an even word boundary, and + thus at least double-word aligned. + + The P (PINUSE_BIT) bit, stored in the unused low-order bit of the + chunk size (which is always a multiple of two words), is an in-use + bit for the *previous* chunk. If that bit is *clear*, then the + word before the current chunk size contains the previous chunk + size, and can be used to find the front of the previous chunk. + The very first chunk allocated always has this bit set, preventing + access to non-existent (or non-owned) memory. If pinuse is set for + any given chunk, then you CANNOT determine the size of the + previous chunk, and might even get a memory addressing fault when + trying to do so. + + The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of + the chunk size redundantly records whether the current chunk is + inuse. This redundancy enables usage checks within free and realloc, + and reduces indirection when freeing and consolidating chunks. + + Each freshly allocated chunk must have both cinuse and pinuse set. + That is, each allocated chunk borders either a previously allocated + and still in-use chunk, or the base of its memory arena. This is + ensured by making all allocations from the the `lowest' part of any + found chunk. Further, no free chunk physically borders another one, + so each free chunk is known to be preceded and followed by either + inuse chunks or the ends of memory. + + Note that the `foot' of the current chunk is actually represented + as the prev_foot of the NEXT chunk. This makes it easier to + deal with alignments etc but can be very confusing when trying + to extend or adapt this code. + + The exceptions to all this are + + 1. The special chunk `top' is the top-most available chunk (i.e., + the one bordering the end of available memory). It is treated + specially. Top is never included in any bin, is used only if + no other chunk is available, and is released back to the + system if it is very large (see M_TRIM_THRESHOLD). In effect, + the top chunk is treated as larger (and thus less well + fitting) than any other available chunk. The top chunk + doesn't update its trailing size field since there is no next + contiguous chunk that would have to index off it. However, + space is still allocated for it (TOP_FOOT_SIZE) to enable + separation or merging when space is extended. + + 3. Chunks allocated via mmap, which have the lowest-order bit + (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set + PINUSE_BIT in their head fields. Because they are allocated + one-by-one, each must carry its own prev_foot field, which is + also used to hold the offset this chunk has within its mmapped + region, which is needed to preserve alignment. Each mmapped + chunk is trailed by the first two fields of a fake next-chunk + for sake of usage checks. + +*/ + +struct malloc_chunk { + size_t prev_foot; /* Size of previous chunk (if free). */ + size_t head; /* Size and inuse bits. */ + struct malloc_chunk* fd; /* double links -- used only if free. */ + struct malloc_chunk* bk; +}; + +typedef struct malloc_chunk mchunk; +typedef struct malloc_chunk* mchunkptr; +typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ +typedef unsigned int bindex_t; /* Described below */ +typedef unsigned int binmap_t; /* Described below */ +typedef unsigned int flag_t; /* The type of various bit flag sets */ + +/* ------------------- Chunks sizes and alignments ----------------------- */ + +#define MCHUNK_SIZE (sizeof(mchunk)) + +#if FOOTERS +#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +#else /* FOOTERS */ +#define CHUNK_OVERHEAD (SIZE_T_SIZE) +#endif /* FOOTERS */ + +/* MMapped chunks need a second word of overhead ... */ +#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +/* ... and additional padding for fake next-chunk at foot */ +#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) + +/* The smallest size we can malloc is an aligned minimal chunk */ +#define MIN_CHUNK_SIZE\ + ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* conversion from malloc headers to user pointers, and back */ +#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) +#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) +/* chunk associated with aligned address A */ +#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) + +/* Bounds on request (not chunk) sizes. */ +#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) +#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) + +/* pad request bytes into a usable size */ +#define pad_request(req) \ + (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* pad request, checking for minimum (but not maximum) */ +#define request2size(req) \ + (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) + + +/* ------------------ Operations on head and foot fields ----------------- */ + +/* + The head field of a chunk is or'ed with PINUSE_BIT when previous + adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in + use. If the chunk was obtained with mmap, the prev_foot field has + IS_MMAPPED_BIT set, otherwise holding the offset of the base of the + mmapped region to the base of the chunk. +*/ + +#define PINUSE_BIT (SIZE_T_ONE) +#define CINUSE_BIT (SIZE_T_TWO) +#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) + +/* Head value for fenceposts */ +#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) + +/* extraction of fields from head words */ +#define cinuse(p) ((p)->head & CINUSE_BIT) +#define pinuse(p) ((p)->head & PINUSE_BIT) +#define chunksize(p) ((p)->head & ~(INUSE_BITS)) + +#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) +#define clear_cinuse(p) ((p)->head &= ~CINUSE_BIT) + +/* Treat space at ptr +/- offset as a chunk */ +#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) +#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) + +/* Ptr to next or previous physical malloc_chunk. */ +#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~INUSE_BITS))) +#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) + +/* extract next chunk's pinuse bit */ +#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) + +/* Get/set size at footer */ +#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) +#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) + +/* Set size, pinuse bit, and foot */ +#define set_size_and_pinuse_of_free_chunk(p, s)\ + ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) + +/* Set size, pinuse bit, foot, and clear next pinuse */ +#define set_free_with_pinuse(p, s, n)\ + (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) + +#define is_mmapped(p)\ + (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT)) + +/* Get the internal overhead associated with chunk p */ +#define overhead_for(p)\ + (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) + +/* Return true if malloced space is not necessarily cleared */ +#if MMAP_CLEARS +#define calloc_must_clear(p) (!is_mmapped(p)) +#else /* MMAP_CLEARS */ +#define calloc_must_clear(p) (1) +#endif /* MMAP_CLEARS */ + +/* ---------------------- Overlaid data structures ----------------------- */ + +/* + When chunks are not in use, they are treated as nodes of either + lists or trees. + + "Small" chunks are stored in circular doubly-linked lists, and look + like this: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space (may be 0 bytes long) . + . . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Larger chunks are kept in a form of bitwise digital trees (aka + tries) keyed on chunksizes. Because malloc_tree_chunks are only for + free chunks greater than 256 bytes, their size doesn't impose any + constraints on user chunk sizes. Each node looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to left child (child[0]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to right child (child[1]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to parent | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | bin index of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Each tree holding treenodes is a tree of unique chunk sizes. Chunks + of the same size are arranged in a circularly-linked list, with only + the oldest chunk (the next to be used, in our FIFO ordering) + actually in the tree. (Tree members are distinguished by a non-null + parent pointer.) If a chunk with the same size an an existing node + is inserted, it is linked off the existing node using pointers that + work in the same way as fd/bk pointers of small chunks. + + Each tree contains a power of 2 sized range of chunk sizes (the + smallest is 0x100 <= x < 0x180), which is is divided in half at each + tree level, with the chunks in the smaller half of the range (0x100 + <= x < 0x140 for the top nose) in the left subtree and the larger + half (0x140 <= x < 0x180) in the right subtree. This is, of course, + done by inspecting individual bits. + + Using these rules, each node's left subtree contains all smaller + sizes than its right subtree. However, the node at the root of each + subtree has no particular ordering relationship to either. (The + dividing line between the subtree sizes is based on trie relation.) + If we remove the last chunk of a given size from the interior of the + tree, we need to replace it with a leaf node. The tree ordering + rules permit a node to be replaced by any leaf below it. + + The smallest chunk in a tree (a common operation in a best-fit + allocator) can be found by walking a path to the leftmost leaf in + the tree. Unlike a usual binary tree, where we follow left child + pointers until we reach a null, here we follow the right child + pointer any time the left one is null, until we reach a leaf with + both child pointers null. The smallest chunk in the tree will be + somewhere along that path. + + The worst case number of steps to add, find, or remove a node is + bounded by the number of bits differentiating chunks within + bins. Under current bin calculations, this ranges from 6 up to 21 + (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case + is of course much better. +*/ + +struct malloc_tree_chunk { + /* The first four fields must be compatible with malloc_chunk */ + size_t prev_foot; + size_t head; + struct malloc_tree_chunk* fd; + struct malloc_tree_chunk* bk; + + struct malloc_tree_chunk* child[2]; + struct malloc_tree_chunk* parent; + bindex_t index; +}; + +typedef struct malloc_tree_chunk tchunk; +typedef struct malloc_tree_chunk* tchunkptr; +typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ + +/* A little helper macro for trees */ +#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) + +/* ----------------------------- Segments -------------------------------- */ + +/* + Each malloc space may include non-contiguous segments, held in a + list headed by an embedded malloc_segment record representing the + top-most space. Segments also include flags holding properties of + the space. Large chunks that are directly allocated by mmap are not + included in this list. They are instead independently created and + destroyed without otherwise keeping track of them. + + Segment management mainly comes into play for spaces allocated by + MMAP. Any call to MMAP might or might not return memory that is + adjacent to an existing segment. MORECORE normally contiguously + extends the current space, so this space is almost always adjacent, + which is simpler and faster to deal with. (This is why MORECORE is + used preferentially to MMAP when both are available -- see + sys_alloc.) When allocating using MMAP, we don't use any of the + hinting mechanisms (inconsistently) supported in various + implementations of unix mmap, or distinguish reserving from + committing memory. Instead, we just ask for space, and exploit + contiguity when we get it. It is probably possible to do + better than this on some systems, but no general scheme seems + to be significantly better. + + Management entails a simpler variant of the consolidation scheme + used for chunks to reduce fragmentation -- new adjacent memory is + normally prepended or appended to an existing segment. However, + there are limitations compared to chunk consolidation that mostly + reflect the fact that segment processing is relatively infrequent + (occurring only when getting memory from system) and that we + don't expect to have huge numbers of segments: + + * Segments are not indexed, so traversal requires linear scans. (It + would be possible to index these, but is not worth the extra + overhead and complexity for most programs on most platforms.) + * New segments are only appended to old ones when holding top-most + memory; if they cannot be prepended to others, they are held in + different segments. + + Except for the top-most segment of an mstate, each segment record + is kept at the tail of its segment. Segments are added by pushing + segment records onto the list headed by &mstate.seg for the + containing mstate. + + Segment flags control allocation/merge/deallocation policies: + * If EXTERN_BIT set, then we did not allocate this segment, + and so should not try to deallocate or merge with others. + (This currently holds only for the initial segment passed + into create_mspace_with_base.) + * If IS_MMAPPED_BIT set, the segment may be merged with + other surrounding mmapped segments and trimmed/de-allocated + using munmap. + * If neither bit is set, then the segment was obtained using + MORECORE so can be merged with surrounding MORECORE'd segments + and deallocated/trimmed using MORECORE with negative arguments. +*/ + +struct malloc_segment { + char* base; /* base address */ + size_t size; /* allocated size */ + struct malloc_segment* next; /* ptr to next segment */ + flag_t sflags; /* mmap and extern flag */ +}; + +#define is_mmapped_segment(S) ((S)->sflags & IS_MMAPPED_BIT) +#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) + +typedef struct malloc_segment msegment; +typedef struct malloc_segment* msegmentptr; + +/* ---------------------------- malloc_state ----------------------------- */ + +/* + A malloc_state holds all of the bookkeeping for a space. + The main fields are: + + Top + The topmost chunk of the currently active segment. Its size is + cached in topsize. The actual size of topmost space is + topsize+TOP_FOOT_SIZE, which includes space reserved for adding + fenceposts and segment records if necessary when getting more + space from the system. The size at which to autotrim top is + cached from mparams in trim_check, except that it is disabled if + an autotrim fails. + + Designated victim (dv) + This is the preferred chunk for servicing small requests that + don't have exact fits. It is normally the chunk split off most + recently to service another small request. Its size is cached in + dvsize. The link fields of this chunk are not maintained since it + is not kept in a bin. + + SmallBins + An array of bin headers for free chunks. These bins hold chunks + with sizes less than MIN_LARGE_SIZE bytes. Each bin contains + chunks of all the same size, spaced 8 bytes apart. To simplify + use in double-linked lists, each bin header acts as a malloc_chunk + pointing to the real first node, if it exists (else pointing to + itself). This avoids special-casing for headers. But to avoid + waste, we allocate only the fd/bk pointers of bins, and then use + repositioning tricks to treat these as the fields of a chunk. + + TreeBins + Treebins are pointers to the roots of trees holding a range of + sizes. There are 2 equally spaced treebins for each power of two + from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything + larger. + + Bin maps + There is one bit map for small bins ("smallmap") and one for + treebins ("treemap). Each bin sets its bit when non-empty, and + clears the bit when empty. Bit operations are then used to avoid + bin-by-bin searching -- nearly all "search" is done without ever + looking at bins that won't be selected. The bit maps + conservatively use 32 bits per map word, even if on 64bit system. + For a good description of some of the bit-based techniques used + here, see Henry S. Warren Jr's book "Hacker's Delight" (and + supplement at http://hackersdelight.org/). Many of these are + intended to reduce the branchiness of paths through malloc etc, as + well as to reduce the number of memory locations read or written. + + Segments + A list of segments headed by an embedded malloc_segment record + representing the initial space. + + Address check support + The least_addr field is the least address ever obtained from + MORECORE or MMAP. Attempted frees and reallocs of any address less + than this are trapped (unless INSECURE is defined). + + Magic tag + A cross-check field that should always hold same value as mparams.magic. + + Flags + Bits recording whether to use MMAP, locks, or contiguous MORECORE + + Statistics + Each space keeps track of current and maximum system memory + obtained via MORECORE or MMAP. + + Locking + If USE_LOCKS is defined, the "mutex" lock is acquired and released + around every public call using this mspace. +*/ + +/* Bin types, widths and sizes */ +#define NSMALLBINS (32U) +#define NTREEBINS (32U) +#define SMALLBIN_SHIFT (3U) +#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) +#define TREEBIN_SHIFT (8U) +#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) +#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) +#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) + +struct malloc_state { + binmap_t smallmap; + binmap_t treemap; + size_t dvsize; + size_t topsize; + char* least_addr; + mchunkptr dv; + mchunkptr top; + size_t trim_check; + size_t magic; + mchunkptr smallbins[(NSMALLBINS+1)*2]; + tbinptr treebins[NTREEBINS]; + size_t footprint; + size_t max_footprint; + flag_t mflags; +#if USE_LOCKS + MLOCK_T mutex; /* locate lock among fields that rarely change */ +#endif /* USE_LOCKS */ + msegment seg; +}; + +typedef struct malloc_state* mstate; + +/* ------------- Global malloc_state and malloc_params ------------------- */ + +/* + malloc_params holds global properties, including those that can be + dynamically set using mallopt. There is a single instance, mparams, + initialized in init_mparams. +*/ + +struct malloc_params { + size_t magic; + size_t page_size; + size_t granularity; + size_t mmap_threshold; + size_t trim_threshold; + flag_t default_mflags; +}; + +static struct malloc_params mparams; + +/* The global malloc_state used for all non-"mspace" calls */ +static struct malloc_state _gm_; +#define gm (&_gm_) +#define is_global(M) ((M) == &_gm_) +#define is_initialized(M) ((M)->top != 0) + +/* -------------------------- system alloc setup ------------------------- */ + +/* Operations on mflags */ + +#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) +#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) +#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) + +#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) +#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) +#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) + +#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) +#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) + +#define set_lock(M,L)\ + ((M)->mflags = (L)?\ + ((M)->mflags | USE_LOCK_BIT) :\ + ((M)->mflags & ~USE_LOCK_BIT)) + +/* page-align a size */ +#define page_align(S)\ + (((S) + (mparams.page_size)) & ~(mparams.page_size - SIZE_T_ONE)) + +/* granularity-align a size */ +#define granularity_align(S)\ + (((S) + (mparams.granularity)) & ~(mparams.granularity - SIZE_T_ONE)) + +#define is_page_aligned(S)\ + (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) +#define is_granularity_aligned(S)\ + (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) + +/* True if segment S holds address A */ +#define segment_holds(S, A)\ + ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) + +/* Return segment holding given address */ +static msegmentptr segment_holding(mstate m, char* addr) { + msegmentptr sp = &m->seg; + for (;;) { + if (addr >= sp->base && addr < sp->base + sp->size) + return sp; + if ((sp = sp->next) == 0) + return 0; + } +} + +/* Return true if segment contains a segment link */ +static int has_segment_link(mstate m, msegmentptr ss) { + msegmentptr sp = &m->seg; + for (;;) { + if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) + return 1; + if ((sp = sp->next) == 0) + return 0; + } +} + +#ifndef MORECORE_CANNOT_TRIM +#define should_trim(M,s) ((s) > (M)->trim_check) +#else /* MORECORE_CANNOT_TRIM */ +#define should_trim(M,s) (0) +#endif /* MORECORE_CANNOT_TRIM */ + +/* + TOP_FOOT_SIZE is padding at the end of a segment, including space + that may be needed to place segment records and fenceposts when new + noncontiguous segments are added. +*/ +#define TOP_FOOT_SIZE\ + (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) + + +/* ------------------------------- Hooks -------------------------------- */ + +/* + PREACTION should be defined to return 0 on success, and nonzero on + failure. If you are not using locking, you can redefine these to do + anything you like. +*/ + +#if USE_LOCKS + +/* Ensure locks are initialized */ +#define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams()) + +#define PREACTION(M) ((GLOBALLY_INITIALIZE() || use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) +#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } +#else /* USE_LOCKS */ + +#ifndef PREACTION +#define PREACTION(M) (0) +#endif /* PREACTION */ + +#ifndef POSTACTION +#define POSTACTION(M) +#endif /* POSTACTION */ + +#endif /* USE_LOCKS */ + +/* + CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. + USAGE_ERROR_ACTION is triggered on detected bad frees and + reallocs. The argument p is an address that might have triggered the + fault. It is ignored by the two predefined actions, but might be + useful in custom actions that try to help diagnose errors. +*/ + +#if PROCEED_ON_ERROR + +/* A count of the number of corruption errors causing resets */ +int malloc_corruption_error_count; + +/* default corruption action */ +static void reset_on_error(mstate m); + +#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) +#define USAGE_ERROR_ACTION(m, p) + +#else /* PROCEED_ON_ERROR */ + +#ifndef CORRUPTION_ERROR_ACTION +#define CORRUPTION_ERROR_ACTION(m) ABORT +#endif /* CORRUPTION_ERROR_ACTION */ + +#ifndef USAGE_ERROR_ACTION +#define USAGE_ERROR_ACTION(m,p) ABORT +#endif /* USAGE_ERROR_ACTION */ + +#endif /* PROCEED_ON_ERROR */ + +/* -------------------------- Debugging setup ---------------------------- */ + +//#ifdef !DEBUG +#define check_free_chunk(M,P) +#define check_inuse_chunk(M,P) +#define check_malloced_chunk(M,P,N) +#define check_mmapped_chunk(M,P) +#define check_malloc_state(M) +#define check_top_chunk(M,P) + +//#else /* DEBUG */ +//#define check_free_chunk(M,P) do_check_free_chunk(M,P) +//#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) +//#define check_top_chunk(M,P) do_check_top_chunk(M,P) +//#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) +//#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) +//#define check_malloc_state(M) do_check_malloc_state(M) + +//static void do_check_any_chunk(mstate m, mchunkptr p); +//static void do_check_top_chunk(mstate m, mchunkptr p); +//static void do_check_mmapped_chunk(mstate m, mchunkptr p); +//static void do_check_inuse_chunk(mstate m, mchunkptr p); +//static void do_check_free_chunk(mstate m, mchunkptr p); +//static void do_check_malloced_chunk(mstate m, void* mem, size_t s); +//static void do_check_tree(mstate m, tchunkptr t); +//static void do_check_treebin(mstate m, bindex_t i); +//static void do_check_smallbin(mstate m, bindex_t i); +//static void do_check_malloc_state(mstate m); +//static int bin_find(mstate m, mchunkptr x); +//static size_t traverse_and_check(mstate m); +//#endif /* DEBUG */ + + +/* ---------------------------- Indexing Bins ---------------------------- */ + +#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) +#define small_index(s) ((s) >> SMALLBIN_SHIFT) +#define small_index2size(i) ((i) << SMALLBIN_SHIFT) +#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) + +/* addressing by index. See above about smallbin repositioning */ +#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) +#define treebin_at(M,i) (&((M)->treebins[i])) + +/* assign tree index for size S to variable I */ +#if defined(__GNUC__) && defined(i386) +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K;\ + __asm__("bsrl %1,%0\n\t" : "=r" (K) : "rm" (X));\ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} +#else /* GNUC */ +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int Y = (unsigned int)X;\ + unsigned int N = ((Y - 0x100) >> 16) & 8;\ + unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ + N += K;\ + N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ + K = 14 - N + ((Y <<= K) >> 15);\ + I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ + }\ +} +#endif /* GNUC */ + +/* Bit representing maximum resolved size in a treebin at i */ +#define bit_for_tree_index(i) \ + (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) + +/* Shift placing maximum resolved bit in a treebin at i as sign bit */ +#define leftshift_for_tree_index(i) \ + ((i == NTREEBINS-1)? 0 : \ + ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) + +/* The size of the smallest chunk held in bin with index i */ +#define minsize_for_tree_index(i) \ + ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ + (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) + + +/* ------------------------ Operations on bin maps ----------------------- */ + +/* bit corresponding to given index */ +#define idx2bit(i) ((binmap_t)(1) << (i)) + +/* Mark/Clear bits with given index */ +#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) +#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) +#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) + +#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) +#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) +#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) + +/* index corresponding to given bit */ + +#if defined(__GNUC__) && defined(i386) +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + __asm__("bsfl %1,%0\n\t" : "=r" (J) : "rm" (X));\ + I = (bindex_t)J;\ +} + +#else /* GNUC */ +#if USE_BUILTIN_FFS +#define compute_bit2idx(X, I) I = ffs(X)-1 + +#else /* USE_BUILTIN_FFS */ +#define compute_bit2idx(X, I)\ +{\ + unsigned int Y = X - 1;\ + unsigned int K = Y >> (16-4) & 16;\ + unsigned int N = K; Y >>= K;\ + N += K = Y >> (8-3) & 8; Y >>= K;\ + N += K = Y >> (4-2) & 4; Y >>= K;\ + N += K = Y >> (2-1) & 2; Y >>= K;\ + N += K = Y >> (1-0) & 1; Y >>= K;\ + I = (bindex_t)(N + Y);\ +} +#endif /* USE_BUILTIN_FFS */ +#endif /* GNUC */ + +/* isolate the least set bit of a bitmap */ +#define least_bit(x) ((x) & -(x)) + +/* mask with all bits to left of least bit of x on */ +#define left_bits(x) ((x<<1) | -(x<<1)) + +/* mask with all bits to left of or equal to least bit of x on */ +#define same_or_left_bits(x) ((x) | -(x)) + + +/* ----------------------- Runtime Check Support ------------------------- */ + +/* + For security, the main invariant is that malloc/free/etc never + writes to a static address other than malloc_state, unless static + malloc_state itself has been corrupted, which cannot occur via + malloc (because of these checks). In essence this means that we + believe all pointers, sizes, maps etc held in malloc_state, but + check all of those linked or offsetted from other embedded data + structures. These checks are interspersed with main code in a way + that tends to minimize their run-time cost. + + When FOOTERS is defined, in addition to range checking, we also + verify footer fields of inuse chunks, which can be used guarantee + that the mstate controlling malloc/free is intact. This is a + streamlined version of the approach described by William Robertson + et al in "Run-time Detection of Heap-based Overflows" LISA'03 + http://www.usenix.org/events/lisa03/tech/robertson.html The footer + of an inuse chunk holds the xor of its mstate and a random seed, + that is checked upon calls to free() and realloc(). This is + (probablistically) unguessable from outside the program, but can be + computed by any code successfully malloc'ing any chunk, so does not + itself provide protection against code that has already broken + security through some other means. Unlike Robertson et al, we + always dynamically check addresses of all offset chunks (previous, + next, etc). This turns out to be cheaper than relying on hashes. +*/ + +#if !INSECURE +/* Check if address a is at least as high as any from MORECORE or MMAP */ +#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) +/* Check if address of next chunk n is higher than base chunk p */ +#define ok_next(p, n) ((char*)(p) < (char*)(n)) +/* Check if p has its cinuse bit on */ +#define ok_cinuse(p) cinuse(p) +/* Check if p has its pinuse bit on */ +#define ok_pinuse(p) pinuse(p) + +#else /* !INSECURE */ +#define ok_address(M, a) (1) +#define ok_next(b, n) (1) +#define ok_cinuse(p) (1) +#define ok_pinuse(p) (1) +#endif /* !INSECURE */ + +#if (FOOTERS && !INSECURE) +/* Check if (alleged) mstate m has expected magic field */ +#define ok_magic(M) ((M)->magic == mparams.magic) +#else /* (FOOTERS && !INSECURE) */ +#define ok_magic(M) (1) +#endif /* (FOOTERS && !INSECURE) */ + + +/* In gcc, use __builtin_expect to minimize impact of checks */ +#if !INSECURE +//#if defined(__GNUC__) && __GNUC__ >= 3 +//#define RTCHECK(e) __builtin_expect(e, 1) +//#else /* GNUC */ +#define RTCHECK(e) (e) +//#endif /* GNUC */ +//#else /* !INSECURE */ +//#define RTCHECK(e) (1) +#endif /* !INSECURE */ + +/* macros to set up inuse chunks with or without footers */ + +#if !FOOTERS + +#define mark_inuse_foot(M,p,s) + +/* Set cinuse bit and pinuse bit of next chunk */ +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set size, cinuse and pinuse bit of this chunk */ +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) + +#else /* FOOTERS */ + +/* Set foot of inuse chunk to be xor of mstate and seed */ +#define mark_inuse_foot(M,p,s)\ + (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) + +#define get_mstate_for(p)\ + ((mstate)(((mchunkptr)((char*)(p) +\ + (chunksize(p))))->prev_foot ^ mparams.magic)) + +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ + mark_inuse_foot(M,p,s)) + +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ + mark_inuse_foot(M,p,s)) + +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + mark_inuse_foot(M, p, s)) + +#endif /* !FOOTERS */ + +/* ---------------------------- setting mparams -------------------------- */ + +/* Initialize mparams */ +static int init_mparams(void) { + if (mparams.page_size == 0) { + size_t s; + + mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; + mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; +#if MORECORE_CONTIGUOUS + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; +#else /* MORECORE_CONTIGUOUS */ + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; +#endif /* MORECORE_CONTIGUOUS */ + +#if (FOOTERS && !INSECURE) + { +#if USE_DEV_RANDOM + int fd; + unsigned char buf[sizeof(size_t)]; + /* Try to use /dev/urandom, else fall back on using time */ + if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && + read(fd, buf, sizeof(buf)) == sizeof(buf)) { + s = *((size_t *) buf); + close(fd); + } + else +#endif /* USE_DEV_RANDOM */ + s = (size_t)(time(0) ^ (size_t)0x55555555U); + + s |= (size_t)8U; /* ensure nonzero */ + s &= ~(size_t)7U; /* improve chances of fault for bad values */ + + } +#else /* (FOOTERS && !INSECURE) */ + s = (size_t)0x58585858U; +#endif /* (FOOTERS && !INSECURE) */ + ACQUIRE_MAGIC_INIT_LOCK(); + if (mparams.magic == 0) { + mparams.magic = s; + /* Set up lock for main malloc area */ + INITIAL_LOCK(&gm->mutex); + gm->mflags = mparams.default_mflags; + } + RELEASE_MAGIC_INIT_LOCK(); + +//#ifndef WIN32 +// mparams.page_size = 4096; +// mparams.granularity = ((DEFAULT_GRANULARITY != 0)? +// DEFAULT_GRANULARITY : mparams.page_size); +//#else /* WIN32 */ +// { + mparams.page_size = 4096; + mparams.granularity = 16384; +// } +//#endif /* WIN32 */ + + /* Sanity-check configuration: + size_t must be unsigned and as wide as pointer type. + ints must be at least 4 bytes. + alignment must be at least 8. + Alignment, min chunk size, and page size must all be powers of 2. + */ + if ((sizeof(size_t) != sizeof(char*)) || + (MAX_SIZE_T < MIN_CHUNK_SIZE) || + (sizeof(int) < 4) || + (MALLOC_ALIGNMENT < (size_t)8U) || + ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || + ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || + ((mparams.granularity & (mparams.granularity-SIZE_T_ONE)) != 0) || + ((mparams.page_size & (mparams.page_size-SIZE_T_ONE)) != 0)) + ABORT; + } + return 0; +} + +/* support for mallopt */ +static int change_mparam(int param_number, int value) { + size_t val = (size_t)value; + init_mparams(); + switch(param_number) { + case M_TRIM_THRESHOLD: + mparams.trim_threshold = val; + return 1; + case M_GRANULARITY: + if (val >= mparams.page_size && ((val & (val-1)) == 0)) { + mparams.granularity = val; + return 1; + } + else + return 0; + case M_MMAP_THRESHOLD: + mparams.mmap_threshold = val; + return 1; + default: + return 0; + } +} + +#ifdef DEBUG +#endif /* DEBUG */ + +/* ----------------------------- statistics ------------------------------ */ + +#if !NO_MALLINFO +#endif /* !NO_MALLINFO */ + +/* ----------------------- Operations on smallbins ----------------------- */ + +/* + Various forms of linking and unlinking are defined as macros. Even + the ones for trees, which are very long but have very short typical + paths. This is ugly but reduces reliance on inlining support of + compilers. +*/ + +/* Link a free chunk into a smallbin */ +#define insert_small_chunk(M, P, S) {\ + bindex_t I = small_index(S);\ + mchunkptr B = smallbin_at(M, I);\ + mchunkptr F = B;\ + assert(S >= MIN_CHUNK_SIZE);\ + if (!smallmap_is_marked(M, I))\ + mark_smallmap(M, I);\ + else if (RTCHECK(ok_address(M, B->fd)))\ + F = B->fd;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + B->fd = P;\ + F->bk = P;\ + P->fd = F;\ + P->bk = B;\ +} + +/* Unlink a chunk from a smallbin */ +#define unlink_small_chunk(M, P, S) {\ + mchunkptr F = P->fd;\ + mchunkptr B = P->bk;\ + bindex_t I = small_index(S);\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (F == B)\ + clear_smallmap(M, I);\ + else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\ + (B == smallbin_at(M,I) || ok_address(M, B)))) {\ + F->bk = B;\ + B->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + +/* Unlink the first chunk from a smallbin */ +#define unlink_first_small_chunk(M, B, P, I) {\ + mchunkptr F = P->fd;\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (B == F)\ + clear_smallmap(M, I);\ + else if (RTCHECK(ok_address(M, F))) {\ + B->fd = F;\ + F->bk = B;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + +/* Replace dv node, binning the old one */ +/* Used only when dvsize known to be small */ +#define replace_dv(M, P, S) {\ + size_t DVS = M->dvsize;\ + if (DVS != 0) {\ + mchunkptr DV = M->dv;\ + assert(is_small(DVS));\ + insert_small_chunk(M, DV, DVS);\ + }\ + M->dvsize = S;\ + M->dv = P;\ +} + +/* ------------------------- Operations on trees ------------------------- */ + +/* Insert chunk into tree */ +#define insert_large_chunk(M, X, S) {\ + tbinptr* H;\ + bindex_t I;\ + compute_tree_index(S, I);\ + H = treebin_at(M, I);\ + X->index = I;\ + X->child[0] = X->child[1] = 0;\ + if (!treemap_is_marked(M, I)) {\ + mark_treemap(M, I);\ + *H = X;\ + X->parent = (tchunkptr)H;\ + X->fd = X->bk = X;\ + }\ + else {\ + tchunkptr T = *H;\ + size_t K = S << leftshift_for_tree_index(I);\ + for (;;) {\ + if (chunksize(T) != S) {\ + tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ + K <<= 1;\ + if (*C != 0)\ + T = *C;\ + else if (RTCHECK(ok_address(M, C))) {\ + *C = X;\ + X->parent = T;\ + X->fd = X->bk = X;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + else {\ + tchunkptr F = T->fd;\ + if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ + T->fd = F->bk = X;\ + X->fd = F;\ + X->bk = T;\ + X->parent = 0;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + }\ + }\ +} + +/* + Unlink steps: + + 1. If x is a chained node, unlink it from its same-sized fd/bk links + and choose its bk node as its replacement. + 2. If x was the last node of its size, but not a leaf node, it must + be replaced with a leaf node (not merely one with an open left or + right), to make sure that lefts and rights of descendents + correspond properly to bit masks. We use the rightmost descendent + of x. We could use any other leaf, but this is easy to locate and + tends to counteract removal of leftmosts elsewhere, and so keeps + paths shorter than minimally guaranteed. This doesn't loop much + because on average a node in a tree is near the bottom. + 3. If x is the base of a chain (i.e., has parent links) relink + x's parent and children to x's replacement (or null if none). +*/ + +#define unlink_large_chunk(M, X) {\ + tchunkptr XP = X->parent;\ + tchunkptr R;\ + if (X->bk != X) {\ + tchunkptr F = X->fd;\ + R = X->bk;\ + if (RTCHECK(ok_address(M, F))) {\ + F->bk = R;\ + R->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else {\ + tchunkptr* RP;\ + if (((R = *(RP = &(X->child[1]))) != 0) ||\ + ((R = *(RP = &(X->child[0]))) != 0)) {\ + tchunkptr* CP;\ + while ((*(CP = &(R->child[1])) != 0) ||\ + (*(CP = &(R->child[0])) != 0)) {\ + R = *(RP = CP);\ + }\ + if (RTCHECK(ok_address(M, RP)))\ + *RP = 0;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + }\ + if (XP != 0) {\ + tbinptr* H = treebin_at(M, X->index);\ + if (X == *H) {\ + if ((*H = R) == 0) \ + clear_treemap(M, X->index);\ + }\ + else if (RTCHECK(ok_address(M, XP))) {\ + if (XP->child[0] == X) \ + XP->child[0] = R;\ + else \ + XP->child[1] = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + if (R != 0) {\ + if (RTCHECK(ok_address(M, R))) {\ + tchunkptr C0, C1;\ + R->parent = XP;\ + if ((C0 = X->child[0]) != 0) {\ + if (RTCHECK(ok_address(M, C0))) {\ + R->child[0] = C0;\ + C0->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + if ((C1 = X->child[1]) != 0) {\ + if (RTCHECK(ok_address(M, C1))) {\ + R->child[1] = C1;\ + C1->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ +} + +/* Relays to large vs small bin operations */ + +#define insert_chunk(M, P, S)\ + if (is_small(S)) insert_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } + +#define unlink_chunk(M, P, S)\ + if (is_small(S)) unlink_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } + + +/* Relays to internal calls to malloc/free from realloc, memalign etc */ + +#if ONLY_MSPACES +#define internal_malloc(m, b) mspace_malloc(m, b) +#define internal_free(m, mem) mspace_free(m,mem); +#else /* ONLY_MSPACES */ +#if MSPACES +#define internal_malloc(m, b)\ + (m == gm)? dlmalloc(b) : mspace_malloc(m, b) +#define internal_free(m, mem)\ + if (m == gm) dlfree(mem); else mspace_free(m,mem); +#else /* MSPACES */ +#define internal_malloc(m, b) dlmalloc(b) +#define internal_free(m, mem) dlfree(mem) +#endif /* MSPACES */ +#endif /* ONLY_MSPACES */ + +/* ----------------------- Direct-mmapping chunks ----------------------- */ + +/* + Directly mmapped chunks are set up with an offset to the start of + the mmapped region stored in the prev_foot field of the chunk. This + allows reconstruction of the required argument to MUNMAP when freed, + and also allows adjustment of the returned chunk to meet alignment + requirements (especially in memalign). There is also enough space + allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain + the PINUSE bit so frees can be checked. +*/ + +/* Malloc using mmap */ +static void* mmap_alloc(mstate m, size_t nb) { + size_t mmsize = granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + if (mmsize > nb) { /* Check for wrap around 0 */ + char* mm = (char*)(gui_ksys_mem_alloc(mmsize)); + if (mm != CMFAIL) { + size_t offset = align_offset(chunk2mem(mm)); + size_t psize = mmsize - offset - MMAP_FOOT_PAD; + mchunkptr p = (mchunkptr)(mm + offset); + p->prev_foot = offset | IS_MMAPPED_BIT; + (p)->head = (psize|CINUSE_BIT); + mark_inuse_foot(m, p, psize); + chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; + + if (mm < m->least_addr) + m->least_addr = mm; + if ((m->footprint += mmsize) > m->max_footprint) + m->max_footprint = m->footprint; + assert(is_aligned(chunk2mem(p))); + check_mmapped_chunk(m, p); + return chunk2mem(p); + } + } + return 0; +} + +/* Realloc using mmap */ +static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) { + size_t oldsize = chunksize(oldp); + if (is_small(nb)) /* Can't shrink mmap regions below small size */ + return 0; + /* Keep old chunk if big enough but not too big */ + if (oldsize >= nb + SIZE_T_SIZE && + (oldsize - nb) <= (mparams.granularity << 1)) + return oldp; + else { + size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT; + size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; + size_t newmmsize = granularity_align(nb + SIX_SIZE_T_SIZES + + CHUNK_ALIGN_MASK); + char* cp = (char*)CALL_MREMAP((char*)oldp - offset, + oldmmsize, newmmsize, 1); + if (cp != CMFAIL) { + mchunkptr newp = (mchunkptr)(cp + offset); + size_t psize = newmmsize - offset - MMAP_FOOT_PAD; + newp->head = (psize|CINUSE_BIT); + mark_inuse_foot(m, newp, psize); + chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; + + if (cp < m->least_addr) + m->least_addr = cp; + if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) + m->max_footprint = m->footprint; + check_mmapped_chunk(m, newp); + return newp; + } + } + return 0; +} + +/* -------------------------- mspace management -------------------------- */ + +/* Initialize top chunk and its size */ +static void init_top(mstate m, mchunkptr p, size_t psize) { + /* Ensure alignment */ + size_t offset = align_offset(chunk2mem(p)); + p = (mchunkptr)((char*)p + offset); + psize -= offset; + + m->top = p; + m->topsize = psize; + p->head = psize | PINUSE_BIT; + /* set size of fake trailing chunk holding overhead space only once */ + chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; + m->trim_check = mparams.trim_threshold; /* reset on each update */ +} + +/* Initialize bins for a new mstate that is otherwise zeroed out */ +static void init_bins(mstate m) { + /* Establish circular links for smallbins */ + bindex_t i; + for (i = 0; i < NSMALLBINS; ++i) { + sbinptr bin = smallbin_at(m,i); + bin->fd = bin->bk = bin; + } +} + +#if PROCEED_ON_ERROR + +/* default corruption action */ +static void reset_on_error(mstate m) { + int i; + ++malloc_corruption_error_count; + /* Reinitialize fields to forget about all memory */ + m->smallbins = m->treebins = 0; + m->dvsize = m->topsize = 0; + m->seg.base = 0; + m->seg.size = 0; + m->seg.next = 0; + m->top = m->dv = 0; + for (i = 0; i < NTREEBINS; ++i) + *treebin_at(m, i) = 0; + init_bins(m); +} +#endif /* PROCEED_ON_ERROR */ + +/* Allocate chunk and prepend remainder with chunk in successor base. */ +static void* prepend_alloc(mstate m, char* newbase, char* oldbase, + size_t nb) { + mchunkptr p = align_as_chunk(newbase); + mchunkptr oldfirst = align_as_chunk(oldbase); + size_t psize = (char*)oldfirst - (char*)p; + mchunkptr q = chunk_plus_offset(p, nb); + size_t qsize = psize - nb; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + + assert((char*)oldfirst > (char*)q); + assert(pinuse(oldfirst)); + assert(qsize >= MIN_CHUNK_SIZE); + + /* consolidate remainder with first chunk of old base */ + if (oldfirst == m->top) { + size_t tsize = m->topsize += qsize; + m->top = q; + q->head = tsize | PINUSE_BIT; + check_top_chunk(m, q); + } + else if (oldfirst == m->dv) { + size_t dsize = m->dvsize += qsize; + m->dv = q; + set_size_and_pinuse_of_free_chunk(q, dsize); + } + else { + if (!cinuse(oldfirst)) { + size_t nsize = chunksize(oldfirst); + unlink_chunk(m, oldfirst, nsize); + oldfirst = chunk_plus_offset(oldfirst, nsize); + qsize += nsize; + } + set_free_with_pinuse(q, qsize, oldfirst); + insert_chunk(m, q, qsize); + check_free_chunk(m, q); + } + + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); +} + + +/* Add a segment to hold a new noncontiguous region */ +static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { + /* Determine locations and sizes of segment, fenceposts, old top */ + char* old_top = (char*)m->top; + msegmentptr oldsp = segment_holding(m, old_top); + char* old_end = oldsp->base + oldsp->size; + size_t ssize = pad_request(sizeof(struct malloc_segment)); + char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + size_t offset = align_offset(chunk2mem(rawsp)); + char* asp = rawsp + offset; + char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; + mchunkptr sp = (mchunkptr)csp; + msegmentptr ss = (msegmentptr)(chunk2mem(sp)); + mchunkptr tnext = chunk_plus_offset(sp, ssize); + mchunkptr p = tnext; + int nfences = 0; + + /* reset top to new space */ + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + + /* Set up segment record */ + assert(is_aligned(ss)); + set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); + *ss = m->seg; /* Push current record */ + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmapped; + m->seg.next = ss; + + /* Insert trailing fenceposts */ + for (;;) { + mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); + p->head = FENCEPOST_HEAD; + ++nfences; + if ((char*)(&(nextp->head)) < old_end) + p = nextp; + else + break; + } + assert(nfences >= 2); + + /* Insert the rest of old top into a bin as an ordinary free chunk */ + if (csp != old_top) { + mchunkptr q = (mchunkptr)old_top; + size_t psize = csp - old_top; + mchunkptr tn = chunk_plus_offset(q, psize); + set_free_with_pinuse(q, psize, tn); + insert_chunk(m, q, psize); + } + + check_top_chunk(m, m->top); +} + +/* -------------------------- System allocation -------------------------- */ + +/* Get memory from system using MORECORE or MMAP */ +static void* sys_alloc(mstate m, size_t nb) { + char* tbase = CMFAIL; + size_t tsize = 0; + flag_t mmap_flag = 0; + + init_mparams(); + + /* Directly map large chunks */ + if (use_mmap(m) && nb >= mparams.mmap_threshold) { + void* mem = mmap_alloc(m, nb); + if (mem != 0) + return mem; + } + + /* + Try getting memory in any of three ways (in most-preferred to + least-preferred order): + 1. A call to MORECORE that can normally contiguously extend memory. + (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or + or main space is mmapped or a previous contiguous call failed) + 2. A call to MMAP new space (disabled if not HAVE_MMAP). + Note that under the default settings, if MORECORE is unable to + fulfill a request, and HAVE_MMAP is true, then mmap is + used as a noncontiguous system allocator. This is a useful backup + strategy for systems with holes in address spaces -- in this case + sbrk cannot contiguously expand the heap, but mmap may be able to + find space. + 3. A call to MORECORE that cannot usually contiguously extend memory. + (disabled if not HAVE_MORECORE) + */ + + if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { + char* br = CMFAIL; + msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); + size_t asize = 0; + ACQUIRE_MORECORE_LOCK(); + + if (ss == 0) { /* First time through or recovery */ + char* base = (char*)CALL_MORECORE(0); + if (base != CMFAIL) { + asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); + /* Adjust to end on a page boundary */ + if (!is_page_aligned(base)) + asize += (page_align((size_t)base) - (size_t)base); + /* Can't call MORECORE if size is negative when treated as signed */ + if (asize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(asize))) == base) { + tbase = base; + tsize = asize; + } + } + } + else { + /* Subtract out existing available top space from MORECORE request. */ + asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + SIZE_T_ONE); + /* Use mem here only if it did continuously extend old space */ + if (asize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { + tbase = br; + tsize = asize; + } + } + + if (tbase == CMFAIL) { /* Cope with partial failure */ + if (br != CMFAIL) { /* Try to use/extend the space we did get */ + if (asize < HALF_MAX_SIZE_T && + asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) { + size_t esize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE - asize); + if (esize < HALF_MAX_SIZE_T) { + char* end = (char*)CALL_MORECORE(esize); + if (end != CMFAIL) + asize += esize; + else { /* Can't use; try to release */ + CALL_MORECORE(-asize); + br = CMFAIL; + } + } + } + } + if (br != CMFAIL) { /* Use the space we did get */ + tbase = br; + tsize = asize; + } + else + disable_contiguous(m); /* Don't try contiguous path in the future */ + } + + RELEASE_MORECORE_LOCK(); + } + + if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ + size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE; + size_t rsize = granularity_align(req); + if (rsize > nb) { /* Fail if wraps around zero */ + char* mp = (char*)(gui_ksys_mem_alloc(rsize)); + if (mp != CMFAIL) { + tbase = mp; + tsize = rsize; + mmap_flag = IS_MMAPPED_BIT; + } + } + } + + if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ + size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); + if (asize < HALF_MAX_SIZE_T) { + char* br = CMFAIL; + char* end = CMFAIL; + ACQUIRE_MORECORE_LOCK(); + br = (char*)(CALL_MORECORE(asize)); + end = (char*)(CALL_MORECORE(0)); + RELEASE_MORECORE_LOCK(); + if (br != CMFAIL && end != CMFAIL && br < end) { + size_t ssize = end - br; + if (ssize > nb + TOP_FOOT_SIZE) { + tbase = br; + tsize = ssize; + } + } + } + } + + if (tbase != CMFAIL) { + + if ((m->footprint += tsize) > m->max_footprint) + m->max_footprint = m->footprint; + + if (!is_initialized(m)) { /* first-time initialization */ + m->seg.base = m->least_addr = tbase; + m->seg.size = tsize; + m->seg.sflags = mmap_flag; + m->magic = mparams.magic; + init_bins(m); + if (is_global(m)) + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + else { + /* Offset top by embedded malloc_state */ + mchunkptr mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); + } + } + + else { + /* Try to merge with an existing segment */ + msegmentptr sp = &m->seg; + while (sp != 0 && tbase != sp->base + sp->size) + sp = sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & IS_MMAPPED_BIT) == mmap_flag && + segment_holds(sp, m->top)) { /* append */ + sp->size += tsize; + init_top(m, m->top, m->topsize + tsize); + } + else { + if (tbase < m->least_addr) + m->least_addr = tbase; + sp = &m->seg; + while (sp != 0 && sp->base != tbase + tsize) + sp = sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & IS_MMAPPED_BIT) == mmap_flag) { + char* oldbase = sp->base; + sp->base = tbase; + sp->size += tsize; + return prepend_alloc(m, tbase, oldbase, nb); + } + else + add_segment(m, tbase, tsize, mmap_flag); + } + } + + if (nb < m->topsize) { /* Allocate from new or extended top space */ + size_t rsize = m->topsize -= nb; + mchunkptr p = m->top; + mchunkptr r = m->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + check_top_chunk(m, m->top); + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); + } + } + + MALLOC_FAILURE_ACTION; + return 0; +} + +/* ----------------------- system deallocation -------------------------- */ + +/* Unmap and unlink any mmapped segments that don't contain used chunks */ +static size_t release_unused_segments(mstate m) { + size_t released = 0; + msegmentptr pred = &m->seg; + msegmentptr sp = pred->next; + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + msegmentptr next = sp->next; + if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { + mchunkptr p = align_as_chunk(base); + size_t psize = chunksize(p); + /* Can unmap if first chunk holds entire segment and not pinned */ + if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { + tchunkptr tp = (tchunkptr)p; + assert(segment_holds(sp, (char*)sp)); + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; + } + else { + unlink_large_chunk(m, tp); + } + if (gui_ksys_mem_free(base, size) == 0) { + released += size; + m->footprint -= size; + /* unlink obsoleted record */ + sp = pred; + sp->next = next; + } + else { /* back out if cannot unmap */ + insert_large_chunk(m, tp, psize); + } + } + } + pred = sp; + sp = next; + } + return released; +} + +static int sys_trim(mstate m, size_t pad) { + size_t released = 0; + if (pad < MAX_REQUEST && is_initialized(m)) { + pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ + + if (m->topsize > pad) { + /* Shrink top space in granularity-size units, keeping at least one */ + size_t unit = mparams.granularity; + size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - + SIZE_T_ONE) * unit; + msegmentptr sp = segment_holding(m, (char*)m->top); + + if (!is_extern_segment(sp)) { + if (is_mmapped_segment(sp)) { + if (HAVE_MMAP && + sp->size >= extra && + !has_segment_link(m, sp)) { /* can't shrink if pinned */ + size_t newsize = sp->size - extra; + /* Prefer mremap, fall back to munmap */ + if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || + (gui_ksys_mem_free(sp->base + newsize, extra) == 0)) { + released = extra; + } + } + } + else if (HAVE_MORECORE) { + if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ + extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; + ACQUIRE_MORECORE_LOCK(); + { + /* Make sure end of memory is where we last set it. */ + char* old_br = (char*)(CALL_MORECORE(0)); + if (old_br == sp->base + sp->size) { + char* rel_br = (char*)(CALL_MORECORE(-extra)); + char* new_br = (char*)(CALL_MORECORE(0)); + if (rel_br != CMFAIL && new_br < old_br) + released = old_br - new_br; + } + } + RELEASE_MORECORE_LOCK(); + } + } + + if (released != 0) { + sp->size -= released; + m->footprint -= released; + init_top(m, m->top, m->topsize - released); + check_top_chunk(m, m->top); + } + } + + /* Unmap any unused mmapped segments */ + if (HAVE_MMAP) + released += release_unused_segments(m); + + /* On failure, disable autotrim to avoid repeated failed future calls */ + if (released == 0) + m->trim_check = MAX_SIZE_T; + } + + return (released != 0)? 1 : 0; +} + +/* ---------------------------- malloc support --------------------------- */ + +/* allocate a large request from the best fitting chunk in a treebin */ +static void* tmalloc_large(mstate m, size_t nb) { + tchunkptr v = 0; + size_t rsize = -nb; /* Unsigned negation */ + tchunkptr t; + bindex_t idx; + compute_tree_index(nb, idx); + + if ((t = *treebin_at(m, idx)) != 0) { + /* Traverse tree for this bin looking for node with size == nb */ + size_t sizebits = nb << leftshift_for_tree_index(idx); + tchunkptr rst = 0; /* The deepest untaken right subtree */ + for (;;) { + tchunkptr rt; + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + v = t; + if ((rsize = trem) == 0) + break; + } + rt = t->child[1]; + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + if (rt != 0 && rt != t) + rst = rt; + if (t == 0) { + t = rst; /* set t to least subtree holding sizes > nb */ + break; + } + sizebits <<= 1; + } + } + + if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ + binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; + if (leftbits != 0) { + bindex_t i; + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + t = *treebin_at(m, i); + } + } + + while (t != 0) { /* find smallest of tree or subtree */ + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + t = leftmost_child(t); + } + + /* If dv is a better fit, return 0 so malloc will use it */ + if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { + if (RTCHECK(ok_address(m, v))) { /* split */ + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + insert_chunk(m, r, rsize); + } + return chunk2mem(v); + } + } + CORRUPTION_ERROR_ACTION(m); + } + return 0; +} + +/* allocate a small request from the best fitting chunk in a treebin */ +static void* tmalloc_small(mstate m, size_t nb) { + tchunkptr t, v; + size_t rsize; + bindex_t i; + binmap_t leastbit = least_bit(m->treemap); + compute_bit2idx(leastbit, i); + + v = t = *treebin_at(m, i); + rsize = chunksize(t) - nb; + + while ((t = leftmost_child(t)) != 0) { + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + } + + if (RTCHECK(ok_address(m, v))) { + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(m, r, rsize); + } + return chunk2mem(v); + } + } + + CORRUPTION_ERROR_ACTION(m); + return 0; +} + +/* --------------------------- realloc support --------------------------- */ + +static void* internal_realloc(mstate m, void* oldmem, size_t bytes) { + if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + return 0; + } + if (!PREACTION(m)) { + mchunkptr oldp = mem2chunk(oldmem); + size_t oldsize = chunksize(oldp); + mchunkptr next = chunk_plus_offset(oldp, oldsize); + mchunkptr newp = 0; + void* extra = 0; + + /* Try to either shrink or extend into top. Else malloc-copy-free */ + + if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) && + ok_next(oldp, next) && ok_pinuse(next))) { + size_t nb = request2size(bytes); + if (is_mmapped(oldp)) + newp = mmap_resize(m, oldp, nb); + else if (oldsize >= nb) { /* already big enough */ + size_t rsize = oldsize - nb; + newp = oldp; + if (rsize >= MIN_CHUNK_SIZE) { + mchunkptr remainder = chunk_plus_offset(newp, nb); + set_inuse(m, newp, nb); + set_inuse(m, remainder, rsize); + extra = chunk2mem(remainder); + } + } + else if (next == m->top && oldsize + m->topsize > nb) { + /* Expand into top */ + size_t newsize = oldsize + m->topsize; + size_t newtopsize = newsize - nb; + mchunkptr newtop = chunk_plus_offset(oldp, nb); + set_inuse(m, oldp, nb); + newtop->head = newtopsize |PINUSE_BIT; + m->top = newtop; + m->topsize = newtopsize; + newp = oldp; + } + } + else { + USAGE_ERROR_ACTION(m, oldmem); + POSTACTION(m); + return 0; + } + + POSTACTION(m); + + if (newp != 0) { + if (extra != 0) { + internal_free(m, extra); + } + check_inuse_chunk(m, newp); + return chunk2mem(newp); + } + else { + void* newmem = internal_malloc(m, bytes); + if (newmem != 0) { + size_t oc = oldsize - overhead_for(oldp); + memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); + internal_free(m, oldmem); + } + return newmem; + } + } + return 0; +} + +/* --------------------------- memalign support -------------------------- */ + +static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { + if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ + return internal_malloc(m, bytes); + if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ + alignment = MIN_CHUNK_SIZE; + if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ + size_t a = MALLOC_ALIGNMENT << 1; + while (a < alignment) a <<= 1; + alignment = a; + } + + if (bytes >= MAX_REQUEST - alignment) { + if (m != 0) { /* Test isn't needed but avoids compiler warning */ + MALLOC_FAILURE_ACTION; + } + } + else { + size_t nb = request2size(bytes); + size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; + char* mem = (char*)internal_malloc(m, req); + if (mem != 0) { + void* leader = 0; + void* trailer = 0; + mchunkptr p = mem2chunk(mem); + + if (PREACTION(m)) return 0; + if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */ + /* + Find an aligned spot inside chunk. Since we need to give + back leading space in a chunk of at least MIN_CHUNK_SIZE, if + the first calculation places us at a spot with less than + MIN_CHUNK_SIZE leader, we can move to the next aligned spot. + We've allocated enough total room so that this is always + possible. + */ + char* br = (char*)mem2chunk((size_t)(((size_t)(mem + + alignment - + SIZE_T_ONE)) & + -alignment)); + char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? + br : br+alignment; + mchunkptr newp = (mchunkptr)pos; + size_t leadsize = pos - (char*)(p); + size_t newsize = chunksize(p) - leadsize; + + if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ + newp->prev_foot = p->prev_foot + leadsize; + newp->head = (newsize|CINUSE_BIT); + } + else { /* Otherwise, give back leader, use the rest */ + set_inuse(m, newp, newsize); + set_inuse(m, p, leadsize); + leader = chunk2mem(p); + } + p = newp; + } + + /* Give back spare room at the end */ + if (!is_mmapped(p)) { + size_t size = chunksize(p); + if (size > nb + MIN_CHUNK_SIZE) { + size_t remainder_size = size - nb; + mchunkptr remainder = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, remainder, remainder_size); + trailer = chunk2mem(remainder); + } + } + + assert (chunksize(p) >= nb); + assert((((size_t)(chunk2mem(p))) % alignment) == 0); + check_inuse_chunk(m, p); + POSTACTION(m); + if (leader != 0) { + internal_free(m, leader); + } + if (trailer != 0) { + internal_free(m, trailer); + } + return chunk2mem(p); + } + } + return 0; +} + +/* ------------------------ comalloc/coalloc support --------------------- */ + +static void** ialloc(mstate m, + size_t n_elements, + size_t* sizes, + int opts, + void* chunks[]) { + /* + This provides common support for independent_X routines, handling + all of the combinations that can result. + + The opts arg has: + bit 0 set if all elements are same size (using sizes[0]) + bit 1 set if elements should be zeroed + */ + + size_t element_size; /* chunksize of each element, if all same */ + size_t contents_size; /* total size of elements */ + size_t array_size; /* request size of pointer array */ + void* mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + size_t remainder_size; /* remaining bytes while splitting */ + void** marray; /* either "chunks" or malloced ptr array */ + mchunkptr array_chunk; /* chunk for malloced ptr array */ + flag_t was_enabled; /* to disable mmap */ + size_t size; + size_t i; + + /* compute array length, if needed */ + if (chunks != 0) { + if (n_elements == 0) + return chunks; /* nothing to do */ + marray = chunks; + array_size = 0; + } + else { + /* if empty req, must still return chunk representing empty array */ + if (n_elements == 0) + return (void**)internal_malloc(m, 0); + marray = 0; + array_size = request2size(n_elements * (sizeof(void*))); + } + + /* compute total element size */ + if (opts & 0x1) { /* all-same-size */ + element_size = request2size(*sizes); + contents_size = n_elements * element_size; + } + else { /* add up all the sizes */ + element_size = 0; + contents_size = 0; + for (i = 0; i != n_elements; ++i) + contents_size += request2size(sizes[i]); + } + + size = contents_size + array_size; + + /* + Allocate the aggregate chunk. First disable direct-mmapping so + malloc won't use it, since we would not be able to later + free/realloc space internal to a segregated mmap region. + */ + was_enabled = use_mmap(m); + disable_mmap(m); + mem = internal_malloc(m, size - CHUNK_OVERHEAD); + if (was_enabled) + enable_mmap(m); + if (mem == 0) + return 0; + + if (PREACTION(m)) return 0; + p = mem2chunk(mem); + remainder_size = chunksize(p); + + assert(!is_mmapped(p)); + + if (opts & 0x2) { /* optionally clear the elements */ + memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); + } + + /* If not provided, allocate the pointer array as final part of chunk */ + if (marray == 0) { + size_t array_chunk_size; + array_chunk = chunk_plus_offset(p, contents_size); + array_chunk_size = remainder_size - contents_size; + marray = (void**) (chunk2mem(array_chunk)); + set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); + remainder_size = contents_size; + } + + /* split out elements */ + for (i = 0; ; ++i) { + marray[i] = chunk2mem(p); + if (i != n_elements-1) { + if (element_size != 0) + size = element_size; + else + size = request2size(sizes[i]); + remainder_size -= size; + set_size_and_pinuse_of_inuse_chunk(m, p, size); + p = chunk_plus_offset(p, size); + } + else { /* the final element absorbs any overallocation slop */ + set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); + break; + } + } + +#ifdef DEBUG +// if (marray != chunks) { + /* final element must have exactly exhausted chunk */ +// if (element_size != 0) { +// assert(remainder_size == element_size); +// } +// else { +// assert(remainder_size == request2size(sizes[i])); +// } +// check_inuse_chunk(m, mem2chunk(marray)); +// } +// for (i = 0; i != n_elements; ++i) +// check_inuse_chunk(m, mem2chunk(marray[i])); + +#endif /* DEBUG */ + + POSTACTION(m); + return marray; +} + + +/* -------------------------- public routines ---------------------------- */ + +#if !ONLY_MSPACES + +static void* dlmalloc(size_t bytes) { + /* + Basic algorithm: + If a small request (< 256 bytes minus per-chunk overhead): + 1. If one exists, use a remainderless chunk in associated smallbin. + (Remainderless means that there are too few excess bytes to + represent as a chunk.) + 2. If it is big enough, use the dv chunk, which is normally the + chunk adjacent to the one used for the most recent small request. + 3. If one exists, split the smallest available chunk in a bin, + saving remainder in dv. + 4. If it is big enough, use the top chunk. + 5. If available, get memory from system and use it + Otherwise, for a large request: + 1. Find the smallest available binned chunk that fits, and use it + if it is better fitting than dv chunk, splitting if necessary. + 2. If better fitting than any binned chunk, use the dv chunk. + 3. If it is big enough, use the top chunk. + 4. If request size >= mmap threshold, try to directly mmap this chunk. + 5. If available, get memory from system and use it + + The ugly goto's here ensure that postaction occurs along all paths. + */ + + if (!PREACTION(gm)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = gm->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(gm, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(gm, b, p, idx); + set_inuse_and_pinuse(gm, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb > gm->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(gm, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(gm, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(gm, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(gm, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + + if (nb <= gm->dvsize) { + size_t rsize = gm->dvsize - nb; + mchunkptr p = gm->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = gm->dv = chunk_plus_offset(p, nb); + gm->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + } + else { /* exhaust dv */ + size_t dvs = gm->dvsize; + gm->dvsize = 0; + gm->dv = 0; + set_inuse_and_pinuse(gm, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb < gm->topsize) { /* Split top */ + size_t rsize = gm->topsize -= nb; + mchunkptr p = gm->top; + mchunkptr r = gm->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + mem = chunk2mem(p); + check_top_chunk(gm, gm->top); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + mem = sys_alloc(gm, nb); + + postaction: + POSTACTION(gm); + return mem; + } + + return 0; +} + +static void dlfree(void* mem) { + /* + Consolidate freed chunks with preceeding or succeeding bordering + free chunks, if they exist, and then place in a bin. Intermixed + with special cases for top, dv, mmapped chunks, and usage errors. + */ + + if (mem != 0) { + mchunkptr p = mem2chunk(mem); +#if FOOTERS + mstate fm = get_mstate_for(p); + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } +#else /* FOOTERS */ +#define fm gm +#endif /* FOOTERS */ + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if ((prevsize & IS_MMAPPED_BIT) != 0) { + prevsize &= ~IS_MMAPPED_BIT; + psize += prevsize + MMAP_FOOT_PAD; + if (gui_ksys_mem_free((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + insert_chunk(fm, p, psize); + check_free_chunk(fm, p); + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +#if !FOOTERS +#undef fm +#endif /* FOOTERS */ +} + +static void* dlcalloc(size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = dlmalloc(req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + memset(mem, 0, req); + return mem; +} + +static void* dlrealloc(void* oldmem, size_t bytes) { + if (oldmem == 0) + return dlmalloc(bytes); +#ifdef REALLOC_ZERO_BYTES_FREES + if (bytes == 0) { + dlfree(oldmem); + return 0; + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { +#if ! FOOTERS + mstate m = gm; +#else /* FOOTERS */ + mstate m = get_mstate_for(mem2chunk(oldmem)); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + return internal_realloc(m, oldmem, bytes); + } +} + +static void* dlmemalign(size_t alignment, size_t bytes) { + return internal_memalign(gm, alignment, bytes); +} + +static void** dlindependent_calloc(size_t n_elements, size_t elem_size, + void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + return ialloc(gm, n_elements, &sz, 3, chunks); +} + +static void** dlindependent_comalloc(size_t n_elements, size_t sizes[], + void* chunks[]) { + return ialloc(gm, n_elements, sizes, 0, chunks); +} + +static void* dlvalloc(size_t bytes) { + size_t pagesz; + init_mparams(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, bytes); +} + +static void* dlpvalloc(size_t bytes) { + size_t pagesz; + init_mparams(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); +} + +static int dlmalloc_trim(size_t pad) { + int result = 0; + if (!PREACTION(gm)) { + result = sys_trim(gm, pad); + POSTACTION(gm); + } + return result; +} + +static size_t dlmalloc_footprint(void) { + return gm->footprint; +} + +static size_t dlmalloc_max_footprint(void) { + return gm->max_footprint; +} + +#if !NO_MALLINFO +struct mallinfo dlmallinfo(void) { + return internal_mallinfo(gm); +} +#endif /* NO_MALLINFO */ + +//void dlmalloc_stats() { +// internal_malloc_stats(gm); +//} + +static size_t dlmalloc_usable_size(void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (cinuse(p)) + return chunksize(p) - overhead_for(p); + } + return 0; +} + +static int dlmallopt(int param_number, int value) { + return change_mparam(param_number, value); +} + +#endif /* !ONLY_MSPACES */ + +/* ----------------------------- user mspaces ---------------------------- */ + +#if MSPACES +#endif /* MSPACES */ + +/* -------------------- Alternative MORECORE functions ------------------- */ + +/* + Guidelines for creating a custom version of MORECORE: + + * For best performance, MORECORE should allocate in multiples of pagesize. + * MORECORE may allocate more memory than requested. (Or even less, + but this will usually result in a malloc failure.) + * MORECORE must not allocate memory when given argument zero, but + instead return one past the end address of memory from previous + nonzero call. + * For best performance, consecutive calls to MORECORE with positive + arguments should return increasing addresses, indicating that + space has been contiguously extended. + * Even though consecutive calls to MORECORE need not return contiguous + addresses, it must be OK for malloc'ed chunks to span multiple + regions in those cases where they do happen to be contiguous. + * MORECORE need not handle negative arguments -- it may instead + just return MFAIL when given negative arguments. + Negative arguments are always multiples of pagesize. MORECORE + must not misinterpret negative args as large positive unsigned + args. You can suppress all such calls from even occurring by defining + MORECORE_CANNOT_TRIM, + + As an example alternative MORECORE, here is a custom allocator + kindly contributed for pre-OSX macOS. It uses virtually but not + necessarily physically contiguous non-paged memory (locked in, + present and won't get swapped out). You can use it by uncommenting + this section, adding some #includes, and setting up the appropriate + defines above: + + #define MORECORE osMoreCore + + There is also a shutdown routine that should somehow be called for + cleanup upon program exit. + + #define MAX_POOL_ENTRIES 100 + #define MINIMUM_MORECORE_SIZE (64 * 1024U) + static int next_os_pool; + void *our_os_pools[MAX_POOL_ENTRIES]; + + void *osMoreCore(int size) + { + void *ptr = 0; + static void *sbrk_top = 0; + + if (size > 0) + { + if (size < MINIMUM_MORECORE_SIZE) + size = MINIMUM_MORECORE_SIZE; + if (CurrentExecutionLevel() == kTaskLevel) + ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); + if (ptr == 0) + { + return (void *) MFAIL; + } + // save ptrs so they can be freed during cleanup + our_os_pools[next_os_pool] = ptr; + next_os_pool++; + ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); + sbrk_top = (char *) ptr + size; + return ptr; + } + else if (size < 0) + { + // we don't currently support shrink behavior + return (void *) MFAIL; + } + else + { + return sbrk_top; + } + } + + // cleanup any allocated memory pools + // called as last thing before shutting down driver + + void osCleanupMem(void) + { + void **ptr; + + for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) + if (*ptr) + { + PoolDeallocate(*ptr); + *ptr = 0; + } + } + +*/ + + +/* ----------------------------------------------------------------------- +History: + V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) + * Add max_footprint functions + * Ensure all appropriate literals are size_t + * Fix conditional compilation problem for some #define settings + * Avoid concatenating segments with the one provided + in create_mspace_with_base + * Rename some variables to avoid compiler shadowing warnings + * Use explicit lock initialization. + * Better handling of sbrk interference. + * Simplify and fix segment insertion, trimming and mspace_destroy + * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x + * Thanks especially to Dennis Flanagan for help on these. + + V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) + * Fix memalign brace error. + + V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) + * Fix improper #endif nesting in C++ + * Add explicit casts needed for C++ + + V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) + * Use trees for large bins + * Support mspaces + * Use segments to unify sbrk-based and mmap-based system allocation, + removing need for emulation on most platforms without sbrk. + * Default safety checks + * Optional footer checks. Thanks to William Robertson for the idea. + * Internal code refactoring + * Incorporate suggestions and platform-specific changes. + Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, + Aaron Bachmann, Emery Berger, and others. + * Speed up non-fastbin processing enough to remove fastbins. + * Remove useless cfree() to avoid conflicts with other apps. + * Remove internal memcpy, memset. Compilers handle builtins better. + * Remove some options that no one ever used and rename others. + + V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) + * Fix malloc_state bitmap array misdeclaration + + V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) + * Allow tuning of FIRST_SORTED_BIN_SIZE + * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. + * Better detection and support for non-contiguousness of MORECORE. + Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger + * Bypass most of malloc if no frees. Thanks To Emery Berger. + * Fix freeing of old top non-contiguous chunk im sysmalloc. + * Raised default trim and map thresholds to 256K. + * Fix mmap-related #defines. Thanks to Lubos Lunak. + * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. + * Branch-free bin calculation + * Default trim and mmap thresholds now 256K. + + V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) + * Introduce independent_comalloc and independent_calloc. + Thanks to Michael Pachos for motivation and help. + * Make optional .h file available + * Allow > 2GB requests on 32bit systems. + * new WIN32 sbrk, mmap, munmap, lock code from . + Thanks also to Andreas Mueller , + and Anonymous. + * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for + helping test this.) + * memalign: check alignment arg + * realloc: don't try to shift chunks backwards, since this + leads to more fragmentation in some programs and doesn't + seem to help in any others. + * Collect all cases in malloc requiring system memory into sysmalloc + * Use mmap as backup to sbrk + * Place all internal state in malloc_state + * Introduce fastbins (although similar to 2.5.1) + * Many minor tunings and cosmetic improvements + * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK + * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS + Thanks to Tony E. Bennett and others. + * Include errno.h to support default failure action. + + V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) + * return null for negative arguments + * Added Several WIN32 cleanups from Martin C. Fong + * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' + (e.g. WIN32 platforms) + * Cleanup header file inclusion for WIN32 platforms + * Cleanup code to avoid Microsoft Visual C++ compiler complaints + * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing + memory allocation routines + * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) + * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to + usage of 'assert' in non-WIN32 code + * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to + avoid infinite loop + * Always call 'fREe()' rather than 'free()' + + V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) + * Fixed ordering problem with boundary-stamping + + V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) + * Added pvalloc, as recommended by H.J. Liu + * Added 64bit pointer support mainly from Wolfram Gloger + * Added anonymously donated WIN32 sbrk emulation + * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen + * malloc_extend_top: fix mask error that caused wastage after + foreign sbrks + * Add linux mremap support code from HJ Liu + + V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) + * Integrated most documentation with the code. + * Add support for mmap, with help from + Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Use last_remainder in more cases. + * Pack bins using idea from colin@nyx10.cs.du.edu + * Use ordered bins instead of best-fit threshhold + * Eliminate block-local decls to simplify tracing and debugging. + * Support another case of realloc via move into top + * Fix error occuring when initial sbrk_base not word-aligned. + * Rely on page size for units instead of SBRK_UNIT to + avoid surprises about sbrk alignment conventions. + * Add mallinfo, mallopt. Thanks to Raymond Nijssen + (raymond@es.ele.tue.nl) for the suggestion. + * Add `pad' argument to malloc_trim and top_pad mallopt parameter. + * More precautions for cases where other routines call sbrk, + courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Added macros etc., allowing use in linux libc from + H.J. Lu (hjl@gnu.ai.mit.edu) + * Inverted this history list + + V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) + * Re-tuned and fixed to behave more nicely with V2.6.0 changes. + * Removed all preallocation code since under current scheme + the work required to undo bad preallocations exceeds + the work saved in good cases for most test programs. + * No longer use return list or unconsolidated bins since + no scheme using them consistently outperforms those that don't + given above changes. + * Use best fit for very large chunks to prevent some worst-cases. + * Added some support for debugging + + V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) + * Removed footers when chunks are in use. Thanks to + Paul Wilson (wilson@cs.texas.edu) for the suggestion. + + V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) + * Added malloc_trim, with help from Wolfram Gloger + (wmglo@Dent.MED.Uni-Muenchen.DE). + + V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) + + V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) + * realloc: try to expand in both directions + * malloc: swap order of clean-bin strategy; + * realloc: only conditionally expand backwards + * Try not to scavenge used bins + * Use bin counts as a guide to preallocation + * Occasionally bin return list chunks in first scan + * Add a few optimizations from colin@nyx10.cs.du.edu + + V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) + * faster bin computation & slightly different binning + * merged all consolidations to one part of malloc proper + (eliminating old malloc_find_space & malloc_clean_bin) + * Scan 2 returns chunks (not just 1) + * Propagate failure in realloc if malloc returns 0 + * Add stuff to allow compilation on non-ANSI compilers + from kpv@research.att.com + + V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) + * removed potential for odd address access in prev_chunk + * removed dependency on getpagesize.h + * misc cosmetics and a bit more internal documentation + * anticosmetics: mangled names in macros to evade debugger strangeness + * tested on sparc, hp-700, dec-mips, rs6000 + with gcc & native cc (hp, dec only) allowing + Detlefs & Zorn comparison study (in SIGPLAN Notices.) + + Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) + * Based loosely on libg++-1.2X malloc. (It retains some of the overall + structure of old version, but most details differ.) + +*/ diff --git a/programs/develop/libraries/libGUI/SRC/parent_window.inc b/programs/develop/libraries/libGUI/SRC/parent_window.inc new file mode 100644 index 0000000000..4df84a233e --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/parent_window.inc @@ -0,0 +1,142 @@ +/* + create parent of window +*/ + +#define PARENT_WINDOW_DEFAULT_SIZEX 320 +#define PARENT_WINDOW_DEFAULT_SIZEY 200 + +#define PARENT_WINDOW_BORDER_WIDTH 5; + +void gui_get_screen_parameters(void) +{ + int value; + + value=(int)gui_ksys_get_screen_bits_per_pixel(); + screen.bits_per_pixel=(char)value; + screen.bytes_per_pixel=screen.bits_per_pixel >> 3; + + screen.skin_height=gui_ksys_get_skin_height(); + + screen.x=PARENT_WINDOW_BORDER_WIDTH; + screen.y=screen.skin_height; + + value=gui_ksys_get_screen_size(); + screen.display_size_y=value & 0xffff; + screen.display_size_y=value >> 16; +} + +void gui_draw_window(parent_t *window) +{ + DWORD flag; + + flag=3; + flag=flag<<24; + flag +=0xaabbcc; + + gui_ksys_begin_draw_window(); + gui_ksys_draw_window(window->ctrl_x,window->ctrl_y,window->ctrl_sizex,window->ctrl_sizey,flag); + gui_ksys_finish_draw_window(); +} + +//--------------------------------------------------------------------------------- +// create window parent +//--------------------------------------------------------------------------------- +void* CreateWindow(void) +{ + struct HEADERPARENT *WindowParent; + + WindowParent=malloc(sizeof(parent_t)); + WindowParent->message=malloc(sizeof(gui_message_t)); + WindowParent->control_for_callback_function=malloc(sizeof(DWORD)*MAX_CALLBACKS); + WindowParent->callback_for_control_callback=malloc(sizeof(DWORD)*MAX_CALLBACKS); + + WindowParent->main_parent=(DWORD*)WindowParent; + WindowParent->global_active_control_for_keys=(DWORD*)NULL; + + WindowParent->control_for_callback_function[0]=(DWORD*)NULL; + WindowParent->number_callbacks=0; + + WindowParent->child_bk=(DWORD*)NULL; + WindowParent->active_control_for_keys=(DWORD*)NULL; + WindowParent->active_control_for_mouse=(DWORD*)NULL; + WindowParent->ctrl_x=0x0; + WindowParent->ctrl_y=0x0; + WindowParent->ctrl_sizex=PARENT_WINDOW_DEFAULT_SIZEX; + WindowParent->ctrl_sizey=PARENT_WINDOW_DEFAULT_SIZEY; + WindowParent->callback=(DWORD*)NULL;//no callbacks yet + WindowParent->timer=(DWORD*)NULL;//no timers yet + + WindowParent->flags=0; + WindowParent->flags=WindowParent->flags | FLAG_SHOW_CONTROL; + WindowParent->flags=WindowParent->flags | FLAG_FOCUSE_INPUT_SUPPOROTE; + + WindowParent->number_timers_for_controls=0; + WindowParent->timer_bk=(DWORD*)NULL; + WindowParent->timer_fd=(DWORD*)NULL; + + WindowParent->callback=(DWORD*)NULL; + WindowParent->calev_bk=(DWORD*)NULL; + WindowParent->calev_fd=(DWORD*)NULL; + + WindowParent->IDL_func=(DWORD*)NULL; + +//--------------------------------------------------------------------------------- +//---------------------------platform depended part of code------------------------ +//--------------------------------------------------------------------------------- + //create and initialize screen buffer + gui_get_screen_parameters(); + //by default draw output to the screen + screen.draw_output=DRAW_OUTPUT_SCREEN; + //calculate size of client's arrea + screen.size_x=WindowParent->ctrl_sizex-9; + screen.size_y=WindowParent->ctrl_sizey-screen.skin_height-4; +//---------------------------------------------------------------------------------- + ID=0; +#ifdef DEBUG + printf("\ncreated parent window %d",(DWORD)WindowParent); +#endif + return(WindowParent); +} + +//--------------------------------------------------------------------------------- +// create window parent +//--------------------------------------------------------------------------------- +void SetWindowSizeRequest(parent_t *WindowParent,int size_x,int size_y) +{ + static int x,y,sizex,sizey; +//--------------------------------------------------------------------------------- +//---------------------------platform depended part of code------------------------ +//--------------------------------------------------------------------------------- + x=WindowParent->ctrl_x; + y=WindowParent->ctrl_y; + sizex=size_x; + sizey=size_y; + gui_ksys_set_position_and_size_window(x,y,sizex,sizey); +//--------------------------------------------------------------------------------- + WindowParent->ctrl_sizex=sizex; + WindowParent->ctrl_sizey=sizey; + + screen.size_x=WindowParent->ctrl_sizex-9; + screen.size_y=WindowParent->ctrl_sizey-screen.skin_height-4; +#ifdef DEBUG + printf("\nwindow resized new sizex=%d sizey=%d", + WindowParent->ctrl_sizex, + WindowParent->ctrl_sizey); +#endif + +} + +void GetNewWindowSizePos(parent_t *WindowParent) +{ + static process_table_t procinfo; + + gui_ksys_get_current_process_information(&procinfo); + + WindowParent->ctrl_x=(DWORD)procinfo.winx_start; + WindowParent->ctrl_y=(DWORD)procinfo.winy_start; + WindowParent->ctrl_sizex=(DWORD)procinfo.winx_size; + WindowParent->ctrl_sizey=(DWORD)procinfo.winy_size; + + //get screen parameters again + gui_get_screen_parameters(); +} diff --git a/programs/develop/libraries/libGUI/SRC/stdarg.h b/programs/develop/libraries/libGUI/SRC/stdarg.h new file mode 100644 index 0000000000..a7dcdfa3c4 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/stdarg.h @@ -0,0 +1,8 @@ + +typedef char *va_list; +#define _roundsize(n) ( (sizeof(n) + 3) & ~3 ) +#define va_start(ap,v) (ap = (va_list)&v+_roundsize(v)) +#define va_arg(ap,t) ( *(t *)((ap += _roundsize(t)) - _roundsize(t)) ) +#define va_end(ap) (ap = (va_list)0) + + diff --git a/programs/develop/libraries/libGUI/SRC/stdio.h b/programs/develop/libraries/libGUI/SRC/stdio.h new file mode 100644 index 0000000000..c71b516a7e --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/stdio.h @@ -0,0 +1,3 @@ + +static int cdecl printf(const char *format,...); + diff --git a/programs/develop/libraries/libGUI/SRC/stdio.inc b/programs/develop/libraries/libGUI/SRC/stdio.inc new file mode 100644 index 0000000000..47b5a423d0 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/stdio.inc @@ -0,0 +1,792 @@ +/* + function for format output to the string +*/ + +static int formatted_double_to_string(long double number,int format1,int format2,char *s) +{ +/* + double n; + double nbefor; + double nafter; + double v,v2; + long intdigit; + long beforpointdigit; + long div; + int i; + int pos; + int size; + int fmt1; + int fmt2; + long mul; + static char buf[200]; + + size=(int)s; + n=(double)number; + if (n<0) {*s='-';s++;n=-n;} + + fmt1=format1; + fmt2=format2; + if (fmt2>18) {fmt2=18;} //maximum of size long long type + + //clear array befor output + for(i=0;i<=200;i++) {buf[i]=0;} + + if ((fmt1>=0) && (n<1)) + { //formatted output if 0<=n<1 + mul=1; + for(i=0;i=0) && (buf[i]<=9)) {*s='0'+buf[i];} + else {*s='0';} + s++; + } + } + else + { //if n>=1 + //v=floorf(n+0.00000000000001); + beforpointdigit=floor(n+0.00000000000001); + //beforpointdigit=n; + nbefor=beforpointdigit; + nafter=n-nbefor; + + //print part of number befor point + mul=1; + for(i=0;i<200-2;i++) + { + mul=mul*10; + if ((beforpointdigit/mul)==0) {fmt1=i+1;break;} + } + + pos=0; + mul=mul/10; + for(i=0;i=0) && (buf[i]<=9)) {*s='0'+buf[i];} + s++; + } + + //print part of number after point + mul=1; + for(i=0;i=0) && (buf[i]<=9)) {*s='0'+buf[i];} + else {*s='0';} + s++; + } + + } + size=(int)s-size; + return(size); +*/ +} + +static int formatted_long_to_string(long long number,int fmt1,char *s) +{ + int i; + int pos; + int fmt; + int size; + int difference_pos; + long digit; + long mul; + long div; + static char buf[200]; + + //clear array befor output + for(i=0;i<200;i++) {buf[i]=0;} + digit=number; + + size=(int)s; + if (digit<0) {*s='-';s++;digit=-digit;} + if (digit==0) {*s='0';s++;goto end;} + + mul=1; + for(i=0;i<200-2;i++) + { + mul=mul*10; + if ((digit/mul)==0) {fmt=i+1;break;} + } + + difference_pos=i+1; + + pos=0; + mul=mul/10; + for(i=0;i=difference_pos) fmt=fmt1; + else + fmt=difference_pos; + + for(i=0;i=0) && (buf[i]<=9)) {*s='0'+buf[i];} + } + else + { + *s=' '; + } + s++; + } + end: + size=(int)s-size; + return(size); +} + +static int formatted_hex_to_string(long long number,int fmt1,char flag_register,char *s) +{ + long n; + int i,pos; + int fmt; + long size; + int difference_pos; + static char xdigs_lower[]="0123456789abcdef"; + static char xdigs_upper[]="0123456789ABCDEF"; + static char buf[200]; + + n=(long)number; + size=(int)s; + if (n<0) {*s='-';s++;n=-n;} + + if (n==0) {*s='0';s++;goto end;} + for(i=0;i<200;i++) {buf[i]=0;} + + i=0; + if (flag_register==0) + { + while (n>0) + { + buf[i]=xdigs_lower[n & 15]; + n=n>>4; + i++; + } + } + else + { + while (n>0) + { + buf[i]=xdigs_upper[n & 15]; + n=n>>4; + i++; + } + } + + pos=i; + difference_pos=i; + + for(i=pos-1;i>=0;i--) + { + *s=buf[i]; + s++; + } + + if (fmt1-difference_pos>0) + { + for(i=difference_pos+1;i<=fmt1;i++) + { + *s=' '; + s++; + } + } + end:size=(int)s-size; + return(size); +} + +static int formatted_octa_to_string(long long number,int fmt1,char flag_register,char *s) +{ + long n; + int i,pos; + int fmt; + long size; + int difference_pos; + static char xdigs_lower[16]="012345678"; + static char buf[200]; + + n=number; + size=(int)s; + if (n<0) {*s='-';s++;n=-n;} + + if (n==0) {*s='0';s++;goto end;} + for(i=0;i<200;i++) {buf[i]=0;} + + i=0; + if (flag_register==0) + { + while (n>0) + { + buf[i]=xdigs_lower[n & 7]; + n=n>>3; + i++; + } + } + + pos=i; + difference_pos=i; + + for(i=pos-1;i>=0;i--) + { + *s=buf[i]; + s++; + } + + if (fmt1-difference_pos>0) + { + for(i=difference_pos+1;i<=fmt1;i++) + { + *s=' '; + s++; + } + } + end:size=(int)s-size; + return(size); +} + +static int format_print(char *dest, size_t maxlen,const char *fmt0, va_list argp) +{ + int i,j,k; + int length; + int fmt1,fmt2,stepen; + size_t pos,posc; + long long intdigit; + long double doubledigit; + float floatdigit; + const char *fmt,*fmtc; + char *s; + char *str; + static char buffmt1[30]; + static char buffmt2[30]; + static char buf[1024]; + char format_flag; + char flag_point; + char flag_noformat; + char flag_long; + char flag_unsigned; + char flag_register; + char flag_plus; + + fmt=fmt0; + s=dest; + pos=0; + maxlen--; + if (maxlen<=0) return(0); + + while(pos0) && (flag_plus==1) && (pos+1=0;i--) + { + fmt1=fmt1+buffmt1[i]*stepen; + stepen=stepen*10; + } + stepen=1; + for(i=k-1;i>=0;i--) + { + fmt2=fmt2+buffmt2[i]*stepen; + stepen=stepen*10; + } + switch(*fmtc) + { + case 'f': + case 'F': + if (flag_long==0) {doubledigit=va_arg(argp,double);} + if (flag_long>=1) {doubledigit=va_arg(argp,long double);} + //doubledigit=*((double *)argp); + //sargp=argp+8; + length=formatted_double_to_string(doubledigit,fmt1,fmt2,buf); + if ((pos+length)0) && (flag_plus==1) && (pos+1> 2;//length=length/4 + __asm__ __volatile__( + "movl %%edi,%%eax\n\t" + "cld\n\t" + "rep\n\t" + "movsd" + :"=D"(value) + :"c"(length),"S"(src),"D"(dst) + :"eax"); + + } + return(value); +} + +static void *memset(const void *dst, int c, size_t length) +{ + unsigned char cfill; + + cfill=c; + while(length) + { + *(char*)dst=c; + dst=(char*)dst+1; + length--; + } + return((void*)1); +} + +static size_t strlen(const char *s) +{ + size_t i; + + i=0; + while(*s!='\0') + { + i++; + s++; + } + return(i); +} + +static char* strchr(const char *string, int c) +{ + while(*string!='\0') + { + if (*string==(char)c) return((char*)string); + string++; + } + return(NULL); +} + +static char* strrchr(const char *string, int c) +{ + char *s; + int i,j; + + s=(char*)string; + while(*s!='\0') {s++;} + + j=(int)(s-string); + s--; + + for(i=0;i*string2) + return 1; + if (*string1=='\0') + return 0; + string1++; + string2++; + } +} + +static int strncmp(const char* string1, const char* string2,size_t count) +{ + while(count>0 && *string1==*string2) + { + if (*string1) return 0; + ++string1; + ++string2; + --count; + } + if(count) return (*string1 - *string2); + return 0; +} + +static int sprintf(char *dest,const char *format,...) +{ + va_list arg; + va_start (arg, format); + return format_print(dest,strlen(dest), format, arg); +} + +static int snprintf(char *dest, size_t size,const char *format,...) +{ + va_list arg; + va_start (arg, format); + return format_print(dest,size, format, arg); +} + +static int vsnprintf(char *dest, size_t size,const char *format,va_list ap) +{ + return format_print(dest,size, format, ap); +} + + diff --git a/programs/develop/libraries/libGUI/SRC/types.h b/programs/develop/libraries/libGUI/SRC/types.h new file mode 100644 index 0000000000..d810383166 --- /dev/null +++ b/programs/develop/libraries/libGUI/SRC/types.h @@ -0,0 +1,13 @@ +/* + some used types +*/ +#define NULL (void*)0 + +typedef unsigned int DWORD; +typedef unsigned char BYTE; +typedef unsigned short int WORD; +typedef unsigned int size_t; + +//for win compilers +#define stdcall __stdcall +#define cdecl __cdecl diff --git a/programs/develop/libraries/libGUI/examples/src/button.c b/programs/develop/libraries/libGUI/examples/src/button.c new file mode 100644 index 0000000000..55893507d5 --- /dev/null +++ b/programs/develop/libraries/libGUI/examples/src/button.c @@ -0,0 +1,70 @@ +/* + test libGUI library +*/ +#include "stdarg.h" +#include "libGUI.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" + +#define FALSE 0 +#define TRUE 1 + +void callback_func_delete_window(header_t *control,void *data) +{ + QuitLibGUI((parent_t*)control); +} + +void callback_func1(header_t *control,void *data) +{ + printf("\nentry in button"); +} + +void callback_func2(header_t *control,void *data) +{ + printf("\nbutton pressed"); +} + +void callback_func3(header_t *control,void *data) +{ + printf("\nbutton released"); +} + +void callback_func4(header_t *control,void *data) +{ + printf("\nleave button"); +} + +int main(int argc, char *argv[]) +{ + parent_t *window; + gui_callback_t *id1,*id2,*id3,*id4; + gui_button_data_t button_data; + gui_button_t *button; + + //load libGUI library + LoadLibGUI(NULL); + + //create main window + window=CreateWindow(); + SetWindowSizeRequest(window,90,60); + //create button + button_data.x=5; + button_data.y=5; + button_data.width=70; + button_data.height=20; + //create button with text + button=CreateButtonWithText(&button_data,"Click my!"); + //set callback functions for button close window + SetCallbackFunction(window,DELETE_EVENT,&callback_func_delete_window,NULL); + + //set callback functions for button + id1=SetCallbackFunction(button,BUTTON_ENTER_EVENT,&callback_func1,NULL); + id2=SetCallbackFunction(button,BUTTON_PRESSED_EVENT,&callback_func2,NULL); + id3=SetCallbackFunction(button,BUTTON_RELEASED_EVENT,&callback_func3,NULL); + id4=SetCallbackFunction(button,BUTTON_LEAVE_EVENT,&callback_func4,NULL); + //pack button in window + PackControls(window,button); + //start main libGUI loop + LibGUImain(window); +} diff --git a/programs/develop/libraries/libGUI/examples/src/image.c b/programs/develop/libraries/libGUI/examples/src/image.c new file mode 100644 index 0000000000..1b81c08a9d --- /dev/null +++ b/programs/develop/libraries/libGUI/examples/src/image.c @@ -0,0 +1,52 @@ +/* + test libGUI library +*/ +#include "stdarg.h" +#include "libGUI.h" +#include "stdlib.h" +#include "stdio.h" + +void callback_func_delete_window(header_t *control,void *data) +{ + QuitLibGUI((parent_t*)control); +} + +int main(int argc, char *argv[]) +{ + parent_t *window; + gui_image_data_t imdata; + gui_image_t *image; + int i,j; + unsigned int *img; + + //load libGUI library + LoadLibGUI(NULL);//use default system path to library + //create main window + window=CreateWindow(); + //change window size + SetWindowSizeRequest(window,220,142); + //set callback function for close window button + SetCallbackFunction(window,DELETE_EVENT,&callback_func_delete_window,NULL); + //create image + imdata.x=5; + imdata.y=5; + imdata.width=200; + imdata.height=100; + imdata.bits_per_pixel=32;//bits per pixel + + image=CreateImage(&imdata); + img=(unsigned int*)image->img; + //generate 32 bits image + for(i=0;iprogress+=0.01;//incrase progress + + if (progress_bar->progress>1.0) progress_bar->progress=0.0; + + //calculate progress level in % + progress=progress_bar->progress*100; + snprintf(txt,16,"progress %d%%",progress); + //set text for progress bar + ProgressBarSetText(progress_bar,txt); +} + +int main(int argc, char *argv[]) +{ + parent_t *window; + gui_progress_bar_data_t progress_bar_data; + gui_progress_bar_t *progress_bar; + gui_timer_t *timer; + + //load libGUI library + LoadLibGUI(NULL);//use default system path to library + //create main window + window=CreateWindow(); + //change size of main window + SetWindowSizeRequest(window,320,57); + //set callback function for button close window + SetCallbackFunction(window,DELETE_EVENT,&callback_func_delete_window,NULL); + //create progress bar + progress_bar_data.x=5; + progress_bar_data.y=5; + progress_bar_data.width=300; + progress_bar_data.height=25; + progress_bar_data.progress=0.0; + progress_bar=CreateProgressBar(&progress_bar_data); + + //create timer for update progress level each 50 millisecunds + timer=SetTimerCallbackForFunction(window,5,&ProgressBarCallback,progress_bar); + + //pack progress bar in window + PackControls(window,progress_bar); + + //update progress bar automatically each 50 millisecund + SetProgressBarPulse(progress_bar,5); + + //call main libGUI loop + LibGUImain(window); +} diff --git a/programs/develop/libraries/libGUI/examples/src/scroll_bar.c b/programs/develop/libraries/libGUI/examples/src/scroll_bar.c new file mode 100644 index 0000000000..8225c796b5 --- /dev/null +++ b/programs/develop/libraries/libGUI/examples/src/scroll_bar.c @@ -0,0 +1,76 @@ +/* + test libGUI library +*/ +#include "stdarg.h" +#include "libGUI.h" +#include "stdio.h" + +#define FALSE 0 +#define TRUE 1 + +void callback_func_delete_window(header_t *control,void *data) +{ + printf("\nlibGUI quit..."); + QuitLibGUI((parent_t*)control); +} + +void ScrollStateH(header_t *control,void *data) +{ + gui_scroll_bar_t *hsc; + + hsc=(gui_scroll_bar_t*)control; + printf("\nhorizontal ruler position %d%%",(int)(hsc->ruller_pos*100)); +} + +void ScrollStateV(header_t *control,void *data) +{ + gui_scroll_bar_t *vsc; + + vsc=(gui_scroll_bar_t*)control; + printf("\nvertical ruler position %d%%",(int)(vsc->ruller_pos*100)); +} + +int main(int argc, char *argv[]) +{ + parent_t *window; + gui_callback_t *id1,*id2; + gui_scroll_bar_data_t horizontal_sbar_data; + gui_scroll_bar_data_t vertical_sbar_data; + gui_scroll_bar_t *ScrollBarH; + gui_scroll_bar_t *ScrollBarV; + + //load libGUI library + LoadLibGUI(NULL);//use default system path to library + //create main window + window=CreateWindow(); + //change size of window + SetWindowSizeRequest(window,270,207); + //create horizontal scroll bar + horizontal_sbar_data.x=5; + horizontal_sbar_data.y=5; + horizontal_sbar_data.width=250; + horizontal_sbar_data.height=16; + horizontal_sbar_data.ruller_size=0.2;//size of ruler E [0,1] + horizontal_sbar_data.ruller_pos=0.5;//ruler position E [0,1] + horizontal_sbar_data.ruller_step=0.1;//step of change ruler pos after press of button E [0,1] + //create vertical scroll bar + vertical_sbar_data.x=5; + vertical_sbar_data.y=26; + vertical_sbar_data.width=16; + vertical_sbar_data.height=150; + vertical_sbar_data.ruller_size=0.5;//size of ruler E [0,1] + vertical_sbar_data.ruller_pos=0.05;//ruler position E [0,1] + vertical_sbar_data.ruller_step=0.1;//step of change ruler pos after press of button E [0,1] + + //create horizontal and vertical scroll bars + ScrollBarH=CreateHorizontalScrollBar(&horizontal_sbar_data); + ScrollBarV=CreateVerticalScrollBar(&vertical_sbar_data); + //set callback functions for scroll bars + id1=SetCallbackFunction(ScrollBarH,SCROLLBAR_CHANGED_EVENT,&ScrollStateH,NULL); + id2=SetCallbackFunction(ScrollBarV,SCROLLBAR_CHANGED_EVENT,&ScrollStateV,NULL); + //pack scroll bars in window + PackControls(window,ScrollBarH); + PackControls(window,ScrollBarV); + //start minl libGUI loop + LibGUImain(window); +} diff --git a/programs/develop/libraries/libGUI/examples/src/scrolled_window.c b/programs/develop/libraries/libGUI/examples/src/scrolled_window.c new file mode 100644 index 0000000000..6aa550d620 --- /dev/null +++ b/programs/develop/libraries/libGUI/examples/src/scrolled_window.c @@ -0,0 +1,67 @@ +/* + test libGUI library +*/ +#include "stdarg.h" +#include "libGUI.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" + +void callback_func_delete_window(header_t *control,void *data) +{ + QuitLibGUI((parent_t*)control); +} + +void callback_func(header_t *control,void *data) +{ + printf("\npressed button with ID=%d control=%d",(int)control->ctrl_ID,(int)control); +} + +int main(int argc, char *argv[]) +{ + parent_t *window; + gui_button_data_t button_data; + gui_button_t *button; + gui_scrolled_window_data_t scroll_win_data; + gui_scrolled_window_t *ScrollWin; + int i,j; + static char txt[20]; + + //load libGUI library + LoadLibGUI(NULL); + //create main window + window=CreateWindow(); + //change size of window + SetWindowSizeRequest(window,270,282); + + //create scrolled window + scroll_win_data.x=5; + scroll_win_data.y=5; + scroll_win_data.width=250; + scroll_win_data.height=250; + ScrollWin=CreateScrolledWindow(&scroll_win_data); + + //create buttons + for(j=1;j<=10;j++) + { + for(i=1;i<=10;i++) + { + button_data.x=10+(i-1)*75; + button_data.y=10+(j-1)*25; + button_data.width=70; + button_data.height=20; + + snprintf(txt,20,"(%d,%d)",j,i); + button=CreateButtonWithText(&button_data,txt); + + SetCallbackFunction(button,BUTTON_PRESSED_EVENT,&callback_func,NULL); + ScrolledWindowPackControls(ScrollWin,button); + } + } + //set callback function for button close window + SetCallbackFunction(window,DELETE_EVENT,&callback_func_delete_window,NULL); + //pack scrolled window in window + PackControls(window,ScrollWin); + //start main libGUI loop + LibGUImain(window); +} diff --git a/programs/develop/libraries/libGUI/examples/src/text.c b/programs/develop/libraries/libGUI/examples/src/text.c new file mode 100644 index 0000000000..6d42072806 --- /dev/null +++ b/programs/develop/libraries/libGUI/examples/src/text.c @@ -0,0 +1,45 @@ +/* + hello world example +*/ + +#include "libGUI.h" + +#define TRUE 1 +#define FALSE 0 + +void callback_func_delete_window(header_t *control,void *data) +{ + QuitLibGUI((parent_t*)control); +} + +int main(int argc, char *argv[]) +{ + parent_t *window; + gui_text_data_t txtdata; + gui_text_t *text; + + //load libGUI library + LoadLibGUI(NULL);//load from default system path to library + //create main window + window=CreateWindow(); + //change size of window + SetWindowSizeRequest(window,92,46); + //set callback function for button close window + SetCallbackFunction(window,DELETE_EVENT,&callback_func_delete_window,NULL); + //create control text + txtdata.x=5; + txtdata.y=5; + txtdata.font=NULL;//use default system libGUI font + txtdata.background=TRUE;//use background for text + txtdata.color=0xffffff;//text color + txtdata.background_color=0xff8000;//background color + txtdata.text="Hello world!"; + text=CreateText(&txtdata); + + //pack control text in window + PackControls(window,text); + + //start libGUI main loop + LibGUImain(window); +} + diff --git a/programs/develop/sdk/trunk/libGUI/MSVC++/libGUI-devel.h b/programs/develop/sdk/trunk/libGUI/MSVC++/libGUI-devel.h new file mode 100644 index 0000000000..42d669c5c6 --- /dev/null +++ b/programs/develop/sdk/trunk/libGUI/MSVC++/libGUI-devel.h @@ -0,0 +1,591 @@ +/* + service structures of libGUI +*/ + +typedef unsigned int DWORD; +typedef unsigned char BYTE; +typedef unsigned short int WORD; +typedef unsigned int size_t; + +#define stdcall __stdcall +#define cdecl __cdecl + +///////////////////////////////////////////////////////////////////////// +// libGUI sysyem messages types +///////////////////////////////////////////////////////////////////////// +#define MESSAGE_FULL_REDRAW_ALL 1 +#define MESSAGE_KEYS_EVENT 2 +#define MESSAGE_SPECIALIZED 3 +#define MESSAGE_SET_FOCUSE 4 +#define MESSAGE_CHANGE_FOCUSE 5 +#define MESSAGE_MOUSE_EVENT 6 +#define MESSAGE_CHANGE_POSITION_EVENT 7 +#define MESSAGE_CHANGESIZE_EVENT 8 +#define MESSAGE_CALL_TIMER_EVENT 9 +#define MESSAGE_FULL_REDRAW_ALL_WITH_FINITION 10 +#define MESSAGE_SET_MAIN_PARENT 11 +#define MESSAGE_DESTROY_CONTROL -1 + +///////////////////////////////////////////////////////////////////////// +// system keys states +///////////////////////////////////////////////////////////////////////// +#define KEY_DOWN 16 +#define KEY_UP 17 +#define KEY_HOTKEY 18 +///////////////////////////////////////////////////////////////////////// +// system mouse buttons states +///////////////////////////////////////////////////////////////////////// +#define MOUSE_LEFT_BUTTON_DOWN 19 +#define MOUSE_LEFT_BUTTON_UP 20 +#define MOUSE_RIGHT_BUTTON_DOWN 21 +#define MOUSE_RIGHT_BUTTON_UP 22 +#define MOUSE_MIDDLE_BUTTON_DOWN 23 +#define MOUSE_MIDDLE_BUTTON_UP 24 +#define MOUSE_4_BUTTON_DOWN 25 +#define MOUSE_4_BUTTON_UP 26 +#define MOUSE_5_BUTTON_DOWN 27 +#define MOUSE_5_BUTTON_UP 28 + + +//----------------------------------------------------------------------- +// CONNECT EVENTS FOR CALLBACKs +//----------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////// +// connect events for button +//////////////////////////////////////////////////////////////// +#define BUTTON_ENTER_EVENT 29 +#define BUTTON_LEAVE_EVENT 30 +#define BUTTON_PRESSED_EVENT 31 +#define BUTTON_RELEASED_EVENT 32 + +//////////////////////////////////////////////////////////////// +// connect events for scroll bar +//////////////////////////////////////////////////////////////// +#define SCROLLBAR_CHANGED_EVENT 33 + +//////////////////////////////////////////////////////////////// +// connect events for main parent window +//////////////////////////////////////////////////////////////// +#define DELETE_EVENT 36 + +//////////////////////////////////////////////////////////////// +// font type structure +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct FONT +{ + DWORD *fnt_draw; + DWORD *fnt_unpacker; + DWORD *fnt_fd; + DWORD *fnt_bk; + int sizex; + int sizey; + int size; + int encoding_type; + char *font; + char *fnt_name; + DWORD type; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct FONT font_t; + +//////////////////////////////////////////////////////////////// +// header of parent of control +//////////////////////////////////////////////////////////////// + +#pragma pack(push,1) +struct HEADERPARENT +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD **control_for_callback_function; + DWORD **callback_for_control_callback; + DWORD number_callbacks; + DWORD *global_active_control_for_keys; + DWORD *message; + DWORD *timer_bk; + DWORD *timer_fd; + DWORD number_timers_for_controls; + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *IDL_func; + DWORD *IDL_func_data; +}; +#pragma pack(pop) + +typedef struct HEADERPARENT parent_t; + +//////////////////////////////////////////////////////////////// +// header of control +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct HEADER +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct HEADER header_t; +//////////////////////////////////////////////////////////////// +// callback structure for callback function of control +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct CALLBACK +{ + DWORD *clb_bk; + DWORD *clb_fd; + DWORD *clb_control; + DWORD *func; + DWORD *func_data; + DWORD connect_event; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct CALLBACK gui_callback_t; +//////////////////////////////////////////////////////////////// +// timer +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct TIMER +{ + DWORD *tmr_bk; + DWORD *tmr_fd; + DWORD *tmr_parent; + DWORD *func; + DWORD *func_data; + DWORD last_time; + DWORD time_tick; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct TIMER gui_timer_t; +//////////////////////////////////////////////////////////////// +// structure for callback events +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct CALLBACKEVENT +{ + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *calev_parent; + DWORD *func; + DWORD *func_data; + DWORD event_type; +}; +#pragma pack(pop) + +typedef struct CALLBACKEVENT gui_callbackevent_t; + +//////////////////////////////////////////////////////////////// +// type of data - structure message +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct MESSAGE +{ + DWORD type; + DWORD arg1; + DWORD arg2; + DWORD arg3; + DWORD arg4; +}; +#pragma pack(pop) + +typedef struct MESSAGE gui_message_t; + +//////////////////////////////////////////////////////////////// +// button +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlButton +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //button's data + BYTE btn_flags; +}; +#pragma pack(pop) + +typedef struct ControlButton gui_button_t; + +// information for creating control Button +#pragma pack(push,1) +struct ButtonData +{ + int x; + int y; + int width; + int height; +}; +#pragma pack(pop) + +typedef struct ButtonData gui_button_data_t; + +//////////////////////////////////////////////////////////////// +// scroller +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlScrollBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scroll bar's data + float ruller_size; + float ruller_pos; + float ruller_step; + BYTE scb_flags; +}; +#pragma pack(pop) + +typedef struct ControlScrollBar gui_scroll_bar_t; + +#pragma pack(push,1) +struct ScrollBarData +{ + int x; + int y; + int width; + int height; + float ruller_size; + float ruller_pos; + float ruller_step; +}; +#pragma pack(pop) + +typedef struct ScrollBarData gui_scroll_bar_data_t; +//////////////////////////////////////////////////////////////// +// progressbar +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlProgressBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //progress bar's data + float progress; + BYTE prb_flags; +}; +#pragma pack(pop) + +typedef struct ControlProgressBar gui_progress_bar_t; + +#pragma pack(push,1) +struct ProgressBarData +{ + int x; + int y; + int width; + int height; + float progress; +}; +#pragma pack(pop) + +typedef struct ProgressBarData gui_progress_bar_data_t; +//////////////////////////////////////////////////////////////// +// scrolled window +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlScrolledWindow +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scrolled windows's data + DWORD virtual_x; + DWORD virtual_y; + DWORD virtual_sizex; + DWORD virtual_sizey; + DWORD *virtual_controls_x; + DWORD *virtual_controls_y; + DWORD number_virtual_controls; + DWORD scroll_arrea_sizex; + DWORD scroll_arrea_sizey; + DWORD *horizontal_scroll; + DWORD *vertical_scroll; + BYTE scw_flags; +}; +#pragma pack(pop) + +typedef struct ControlScrolledWindow gui_scrolled_window_t; + +#pragma pack(push,1) +struct ScrolledWindowData +{ + int x; + int y; + int width; + int height; +}; +#pragma pack(pop) + +typedef struct ScrolledWindowData gui_scrolled_window_data_t; + +//////////////////////////////////////////////////////////////// +// image +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlImage +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + char bits_per_pixel; + char bytes_per_pixel; + char *img; +}; +#pragma pack(pop) + +typedef struct ControlImage gui_image_t; + +#pragma pack(push,1) +struct ImageData +{ + int x; + int y; + int width; + int height; + char bits_per_pixel; +}; +#pragma pack(pop) + +typedef struct ImageData gui_image_data_t; + +//////////////////////////////////////////////////////////////// +// text +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlText +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD *font; + DWORD color; + DWORD background_color; + char *text; + BYTE txt_flags; +}; +#pragma pack(pop) + +typedef struct ControlText gui_text_t; + +#pragma pack(push,1) +struct TextData +{ + int x; + int y; + DWORD *font; + DWORD color; + DWORD background_color; + char background; + char *text; +}; +#pragma pack(pop) + +typedef struct TextData gui_text_data_t; +///////////////////////////////////////////////////////////////// +// load libGUI library and link functions +///////////////////////////////////////////////////////////////// +void LoadLibGUI(char *lib_path); + +//********************************************************************** +// libGUI service functions +//********************************************************************** + +DWORD (stdcall *LibGUIversion)(void); +char (stdcall *InitLibGUI)(void); +void (stdcall *LibGUImain)(parent_t *WindowParent); +void (stdcall *QuitLibGUI)(parent_t *window); + +parent_t* (stdcall *CreateWindow)(void); +void (stdcall *SetWindowSizeRequest)(parent_t *WindowParent,int size_x,int size_y); + +void (stdcall *PackControls)(void *Parent,void *control); +void (stdcall *DestroyControl)(void *control); +void (stdcall *SetControlSizeRequest)(void *Control,int new_size_x,int new_size_y); +int (stdcall *GetControlSizeX)(void *Control); +int (stdcall *GetControlSizeY)(void *Control); +void (stdcall *SetControlNewPosition)(void *Control,int new_x,int new_y); +int (stdcall *GetControlPositionX)(void *Control); +int (stdcall *GetControlPositionY)(void *Control); +void* (stdcall *SetFocuse)(void *Control); +void (stdcall *RedrawControl)(void *Control); +void (stdcall *SpecialRedrawControl)(void *Control); + +gui_callback_t* (stdcall *SetCallbackFunction)(void *Control, + int event_name,void *callback_func, + void *callback_func_data); +void (stdcall *BlockCallbackFunction)(void *Control,gui_callback_t *callback_ID); +void (stdcall *UnblockCallbackFunction)(void *Control,gui_callback_t *callback_ID); + +void (stdcall *SetIDL_Function)(parent_t *Parent,void *function,void *function_data); +void (stdcall *DestroyIDL_Function)(parent_t *Parent); + +gui_timer_t* (stdcall *SetTimerCallbackForFunction)(parent_t *parent_window, + int time_tick,void *func,void *func_data); +void (stdcall *DestroyTimerCallbackForFunction)(gui_timer_t *timer); + +gui_callbackevent_t* (stdcall *SetCallbackFunctionForEvent)(parent_t *parent_window, + int event_type,void *func,void *func_data); +void (stdcall *DestroyCallbackFunctionForEvent)(gui_callbackevent_t *callback_event); + +gui_button_t* (stdcall *CreateButton)(gui_button_data_t *info_for_control); +gui_button_t* (stdcall *CreateButtonWithText)(gui_button_data_t *info,char *txt); + +gui_progress_bar_t* (stdcall *CreateProgressBar)(gui_progress_bar_data_t *info_for_control); +void (stdcall *SetProgressBarPulse)(gui_progress_bar_t *ProgressBar,int time_update); +void (stdcall *ProgressBarSetText)(gui_progress_bar_t *pbar,char *txt); +char* (stdcall *ProgressBarGetText)(gui_progress_bar_t *pbar); + +gui_scroll_bar_t* (stdcall *CreateHorizontalScrollBar)(gui_scroll_bar_data_t *info_for_control); +gui_scroll_bar_t* (stdcall *CreateVerticalScrollBar)(gui_scroll_bar_data_t *info_for_control); + +gui_scrolled_window_t* (stdcall *CreateScrolledWindow)(gui_scrolled_window_data_t *info_for_control); +void (stdcall *ScrolledWindowPackControls)(gui_scrolled_window_t *parent,void *Control); + +gui_image_t* (stdcall *CreateImage)(gui_image_data_t *info_for_control); + +gui_text_t* (stdcall *CreateText)(gui_text_data_t *info_for_control); +void (stdcall *TextBackgroundOn)(gui_text_t *Text); +void (stdcall *TextBackgroundOff)(gui_text_t *Text); + +font_t* (stdcall *LoadFont)(char *fullfontname); +void (stdcall *FreeFont)(font_t *font); + diff --git a/programs/develop/sdk/trunk/libGUI/MSVC++/libGUI.cpp b/programs/develop/sdk/trunk/libGUI/MSVC++/libGUI.cpp new file mode 100644 index 0000000000..8789076f25 --- /dev/null +++ b/programs/develop/sdk/trunk/libGUI/MSVC++/libGUI.cpp @@ -0,0 +1,250 @@ +/* + libGUI dinamic library SDK + load library and link function + */ + +#include "libGUI-devel.h" + +#pragma pack(push,1) +struct IMPORT +{ + char *name; + void *function; +}; +#pragma pack(pop) + +typedef struct IMPORT import_t; + +static char *sys_libGUI_path="/sys/lib/libGUI.obj"; + +static char* funcnames[] = {"LibGUIversion","InitLibGUI","LibGUImain","QuitLibGUI", + + "CreateWindow","SetWindowSizeRequest", + + "PackControls","DestroyControl","SetControlSizeRequest","GetControlSizeX", + "GetControlSizeY","SetControlNewPosition","GetControlPositionX", + "GetControlPositionY","SetFocuse","RedrawControl","SpecialRedrawControl", + + "SetCallbackFunction","BlockCallbackFunction","UnblockCallbackFunction", + + "SetIDL_Function","DestroyIDL_Function", + + "SetTimerCallbackForFunction","DestroyTimerCallbackForFunction", + + "SetCallbackFunctionForEvent","DestroyCallbackFunctionForEvent", + + "CreateButton","CreateButtonWithText", + + "CreateProgressBar","SetProgressBarPulse","ProgressBarSetText","ProgressBarGetText", + + "CreateHorizontalScrollBar","CreateVerticalScrollBar", + + "CreateScrolledWindow","ScrolledWindowPackControls", + + "CreateImage", + + "CreateText","TextBackgroundOn","TextBackgroundOff", + + "LoadFont","FreeFont"}; + + +static inline void* gui_ksys_load_dll(char *path) +{ + void *dll_export; + + __asm{ + mov eax,68 + mov ebx,19 + mov ecx,path + int 0x40 + mov dll_export,eax + }; + + return(dll_export); +} + +static inline void gui_ksys_debug_out(int c) +{ + __asm{ + mov eax,63 + mov ebx,1 + mov ecx,c + int 0x40 + }; +} + +static void gui_debug_out_str(char *s) +{ + + while(*s) + { + if (*s=='\n') gui_ksys_debug_out(13); + + gui_ksys_debug_out(*s); + s++; + } +} + +static int gui_strcmp(const char* string1, const char* string2) +{ + while (1) + { + if (*string1<*string2) + return -1; + if (*string1>*string2) + return 1; + if (*string1=='\0') + return 0; + string1++; + string2++; + } +} + +static void* gui_cofflib_getproc(import_t *lib, char *name) +{ + int i; + + for(i = 0; lib[i].name && gui_strcmp(name, lib[i].name); i++); + + if(lib[i].name) return lib[i].function; + else return 0; +} + +static inline void __declspec(noreturn) gui_ksys_exit(int value) +{ + __asm{ + xor eax,eax + dec eax + mov ebx,value + int 0x40 + }; +} + +void link_libGUI(import_t *exp,char **imports) +{ + LibGUIversion=(DWORD (stdcall *)(void)) + gui_cofflib_getproc(exp,imports[0]); + InitLibGUI=(char (stdcall *)(void)) + gui_cofflib_getproc(exp,imports[1]); + LibGUImain=(void (stdcall *)(parent_t *WindowParent)) + gui_cofflib_getproc(exp,imports[2]); + QuitLibGUI=(void (stdcall *)(parent_t *window)) + gui_cofflib_getproc(exp,imports[3]); + CreateWindow=(parent_t* (stdcall *)(void)) + gui_cofflib_getproc(exp,imports[4]); + SetWindowSizeRequest=(void (stdcall *)(parent_t *WindowParent,int size_x,int size_y)) + gui_cofflib_getproc(exp,imports[5]); + PackControls=(void (stdcall *)(void *Parent,void *control)) + gui_cofflib_getproc(exp,imports[6]); + DestroyControl=(void (stdcall *)(void *control)) + gui_cofflib_getproc(exp,imports[7]); + SetControlSizeRequest=(void (stdcall *)(void *Control,int new_size_x,int new_size_y)) + gui_cofflib_getproc(exp,imports[8]); + GetControlSizeX=(int (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[9]); + GetControlSizeY=(int (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[10]); + SetControlNewPosition=(void (stdcall *)(void *Control,int new_x,int new_y)) + gui_cofflib_getproc(exp,imports[11]); + GetControlPositionX=(int (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[12]); + GetControlPositionY=(int (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[13]); + SetFocuse=(void* (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[14]); + RedrawControl=(void (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[15]); + SpecialRedrawControl=(void (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[16]); + SetCallbackFunction=(gui_callback_t* (stdcall *)(void *Control, + int event_name,void *callback_func,void *callback_func_data)) + gui_cofflib_getproc(exp,imports[17]); + BlockCallbackFunction=(void (stdcall *)(void *Control,gui_callback_t *callback_ID)) + gui_cofflib_getproc(exp,imports[18]); + UnblockCallbackFunction=(void (stdcall *)(void *Control,gui_callback_t *callback_ID)) + gui_cofflib_getproc(exp,imports[19]); + SetIDL_Function=(void (stdcall *)(parent_t *Parent,void *function,void *function_data)) + gui_cofflib_getproc(exp,imports[20]); + DestroyIDL_Function=(void (stdcall *)(parent_t *Parent)) + gui_cofflib_getproc(exp,imports[21]); + SetTimerCallbackForFunction=(gui_timer_t* (stdcall *)(parent_t *parent_window, + int time_tick,void *func,void *func_data)) + gui_cofflib_getproc(exp,imports[22]); + DestroyTimerCallbackForFunction=(void (stdcall *)(gui_timer_t *timer)) + gui_cofflib_getproc(exp,imports[23]); + SetCallbackFunctionForEvent=(gui_callbackevent_t* (stdcall *)(parent_t *parent_window, + int event_type,void *func,void *func_data)) + gui_cofflib_getproc(exp,imports[24]); + DestroyCallbackFunctionForEvent=(void (stdcall *)(gui_callbackevent_t *callback_event)) + gui_cofflib_getproc(exp,imports[25]); + CreateButton=(gui_button_t* (stdcall *)(gui_button_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[26]); + CreateButtonWithText=(gui_button_t* (stdcall *)(gui_button_data_t *info,char *txt)) + gui_cofflib_getproc(exp,imports[27]); + CreateProgressBar=(gui_progress_bar_t* (stdcall *)(gui_progress_bar_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[28]); + SetProgressBarPulse=(void (stdcall *)(gui_progress_bar_t *ProgressBar,int time_update)) + gui_cofflib_getproc(exp,imports[29]); + ProgressBarSetText=(void (stdcall *)(gui_progress_bar_t *pbar,char *txt)) + gui_cofflib_getproc(exp,imports[30]); + ProgressBarGetText=(char* (stdcall *)(gui_progress_bar_t *pbar)) + gui_cofflib_getproc(exp,imports[31]); + CreateHorizontalScrollBar=(gui_scroll_bar_t* (stdcall *)(gui_scroll_bar_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[32]); + CreateVerticalScrollBar=(gui_scroll_bar_t* (stdcall *)(gui_scroll_bar_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[33]); + CreateScrolledWindow=(gui_scrolled_window_t* (stdcall *)(gui_scrolled_window_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[34]); + ScrolledWindowPackControls=(void (stdcall *)(gui_scrolled_window_t *parent,void *Control)) + gui_cofflib_getproc(exp,imports[35]); + CreateImage=(gui_image_t* (stdcall *)(gui_image_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[36]); + CreateText=(gui_text_t* (stdcall *)(gui_text_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[37]); + TextBackgroundOn=(void (stdcall *)(gui_text_t *Text)) + gui_cofflib_getproc(exp,imports[38]); + TextBackgroundOff=(void (stdcall *)(gui_text_t *Text)) + gui_cofflib_getproc(exp,imports[39]); + LoadFont=(font_t* (stdcall *)(char *fullfontname)) + gui_cofflib_getproc(exp,imports[40]); + FreeFont=(void (stdcall *)(font_t *font)) + gui_cofflib_getproc(exp,imports[41]); +} + +void LoadLibGUI(char *lib_path) +{ + import_t *exp; + char *path; + DWORD vers; + + if (lib_path==0) + { + path=sys_libGUI_path; + exp=(import_t*)gui_ksys_load_dll(path); + } + else + { + path=lib_path; + exp=(import_t*)gui_ksys_load_dll(path); + } + + if (exp==0) + { + gui_debug_out_str("\ncan't load lib="); + gui_debug_out_str(path); + gui_ksys_exit(0); + } + else + { + link_libGUI(exp,funcnames); + if (InitLibGUI()) + { + gui_debug_out_str("\ncan't initialize libGUI"); + gui_ksys_exit(0); + } + } +} + + + + diff --git a/programs/develop/sdk/trunk/libGUI/MSVC++/libGUI.h b/programs/develop/sdk/trunk/libGUI/MSVC++/libGUI.h new file mode 100644 index 0000000000..4a5a0ddf91 --- /dev/null +++ b/programs/develop/sdk/trunk/libGUI/MSVC++/libGUI.h @@ -0,0 +1,591 @@ +/* + service structures of libGUI +*/ + +typedef unsigned int DWORD; +typedef unsigned char BYTE; +typedef unsigned short int WORD; +typedef unsigned int size_t; + +#define stdcall __stdcall + +///////////////////////////////////////////////////////////////////////// +// libGUI sysyem messages types +///////////////////////////////////////////////////////////////////////// +#define MESSAGE_FULL_REDRAW_ALL 1 +#define MESSAGE_KEYS_EVENT 2 +#define MESSAGE_SPECIALIZED 3 +#define MESSAGE_SET_FOCUSE 4 +#define MESSAGE_CHANGE_FOCUSE 5 +#define MESSAGE_MOUSE_EVENT 6 +#define MESSAGE_CHANGE_POSITION_EVENT 7 +#define MESSAGE_CHANGESIZE_EVENT 8 +#define MESSAGE_CALL_TIMER_EVENT 9 +#define MESSAGE_FULL_REDRAW_ALL_WITH_FINITION 10 +#define MESSAGE_SET_MAIN_PARENT 11 +#define MESSAGE_DESTROY_CONTROL -1 + +///////////////////////////////////////////////////////////////////////// +// system keys states +///////////////////////////////////////////////////////////////////////// +#define KEY_DOWN 16 +#define KEY_UP 17 +#define KEY_HOTKEY 18 +///////////////////////////////////////////////////////////////////////// +// system mouse buttons states +///////////////////////////////////////////////////////////////////////// +#define MOUSE_LEFT_BUTTON_DOWN 19 +#define MOUSE_LEFT_BUTTON_UP 20 +#define MOUSE_RIGHT_BUTTON_DOWN 21 +#define MOUSE_RIGHT_BUTTON_UP 22 +#define MOUSE_MIDDLE_BUTTON_DOWN 23 +#define MOUSE_MIDDLE_BUTTON_UP 24 +#define MOUSE_4_BUTTON_DOWN 25 +#define MOUSE_4_BUTTON_UP 26 +#define MOUSE_5_BUTTON_DOWN 27 +#define MOUSE_5_BUTTON_UP 28 + + +//----------------------------------------------------------------------- +// CONNECT EVENTS FOR CALLBACKs +//----------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////// +// connect events for button +//////////////////////////////////////////////////////////////// +#define BUTTON_ENTER_EVENT 29 +#define BUTTON_LEAVE_EVENT 30 +#define BUTTON_PRESSED_EVENT 31 +#define BUTTON_RELEASED_EVENT 32 + +//////////////////////////////////////////////////////////////// +// connect events for scroll bar +//////////////////////////////////////////////////////////////// +#define SCROLLBAR_CHANGED_EVENT 33 + +//////////////////////////////////////////////////////////////// +// connect events for main parent window +//////////////////////////////////////////////////////////////// +#define DELETE_EVENT 36 + +//////////////////////////////////////////////////////////////// +// font type structure +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct FONT +{ + DWORD *fnt_draw; + DWORD *fnt_unpacker; + DWORD *fnt_fd; + DWORD *fnt_bk; + int sizex; + int sizey; + int size; + int encoding_type; + char *font; + char *fnt_name; + DWORD type; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct FONT font_t; + +//////////////////////////////////////////////////////////////// +// header of parent of control +//////////////////////////////////////////////////////////////// + +#pragma pack(push,1) +struct HEADERPARENT +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD **control_for_callback_function; + DWORD **callback_for_control_callback; + DWORD number_callbacks; + DWORD *global_active_control_for_keys; + DWORD *message; + DWORD *timer_bk; + DWORD *timer_fd; + DWORD number_timers_for_controls; + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *IDL_func; + DWORD *IDL_func_data; +}; +#pragma pack(pop) + +typedef struct HEADERPARENT parent_t; + +//////////////////////////////////////////////////////////////// +// header of control +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct HEADER +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct HEADER header_t; +//////////////////////////////////////////////////////////////// +// callback structure for callback function of control +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct CALLBACK +{ + DWORD *clb_bk; + DWORD *clb_fd; + DWORD *clb_control; + DWORD *func; + DWORD *func_data; + DWORD connect_event; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct CALLBACK gui_callback_t; +//////////////////////////////////////////////////////////////// +// timer +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct TIMER +{ + DWORD *tmr_bk; + DWORD *tmr_fd; + DWORD *tmr_parent; + DWORD *func; + DWORD *func_data; + DWORD last_time; + DWORD time_tick; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct TIMER gui_timer_t; +//////////////////////////////////////////////////////////////// +// structure for callback events +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct CALLBACKEVENT +{ + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *calev_parent; + DWORD *func; + DWORD *func_data; + DWORD event_type; +}; +#pragma pack(pop) + +typedef struct CALLBACKEVENT gui_callbackevent_t; + +//////////////////////////////////////////////////////////////// +// type of data - structure message +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct MESSAGE +{ + DWORD type; + DWORD arg1; + DWORD arg2; + DWORD arg3; + DWORD arg4; +}; +#pragma pack(pop) + +typedef struct MESSAGE gui_message_t; + +//////////////////////////////////////////////////////////////// +// button +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlButton +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //button's data + BYTE btn_flags; +}; +#pragma pack(pop) + +typedef struct ControlButton gui_button_t; + +// information for creating control Button +#pragma pack(push,1) +struct ButtonData +{ + int x; + int y; + int width; + int height; +}; +#pragma pack(pop) + +typedef struct ButtonData gui_button_data_t; + +//////////////////////////////////////////////////////////////// +// scroller +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlScrollBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scroll bar's data + float ruller_size; + float ruller_pos; + float ruller_step; + BYTE scb_flags; +}; +#pragma pack(pop) + +typedef struct ControlScrollBar gui_scroll_bar_t; + +#pragma pack(push,1) +struct ScrollBarData +{ + int x; + int y; + int width; + int height; + float ruller_size; + float ruller_pos; + float ruller_step; +}; +#pragma pack(pop) + +typedef struct ScrollBarData gui_scroll_bar_data_t; +//////////////////////////////////////////////////////////////// +// progressbar +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlProgressBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //progress bar's data + float progress; + BYTE prb_flags; +}; +#pragma pack(pop) + +typedef struct ControlProgressBar gui_progress_bar_t; + +#pragma pack(push,1) +struct ProgressBarData +{ + int x; + int y; + int width; + int height; + float progress; +}; +#pragma pack(pop) + +typedef struct ProgressBarData gui_progress_bar_data_t; +//////////////////////////////////////////////////////////////// +// scrolled window +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlScrolledWindow +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scrolled windows's data + DWORD virtual_x; + DWORD virtual_y; + DWORD virtual_sizex; + DWORD virtual_sizey; + DWORD *virtual_controls_x; + DWORD *virtual_controls_y; + DWORD number_virtual_controls; + DWORD scroll_arrea_sizex; + DWORD scroll_arrea_sizey; + DWORD *horizontal_scroll; + DWORD *vertical_scroll; + BYTE scw_flags; +}; +#pragma pack(pop) + +typedef struct ControlScrolledWindow gui_scrolled_window_t; + +#pragma pack(push,1) +struct ScrolledWindowData +{ + int x; + int y; + int width; + int height; +}; +#pragma pack(pop) + +typedef struct ScrolledWindowData gui_scrolled_window_data_t; + +//////////////////////////////////////////////////////////////// +// image +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlImage +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + char bits_per_pixel; + char bytes_per_pixel; + char *img; +}; +#pragma pack(pop) + +typedef struct ControlImage gui_image_t; + +#pragma pack(push,1) +struct ImageData +{ + int x; + int y; + int width; + int height; + char bits_per_pixel; +}; +#pragma pack(pop) + +typedef struct ImageData gui_image_data_t; + +//////////////////////////////////////////////////////////////// +// text +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlText +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD *font; + DWORD color; + DWORD background_color; + char *text; + BYTE txt_flags; +}; +#pragma pack(pop) + +typedef struct ControlText gui_text_t; + +#pragma pack(push,1) +struct TextData +{ + int x; + int y; + DWORD *font; + DWORD color; + DWORD background_color; + char background; + char *text; +}; +#pragma pack(pop) + +typedef struct TextData gui_text_data_t; +///////////////////////////////////////////////////////////////// +// load libGUI library and link functions +///////////////////////////////////////////////////////////////// +void LoadLibGUI(char *lib_path); + +//********************************************************************** +// prototypes of libGUI service functions +//********************************************************************** + +extern DWORD (stdcall *LibGUIversion)(void); +extern char (stdcall *InitLibGUI)(void); +extern void (stdcall *LibGUImain)(parent_t *WindowParent); +extern void (stdcall *QuitLibGUI)(parent_t *window); + +extern parent_t* (stdcall *CreateWindow)(void); +extern void (stdcall *SetWindowSizeRequest)(parent_t *WindowParent,int size_x,int size_y); + +extern void (stdcall *PackControls)(void *Parent,void *control); +extern void (stdcall *DestroyControl)(void *control); +extern void (stdcall *SetControlSizeRequest)(void *Control,int new_size_x,int new_size_y); +extern int (stdcall *GetControlSizeX)(void *Control); +extern int (stdcall *GetControlSizeY)(void *Control); +extern void (stdcall *SetControlNewPosition)(void *Control,int new_x,int new_y); +extern int (stdcall *GetControlPositionX)(void *Control); +extern int (stdcall *GetControlPositionY)(void *Control); +extern void* (stdcall *SetFocuse)(void *Control); +extern void (stdcall *RedrawControl)(void *Control); +extern void (stdcall *SpecialRedrawControl)(void *Control); + +extern gui_callback_t* (stdcall *SetCallbackFunction)(void *Control, + int event_name,void *callback_func, + void *callback_func_data); +extern void (stdcall *BlockCallbackFunction)(void *Control,gui_callback_t *callback_ID); +extern void (stdcall *UnblockCallbackFunction)(void *Control,gui_callback_t *callback_ID); + +extern void (stdcall *SetIDL_Function)(parent_t *Parent,void *function,void *function_data); +extern void (stdcall *DestroyIDL_Function)(parent_t *Parent); + +extern gui_timer_t* (stdcall *SetTimerCallbackForFunction)(parent_t *parent_window, + int time_tick,void *func,void *func_data); +extern void (stdcall *DestroyTimerCallbackForFunction)(gui_timer_t *timer); + +extern gui_callbackevent_t* (stdcall *SetCallbackFunctionForEvent)(parent_t *parent_window, + int event_type,void *func,void *func_data); +extern void (stdcall *DestroyCallbackFunctionForEvent)(gui_callbackevent_t *callback_event); + +extern gui_button_t* (stdcall *CreateButton)(gui_button_data_t *info_for_control); +extern gui_button_t* (stdcall *CreateButtonWithText)(gui_button_data_t *info,char *txt); + +extern gui_progress_bar_t* (stdcall *CreateProgressBar)(gui_progress_bar_data_t *info_for_control); +extern void (stdcall *SetProgressBarPulse)(gui_progress_bar_t *ProgressBar,int time_update); +extern void (stdcall *ProgressBarSetText)(gui_progress_bar_t *pbar,char *txt); +extern char* (stdcall *ProgressBarGetText)(gui_progress_bar_t *pbar); + +extern gui_scroll_bar_t* (stdcall *CreateHorizontalScrollBar)(gui_scroll_bar_data_t *info_for_control); +extern gui_scroll_bar_t* (stdcall *CreateVerticalScrollBar)(gui_scroll_bar_data_t *info_for_control); + +extern gui_scrolled_window_t* (stdcall *CreateScrolledWindow)(gui_scrolled_window_data_t *info_for_control); +extern void (stdcall *ScrolledWindowPackControls)(gui_scrolled_window_t *parent,void *Control); + +extern gui_image_t* (stdcall *CreateImage)(gui_image_data_t *info_for_control); + +extern gui_text_t* (stdcall *CreateText)(gui_text_data_t *info_for_control); +extern void (stdcall *TextBackgroundOn)(gui_text_t *Text); +extern void (stdcall *TextBackgroundOff)(gui_text_t *Text); + +extern font_t* (stdcall *LoadFont)(char *fullfontname); +extern void (stdcall *FreeFont)(font_t *font); + + diff --git a/programs/develop/sdk/trunk/libGUI/MinGW(windows)/libGUI.c b/programs/develop/sdk/trunk/libGUI/MinGW(windows)/libGUI.c new file mode 100644 index 0000000000..0822f22599 --- /dev/null +++ b/programs/develop/sdk/trunk/libGUI/MinGW(windows)/libGUI.c @@ -0,0 +1,243 @@ +/* + libGUI dinamic library SDK + load library and link function + */ + +#include "libGUI.h" + + +struct IMPORT +{ + char *name; + void *function; +}; + +typedef struct IMPORT import_t; + +static char *sys_libGUI_path="/sys/lib/libGUI.obj"; + +static char* funcnames[] = {"LibGUIversion","InitLibGUI","LibGUImain","QuitLibGUI", + + "CreateWindow","SetWindowSizeRequest", + + "PackControls","DestroyControl","SetControlSizeRequest","GetControlSizeX", + "GetControlSizeY","SetControlNewPosition","GetControlPositionX", + "GetControlPositionY","SetFocuse","RedrawControl","SpecialRedrawControl", + + "SetCallbackFunction","BlockCallbackFunction","UnblockCallbackFunction", + + "SetIDL_Function","DestroyIDL_Function", + + "SetTimerCallbackForFunction","DestroyTimerCallbackForFunction", + + "SetCallbackFunctionForEvent","DestroyCallbackFunctionForEvent", + + "CreateButton","CreateButtonWithText", + + "CreateProgressBar","SetProgressBarPulse","ProgressBarSetText","ProgressBarGetText", + + "CreateHorizontalScrollBar","CreateVerticalScrollBar", + + "CreateScrolledWindow","ScrolledWindowPackControls", + + "CreateImage", + + "CreateText","TextBackgroundOn","TextBackgroundOff", + + "LoadFont","FreeFont"}; + + +static inline void* gui_ksys_load_dll(char *path) +{ + void *dll_export; + + __asm__ __volatile__( + "int $0x40" + :"=a"(dll_export) + :"a"(68),"b"(19),"c"(path)); + + return(dll_export); +} + +static inline void gui_ksys_debug_out(int c) +{ + __asm__ __volatile__( + "int $0x40" + : + :"a"(63),"b"(1),"c"(c)); +} + +static void gui_debug_out_str(char *s) +{ + + while(*s) + { + if (*s=='\n') gui_ksys_debug_out(13); + + gui_ksys_debug_out(*s); + s++; + } +} + +static int gui_strcmp(const char* string1, const char* string2) +{ + while (1) + { + if (*string1<*string2) + return -1; + if (*string1>*string2) + return 1; + if (*string1=='\0') + return 0; + string1++; + string2++; + } +} + +static void* gui_cofflib_getproc(import_t *lib, char *name) +{ + int i; + + for(i = 0; lib[i].name && gui_strcmp(name, lib[i].name); i++); + + if(lib[i].name) return lib[i].function; + else return NULL; +} + +static inline void gui_ksys_exit(int value) +{ + __asm__ __volatile__( + "int $0x40" + : + :"a"(-1),"b"(value)); +} + +void link_libGUI(import_t *exp,char **imports) +{ + LibGUIversion=(DWORD (stdcall *)(void)) + gui_cofflib_getproc(exp,imports[0]); + InitLibGUI=(char (stdcall *)(void)) + gui_cofflib_getproc(exp,imports[1]); + LibGUImain=(void (stdcall *)(parent_t *WindowParent)) + gui_cofflib_getproc(exp,imports[2]); + QuitLibGUI=(void (stdcall *)(parent_t *window)) + gui_cofflib_getproc(exp,imports[3]); + CreateWindow=(void* (stdcall *)(void)) + gui_cofflib_getproc(exp,imports[4]); + SetWindowSizeRequest=(void (stdcall *)(parent_t *WindowParent,int size_x,int size_y)) + gui_cofflib_getproc(exp,imports[5]); + PackControls=(void (stdcall *)(void *Parent,void *control)) + gui_cofflib_getproc(exp,imports[6]); + DestroyControl=(void (stdcall *)(void *control)) + gui_cofflib_getproc(exp,imports[7]); + SetControlSizeRequest=(void (stdcall *)(void *Control,int new_size_x,int new_size_y)) + gui_cofflib_getproc(exp,imports[8]); + GetControlSizeX=(int (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[9]); + GetControlSizeY=(int (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[10]); + SetControlNewPosition=(void (stdcall *)(void *Control,int new_x,int new_y)) + gui_cofflib_getproc(exp,imports[11]); + GetControlPositionX=(int (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[12]); + GetControlPositionY=(int (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[13]); + SetFocuse=(void* (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[14]); + RedrawControl=(void (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[15]); + SpecialRedrawControl=(void (stdcall *)(void *Control)) + gui_cofflib_getproc(exp,imports[16]); + SetCallbackFunction=(gui_callback_t* (stdcall *)(void *Control, + int event_name,void *callback_func,void *callback_func_data)) + gui_cofflib_getproc(exp,imports[17]); + BlockCallbackFunction=(void (stdcall *)(void *Control,gui_callback_t *callback_ID)) + gui_cofflib_getproc(exp,imports[18]); + UnblockCallbackFunction=(void (stdcall *)(void *Control,gui_callback_t *callback_ID)) + gui_cofflib_getproc(exp,imports[19]); + SetIDL_Function=(void (stdcall *)(parent_t *Parent,void *function,void *function_data)) + gui_cofflib_getproc(exp,imports[20]); + DestroyIDL_Function=(void (stdcall *)(parent_t *Parent)) + gui_cofflib_getproc(exp,imports[21]); + SetTimerCallbackForFunction=(gui_timer_t* (stdcall *)(parent_t *parent_window, + int time_tick,void *func,void *func_data)) + gui_cofflib_getproc(exp,imports[22]); + DestroyTimerCallbackForFunction=(void (stdcall *)(gui_timer_t *timer)) + gui_cofflib_getproc(exp,imports[23]); + SetCallbackFunctionForEvent=(gui_callbackevent_t* (stdcall *)(parent_t *parent_window, + int event_type,void *func,void *func_data)) + gui_cofflib_getproc(exp,imports[24]); + DestroyCallbackFunctionForEvent=(void (stdcall *)(gui_callbackevent_t *callback_event)) + gui_cofflib_getproc(exp,imports[25]); + CreateButton=(gui_button_t* (stdcall *)(gui_button_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[26]); + CreateButtonWithText=(gui_button_t* (stdcall *)(gui_button_data_t *info,char *txt)) + gui_cofflib_getproc(exp,imports[27]); + CreateProgressBar=(gui_progress_bar_t* (stdcall *)(gui_progress_bar_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[28]); + SetProgressBarPulse=(void (stdcall *)(gui_progress_bar_t *ProgressBar,int time_update)) + gui_cofflib_getproc(exp,imports[29]); + ProgressBarSetText=(void (stdcall *)(gui_progress_bar_t *pbar,char *txt)) + gui_cofflib_getproc(exp,imports[30]); + ProgressBarGetText=(char* (stdcall *)(gui_progress_bar_t *pbar)) + gui_cofflib_getproc(exp,imports[31]); + CreateHorizontalScrollBar=(gui_scroll_bar_t* (stdcall *)(gui_scroll_bar_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[32]); + CreateVerticalScrollBar=(gui_scroll_bar_t* (stdcall *)(gui_scroll_bar_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[33]); + CreateScrolledWindow=(gui_scrolled_window_t* (stdcall *)(gui_scrolled_window_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[34]); + ScrolledWindowPackControls=(void (stdcall *)(gui_scrolled_window_t *parent,void *Control)) + gui_cofflib_getproc(exp,imports[35]); + CreateImage=(gui_image_t* (stdcall *)(gui_image_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[36]); + CreateText=(gui_text_t* (stdcall *)(gui_text_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[37]); + TextBackgroundOn=(void (stdcall *)(gui_text_t *Text)) + gui_cofflib_getproc(exp,imports[38]); + TextBackgroundOff=(void (stdcall *)(gui_text_t *Text)) + gui_cofflib_getproc(exp,imports[39]); + LoadFont=(font_t* (stdcall *)(char *fullfontname)) + gui_cofflib_getproc(exp,imports[40]); + FreeFont=(void (stdcall *)(font_t *font)) + gui_cofflib_getproc(exp,imports[41]); +} + +void LoadLibGUI(char *lib_path) +{ + import_t *export; + char *path; + DWORD vers; + + if (lib_path==NULL) + { + path=sys_libGUI_path; + export=(import_t*)gui_ksys_load_dll(path); + } + else + { + path=lib_path; + export=(import_t*)gui_ksys_load_dll(path); + } + + if (export==NULL) + { + gui_debug_out_str("\ncan't load lib="); + gui_debug_out_str(path); + gui_ksys_exit(0); + } + else + { + link_libGUI(export,funcnames); + if (InitLibGUI()) + { + gui_debug_out_str("\ncan't initialize libGUI"); + gui_ksys_exit(0); + } + gui_debug_out_str(" initialized"); + } +} + + + + diff --git a/programs/develop/sdk/trunk/libGUI/MinGW(windows)/libGUI.h b/programs/develop/sdk/trunk/libGUI/MinGW(windows)/libGUI.h new file mode 100644 index 0000000000..5f0c5c0351 --- /dev/null +++ b/programs/develop/sdk/trunk/libGUI/MinGW(windows)/libGUI.h @@ -0,0 +1,591 @@ +/* + service structures of libGUI +*/ +#define NULL (void*)0 + +typedef unsigned int DWORD; +typedef unsigned char BYTE; +typedef unsigned short int WORD; +typedef unsigned int size_t; + +#define stdcall __stdcall +#define cdecl __cdecl + +///////////////////////////////////////////////////////////////////////// +// libGUI sysyem messages types +///////////////////////////////////////////////////////////////////////// +#define MESSAGE_FULL_REDRAW_ALL 1 +#define MESSAGE_KEYS_EVENT 2 +#define MESSAGE_SPECIALIZED 3 +#define MESSAGE_SET_FOCUSE 4 +#define MESSAGE_CHANGE_FOCUSE 5 +#define MESSAGE_MOUSE_EVENT 6 +#define MESSAGE_CHANGE_POSITION_EVENT 7 +#define MESSAGE_CHANGESIZE_EVENT 8 +#define MESSAGE_CALL_TIMER_EVENT 9 +#define MESSAGE_FULL_REDRAW_ALL_WITH_FINITION 10 +#define MESSAGE_SET_MAIN_PARENT 11 +#define MESSAGE_DESTROY_CONTROL -1 + +///////////////////////////////////////////////////////////////////////// +// system keys states +///////////////////////////////////////////////////////////////////////// +#define KEY_DOWN 16 +#define KEY_UP 17 +#define KEY_HOTKEY 18 +///////////////////////////////////////////////////////////////////////// +// system mouse buttons states +///////////////////////////////////////////////////////////////////////// +#define MOUSE_LEFT_BUTTON_DOWN 19 +#define MOUSE_LEFT_BUTTON_UP 20 +#define MOUSE_RIGHT_BUTTON_DOWN 21 +#define MOUSE_RIGHT_BUTTON_UP 22 +#define MOUSE_MIDDLE_BUTTON_DOWN 23 +#define MOUSE_MIDDLE_BUTTON_UP 24 +#define MOUSE_4_BUTTON_DOWN 25 +#define MOUSE_4_BUTTON_UP 26 +#define MOUSE_5_BUTTON_DOWN 27 +#define MOUSE_5_BUTTON_UP 28 + + +//----------------------------------------------------------------------- +// CONNECT EVENTS FOR CALLBACKs +//----------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////// +// connect events for button +//////////////////////////////////////////////////////////////// +#define BUTTON_ENTER_EVENT 29 +#define BUTTON_LEAVE_EVENT 30 +#define BUTTON_PRESSED_EVENT 31 +#define BUTTON_RELEASED_EVENT 32 + +//////////////////////////////////////////////////////////////// +// connect events for scroll bar +//////////////////////////////////////////////////////////////// +#define SCROLLBAR_CHANGED_EVENT 33 + +//////////////////////////////////////////////////////////////// +// connect events for main parent window +//////////////////////////////////////////////////////////////// +#define DELETE_EVENT 36 + +//////////////////////////////////////////////////////////////// +// font type structure +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct FONT +{ + DWORD *fnt_draw; + DWORD *fnt_unpacker; + DWORD *fnt_fd; + DWORD *fnt_bk; + int sizex; + int sizey; + int size; + int encoding_type; + char *font; + char *fnt_name; + DWORD type; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct FONT font_t; + +//////////////////////////////////////////////////////////////// +// header of parent of control +//////////////////////////////////////////////////////////////// + +#pragma pack(push,1) +struct HEADERPARENT +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD **control_for_callback_function; + DWORD **callback_for_control_callback; + DWORD number_callbacks; + DWORD *global_active_control_for_keys; + DWORD *message; + DWORD *timer_bk; + DWORD *timer_fd; + DWORD number_timers_for_controls; + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *IDL_func; + DWORD *IDL_func_data; +}; +#pragma pack(pop) + +typedef struct HEADERPARENT parent_t; + +//////////////////////////////////////////////////////////////// +// header of control +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct HEADER +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct HEADER header_t; +//////////////////////////////////////////////////////////////// +// callback structure for callback function of control +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct CALLBACK +{ + DWORD *clb_bk; + DWORD *clb_fd; + DWORD *clb_control; + DWORD *func; + DWORD *func_data; + DWORD connect_event; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct CALLBACK gui_callback_t; +//////////////////////////////////////////////////////////////// +// timer +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct TIMER +{ + DWORD *tmr_bk; + DWORD *tmr_fd; + DWORD *tmr_parent; + DWORD *func; + DWORD *func_data; + DWORD last_time; + DWORD time_tick; + DWORD flags; +}; +#pragma pack(pop) + +typedef struct TIMER gui_timer_t; +//////////////////////////////////////////////////////////////// +// structure for callback events +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct CALLBACKEVENT +{ + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *calev_parent; + DWORD *func; + DWORD *func_data; + DWORD event_type; +}; +#pragma pack(pop) + +typedef struct CALLBACKEVENT gui_callbackevent_t; + +//////////////////////////////////////////////////////////////// +// type of data - structure message +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct MESSAGE +{ + DWORD type; + DWORD arg1; + DWORD arg2; + DWORD arg3; + DWORD arg4; +}; +#pragma pack(pop) + +typedef struct MESSAGE gui_message_t; + +//////////////////////////////////////////////////////////////// +// button +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlButton +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //button's data + BYTE btn_flags; +}; +#pragma pack(pop) + +typedef struct ControlButton gui_button_t; + +// information for creating control Button +#pragma pack(push,1) +struct ButtonData +{ + int x; + int y; + int width; + int height; +}; +#pragma pack(pop) + +typedef struct ButtonData gui_button_data_t; + +//////////////////////////////////////////////////////////////// +// scroller +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlScrollBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scroll bar's data + float ruller_size; + float ruller_pos; + float ruller_step; + BYTE scb_flags; +}; + +typedef struct ControlScrollBar gui_scroll_bar_t; + +#pragma pack(push,1) +struct ScrollBarData +{ + int x; + int y; + int width; + int height; + float ruller_size; + float ruller_pos; + float ruller_step; +}; +#pragma pack(pop) + +typedef struct ScrollBarData gui_scroll_bar_data_t; +//////////////////////////////////////////////////////////////// +// progressbar +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlProgressBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //progress bar's data + float progress; + BYTE prb_flags; +}; +#pragma pack(pop) + +typedef struct ControlProgressBar gui_progress_bar_t; + +#pragma pack(push,1) +struct ProgressBarData +{ + int x; + int y; + int width; + int height; + float progress; +}; +#pragma pack(pop) + +typedef struct ProgressBarData gui_progress_bar_data_t; +//////////////////////////////////////////////////////////////// +// scrolled window +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlScrolledWindow +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scrolled windows's data + DWORD virtual_x; + DWORD virtual_y; + DWORD virtual_sizex; + DWORD virtual_sizey; + DWORD *virtual_controls_x; + DWORD *virtual_controls_y; + DWORD number_virtual_controls; + DWORD scroll_arrea_sizex; + DWORD scroll_arrea_sizey; + DWORD *horizontal_scroll; + DWORD *vertical_scroll; + BYTE scw_flags; +}; +#pragma pack(pop) + +typedef struct ControlScrolledWindow gui_scrolled_window_t; + +#pragma pack(push,1) +struct ScrolledWindowData +{ + int x; + int y; + int width; + int height; +}; +#pragma pack(pop) + +typedef struct ScrolledWindowData gui_scrolled_window_data_t; + +//////////////////////////////////////////////////////////////// +// image +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlImage +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + char bits_per_pixel; + char bytes_per_pixel; + char *img; +}; +#pragma pack(pop) + +typedef struct ControlImage gui_image_t; + +#pragma pack(push,1) +struct ImageData +{ + int x; + int y; + int width; + int height; + char bits_per_pixel; +}; +#pragma pack(pop) + +typedef struct ImageData gui_image_data_t; + +//////////////////////////////////////////////////////////////// +// text +//////////////////////////////////////////////////////////////// +#pragma pack(push,1) +struct ControlText +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD *font; + DWORD color; + DWORD background_color; + char *text; + BYTE txt_flags; +}; +#pragma pack(pop) + +typedef struct ControlText gui_text_t; + +#pragma pack(push,1) +struct TextData +{ + int x; + int y; + DWORD *font; + DWORD color; + DWORD background_color; + char background; + char *text; +}; +#pragma pack(pop) + +typedef struct TextData gui_text_data_t; +///////////////////////////////////////////////////////////////// +// load libGUI library and link functions +///////////////////////////////////////////////////////////////// +void LoadLibGUI(char *lib_path); + +//********************************************************************** +// libGUI service functions +//********************************************************************** + +DWORD (stdcall *LibGUIversion)(void); +char (stdcall *InitLibGUI)(void); +void (stdcall *LibGUImain)(parent_t *WindowParent); +void (stdcall *QuitLibGUI)(parent_t *window); + +void* (stdcall *CreateWindow)(void); +void (stdcall *SetWindowSizeRequest)(parent_t *WindowParent,int size_x,int size_y); + +void (stdcall *PackControls)(void *Parent,void *control); +void (stdcall *DestroyControl)(void *control); +void (stdcall *SetControlSizeRequest)(void *Control,int new_size_x,int new_size_y); +int (stdcall *GetControlSizeX)(void *Control); +int (stdcall *GetControlSizeY)(void *Control); +void (stdcall *SetControlNewPosition)(void *Control,int new_x,int new_y); +int (stdcall *GetControlPositionX)(void *Control); +int (stdcall *GetControlPositionY)(void *Control); +void* (stdcall *SetFocuse)(void *Control); +void (stdcall *RedrawControl)(void *Control); +void (stdcall *SpecialRedrawControl)(void *Control); + +gui_callback_t* (stdcall *SetCallbackFunction)(void *Control, + int event_name,void *callback_func, + void *callback_func_data); +void (stdcall *BlockCallbackFunction)(void *Control,gui_callback_t *callback_ID); +void (stdcall *UnblockCallbackFunction)(void *Control,gui_callback_t *callback_ID); + +void (stdcall *SetIDL_Function)(parent_t *Parent,void *function,void *function_data); +void (stdcall *DestroyIDL_Function)(parent_t *Parent); + +gui_timer_t* (stdcall *SetTimerCallbackForFunction)(parent_t *parent_window, + int time_tick,void *func,void *func_data); +void (stdcall *DestroyTimerCallbackForFunction)(gui_timer_t *timer); + +gui_callbackevent_t* (stdcall *SetCallbackFunctionForEvent)(parent_t *parent_window, + int event_type,void *func,void *func_data); +void (stdcall *DestroyCallbackFunctionForEvent)(gui_callbackevent_t *callback_event); + +gui_button_t* (stdcall *CreateButton)(gui_button_data_t *info_for_control); +gui_button_t* (stdcall *CreateButtonWithText)(gui_button_data_t *info,char *txt); + +gui_progress_bar_t* (stdcall *CreateProgressBar)(gui_progress_bar_data_t *info_for_control); +void (stdcall *SetProgressBarPulse)(gui_progress_bar_t *ProgressBar,int time_update); +void (stdcall *ProgressBarSetText)(gui_progress_bar_t *pbar,char *txt); +char* (stdcall *ProgressBarGetText)(gui_progress_bar_t *pbar); + +gui_scroll_bar_t* (stdcall *CreateHorizontalScrollBar)(gui_scroll_bar_data_t *info_for_control); +gui_scroll_bar_t* (stdcall *CreateVerticalScrollBar)(gui_scroll_bar_data_t *info_for_control); + +gui_scrolled_window_t* (stdcall *CreateScrolledWindow)(gui_scrolled_window_data_t *info_for_control); +void (stdcall *ScrolledWindowPackControls)(gui_scrolled_window_t *parent,void *Control); + +gui_image_t* (stdcall *CreateImage)(gui_image_data_t *info_for_control); + +gui_text_t* (stdcall *CreateText)(gui_text_data_t *info_for_control); +void (stdcall *TextBackgroundOn)(gui_text_t *Text); +void (stdcall *TextBackgroundOff)(gui_text_t *Text); + +font_t* (stdcall *LoadFont)(char *fullfontname); +void (stdcall *FreeFont)(font_t *font); + diff --git a/programs/develop/sdk/trunk/libGUI/gcc(unix)/libGUI.c b/programs/develop/sdk/trunk/libGUI/gcc(unix)/libGUI.c new file mode 100644 index 0000000000..3c9f1fd527 --- /dev/null +++ b/programs/develop/sdk/trunk/libGUI/gcc(unix)/libGUI.c @@ -0,0 +1,241 @@ +/* + libGUI dinamic library SDK + load library and link function + */ + +#include "libGUI.h" + + +struct IMPORT +{ + char *name; + void *function; +}__attribute__((packed)); + +typedef struct IMPORT import_t; + +static char *sys_libGUI_path="/sys/lib/libGUI.obj"; + +static char* funcnames[] = {"LibGUIversion","InitLibGUI","LibGUImain","QuitLibGUI", + + "CreateWindow","SetWindowSizeRequest", + + "PackControls","DestroyControl","SetControlSizeRequest","GetControlSizeX", + "GetControlSizeY","SetControlNewPosition","GetControlPositionX", + "GetControlPositionY","SetFocuse","RedrawControl","SpecialRedrawControl", + + "SetCallbackFunction","BlockCallbackFunction","UnblockCallbackFunction", + + "SetIDL_Function","DestroyIDL_Function", + + "SetTimerCallbackForFunction","DestroyTimerCallbackForFunction", + + "SetCallbackFunctionForEvent","DestroyCallbackFunctionForEvent", + + "CreateButton","CreateButtonWithText", + + "CreateProgressBar","SetProgressBarPulse","ProgressBarSetText","ProgressBarGetText", + + "CreateHorizontalScrollBar","CreateVerticalScrollBar", + + "CreateScrolledWindow","ScrolledWindowPackControls", + + "CreateImage", + + "CreateText","TextBackgroundOn","TextBackgroundOff", + + "LoadFont","FreeFont"}; + + +static inline void* gui_ksys_load_dll(char *path) +{ + void *dll_export; + + __asm__ __volatile__( + "int $0x40" + :"=a"(dll_export) + :"a"(68),"b"(19),"c"(path)); + + return(dll_export); +} + +static inline void gui_ksys_debug_out(int c) +{ + __asm__ __volatile__( + "int $0x40" + : + :"a"(63),"b"(1),"c"(c)); +} + +static void gui_debug_out_str(char *s) +{ + + while(*s) + { + if (*s=='\n') gui_ksys_debug_out(13); + + gui_ksys_debug_out(*s); + s++; + } +} + +static int gui_strcmp(const char* string1, const char* string2) +{ + while (1) + { + if (*string1<*string2) + return -1; + if (*string1>*string2) + return 1; + if (*string1=='\0') + return 0; + string1++; + string2++; + } +} + +static void* gui_cofflib_getproc(import_t *lib, char *name) +{ + int i; + + for(i = 0; lib[i].name && gui_strcmp(name, lib[i].name); i++); + + if(lib[i].name) return lib[i].function; + else return NULL; +} + +static inline void gui_ksys_exit(int value) +{ + __asm__ __volatile__( + "int $0x40" + : + :"a"(-1),"b"(value)); +} + +void link_libGUI(import_t *exp,char **imports) +{ + LibGUIversion=(DWORD stdcall (*)(void)) + gui_cofflib_getproc(exp,imports[0]); + InitLibGUI=(char stdcall (*)(void)) + gui_cofflib_getproc(exp,imports[1]); + LibGUImain=(void stdcall (*)(parent_t *WindowParent)) + gui_cofflib_getproc(exp,imports[2]); + QuitLibGUI=(void stdcall (*)(parent_t *window)) + gui_cofflib_getproc(exp,imports[3]); + CreateWindow=(void* stdcall (*)(void)) + gui_cofflib_getproc(exp,imports[4]); + SetWindowSizeRequest=(void stdcall (*)(parent_t *WindowParent,int size_x,int size_y)) + gui_cofflib_getproc(exp,imports[5]); + PackControls=(void stdcall (*)(void *Parent,void *control)) + gui_cofflib_getproc(exp,imports[6]); + DestroyControl=(void stdcall (*)(void *control)) + gui_cofflib_getproc(exp,imports[7]); + SetControlSizeRequest=(void stdcall (*)(void *Control,int new_size_x,int new_size_y)) + gui_cofflib_getproc(exp,imports[8]); + GetControlSizeX=(int stdcall (*)(void *Control)) + gui_cofflib_getproc(exp,imports[9]); + GetControlSizeY=(int stdcall (*)(void *Control)) + gui_cofflib_getproc(exp,imports[10]); + SetControlNewPosition=(void stdcall (*)(void *Control,int new_x,int new_y)) + gui_cofflib_getproc(exp,imports[11]); + GetControlPositionX=(int stdcall (*)(void *Control)) + gui_cofflib_getproc(exp,imports[12]); + GetControlPositionY=(int stdcall (*)(void *Control)) + gui_cofflib_getproc(exp,imports[13]); + SetFocuse=(void* stdcall (*)(void *Control)) + gui_cofflib_getproc(exp,imports[14]); + RedrawControl=(void stdcall (*)(void *Control)) + gui_cofflib_getproc(exp,imports[15]); + SpecialRedrawControl=(void stdcall (*)(void *Control)) + gui_cofflib_getproc(exp,imports[16]); + SetCallbackFunction=(gui_callback_t* stdcall (*)(void *Control, + int event_name,void *callback_func,void *callback_func_data)) + gui_cofflib_getproc(exp,imports[17]); + BlockCallbackFunction=(void stdcall (*)(void *Control,gui_callback_t *callback_ID)) + gui_cofflib_getproc(exp,imports[18]); + UnblockCallbackFunction=(void stdcall (*)(void *Control,gui_callback_t *callback_ID)) + gui_cofflib_getproc(exp,imports[19]); + SetIDL_Function=(void stdcall (*)(parent_t *Parent,void *function,void *function_data)) + gui_cofflib_getproc(exp,imports[20]); + DestroyIDL_Function=(void stdcall (*)(parent_t *Parent)) + gui_cofflib_getproc(exp,imports[21]); + SetTimerCallbackForFunction=(gui_timer_t* stdcall (*)(parent_t *parent_window, + int time_tick,void *func,void *func_data)) + gui_cofflib_getproc(exp,imports[22]); + DestroyTimerCallbackForFunction=(void stdcall (*)(gui_timer_t *timer)) + gui_cofflib_getproc(exp,imports[23]); + SetCallbackFunctionForEvent=(gui_callbackevent_t* stdcall (*)(parent_t *parent_window, + int event_type,void *func,void *func_data)) + gui_cofflib_getproc(exp,imports[24]); + DestroyCallbackFunctionForEvent=(void stdcall (*)(gui_callbackevent_t *callback_event)) + gui_cofflib_getproc(exp,imports[25]); + CreateButton=(gui_button_t* stdcall (*)(gui_button_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[26]); + CreateButtonWithText=(gui_button_t* stdcall (*)(gui_button_data_t *info,char *txt)) + gui_cofflib_getproc(exp,imports[27]); + CreateProgressBar=(gui_progress_bar_t* stdcall (*)(gui_progress_bar_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[28]); + SetProgressBarPulse=(void stdcall (*)(gui_progress_bar_t *ProgressBar,int time_update)) + gui_cofflib_getproc(exp,imports[29]); + ProgressBarSetText=(void stdcall (*)(gui_progress_bar_t *pbar,char *txt)) + gui_cofflib_getproc(exp,imports[30]); + ProgressBarGetText=(char* stdcall (*)(gui_progress_bar_t *pbar)) + gui_cofflib_getproc(exp,imports[31]); + CreateHorizontalScrollBar=(gui_scroll_bar_t* stdcall (*)(gui_scroll_bar_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[32]); + CreateVerticalScrollBar=(gui_scroll_bar_t* stdcall (*)(gui_scroll_bar_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[33]); + CreateScrolledWindow=(gui_scrolled_window_t* stdcall (*)(gui_scrolled_window_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[34]); + ScrolledWindowPackControls=(void stdcall (*)(gui_scrolled_window_t *parent,void *Control)) + gui_cofflib_getproc(exp,imports[35]); + CreateImage=(gui_image_t* stdcall (*)(gui_image_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[36]); + CreateText=(gui_text_t* stdcall (*)(gui_text_data_t *info_for_control)) + gui_cofflib_getproc(exp,imports[37]); + TextBackgroundOn=(void stdcall (*)(gui_text_t *Text)) + gui_cofflib_getproc(exp,imports[38]); + TextBackgroundOff=(void stdcall (*)(gui_text_t *Text)) + gui_cofflib_getproc(exp,imports[39]); + LoadFont=(font_t* stdcall (*)(char *fullfontname)) + gui_cofflib_getproc(exp,imports[40]); + FreeFont=(void stdcall (*)(font_t *font)) + gui_cofflib_getproc(exp,imports[41]); +} + +void LoadLibGUI(char *lib_path) +{ + import_t *export; + char *path; + + if (lib_path==NULL) + { + path=sys_libGUI_path; + export=(import_t*)gui_ksys_load_dll(path); + } + else + { + path=lib_path; + export=(import_t*)gui_ksys_load_dll(path); + } + + if (export==NULL) + { + gui_debug_out_str("\ncan't load lib="); + gui_debug_out_str(path); + gui_ksys_exit(0); + } + else + { + link_libGUI(export,funcnames); + if (InitLibGUI()) + { + gui_debug_out_str("\ncan't initialize libGUI"); + gui_ksys_exit(0); + } + } +} + + + + diff --git a/programs/develop/sdk/trunk/libGUI/gcc(unix)/libGUI.h b/programs/develop/sdk/trunk/libGUI/gcc(unix)/libGUI.h new file mode 100644 index 0000000000..556d591e10 --- /dev/null +++ b/programs/develop/sdk/trunk/libGUI/gcc(unix)/libGUI.h @@ -0,0 +1,589 @@ +/* + service structures of libGUI +*/ +#define NULL (void*)0 + +typedef unsigned int DWORD; +typedef unsigned char BYTE; +typedef unsigned short int WORD; +typedef unsigned int size_t; + +#define stdcall __attribute__ ((stdcall)) +#define cdecl __attribute__ ((cdecl)) +#define pack __attribute__ ((packed)) + +///////////////////////////////////////////////////////////////////////// +// libGUI sysyem messages types +///////////////////////////////////////////////////////////////////////// +#define MESSAGE_FULL_REDRAW_ALL 1 +#define MESSAGE_KEYS_EVENT 2 +#define MESSAGE_SPECIALIZED 3 +#define MESSAGE_SET_FOCUSE 4 +#define MESSAGE_CHANGE_FOCUSE 5 +#define MESSAGE_MOUSE_EVENT 6 +#define MESSAGE_CHANGE_POSITION_EVENT 7 +#define MESSAGE_CHANGESIZE_EVENT 8 +#define MESSAGE_CALL_TIMER_EVENT 9 +#define MESSAGE_FULL_REDRAW_ALL_WITH_FINITION 10 +#define MESSAGE_SET_MAIN_PARENT 11 +#define MESSAGE_DESTROY_CONTROL -1 + +///////////////////////////////////////////////////////////////////////// +// system keys states +///////////////////////////////////////////////////////////////////////// +#define KEY_DOWN 16 +#define KEY_UP 17 +#define KEY_HOTKEY 18 +///////////////////////////////////////////////////////////////////////// +// system mouse buttons states +///////////////////////////////////////////////////////////////////////// +#define MOUSE_LEFT_BUTTON_DOWN 19 +#define MOUSE_LEFT_BUTTON_UP 20 +#define MOUSE_RIGHT_BUTTON_DOWN 21 +#define MOUSE_RIGHT_BUTTON_UP 22 +#define MOUSE_MIDDLE_BUTTON_DOWN 23 +#define MOUSE_MIDDLE_BUTTON_UP 24 +#define MOUSE_4_BUTTON_DOWN 25 +#define MOUSE_4_BUTTON_UP 26 +#define MOUSE_5_BUTTON_DOWN 27 +#define MOUSE_5_BUTTON_UP 28 + + +//----------------------------------------------------------------------- +// CONNECT EVENTS FOR CALLBACKs +//----------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////// +// connect events for button +//////////////////////////////////////////////////////////////// +#define BUTTON_ENTER_EVENT 29 +#define BUTTON_LEAVE_EVENT 30 +#define BUTTON_PRESSED_EVENT 31 +#define BUTTON_RELEASED_EVENT 32 + +//////////////////////////////////////////////////////////////// +// connect events for scroll bar +//////////////////////////////////////////////////////////////// +#define SCROLLBAR_CHANGED_EVENT 33 + +//////////////////////////////////////////////////////////////// +// connect events for main parent window +//////////////////////////////////////////////////////////////// +#define DELETE_EVENT 36 + +//////////////////////////////////////////////////////////////// +// font type structure +//////////////////////////////////////////////////////////////// +struct FONT +{ + DWORD *fnt_draw; + DWORD *fnt_unpacker; + DWORD *fnt_fd; + DWORD *fnt_bk; + int sizex; + int sizey; + int size; + int encoding_type; + char *font; + char *fnt_name; + DWORD type; + DWORD flags; +}pack; + +typedef struct FONT font_t; + +//////////////////////////////////////////////////////////////// +// header of parent of control +//////////////////////////////////////////////////////////////// + +struct HEADERPARENT +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD **control_for_callback_function; + DWORD **callback_for_control_callback; + DWORD number_callbacks; + DWORD *global_active_control_for_keys; + DWORD *message; + DWORD *timer_bk; + DWORD *timer_fd; + DWORD number_timers_for_controls; + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *IDL_func; + DWORD *IDL_func_data; +}pack; + +typedef struct HEADERPARENT parent_t; + +//////////////////////////////////////////////////////////////// +// header of control +//////////////////////////////////////////////////////////////// + +struct HEADER +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; +}pack; + + +typedef struct HEADER header_t; +//////////////////////////////////////////////////////////////// +// callback structure for callback function of control +//////////////////////////////////////////////////////////////// + +struct CALLBACK +{ + DWORD *clb_bk; + DWORD *clb_fd; + DWORD *clb_control; + DWORD *func; + DWORD *func_data; + DWORD connect_event; + DWORD flags; +}pack; + + +typedef struct CALLBACK gui_callback_t; +//////////////////////////////////////////////////////////////// +// timer +//////////////////////////////////////////////////////////////// + +struct TIMER +{ + DWORD *tmr_bk; + DWORD *tmr_fd; + DWORD *tmr_parent; + DWORD *func; + DWORD *func_data; + DWORD last_time; + DWORD time_tick; + DWORD flags; +}pack; + + +typedef struct TIMER gui_timer_t; +//////////////////////////////////////////////////////////////// +// structure for callback events +//////////////////////////////////////////////////////////////// + +struct CALLBACKEVENT +{ + DWORD *calev_bk; + DWORD *calev_fd; + DWORD *calev_parent; + DWORD *func; + DWORD *func_data; + DWORD event_type; +}pack; + + +typedef struct CALLBACKEVENT gui_callbackevent_t; + +//////////////////////////////////////////////////////////////// +// type of data - structure message +//////////////////////////////////////////////////////////////// + +struct MESSAGE +{ + DWORD type; + DWORD arg1; + DWORD arg2; + DWORD arg3; + DWORD arg4; +}pack; + + +typedef struct MESSAGE gui_message_t; + +//////////////////////////////////////////////////////////////// +// button +//////////////////////////////////////////////////////////////// + +struct ControlButton +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //button's data + BYTE btn_flags; +}pack; + + +typedef struct ControlButton gui_button_t; + +// information for creating control Button + +struct ButtonData +{ + int x; + int y; + int width; + int height; +}pack; + + +typedef struct ButtonData gui_button_data_t; + +//////////////////////////////////////////////////////////////// +// scroller +//////////////////////////////////////////////////////////////// + +struct ControlScrollBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scroll bar's data + float ruller_size; + float ruller_pos; + float ruller_step; + BYTE scb_flags; +}pack; + + +typedef struct ControlScrollBar gui_scroll_bar_t; + + +struct ScrollBarData +{ + int x; + int y; + int width; + int height; + float ruller_size; + float ruller_pos; + float ruller_step; +}pack; + + +typedef struct ScrollBarData gui_scroll_bar_data_t; +//////////////////////////////////////////////////////////////// +// progressbar +//////////////////////////////////////////////////////////////// + +struct ControlProgressBar +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //progress bar's data + float progress; + BYTE prb_flags; +}pack; + + +typedef struct ControlProgressBar gui_progress_bar_t; + + +struct ProgressBarData +{ + int x; + int y; + int width; + int height; + float progress; +}pack; + + +typedef struct ProgressBarData gui_progress_bar_data_t; +//////////////////////////////////////////////////////////////// +// scrolled window +//////////////////////////////////////////////////////////////// + +struct ControlScrolledWindow +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + //scrolled windows's data + DWORD virtual_x; + DWORD virtual_y; + DWORD virtual_sizex; + DWORD virtual_sizey; + DWORD *virtual_controls_x; + DWORD *virtual_controls_y; + DWORD number_virtual_controls; + DWORD scroll_arrea_sizex; + DWORD scroll_arrea_sizey; + DWORD *horizontal_scroll; + DWORD *vertical_scroll; + BYTE scw_flags; +}pack; + + +typedef struct ControlScrolledWindow gui_scrolled_window_t; + + +struct ScrolledWindowData +{ + int x; + int y; + int width; + int height; +}pack; + + +typedef struct ScrolledWindowData gui_scrolled_window_data_t; + +//////////////////////////////////////////////////////////////// +// image +//////////////////////////////////////////////////////////////// + +struct ControlImage +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + char bits_per_pixel; + char bytes_per_pixel; + char *img; +}pack; + + +typedef struct ControlImage gui_image_t; + + +struct ImageData +{ + int x; + int y; + int width; + int height; + char bits_per_pixel; +}pack; + + +typedef struct ImageData gui_image_data_t; + +//////////////////////////////////////////////////////////////// +// text +//////////////////////////////////////////////////////////////// + +struct ControlText +{ + DWORD *ctrl_proc; + DWORD *ctrl_fd; + DWORD *ctrl_bk; + DWORD *child_fd; + DWORD *child_bk; + DWORD *parent; + DWORD *main_parent; + DWORD ctrl_x; + DWORD ctrl_y; + DWORD ctrl_sizex; + DWORD ctrl_sizey; + DWORD ctrl_ID; + DWORD *active_control_for_keys; + DWORD *active_control_for_mouse; + DWORD *callback; + DWORD *finition; + DWORD *timer; + DWORD flags; + + DWORD *font; + DWORD color; + DWORD background_color; + char *text; + BYTE txt_flags; +}pack; + + +typedef struct ControlText gui_text_t; + + +struct TextData +{ + int x; + int y; + DWORD *font; + DWORD color; + DWORD background_color; + char background; + char *text; +}pack; + + +typedef struct TextData gui_text_data_t; +///////////////////////////////////////////////////////////////// +// load libGUI library and link functions +///////////////////////////////////////////////////////////////// +void LoadLibGUI(char *lib_path); + +//********************************************************************** +// libGUI service functions +//********************************************************************** + +DWORD stdcall (*LibGUIversion)(void); +char stdcall (*InitLibGUI)(void); +void stdcall (*LibGUImain)(parent_t *WindowParent); +void stdcall (*QuitLibGUI)(parent_t *window); + +void* stdcall (*CreateWindow)(void); +void stdcall (*SetWindowSizeRequest)(parent_t *WindowParent,int size_x,int size_y); + +void stdcall (*PackControls)(void *Parent,void *control); +void stdcall (*DestroyControl)(void *control); +void stdcall (*SetControlSizeRequest)(void *Control,int new_size_x,int new_size_y); +int stdcall (*GetControlSizeX)(void *Control); +int stdcall (*GetControlSizeY)(void *Control); +void stdcall (*SetControlNewPosition)(void *Control,int new_x,int new_y); +int stdcall (*GetControlPositionX)(void *Control); +int stdcall (*GetControlPositionY)(void *Control); +void* stdcall (*SetFocuse)(void *Control); +void stdcall (*RedrawControl)(void *Control); +void stdcall (*SpecialRedrawControl)(void *Control); + +gui_callback_t* stdcall (*SetCallbackFunction)(void *Control, + int event_name,void *callback_func, + void *callback_func_data); +void stdcall (*BlockCallbackFunction)(void *Control,gui_callback_t *callback_ID); +void stdcall (*UnblockCallbackFunction)(void *Control,gui_callback_t *callback_ID); + +void stdcall (*SetIDL_Function)(parent_t *Parent,void *function,void *function_data); +void stdcall (*DestroyIDL_Function)(parent_t *Parent); + +gui_timer_t* stdcall (*SetTimerCallbackForFunction)(parent_t *parent_window, + int time_tick,void *func,void *func_data); +void stdcall (*DestroyTimerCallbackForFunction)(gui_timer_t *timer); + +gui_callbackevent_t* stdcall (*SetCallbackFunctionForEvent)(parent_t *parent_window, + int event_type,void *func,void *func_data); +void stdcall (*DestroyCallbackFunctionForEvent)(gui_callbackevent_t *callback_event); + +gui_button_t* stdcall (*CreateButton)(gui_button_data_t *info_for_control); +gui_button_t* stdcall (*CreateButtonWithText)(gui_button_data_t *info,char *txt); + +gui_progress_bar_t* stdcall (*CreateProgressBar)(gui_progress_bar_data_t *info_for_control); +void stdcall (*SetProgressBarPulse)(gui_progress_bar_t *ProgressBar,int time_update); +void stdcall (*ProgressBarSetText)(gui_progress_bar_t *pbar,char *txt); +char* stdcall (*ProgressBarGetText)(gui_progress_bar_t *pbar); + +gui_scroll_bar_t* stdcall (*CreateHorizontalScrollBar)(gui_scroll_bar_data_t *info_for_control); +gui_scroll_bar_t* stdcall (*CreateVerticalScrollBar)(gui_scroll_bar_data_t *info_for_control); + +gui_scrolled_window_t* stdcall (*CreateScrolledWindow)(gui_scrolled_window_data_t *info_for_control); +void stdcall (*ScrolledWindowPackControls)(gui_scrolled_window_t *parent,void *Control); + +gui_image_t* stdcall (*CreateImage)(gui_image_data_t *info_for_control); + +gui_text_t* stdcall (*CreateText)(gui_text_data_t *info_for_control); +void stdcall (*TextBackgroundOn)(gui_text_t *Text); +void stdcall (*TextBackgroundOff)(gui_text_t *Text); + +font_t* stdcall (*LoadFont)(char *fullfontname); +void stdcall (*FreeFont)(font_t *font); +