home *** CD-ROM | disk | FTP | other *** search
Wrap
/* DU_LIB v2 Gem Window Management & Dialog Library For Lattice C ©1994, by Craig Graham. Based on the DU_LIBv1 Library for HiSoft Basic. */ /* Main Code */ #include "dulib.h" #include <stdio.h> #include <stdlib.h> short junk; short messB[40]; short timeB[40]; short x_handle; short AESid; /* Our AES id */ short AESversion; /* Current AES version */ short AESversion_m; /* Current AES version (minor revision number)*/ Wdetails windows[max_windows]; Ddetails dialog_details[max_dialogs]; Elist *event_value[max_dialogs]; Elist *key_values; mouse_shape wm_mouse_shape; short wm_inv[512],wm_outv[200]; short menu; /*The menubar form*/ short last_opened_window; /*The handle of the last handle opened by activate_dialog*/ short d_parm; /*Any parameter which has to be returned by a dialog (eg slider pos.)*/ short this_ob,this_dialog; /*The current object handle when any callback routine is called*/ short udx,udy,udw,udh,icon_x,icon_y; short cr_wind_handle; GRECT cr_clip; /*Custom redraw object locations*/ GRECT cr_dclip; /*Custom redraw object display clip rectangle*/ short cr_mx,cr_my; /*Custom redraw/callback relative mouse location inside object*/ short scrn_x,scrn_y,scrn_w,scrn_h; /*screen size*/ short scrn_planes; /*screen - number of bitplanes*/ short wmi_total_buffering; short scroll_selection; /*index to string when a scroll text has been clicked on */ CallBack XaccTextHandler; /*handler routine for Xacc2 text transfers*/ short click_count; /*number of mouse click events from last evnt_multi()*/ /* Key triggered callbacks */ short kc_key; /* AES key code */ short kc_shstate; /* Keyboard shift state */ /* Configuration Variables*/ short RightClickEqualsDoubleClick; /*a right button click has same effect as a double click if this is set to TRUE*/ short ScrollSelectionIsInverse; /*selected item in a scrolling list is shown in inverse*/ short KeypressToWindowUnderMouse; /*control how the keyboard handler behaves */ /* Clipboard stuff */ char clipboard_path[FMSIZE+10]; /*path to the GEM clipboard*/ /* Timer driven routine stuff*/ CallBack timer_callback; short timer_rate; /* Poll for an event for time t_poll (milliseconds) */ /* Use this when you are doing a long task to check for user interaction and return after a short time to do some more processing. */ short poll_flag; event PollEvent(short t_poll) { event e; short old_timer_rate; CallBack old_timer_callback; old_timer_rate=timer_rate; old_timer_callback=timer_callback; timer_rate=t_poll; timer_callback=NULL; poll_flag=TRUE; e=WaitEvent(); timer_rate=old_timer_rate; timer_callback=old_timer_callback; poll_flag=FALSE; return e; } event WaitEvent(void) { OBJECT *form_under_mouse; short x1,y1,d1,d2,d3,d4; short x,y,a,b,d6; short e,wait_for; event exit_flag; Wtype t; short window_clicked_in, window_for_keypress, window_under_mouse, ob, clip[4]; CallBack key_handler; click_count=exit_flag=e=x1=y1=d1=d2=d3=d4=x=y=a=b=d6=0; do { if ((timer_callback!=NULL)||(poll_flag)) wait_for=MU_KEYBD+MU_BUTTON+MU_MESAG+MU_TIMER; else wait_for=MU_KEYBD+MU_BUTTON+MU_MESAG; #ifndef __USE_GNU e=evnt_multi(wait_for,258,3,0,1,x1,y1,a,b,0,d1,d2,d3,d4, messB,timer_rate,0,&x,&y,&a,&kc_shstate,&kc_key,&click_count); #else e=evnt_multi(wait_for, 258, 3, 0, 1,x1,y1,a,b,0,d1,d2,d3,d4, messB,1,&x,&y,&a,&kc_shstate,&kc_key,&click_count); #endif if ((e & MU_KEYBD)==MU_KEYBD) // Multi-layer keyboard handling { window_under_mouse=wind_find(x,y); // Find the window under the mouse if ((KeypressToWindowUnderMouse==TRUE)&&(window_under_mouse!=0)) // Check with the config variable for how we behave here window_for_keypress=window_under_mouse; else wind_get(0,WF_TOP,&window_for_keypress,0,0,0); if (!window_under_mouse) window_under_mouse=window_for_keypress; // If there is no window under the mouse, then select the top one anyway t=windows[window_for_keypress].window_type; // Type of the window we are going to work with a=FALSE; // Use a as a flag to indicate that a key has been consumed by a layer if (t!=wt_null) // If mouse was over one of our windows, give keypress to the Object & Dialog layers to see if they want it. { cr_wind_handle=window_for_keypress; this_dialog=windows[window_for_keypress].the_dialog; // Callback is being called for a valid dialog if (window_under_mouse==window_for_keypress) // Only go into Object layer if we are putting keypresses into the dialog under the mouse cursor (or the top window) { rsrc_gaddr(0,this_dialog,&form_under_mouse); if (dialog_details[this_dialog].focus_mode==FOCUS_FIELD) //Key focus policy stuff { ob=dialog_details[this_dialog].current_focus; }else{ ob=objc_find(form_under_mouse, 0, 5, x, y); // Find the object under the mouse } key_handler=Get_object_Kcallback(this_dialog, ob); // Check for a Object Specific key handler (Object Layer) if (key_handler) { this_ob=ob; // Callback is being called for a valid object #ifndef __USE_GNU objc_xywh(form_under_mouse,this_ob,&cr_clip); // Get the dimensions of the object into the cr_clip global to ensure it is valid. #else objc_offset(form_unuder_mouse,this_ob,&cx,&cy); cr_clip.g_x=cx; cr_clip.g_y=cy; cr_clip.g_w=(TheDial+this_ob)->ob_width; cr_clip.g_h=(TheDial+this_ob)->ob_height; #endif clip[0]=cr_clip.g_x; clip[1]=cr_clip.g_y; clip[2]=cr_clip.g_x+cr_clip.g_w-1; clip[3]=cr_clip.g_y+cr_clip.g_h-1; vs_clip(x_handle,1,clip); // Ensure that we are clipping to the object we are calling for a=(*key_handler)(); // Call key Object layer key handler } } if (!a) // If the Object Layer didn't consume keypress, let's see if there is a dialog key handler which wants it { key_handler=Get_dialog_Kcallback(windows[window_for_keypress].the_dialog); // Check for the dialog general key handler (Dialog Layer) if (key_handler) { this_ob=-1; a=(*key_handler)(); } } } if (!a) // If key is still valid, then try for an event/callback from the Application Global layer { // associated with the key as no object or dialogs handler has claimed it. key_handler=Get_key_callback(kc_key); /*Check for a specific key callback */ if (key_handler) { this_ob=-1; // we are calling the key callback soley for the key event having happened this_dialog=-1; // - there is no object/dialog to pass it to. (*key_handler)(); } } } if ((e & MU_MESAG)==MU_MESAG) { exit_flag=process_message(messB); } if ((e & MU_BUTTON)==MU_BUTTON) { if (RightClickEqualsDoubleClick) if (a>1) { a=1; click_count=2; } exit_flag=2; } if ((e & MU_TIMER)==MU_TIMER) { if (timer_callback!=NULL) // If we got a TIMER event, are we handling a timer_callback? (*timer_callback)(); } } while ((exit_flag==0)&&(poll_flag==FALSE)); window_clicked_in=wind_find(x,y); t=windows[window_clicked_in].window_type; if (window_clicked_in) // Window 0 is the desktop - ignore clicks in this window. { switch(exit_flag) { case 2: junk=process_win_dial(window_clicked_in,x,y); if (t!=wt_null) { if (junk!=0) { switch (click_count) { case 1: exit_flag=Get_object_event(windows[window_clicked_in].the_dialog,junk); break; case 2: exit_flag=Get_object_devent(windows[window_clicked_in].the_dialog,junk); break; } } else { exit_flag=(event)junk; } } break; } } return exit_flag; } short enviroment_initialise(void) { short f,n; short open_vwk_workin[11]={1,1,1,1,1,1,1,1,1,1,2}; short w[128]; AESid=appl_init(); if (AESid==-1) { form_alert(1,"[3][ DULIB ERROR: | appl_init() failled. ][ EXIT ]"); exit(1); } AESversion=_AESglobal[0]>>8; AESversion_m=_AESglobal[0]&255; for(f=0; f<max_dialogs; f++) { event_value[f]=NULL; /* No initial event list for each dialog */ dialog_details[f].help_topic[0]='\0'; /* No initial help topic for each dialog */ /* No initial handlers for window widgets */ dialog_details[f].wind_widgets.close_widget=NULL; dialog_details[f].wind_widgets.full_widget=NULL; dialog_details[f].wind_widgets.iconify_widget=NULL; dialog_details[f].wind_widgets.resize_widget=NULL; dialog_details[f].wind_widgets.h_slide=NULL; dialog_details[f].wind_widgets.v_slide=NULL; for(n=0; n<8; n++) dialog_details[f].wind_widgets.arrows[n]=NULL; } for(f=0; f<max_windows; windows[f++].window_type=wt_null); wind_get(DESK,WF_WORKXYWH,&scrn_x,&scrn_y,&scrn_w,&scrn_h); graf_mouse(ARROW,NULL); x_handle=graf_handle(&junk,&junk,&junk,&junk); v_opnvwk(open_vwk_workin, &x_handle, w); if (!x_handle) { form_alert(1,"[3][ DULIB ERROR: | Cann't open a virtual | workstation. ][ EXIT ]"); close_down(); exit(2); } vq_extnd(x_handle,1,w); scrn_planes=w[4]; wmi_total_buffering=0; XaccTextHandler=NULL; timer_callback=NULL; /* Default GUI Configuration */ DU_mode(DU_MODE_RIGHT_EQUALS_DOUBLE,FALSE); DU_mode(DU_MODE_SCROLL_HIGHLIGHT_IS_INVERSE,TRUE); DU_mode(DU_MODE_KEYPRESS_TO_WINDOW_UNDER_MOUSE,FALSE); /* Check for the clipboard */ f=scrp_read(clipboard_path); if (!f) { sprintf(clipboard_path, "%s", "\\"); scrp_write(clipboard_path); } /* Initially, we aren't polling for events, we are waiting for them */ poll_flag=FALSE; return 0; } /*================================================== Exit from program - close all windows - clean up the av_accessories - unhook our custom mouse handlers ==================================================*/ short close_down() { OBJECT *menu_loc; short f; /* Close all our windows */ for (f=1; f<max_windows; f++) { if (windows[f].window_type!=wt_null) { wind_close(f); wind_delete(f); }; } /* Remove GEM menu bar prior to exitting */ if (menu!=0) { rsrc_gaddr(0,menu,&menu_loc); menu_bar(menu_loc,1); } v_clsvwk(x_handle); /*revert to the AES's workstation*/ x_handle = graf_handle(&f,&f,&f,&f); appl_exit(); return 0; }