pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 #ifdef HAVE_CONFIG_H 00002 #include "config.h" 00003 #endif 00004 00005 #include <stdio.h> 00006 #include <stdarg.h> 00007 #include <stdlib.h> 00008 #include <string.h> 00009 00010 #include "xincludes.h" 00011 00012 #include "compat.h" 00013 #include "global.h" 00014 #include "data.h" 00015 #include "set.h" 00016 #include "misc.h" 00017 #include "mymem.h" 00018 #include "pcb-printf.h" 00019 00020 #include "hid.h" 00021 #include "../hidint.h" 00022 #include "lesstif.h" 00023 00024 #ifdef HAVE_LIBDMALLOC 00025 #include <dmalloc.h> 00026 #endif 00027 00028 /* There are three places where styles are kept: 00029 00030 First, the "active" style is in Settings.LineThickness et al. 00031 00032 Second, there are NUM_STYLES styles in PCB->RouteStyle[]. 00033 00034 Third, there are NUM_STYLES styles in Settings.RouteStyle[] 00035 00036 Selecting a style copies its values to the active style. We also 00037 need a way to modify the active style, copy the active style to 00038 PCB->RouteStyle[], and copy PCB->RouteStyle[] to 00039 Settings.RouteStyle[]. Since Lesstif reads the default style from 00040 .Xdefaults, we can ignore Settings.RouteStyle[] in general, as it's 00041 only used to initialize new PCB files. 00042 00043 So, we need to do PCB->RouteStyle <-> active style. 00044 */ 00045 00046 static Arg args[30]; 00047 static int n; 00048 #define stdarg(t,v) XtSetArg(args[n], t, v); n++ 00049 00050 typedef enum 00051 { 00052 SSthick, SSdiam, SShole, SSkeep, 00053 SSNUM 00054 } StyleValues; 00055 00056 static Widget style_dialog = 0; 00057 static Widget style_values[SSNUM]; 00058 static Widget style_pb[NUM_STYLES]; 00059 static Widget units_pb[NUM_STYLES]; 00060 static int name_hashes[NUM_STYLES]; 00061 static Widget value_form, value_labels, value_texts, units_form; 00062 static int local_update = 0; 00063 XmString xms_mm, xms_mil; 00064 00065 static const Unit *unit = 0; 00066 static XmString ustr; 00067 00068 static int 00069 hash (char *cp) 00070 { 00071 int h = 0; 00072 while (*cp) 00073 { 00074 h = h * 13 + *(unsigned char *) cp; 00075 h ^= (h >> 16); 00076 cp++; 00077 } 00078 return h; 00079 } 00080 00081 typedef struct 00082 { 00083 Widget w[NUM_STYLES]; 00084 } StyleButtons; 00085 00086 static StyleButtons *style_button_list = 0; 00087 static int num_style_buttons = 0; 00088 00089 static char *value_names[] = { 00090 "Thickness", "Diameter", "Hole", "Keepaway" 00091 }; 00092 00093 static int RouteStylesChanged (int argc, char **argv, Coord x, Coord y); 00094 00095 static void 00096 update_one_value (int i, Coord v) 00097 { 00098 char buf[100]; 00099 00100 pcb_snprintf (buf, sizeof (buf), "%m+%.2mS", unit->allow, v); 00101 XmTextSetString (style_values[i], buf); 00102 n = 0; 00103 stdarg (XmNlabelString, ustr); 00104 XtSetValues (units_pb[i], args, n); 00105 } 00106 00107 static void 00108 update_values () 00109 { 00110 local_update = 1; 00111 update_one_value (SSthick, Settings.LineThickness); 00112 update_one_value (SSdiam, Settings.ViaThickness); 00113 update_one_value (SShole, Settings.ViaDrillingHole); 00114 update_one_value (SSkeep, Settings.Keepaway); 00115 local_update = 0; 00116 lesstif_update_status_line (); 00117 } 00118 00119 void 00120 lesstif_styles_update_values () 00121 { 00122 if (!style_dialog) 00123 { 00124 lesstif_update_status_line (); 00125 return; 00126 } 00127 unit = Settings.grid_unit; 00128 ustr = XmStringCreateLocalized ((char *)Settings.grid_unit->suffix); 00129 update_values (); 00130 } 00131 00132 static void 00133 update_style_buttons () 00134 { 00135 int i = hid_get_flag ("style"); 00136 int j, n; 00137 00138 for (n = 0; n < num_style_buttons; n++) 00139 { 00140 for (j = 0; j < NUM_STYLES; j++) 00141 if (j != i - 1) 00142 XmToggleButtonSetState (style_button_list[n].w[j], 0, 0); 00143 else 00144 XmToggleButtonSetState (style_button_list[n].w[j], 1, 0); 00145 } 00146 if (style_dialog) 00147 { 00148 for (j = 0; j < NUM_STYLES; j++) 00149 if (j != i - 1) 00150 XmToggleButtonSetState (style_pb[j], 0, 0); 00151 else 00152 XmToggleButtonSetState (style_pb[j], 1, 0); 00153 } 00154 } 00155 00156 static void 00157 style_value_cb (Widget w, int i, void *cbs) 00158 { 00159 Coord n; 00160 char *s; 00161 00162 if (local_update) 00163 return; 00164 s = XmTextGetString (w); 00165 n = GetValueEx (s, NULL, NULL, NULL, unit->suffix); 00166 switch (i) 00167 { 00168 case SSthick: 00169 Settings.LineThickness = n; 00170 break; 00171 case SSdiam: 00172 Settings.ViaThickness = n; 00173 break; 00174 case SShole: 00175 Settings.ViaDrillingHole = n; 00176 break; 00177 case SSkeep: 00178 Settings.Keepaway = n; 00179 break; 00180 } 00181 update_style_buttons (); 00182 } 00183 00184 static void 00185 units_cb () 00186 { 00187 if (unit == get_unit_struct ("mm")) 00188 unit = get_unit_struct ("mil"); 00189 else 00190 unit = get_unit_struct ("mm"); 00191 ustr = XmStringCreateLocalized ((char *)unit->suffix); 00192 update_values (); 00193 } 00194 00195 static Widget 00196 style_value (int i) 00197 { 00198 Widget w, l; 00199 n = 0; 00200 stdarg (XmNtopAttachment, XmATTACH_POSITION); 00201 stdarg (XmNtopPosition, i); 00202 stdarg (XmNbottomAttachment, XmATTACH_POSITION); 00203 stdarg (XmNbottomPosition, i + 1); 00204 stdarg (XmNleftAttachment, XmATTACH_FORM); 00205 stdarg (XmNrightAttachment, XmATTACH_FORM); 00206 stdarg (XmNalignment, XmALIGNMENT_END); 00207 l = XmCreateLabel (value_labels, value_names[i], args, n); 00208 XtManageChild (l); 00209 00210 n = 0; 00211 stdarg (XmNtopAttachment, XmATTACH_POSITION); 00212 stdarg (XmNtopPosition, i); 00213 stdarg (XmNbottomAttachment, XmATTACH_POSITION); 00214 stdarg (XmNbottomPosition, i + 1); 00215 stdarg (XmNleftAttachment, XmATTACH_FORM); 00216 stdarg (XmNrightAttachment, XmATTACH_FORM); 00217 stdarg (XmNcolumns, 8); 00218 w = XmCreateTextField (value_texts, value_names[i], args, n); 00219 XtAddCallback (w, XmNvalueChangedCallback, 00220 (XtCallbackProc) style_value_cb, (XtPointer) (size_t) i); 00221 XtManageChild (w); 00222 00223 n = 0; 00224 stdarg (XmNtopAttachment, XmATTACH_POSITION); 00225 stdarg (XmNtopPosition, i); 00226 stdarg (XmNbottomAttachment, XmATTACH_POSITION); 00227 stdarg (XmNbottomPosition, i + 1); 00228 stdarg (XmNleftAttachment, XmATTACH_FORM); 00229 stdarg (XmNrightAttachment, XmATTACH_FORM); 00230 stdarg (XmNlabelString, ustr); 00231 units_pb[i] = XmCreatePushButton (units_form, value_names[i], args, n); 00232 XtAddCallback (units_pb[i], XmNactivateCallback, 00233 (XtCallbackProc) units_cb, (XtPointer) (size_t) i); 00234 XtManageChild (units_pb[i]); 00235 00236 return w; 00237 } 00238 00239 static void 00240 style_name_cb (Widget w, int i, XmToggleButtonCallbackStruct * cbs) 00241 { 00242 char *newname = lesstif_prompt_for ("New name", PCB->RouteStyle[i].Name); 00243 free (PCB->RouteStyle[i].Name); 00244 PCB->RouteStyle[i].Name = newname; 00245 RouteStylesChanged (0, 0, 0, 0); 00246 } 00247 00248 static void 00249 style_set_cb (Widget w, int i, XmToggleButtonCallbackStruct * cbs) 00250 { 00251 PCB->RouteStyle[i].Thick = Settings.LineThickness; 00252 PCB->RouteStyle[i].Diameter = Settings.ViaThickness; 00253 PCB->RouteStyle[i].Hole = Settings.ViaDrillingHole; 00254 PCB->RouteStyle[i].Keepaway = Settings.Keepaway; 00255 update_style_buttons (); 00256 } 00257 00258 static void 00259 style_selected (Widget w, int i, XmToggleButtonCallbackStruct * cbs) 00260 { 00261 RouteStyleType *style; 00262 int j, n; 00263 if (cbs && cbs->set == 0) 00264 { 00265 XmToggleButtonSetState (w, 1, 0); 00266 return; 00267 } 00268 style = PCB->RouteStyle + i; 00269 SetLineSize (style->Thick); 00270 SetViaSize (style->Diameter, true); 00271 SetViaDrillingHole (style->Hole, true); 00272 SetKeepawayWidth (style->Keepaway); 00273 if (style_dialog) 00274 { 00275 for (j = 0; j < NUM_STYLES; j++) 00276 if (j != i) 00277 XmToggleButtonSetState (style_pb[j], 0, 0); 00278 else 00279 XmToggleButtonSetState (style_pb[j], 1, 0); 00280 update_values (); 00281 } 00282 else 00283 lesstif_update_status_line (); 00284 for (n = 0; n < num_style_buttons; n++) 00285 { 00286 for (j = 0; j < NUM_STYLES; j++) 00287 if (j != i) 00288 XmToggleButtonSetState (style_button_list[n].w[j], 0, 0); 00289 else 00290 XmToggleButtonSetState (style_button_list[n].w[j], 1, 0); 00291 } 00292 } 00293 00294 static Widget 00295 style_button (int i) 00296 { 00297 Widget pb, set; 00298 00299 n = 0; 00300 stdarg (XmNtopAttachment, XmATTACH_WIDGET); 00301 stdarg (XmNtopWidget, i ? style_pb[i - 1] : value_form); 00302 stdarg (XmNleftAttachment, XmATTACH_FORM); 00303 stdarg (XmNlabelString, XmStringCreatePCB ("Name")); 00304 set = XmCreatePushButton (style_dialog, "style", args, n); 00305 XtManageChild (set); 00306 XtAddCallback (set, XmNactivateCallback, 00307 (XtCallbackProc) style_name_cb, (XtPointer) (size_t) i); 00308 00309 n = 0; 00310 stdarg (XmNtopAttachment, XmATTACH_WIDGET); 00311 stdarg (XmNtopWidget, i ? style_pb[i - 1] : value_form); 00312 stdarg (XmNleftAttachment, XmATTACH_WIDGET); 00313 stdarg (XmNleftWidget, set); 00314 stdarg (XmNlabelString, XmStringCreatePCB ("Set")); 00315 set = XmCreatePushButton (style_dialog, "style", args, n); 00316 XtManageChild (set); 00317 XtAddCallback (set, XmNactivateCallback, 00318 (XtCallbackProc) style_set_cb, (XtPointer) (size_t) i); 00319 00320 n = 0; 00321 stdarg (XmNtopAttachment, XmATTACH_WIDGET); 00322 stdarg (XmNtopWidget, i ? style_pb[i - 1] : value_form); 00323 stdarg (XmNrightAttachment, XmATTACH_FORM); 00324 stdarg (XmNleftAttachment, XmATTACH_WIDGET); 00325 stdarg (XmNleftWidget, set); 00326 stdarg (XmNlabelString, XmStringCreatePCB (PCB->RouteStyle[i].Name)); 00327 stdarg (XmNindicatorType, XmONE_OF_MANY); 00328 stdarg (XmNalignment, XmALIGNMENT_BEGINNING); 00329 pb = XmCreateToggleButton (style_dialog, "style", args, n); 00330 XtManageChild (pb); 00331 XtAddCallback (pb, XmNvalueChangedCallback, 00332 (XtCallbackProc) style_selected, (XtPointer) (size_t) i); 00333 return pb; 00334 } 00335 00336 static const char adjuststyle_syntax[] = 00337 "AdjustStyle()"; 00338 00339 static const char adjuststyle_help[] = 00340 "Displays the route style adjustment window."; 00341 00342 /* %start-doc actions AdjustStyle 00343 00344 %end-doc */ 00345 00346 static int 00347 AdjustStyle (int argc, char **argv, Coord x, Coord y) 00348 { 00349 if (!mainwind) 00350 return 1; 00351 if (style_dialog == 0) 00352 { 00353 int i; 00354 00355 unit = Settings.grid_unit; 00356 ustr = XmStringCreateLocalized ((char *)unit->suffix); 00357 00358 n = 0; 00359 stdarg (XmNautoUnmanage, False); 00360 stdarg (XmNtitle, "Route Styles"); 00361 style_dialog = XmCreateFormDialog (mainwind, "style", args, n); 00362 00363 n = 0; 00364 stdarg (XmNtopAttachment, XmATTACH_FORM); 00365 stdarg (XmNleftAttachment, XmATTACH_FORM); 00366 stdarg (XmNrightAttachment, XmATTACH_FORM); 00367 value_form = XmCreateForm (style_dialog, "values", args, n); 00368 XtManageChild (value_form); 00369 00370 n = 0; 00371 stdarg (XmNtopAttachment, XmATTACH_FORM); 00372 stdarg (XmNrightAttachment, XmATTACH_FORM); 00373 stdarg (XmNbottomAttachment, XmATTACH_FORM); 00374 stdarg (XmNfractionBase, 4); 00375 stdarg (XmNresizePolicy, XmRESIZE_GROW); 00376 units_form = XmCreateForm (value_form, "units", args, n); 00377 XtManageChild (units_form); 00378 00379 n = 0; 00380 stdarg (XmNtopAttachment, XmATTACH_FORM); 00381 stdarg (XmNbottomAttachment, XmATTACH_FORM); 00382 stdarg (XmNleftAttachment, XmATTACH_FORM); 00383 stdarg (XmNfractionBase, 4); 00384 value_labels = XmCreateForm (value_form, "values", args, n); 00385 XtManageChild (value_labels); 00386 00387 n = 0; 00388 stdarg (XmNtopAttachment, XmATTACH_FORM); 00389 stdarg (XmNbottomAttachment, XmATTACH_FORM); 00390 stdarg (XmNrightAttachment, XmATTACH_WIDGET); 00391 stdarg (XmNrightWidget, units_form); 00392 stdarg (XmNleftAttachment, XmATTACH_WIDGET); 00393 stdarg (XmNleftWidget, value_labels); 00394 stdarg (XmNfractionBase, 4); 00395 value_texts = XmCreateForm (value_form, "values", args, n); 00396 XtManageChild (value_texts); 00397 00398 for (i = 0; i < SSNUM; i++) 00399 { 00400 style_values[i] = style_value (i); 00401 name_hashes[i] = hash (PCB->RouteStyle[i].Name); 00402 } 00403 for (i = 0; i < NUM_STYLES; i++) 00404 style_pb[i] = style_button (i); 00405 update_values (); 00406 update_style_buttons (); 00407 } 00408 XtManageChild (style_dialog); 00409 return 0; 00410 } 00411 00412 static int 00413 RouteStylesChanged (int argc, char **argv, Coord x, Coord y) 00414 { 00415 int i, j, h; 00416 if (!PCB || !PCB->RouteStyle[0].Name) 00417 return 0; 00418 update_style_buttons (); 00419 if (!style_dialog) 00420 return 0; 00421 for (j = 0; j < NUM_STYLES; j++) 00422 { 00423 h = hash (PCB->RouteStyle[j].Name); 00424 if (name_hashes[j] == h) 00425 continue; 00426 name_hashes[j] = h; 00427 n = 0; 00428 stdarg (XmNlabelString, 00429 XmStringCreatePCB (PCB->RouteStyle[j].Name)); 00430 if (style_dialog) 00431 XtSetValues (style_pb[j], args, n); 00432 for (i = 0; i < num_style_buttons; i++) 00433 XtSetValues (style_button_list[i].w[j], args, n); 00434 } 00435 update_values (); 00436 return 0; 00437 } 00438 00439 void 00440 lesstif_insert_style_buttons (Widget menu) 00441 { 00442 StyleButtons *sb; 00443 int s, i; 00444 00445 num_style_buttons++; 00446 s = num_style_buttons * sizeof (StyleButtons); 00447 style_button_list = (StyleButtons *) realloc (style_button_list, s); 00448 sb = style_button_list + num_style_buttons - 1; 00449 00450 for (i = 0; i < NUM_STYLES; i++) 00451 { 00452 Widget btn; 00453 n = 0; 00454 stdarg (XmNindicatorType, XmONE_OF_MANY); 00455 stdarg (XmNlabelString, 00456 XmStringCreatePCB (PCB->RouteStyle[i].Name)); 00457 btn = XmCreateToggleButton (menu, "style", args, n); 00458 XtManageChild (btn); 00459 XtAddCallback (btn, XmNvalueChangedCallback, 00460 (XtCallbackProc) style_selected, (XtPointer) (size_t) i); 00461 sb->w[i] = btn; 00462 } 00463 update_style_buttons (); 00464 } 00465 00466 HID_Action lesstif_styles_action_list[] = { 00467 {"AdjustStyle", 0, AdjustStyle, 00468 adjuststyle_help, adjuststyle_syntax}, 00469 {"RouteStylesChanged", 0, RouteStylesChanged, 00470 routestyleschanged_help, routestyleschanged_syntax} 00471 }; 00472 00473 REGISTER_ACTIONS (lesstif_styles_action_list)