/*****************************************************************************/ /* */ /* Modul: EXTOBFIX.C */ /* Datum: 17.02.91 */ /* */ /*****************************************************************************/ #include <stdio.h> #include <string.h> #include <portab.h> #include <aes.h> #include <vdi.h> #include "extobfix.h" /****** DEFINES **************************************************************/ #ifndef RSC_NAME #define RSC_NAME "EXTOBFIX.RSC" /* Name der Resource-Datei */ #endif #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) /* Maximum-Funktion */ #define min(a,b) (((a) < (b)) ? (a) : (b)) /* Minimum Funktion */ #endif #define DHEADER 0x0020 #define DHEIGHT 0x0040 #define DCRBUTTON 0x0080 #define HALFSTRSIZE 128 /* Halblange Stringgr”že */ #define DESK 0 /* Window-Handle/Klasse des Desktop als Objekt */ #define RC 2 /* Raster Koordinaten */ /****** TYPES ****************************************************************/ typedef struct { WORD bgc; WORD style; WORD interior; WORD bdc; WORD width; WORD chc; } OBINFO; typedef struct { WORD x; /* X-Koordinate */ WORD y; /* Y-Koordinate */ WORD w; /* Breite */ WORD h; /* H”he */ } RECT; typedef BYTE STR128 [HALFSTRSIZE]; /* Halblange Zeichenkette */ /****** VARIABLES ************************************************************/ #if DR_C | LASER_C | MW_C EXTERN WORD gl_apid; /* Identifikation fr Applikation */ #else LOCAL WORD gl_apid; /* Identifikation fr Applikation */ #endif LOCAL USERBLK check_blk; /* used for Macintosh check boxes */ LOCAL USERBLK radio_blk; /* used for Macintosh radio buttons */ LOCAL WORD gl_wbox; /* Breite einer Zeichenbox */ LOCAL WORD gl_hbox; /* H”he einer Zeichenbox */ LOCAL WORD gl_wattr; /* Breite eines Fensterattributes */ LOCAL WORD gl_hattr; /* H”he eines Fensterattributes */ LOCAL WORD phys_handle; /* Physikalisches Workstation Handle */ LOCAL WORD vdi_handle; /* Virtuelles Workstation Handle */ LOCAL BOOLEAN vwork_open; /* Virtuelle Workstation ge”ffnet ? */ LOCAL RECT desk; /* Desktop Gr”že */ LOCAL RECT clip; /* Letztes Clipping Rechteck */ LOCAL OBJECT *userimg; /****** FUNCTIONS ************************************************************/ GLOBAL LONG pinit_obfix _((BOOLEAN status)); LOCAL VOID fix_objs _((OBJECT *tree, BOOLEAN is_dialog)); LOCAL VOID xywh2rect _((WORD x, WORD y, WORD w, WORD h, RECT *rect)); LOCAL VOID set_clip _((BOOLEAN flag, CONST RECT *size)); LOCAL VOID trans_gimage _((OBJECT *tree, WORD obj)); LOCAL VOID rc_copy _((CONST RECT *ps, RECT *pd)); LOCAL BOOLEAN rc_intersect _((CONST RECT *p1, RECT *p2)); LOCAL VOID rect2array _((CONST RECT *rect, WORD *array)); LOCAL VOID xywh2array _((WORD x, WORD y, WORD w, WORD h, WORD *array)); LOCAL VOID open_vwork _((VOID)); LOCAL VOID close_vwork _((VOID)); LOCAL BOOLEAN init_global _((INT argc, BYTE *argv [], BYTE *acc_menu, WORD class)); LOCAL BOOLEAN term_global _((VOID)); LOCAL VOID get_obinfo _((LONG obspec, OBINFO *obinfo)); LOCAL WORD CDECL draw_checkbox _((FAR PARMBLK *pb)); LOCAL WORD CDECL draw_rbutton _((FAR PARMBLK *pb)); LOCAL VOID vdi_fix _((MFDB *pfd, VOID *theaddr, WORD wb, WORD h)); LOCAL VOID vdi_trans _((WORD *saddr, WORD swb, WORD *daddr, WORD dwb, WORD h)); /*****************************************************************************/ LOCAL LONG routines[] = { (LONG)fix_objs, /* Eigene ob_fix Routine */ 0L, /* Keine eigene form_alert Routine */ 0L, /* Keine eigene Testroutine */ 0L, /* Noch keine Hilfeseite */ '0610', '1965', /* Magic */ (LONG)pinit_obfix, }; /*****************************************************************************/ LOCAL VOID get_obinfo (obspec, obinfo) LONG obspec; OBINFO *obinfo; { WORD colorwd; colorwd = (WORD)obspec; obinfo->bgc = colorwd & 0x0F; obinfo->style = (colorwd & 0x70) >> 4; if (obinfo->style == 0) obinfo->interior = 0; else if (obinfo->style == 7) obinfo->interior = 1; else obinfo->interior = (colorwd & 0x80) ? 3 : 2; obinfo->bdc = (colorwd & 0xF000) >> 12; obinfo->width = (WORD)(obspec >> 16) & 0xFF; if (obinfo->width > 127) obinfo->width = 256 - obinfo->width; obinfo->chc = (colorwd & 0x0F00) >> 8; } /* get_obinfo */ /*****************************************************************************/ /* Zeichnet ankreuzbare Buttons */ /*****************************************************************************/ LOCAL WORD CDECL draw_checkbox (pb) FAR PARMBLK *pb; { LONG ob_spec; WORD ob_x, ob_y; BOOLEAN selected; MFDB s, d; BITBLK *bitblk; WORD obj; WORD pxy [8]; WORD index [2]; RECT r; OBINFO obinfo; ob_spec = pb->pb_parm; ob_x = pb->pb_x; ob_y = pb->pb_y; selected = pb->pb_currstate & SELECTED; get_obinfo (ob_spec, &obinfo); xywh2rect (pb->pb_xc, pb->pb_yc, pb->pb_wc, pb->pb_hc, &r); set_clip (TRUE, &r); if (selected) /* it was an objc_change */ obj = (gl_hbox > 8) ? CBHSEL : CBLSEL; /* high resolution : low resolution */ else obj = (gl_hbox > 8) ? CBHNORM : CBLNORM; /* high resolution : low resolution */ bitblk = (BITBLK *)userimg [obj].ob_spec; d.mp = NULL; /* screen */ s.mp = (VOID *)bitblk->bi_pdata; s.fwp = bitblk->bi_wb << 3; s.fh = bitblk->bi_hl; s.fww = bitblk->bi_wb >> 1; s.ff = FALSE; s.np = 1; pxy [0] = 0; pxy [1] = 0; pxy [2] = s.fwp - 1; pxy [3] = s.fh - 1; pxy [4] = ob_x; pxy [5] = ob_y; pxy [6] = ob_x + pxy [2]; pxy [7] = ob_y + pxy [3]; index [0] = obinfo.bgc; index [1] = WHITE; vrt_cpyfm (vdi_handle, MD_REPLACE, pxy, &s, &d, index); /* copy it */ return (pb->pb_currstate & ~ SELECTED); } /* draw_checkbox */ /*****************************************************************************/ /* Zeichnet runde Radiobuttons */ /*****************************************************************************/ LOCAL WORD CDECL draw_rbutton (pb) FAR PARMBLK *pb; { LONG ob_spec; WORD ob_x, ob_y; BOOLEAN selected; MFDB s, d; BITBLK *bitblk; WORD obj; WORD pxy [8]; WORD index [2]; RECT r; OBINFO obinfo; ob_spec = pb->pb_parm; ob_x = pb->pb_x; ob_y = pb->pb_y; selected = pb->pb_currstate & SELECTED; get_obinfo (ob_spec, &obinfo); xywh2rect (pb->pb_xc, pb->pb_yc, pb->pb_wc, pb->pb_hc, &r); set_clip (TRUE, &r); if (selected) /* it was an objc_change */ obj = (gl_hbox > 8) ? RBHSEL : RBLSEL; /* high resolution : low resolution */ else obj = (gl_hbox > 8) ? RBHNORM : RBLNORM; /* high resolution : low resolution */ bitblk = (BITBLK *)userimg [obj].ob_spec; d.mp = NULL; /* screen */ s.mp = (VOID *)bitblk->bi_pdata; s.fwp = bitblk->bi_wb << 3; s.fh = bitblk->bi_hl; s.fww = bitblk->bi_wb >> 1; s.ff = FALSE; s.np = 1; pxy [0] = 0; pxy [1] = 0; pxy [2] = s.fwp - 1; pxy [3] = s.fh - 1; pxy [4] = ob_x; pxy [5] = ob_y; pxy [6] = ob_x + pxy [2]; pxy [7] = ob_y + pxy [3]; index [0] = obinfo.bgc; index [1] = WHITE; vrt_cpyfm (vdi_handle, MD_REPLACE, pxy, &s, &d, index); /* copy it */ return (pb->pb_currstate & ~ SELECTED); } /* draw_rbutton */ /*****************************************************************************/ LOCAL VOID fix_objs (tree, is_dialog) OBJECT *tree; BOOLEAN is_dialog; { WORD obj; OBJECT *ob; ICONBLK *ib; BITBLK *bi; WORD y_radio, h_radio; WORD y_check, h_check; BOOLEAN hires; UWORD type, xtype; #if GEM & (GEM2 | GEM3 | XGEM) BYTE *s; #endif hires = (gl_hbox > 8) ? TRUE : FALSE; obj = hires ? RBHNORM : RBLNORM; bi = (BITBLK *)userimg [obj].ob_spec; h_radio = bi->bi_hl; y_radio = (gl_hbox - h_radio) / 2; obj = hires ? CBHNORM : CBLNORM; bi = (BITBLK *)userimg [obj].ob_spec; h_check = bi->bi_hl; y_check = (gl_hbox - h_check) / 2; check_blk.ub_code = draw_checkbox; radio_blk.ub_code = draw_rbutton; if (tree != NULL) { #if GEM & (GEM2 | GEM3 | XGEM) if (is_dialog) { undo_state (tree, ROOT, SHADOWED); do_state (tree, ROOT, OUTLINED); } /* if */ #endif obj = NIL; do { ob = &tree [++obj]; type = ob->ob_type & 0xFF; xtype = ob->ob_type >> 8; #if GEM & (GEM2 | GEM3 | XGEM) if ((type == G_STRING) && (ob->ob_state & DISABLED)) for (s = (BYTE *)ob->ob_spec; *s; s++) if (*s == 0x13) *s = '-'; #endif if (type == G_ICON) { ib = (ICONBLK *)ob->ob_spec; ob->ob_height = ib->ib_ytext + ib->ib_htext; /* Objekth”he = Iconh”he */ trans_gimage (tree, obj); /* Icons an Bildschirm anpassen */ } /* if */ if (type == G_IMAGE) { bi = (BITBLK *)ob->ob_spec; ob->ob_height = bi->bi_hl; /* Objekth”he = Imageh”he */ trans_gimage (tree, obj); /* Bit Images an Bildschirm anpassen */ } /* if */ if (xtype & DHEADER) ob->ob_y -= gl_hbox / 2; /* group box */ if (xtype & DHEIGHT) /* half height box */ { ob->ob_height -= gl_hbox / 2; if (! hires) ob->ob_height--; } /* if */ if (xtype & DCRBUTTON) { if (ob->ob_flags & RBUTTON) /* radio button */ { radio_blk.ub_parm = (LONG)ob->ob_spec; ob->ob_y += y_radio; ob->ob_height = h_radio; #if MSDOS | FLEXOS | DR_C | LATTICE_C | MW_C | TURBO_C ob->ob_type = G_USERDEF; ob->ob_spec = (LONG)&radio_blk; #endif } /* if */ else /* checkbox */ { check_blk.ub_parm = (LONG)ob->ob_spec; ob->ob_y += y_check; ob->ob_height = h_check; #if MSDOS | FLEXOS | DR_C | LATTICE_C | MW_C | TURBO_C ob->ob_type = G_USERDEF; ob->ob_spec = (LONG)&check_blk; #endif } /* else */ } /* if */ } while (! (ob->ob_flags & LASTOB)); } /* if */ } /* fix_objs */ /*****************************************************************************/ main() { if (init_global (0, NULL, NULL, 0) == TRUE) { form_alert (1, "[3][Dieses Programm kann|nur von Interface|gestartet werden !][ Abbruch ]"); term_global (); } return (0); } /*****************************************************************************/ /* Initialisieren des Moduls */ /*****************************************************************************/ LOCAL BOOLEAN init_global (argc, argv, acc_menu, class) INT argc; BYTE *argv []; BYTE *acc_menu; WORD class; { WORD i; STR128 rsc_name, s; #if GEM & (GEM2 | GEM3 | XGEM) BYTE *p; #endif i = appl_init (); /* Applikationsnummer besorgen */ #if (LATTICE_C | TURBO_C) | (GEM & (GEM2 | GEM3 | XGEM)) gl_apid = i; /* gl_apid nicht extern */ #endif if (gl_apid < 0) return (FALSE); phys_handle = graf_handle (&gl_wbox, &gl_hbox, &gl_wattr, &gl_hattr); /* Handle des Bildschirms */ vdi_handle = phys_handle; /* Benutze physikalischen Bildschirm */ vwork_open = FALSE; wind_get (DESK, WF_WXYWH, &desk.x, &desk.y, &desk.w, &desk.h); /* Gr”že des Desktop */ #if GEM & GEM1 strcpy (rsc_name, RSC_NAME); /* Programm wurde vielleicht mit Pexec gestartet */ #else strcpy (rsc_name, app_name); p = strrchr (rsc_name, SUFFSEP); /* Programmname hat immer Suffix */ strcpy (p + 1, "RSC"); #endif if (! rsrc_load (rsc_name)) { strcpy (s, "[3][Resource-File|"); strcat (s, rsc_name); strcat (s, "?][ EXIT ]"); form_alert (1, s); return (FALSE); } /* if */ rsrc_gaddr (R_TREE, USERIMG, &userimg); /* Adresse der Mac-Images */ rsrc_gaddr (R_TREE, HELP_EXT, &routines[3]); /* Adresse der Hilfeseite */ fix_objs (userimg, FALSE); open_vwork (); /* ™ffne virtuelle Workstation */ return (TRUE); } /* init_global */ /*****************************************************************************/ /* Terminieren des Moduls */ /*****************************************************************************/ LOCAL BOOLEAN term_global () { if (gl_apid >= 0) { rsrc_free (); /* Resourcen freigeben */ close_vwork (); /* Workstation schliežen */ appl_exit (); /* Applikation beenden */ } /* if */ return (TRUE); } /* term_global */ /*****************************************************************************/ /* ™ffne virtuelle Workstation */ /*****************************************************************************/ LOCAL VOID open_vwork () { WORD i; WORD work_in [11]; WORD work_out [57]; if (! vwork_open) { vwork_open = TRUE; for (i = 0; i < 10; work_in [i++] = 1); work_in [10] = RC; /* Raster Koordinaten */ vdi_handle = phys_handle; v_opnvwk (work_in, &vdi_handle, work_out); /* ™ffne virtuelle Workstation */ #if GEM & XGEM vst_point (vdi_handle, 10, &i, &i, &i, &i); #endif vqt_attributes (vdi_handle, work_out); /* Globale Zeichensatzgr”žen */ } /* if */ } /* open_vwork */ /*****************************************************************************/ /* Schlieže virtuelle Workstation */ /*****************************************************************************/ LOCAL VOID close_vwork () { if (vwork_open) { v_clsvwk (vdi_handle); /* Workstation freigeben */ vdi_handle = phys_handle; /* Physikalischen Bildschirm benutzen */ vwork_open = FALSE; } /* if */ } /* close_vwork */ /*****************************************************************************/ LOCAL VOID trans_gimage (tree, obj) OBJECT *tree; WORD obj; { ICONBLK *piconblk; BITBLK *pbitblk; WORD *taddr; WORD wb, hl, type; type = tree [obj].ob_type; if (type == G_ICON) { piconblk = (ICONBLK *)tree [obj].ob_spec; taddr = piconblk->ib_pmask; wb = piconblk->ib_wicon; wb = wb >> 3; hl = piconblk->ib_hicon; vdi_trans (taddr, wb, taddr, wb, hl); taddr = piconblk->ib_pdata; } /* if */ else { pbitblk = (BITBLK *)tree [obj].ob_spec; taddr = pbitblk->bi_pdata; wb = pbitblk->bi_wb; hl = pbitblk->bi_hl; } /* else */ vdi_trans (taddr, wb, taddr, wb, hl); } /* trans_gimage */ /*****************************************************************************/ LOCAL VOID xywh2rect (x, y, w, h, rect) WORD x, y, w, h; RECT *rect; { rect->x = x; rect->y = y; rect->w = w; rect->h = h; } /* xywh2rect */ /*****************************************************************************/ LOCAL VOID set_clip (clipflag, size) BOOLEAN clipflag; CONST RECT *size; { RECT r; WORD xy [4]; if (size == NULL) rc_copy (&desk, &r); /* Nichts definiert, nimm Desktop */ else rc_copy (size, &r); /* Benutze definierte Gr”že */ rc_copy (&r, &clip); /* Rette aktuelle Werte */ if (rc_intersect (&desk, &r)) /* Nur auf Desktop zeichnen */ rect2array (&r, xy); else xywh2array (0 ,0 ,0 ,0, xy); /* Nichts zeichnen */ vs_clip (vdi_handle, clipflag, xy); /* Setze Rechteckausschnitt */ } /* set_clip */ /*****************************************************************************/ LOCAL VOID vdi_fix (pfd, theaddr, wb, h) MFDB *pfd; VOID *theaddr; WORD wb, h; { pfd->mp = theaddr; pfd->fwp = wb << 3; pfd->fh = h; pfd->fww = wb >> 1; pfd->np = 1; } /* vdi_fix */ /*****************************************************************************/ LOCAL VOID vdi_trans (saddr, swb, daddr, dwb, h) WORD *saddr; WORD swb; WORD *daddr; WORD dwb; WORD h; { MFDB src, dst; vdi_fix (&src, saddr, swb, h); src.ff = TRUE; vdi_fix (&dst, daddr, dwb, h); dst.ff = FALSE; vr_trnfm (vdi_handle, &src, &dst); } /* vdi_trans */ /*****************************************************************************/ LOCAL VOID rc_copy (ps, pd) CONST REG RECT *ps; REG RECT *pd; { pd->x = ps->x; pd->y = ps->y; pd->w = ps->w; pd->h = ps->h; } /* rc_copy */ /*****************************************************************************/ LOCAL BOOLEAN rc_intersect (p1, p2) CONST REG RECT *p1; REG RECT *p2; { REG WORD tx, ty, tw, th; tw = min (p2->x + p2->w, p1->x + p1->w); th = min (p2->y + p2->h, p1->y + p1->h); tx = max (p2->x, p1->x); ty = max (p2->y, p1->y); p2->x = tx; p2->y = ty; p2->w = tw - tx; p2->h = th - ty; return ((tw > tx) && (th > ty)); } /* rc_intersect */ /*****************************************************************************/ LOCAL VOID rect2array (rect, array) CONST RECT *rect; WORD *array; { *array++ = rect->x; *array++ = rect->y; *array++ = rect->x + rect->w - 1; *array = rect->y + rect->h - 1; } /* rect2array */ /*****************************************************************************/ LOCAL VOID xywh2array (x, y, w, h, array) WORD x, y, w, h; WORD *array; { *array++ = x; *array++ = y; *array++ = x + w - 1; *array = y + h - 1; } /* xywh2array */ /*****************************************************************************/ GLOBAL LONG pinit_obfix (status) BOOLEAN status; { if (status == TRUE) { if (!init_global (0, NULL, NULL, 0)) return (0L); else return ((LONG)routines); } else term_global (); return (0L); }