summaryrefslogblamecommitdiffstats
path: root/extra/source/xv/xv-3.10a-jumbo-fix-enh-patch-20070520.txt
blob: 51ff30a985ceb618bbca58a046921a3076975fd2 (plain) (tree)
1
2
3
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
15713
15714
15715
15716
15717
15718
15719
15720
15721
15722
15723
15724
15725
15726
15727
15728
15729
15730
15731
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744
15745
15746
15747
15748
15749
15750
15751
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763
15764
15765
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
15864
15865
15866
15867
15868
15869
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
15887
15888
15889
15890
15891
15892
15893
15894
15895
15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916
15917
15918
15919
15920
15921
15922
15923
15924
15925
15926
15927
15928
15929
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
15963
15964
15965
15966
15967
15968
15969
15970
15971
15972
15973
15974
15975
15976
15977
15978
15979
15980
15981
15982
15983
15984
15985
15986
15987
15988
15989
15990
15991
15992
15993
15994
15995
15996
15997
15998
15999
16000
16001
16002
16003
16004
16005
16006
16007
16008
16009
16010
16011
16012
16013
16014
16015
16016
16017
16018
16019
16020
16021
16022
16023
16024
16025
16026
16027
16028
16029
16030
16031
16032
16033
16034
16035
16036
16037
16038
16039
16040
16041
16042
16043
16044
16045
16046
16047
16048
16049
16050
16067
16068
16069
16070
16071
16072
16073
16074
16075
16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087
16088
16089
16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104
16105
16106
16107
16108
16109
16110
16111
16112
16113
16114
16115
16116
16117
16118
16119
16120
16121
16122
16123
16124
16125
16126
16127
16128
16129
16130
16131
16132
16133
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150
16151
16152
16153
16154
16155
16156
16157
16158
16159
16160
16161
16162
16163
16164
16165
16166
16167
16168
16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
16183
16184
16185
16186
16187
16188
16189
16190
16191
16192
16193
16194
16195
16196
16197
16198
16199
16200
16201
16202
16203
16204
16205
16206
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
16224
16225
16226
16227
16228
16229
16230
16231
16232
16233
16234
16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
16248
16249
16250
16251
16252
16253
16254
16255
16256
16257
16258
16259
16260
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
16273
16274
16275
16276
16277
16278
16279
16280
16281
16282
16283
16284
16285
16286
16287
16288
16289
16290
16291
16292
16293
16294
16295
16296
16297
16298
16299
16300
16301
16302
16303
16304
16305
16306
16307
16308
16309
16310
16311
16312
16313
16314
16315
16316
16317
16318
16319
16320
16321
16322
16323
16324
16325
16326
16327
16328
16329
16330
16331
16332
16333
16334
16335
16336
16337
16338
16339
16340
16341
16342
16343
16344
16345
16346
16347
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357
16358
16359
16360
16361
16362
16363
16364
16365
16366
16367
16368
16369
16370
16371
16372
16373
16374
16375
16376
16377
16378
16379
16380
16381
16382
16383
16384
16385
16386
16387
16388
16389
16390
16391
16392
16393
16394
16395
16396
16397
16398
16399
16400
16401
16402
16403
16404
16405
16406
16407
16408
16409
16410
16411
16412
16413
16414
16415
16416
16417
16418
16419
16420
16421
16422
16423
16424
16425
16426
16427
16428
16429
16430
16431
16432
16433
16434
16435
16436
16437
16438
16439
16440
16441
16442
16443
16444
16445
16446
16447
16448
16449
16450
16451
16452
16453
16454
16455
16456
16457
16458
16459
16460
16461
16462
16463
16464
16465
16466
16467
16468
16469
16470
16471
16472
16473
16474
16475
16476
16477
16478
16479
16480
16481
16482
16483
16484
16485
16486
16487
16488
16489
16490
16491
16492
16493
16494
16495
16496
16497
16498
16499
16500
16501
16502
16503
16504
16505
16506
16507
16508
16509
16510
16511
16512
16513
16514
16515
16516
16517
16518
16519
16520
16521
16522
16523
16524
16525
16526
16527
16528
20104
20105
20106
20107
20108
20109
20110
20111
20112
20113
20114
20115
20116
20117
20118
20119
20120
20121
20122
20123
20124
20125
20126
20127
20128
20129
20130
20131
20132
20133
20134
20135
20136
20137
20138
20139
20140
20141
20142
20143
20144
20145
20146
20147
20148
20149
20150
20151
20152
20153
20154
20155
20156
20157
20158
20159
20160
20161
20162
20163
20164
20165
20166
20167
20168
20169
20170
20171
20172
20173
20174
20175
20176
20177
20178
20179
20180
20181
20182
20183
20184
20185
20186
20187
20188
20189
20190
20191
20192
20193
20194
20195
20196
20197
20198
20199
20200
20201
20202
20203
20204
20205
20206
20207
20208
20209
20210
20211
20212
20213
20214
20215
20216
20217
20218
20219
20220
20221
20222
20223
20224
20225
20226
20227
20228
20229
20230
20231
20232
20233
20234
20235
20236
20237
20238
20239
20240
20241
20242
20243
20244
20245
20246
20247
20248
20249
20250
20251
20252
20253
20254
20255
20256
20257
20258
20259
20260
20261
20262
20263
20264
20265
20266
20267
20268
20269
20270
20271
20272
20273
20274
20275
20276
20277
20278
20279
20280
20281
20282
20283
20284
20285
20286
20287
20288
20289
20290
20291
20292
20293
20294
20295
20296
20297
20298
20299
20300
20301
20302
20303
20304
20305
20306
20307
20308
20309
20310
20311
20312
20313
20314
20315
20316
20317
20318
20319
20320
20321
20322
20323
20324
20325
20326
20327
20328
20329
20330
20331
20332
20333
20334
20335
20336
20337
20338
20339
20340
20341
20342
20343
20344
20345
20346
20347
20348
20349
20350
20351
20352
20353
20354
20355
20356
20357
20358
20359
20360
20361
20362
20363
20364
20365
20366
20367
20368
20369
20370
20371
20372
20373
20374
20375
20376
20377
20378
20379
20380
20381
20382
20383
20384
20385
20386
20387
20388
20389
20390
20391
20392
20393
20394
20395
20396
20397
20398
20399
20400
20401
20402
20403
20404
20405
20406
20407
20408
20409
20410
20411
20412
20413
20414
20415
20416
20417
20418
20419
20420
20421
20422
20423
20424
20425
20426
20427
20428
20429
20430
20431
20432
20433
20434
20435
27700
27701
27702
27703
27704
27705
27706
27707
27708
27709
27710
27711
27712
27713
27714
27715
27716
27717
27718
27719
27720
27721
27722
27723
27724
27725
27726
27727
27728
27729
27730
27731
27732
27733
27734
27735
27736
27737
27738
27739
27740
27741
27742
27743
27744
27745
27746
27747
27748
27749
27750
27751
27752
27753
27754
27755
27756
27757
27758
27759
27760
27761
27762
27763
27764
27765
27766
27767
27768
27769
27770
27771
27772
27773
27774
27775
27776
27777
27778
27779
27780
27781
27782
27783
27784
27785
27786
27787
27788
27789
27790
27791
27792
27793
27794
27795
27796
27797
27798
27799
27800
27801
27802
27803
27804
27805
27806
27807
27808
27809
27810
27811
27812
27813
27814
27815
27816
27817
27818
27819
27820
27821
27822
27823
27824
27825
27826
27827
27828
27829
27830
27831
27832
27833
27834
27835
27836
27837
27838
27839
27840
27841
27842
27843
27844
27845
27846
27847
27848
27849
27850
27851
27852
27853
27854
27855
27856
27857
27858
27859
27860
27861
27862
27863
27864
27865
27866
27867
27868
27869
27870
27871
27872
27873
27874
27875
27876
27877
27878
27879
27880
27881
27882
27883
27884
27885
27886
27887
27888
27889
27890
27891
27892
27893
27894
27895
27896
27897
27898
27899
27900
27901
27902
27903
27904
27905
27906
27907
27908
27909
27910
27911
27912
27913
27914
27915
27916
27917
27918
27919
27920
27921
27922
27923
27924
27925
27926
27927
27928
27929
27930
27931
27932
27933
27934
27935
27936
27937
27938
27939
27940
27941
27942
27943
27944
27945
27946
27947
27948
27949
27950
27951
27952
27953
27954
27955
27956
27957
27958
27959
27960
27961
27962
27963
27964
27965
27966
27967
27968
27969
27970
27971
28040
28041
28042
28043
28044
28045
28046
28047
28048
28049
28050
28051
28052
28053
28054
28055
28056
28057
28058
28059
28060
28061
28062
28063
28064
28065
28066
28067
28068
28069
28070
28071
28072
28073
28074
28075
28076
28077
28078
28079
28080
28081
28082
28083
28084
28085
28086
28087
28088
28089
28090
28091
28092
28093
28094
28095
28096
28097
28098
28099
28100
28101
28102
28103
28104
28105
28106
28107
28108
28109
28110
28111
28112
28113
28114
28115
28116
28117
28118
28119
28120
28121
28122
28123
28124
28125
28126
28127
28128
28129
28130
28131
28132
28133
28134
28135
28136
28137
28138
28139
28140
28141
28142
28143
28144
28145
28146
28147
28148
28149
28150
28151
28152
28153
28154
28155
28156
28157
28158
28159
28160
28161
28162
28163
28164
28165
28166
28167
28168
28169
28170
28171
28172
28173
28174
28175
28176
28177
28178
28179
28180
28181
28182
28183
28184
28185
28186
28187
28188
28189
28190
28191
28192
28193
28194
28195
28196
28197
28198
28199
28200
28201
28202
28203
28204
28205
28206
28207
28208
28209
28210
28211
28212
28213
28214
28215
28216
28217
28218
28219
28220
28221
28222
28223
28224
28225
28226
28227
28228
28229
28230
28231
28232
28233
28234
28235
28236
28237
28238
28239
28240
28241
28242
28243
28244
28245
28246
28247
28248
28249
28250
28251
28252
28253
28254
28255
28256
28257
28258
28259
28260
28261
28262
28263
28264
28265
28266
28267
28268
28269
28270
28271
28272
28273
28274
28275
28276
28277
28278
28279
28280
28281
28282
28283
28284
28285
28286
28287
28288
28289
28290
28291
28292
28293
28294
28295
28296
28297
28298
28299
28300
28301
28302
28303
28304
28305
28306
28307
28308
28309
28310
28311
28312
28313
28314
28315
28316
28317
28318
28319
28320
28321
28322
28323
28324
28325
28326
28327
28328
28329
28330
28331
28332
28333
28334
28335
28336
36629
36630
36631
36632
36633
36634
36635
36636
36637
36638
36639
36640
36641
36642
36643
36644
36645
36646
36647
36648
36649
36650
36651
36652
36653
36654
36655
36656
36657
36658
36659
36660
36661
36662
36663
36664
36665
36666
36667
36668
36669
36670
36671
36672
36673
36674
36675
36676
36677
36678
36679
36680
36681
36682
36683
36684
36685
36686
36687
36688
36689
36690
36691
36692
36693
36694
36695
36696
36697
36698
36699
36700
36701
36702
36703
36704
36705
36706
36707
36708
36709
36710
36711
36712
36713
36714
36715
36716
36717
36718
36719
36720
36721
36722
36723
36724
36725
36726
36727
36728
36729
36730
36731
36732
36733
36734
36735
36736
36737
36738
36739
36740
36741
36742
36743
36744
36745
36746
36747
36748
36749
36750
36751
36752
36753
36754
36755
36756
36757
36758
36759
36760
36761
36762
36763
36764
36765
36766
36767
36768
36769
36770
36771
36772
36773
36774
36775
36776
36777
36778
36779
36780
36781
36782
36783
36784
36785
36786
36787
36788
36789
36790
36791
36792
36793
36794
36795
36796
36797
36798
36799
36800
36801
36802
36803
36804
36805
36806
36807
36808
36809
36810
36811
36812
36813
36814
36815
36816
36817
36818
36819
36820
36821
36822
36823
36824
36825
36826
36827
36828
36829
36830
36831
36832
36833
36834
36835
36836
36837
36838
36839
36840
36841
36842
36843
36844
36845
36846
36847
36848
36849
36850
36851
36852
36853
36854
36855
36856
36857
36858
36859
36860
36861
36862
36863
36864
36865
36866
36867
36868
36869
36870
36871
36872
36873
36874
36875
36876
36877
36878
36879
36880
36881
36882
36883
36884
36885
36886
36887
36888
36889
36890
36891
36892
36893
36894
36895
36896
38485
38486
38487
38488
38489
38490
38491
38492
38493
38494
38495
38496
38497
38498
38499
38500
38501
38502
38503
38504
38505
38506
38507
38508
38509
38510
38511
38512
38513
38514
38515
38516
38517
38518
38519
38520
38521
38522
38523
38524
38525
38526
38527
38528
38529
38530
38531
38532
38533
38534
38535
38536
38537
38538
38539
38540
38541
38542
38543
38544
38545
38546
38547
38548
38549
38550
38551
38552
38553
38554
38555
38556
38557
38558
38559
38560
38561
38562
38563
38564
38565
38566
38567
38568
38569
38570
38571
38572
38573
38574
38575
38576
38577
38578
38579
38580
38581
38582
38583
38584
38585
38586
38587
38588
38589
38590
38591
38592
38593
38594
38595
38596
38597
38598
38599
38600
38601
38602
38603
38604
38605
38606
38607
38608
38609
38610
38611
38612
38613
38614
38615
38616
38617
38618
38619
38620
38621
38622
38623
38624
38625
38626
38627
38628
38629
38630
38631
38632
38633
38634
38635
38636
38637
38638
38639
38640
38641
38642
38643
38644
38645
38646
38647
38648
38649
38650
38651
38652
38653
38654
38655
38656
38657
38658
38659
38660
38661
38662
38663
38664
38665
38666
38667
38668
38669
38670
38671
38672
38673
38674
38675
38676
38677
38678
38679
38680
38681
38682
38683
38684
38685
38686
38687
38688
38689
38690
38691
38692
38693
38694
38695
38696
38697
38698
38699
38700
38701
38702
38703
38704
38705
38706
38707
38708
38709
38710
38711
38712
38713
38714
38715
38716
38717
38718
38719
38720
38721
38722
38723
38724
38725
38726
38727
38728
38729
38730
38731
38732
38733
38734
38735
38736
38737
38738
38739
38740
38741
38742
38743
38744
38745
38746
38747
38748
38749
38750
38751
38752
38753
38754
38755
38756
38757
38758
38759
38760
38761
38762
38763
38764
38765
38766
38767
38768
38769
38770
38771
38772
38773
38774
38775
38776
38777
38778
38779
38780
38781
38782
38783
38784
38785
38786
38787
38788
38789
38790
38791
38792
38793
38794
38795
38796
38797
38798
38799
38800
38801
38802
38803
38804
38805
38806
38807
38808
38809
38810
38811
38812
38813
38814
38815
38816
38817
38818
38819
38820
38821
38822
38823
38824
38825
38826
38827
38828
38829
38830
38831
38832
38833
38834
38835
38836
38837
38838
38839
38840
38841
38842
38843
38844
38845
38846
38847
38848
38849
38850
38851
38852
38853
38854
38855
38856
38857
38858
38859
38860
38861
38862
38863
38864
38865
38866
38867
38868
38869
38870
38871
38872
38873
38874
38875
38876
38877
38878
38879
38880
38881
38882
38883
38884
38885
38886
38887
38888
38889
38890
38891
38892
38893
38894
38895
38896
38897
38898
38899
38900
38901
38902
38903
38904
38905
38906
38907
38908
38909
38910
38911
38912
38913
38914
38915
38916
38917
38918
38919
38920
38921
38922
38923
38924
38925
38926
38927
38928
38929
38930
38931
38932
38933
38934
38935
38936
38937
38938
38939
38940
38941
38942
38943
38944
38945
38946
38947
38948
38949
38950
38951
38952
38953
38954
38955
38956
38957
38958
38959
38960
38961
38962
38963
38964
38965
38966
38967
38968
38969
38970
38971
38972
38973
38974
38975
38976
38977
38978
38979
38980
38981
38982
38983
38984
38985
38986
38987
38988
38989
38990
38991
38992
38993
38994
38995
38996
38997
38998
38999
39000
39001
39002
39003
39004
39005
39006
39007
39008
39009
39010
39011
39012
39013
39014
39015
39016
39017
39018
39019
39020
39021
39022
39023
39024
39025
39026
39027
39028
39029
39030
39031
39032
39033
39034
39035
39036
39037
39038
39039
39040
39041
39042
39043
39044
39045
39046
39047
39048
39049
39050
39051
39052
39053
39054
39055
39056
39057
39058
39059
39060
39061
39062
39063
39064
39065
39066
39067
39068
39069
39070
39071
39072
39073
39074
39075
39076
39077
39078
39079
39080
39081
39082
39083
39084
39085
39086
39087
39088
39089
39090
39091
39092
39093
39094
39095
39096
39097
39098
39099
39100
39101
39102
39103
39104
39105
39106
39107
39108
39109
39110
39111
39112
39113
39114
39115
39116
39117
39118
39119
39120
39121
39122
39123
39124
39125
39126
39127
39128
39129
39130
39131
39132
39133
39134
39135
39136
39137
39138
39139
39140
39141
39142
39143
39144
39145
39146
39147
39148
39149
39150
39151
39152
39153
39154
39155
39156
39157
39158
39159
39160
39161
39162
39163
39164
39165
39166
39167
39168
39169
39170
39171
39172
39173
39174
39175
39176
39177
39178
39179
39180
39181
39182
39183
39184
39185
39186
39187
39188
39189
39190
39191
39192
39193
39194
39195
39196
39197
39198
39199
39200
39201
39202
39203
39204
39205
39206
39207
39208
39209
39210
39211
39212
39213
39214
39215
39216
39217
39218
39219
39220
39221
39222
39223
39224
39225
39226
39227
39228
39229
39230
39231
39232
39233
39234
39235
39236
39237
39238
39239
39240
39241
39242
39243
39244
39245
39246
39247
39248
39249
39250
39251
39252
39253
39254
39255
39256
39257
39258
39259
39260
39261
39262
39263
39264
39265
39266
39267
39268
39269
39270
39271
39272
39273
39274
                                                 

                                                                         
















































                                                                          

            
 






























































                         
 

































































                                                                                 
                                                           
                                                                           





                                          
                                                                           





                                                                                
                  





                                      
  


                                                                            





                                                                                  





                                                                            
                    


                                                                               




                                                                               




                                                                       
















                                                                           







                                                                               


                                                                              







                                                                              





































































                                                                              
                                           











































                                                                               





                                                                          
                                                        


              
                    



                                                                            





                                                                           
 







                                                                        

                                                     









                                                                 











                                                                         

 
                                            
                
                                                     
                                 
                                   




















                                                                     
                   









                                                                          
                   







                                                                       





















                                                                            
 














                                                                           
                         

                                                                                        


                                                                                 


























                                                                         











                                                                           

                                                                         
             

































                                                                            








                                                                         
                     









                                                                            
                                                                 
                                                                         
                                                                               

                                                                    





                                                                             

                                                                            













                                                                         
                     














                                                                           
                                                                 
                                                                   
                                                                           





                                          
                                                                           





                                                                                
                  





                                      
  


                                                                            





                                                                                  





                                                                            
                    


                                                                               




                                                                               




                                                                       
















                                                                           







                                                                               


                                                                              







                                                                              





































































                                                                              
                                           











































                                                                               





                                                                          
                                                        


              
                    



                                                                            





                                                                           
 







                                                                        

                                                     









                                                                 











                                                                         

 
                                            
                
                                                     
                                 
                                   




















                                                                     
                   









                                                                          
                   







                                                                       




























                                                                            
 







                                                                           
                         

                                                                                        


                                                                                 


























                                                                         











                                                                           

                                                                         
             

































                                                                            








                                                                         
                     









                                                                            
                                                                 
                                                                         
                                                                               

                                                                    





                                                                             

                                                                            













                                                                         
                     














                                                                           
                                                       
                                                           
                                                                           











                                           








                                                                                                                                        


















































































































































































































































































































                                                                                













                                                                           
                                                           
                                                                           











                                                                           
                                                         
                                                           
                                                                           



















                                                                           
                                                         
                                                           



                                                                             
   

                                                                        
                                                                           
                                                                           
                                                                              







                                                                               
    



                   



                                              
                              


         








































                                                                               






















                                                                             








                                          



                                                                          
                                                                           
                                                                         
                                                                         
                                                                             





                                                     









                                                                               






                                                                             
   















                                                                               
   



















                                                                             
   









                                                                             
   

                                                                       
   




































































































































































































                                                                               



















                                                                               


































































































































                                                                                   
                                                                   

                                                                           











                            





                                               







                                                               
                                                                           
                                                                   
                                                                                   




















                                                               
                                                         
                                                           
                                                                           










                                                                       















                                                
                       







































                                                                                                                       
 






                                

                                                                       


                                                                       

                                                                       



                                                                       





                                                                       

















                                                                            







                                                      
                   









                                                    
                     













                                                                          
                     






























                                                                              
                     














                                                                   
                     













                                                                            
                     















































                                                                        
                   










                                                                            
                     


















                                                          
                     



















































































                                                                        
                     













                                                                        
                     












                                                                             
                   







                                                       
                   







                                                                        
                     











                                                                        
                   







                                                                        
                   







                                                                       
                   







                                                                       
                   






                                                                        
                     












                                                                        
                   







                                                                        
                     












                                                                        
                   







                                                                        
                      


















                                                                        
                       





















                                                                      
                     






                                                                        
                       




























                                                                             
                       












                                                                               


                                          





                                   
                      






                                                                              
                                                              
                          


                     








                                                                               
                     






                                                                 
                     







                                                   
                     







                                  
                     










                                                                  
                      











                                                                               
                       











                                                                              





                                                          










































                                                                               
                                                       
                                                           
                                                                           


















                                            








                                                                   








































































































                                                                             
                     

                                                            
                               

















































                                                                     


                                                                  
 

                                                                 

















                                                      














                                                








                                                                 

                   




































                                                         
                     



























                                                                
                     












                                                                               
                     





















                                                                           
                     











                                                         
                     





































                                                                
                                                 
                                                           
                                                                   











                                                                       













































































                                                                              



                                                                   




                                                                         
                                                                          

































































                                                                                  






                               
                 











                                                                




















                                                        











                                                             












































































                                                                                






                                                          










                                                

                       
                                    
                                                             
                                    










































































                                                                               
                     












                                                                 
                   










                                                                             










                                                            











                                                                                 

                                                                    
                            



















                                                             







                                             
                   







                                                               



















                                                                         







                                                                         
                     

































                                                                             

                      
                                                                               






                                               
















                                                                      

                                                                          
                                     



                                              






                           




                                  
 

                                                   
 










                                                                                
 







































                                                                            
























                                                                             
                     



                             











                                     


















                                                                             
                     














                                                                             
                     


























                                                                              
                     
















































                                                                            




                                              






                                              


















                                                























                                                                         
                      



















                                              
                      













                                                        
                      

























                                                                        
                    










                                                                        
                      











                                                                      
                      















                                                                             
                      






                                                                     





                                              











































                                                                           































                                                             









                                                                     








                                                                                







                                                              







































                                                             

                                                        


                                                        





                                                               




































                                                                         







                                                   

















                                                                           
 


































                                                                                   

                            
                                                                         
 
                                                                          

                                         
                                                                            
 
                                                                             

                                            
                                                                             
 
                                                                              

                                              
                                                                          
     
                                                                          
 


                                                                           

                                           
                                                                     
     
                                                                            
 


                                                                             










                                   
                                                                        
 
                                                                         

                                            


                                                                             
 





                                                                              

                                           
                                                                              
     
                                                                     
 


                                                                               












                                  
                                                                      
 
                                                                       

                                                  

























                                                                              






                                                                 

        
 





                                                                          

                                         
                                                                               
     


                                                                                
 




                                                                                

                                             

                                                                              

                                                           
                                                                        
 
                                                                         

                                            
                                                                         
 
                                                                          

                                                   
                                                                                
 
                                                                                 

                                         
                                                                           
 
                                                                            

                                             
                                                                             
 
                                                                              

                                                  
                                                                      
 



                                                                          

                                         
                                                                        
 




                                                                                 












                                                                               

                                                                                
 









                                                                                 









                                                                                
                         




                                                                            



                                                                             


                                                                             



                                                                     









                                                                   
                                                                               
 
                                                                                

                                                              























                                                                                 


















































                                                                               
                                                                            












                                                                              



                                                                           












                                                                               





                                                                      













                                                                                 












                                                                             







                                                                        
                       


















                                                                               
                     





                                                       

                                                                                 
                                                            


                                                                    



                                                                       

                                                                           
               

                                                                               







                                                            






































































































































                                                                        







                                                                     













                                                             



                                                                         
                                                            
                                                                        
                                                            







                                                                              
                     







                                                   
                      





                                                                           



                                                                        


                                             
                     







                                                                          
                       







                                                    

































                                                                              



                                                                                

                                                                            

                                         


                                                                              
                                           
 
                                     


                                                                               
                                           







                                                                                







                                                                             
                       














                                                                         
                     







                                                                                
                       














                                                            


                    











                                              


                                                                           








                                                                    


                    
 
























                                                                            







                                                                             



























































































                                                                           







                                                                   
                     







                                                                          
                     







                                                                         
                     







                                                                              
                       







                                                                  







                                                                  

 
                                
        
                                       




                                                            





                                                                                 


                                           
                     







                                                                   
                     







                                                                
                       
















                                                                                
                       












                                                                             
                     







                                                                          









                                                                          







                                                                    
                     







                                                                            
                     







                                                           









                                                                               


















                                                                 





















                                                                        



                                                     



                                                                             

              























                                                                                
                                                              






                                                                            

                                                    
                                                                     
                                                   
                                                                           

                                                                          






























                                                                                 
 

                                                                            

                                                                  
                                                                              
                                                                 
                                                                            

                                             




                                                                             
                                                   

                                                                           

                                                                   
                                                                      
   

                                                                            
 

                                                                           


                                                    
                                                                      
                                                   







                                                                             


                 







                                                                            


                


                         
 





























































































































































































                                                                                 



                                               
                       





                                               


                                                              
      
                                     





                              







                                                                              


            






                                                                     
               
                                                              
       
                                             























                                                                            
                      




                     






















































                                                                               

            












                                                                             
 

                       












                                                                            
                       





















                                                                          
                       













                                                                 
                       







                                                       






                                            







                                                     


                                                                       




                                                                  












                                                               
                           






















                                                                          












                                                              


                       
 

                                   
                                                                





















                                                                 
 


                       
 
                                     
                                                                  




















                                                                   
 






                                                                          







                                                           


                       
 

























                                                                            
   













                                                                       















                                                                               










                                                                       







                                                         
                     







                                                                          





















































                                                                                             

                                                            
                                    
     

                                    
 
                                         







                                                                        
                     










                                                                              









                                                                      












                                                                           







                                                                  









                                                 








                                          
 


                                                                         





                                                                    
                     







                                                                   
                       















                                                                      















                                      








                                                                         
                       















                                                                               
                       


























                                                                               
                       























                                                                      
                     










                                 





                                      








































                                                                                
                       

















                                                                                
                     







                                                                               
                       
















                                                                           













                                                                             










                                                                 
                       















                                                                         
                     







                                                               
                     







                                                                          
                     









                                                        
                     







                                                                             
                     







                                                                  
                       
















                                                                             
                     







                                    
                     







                                                        

















                                                                       







                                                                            














                                      














                                                      
                       












                                            








                                                                    

                  
                                                              

                                                                               











                                                                                


                                                                             
                                                      
                                                                       











                                                                              

                                                                       

                       









                                                                               
        
                                                                         


                                           





                                                    

                                                








































                                                                   
                       












                                                                        







                                                 
                                                           
                                                                   







                                                                  
                










                                                   



                                                           


                                                                         









                                                                          
 


                   
 








                                                                                                                       




                                                                           

             



                              


                   














                                                                  
                   


       




























                                                                               













                                                                                 


                     
 






















                                                                                
                                                        

























                                                                              









                              
                   







                                                                











                                                                           






                                                                          



                                                           









                                                                             


       






























                                                                               

                                
 


                    



                    




                    



                   






                   









                                                                      
 

                                                                      
 
















                                                                          
                                                                        






























































































































                                                                                                       
 







                                                                           










































































                                                               







                                                                     
































































































































































































                                                                                             













                                                                                















































































                                                                                






                                            
































                                                                                

                              
                                                              
                                           

                                                                
                                        
                                       

                           
 









                                                                 
 
 












                                                                  
 

































































































































































                                                                                
 










































































                                                                                
                                                          


                                                                     
                                                                   



































                                                                           
                                                                               



                                                                                

                                                                    



                                                           

                                                                             
                                                                        

                                                                             


                                                                          
 

                                                                   
                                                         




















































                                                                               







                                                                              

















































































                                                                               





                                                               



































































                                                                                

                                        
                                                                   

                                                                      
                                                                         

                                                                   



                                                                    
 



                                                               
 


                                                                    
 
                                                                   

                                                                           






































                                                                        
                                                                          


                                                                          
 





                                                                 
 
                                                         

                                                                     
















                                                                          

                                                                     

















                                                                   


                                                                           




















































                                                                              
                                                            



































                                                                                
                                                                 




                                                                            
 

                                                                   
                                                                         


                                                                    
 

                                                                   
                                                                         







                                                                         
                                                                            
                                                  
 

                                                                      
                                                                         



                                                                             
 

                                                                   
                                                                         


                                                                  
 



                                                                           
 

                                                                    
                                                                         















                                                                           
                                                                         



                                                            
 

                                                                   
                                                                         



















































                                                                            
 































                                                                            
                                                
                                                                          
 
                                                                    
                                                      


























































































                                                                            
                                                                     




















































































                                                                               
                                                           
                                                                           











































































































































































































                                                                               






























                                              





























































































































































































































                                                                               
                                                       
                                                           
                                                                           








                                                                                























                                                     







                                                                   
                     







                                                                           




                                                    
   




                                                          



                                                                 
                   







                                                                              
                   







                                                                      








                                                    
   




                                                          



                                                                    
                   







                                                                      









                                    







                                                                      
                     



                                         
             

                                  

                                   
















                                                                      
                   










                                                            
                   










                                        
                   







                                                                      
                   







                                                       



















                                                                                













                                                       

















                                                                          












                                                       

















                                                                       












                                                       














                                                                            



                                                                             
                   







                                                                              
                   







                                                                      
                   







                                                                          
                   







                                           
                   







                                           
                   







                                            
                   







                                                                            
                   







                                                                           
                     

























                                                                          
                   







                                                        
                     














                                                                          
                   







                                         
                     















                                                                            
                   







                                                                              
                     














                                                                               
                   







                                                                   
                     







                                                                           
                     







                                                                             
                     







                                                                               
                     







                                                                           
                     







                                                         
                     







                                                                             
                     







                                                                          
                     











                                   
                       












                                                                      
                       




































                                                                        
                       




















                                                                  
                     







                                                                            
                       




















                                                                          
                     







                                                                         
                     







                                                  
                     







                                           
                       















                                                                   
                       















                                                                          
                     







                                                                         
                     







                                                                          
                     







                                                                        
                       


















                                                                                
                     







                                                                          
                     







                                                                                
                                                       
                                                           








                                                                           
 
                
 


































































                                                                              
                                                           
















                                                                      







                                                           






                                                                        



                                    
                                                     
 
                                                       







                                                                        

                                                                                

 
                       

                                                                              



                                                              



                                                      

                                                                          

                                                                               











                                                                             

                          
















                                                                            

                                                                          
                                  
     

                        


                                      










                                                               

                    
                                                         
                   







                                                                     
                   







                                                                  

                     

                             
                        
                                                                          
                                                            


















                                                                        
                
 




























                                                                             

                                                                   

                                                                     

              





























                                                                   







                                              
















                                                                       







                                   
                   







                       

                      

                                     
            

   

                                   







                                                                             
                             
 
                                                 













                                                     
                     

















                                                                    
                                                        
























                                                                    

                                                              
























                                                                      

                      

                              
            
   


                                   


          

                       
                                                       







                                                                             






                                                               











                                                                    







                                                                  





                                                                    























                                                                            

























































































































                                                                               



                                   
                          
 
                                               

                                      





                                    




             































































                                                                                


























                                                                
                              




                               
                   







                                                                        
                     













                                                          
                     












                                                           
                     

















                                                                     
                   







                                                        
                     















                                              
                   







                                                                       
                   







                       
                   







        
                    







        
                    







                                                                           
                    







                                                
                    







                                                                                
                    







                                        









                                                             
                                                           
                                                                           







                                                                   

















                                                                                




                                                                
 
                          




































































                                                                     


                                                                             


                                                        

                                                         




















































































                                                                                
 



                                                       


                                                      
                                                   

                                                   

























































































































                                                                                







                                                                     







                                                               



                                                                            
                                                               
                                                                           
                                                                     

                                                     




























                                                                  









                                                          
                     












                                                                       















                                                                







                                                                                


                                                                         
 






                                                                               
                                                       
                                                              
                                                            














































                                                                                
                                                           


                                                                      
 














                                                                          
                   







                                                                                
                   







                                                                     













                                         












                                                                      
                   







                                                  


















                                                                  




                                                                       


              
 





























                                                                              
 


                                                                                







                                                                          















                                                                           





                                                                         
































                                                                       
        


                   







                                                                           
                    







                                                                       
                    







                                                               
                      












                                                                   
                      













                                                                     






                                                                  







                                           





                                                                  





                                           
                    







                                                                      
                       








                                                                         

                                                                      





                                                             










                                                 









                                                 
                       










                                                            

                                                                                

                                   













                                                


















                                                                        
                     







                                                                       
                       















                                                                     
                     







                                                    
































                                                              







                                                                            
                       





                                                                             


                       
                                    





                                                                       









                                                                           
                      










                                                      
                     







                                                                       
                       













                                                                               
                      



                                                

                            





                                         
                       













                                                                  


















                                                                         

                                                                 
                                          
                 

                                           
                
                                        
















                                                                      
                   
   
                    



                          
                       













                                                                          
                     






                                         
                       














                                                                             













                                                                               
 













                                                                       
                                                                

















                                             







                                
                       





                                                
                                                                              
             

                                                                              


                                             












































                                                                       











                                                                       
                     







                                                      
                       




















































                                                                              
                       














                                                                             
                     







                                                                           
                     










                                                                              
                       






















                                                                       
                     







                                                           
                     







                                                              
                     






                                                             
                     







                                                                          
                     







                                                                             
                       















                                                                    

                                                                                                     







                                                                            


















                                                                        







                                                                   





































                                                                   




                                                        


















                                                                          


                                                         
                     







                                                                       


















                                                                                







                                                                            
                     







                                                                               











                                                                        

                                                                              


                       





                                                 
                     







                                                                           



















                                                                             











                                                                                
                     









                                                 
                     







                                                                 































                                                                                














                                                                           










































































                                                                              







                                                             












                                                                      
                                     



                                                             





                                                                         
                     







                                                         
                     







                                                                         
                       











                                                                              
                       

















                                                                  
                     







                                                                          









                                                                                       



                                                                    
                                                                    
                                                         





                                                                   
 




                                                












                                                                
                     







                                                        
                       













                                                      
                       















                                                                       
                       












                                                                            
                       






                                


                                                        
                                             




































                                                                         













                                                                  
                     







                                                                            
                     







                                                                               
                     







                                                                              
                       

























                                                                         
                     







                                                   





                                                                  















                                                                          
                     










                                                            
                     







                                               
                     







                                                         
                     







                                   
                     







                                                                 


                           
                          

                                                               









                                                                                
                       
   
                                                     









                                                
                       






                                      
                                  
 
                                                               

                                                                           

                                                                         



                        
                                               
 
                                                         
                                           





                                                               




                            


















































                                                                               





















                                                                          


                            
























                                                                          
                                              

   
                                                       






















                                                                             




                                                                   
                                                    
                       

                                                    


















                                                                           














                                                                     
                       













                                                                                


                                                                 
                                                                 








                                                                             





















                                                                 
                       



















                                                                           











                                                              







                                                                            
                     







                                                                          
                       
















                                                                      
                     







                                                                  


                                                             
 




                                                                         






                                                                    
                     










                                            

































                                                                              
 










                                                            
                                                                

                                                                         
                                                               
                                                             

                                          

                               




                                                                             
                                                                               

                                                                               

                                                                   

         



















                                                                







                                             
                       


















                                                                              























                                                                               







                                                      
                     







                                                               
                     







                                                                





















                                                                         







                                                               
                     







                                                                         






                                                    
                                



                                                          


                                                                               

                                                                   

    










































































                                                                               
                  


















                                                                     






                                                                            



















                                                                      






                                                                  









                                                      







                                                                






                                                    
                                



                                                          


                                                                  


                             
  

                                                    
                                        


                                                          


                                                                       
                     



                                              

                       
                                      

                         
  


                                                                         







                                                                 












                                                    







                                                                





















                                                           









                                                                            

























                                                                 







                                                            
                     







                                                                   
                     







                                                                         
                       



                                     





                                                                        
 


                                                                       

                                                
        







                                          
                       
 







                      




                                                               






                                                    












                                                                       

























                                                                           

 




































                                                                             





                                                  
                       












                                                                 
                       











                                                                       




















































































                                                                                       
                                                      
       


                                                     
                                                                  
                                                  











                                                             
 








                                                                     







                                                                 












                                                                     







                                                                                


































































                                                                                      







                                                             
                     







                                                                              

                      

    
 
                                              


                                                       
                                           
       


                                                                            










                                                                














                                                        
                       













                                                                
                     










                                                                       
                       



                                   
                                                    
 





                                                              







                                                                            
                     







                                               

                       

                                
                                                
                                    



                                                                                      





                                                                





















                                                                  







                                                                
                     







                                                                
                       





                                    




                                   

                             
       





                                                                       










                                           









                                                                            
                     







                                                    
                     







                                                                               
                     







                                 



































































































                                                                                     
                                                           
                                                                           























                                                                       








                                












































































                                                                                






                                 




































































































































































                                                                             








                                            




































































































                                                                                
















                                                                       







                                                                              








                        





































                                                                          
                     







                                                                       

















                                                                               















                                                                              
                       















                                                                            
                     







                                                                    
                     







                                                                           







                                                   











                                                                                
                       

















                                                                               
                                                           
                                                           
                                                                           

















































































































































































































































































































































                                                                               
                     







                                                                         






                                                                        













































































































































































































































































































































































































































































                                                                               
                                                         
                                                           
                                                                           


























                                                                            
                   



                                        









                                                   
                                        
































































































































                                                                
                      

                       











                                                              
                     











                                                                            
                   







                                                                       
                   







                                                            
                   









                                                              
                   







                                                                                
                   







                                                                        
                   







                                                                   
                     



























                                                                           
                   







                                                                    
                   







                                         
                   






                         
                   







                                                      
                     















                                                                               
                   







                                                   
                   







                                                                         
                     


















                                                                             
                   







                                                                               
                   







                                                                  
                   







                                                                    
                     



















































                                                                         
                   









                                                              
                   







                                                              
                   







                                                        
                   







                                                                       
                   







                                                        
                     



















                                                                                
                   







                                                         
                     











                                                                
                   







                                                              
                   







                                                      
                                                       
                                                           
                                                                           







































































                                                                              
                     





                                                                              


                                                                


                                                                        
                                                              
 
                                                              







                                                                             


                                                                                   




                                                                               
                                      
 
                                      

                                                                               

                   









                                                                           
                     






















                                                                            
                     

























                                                                               
                     





























                                                                             
                   







                                                 
                     












                                 
                   







                                                                           
                     



















                                                               
                     





























                                                                               
                     


















                                                                       
                     












                                                                    
                     

















                                
                     

























                                                                               
                   







                                                                    
                     

















                                                                               
                     













                                                                               
                     





























                                                                          
                     

















                                                                                
                   











                                                                              
                   









                                                                          
                   







                                                             
                     






















                                                                                
                   







                                                              









                                               







                                             
                     







                                                                  
                     







                                                                         
                       














                                                                            
                     







             
                     







                                                                            
                     







                                                                               
                     







                                                                          
                     









                                                                      
                     







                                     
                     







                                                            
                       













                                                                            
                     







                                                                
                       















                                                                      
                     







                                                                         
                     










                                               
                     







                                               
                     







                      
                     







                                                            
                       











                                                         
                       




































                                                                              
                       



















                                                                     
                       













                                                                
                     







                                                             
                     







                                                                               
                       



















                                                                               
                     







                                                                  
                     









                                                                     
                     







                                                                  
                     







                                      
                                                         
                                                           
                                                                           














                                           








                                   



























                                                                              












                                







                                                                       
                     



































                                                                               





















                                                            







                                              
                   







                         
                   







                                                                

























                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                           
                                                                           













                                                                        















                                                        



                                                              
                                                                  
                                               










                                            
















                                                                   










































































                                                                             






                                           

                                                                                 







                                           


















                                                                              








                                                                              

                                    
                                                



                                    







                                                                       











                                    





                                                   
                     



                                                                    
                                                                         


                                                                          




                                                                          







                                                   
                     



















                                                               





































































                                                                          











                                                                               

















                                                                  







                                                                              









                                                                         
                                                           
                                                                           





                                                     
                   



                                                                  
















































































                                                                           






                                                                 

                                                   








                                                                          





































                                                                                        







                                                                              
                     




























































                                                                                
                     










































                                                                             
                   







                                                
                     

















                                                              

                     

                            
                            
                 

                      





















                                                                        
                     














                                                                              
                   







                                                                                
                     





















                                                                  
                   







                                                       





































                                                                                                    







                                                                          











                                                      







                                                      
                     







                                               

















































                                                                              











                                                          
                   









                                                          









                                                                          







                                                                         










                                                                             












                                                      
                     







                                                                   































                                                                                    























                                                                               
                    







                                                                            
                      
















                                                                             
                     







                                                      
                     







                                                                              
                     







                                                                          






























                                                                              







                                                                          
                       





















                                                                               




























































                                                                    





















                                                                               



                                                                    
























                                                                              















                                                                   
           












                                                                    





                                             
                       














                                                





                                                      





                                              






                                                      







                                                                
                       





















                                                                      
                     







                                                                        
                     







                                                                       
                       











                                         






                                                               











                                                        
                       













                                                                         
                     







                                                       




































                                                                              







                                                                        











































                                                   

      
 









                                                                      
                     







                                                      
                     







                                                               












                               







                  

                     

                                                              
                   
                                         

                                             


                                        






                                          







                                                                        












                                                      




















                                                                                

                                                              





                                                              
                                              













                                                                           
                       







                                          






                           









                                                                           
                     







                                                                 
                     







                                    
                     







                                                                       
                       







































                                                                               
                     







                                                                               
                     







                                               
                     









                                                                               
                     







                                                                   
                     







                                                               
                     







                                   
                       












                                                                         
                     










                                                                
                     







                                     
                     







                                          
                     







                                                                     
                     



                                                                             
                                                              
                                                                             
                                                                          

      

                     







                                                                     
                       



                                                                 
                                                  
                                                                 
                                                              









                                                                        
                     







            
                       








                                                                         

                                                                      





                                                    

                       
 
 







                                                                          
 











































































































































































































































































































































                                                                                 










                                                                    
                   







                                                                       



































                                                                             







                                                                             
                   







                                                                      
                   







                                                           
                     











                                                           












































                                                                            

                        

                 


                                                                            
                                                                             



                                                                       

          
                             


                                 





                                                                               


                                    












                                                                        
                     












                                                                           
                   







                                                                                                                                                                   
                   







                                                              
                     













                                                                            
                   










                                   


























                                                                       







                                                              


























                                                                     









                                                                             
                   







                                                                              
                   









                                                                       
                   









                                                                          
                     



                       






















                                                          
 




                                                                                 


                                        
 
                           

                                                                        

                                               
                                                                                

                                                                 



                                                                         



                                 
                                                                         

                           

       


























                                                                              
                     













                                                                         
                   







                                                                              
                   











                                                              





                                      







                                                    
                     
















































                                                                   





                                      



















                                                          







                                      





























                                                                       









                                      


















                                               









                                      





















                                                         
                      





























                                                                   
                    







                                     
                      












                                                 










                                                                            
   



                                                                                      



                                                                            
                       












                                                            





                                 







                                           
                     







                                                     
                       
























                                                                    



                                      




                                      



















                                                                      


















                                                                             
                     










                                                          
                       


























                                                                             
                        































                                                                  














                                    











































                                                                     













































                                                                            
















                                                                        
                       
































                                                                          
                       













                                                                           































                                                         



                                                         












                                                                              







                                                              













                                                                  







                                   
                       







                                                                     













                                                                              







                                                          
                     







                                                           
                       




                        


























                                                                                   


















                                                                            
                     







                                                                          
                       






















                                                                     

                                                           


        

                                                           



                                                                     
                   














                                                                     
                       





























                                                              
                     







                                       






                                                                       
   


                                                                            



                                                                     
                     







                                                                
                     







                                                                               

















                                                                             







                                                       
                       















                                                                              
                     







                              
                     







                                                                    
                     







                                                          












                                                                       





                                                            
                     









                                                                         
                       







                                                                              

























                                                    










                                                                            





                                                                                   














                                                                               
                     







                                                                             
                     







                                                               
                     







                                               
                     



                                   
                       


                                                                         
                       

















                                                                           
                     







                                                            
                     







                                                          
                     







                                                     
                     







                                                                        
                       


















                                                                                
                     







                                                     
                     









                                                                            
                     







                                                                        
                     







                                                                               
                       







                                                                             
































                                                                     

















                                                                  
                     







                                                            
                     







                                                                          
                     







                                                  
                     







                                                          
                       












                                                    
                       














                                                            
                       





















                                                                            

                                 

                 
                             
   


















































                                                              






      
                       
















                                                      
                      










                                                                           
                       

















                                                                  
                     







                                                            
                       













                                                                              
                       












                                                            
                     










                                                                       
                     







                                          
                       
























































                                                                           
                       
















                                                                             
                     







                                                          
                       





















                                                                        













                                                         














                                                       
                                                         
                                                           







































                                                                                 





                                                               

                     
                      

                            


































































































                                                                                    

                     









































                                                                              
                                         
            
               
              
                     
















                                                                       











                                                             






                                                  
                  
                  

                        




                                                                        
                
                
                  











                                                     







                                                 















                                                         
                   







                                                                              
                   







                                                                       
                   







                                                                      









                                                          






                                                                    
               
   
                     








































                                              











                                                               
                              

                     










                                                                
                     














                                                                          
                     
























                                                                                
                   







                                                                        










                                                      










                                                            
                   










                                           












                                                     







                                             
                     



























                                                                              
                   







                                                                     
                     















                                                                  
                   







                                                                            
                     













                                                                          
                   







                                                                  
                     














                                                                          
                   







                                                                        
                     












































                                                                               
                     

































                                                                  
                     










































                                                               
                   







                                  
                                                       
                                                           
                                                                           














                                                            


















                                                                             



                                                                         
                                                                      
                                                                        
                                                                            

                                                   
























                                                        















                                                                           
                   







                                                                         
                     























                                                                       
                                                                          

                                                            
                                                                          

                                                              
                                                                          


                                                                    
                     


























































                                                                
                     












                                                                
                     



                                                                
                                                                            

























                                                          
                     














                                                                               
                     















                                                                                
                   







                                                      
                     















                                                               
                   







                                                            
                   







                                                                 
                   







                                                                  









                                                        







                                         
                     












                                                           
                     
















                                                                              
                     







                                                    
                     










                                                                    
                     







                                                           
                     







                                                                        
                     







                                                                              
                     







                                                                              
                       













                                                                
                     







                                                                
                       












                                                        
                     







                                       
                       
















                                                                      
                       
















                                                                  

















                                                                               








                        
                       



                                                                 

                                                                                

                           











                                        





















































































































                                                                           
                       



                            






















                                                                         













































































































                                                                             
                       







                                                                







                                            

















                                                                               
                       









                                                           





                                      

















                                                                        
                     



                                         

                                   
 

                                          
               

    









































































































































                                                                             
















                                                                    








                                            







                                          






































































































































































































































                                                                               








                                                  








                                                                 








                                     


























                                                                             
                                                       
                                                           

                                                                           




                                                                  

                                                             




                           
 

































































                                                                                       
                                                             
                                       








                                                                
















                                                          





                                    



                                   


                                                        
                                      


                                 




                                  
 


                            

















                                                                                
                                                       
                                                               
 



                                                                     

                                                       
 
                     
 















                                                                            
                                                                                

                 
                                                      
   


                                              
   






                                                                             








                                                                                

                                                                             






                                 
                   
 
                         
                                     



































                                                                             






















                                                                              
                    












                                                                              
                     











                                                                           
                   









                                                                      
                     














                                                                            
                     



                                                                   
                                                                    
        


                                                      
 

                                                                     
            
                                   
                                              
















                                                                 






                                                          
                     











                                               
                     












                                                                       
 

                                  
                                                                 
                                                                              




                                                              



                                                 



                                                                      
                                           





















                                                                                

           
 
                                               



                                        
                                




                                                                  
                                                                               


























                                                                               


      
                   

                                                                           







                                                                   
 
                    



                                       
                        
                                                                   

























                                                                            

            






                                         







                                                 

























                                                                             
 


                                                 








                                                                   










                                                                        




























                                                                           
                   







                                                                           





                                                                                












                                                                           
 










                                                                            
                     





































































                                                                               
                     







                                                                 







                                                                      







                                      
                   









                                                                               
                     














                                                                          
                     

























































                                                                              
                     






                                
















                                                           
                                                           
                                                                           






























                                                                           



















                                                                                







                                                       
                     

















                                                         
                   







                                                                              
                   







                                                                                
                   







                                                                         
                   







                                                                     
                   







                                     
                   







                                           
                   







                                               
                     












                                              
                   







                          
                   




                                                             
                                                         
                                                           
                                                                           








                                                                             
                   





















                                                                         







                                                                                




                            


                  


                         

 
































                                                                            
 

                                      

                       

                                                            
                                               

                                         

                                            

                                 
                           
                       



                    
 


                                                                              







                                                                         
                    











                                                                           



                                                            




                                                  
       




                                                                              




                                                                 






                                                                             









                                                    







                                                                              
                     





      




                                                               




                                                             
 

                                                                           
                                                          


                                                                        






                                                         














                                                                              


































                                                                         

           





























                                                                             














                                                                        


                     
 


                                            












                                    








                                                                       









                                                                       
                    






                                       

       

                
                            























                                                                            












                                                                             

    


                                                                         
                                                                        













                                                                             














                                                           































                                                                             
                    












































                                                                    
                   







                                                                              
                     

















                                                        
                      






































































































































































                                                                            
                      











































































                                                                               





                                                                              



                                                                       

            
 







































































































































































































                                                                                
                   






                                               
                     

























                                                                                
                     










































                                                                          
                     





































                                                                              
                      
















                                                                         
                      






























































                                                                              
                      













                                                                        
                        



                                                            



                                                                            



                                                                     
         
                                       
 





















                                                                      



                                                        




                                                  




                                 

                                                      


                                          

                                                         


                                     







                                        


            




















































































                                                                          
 


 
































































                                                                              
 





                                                        


                                                                           












                                                           
 
                                                   
 












                                                   
 


                                                                           
 
                                           
 
                

  
















                                                                      












                                                              






                                                                     





                                                                


                                                     





                                           


                                           


                                                         
                                                           
                                                                           





                                             








                                                                       



































                                                                               
                     






                         






                                            
























































































































                                                                            

                     

         
                          
   
                                






                                                       



                                                                                  



                                                              
                                           
                                                             
                                                     






















































































                                                                          


















                                                                      



                                                            


                                           

              






                                             






                                                 
                   







                                                          
                   







                                              
                   







                                                               
                   










                                                                            
                                                       
                                                           

                                                                           



                                                          
                                                          
                                                                                
                                                                      

                                                                      







                                                  















































































































































































































































































                                                                                









                                                           
                                                           


















                                                                              





                                                                      
                    
                                                     
       
 



                                                                  
 
 


















                                                                  
 
                                         
 








































































































































































































































































































                                                                               



                                                                                
                     














                                                                             
                   







                                                              
                   







                                                             
                   







                                                                   
                   







                                      
                   







                                                    
                     











                                                                            
                   







                                                                               
                   







                                                                  
                     


















                                                                          
                   







                                                                       
                   







                                                   
                     





























































                                                                          
                   







                                                             
                   







                                      
                   








                                     
                   







                                                          
                   







                                                              
                   







                                      
                   







                                                     
                   







                                                     
                   







                                                                     
                    







                                                                    
                    







                                                                             
                    









                                                                     
                    







                                                                       
                    







                                                                     
                    







                                                                  
                    







                                                                  
                    







                                                         
                      














                                                                       
                    







                                                  
                    







                                                         
                    







                                                            
                    







                                                         
                      


















                                                                      
                      































                                                                
                     







                                                                               
                     







                                   
                       

























                                                                               
                       
















                                                                        
                       































                                                                         
                       
















                                                                                
                       

























                                                                            
                       


















                                                                    
                     







                                               
                     







                                                                  
                       
















                                                                         
                     







                                                            
                       











                                                            
                     







                                                       
                       















                                                                            
 






                                                     
                     











                                                     
                       















                                                                    
                     










                                                                    
                     









                                                                     
                     







                                                                              
                     







                                                                         
                       












                                                                              
                       
















                                                                            
                     










                                                             
                       














                                                                        
                     







                                                             
                       























                                                                          
                       












                                                                          
                     









                                                                        
                       



















                                                                   
                       















                                                             
                       
















                                                                    
                     







                                                                
                     







                                             
                       




                                        
                                                                      

           
                                                                           
                      





                          







                                         









                                                                              









                                                                            





                     







                                                                         








































                                                                               
 




                                            

                                                                        













                                                                
        

























































































































































































                                                                                
 

                       




















                                                                               
                       
















                                                                              
                     







                                                                   
                       
















                                                                          
                       
















                                                                            
                     







                                                                          
                       



























                                                                            
                     







                                          
                     







                                                                      
                     







                                                                
                     







                                                        
                     







                                       
                     







                                                 
                       















                                                                           
















                                                      







                                                                     
                     






                                                                     
                     









                                                                               
                     









                                                                               
                     







                                      
                     







                                                           
                     







                                                










                                             






                                         






                                                                     



                                                                     
                     







                                          
                     







                                                                           
                       








































                                                                          
                     







                                                              
                       





















                                                                         
                       




















                                                                   
                     







                                                
                     







                                                                          
                       
















                                                                          





                                                                                 



                    
                                               
 
                                                      

                                        

                     







                                                      
                     
 




            
     


                                                         
                                                           
                                                                           





                                            
               



                                                                              


                                                                                

    



                                                      
                      

                       





























                                                                               
                   

















                                                                           



                                                                






                                                                       










                                                                                






























                                                                           
                                                                 































                                                         





                                                                       






                                                        


                                                                        

                               

                     




















                                                                    





                                                                             
                                                           
                                                                           

















                                                                        



















                                                                  



















































































                                                                            
                     







                                              






                                            

















                                                                           





                                                     





























































































































































































































                                                                                
                                                         
                                                           




























                                                                               







                                                                            



































                                                                               












                                                                               
                                                                      



                                                           
                                                                       



















                                                                            
                     







































                                                                      
                     






















                                                                  
                     













                                                                      































                                                      







                                                             
                     












                                                                 
                     
















                                                           
                   







                                 
                   







                                                         
                    













                                                                               
                     
























































                                                                                
                     


















                                                                     
                    



                                                     




                                     


                         
                    



                                                     




                                       


                         
                    

 












































                                                                 
 



                                     
 




                              
    


























                                                                   
     





















                                                                              
        






























                                                                              
        
      
     


                                                                 
   
                                                                          
     















                                                                      
 

                                                                          
 








                                                                        
             





                                                                       




                                     

    
                         






                                                                         
               






                                                                      





































                                                                                


                                         


                           
                                                
                                                                       





                                                                       




























                                                                     




                                                    
                                                                              
   
                            
 





                                                                               

                                  








                                       








                                                     
                   







                                                 













                                                     







                                                                          






















































                                                                              

                                                            
                                                       
   
                                                                 


















                                                                 
                   







                                                                      
                     




                            

                                                                               

 



                                                                                









                                                                    




























                                                                          
                                                           









                                                                           


















                                                                          
                   













                                                                              















                                                              










                                                                            


















                                                                  







                                                                      
 


















                                                                              






                                                     







                             






                                                                  






                      






                                                                     





                      










                                                     


                      














                                                                           
                     



                                               
                                                           
                                              
                                                           

                                               
                                                             
                                              
                                                             

                                               
                                                             
                                              
                                                             

                                               
                                                              
                                              
                                                              

                                              

















                                                                 







                                            
                   










                                                                
                   







                                                                     
                   







                               
                   







                                                                
                     





















                                                                      
                   







                                                
                     







                                      





                                               







                                                                              



















                                                                 

       



















                                                   








                                                               
                     














                                                                           
                   







                                                 
                   







                                                                                
                   







                                                                       
                   









                                                               
                   









                                                                 
                     












                                                               
                     









                                                    



                                                    


                                                    



























                                                        
  

                       





                                                                           






                                               





                                                          













                                                                           
















                                                                       
                     























                                                                             
                     











































                                                                            




                                       






                                                                             
                   







                                                                               



















                                                                              







                                                          
                      







                                                      







                                      
  

                                                                                 

             
                  

                  




                                           



                                                


                                                             

                     





                   







                                                          










































                                                                         





                                                      

                        













                                        





































































                                                                                                               
    

                                                                        
     

                                                                      



                                   


                                                                      
    


                 
 
 








                                                                              

 
















































































































































































                                                                               
























                                                               
                   







                                                                    
                     



























                                                                
                     



                                                                               











                                                                                                 
                                                                                 
       







                                                                         
                     





























                                                                  
                      



                                                                              











                                                                                                 
                                                                                
       

















                                                                      



















































































































                                                                                         


                                                         
                   









                                                                       



















                                                                             









                                                                       









                                              







                                                                      
                   







                                                                          
                   







                                                   









                                                                             









            
                                                       
                                                           

                                                                           







                                                                       













                                                                            




                           

                                     
                      

                      
                                  















































                                                                                







                                                


























                                                                                







                                                 



























































































































                                                                                
                     














                                           







                                                       
                                                           
                                                                           
















































                                                                                  










                                                                                 











                                                                              













                                                                              




                                              







































                                                  












                                                            
                   







                                                                             
                     




                                               


                    





                                                                     

                         
                          


                        







                                                                              
                   







                                                                            
                   







                             
                   







                            


















                                                                                   













                                                                              






























                                                                                            
 









                                                                                                

                                     
                                                                         
 








                                                                                               

                                     



























































                                                                                                     












                                                                          









                                                                   











                                                                       
                   









                                                                
                   







                                                                
                    












                                                                                 






































                                                                          

            
                                                       

                                                                      
                                                                                     







                                                      





                                                                   


            
                                                                            



                                                                   
                     
























































































                                                                               
                     



                              

                                                                          
     

                                                                           
     

                                                                          
     

                                                                            
     

                                                                                
     

                                                                        
     










                                                                                 
 










                                                                                      
    


                                               

























                                                                              
                     






















                                                                           
                      


















                                                                              
                     






                      
                                                                 
                                                                   
                                                                           












































































                                                                                 
                                                     
                                                           













                                                                           



                             
                
                                               
                      

                           
                                   





























































































                                                                          
                     











                                                                 




                                                          








                                                                        









                                                           
                                                           
                                                                           







                                                                       







                                                                        






                                                                             

                   
                   
 

                       
 
                   
 













































































































































                                                                                                                                                                  











                              

























                                                         






                                                                














                                                                     









                                                                
                     



                                               
                                                  
                                          


                                                                   
                                        
                                                                   

                                                                                

                                                






                                                                                
                                                                            
                  



                                                                              
 
                                                                           
                                                                        









                                                                               
 
























                                                                          











                                                                           
                   







                                                               













                                                                             







                                                               













                                                          




                                                               

                         
                        















                                                           
    


                                       




                                       


                           

                      






                                







                                                                         


                                                          
                                                                

                                                               






                                                                        



                                                     
                                            







                                  

                                                   












                                                                      
       


                              


                                                                                














                                                            

        



                                                                      
 


                                                               
                          



                           


















                                                       






                         


                                                      
                    

                      





                                                                    
                     















                                                                               
                   







                                                                  
                   







                                                                        
























                                                                     










                                      







                                                                         







                                                                               
                   







                                                                       
                   







                                                          
                   







                                                      
                     






























                                                                            
                     













                                                        
            
   
                   





                                                           
                               
 
                                     

                                       












                                                                          













                                                      
                     







                                                                   
                       













                                                      
                     









                                                                             
                     







                                                                   
                     







                                                                              


















                                                                                      







                                                                               
                     







                                                                        
                     







                                                                            
                                                     
                                                           
                                                                           












                                                                               

                                                                                




















                                                                              
                                                                        

                                                            
                                                                        






















































                                                                          













                                                                               

























                                                                  




























                                                                       







                                                      
                   







                                                      
                   











                                                      
                   







                                                                  
                   







                                                          
                   







                                               
                     


















                                                           
                     























                                                                     





                                                                  

















                                                           
                   







                                                                  
                     





















                                                                          
                     













                                                                        
                   










                                                                     
                   







                                                                      
                       














                                                            
                     







                                                              
                       











                                          
                     







                                                                            
                     







                                              
                       

















                                                 
                     







                                                                           
                       













                                                                          
                     







                                                                         
                       










































                                                                               
                     









                                                                              





                                                      






                                                                          
                       





                                                                        
             
               

                                                           
                                                   





















                                                                              

                                                                   

                                                                  

                                                                        
              
    







                                                                       
                                                                                 






                                                                             
                       














































































































                                                                              
                     







                                                               
                     









                                                                 
                     







                                  
                      






                                                                     

                                                 


                                                                     














                                                           


            
                                                                                  

                                        
                                                                      


                                                                 
                                                                    


                                                                     
                                                               





                                                                     
               




                      
                                                       
                                                           










                                                                           

                                                                      
                 
                     

                 


                         
 


                                  







                                                            
                 







                                                                     
                 







                                                                                

                                                          


                                     
                                    


                                                 
                   







                                                             
                   







                                                                           
                   







                                                 
                   







                                                        
                   







                                                                 
                   







                                                             
                   







                                                                  









                                                         
                                                           
                                                                           








                                                                     








                                                              




































                                                                            









                                                                              

















                                                                  
                    
 







                                                            






                                                                               
                     













                                                                    
                                                       




                                                                   
                   







                                                                                
                   







                                                                                
                     











                                                                                
                   









                                                                          
                   









                                                                          
                   




     
                                                         
                                                           
                                                                           

































































































































































































































                                                                             
                                                             
                                                           
                                                                           


















































                                                                                
                   



























                                                                           







                                                                   



                                                 


                                                





                                                                  







                                                             








                                                                  











                                                      


                                                                    


                                                                     

                                                                    


                                                                     

                                                                    


                                                                     


                                                                               


                                                                               

                                                                               


                                                                               

                                                                              


                                                                               











































































































































































































































































                                                                               
                                                             
                                                           










                                                                           







                                                           



                           



























































































































                                                                                 








                                              





































































                                                                       
                                                           
                                                           
                                                                           



















                                                                








                                              























































                                                                                
                                                         
                                                           
                                                                           







                                                              












































































































































































                                                                                




                                                  









                                                       
 






































                                                                           
 

                               

                    







                                                                      











                                                                                
                     




















                                                                      
                      



                                                                      
                                                             
 
                                                              
                                                



















































                                                                          







                                                                          












                                                                       



                                                                               
                  


                                                           




























                                                                              


       
 

                           














                                                                              
 

                                                





                                                                 




















                                                                  






                                                                  



                               






                                   













                                                           






                                                                   
                   






                                                        
                   










                                                                   





                                                            


                                  


                                    
                                                



                       
  


                   







                                                                     
                   







                                                              
                   







                                                                          
                   







                                            









































                                                                       







                                                                           
                     






                                                      
                        
                                                                       




                                                   






                                                               






















                                                            









                                                              






























                                                                 












                                                                      













                                                       


















                                                                           
                      














                                                                               
                      












                                                                       

















                                                                       














                                                                       

































                                                              
                                                           

                                





                                                                     


































                                                                            




                                                    


































































































                                                                             
                                 
       

                                                











                                                                             



                                                   








                                                                      
                       
                             
                      


                        
                                                           

                                





                                        





















                                                                                   







                                                                              
                      


















                                                                               
























                                                                            







                                                                       











































                                                                           







                                                                       
                       







                                                   





















                                                               
                                

                  



                                       





                                  

                                     







                                      


            



















                                                                                    









                                                                         
                        






                                                                         





















































































































































































































































































































































































































































































































































































































































































































































































































                                                                                     
                                                           

                                                                           







                                                        




                    



































                                                                               






                                 

                             
 






















                                                                  
                 







                                                                        









                                                                           













                                                                         
                                   
                        
                                           







                                                                               


                  













                                                                               










                                                                        
                     



                                                       
                                                                           




                           
                                 


                                                        
                    










                                                                 
                     





















                                                                    
                   







                                                        
                      











































                                                                               
                            







                                       















































                                                                              













































































                                                                         
                   






                            
                   







                                                                      
                    

















                                                                               
                     






























                                                                               


















                                    



                                                                      



                                                            







                                                                                
                     
















                                                                               









                                                                            















                                                                            

                                                     

                                                                         























                                                                                
 


                                                                    












                                                                     





                                                                      









                                                                         





















                                                                          






                                                                       

















































                                                                                 











                                                      









                                                                        







                                                                     


















                                                                          







                                                                        
                    










                                                                             
                     












                                                             
                     














                                                       
                      



























                                                                                
                      




















                                                                                
                      












                                                       
                      





























                                                                         
                      











                                                                            
                    







                                                             
                      
















                                                        
                      


































                                                                           






                                                  







                                                                             
                    







                                                                             









                                                                     







                                                                           
















                                                                      







                                                                            









                                                          







                                                                                  
                     







                                                 
                     







                                                 
                     







                                                                            
                     



                                            
                                            


                    
                     







                                                   
                     







                                                   
                       











                                                   
                       











                                                  
                     







                                                  
                     







                                                  







                                                                






                           






                                         







                            
                     







                               
                     







                           
                     







                           
                     







                                
                     







                                                                               

                                              

                                              
                     
                         
                                       





























                                                                                
                     







                                                                 
                      
























                                                                                































































                                                                                         







                                                       
                        







                                                                            











































































































                                                                                  







                             
                     







                                                                      



























                                                                







                               











































                                                                           
                                                           
                                                                           


























































                                                                              









                                                                






























                                                                              
                     
















                                                                         
                     














































                                                                                
                   







                                                               
                     


















                                                                               
                   







                                                      
                   










                                                         









                                            







                                                             
                   







                                               
                                                       
                                                           

                                                                           



                                            

                                            
 
                                                        
 









                                              













































                                                                           






                                                        















                                                                        
                     







              






                                              








                                                                              







                                 







                                                                        
                                                       
                                                           
                                                                           








                                                                  











                                                                 







                               



                               
































































































































                                                                              
                                                                    

                                                               








                                                                    



                                                                       









                                                                            
















                                                                            
                   









                                                 
                   










                                                                
                     













                                               







                                                                           







                                         
                     















































                                                                               
                   







                                                                        

                                        

                           
                                                            
   

                                                                                




























                                                                          








                                               



















                                                                        
                     















                                          
                   







                                                             
                   







                                   
                     



























                                                                         
                   










                                             
                   







                               
                   







                        
                     







                                                                             
                           


                                                                                
                     












                                                                          

                           

    
                                      







                                                                
                     

















                                                                      
                   







                                         
                   







                                                                              
                     













                                        
                                                       
                                                           
                                                                           












                                                                         
                   






































































                                                                              
                   






                                                                         






                                                        






                                                        
 
                            
                                               
                                                                   
                                                  









                                                          


                           
 

                     



                                    


                                                            

              



                                    






























                                                                          
                     




















                                                             
                     






















                                                               




                                                            
        

                                 












                                            
                
                                                                    











                                                                 
 






















                                                              


















                                                          
                     











                                                               
                   









                                                              
                   







                                                                     
                     



                                                                         
                                 
                                                                          
                                       





                                                                           
                               
                                                                            
                                     























                                                                        
                     












                                                                             
                    





                                      
                                                                         




                                                                        
                     

































                                                                             
                                          






                                                                           

                               

                                 

                               
 



                                            
    


                             
    


                              
    



                           














                                             
                   







                                           
                     
















































                                                          

















                                              







                       
                   







                                             
                   







               
                   







                                 
                   






                                
                   



                         
diff :  xv-3.10a-jumbo-fix-enh-patch-20070520.txt

This is a unified diff.  It should be applied (using Larry Wall's "patch"
program) to the stock XV 3.10a sources.  See the "How to build" section of
README.jumbo, which, along with roughly 40 other new files and 3 new sub-
directories, should have been unpacked along with this jumbo patch:

	README.jumbo
	README.pcd
	bits/br_bzip2
	bits/br_jp2
	bits/br_jpc
	bits/br_mag
	bits/br_maki
	bits/br_mgcsfx
	bits/br_pcd
	bits/br_pi
	bits/br_pic
	bits/br_pic2
	bits/br_png
	bits/br_zx
	contrib/
	contrib/fnkey-scripts/
	contrib/fnkey-scripts/README
	contrib/fnkey-scripts/jpegcrop.sh
	contrib/fnkey-scripts/jpegeditcom.sh
	contrib/fnkey-scripts/jpeglogrot.sh
	contrib/fnkey-scripts/jpegrot.sh
	contrib/fnkey-scripts/jpegundocrop.sh
	contrib/fedora/
	contrib/fedora/README
	contrib/fedora/Build-FC5
	docs/xvdocs.pdf
	tiff/RANLIB.sh
	xv_mgcsfx.sample
	xvhips.c
	xvhips.h
	xvjp2k.c
	xvmag.c
	xvmaki.c
	xvmgcsfx.c
	xvml.c
	xvml.h
	xvpcd.c
	xvpi.c
	xvpic.c
	xvpic2.c
	xvpng.c
	xvvd.c
	xvwbmp.c
	xvzx.c


diffs below:

	Imakefile
	Makefile
	Makefile.std
	bggen.c
	bits/br_targa
	bits/icon
	cleandir
	config.h
	copyright.h
	docs/bggen.man
	docs/xcmap.man
	docs/xv.man
	docs/xvp2p.man
	tiff/Makefile
	tiff/Makefile.std
	vdcomp.c
	xcmap.c
	xv.c
	xv.h
	xv24to8.c
	xvalg.c
	xvbmp.c
	xvbrowse.c
	xvbutt.c
	xvcolor.c
	xvctrl.c
	xvcut.c
	xvdflt.c
	xvdflt.h
	xvdial.c
	xvdir.c
	xvevent.c
	xvfits.c
	xvgam.c
	xvgif.c
	xvgifwr.c
	xvgrab.c
	xvgraf.c
	xviff.c
	xvimage.c
	xvinfo.c
	xviris.c
	xvjpeg.c
	xvmisc.c
	xvpbm.c
	xvpcx.c
	xvpds.c
	xvpictoppm.c
	xvpm.c
	xvpopup.c
	xvps.c
	xvrle.c
	xvroot.c
	xvscrl.c
	xvsmooth.c
	xvsunras.c
	xvtarga.c
	xvtext.c
	xvtiff.c
	xvtiffwr.c
	xvxbm.c
	xvxpm.c
	xvxwd.c


diff -ru xv-3.10a/Imakefile xv-3.10a-enhancements/Imakefile
--- xv-3.10a/Imakefile	1995-01-13 12:24:01.000000000 -0800
+++ xv-3.10a-enhancements/Imakefile	2005-04-17 14:04:22.000000000 -0700
@@ -104,6 +104,11 @@
 SGI = -Dsgi
 #endif
 
+/* install directory of xv_mgcsfx.sample. */
+MGCSFXDIR = $(LIBDIR)
+/* Directory of default configuration file. */
+MGCSFX = -DMGCSFXDIR=\"$(MGCSFXDIR)\"
+
 
 
 
@@ -137,6 +142,8 @@
 #if defined(SCOArchitecture)
 SCO= -Dsco -DPOSIX -DNO_RANDOM 
 SYS_LIBRARIES=        -lm -lc -lx 
+#elif defined(HPArchitecture)
+SYS_LIBRARIES=        -lm -lV3
 #else
 SYS_LIBRARIES=        -lm
 #endif
@@ -147,7 +154,7 @@
 
 DEFINES= $(SCO) $(UNIX) $(NODIRENT) $(VPRINTF) $(TIMERS) \
 	$(HPUX7) $(JPEG) $(TIFF) $(PDS) $(DXWM) $(RAND) \
-	$(BACKING_STORE) $(BSDTYPES) $(SGI)
+	$(BACKING_STORE) $(BSDTYPES) $(SGI) $(MGCSFX)
 
 INCLUDES = $(JPEGINCLUDE) $(TIFFINCLUDE)
 
@@ -157,7 +164,9 @@
 	xvdial.c xvgraf.c xvsunras.c xvjpeg.c xvps.c xvpopup.c xvdflt.c \
 	xvtiff.c xvtiffwr.c xvpds.c xvrle.c xviris.c xvgrab.c vprintf.c \
 	xvbrowse.c xvtext.c xvpcx.c xviff.c xvtarga.c xvxpm.c xvcut.c \
-	xvxwd.c xvfits.c
+	xvxwd.c xvfits.c xvpng.c xvzx.c xvwbmp.c xvpcd.c \
+	xvmag.c xvpic.c xvmaki.c xvpi.c xvpic2.c xvvd.c xvmgcsfx.c \
+	xvml.c
 
 OBJS1 =	xv.o xvevent.o xvroot.o xvmisc.o xvimage.o xvcolor.o xvsmooth.o \
 	xv24to8.o xvgif.o xvpm.o xvinfo.o xvctrl.o xvscrl.o xvalg.o \
@@ -165,7 +174,9 @@
 	xvdial.o xvgraf.o xvsunras.o xvjpeg.o xvps.o xvpopup.o xvdflt.o \
 	xvtiff.o xvtiffwr.o xvpds.o xvrle.o xviris.o xvgrab.o vprintf.o \
 	xvbrowse.o xvtext.o xvpcx.o xviff.o xvtarga.o xvxpm.o xvcut.o \
-	xvxwd.o xvfits.o
+	xvxwd.o xvfits.o xvpng.o xvzx.o xvwbmp.o xvpcd.o \
+	xvmag.o xvpic.o xvmaki.o xvpi.o xvpic2.o xvvd.o xvmgcsfx.o \
+	xvml.o
 
 SRCS2=	bggen.c
 OBJS2=	bggen.o
@@ -266,6 +277,8 @@
 InstallManPageLong(docs/xvp2p,$(MANDIR),xvpictoppm)
 InstallManPageLong(docs/vdcomp,$(MANDIR),vdcomp)
 
+InstallNonExecFile(xv_mgcsfx.sample,$(MGCSFXDIR))
+
 tar:
 	tar cf xv.tar Makefile* Imakefile *.c *.h bits docs \
 		 docs unsupt vms $(JPEGDIR) $(TIFFDIR) $(MISC)
diff -ru xv-3.10a/Makefile xv-3.10a-enhancements/Makefile
--- xv-3.10a/Makefile	1995-01-23 12:20:54.000000000 -0800
+++ xv-3.10a-enhancements/Makefile	2007-05-20 21:17:35.000000000 -0700
@@ -2,7 +2,11 @@
 
 # your C compiler (and options) of choice
 CC = cc
-# CC = gcc -ansi
+#CC = gcc -ansi
+# note that -ansi kills __USE_MISC (gcc 2.95.3), which, at least on Linux,
+# determines whether stdlib.h includes prototypes for mktemp(), random(), etc.
+# (i.e., if you use it, you will get unnecessary compiler warnings)
+#CC = gcc
 
 # use this if you're using 'cc' on a DEC Alpha (OSF/1) or MIPS (Ultrix) system:
 # CC = cc -std1 -Olimit 750
@@ -14,8 +18,20 @@
 #       -Wuninitialized -Wparentheses
 
 
-CCOPTS = -O 
-
+CCOPTS = -O
+#
+# these are the usual optimization and warning options for gcc; all such
+# warnings but one (mktemp() use) have been eliminated (at least on Linux):
+#CCOPTS = -O3 -Wall
+#
+# slightly more warnings... older code often made non-const pointers to
+# static strings (nothing should blow up unless something tries to write
+# to them):
+#CCOPTS = -O3 -Wall -Wpointer-arith -Wcast-align -Wwrite-strings -Wnested-externs
+#
+# for the next step up in gcc noise, try adding -W (but note that it adds a
+# huge number of unused-parameter and signed/unsigned comparison warnings):
+#CCOPTS = -O3 -Wall -W
 
 ### NOTE: Sun running OpenWindows:
 ### if you're using a SUN running OPENWINDOWS, you need to add these two
@@ -27,50 +43,155 @@
 ### '-I' options on the CCOPTS line to tell the compiler where said files are.
 
 
+# older Unixen don't support the -p option, but its lack may mean installation
+# will fail (if more than one directory level is missing)
+MKDIR = mkdir -p
+
+
+# BeOS _may_ need to use a different version (below), but probably not
+CLEANDIR = cleandir
+
+
 ### Installation locations
-BINDIR = /usr/local/bin
-MANDIR = /usr/local/man/man1
+### NOTE: Users of old K&R compilers (i.e., any version not supporting C89
+### string concatenation, such as "fub" "ar" => "fubar") should update
+### xvtext.c:1831 (or thereabouts) if either PREFIX or DOCDIR changes:
+PREFIX = /usr/local
+BINDIR = $(PREFIX)/bin
+MANDIR = $(PREFIX)/share/man/man1
 MANSUF = 1
-LIBDIR = /usr/local/lib
+DOCDIR = $(PREFIX)/share/doc/xv
+LIBDIR = $(PREFIX)/lib/xv
+SYSCONFDIR = /etc
+DESTDIR =
 
 
 buildit: all
 
 
 ########################### CONFIGURATION OPTIONS ############################
-### NOTE: be sure to check 'config.h', for a few other configuration options 
+### NOTE: be sure to check 'config.h', for a few other configuration options
 ##############################################################################
 
 ###
+### if, for whatever reason, you're unable to get the TIFF library to compile
+### on your machine, *COMMENT OUT* the following lines
+###
+### GRR 20050319:  USE_TILED_TIFF_BOTLEFT_FIX enables an experimental fix for
+###   tiled TIFFs with ORIENTATION_BOTLEFT.  It may break other tiled TIFFs,
+###   or it may be required for certain other TIFF types (e.g., strips with
+###   ORIENTATION_BOTLEFT).  I don't have a sufficient variety of TIFF test
+###   images at hand.
+###
+#TIFF    = -DDOTIFF
+TIFF    = -DDOTIFF -DUSE_TILED_TIFF_BOTLEFT_FIX
+###
+#TIFFDIR = tiff
+TIFFDIR = /usr
+#TIFFDIR = /usr/local
+#TIFFDIR = ../../libtiff
+###
+TIFFINC = -I$(TIFFDIR)/include
+#TIFFINC = -I$(TIFFDIR)
+###
+### libtiff 3.5 and up may be compiled with zlib and libjpeg, but the
+### dependency is properly handled in LIBS line ~247 lines below
+###
+TIFFLIB = -L$(TIFFDIR)/lib -ltiff
+#TIFFLIB = $(TIFFDIR)/lib/libtiff.a
+#TIFFLIB = -L$(TIFFDIR) -ltiff
+#TIFFLIB = $(TIFFDIR)/libtiff.a
+###
+### this is intended to build the ancient version (3.3.016 beta) that's
+### included in the "tiff" subdir of XV, not an arbitrary copy of libtiff:
+###
+#$(TIFFLIB):
+#	( cd $(TIFFDIR) ; make CC='$(CC)' COPTS='$(CCOPTS) $(MCHN)' )
+
+
+###
 ### if, for whatever reason, you're unable to get the JPEG library to compile
 ### on your machine, *COMMENT OUT* the following lines
 ###
+### NOTE: /usr/sfw can be used on Solaris with "Sun freeware" installed
+###
 JPEG    = -DDOJPEG
-JPEGDIR = jpeg
-JPEGINC = -I$(JPEGDIR)
-JPEGLIB = $(JPEGDIR)/libjpeg.a
-$(JPEGDIR)/jconfig.h:
-	cd $(JPEGDIR) ; ./configure CC='$(CC)'
-$(JPEGLIB):  $(JPEGDIR)/jconfig.h
-	cd $(JPEGDIR) ; make
+#JPEGDIR = jpeg
+JPEGDIR = /usr
+#JPEGDIR = /usr/local
+#JPEGDIR = ../../libjpeg
+#JPEGDIR = /usr/sfw
+###
+JPEGINC = -I$(JPEGDIR)/include
+#JPEGINC = -I$(JPEGDIR)
+###
+JPEGLIB = -L$(JPEGDIR)/lib -ljpeg
+#JPEGLIB = -L$(JPEGDIR) -ljpeg
+#JPEGLIB = $(JPEGDIR)/libjpeg.a
+###
+### this is intended to build the ancient version (5a) that's included in the
+### "jpeg" subdir of XV, not an arbitrary copy of libjpeg:
+###
+#$(JPEGDIR)/jconfig.h:
+#	cd $(JPEGDIR) ; ./configure CC='$(CC)'
+#$(JPEGLIB):  $(JPEGDIR)/jconfig.h
+#	cd $(JPEGDIR) ; make
 
 
 ###
-### if, for whatever reason, you're unable to get the TIFF library to compile
+### if, for whatever reason, you're unable to get the PNG library to compile
 ### on your machine, *COMMENT OUT* the following lines
 ###
-TIFF    = -DDOTIFF
-TIFFDIR = tiff
-TIFFINC = -I$(TIFFDIR)
-TIFFLIB = $(TIFFDIR)/libtiff.a
-$(TIFFLIB):
-	( cd $(TIFFDIR) ; make CC='$(CC)' )
+PNG    = -DDOPNG
+PNGDIR = /usr
+#PNGDIR = /usr/local
+#PNGDIR = ../../libpng
+###
+PNGINC = -I$(PNGDIR)/include
+#PNGINC = -I$(PNGDIR)
+###
+PNGLIB = -L$(PNGDIR)/lib -lpng
+#PNGLIB = -L$(PNGDIR) -lpng
+#PNGLIB = $(PNGDIR)/libpng.a
+
+
+###
+### if, for whatever reason, you're unable to get both the PNG library and
+### (newer versions of) the TIFF library to compile on your machine, *COMMENT
+### OUT* the following lines
+###
+ZLIBDIR = /usr
+#ZLIBDIR = /usr/local
+#ZLIBDIR = ../../zlib
+###
+ZLIBINC = -I$(ZLIBDIR)/include
+#ZLIBINC = -I$(ZLIBDIR)
+###
+ZLIBLIB = -L$(ZLIBDIR)/lib -lz
+#ZLIBLIB = -L$(ZLIBDIR) -lz
+#ZLIBLIB = $(ZLIBDIR)/libz.a
+
+
+###
+### if, for whatever reason, you're unable to get the JasPer JPEG-2000 library
+### to compile on your machine, *COMMENT OUT* the following lines
+###
+JP2K    = -DDOJP2K
+###
+#JP2KDIR = ../../jasper
+JP2KDIR = /usr/local/lib
+###
+#JP2KINC = -I$(JP2KDIR)
+JP2KINC = -I/usr/local/include
+###
+#JP2KLIB = -L$(JP2KDIR) -ljasper
+JP2KLIB = $(JP2KDIR)/libjasper.a
 
 
 ###
 ### if, for whatever reason, you're unable to get the PDS/VICAR support
 ### to compile (xvpds.c, and vdcomp.c), *COMMENT OUT* the following line,
-### and also remove 'vdcomp' from the 'all:' dependancy 
+### and also remove 'vdcomp' from the 'all:' dependency
 ###
 PDS = -DDOPDS
 
@@ -78,46 +199,60 @@
 #----------System V----------
 
 # if you are running on a SysV-based machine, such as HP, Silicon Graphics,
-# Solaris, etc., uncomment the following line to get mostly there.  
-#UNIX = -DSVR4
+# Solaris, etc.; uncomment one of the following lines to get you *most* of
+# the way there.  SYSV means System V R3.
+# UNIX = -DSVR4
+# UNIX = -DSYSV
+
 
+#----------Machine-Specific Configurations----------
+
+### If you are using a BeOS system, uncomment the following line
+#MCHN = -DUSE_GETCWD -I/usr/X11/include -L/usr/X11/lib
+###
+### The stock version of cleandir now should work for BeOS, too, so try
+### leaving this commented out:
+#CLEANDIR = cleandir.BeOS
 
-#----------Machine Specific Configurations----------
 
 ### If you are using an SGI system, uncomment the following line
 #MCHN = -Dsgi
 
 
-### For HP-UX, uncomment the following line:
+### For HP-UX, uncomment the following line
 #MCHN= -Dhpux -D_HPUX_SOURCE
 # To use old HP compilers (HPUX 7.0 or so), you may need
 #MCHN= -Dhpux -D_HPUX_SOURCE +Ns4000
 #
-# also, if you're using HP's compiler, add '-Aa' to whichever of those
+# Also, if you're using HP's compiler, add '-Aa' to whichever of those
 # two lines you're using, to turn on ANSI C mode.  Or so I'm told.
 #
-# note:  You may need to add '-I/usr/include/X11R5' (or R6, or whatever)
+# Note:  You may need to add '-I/usr/include/X11R5' (or R6, or whatever)
 # to whichever of those lines you used, as HP tends to store their X11
 # include files in a non-standard place...
+#
+# And you probably have to add '-lV3' to the end of the LIBS def when
+# using XV's AUTO_EXPAND option.
 
 
-### for LINUX, uncomment the following line
-#MCHN = -DLINUX
+### for Linux, uncomment one of the following lines:
+#MCHN = -DLINUX -L/usr/X11R6/lib
+#MCHN = -DLINUX -L/usr/X11R6/lib64
 
 
 # For SCO 1.1 (UNIX 3.2v2) machines, uncomment the following:
 #MCHN = -Dsco -DPOSIX
 #
 # For ODT 2.0 (UNIX 3.2v4) machines, uncomment the following:
-#MCHN= -Dsco -DPOSIX -DNO_RANDOM 
+#MCHN= -Dsco -DPOSIX -DNO_RANDOM
 #
 # Also, you should add '-lc -lx' to the end of the LIBS def below
 # -lx must be after -lc so you get the right directory routines.
 
 
 # for UMAX V by Encore Computers uncomment the following line for
-# the portable c compiler, system specific definitions and
-# location of local X11 library(if site specific, modify -L option)
+# the portable C compiler, system-specific definitions and
+# location of local X11 library (if site-specific, modify -L option)
 # No other switches should be necessary, or so I'm told...
 #
 #MCHN = -q extensions=pcc_c -D__UMAXV__ -L/usr2/usr/lib/X11 -DSVR4
@@ -147,8 +282,8 @@
 #TIMERS = -DUSLEEP
 
 
-# if XV locks up whenever you click on *any* of the buttons, the Timer() 
-# function in xvmisc.c is going out to lunch.  A simple workaround is to 
+# if XV locks up whenever you click on *any* of the buttons, the Timer()
+# function in xvmisc.c is going out to lunch.  A simple workaround is to
 # uncomment the following line:
 #TIMERS = -DNOTIMER
 
@@ -160,7 +295,7 @@
 #DXWM = -DDXWM
 
 
-# if, during compilation, your system complains about the types 
+# if, during compilation, your system complains about the types
 # 'u_long', 'u_short', 'u_int', etc. as being undefined, uncomment the
 # following line:
 #BSDTYPES = -DBSDTYPES
@@ -177,18 +312,38 @@
 #VPRINTF = -DNEED_VPRINTF -DLONGINT -DNOSTDHDRS
 
 
+# if your machine puts the prototype for 'malloc()' in malloc.h rather than
+# stdlib.h, uncomment the following line:
+#
+#MALLOC = -DNEED_MALLOC_H
 
 
-################ END OF CONFIGURATION OPTIONS #################
+# if your X Window System compiled with -DX_LOCALE, 
+# uncomment the following line:
+# TVL10N = -DX_LOCALE
+
+# Install directory of xv_mgcsfx.sample.
+MGCSFXDIR = $(LIBDIR)
+# Directory of default configuration file.
+MGCSFX = -DMGCSFXDIR=\"$(MGCSFXDIR)\"
+
 
 
 
+################ END OF CONFIGURATION OPTIONS #################
+
 
-CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \
-	$(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \
-	$(DXWM) $(MCHN)
 
-LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -lm
+
+CFLAGS = $(CCOPTS) $(PNG) $(PNGINC) $(ZLIBINC) $(JPEG) $(JPEGINC) \
+	$(TIFF) $(TIFFINC) $(PDS) $(JP2K) $(JP2KINC) $(TVL10N) $(MGCSFX) \
+	$(UNIX) $(BSDTYPES) $(RAND) $(MALLOC) $(DXWM) $(MCHN) $(NODIRENT) \
+	$(VPRINTF) $(TIMERS) -DDOCDIR=\"$(DOCDIR)\" \
+	-DSYSCONFDIR=\"$(SYSCONFDIR)\" -DXVEXECPATH=\"$(LIBDIR)\"
+
+### remove -lm for BeOS:
+LIBS = $(TIFFLIB) $(JPEGLIB) $(PNGLIB) $(ZLIBLIB) $(JP2KLIB) -L/usr/X11R6/lib -lX11 -lm
+#LIBS = $(TIFFLIB) $(JPEGLIB) $(PNGLIB) $(ZLIBLIB) $(JP2KLIB) -lX11
 
 OBJS = 	xv.o xvevent.o xvroot.o xvmisc.o xvimage.o xvcolor.o xvsmooth.o \
 	xv24to8.o xvgif.o xvpm.o xvinfo.o xvctrl.o xvscrl.o xvalg.o \
@@ -196,7 +351,9 @@
 	xvdial.o xvgraf.o xvsunras.o xvjpeg.o xvps.o xvpopup.o xvdflt.o \
 	xvtiff.o xvtiffwr.o xvpds.o xvrle.o xviris.o xvgrab.o vprintf.o \
 	xvbrowse.o xvtext.o xvpcx.o xviff.o xvtarga.o xvxpm.o xvcut.o \
-	xvxwd.o xvfits.o
+	xvxwd.o xvfits.o xvpng.o xvzx.o xvwbmp.o xvpcd.o xvhips.o \
+	xvmag.o xvpic.o xvmaki.o xvpi.o xvpic2.o xvvd.o xvmgcsfx.o \
+	xvml.o xvjp2k.o
 
 MISC = README INSTALL CHANGELOG IDEAS
 
@@ -206,10 +363,12 @@
 
 
 
-all: $(JPEGLIB) $(TIFFLIB) xv bggen vdcomp xcmap xvpictoppm
+#all: $(JPEGLIB) $(TIFFLIB) xv bggen vdcomp xcmap xvpictoppm
+all: xv bggen vdcomp xcmap xvpictoppm
 
 
-xv: $(OBJS) $(JPEGLIB) $(TIFFLIB)
+#xv: $(OBJS) $(JPEGLIB) $(TIFFLIB)
+xv: $(OBJS)
 	$(CC) -o xv $(CFLAGS) $(OBJS) $(LIBS)
 
 bggen: bggen.c
@@ -231,23 +390,47 @@
 
 clean:  xvclean
 	rm -f bggen vdcomp xcmap xvpictoppm
-	./cleandir $(JPEGDIR)
-	rm -f $(JPEGDIR)/jconfig.h $(JPEGDIR)/Makefile
-	./cleandir $(TIFFDIR)
+#	clean only local jpeg and tiff dirs, not user's or system's copies:
+	./$(CLEANDIR) jpeg
+	rm -f jpeg/jconfig.h jpeg/Makefile
+	./$(CLEANDIR) tiff
 
 
+# could also do some shell trickery here to attempt mkdir only if dir is
+# missing (e.g., "test -d <dir> || $(MKDIR) <dir>")
 install: all
-	cp xv bggen vdcomp xcmap xvpictoppm $(BINDIR)
-	cp docs/xv.man     $(MANDIR)/xv.$(MANSUF)
-	cp docs/bggen.man  $(MANDIR)/bggen.$(MANSUF)
-	cp docs/xcmap.man  $(MANDIR)/xcmap.$(MANSUF)
-	cp docs/xvp2p.man  $(MANDIR)/xvpictoppm.$(MANSUF)
-	cp docs/vdcomp.man $(MANDIR)/vdcomp.$(MANSUF)
-	cp docs/xvdocs.ps* $(LIBDIR)
+	$(MKDIR) $(DESTDIR)$(BINDIR)
+	cp xv bggen vdcomp xcmap xvpictoppm $(DESTDIR)$(BINDIR)/.
+	chmod 755 $(DESTDIR)$(BINDIR)/xv $(DESTDIR)$(BINDIR)/bggen \
+	  $(DESTDIR)$(BINDIR)/vdcomp $(DESTDIR)$(BINDIR)/xcmap \
+	  $(DESTDIR)$(BINDIR)/xvpictoppm
+#
+	$(MKDIR) $(DESTDIR)$(MANDIR)
+	cp docs/xv.man     $(DESTDIR)$(MANDIR)/xv.$(MANSUF)
+	cp docs/bggen.man  $(DESTDIR)$(MANDIR)/bggen.$(MANSUF)
+	cp docs/xcmap.man  $(DESTDIR)$(MANDIR)/xcmap.$(MANSUF)
+	cp docs/xvp2p.man  $(DESTDIR)$(MANDIR)/xvpictoppm.$(MANSUF)
+	cp docs/vdcomp.man $(DESTDIR)$(MANDIR)/vdcomp.$(MANSUF)
+	chmod 644 $(DESTDIR)$(MANDIR)/xv.$(MANSUF) \
+	  $(DESTDIR)$(MANDIR)/bggen.$(MANSUF) \
+	  $(DESTDIR)$(MANDIR)/xcmap.$(MANSUF) \
+	  $(DESTDIR)$(MANDIR)/xvpictoppm.$(MANSUF) \
+	  $(DESTDIR)$(MANDIR)/vdcomp.$(MANSUF)
+#
+	$(MKDIR) $(DESTDIR)$(DOCDIR)		# or $(DESTDIR)$(LIBDIR)
+	cp README.jumbo docs/xvdocs.pdf docs/xvdocs.ps $(DESTDIR)$(DOCDIR)/.
+	chmod 644 $(DESTDIR)$(DOCDIR)/README.jumbo \
+	  $(DESTDIR)$(DOCDIR)/xvdocs.pdf $(DESTDIR)$(DOCDIR)/xvdocs.ps
+#
+	#$(MKDIR) $(DESTDIR)$(SYSCONFDIR)
+	#cp xv_mgcsfx.sample $(DESTDIR)$(SYSCONFDIR)/xv_mgcsfx
+	#chmod 644 $(DESTDIR)$(SYSCONFDIR)/xv_mgcsfx
+
 
 tar:
+#	tar only local jpeg and tiff dirs, not user's or system's copies:
 	tar cvf xv.tar Makefile* Imakefile *.c *.h bits \
-		docs unsupt vms $(JPEGDIR) $(TIFFDIR) $(MISC) 
+		docs unsupt vms jpeg tiff $(MISC)
 
 xvtar:
 	tar cvf xv.tar Makefile* Imakefile *.c *.h bits
@@ -257,26 +440,28 @@
 
 ################# bitmap dependencies ####################
 
-xv.o:      	bits/icon bits/iconmask bits/runicon bits/runiconm
-xv.o:      	bits/cboard50 bits/gray25 
+xv.o:		bits/icon bits/iconmask bits/runicon bits/runiconm
+xv.o:		bits/cboard50 bits/gray25
 
 xvbrowse.o:	bits/br_file bits/br_dir bits/br_exe bits/br_chr bits/br_blk
-xvbrowse.o:	bits/br_sock bits/br_fifo bits/br_error bits/br_unknown
-xvbrowse.o:	bits/br_cmpres bits/br_gif bits/br_pm bits/br_pbm
+xvbrowse.o:	bits/br_sock bits/br_fifo bits/br_error # bits/br_unknown
+xvbrowse.o:	bits/br_cmpres bits/br_bzip2 bits/br_gif bits/br_pm bits/br_pbm
 xvbrowse.o:	bits/br_sunras bits/br_bmp bits/br_utah bits/br_iris
-xvbrowse.o:	bits/br_pcx bits/br_jfif bits/br_tiff bits/br_pds 
-xvbrowse.o:	bits/br_ps bits/br_iff bits/br_targa bits/br_xpm
+xvbrowse.o:	bits/br_pcx bits/br_jfif bits/br_tiff bits/br_pds bits/br_pcd
+xvbrowse.o:	bits/br_ps bits/br_iff bits/br_targa bits/br_xpm bits/br_xwd
+xvbrowse.o:	bits/br_fits bits/br_png bits/br_zx bits/br_mag bits/br_maki
+xvbrowse.o:	bits/br_pic bits/br_pi bits/br_pic2 bits/br_mgcsfx
+xvbrowse.o:	bits/br_jp2 bits/br_jpc
 xvbrowse.o:	bits/br_trash bits/fcurs bits/fccurs bits/fdcurs bits/fcursm
-xvbrowse.o:     bits/br_xwd
 
 xvbutt.o:	bits/cboard50 bits/rb_frame bits/rb_frame1 bits/rb_top
 xvbutt.o:	bits/rb_bot bits/rb_dtop bits/rb_dbot bits/rb_body
 xvbutt.o:	bits/rb_dot bits/cb_check bits/mb_chk
 
 xvctrl.o:	bits/gray25 bits/gray50 bits/i_fifo bits/i_chr bits/i_dir
-xvctrl.o: 	bits/i_blk bits/i_lnk bits/i_sock bits/i_exe bits/i_reg
+xvctrl.o:	bits/i_blk bits/i_lnk bits/i_sock bits/i_exe bits/i_reg
 xvctrl.o:	bits/h_rotl bits/h_rotr bits/fliph bits/flipv bits/p10
-xvctrl.o:	bits/m10 bits/cut bits/copy bits/paste bits/clear 
+xvctrl.o:	bits/m10 bits/cut bits/copy bits/paste bits/clear
 xvctrl.o:	bits/uicon bits/oicon1 bits/oicon2 bits/icon
 xvctrl.o:	bits/padimg bits/annot
 
@@ -285,13 +470,13 @@
 xvdflt.o:	bits/logo_top bits/logo_bot bits/logo_out bits/xv_jhb
 xvdflt.o:	bits/xv_cpyrt bits/xv_rev bits/xv_ver
 xvdflt.o:	bits/xf_left bits/xf_right bits/font5x9.h
-xvdflt.o:       xvdflt.h
+xvdflt.o:	xvdflt.h
 
 xvdial.o:	bits/dial_cw1 bits/dial_ccw1 bits/dial_cw2 bits/dial_ccw2
 
 xvdir.o:	bits/d_load bits/d_save
 
-xvevent.o:	bits/dropper bits/dropperm bits/pen bits/penm 
+xvevent.o:	bits/dropper bits/dropperm bits/pen bits/penm
 xvevent.o:	bits/blur bits/blurm
 
 xvgam.o:	bits/h_rotl bits/h_rotr bits/h_flip bits/h_sinc bits/h_sdec
diff -ru xv-3.10a/Makefile.std xv-3.10a-enhancements/Makefile.std
--- xv-3.10a/Makefile.std	1995-01-23 17:06:26.000000000 -0800
+++ xv-3.10a-enhancements/Makefile.std	2007-05-20 21:17:35.000000000 -0700
@@ -2,7 +2,11 @@
 
 # your C compiler (and options) of choice
 CC = cc
-# CC = gcc -ansi
+#CC = gcc -ansi
+# note that -ansi kills __USE_MISC (gcc 2.95.3), which, at least on Linux,
+# determines whether stdlib.h includes prototypes for mktemp(), random(), etc.
+# (i.e., if you use it, you will get unnecessary compiler warnings)
+#CC = gcc
 
 # use this if you're using 'cc' on a DEC Alpha (OSF/1) or MIPS (Ultrix) system:
 # CC = cc -std1 -Olimit 750
@@ -14,8 +18,20 @@
 #       -Wuninitialized -Wparentheses
 
 
-CCOPTS = -O 
-
+CCOPTS = -O
+#
+# these are the usual optimization and warning options for gcc; all such
+# warnings but one (mktemp() use) have been eliminated (at least on Linux):
+#CCOPTS = -O3 -Wall
+#
+# slightly more warnings... older code often made non-const pointers to
+# static strings (nothing should blow up unless something tries to write
+# to them):
+#CCOPTS = -O3 -Wall -Wpointer-arith -Wcast-align -Wwrite-strings -Wnested-externs
+#
+# for the next step up in gcc noise, try adding -W (but note that it adds a
+# huge number of unused-parameter and signed/unsigned comparison warnings):
+#CCOPTS = -O3 -Wall -W
 
 ### NOTE: Sun running OpenWindows:
 ### if you're using a SUN running OPENWINDOWS, you need to add these two
@@ -27,50 +43,155 @@
 ### '-I' options on the CCOPTS line to tell the compiler where said files are.
 
 
+# older Unixen don't support the -p option, but its lack may mean installation
+# will fail (if more than one directory level is missing)
+MKDIR = mkdir -p
+
+
+# BeOS _may_ need to use a different version (below), but probably not
+CLEANDIR = cleandir
+
+
 ### Installation locations
-BINDIR = /usr/local/bin
-MANDIR = /usr/local/man/man1
+### NOTE: Users of old K&R compilers (i.e., any version not supporting C89
+### string concatenation, such as "fub" "ar" => "fubar") should update
+### xvtext.c:1831 (or thereabouts) if either PREFIX or DOCDIR changes:
+PREFIX = /usr/local
+BINDIR = $(PREFIX)/bin
+MANDIR = $(PREFIX)/share/man/man1
 MANSUF = 1
-LIBDIR = /usr/local/lib
+DOCDIR = $(PREFIX)/share/doc/xv
+LIBDIR = $(PREFIX)/lib/xv
+SYSCONFDIR = /etc
+DESTDIR =
 
 
 buildit: all
 
 
 ########################### CONFIGURATION OPTIONS ############################
-### NOTE: be sure to check 'config.h', for a few other configuration options 
+### NOTE: be sure to check 'config.h', for a few other configuration options
 ##############################################################################
 
 ###
+### if, for whatever reason, you're unable to get the TIFF library to compile
+### on your machine, *COMMENT OUT* the following lines
+###
+### GRR 20050319:  USE_TILED_TIFF_BOTLEFT_FIX enables an experimental fix for
+###   tiled TIFFs with ORIENTATION_BOTLEFT.  It may break other tiled TIFFs,
+###   or it may be required for certain other TIFF types (e.g., strips with
+###   ORIENTATION_BOTLEFT).  I don't have a sufficient variety of TIFF test
+###   images at hand.
+###
+#TIFF    = -DDOTIFF
+TIFF    = -DDOTIFF -DUSE_TILED_TIFF_BOTLEFT_FIX
+###
+#TIFFDIR = tiff
+TIFFDIR = /usr
+#TIFFDIR = /usr/local
+#TIFFDIR = ../../libtiff
+###
+TIFFINC = -I$(TIFFDIR)/include
+#TIFFINC = -I$(TIFFDIR)
+###
+### libtiff 3.5 and up may be compiled with zlib and libjpeg, but the
+### dependency is properly handled in LIBS line ~247 lines below
+###
+TIFFLIB = -L$(TIFFDIR)/lib -ltiff
+#TIFFLIB = $(TIFFDIR)/lib/libtiff.a
+#TIFFLIB = -L$(TIFFDIR) -ltiff
+#TIFFLIB = $(TIFFDIR)/libtiff.a
+###
+### this is intended to build the ancient version (3.3.016 beta) that's
+### included in the "tiff" subdir of XV, not an arbitrary copy of libtiff:
+###
+#$(TIFFLIB):
+#	( cd $(TIFFDIR) ; make CC='$(CC)' COPTS='$(CCOPTS) $(MCHN)' )
+
+
+###
 ### if, for whatever reason, you're unable to get the JPEG library to compile
 ### on your machine, *COMMENT OUT* the following lines
 ###
+### NOTE: /usr/sfw can be used on Solaris with "Sun freeware" installed
+###
 JPEG    = -DDOJPEG
-JPEGDIR = jpeg
-JPEGINC = -I$(JPEGDIR)
-JPEGLIB = $(JPEGDIR)/libjpeg.a
-$(JPEGDIR)/jconfig.h:
-	cd $(JPEGDIR) ; ./configure CC='$(CC)'
-$(JPEGLIB):  $(JPEGDIR)/jconfig.h
-	cd $(JPEGDIR) ; make
+#JPEGDIR = jpeg
+JPEGDIR = /usr
+#JPEGDIR = /usr/local
+#JPEGDIR = ../../libjpeg
+#JPEGDIR = /usr/sfw
+###
+JPEGINC = -I$(JPEGDIR)/include
+#JPEGINC = -I$(JPEGDIR)
+###
+JPEGLIB = -L$(JPEGDIR)/lib -ljpeg
+#JPEGLIB = -L$(JPEGDIR) -ljpeg
+#JPEGLIB = $(JPEGDIR)/libjpeg.a
+###
+### this is intended to build the ancient version (5a) that's included in the
+### "jpeg" subdir of XV, not an arbitrary copy of libjpeg:
+###
+#$(JPEGDIR)/jconfig.h:
+#	cd $(JPEGDIR) ; ./configure CC='$(CC)'
+#$(JPEGLIB):  $(JPEGDIR)/jconfig.h
+#	cd $(JPEGDIR) ; make
 
 
 ###
-### if, for whatever reason, you're unable to get the TIFF library to compile
+### if, for whatever reason, you're unable to get the PNG library to compile
 ### on your machine, *COMMENT OUT* the following lines
 ###
-TIFF    = -DDOTIFF
-TIFFDIR = tiff
-TIFFINC = -I$(TIFFDIR)
-TIFFLIB = $(TIFFDIR)/libtiff.a
-$(TIFFLIB):
-	( cd $(TIFFDIR) ; make CC='$(CC)' )
+PNG    = -DDOPNG
+PNGDIR = /usr
+#PNGDIR = /usr/local
+#PNGDIR = ../../libpng
+###
+PNGINC = -I$(PNGDIR)/include
+#PNGINC = -I$(PNGDIR)
+###
+PNGLIB = -L$(PNGDIR)/lib -lpng
+#PNGLIB = -L$(PNGDIR) -lpng
+#PNGLIB = $(PNGDIR)/libpng.a
+
+
+###
+### if, for whatever reason, you're unable to get both the PNG library and
+### (newer versions of) the TIFF library to compile on your machine, *COMMENT
+### OUT* the following lines
+###
+ZLIBDIR = /usr
+#ZLIBDIR = /usr/local
+#ZLIBDIR = ../../zlib
+###
+ZLIBINC = -I$(ZLIBDIR)/include
+#ZLIBINC = -I$(ZLIBDIR)
+###
+ZLIBLIB = -L$(ZLIBDIR)/lib -lz
+#ZLIBLIB = -L$(ZLIBDIR) -lz
+#ZLIBLIB = $(ZLIBDIR)/libz.a
+
+
+###
+### if, for whatever reason, you're unable to get the JasPer JPEG-2000 library
+### to compile on your machine, *COMMENT OUT* the following lines
+###
+JP2K    = -DDOJP2K
+###
+#JP2KDIR = ../../jasper
+JP2KDIR = /usr/local/lib
+###
+#JP2KINC = -I$(JP2KDIR)
+JP2KINC = -I/usr/local/include
+###
+#JP2KLIB = -L$(JP2KDIR) -ljasper
+JP2KLIB = $(JP2KDIR)/libjasper.a
 
 
 ###
 ### if, for whatever reason, you're unable to get the PDS/VICAR support
 ### to compile (xvpds.c, and vdcomp.c), *COMMENT OUT* the following line,
-### and also remove 'vdcomp' from the 'all:' dependancy 
+### and also remove 'vdcomp' from the 'all:' dependency
 ###
 PDS = -DDOPDS
 
@@ -78,46 +199,60 @@
 #----------System V----------
 
 # if you are running on a SysV-based machine, such as HP, Silicon Graphics,
-# Solaris, etc., uncomment the following line to get mostly there.  
-#UNIX = -DSVR4
+# Solaris, etc.; uncomment one of the following lines to get you *most* of
+# the way there.  SYSV means System V R3.
+# UNIX = -DSVR4
+# UNIX = -DSYSV
+
 
+#----------Machine-Specific Configurations----------
+
+### If you are using a BeOS system, uncomment the following line
+#MCHN = -DUSE_GETCWD -I/usr/X11/include -L/usr/X11/lib
+###
+### The stock version of cleandir now should work for BeOS, too, so try
+### leaving this commented out:
+#CLEANDIR = cleandir.BeOS
 
-#----------Machine Specific Configurations----------
 
 ### If you are using an SGI system, uncomment the following line
 #MCHN = -Dsgi
 
 
-### For HP-UX, uncomment the following line:
+### For HP-UX, uncomment the following line
 #MCHN= -Dhpux -D_HPUX_SOURCE
 # To use old HP compilers (HPUX 7.0 or so), you may need
 #MCHN= -Dhpux -D_HPUX_SOURCE +Ns4000
 #
-# also, if you're using HP's compiler, add '-Aa' to whichever of those
+# Also, if you're using HP's compiler, add '-Aa' to whichever of those
 # two lines you're using, to turn on ANSI C mode.  Or so I'm told.
 #
-# note:  You may need to add '-I/usr/include/X11R5' (or R6, or whatever)
+# Note:  You may need to add '-I/usr/include/X11R5' (or R6, or whatever)
 # to whichever of those lines you used, as HP tends to store their X11
 # include files in a non-standard place...
+#
+# And you probably have to add '-lV3' to the end of the LIBS def when
+# using XV's AUTO_EXPAND option.
 
 
-### for LINUX, uncomment the following line
-#MCHN = -DLINUX
+### for Linux, uncomment one of the following lines:
+#MCHN = -DLINUX -L/usr/X11R6/lib
+#MCHN = -DLINUX -L/usr/X11R6/lib64
 
 
 # For SCO 1.1 (UNIX 3.2v2) machines, uncomment the following:
 #MCHN = -Dsco -DPOSIX
 #
 # For ODT 2.0 (UNIX 3.2v4) machines, uncomment the following:
-#MCHN= -Dsco -DPOSIX -DNO_RANDOM 
+#MCHN= -Dsco -DPOSIX -DNO_RANDOM
 #
 # Also, you should add '-lc -lx' to the end of the LIBS def below
 # -lx must be after -lc so you get the right directory routines.
 
 
 # for UMAX V by Encore Computers uncomment the following line for
-# the portable c compiler, system specific definitions and
-# location of local X11 library(if site specific, modify -L option)
+# the portable C compiler, system-specific definitions and
+# location of local X11 library (if site-specific, modify -L option)
 # No other switches should be necessary, or so I'm told...
 #
 #MCHN = -q extensions=pcc_c -D__UMAXV__ -L/usr2/usr/lib/X11 -DSVR4
@@ -147,8 +282,8 @@
 #TIMERS = -DUSLEEP
 
 
-# if XV locks up whenever you click on *any* of the buttons, the Timer() 
-# function in xvmisc.c is going out to lunch.  A simple workaround is to 
+# if XV locks up whenever you click on *any* of the buttons, the Timer()
+# function in xvmisc.c is going out to lunch.  A simple workaround is to
 # uncomment the following line:
 #TIMERS = -DNOTIMER
 
@@ -160,7 +295,7 @@
 #DXWM = -DDXWM
 
 
-# if, during compilation, your system complains about the types 
+# if, during compilation, your system complains about the types
 # 'u_long', 'u_short', 'u_int', etc. as being undefined, uncomment the
 # following line:
 #BSDTYPES = -DBSDTYPES
@@ -177,18 +312,38 @@
 #VPRINTF = -DNEED_VPRINTF -DLONGINT -DNOSTDHDRS
 
 
+# if your machine puts the prototype for 'malloc()' in malloc.h rather than
+# stdlib.h, uncomment the following line:
+#
+#MALLOC = -DNEED_MALLOC_H
 
 
-################ END OF CONFIGURATION OPTIONS #################
+# if your X Window System compiled with -DX_LOCALE, 
+# uncomment the following line:
+# TVL10N = -DX_LOCALE
+
+# Install directory of xv_mgcsfx.sample.
+MGCSFXDIR = $(LIBDIR)
+# Directory of default configuration file.
+MGCSFX = -DMGCSFXDIR=\"$(MGCSFXDIR)\"
+
 
 
 
+################ END OF CONFIGURATION OPTIONS #################
+
 
-CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \
-	$(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \
-	$(DXWM) $(MCHN)
 
-LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -lm
+
+CFLAGS = $(CCOPTS) $(PNG) $(PNGINC) $(ZLIBINC) $(JPEG) $(JPEGINC) \
+	$(TIFF) $(TIFFINC) $(PDS) $(JP2K) $(JP2KINC) $(TVL10N) $(MGCSFX) \
+	$(UNIX) $(BSDTYPES) $(RAND) $(MALLOC) $(DXWM) $(MCHN) $(NODIRENT) \
+	$(VPRINTF) $(TIMERS) -DDOCDIR=\"$(DOCDIR)\" \
+	-DSYSCONFDIR=\"$(SYSCONFDIR)\" -DXVEXECPATH=\"$(LIBDIR)\"
+
+### remove -lm for BeOS:
+LIBS = $(TIFFLIB) $(JPEGLIB) $(PNGLIB) $(ZLIBLIB) $(JP2KLIB) -L/usr/X11R6/lib -lX11 -lm
+#LIBS = $(TIFFLIB) $(JPEGLIB) $(PNGLIB) $(ZLIBLIB) $(JP2KLIB) -lX11
 
 OBJS = 	xv.o xvevent.o xvroot.o xvmisc.o xvimage.o xvcolor.o xvsmooth.o \
 	xv24to8.o xvgif.o xvpm.o xvinfo.o xvctrl.o xvscrl.o xvalg.o \
@@ -196,7 +351,9 @@
 	xvdial.o xvgraf.o xvsunras.o xvjpeg.o xvps.o xvpopup.o xvdflt.o \
 	xvtiff.o xvtiffwr.o xvpds.o xvrle.o xviris.o xvgrab.o vprintf.o \
 	xvbrowse.o xvtext.o xvpcx.o xviff.o xvtarga.o xvxpm.o xvcut.o \
-	xvxwd.o xvfits.o
+	xvxwd.o xvfits.o xvpng.o xvzx.o xvwbmp.o xvpcd.o xvhips.o \
+	xvmag.o xvpic.o xvmaki.o xvpi.o xvpic2.o xvvd.o xvmgcsfx.o \
+	xvml.o xvjp2k.o
 
 MISC = README INSTALL CHANGELOG IDEAS
 
@@ -206,10 +363,12 @@
 
 
 
-all: $(JPEGLIB) $(TIFFLIB) xv bggen vdcomp xcmap xvpictoppm
+#all: $(JPEGLIB) $(TIFFLIB) xv bggen vdcomp xcmap xvpictoppm
+all: xv bggen vdcomp xcmap xvpictoppm
 
 
-xv: $(OBJS) $(JPEGLIB) $(TIFFLIB)
+#xv: $(OBJS) $(JPEGLIB) $(TIFFLIB)
+xv: $(OBJS)
 	$(CC) -o xv $(CFLAGS) $(OBJS) $(LIBS)
 
 bggen: bggen.c
@@ -231,23 +390,47 @@
 
 clean:  xvclean
 	rm -f bggen vdcomp xcmap xvpictoppm
-	./cleandir $(JPEGDIR)
-	rm -f $(JPEGDIR)/jconfig.h $(JPEGDIR)/Makefile
-	./cleandir $(TIFFDIR)
+#	clean only local jpeg and tiff dirs, not user's or system's copies:
+	./$(CLEANDIR) jpeg
+	rm -f jpeg/jconfig.h jpeg/Makefile
+	./$(CLEANDIR) tiff
 
 
+# could also do some shell trickery here to attempt mkdir only if dir is
+# missing (e.g., "test -d <dir> || $(MKDIR) <dir>")
 install: all
-	cp xv bggen vdcomp xcmap xvpictoppm $(BINDIR)
-	cp docs/xv.man     $(MANDIR)/xv.$(MANSUF)
-	cp docs/bggen.man  $(MANDIR)/bggen.$(MANSUF)
-	cp docs/xcmap.man  $(MANDIR)/xcmap.$(MANSUF)
-	cp docs/xvp2p.man  $(MANDIR)/xvpictoppm.$(MANSUF)
-	cp docs/vdcomp.man $(MANDIR)/vdcomp.$(MANSUF)
-	cp docs/xvdocs.ps* $(LIBDIR)
+	$(MKDIR) $(DESTDIR)$(BINDIR)
+	cp xv bggen vdcomp xcmap xvpictoppm $(DESTDIR)$(BINDIR)/.
+	chmod 755 $(DESTDIR)$(BINDIR)/xv $(DESTDIR)$(BINDIR)/bggen \
+	  $(DESTDIR)$(BINDIR)/vdcomp $(DESTDIR)$(BINDIR)/xcmap \
+	  $(DESTDIR)$(BINDIR)/xvpictoppm
+#
+	$(MKDIR) $(DESTDIR)$(MANDIR)
+	cp docs/xv.man     $(DESTDIR)$(MANDIR)/xv.$(MANSUF)
+	cp docs/bggen.man  $(DESTDIR)$(MANDIR)/bggen.$(MANSUF)
+	cp docs/xcmap.man  $(DESTDIR)$(MANDIR)/xcmap.$(MANSUF)
+	cp docs/xvp2p.man  $(DESTDIR)$(MANDIR)/xvpictoppm.$(MANSUF)
+	cp docs/vdcomp.man $(DESTDIR)$(MANDIR)/vdcomp.$(MANSUF)
+	chmod 644 $(DESTDIR)$(MANDIR)/xv.$(MANSUF) \
+	  $(DESTDIR)$(MANDIR)/bggen.$(MANSUF) \
+	  $(DESTDIR)$(MANDIR)/xcmap.$(MANSUF) \
+	  $(DESTDIR)$(MANDIR)/xvpictoppm.$(MANSUF) \
+	  $(DESTDIR)$(MANDIR)/vdcomp.$(MANSUF)
+#
+	$(MKDIR) $(DESTDIR)$(DOCDIR)		# or $(DESTDIR)$(LIBDIR)
+	cp README.jumbo docs/xvdocs.pdf docs/xvdocs.ps $(DESTDIR)$(DOCDIR)/.
+	chmod 644 $(DESTDIR)$(DOCDIR)/README.jumbo \
+	  $(DESTDIR)$(DOCDIR)/xvdocs.pdf $(DESTDIR)$(DOCDIR)/xvdocs.ps
+#
+	#$(MKDIR) $(DESTDIR)$(SYSCONFDIR)
+	#cp xv_mgcsfx.sample $(DESTDIR)$(SYSCONFDIR)/xv_mgcsfx
+	#chmod 644 $(DESTDIR)$(SYSCONFDIR)/xv_mgcsfx
+
 
 tar:
+#	tar only local jpeg and tiff dirs, not user's or system's copies:
 	tar cvf xv.tar Makefile* Imakefile *.c *.h bits \
-		docs unsupt vms $(JPEGDIR) $(TIFFDIR) $(MISC) 
+		docs unsupt vms jpeg tiff $(MISC)
 
 xvtar:
 	tar cvf xv.tar Makefile* Imakefile *.c *.h bits
@@ -257,26 +440,28 @@
 
 ################# bitmap dependencies ####################
 
-xv.o:      	bits/icon bits/iconmask bits/runicon bits/runiconm
-xv.o:      	bits/cboard50 bits/gray25 
+xv.o:		bits/icon bits/iconmask bits/runicon bits/runiconm
+xv.o:		bits/cboard50 bits/gray25
 
 xvbrowse.o:	bits/br_file bits/br_dir bits/br_exe bits/br_chr bits/br_blk
-xvbrowse.o:	bits/br_sock bits/br_fifo bits/br_error bits/br_unknown
-xvbrowse.o:	bits/br_cmpres bits/br_gif bits/br_pm bits/br_pbm
+xvbrowse.o:	bits/br_sock bits/br_fifo bits/br_error # bits/br_unknown
+xvbrowse.o:	bits/br_cmpres bits/br_bzip2 bits/br_gif bits/br_pm bits/br_pbm
 xvbrowse.o:	bits/br_sunras bits/br_bmp bits/br_utah bits/br_iris
-xvbrowse.o:	bits/br_pcx bits/br_jfif bits/br_tiff bits/br_pds 
-xvbrowse.o:	bits/br_ps bits/br_iff bits/br_targa bits/br_xpm
+xvbrowse.o:	bits/br_pcx bits/br_jfif bits/br_tiff bits/br_pds bits/br_pcd
+xvbrowse.o:	bits/br_ps bits/br_iff bits/br_targa bits/br_xpm bits/br_xwd
+xvbrowse.o:	bits/br_fits bits/br_png bits/br_zx bits/br_mag bits/br_maki
+xvbrowse.o:	bits/br_pic bits/br_pi bits/br_pic2 bits/br_mgcsfx
+xvbrowse.o:	bits/br_jp2 bits/br_jpc
 xvbrowse.o:	bits/br_trash bits/fcurs bits/fccurs bits/fdcurs bits/fcursm
-xvbrowse.o:     bits/br_xwd
 
 xvbutt.o:	bits/cboard50 bits/rb_frame bits/rb_frame1 bits/rb_top
 xvbutt.o:	bits/rb_bot bits/rb_dtop bits/rb_dbot bits/rb_body
 xvbutt.o:	bits/rb_dot bits/cb_check bits/mb_chk
 
 xvctrl.o:	bits/gray25 bits/gray50 bits/i_fifo bits/i_chr bits/i_dir
-xvctrl.o: 	bits/i_blk bits/i_lnk bits/i_sock bits/i_exe bits/i_reg
+xvctrl.o:	bits/i_blk bits/i_lnk bits/i_sock bits/i_exe bits/i_reg
 xvctrl.o:	bits/h_rotl bits/h_rotr bits/fliph bits/flipv bits/p10
-xvctrl.o:	bits/m10 bits/cut bits/copy bits/paste bits/clear 
+xvctrl.o:	bits/m10 bits/cut bits/copy bits/paste bits/clear
 xvctrl.o:	bits/uicon bits/oicon1 bits/oicon2 bits/icon
 xvctrl.o:	bits/padimg bits/annot
 
@@ -285,13 +470,13 @@
 xvdflt.o:	bits/logo_top bits/logo_bot bits/logo_out bits/xv_jhb
 xvdflt.o:	bits/xv_cpyrt bits/xv_rev bits/xv_ver
 xvdflt.o:	bits/xf_left bits/xf_right bits/font5x9.h
-xvdflt.o:       xvdflt.h
+xvdflt.o:	xvdflt.h
 
 xvdial.o:	bits/dial_cw1 bits/dial_ccw1 bits/dial_cw2 bits/dial_ccw2
 
 xvdir.o:	bits/d_load bits/d_save
 
-xvevent.o:	bits/dropper bits/dropperm bits/pen bits/penm 
+xvevent.o:	bits/dropper bits/dropperm bits/pen bits/penm
 xvevent.o:	bits/blur bits/blurm
 
 xvgam.o:	bits/h_rotl bits/h_rotr bits/h_flip bits/h_sinc bits/h_sdec
diff -ru xv-3.10a/bggen.c xv-3.10a-enhancements/bggen.c
--- xv-3.10a/bggen.c	1994-12-22 14:34:41.000000000 -0800
+++ xv-3.10a-enhancements/bggen.c	2005-04-17 14:04:22.000000000 -0700
@@ -18,6 +18,11 @@
 #include <stdio.h>
 #include <math.h>
 
+#ifdef __STDC__
+#  include <stdlib.h>	/* atoi() */
+#  include <ctype.h>	/* isdigit() */
+#endif
+
 #ifndef M_PI
 #  define M_PI       3.1415926535897932385
 #endif
@@ -29,7 +34,7 @@
 #define MAXCOLS  128
 
 /* some VMS thing... */
-#ifdef vax11c
+#if defined(vax11c) || (defined(__sony_news) && (defined(bsd43) || defined(__bsd43) || defined(SYSTYPE_BSD) || defined(__SYSTYPE_BSD)))
 #include <ctype.h>
 #endif
 
@@ -46,8 +51,8 @@
 
 typedef unsigned char byte;
 
-struct   color { int   r,g,b; 
-		 int   y; 
+struct   color { int   r,g,b;
+		 int   y;
 	       } colors[MAXCOLS], *cur, *nex;
 
 int      numcols;
@@ -62,7 +67,7 @@
 double computeDist PARM((int, int, int, int, int));
 void   writePPM    PARM((byte *, int, int, int));
 
-     
+
 /*************************************/
 int main(argc,argv)
      int    argc;
@@ -80,18 +85,18 @@
   char *geom    = NULL;
   char *rptgeom = NULL;
 
-  
+
 #ifdef VMS
   getredirection(&argc, &argv);
 #endif
-  
+
 
   for (i=1; i<argc; i++) {
     if (!strncmp(argv[i],"-d",(size_t) 2)) {         /* -d disp */
       i++;  if (i<argc) dname = argv[i];
     }
   }
-    
+
   if ((theDisp = XOpenDisplay(dname)) == NULL) {
     fprintf(stderr,"bggen:  Warning - can't open display, screen %s",
 	    "size unknown, color names not accepted.\n");
@@ -99,41 +104,41 @@
 
 
   cnt = 0;  numcols = 0;
-  
+
   /* parse cmd-line args */
   for (i=1; i<argc; i++) {
     if (!strcmp(argv[i],"-h")) {                          /* -h high */
       i++;  if (i<argc) high = atoi(argv[i]);
       hset++;
     }
-    
+
     else if (!strcmp(argv[i],"-w")) {                     /* -w wide */
       i++;  if (i<argc) wide = atoi(argv[i]);
       wset++;
     }
-    
+
     else if (!strcmp(argv[i],"-b")) {                     /* -b bits */
       i++;  if (i<argc) bits = atoi(argv[i]);
     }
-    
+
     else if (!strncmp(argv[i],"-g",(size_t) 2)) {         /* -g geom */
       i++;  if (i<argc) geom = argv[i];
     }
-    
+
     else if (!strncmp(argv[i],"-d",(size_t) 2)) {         /* -d disp */
       i++;  if (i<argc) dname = argv[i];
     }
-    
+
     else if (!strcmp(argv[i],"-G")) {                      /* -G rptgeom */
       i++;  if (i<argc) rptgeom = argv[i];
     }
-    
+
     else if (!strncmp(argv[i],"-a",(size_t) 2)) doascii++;  /* -a */
-    
+
     else if (!strcmp(argv[i],"-r")) {                     /* -r rot */
       i++;  if (i<argc) rot = atoi(argv[i]);
     }
-    
+
     else if (argv[i][0]=='-') usage();    /* any other '-' option is unknown */
 
     else if (isdigit(argv[i][0])) {
@@ -143,7 +148,7 @@
       case 2:  colors[numcols].b = atoi(argv[i]);  break;
       }
       cnt++;
-      
+
       if (cnt==3) {
 	if (numcols<MAXCOLS) numcols++;
 	cnt = 0;
@@ -176,50 +181,50 @@
       }
     }
   }
-  
-  
-  
+
+
+
   /* print error/usage message, if appropriate */
   if (cnt || numcols==0 || high<1 || wide<1 || bits<1 || bits>8) usage();
-  
-  
+
+
   if (geom) {
     int x,y;  unsigned int w,h;
     i = XParseGeometry(geom, &x, &y, &w, &h);
     if (i&WidthValue)  { wset++;  wide = (int) w; }
     if (i&HeightValue) { hset++;  high = (int) h; }
   }
-  
-  
+
+
   /* attempt to connect to X server and get screen dimensions */
   if (theDisp) {
     i = DefaultScreen(theDisp);
     if (!wset) wide = DisplayWidth(theDisp, i);
     if (!hset) high = DisplayHeight(theDisp, i);
   }
-  
-  
+
+
   /* normalize 'rot' */
   while (rot<   0) rot += 360;
   while (rot>=360) rot -= 360;
-  
-  
+
+
   rptwide = wide;  rpthigh = high;
   if (rptgeom) {
     int x,y;  unsigned int w,h;
     i = XParseGeometry(rptgeom, &x, &y, &w, &h);
     if (i&WidthValue)  rptwide = (int) w;
     if (i&HeightValue) rpthigh = (int) h;
-    
+
     RANGE(rptwide, 1, wide);
     RANGE(rpthigh, 1, high);
   }
-  
-  
 
-  
+
+
+
   rpic24 = (byte *) malloc(rptwide * rpthigh * 3 * sizeof(byte));
-  if (rptwide != wide || rpthigh != high) 
+  if (rptwide != wide || rpthigh != high)
     pic24  = (byte *) malloc(wide * high * 3 * sizeof(byte));
   else pic24 = rpic24;
 
@@ -229,7 +234,7 @@
     exit(1);
   }
   for (i=0, pp=pic24; i<wide*high*3; i++) *pp++ = 0;
-  
+
 
 
   /*** generate image ***/
@@ -244,34 +249,34 @@
       }
     }
   }
-  
-  
+
+
   else if (rot==0) {   /* un-rotated linear (vertical) gradient */
     for (i=0; i<numcols; i++)
       colors[i].y = ((rpthigh-1) * i) / (numcols-1);
-    
+
     cur = &colors[0];  nex = cur+1;
-    
+
     for (i=0; i<rpthigh; i++) {
       pp = rpic24 + (i * rptwide * 3);
 
       /* advance to next pair of colors if we're outside region */
       while (nex->y < i) { cur++; nex++; }
-      
+
       r = cur->r + ((nex->r - cur->r) * (i - cur->y)) / (nex->y - cur->y);
       g = cur->g + ((nex->g - cur->g) * (i - cur->y)) / (nex->y - cur->y);
       b = cur->b + ((nex->b - cur->b) * (i - cur->y)) / (nex->y - cur->y);
-      
+
       r = r & bmask[bits-1];
       g = g & bmask[bits-1];
       b = b & bmask[bits-1];
-      
+
       for (j=0; j<rptwide; j++) {
 	*pp++ = (byte) r;  *pp++ = (byte) g;  *pp++ = (byte) b;
       }
     }
   }
-  
+
   else dorot(rpic24, rptwide, rpthigh, rot);
 
 
@@ -293,7 +298,7 @@
 	y = ((i-ay) % rpthigh);
 
 	sp = rpic24 + (y * rptwide + x) * 3;
-	
+
 	pp[0] = *sp++;  pp[1] = *sp++;  pp[2] = *sp++;
       }
     }
@@ -355,12 +360,12 @@
     mind = computeDist(w-1,  0,    cx, cy, rot);
     maxd = computeDist(0,    h-1,  cx, cy, rot);
   }
-  
+
   del = maxd - mind;         /* maximum distance */
-  
+
   distdebug = 0;
-  
-  
+
+
   for (y=0; y<h; y++) {
     pp = pic + (y * w * 3);
     for (x=0; x<w; x++) {
@@ -368,11 +373,11 @@
       rat = (d - mind) / del;
       if (rat<0.0) rat = 0.0;
       if (rat>1.0) rat = 1.0;
-      
+
       cval = rat * nc1;
       bc   = floor(cval);
       crat = cval - bc;
-      
+
       if (bc < nc1) {
 	r = colors[bc].r + crat * (colors[bc+1].r - colors[bc].r);
 	g = colors[bc].g + crat * (colors[bc+1].g - colors[bc].g);
@@ -383,7 +388,7 @@
 	g = colors[nc1].g;
 	b = colors[nc1].b;
       }
-      
+
       *pp++ = (byte) r;  *pp++ = (byte) g;  *pp++ = (byte) b;
     }
   }
@@ -395,9 +400,9 @@
      int x,y,cx,cy,rot;
 {
   /* rot has to be in range 0-359 */
-  
-  double x1, y1, x2, y2, x3, y3, d, d1, b, theta;
-  
+
+  double x1, y1, x2, y2, x3, y3, d, d1, b;
+
   if (rot == 0)   return (double) (y - cy);
   if (rot == 180) return (double) (cy - y);
 
@@ -407,7 +412,7 @@
   /* x2,y2 = vertical projection onto a || line that runs through cx,cy */
   x2 = x1;
   y2 = cy - (cx-x2)*tant1;
-  
+
   d1 = y2 - y1;  /* vertical distance between lines */
   b  = d1 * cost1;
 
@@ -435,11 +440,11 @@
      int   w,h,doascii;
 {
   /* dumps a pic24 in PPM format to stdout */
-  
+
   int x,y;
-  
+
   printf("P%s %d %d 255\n", (doascii) ? "3" : "6", w, h);
-  
+
   for (y=0; y<h; y++) {
     if (doascii) {
       for (x=0; x<w; x++, pic+=3)
diff -ru xv-3.10a/bits/br_targa xv-3.10a-enhancements/bits/br_targa
--- xv-3.10a/bits/br_targa	1994-12-22 14:35:30.000000000 -0800
+++ xv-3.10a-enhancements/bits/br_targa	2007-04-15 10:40:46.000000000 -0700
@@ -1,6 +1,6 @@
-#define br_targa_width 48
-#define br_targa_height 48
-static unsigned char br_targa_bits[] = {
+#define br_tga_width 48
+#define br_tga_height 48
+static unsigned char br_tga_bits[] = {
    0xe0, 0xff, 0xff, 0xff, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00,
    0x20, 0x00, 0x00, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x09, 0x00,
    0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00,
diff -ru xv-3.10a/bits/icon xv-3.10a-enhancements/bits/icon
--- xv-3.10a/bits/icon	1994-12-22 14:35:28.000000000 -0800
+++ xv-3.10a-enhancements/bits/icon	2004-04-28 08:00:16.000000000 -0700
@@ -1,5 +1,6 @@
 #define icon_width 40
 #define icon_height 32
+#ifndef OMIT_ICON_BITS
 static unsigned char icon_bits[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
@@ -15,3 +16,4 @@
    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00};
+#endif
diff -ru xv-3.10a/cleandir xv-3.10a-enhancements/cleandir
--- xv-3.10a/cleandir	1994-12-22 14:34:50.000000000 -0800
+++ xv-3.10a-enhancements/cleandir	2004-05-10 23:19:16.000000000 -0700
@@ -1,9 +1,13 @@
-#!/bin/csh -f
+#!/bin/sh -f
 # cleandir: if called with an argument, cd's there and does a 'make clean'
 #
 
-if ( x$1 != x ) then
-  echo "cleaning $1 subdirectory"
-  cd $1
-  make clean
-endif
+if [ x"$1" != x ]; then
+  if [ -f "$1"/makefile -o -f "$1"/Makefile ]; then
+    echo "cleaning '$1' subdirectory"
+    cd "$1"
+    make clean
+# else
+#   echo "no makefile found; NOT cleaning '$1' subdirectory"
+  fi
+fi
diff -ru xv-3.10a/config.h xv-3.10a-enhancements/config.h
--- xv-3.10a/config.h	1995-01-05 10:49:21.000000000 -0800
+++ xv-3.10a-enhancements/config.h	2007-05-14 08:51:10.000000000 -0700
@@ -6,25 +6,42 @@
 /***************************************************************************
  * GZIP'd file support
  *
- * if you have the gnu uncompression utility 'gunzip', XV can use it to
- * automatically 'unzip' any gzip'd files.  To enable this feature,
- * change 'undef' to 'define' in the following line.  Needless to say, if 
- * your gunzip is installed elsewhere on your machine, change the 'GUNZIP'
- * definition appropriately. (use 'which gunzip' to find if you have gunzip, 
- * and where it lives)
+ * if you have the GNU uncompression utility 'gunzip' (or 'gzip' itself,
+ * which is just a link to gunzip), XV can use it to automatically 'unzip'
+ * any gzip'd files.  To enable this feature, change 'undef' to 'define' in
+ * the following line.  Needless to say, if your gunzip is installed elsewhere
+ * on your machine, change the 'GUNZIP' definition appropriately. (use
+ * 'which gunzip' to find if you have gunzip, and where it lives; ditto for
+ * gzip)
  */
-#undef USE_GUNZIP
+#define USE_GUNZIP
 
 #ifdef USE_GUNZIP
 #  ifdef VMS
 #    define GUNZIP "UNCOMPRESS"
 #  else
-#    define GUNZIP "/usr/local/bin/gunzip -q"
+#    define GUNZIP "gzip -dq"
 #  endif
 #endif
 
 
 /***************************************************************************
+ * BZIP2'd file support
+ *
+ * if you have the uncompression utility 'bunzip2' (or 'bzip2' itself, which
+ * is just a link to bunzip2), XV can use it to automatically 'unzip' any
+ * bzip2'd files.  To enable this feature, change 'undef' to 'define' in the
+ * following line (if not already done).  Use 'which bunzip2' or 'which bzip2'
+ * to find if you have bzip2/bunzip2, and where it lives.
+ */
+#define USE_BUNZIP2
+
+#ifdef USE_BUNZIP2
+#  define BUNZIP2 "bzip2 -d"  /* should this include the full path? */
+#endif
+
+
+/***************************************************************************
  * compress'd file support
  *
  * if you have GUNZIP defined above, just ignore this, as 'gunzip' can
@@ -37,9 +54,16 @@
  */
 #define UNCOMPRESS "/usr/ucb/uncompress"
 
-#if defined(hpux) || defined(SVR4) || defined(__386BSD__)
+#if defined(hpux) || defined(SVR4) || \
+    defined(__386BSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
+    defined(__linux__)
+    /*
+     I want to use BSD macro for checking if this OS is *BSD or not,
+     but the macro is defined in <sys/parm.h>, which I don't know all
+     machine has or not.
+     */
 #  undef  UNCOMPRESS
-#  define UNCOMPRESS "/usr/bin/uncompress"
+#  define UNCOMPRESS "uncompress"
 #endif
 
 #if defined(sgi)
@@ -70,18 +94,18 @@
  * PostScript file input support:
  *
  * if you have the 'ghostscript' package installed (version 2.6 or later),
- * XV can use it to read and display PostScript files.  To do so, 
+ * XV can use it to read and display PostScript files.  To do so,
  * uncomment the '#define GS_PATH' line, below.  You probably will not
  * need to modify the GS_LIB or GS_DEV lines, but if you do modify them,
  * be sure to uncomment them, as well.
  *
- * the ghostscript package can be acquired via anonymous ftp on 
+ * the ghostscript package can be acquired via anonymous ftp on
  * prep.ai.mit.edu, in the 'pub/gnu' directory
  *
- * GS_PATH specifies the complete path to your gs executable.  
+ * GS_PATH specifies the complete path to your gs executable.
  *
- * GS_LIB should be set if there's some other gs libs that should be 
- * searched, but aren't by default.  (In which case you should probably 
+ * GS_LIB should be set if there's some other gs libs that should be
+ * searched, but aren't by default.  (In which case you should probably
  * just fix your 'gs' so it looks in the right places without being told...)
  *
  * GS_DEV is the file format that ghostscript will convert PS into.  It
@@ -89,6 +113,7 @@
  */
 
 /* #define GS_PATH "/usr/local/bin/gs" */
+#define GS_PATH "gs"
 /* #define GS_LIB  "."                 */
 /* #define GS_DEV  "ppmraw"            */
 
@@ -97,10 +122,10 @@
  * 'old-style' XV logo image:
  *
  * XV now has a nifty, new logo image.  The downside is that it increases
- * the size of the 'xv' executable by 250K or so, and it's possible that 
- * your compiler may choke while compiling 'xvdflt.c'.  If you're compiler
+ * the size of the 'xv' executable by 250K or so, and it's possible that
+ * your compiler may choke while compiling 'xvdflt.c'.  If your compiler
  * can't handle it, or you're running Linux on a system with minimal memory,
- * change 'undef' to 'define' in the following line
+ * change 'undef' to 'define' in the following line:
  */
 
 #undef USEOLDPIC
@@ -108,8 +133,8 @@
 
 /***************************************************************************
  * Backing Store:
- * 
- * XV can request that 'Backing Store' may be turned on ('WhenMapped') for 
+ *
+ * XV can request that 'Backing Store' may be turned on ('WhenMapped') for
  * several of its windows, which may help performance over a slow network
  * connection.  However, it has been known to behave strangely (or crash)
  * on some X servers, so it's left here as an option.  If you run into trouble
@@ -119,3 +144,218 @@
 
 #define BACKING_STORE
 
+
+/***************************************************************************
+ * TIFF YCbCr-to-RGB conversion:
+ *
+ * Newer versions of libtiff can be compiled with libjpeg for JPEG-in-TIFF
+ * support, and according to Scott Marovich, "the IJG JPEG Library...sometimes
+ * seems to produce slightly more accurate results" (one known example:  the
+ * 'quad-jpeg.tif' test image).  In addition, libtiff can be compiled with
+ * "old JPEG" support, although its configure script will not enable that by
+ * default.  Change 'define' and 'undef' in the following lines as you wish,
+ * but note that defining LIBTIFF_HAS_OLDJPEG_SUPPORT when such is _not_ the
+ * case will result in crashes when encountering old-JPEG TIFFs:
+ */
+
+#define USE_LIBJPEG_FOR_TIFF_YCbCr_RGB_CONVERSION
+#undef LIBTIFF_HAS_OLDJPEG_SUPPORT
+
+
+/***************************************************************************
+ * PhotoCD/MAG/PIC/MAKI/Pi/PIC2/HIPS format Support:
+ *
+ * if, for whatever reason--say, security concerns--you don't want to
+ * include support for one or more of the PhotoCD, MAG/MAKI/Pi/PIC/PIC2
+ * (Japanese), or HIPS (astronomical) image formats, change the relevant
+ * 'define' to 'undef' in the following lines.  Conversely, if you *do*
+ * want them, change 'undef' to 'define' as appropriate.
+ */
+
+#define HAVE_PCD	/* believed to be reasonably safe */
+
+#undef HAVE_MAG		/* probable security issues */
+#undef HAVE_MAKI	/* probable security issues */
+#undef HAVE_PI		/* probable security issues */
+#undef HAVE_PIC		/* probable security issues */
+#undef HAVE_PIC2	/* probable security issues */
+
+#undef HAVE_HIPS	/* probable security issues */
+
+
+/***************************************************************************
+ * MacBinary file support:
+ *
+ * if you want XV to be able to handle ``MacBinary'' files (which have
+ * 128 byte info file header at the head), change 'undef' to 'define'
+ * in the following line.
+ */
+
+#undef MACBINARY
+
+
+/***************************************************************************
+ * Auto Expand support:
+ *
+ * if you want to extract archived file automatically and regard it as
+ * a directory, change 'undef' to 'define' in the AUTO_EXPAND line.
+ *
+ * Virtual Thumbdir support:
+ *
+ * if you want Virtual directory based Thumbdir(It means that XV
+ * doesn't forget builded Icons still be quited even if the directory
+ * is read-only), change 'undef' to 'define' the VIRTUAL_TD line.
+ */
+
+#undef AUTO_EXPAND
+#undef VIRTUAL_TD
+
+#if defined(VIRTUAL_TD) && !defined(AUTO_EXPAND)
+#  undef VIRTUAL_TD
+#endif
+
+
+/***************************************************************************
+ * Adjust the aspect ratio of Icons:
+ *
+ * if you want to adjust the aspect ratio of the icons in Visual
+ * Schnauzer, change 'undef' to 'define' in the following line.
+ */
+
+#undef VS_ADJUST
+
+
+/***************************************************************************
+ * Restore original colormap:
+ *
+ * if you want to restore original colormap when icons in Visual
+ * Shunauzer is double-clicked, change 'undef' to 'define' in the
+ * following line.
+ */
+
+#undef VS_RESCMAP
+
+
+/***************************************************************************
+ * TextViewer l10n support:
+ *
+ * if you want XV to show the text in Japanese on TextViewer, change
+ * 'undef' to 'define' in the following line.
+ */
+
+#undef TV_L10N
+
+#ifdef TV_L10N
+/*
+ * if you want to change the default code-set used in case that XV
+ * fails to select correct code-set, uncomment the '#define
+ * LOCALE_DEFAULT' line and change the 'LOCALE_DEFAULT' definition
+ * appropriately.
+ * (0:ASCII, 1:EUC-j, 2:JIS, 3:MS Kanji) */
+
+/* #  define LOCALE_DEFAULT 0 */
+
+/*
+ * Uncomment and edit the following lines, if your X Window System was
+ * not compiled with -DX_LOCALE and you failed to display the Japanese
+ * text in TextViewer.  You don't have to write locale name of JIS code-set
+ * and Microsoft code-set, if your system doesn't support those code-sets.
+ */
+
+/*
+#  define LOCALE_NAME_EUC     "ja_JP.EUC"
+#  define LOCALE_NAME_JIS     "ja_JP.JIS"
+#  define LOCALE_NAME_MSCODE  "ja_JP.SJIS"
+*/
+
+/*
+ * if your system doesn't have the Japanese fonts in the sizes,
+ * Uncomment and edit the following font size entries.
+ */
+
+/* #  define TV_FONTSIZE 14,16,24 */
+
+/*
+ * If you need, uncomment and modify the following font name.
+ */
+
+/* #  define TV_FONTSET "-*-fixed-medium-r-normal--%d-*" */
+#endif /* TV_L10N */
+
+
+/***************************************************************************
+ * User definable filter support:
+ *
+ * Use the filters as input and output method for load and save unsupported
+ * image format file. The filter command is recognized by definition of
+ * magic number or suffix in "~/.xv_mgcsfx" .
+ * To enable this feature, change 'undef' to 'define' in the following line.
+ */
+#undef HAVE_MGCSFX
+
+#ifdef HAVE_MGCSFX
+/*
+ * Support symbol 'auto' as <input image type> in startup file. This type
+ * cannot use pipe as input; it writes to a temporary file and recognizes
+ * the actual filetype by XV processing.
+ */
+#  define HAVE_MGCSFX_AUTO
+
+/*
+ * The startup file of definition for MgcSfx. 'MGCSFX_SITE_RC' is read
+ * first and '~/MGCSFX_RC' is second. So same definitions in both files
+ * are overridden by '~/MGCSFX_RC'
+ * To define startup file, see the sample of startup file 'xv_mgcsfx.sample'.
+ */
+#  define MGCSFX_SITE_RC  "xv_mgcsfx"
+#  define MGCSFX_RC       ".xv_mgcsfx"
+
+/*
+ * If you want startup file to pass preprocessor in reading time, then
+ * change 'undef' to 'define' in the following line.
+ *
+ * WARNING : If you decide to use preprocessor, you must not write
+ *           '# <comment>' style comment in startup file. Because,
+ *           preprocessor can't recognize.  */
+#  undef USE_MGCSFX_PREPROCESSOR
+
+#  ifdef USE_MGCSFX_PREPROCESSOR
+/*
+ * This is used like "system("MGCSFX_PREPROCESSOR MGCSFX_RC > tmp_name");",
+ * and read tmp_name instead of MGCSFX_RC.
+ */
+#    define MGCSFX_PREPROCESSOR "/usr/lib/cpp"
+/* #    define MGCSFX_PREPROCESSOR "cc -E" */
+
+#  endif /* USE_MGCSFX_PREPROCESSOR */
+
+/*
+ * Default string of command. If input command is required for undefined file,
+ * dialog is popuped with 'MGCSFX_DEFAULT_INPUT_COMMAND'. And, if output
+ * command is required in save dialog of MgcSfx, dialog is popuped with
+ * 'MGCSFX_DEFAULT_OUTPUT_COMMAND'.
+ *
+ * WARNING : Now, supported only 'PNM' image format, when command input is
+ *           required. You should define filter which use 'PNM' image format
+ *           as input or output.
+ */
+#  define MGCSFX_DEFAULT_INPUT_COMMAND  "tifftopnm"
+#  define MGCSFX_DEFAULT_OUTPUT_COMMAND "pnmtotiff"
+
+#endif /* HAVE_MGCSFX */
+
+
+/***************************************************************************
+ * Multi-Lingual TextViewer
+ *
+ * if you want XV to show the text in multi-lingual on TextViewer, change
+ * 'undef' to 'define' in the following line.
+ */
+
+#undef TV_MULTILINGUAL
+
+#define TV_DEFAULT_CODESET TV_EUC_JAPAN
+
+#ifdef TV_MULTILINGUAL
+#  undef TV_L10N
+#endif
diff -ru xv-3.10a/copyright.h xv-3.10a-enhancements/copyright.h
--- xv-3.10a/copyright.h	1994-12-22 14:34:56.000000000 -0800
+++ xv-3.10a-enhancements/copyright.h	2007-05-20 21:35:34.000000000 -0700
@@ -1,11 +1,11 @@
 /* Copyright Notice
  * ================
  * Copyright 1989, 1994 by John Bradley
- * 
- * Permission to copy and distribute XV in its entirety, for non-commercial 
- * purposes, is hereby granted without fee, provided that this license 
+ *
+ * Permission to copy and distribute XV in its entirety, for non-commercial
+ * purposes, is hereby granted without fee, provided that this license
  * information and copyright notice appear unmodified in all copies.
- * 
+ *
  * Note that distributing XV 'bundled' in with any product is considered
  * to be a 'commercial purpose'.
  *
@@ -13,16 +13,16 @@
  * and/or configured to be in their 'unregistered copy' mode, so that it
  * is made obvious to the user that XV is shareware, and that they should
  * consider donating, or at least reading this License Info.
- * 
+ *
  * The software may be modified for your own purposes, but modified
  * versions may not be distributed without prior consent of the author.
- * 
+ *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author be held liable for any damages
  * arising from the use of this software.
- * 
+ *
  * If you would like to do something with XV that this copyright
- * prohibits (such as distributing it with a commercial product, 
+ * prohibits (such as distributing it with a commercial product,
  * using portions of the source in some other program, etc.), please
  * contact the author (preferably via email).  Arrangements can
  * probably be worked out.
@@ -34,13 +34,13 @@
  * larger donations are quite welcome.  Folks who donate $25 or more
  * can receive a Real Nice bound copy of the XV manual for no extra
  * charge.
- * 
+ *
  * Commercial, government, and institutional users must register their
  * copies of XV, for the price of $25 per workstation/X terminal or per
  * XV user, whichever is less.  Note that it does NOT say 'simultaneous user',
- * but rather, the total number of people who use XV on any sort of 
- * recurring basis. Site licenses are available (and recommended) for those 
- * who wish to run XV on a large (>10) number of machines.  
+ * but rather, the total number of people who use XV on any sort of
+ * recurring basis. Site licenses are available (and recommended) for those
+ * who wish to run XV on a large (>10) number of machines.
  * Contact the author for more details.
  *
  * The author may be contacted via:
@@ -56,3 +56,51 @@
  * The author may not be contacted by (voice) phone.  Please don't try.
  *
  */
+
+/*
+ * Portions copyright 2000-2007 by Greg Roelofs and contributors:
+ *
+ *   Andrey A. Chernov [ache]
+ *     (http://cvsweb.freebsd.org/ports/graphics/xv/files/patch-ab)
+ *   Andreas Dilger (adilger clusterfs.com)
+ *   Alexander Lehmann (lehmann usa.net)
+ *   Alexey Spiridonov (http://www-math.mit.edu/~lesha/)
+ *   Anthony Thyssen (http://www.cit.gu.edu.au/~anthony/)
+ *   Bruno Rohee (http://bruno.rohee.com/)
+ *   David A. Clunie (http://www.dclunie.com/xv-pcd.html)
+ *   Erling A. Jacobsen (linuxcub email.dk)
+ *   Egmont Koblinger (egmont users.sourceforge.net)
+ *   Fabian Greffrath (fabian debian-unofficial.org)
+ *   Greg Roelofs (http://pobox.com/~newt/greg_contact.html)
+ *   Guido Vollbeding (http://sylvana.net/guido/)
+ *   IKEMOTO Masahiro (ikeyan airlab.cs.ritsumei.ac.jp)
+ *   John Cooper (john.cooper third-harmonic.com)
+ *   John C. Elliott (http://www.seasip.demon.co.uk/ZX/zxdload.html)
+ *   John D. Baker (http://mylinuxisp.com/~jdbaker/)
+ *   Jörgen Grahn (jgrahn algonet.se)
+ *   John H. Bradley, of course (http://www.trilon.com/xv/)
+ *   Jean-Pierre Demailly (http://www-fourier.ujf-grenoble.fr/~demailly/)
+ *   John Rochester (http://www.freebsd.org/cgi/query-pr.cgi?pr=2920)
+ *   (also http://cvsweb.freebsd.org/ports/graphics/xv/files/patch-af, -ag)
+ *   James Roberts Kirkpatrick (uwyo.edu)
+ *   Joe Zbiciak (http://spatula-city.org/~im14u2c/)
+ *   Kyoichiro Suda (http://www.coara.or.jp/~sudakyo/XV_jp.html)
+ *   Landon Curt "chongo" Noll (http://www.isthe.com/chongo/)
+ *   Larry Jones (lawrence.jones ugs.com)
+ *   Peter Jordan (http://www.ibiblio.org/pub/Linux/apps/graphics/viewers/X/)
+ *   Pawel S. Veselov (http://manticore.2y.net/wbmp.html)
+ *   Ross Combs (rocombs cs.nmsu.edu)
+ *   Robin Humble (http://www.cita.utoronto.ca/~rjh/)
+ *   Sean Borman (http://www.nd.edu/~sborman/software/xvwheelmouse.html)
+ *   TenThumbs (tenthumbs cybernex.net)
+ *   Scott B. Marovich (formerly marovich hpl.hp.com)
+ *   Tim Adye (http://hepwww.rl.ac.uk/Adye/xv-psnewstyle.html)
+ *   Tim Ramsey (tar pobox.com)
+ *   Tetsuya INOUE (tin329 chino.it.okayama-u.ac.jp)
+ *   Tavis Ormandy (taviso gentoo.org)
+ *   Werner Fink (http://www.suse.de/~werner/)
+ *
+ * Other credits are as listed on the XV Downloads page or in the respective
+ * patches (e.g., the jp-extension patches or within the PNG patch).
+ *
+ */
diff -ru xv-3.10a/docs/bggen.man xv-3.10a-enhancements/docs/bggen.man
--- xv-3.10a/docs/bggen.man	1994-12-22 14:35:22.000000000 -0800
+++ xv-3.10a-enhancements/docs/bggen.man	2007-04-22 17:32:11.000000000 -0700
@@ -1,4 +1,4 @@
-.TH bggen l
+.TH bggen 1
 .SH NAME
 bggen \- generates colored backgrounds on X11 displays
 .SH SYNTAX
diff -ru xv-3.10a/docs/xcmap.man xv-3.10a-enhancements/docs/xcmap.man
--- xv-3.10a/docs/xcmap.man	1994-12-22 14:35:23.000000000 -0800
+++ xv-3.10a-enhancements/docs/xcmap.man	2007-04-22 17:32:31.000000000 -0700
@@ -1,4 +1,4 @@
-.TH xcmap 1X
+.TH xcmap 1
 .SH NAME
 xcmap \- displays the default colormap on X11 displays
 .SH SYNTAX
diff -ru xv-3.10a/docs/xv.man xv-3.10a-enhancements/docs/xv.man
--- xv-3.10a/docs/xv.man	1994-12-22 14:35:22.000000000 -0800
+++ xv-3.10a-enhancements/docs/xv.man	2007-04-22 17:32:53.000000000 -0700
@@ -1,4 +1,4 @@
-.TH XV l "2 December 1994" "Rev. 3.10"
+.TH XV 1 "22 April 2007" "Rev. 3.10a-jumboFix+Enh"
 .SH NAME
 \fBxv\fP \- interactive image display for the X Window System
 .SH SYNTAX
@@ -8,14 +8,17 @@
 .SH DESCRIPTION
 The
 .I xv
-program displays images in the GIF, JPEG, TIFF,
-PBM, PGM, PPM, X11 bitmap, Utah Raster Toolkit RLE, PDS/VICAR, Sun Rasterfile, 
-BMP, PCX, IRIS RGB, XPM, Targa, XWD, possibly PostScript, and PM formats on 
-workstations and terminals running the X Window System, Version 11.
+program displays images on workstations and terminals running the X Window
+System, Version 11.  Supported image formats include
+PBM, PGM, PPM, X11 bitmap, XWD, XPM, Utah Raster Toolkit RLE, PDS/VICAR,
+FITS, Sun Rasterfile, GIF, PCX, Targa/TGA, BMP, WBMP, IRIS RGB, Spectrum
+SCREEN$, PM, and optionally PNG, JPEG, JPEG 2000, JP2, TIFF, PostScript,
+PDF, G3 fax, MAG, PIC, MAKI (640x400), PI, and PIC2.
 .LP
-The documentation for XV is now distributed
+Aside from the usage screen (available by typing 'xv -help' at the command
+line), documentation for XV is now distributed
 .I only
-as a PostScript file, as it has gotten enormous, 
+as a PostScript (or PDF) file, as it has gotten enormous
 and is no longer very well suited to the 'man' page format.
 Print a copy of the (100-ish page) manual found in
 .IR docs/xvdocs.ps .
@@ -26,9 +29,14 @@
 If you don't 
 .I have
 the PostScript file, it is part of the standard XV distribution, the
-latest version of which can be obtained via anonymous ftp from 
+latest version of which can be obtained from
+.IR http://www.trilon.com/xv/
+or via anonymous ftp from 
 .IR ftp.cis.upenn.edu
-in the directory pub/xv
+in the directory pub/xv .
+.PP
+This version has been patched with the XV Jumbo Patches, available from
+.IR http://pobox.com/~newt/greg_xv.html .
 .PP
 .SH AUTHOR
-John Bradley
+John Bradley (and many contributors)
diff -ru xv-3.10a/docs/xvp2p.man xv-3.10a-enhancements/docs/xvp2p.man
--- xv-3.10a/docs/xvp2p.man	1994-12-22 14:35:25.000000000 -0800
+++ xv-3.10a-enhancements/docs/xvp2p.man	2007-04-22 17:33:23.000000000 -0700
@@ -1,4 +1,4 @@
-.TH xvpictoppm 1X
+.TH xvpictoppm 1
 .SH NAME
 xvpictoppm \- converts XV 'thumbnail' files to standard PPM format
 .SH SYNTAX
diff -ru xv-3.10a/tiff/Makefile xv-3.10a-enhancements/tiff/Makefile
--- xv-3.10a/tiff/Makefile	1994-12-22 14:35:12.000000000 -0800
+++ xv-3.10a-enhancements/tiff/Makefile	2005-04-17 14:45:28.000000000 -0700
@@ -30,13 +30,15 @@
 # OF THIS SOFTWARE.
 #
 
-AR=     ar
-RANLIB=	./RANLIB.csh
+AR=	ar
+CHMOD=	chmod
+#RANLIB=	./RANLIB.csh
+RANLIB=	./RANLIB.sh
 
 IPATH= -I.
 
 COPTS=	-O
-CFLAGS=	${COPTS} ${IPATH}
+CFLAGS=	${COPTS} ${IPATH} -D_BSD_SOURCE
 
 INCS=	tiff.h tiffio.h
 
@@ -60,6 +62,7 @@
 
 ${ALL}:	${OBJS}
 	${AR} rc libtiff.a $?
+	${CHMOD} +x ${RANLIB}
 	${RANLIB} libtiff.a
 
 ${OBJS}:	tiffio.h tiff.h tiffcomp.h tiffiop.h tiffconf.h
diff -ru xv-3.10a/tiff/Makefile.std xv-3.10a-enhancements/tiff/Makefile.std
--- xv-3.10a/tiff/Makefile.std	1994-12-22 14:35:16.000000000 -0800
+++ xv-3.10a-enhancements/tiff/Makefile.std	2004-05-16 18:50:39.000000000 -0700
@@ -30,8 +30,10 @@
 # OF THIS SOFTWARE.
 #
 
-AR=     /bin/ar
-RANLIB=	./RANLIB.csh
+AR=	/bin/ar
+CHMOD=	chmod
+#RANLIB=	./RANLIB.csh
+RANLIB=	./RANLIB.sh
 
 IPATH= -I.
 
@@ -60,6 +62,7 @@
 
 ${ALL}:	${OBJS}
 	${AR} rc libtiff.a $?
+	${CHMOD} +x ${RANLIB}
 	${RANLIB} libtiff.a
 
 ${OBJS}:	tiffio.h tiff.h tiffcomp.h tiffiop.h tiffconf.h
diff -ru xv-3.10a/vdcomp.c xv-3.10a-enhancements/vdcomp.c
--- xv-3.10a/vdcomp.c	1994-12-22 14:34:47.000000000 -0800
+++ xv-3.10a-enhancements/vdcomp.c	2007-04-15 21:09:55.000000000 -0700
@@ -5,8 +5,8 @@
 /*  Decompresses images using Kris Becker's subroutine DECOMP.C     */
 /*  which is included in this program in a shortened version.       */
 /*                                                                  */
-/*  Reads a variable length compressed PDS image and outputs a      */
-/*  fixed length uncompressed image file in PDS format with         */
+/*  Reads a variable-length compressed PDS image and outputs a      */
+/*  fixed-length uncompressed image file in PDS format with         */
 /*  labels, image histogram, engineering table, line header table   */
 /*  and an image with PDS, FITS, VICAR or no labels.  If used on    */
 /*  a non-byte-swapped machine the image histogram is un-swapped.   */
@@ -96,40 +96,54 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-/* include a malloc.h, of some sort... */
-#ifndef VMS   /* VMS hates multi-line '#if's */
-# if !defined(ibm032)                    && \
-     !defined(__convex__)                && \
-     !(defined(vax) && !defined(ultrix)) && \
-     !defined(mips)                      && \
-     !defined(apollo)                    && \
-     !defined(pyr)                       && \
-     !defined(__UMAXV__)                 && \
-     !defined(bsd43)                     && \
-     !defined(aux)                       && \
-     !defined(__bsdi__)                  && \
-     !defined(sequent)
-
-#  if defined(hp300) || defined(hp800) || defined(NeXT)
-#   include <sys/malloc.h>                /* it's in 'sys' on HPs and NeXT */
-#  else
-#   include <malloc.h>
-#  endif
-# endif
+/* include a malloc.h of some sort (if needed...most systems use stdlib.h) */
+#ifndef VMS   /* VMS hates multi-line "#if"s */
+   /*
+    * I want to use BSD macro for checking if this OS is *BSD or not,
+    * but the macro is defined in <sys/parm.h>, which I don't know all
+    * machine has or not.
+    */
+#  if !defined(ibm032)                    && \
+      !defined(__convex__)                && \
+      !(defined(vax) && !defined(ultrix)) && \
+      !defined(mips)                      && \
+      !defined(apollo)                    && \
+      !defined(pyr)                       && \
+      !defined(sequent)                   && \
+      !defined(__UMAXV__)                 && \
+      !defined(aux)                       && \
+      !defined(bsd43)                     && \
+      !defined(__bsd43)                   && \
+      !defined(__bsdi__)                  && \
+      !defined(__386BSD__)                && \
+      !defined(__FreeBSD__)               && \
+      !defined(__OpenBSD__)               && \
+      !defined(__NetBSD__)                && \
+      !defined(__DARWIN__)
+
+#    if defined(hp300) || defined(hp800) || defined(NeXT)
+#      include <sys/malloc.h>    /* it's in "sys" on HPs and NeXT */
+#    else
+#      include <malloc.h>        /* FIXME: should explicitly list systems that NEED this, not everyone that doesn't */
+#    endif
+
+#  endif /* !most modern systems */
 #endif /* !VMS */
 
 
 #include <X11/Xos.h>
 
-#define TRUE                  1
-#define FALSE                 0
+#define TRUE         1
+#define FALSE        0
+
+#define NAMELEN      1024           /* inname and outname sizes     */
 
-                                    /* pc i/o defines               */
-#define O_BINARY         0x8000     /* file mode is binary          */
+                                    /* PC I/O defines               */
+#define O_BINARY     0x8000         /* file mode is binary          */
 
-                                    /* vax i/o defines              */
-#define RECORD_TYPE      "rfm=fix"  /* VAX fixed length output      */
-#define CTX              "ctx=bin"  /* no translation of \n         */
+                                    /* VAX/VMS I/O defines          */
+#define RECORD_TYPE  "rfm=fix"      /* VAX/VMS fixed-length output  */
+#define CTX          "ctx=bin"      /* no translation of \n         */
 #define FOP          "fop=cif,sup"  /* file processing ops          */
 
 typedef struct leaf { struct leaf *right;
@@ -142,9 +156,9 @@
  once the tree is created by the accompanying routine huff_tree.
 **************************************************************************/
 
-  NODE *tree;
+static NODE *tree;
 
-/* subroutine definitions                                           */
+/* subroutine definitions */
 
 #undef PARM
 #ifdef __STDC__
@@ -172,11 +186,11 @@
 void free_tree    PARM((int *));
 int  free_node    PARM((NODE *, int));
 
-/* global variables                                                 */
+/* global variables */
 
 int                infile;
 FILE               *outfile;
-char               inname[1024],outname[1024];
+char               inname[NAMELEN], outname[NAMELEN];
 int                output_format;
 int                record_bytes, max_lines;
 int                line_samples, fits_pad;
@@ -185,8 +199,8 @@
 
 /*************************************************/
 int main(argc,argv)
-     int  argc;
-     char **argv;
+  int  argc;
+  char **argv;
 {
   unsigned char ibuf[2048],obuf[2048];
   unsigned char blank=32;
@@ -200,12 +214,12 @@
   /*                                                                   */
   /*********************************************************************/
 
-  strcpy(inname,"   ");  
+  strcpy(inname,"   ");
   strcpy(outname,"   ");
   output_format = 0;
 
   if (argc == 1);                     /* prompt user for parameters */
-  else if (argc == 2 && (strncmp(argv[1],"help",(size_t) 4) == 0 || 
+  else if (argc == 2 && (strncmp(argv[1],"help",(size_t) 4) == 0 ||
 			 strncmp(argv[1],"HELP",(size_t) 4) == 0 ||
 			 strncmp(argv[1],"?",   (size_t) 1) == 0)) {
     fprintf(stderr,
@@ -214,18 +228,22 @@
     fprintf(stderr,"   infile        - name of compressed image file. \n");
     fprintf(stderr,"   outfile       - name of uncompressed output file.\n");
     fprintf(stderr,"   output format - selected from the following list:\n");
-    fprintf(stderr,"\n");   
-    fprintf(stderr,"     1  SFDU/PDS format [DEFAULT].\n");   
-    fprintf(stderr,"     2  FITS format.              \n");   
-    fprintf(stderr,"     3  VICAR format.             \n");   
-    fprintf(stderr,"     4  Unlabelled binary array.  \n\n");   
+    fprintf(stderr,"\n");
+    fprintf(stderr,"     1  SFDU/PDS format [DEFAULT].\n");
+    fprintf(stderr,"     2  FITS format.              \n");
+    fprintf(stderr,"     3  VICAR format.             \n");
+    fprintf(stderr,"     4  Unlabelled binary array.  \n\n");
     exit(1);
-  }  
+  }
   else {
-    strcpy(inname,argv[1]);  
-    if (argc >= 3) strcpy(outname,argv[2]); 
+    strncpy(inname, argv[1], sizeof(inname)-1);
+    inname[sizeof(inname)-1] = '\0';
+    if (argc >= 3) {
+      strncpy(outname, argv[2], sizeof(outname)-1);
+      outname[sizeof(outname)-1] = '\0';
+    }
     if (argc == 3) output_format = 1;
-    if (argc == 4) sscanf(argv[3],"%d",&output_format); 
+    if (argc == 4) sscanf(argv[3],"%d",&output_format);
   }
 
   host = check_host();
@@ -244,13 +262,13 @@
     case 4: no_labels(host);     break;
   }
 
-  if (record_bytes == 836) {  /* set up values for image sizes */ 
+  if (record_bytes == 836) {  /* set up values for image sizes */
     max_lines    =  800;
     fits_pad     = 2240;
     line_samples =  800;
   }
   else {
-    max_lines    = 1056;         
+    max_lines    = 1056;
     fits_pad     = 1536;
     line_samples = 1204;
   }
@@ -394,12 +412,12 @@
     if (record_bytes == 1204) /* do checksum for viking */
       for (i=0; i<record_bytes; i++) checksum += (int)obuf[i];
 
-    if ((line % 100 == 0) && (outfile != stdout)) 
+    if ((line % 100 == 0) && (outfile != stdout))
       fprintf(stderr,"\nline %d",line);
 
   } while (length > 0 && line < max_lines);
 
-  if (record_bytes == 1204  && (outfile  != stdout)) 
+  if (record_bytes == 1204  && (outfile  != stdout))
     /* print checksum for viking */
     fprintf(stderr,"\n Image label checksum = %d computed checksum = %d\n",
 	    label_checksum,checksum);
@@ -425,33 +443,36 @@
 /*********************************************************************/
 
 int get_files(host)
-int host;
+  int host;
 {
-  short   shortint;
   typedef long    off_t;
+  short   shortint;
+  char    *s;
 
   if (inname[0] == ' ') {
     printf("\nEnter name of file to be decompressed: ");
-    gets (inname);
+    fgets(inname, sizeof(inname), stdin);
+    if ((s = strchr(inname, '\n')) != NULL)
+      *s = '\0';
   }
 
-  if (host == 1 | host == 2) {
-    if ((infile = open(inname,O_RDONLY | O_BINARY)) <= 0) {
-      fprintf(stderr,"\ncan't open input file: %s\n",inname);
+  if (host == 1 || host == 2) {
+    if ((infile = open(inname, O_RDONLY | O_BINARY)) <= 0) {
+      fprintf(stderr,"\ncan't open input file: %s\n", inname);
       exit(1);
     }
   }
-  else if (host == 3 | host == 5) {
-    if ((infile = open(inname,O_RDONLY)) <= 0) {
-      fprintf(stderr,"\ncan't open input file: %s\n",inname);
+  else if (host == 3 || host == 5) {
+    if ((infile = open(inname, O_RDONLY)) <= 0) {
+      fprintf(stderr,"\ncan't open input file: %s\n", inname);
       exit(1);
     }
 
     /****************************************************************/
-    /* If we are on a vax see if the file is in var length format.  */
-    /* This logic is in here in case the vax file has been stored   */
+    /* If we are on a VAX see if the file is in var length format.  */
+    /* This logic is in here in case the VAX file has been stored   */
     /* in fixed or undefined format.  This might be necessary since */
-    /* vax variable length files can't be moved to other computer   */
+    /* VAX variable-length files can't be moved to other computer   */
     /* systems with standard comm programs (kermit, for example).   */
     /****************************************************************/
 
@@ -459,9 +480,9 @@
        read(infile,&shortint, (size_t) 2);
        if (shortint > 0 && shortint < 80) {
 	 host = 4;              /* change host to 4                */
-	 printf("This is not a VAX variable length file.");
+	 printf("This is not a VAX variable-length file.");
        }
-       else printf("This is a VAX variable length file.");
+       else printf("This is a VAX variable-length file.");
        lseek(infile,(off_t) 0,0);     /* reposition to beginning of file */
      }
   }
@@ -474,13 +495,17 @@
       printf("\n  3.  VICAR format.");
       printf("\n  4.  Unlabelled binary array.\n");
       printf("\n  Enter format number:");
-      gets(inname);
+      fgets(inname, sizeof(inname), stdin);
+      if ((s = strchr(inname, '\n')) != NULL)
+        *s = '\0';
       output_format = atoi(inname);
     } while (output_format < 1 || output_format > 4);
 
   if (outname[0] == ' ') {
     printf("\nEnter name of uncompressed output file: ");
-    gets (outname);
+    fgets(outname, sizeof(outname), stdin);
+    if ((s = strchr(outname, '\n')) != NULL)
+      *s = '\0';
   }
 
   return(host);
@@ -495,68 +520,68 @@
 /*********************************************************************/
 
 void open_files(host)
-int *host;
+  int *host;
 {
   if (*host == 1 || *host == 2 || *host == 5)  {
     if (outname[0] == '-') outfile=stdout;
-    else if ((outfile = fopen(outname,"wb"))==NULL) {
-      fprintf(stderr,"\ncan't open output file: %s\n",outname);
+    else if ((outfile = fopen(outname, "wb"))==NULL) {
+      fprintf(stderr,"\ncan't open output file: %s\n", outname);
       exit(1);
     }
   }
 
   else if (*host == 3 || *host == 4) {
     if (output_format == 1) {     /* write PDS format blocks */
-      if (record_bytes == 836) { 
-	if ((outfile=fopen(outname,"w"
+      if (record_bytes == 836) {
+	if ((outfile=fopen(outname, "w"
 #ifdef VMS
 			   ,"mrs=836",FOP,CTX,RECORD_TYPE
 #endif
 			   ))==NULL) {
-	  fprintf(stderr,"\ncan't open output file: %s\n",outname);
+	  fprintf(stderr,"\ncan't open output file: %s\n", outname);
 	  exit(1);
 	}
       }
       else {
-	if ((outfile=fopen(outname,"w"
+	if ((outfile=fopen(outname, "w"
 #ifdef VMS
 			   ,"mrs=1204",FOP,CTX,RECORD_TYPE
 #endif
 			   ))==NULL) {
-	  fprintf(stderr,"\ncan't open output file: %s\n",outname);
+	  fprintf(stderr,"\ncan't open output file: %s\n", outname);
 	  exit(1);
 	}
       }
     }
     else if (output_format == 2) {  /* write FITS format blocks */
-      if ((outfile=fopen(outname,"w"
+      if ((outfile=fopen(outname, "w"
 #ifdef VMS
 			 ,"mrs=2880",FOP,CTX,RECORD_TYPE
 #endif
 			 ))==NULL) {
-	fprintf(stderr,"\ncan't open output file: %s\n",outname);
+	fprintf(stderr,"\ncan't open output file: %s\n", outname);
 	exit(1);
       }
     }
 
-    else {                       /* write fixed length records */
-      if (record_bytes == 836) { 
-	if ((outfile=fopen(outname,"w"
+    else {                       /* write fixed-length records */
+      if (record_bytes == 836) {
+	if ((outfile=fopen(outname, "w"
 #ifdef VMS
 			   ,"mrs=800",FOP,CTX,RECORD_TYPE
 #endif
 			   ))==NULL) {
-	  fprintf(stderr,"\ncan't open output file: %s\n",outname);
+	  fprintf(stderr,"\ncan't open output file: %s\n", outname);
 	  exit(1);
 	}
       }
       else {
-	if ((outfile=fopen(outname,"w"
+	if ((outfile=fopen(outname, "w"
 #ifdef VMS
 			   ,"mrs=1204",FOP,CTX,RECORD_TYPE
 #endif
 			   ))==NULL) {
-	  fprintf(stderr,"\ncan't open output file: %s\n",outname);
+	  fprintf(stderr,"\ncan't open output file: %s\n", outname);
 	  exit(1);
 	}
       }
@@ -572,11 +597,11 @@
 /*********************************************************************/
 
 void pds_labels(host)
-     int host;
+  int host;
 {
-  char          outstring[80],ibuf[2048];
+  char          ibuf[2048];
   unsigned char cr=13,lf=10,blank=32;
-  short         length,nlen,total_bytes,line,i;
+  short         length,total_bytes,i;
 
 
   total_bytes = 0;
@@ -613,11 +638,11 @@
 	       (size_t) 53,(size_t) 1,outfile);
       else
         fwrite("CCSD3ZF0000100000001NJPL3IF0PDS200000001 = SFDU_LABEL",
-	       (size_t) 53,(size_t) 1,outfile);      
+	       (size_t) 53,(size_t) 1,outfile);
 
       fprintf(outfile,"%c%c",cr,lf);
       fwrite("/*          FILE FORMAT AND LENGTH */",(size_t) 37,(size_t) 1,
-	     outfile);      
+	     outfile);
       fprintf(outfile,"%c%c",cr,lf);
       fwrite("RECORD_TYPE                      = FIXED_LENGTH",(size_t) 47,
 	     (size_t) 1,outfile);
@@ -710,7 +735,7 @@
       }
       else {
 	strcpy(ibuf+35,"60");
-	length = length - 2; 
+	length = length - 2;
       }
 
       fwrite(ibuf,(size_t) length,(size_t) 1,outfile);
@@ -730,7 +755,7 @@
     }
 
     else if ((i = strncmp(ibuf," ENCODING",(size_t) 9)) == 0);
-    
+
     /*****************************************************************/
     /* delete the encoding type label in the image object            */
     /*****************************************************************/
@@ -787,10 +812,10 @@
 /*********************************************************************/
 
 void fits_labels(host)
-int host;
+  int host;
 {
   char          ibuf[2048],outstring[80];
-  short         length,nlen,total_bytes,line,i;
+  short         length,total_bytes,i;
   unsigned char cr=13,lf=10,blank=32;
 
   do {
@@ -799,7 +824,7 @@
     /*****************************************************************/
     /* find the checksum and store in label_checksum                 */
     /*****************************************************************/
-    if ((i = strncmp(ibuf," CHECKSUM",(size_t) 9)) == 0) { 
+    if ((i = strncmp(ibuf," CHECKSUM",(size_t) 9)) == 0) {
       ibuf[length]   = '\0';
       label_checksum = atol(ibuf+35);
     }
@@ -842,7 +867,7 @@
 
   if (record_bytes == 836)
     strcpy(outstring,"NAXIS1  =                  800");
-  else 
+  else
     strcpy(outstring,"NAXIS1  =                 1204");
 
   strcat(outstring,"                                               ");
@@ -862,7 +887,7 @@
 
   strcpy(outstring,"END                             ");
   strcat(outstring,"                                               ");
-  
+
   fwrite(outstring,(size_t) 78,(size_t) 1,outfile);
   fprintf(outfile,"%c%c",cr,lf);
   total_bytes = total_bytes + 80;
@@ -871,6 +896,7 @@
   for (i=total_bytes; i<2880; i++) fputc(blank,outfile);
 }
 
+
 /*********************************************************************/
 /*                                                                   */
 /* subroutine vicar_labels - write vicar labels to output file       */
@@ -878,11 +904,10 @@
 /*********************************************************************/
 
 void vicar_labels(host)
-int host;
-
+  int host;
 {
   char          ibuf[2048],outstring[80];
-  short         length,nlen,total_bytes,line,i;
+  short         length,total_bytes,i;
   unsigned char cr=13,lf=10,blank=32;
 
   do {
@@ -890,7 +915,7 @@
     /*****************************************************************/
     /* find the checksum and store in label_checksum                 */
     /*****************************************************************/
-    if ((i = strncmp(ibuf," CHECKSUM",(size_t) 9)) == 0) { 
+    if ((i = strncmp(ibuf," CHECKSUM",(size_t) 9)) == 0) {
       ibuf[length]   = '\0';
       label_checksum = atol(ibuf+35);
     }
@@ -950,10 +975,10 @@
 /*********************************************************************/
 
 void no_labels(host)
-int host;
+  int host;
 {
-  char          ibuf[2048],outstring[80];
-  short         length,nlen,total_bytes,line,i;
+  char          ibuf[2048];
+  short         length,i;
 
   do {
     length = read_var(ibuf,host);
@@ -961,7 +986,7 @@
     /*****************************************************************/
     /* find the checksum and store in label_checksum                 */
     /*****************************************************************/
-    if ((i = strncmp(ibuf," CHECKSUM",(size_t) 9)) == 0) { 
+    if ((i = strncmp(ibuf," CHECKSUM",(size_t) 9)) == 0) {
       ibuf[length]   = '\0';
       label_checksum = atol(ibuf+35);
     }
@@ -984,15 +1009,16 @@
   open_files(&host);
 }
 
+
 /*********************************************************************/
 /*                                                                   */
-/* subroutine read_var - read variable length records from input file*/
+/* subroutine read_var - read variable-length records from input file*/
 /*                                                                   */
 /*********************************************************************/
 
 int read_var(ibuf,host)
-char  *ibuf;
-int   host;
+  char  *ibuf;
+  int   host;
 {
   int   length,result,nlen;
   char  temp;
@@ -1027,19 +1053,19 @@
     return (length);
 
   case 3: /*******************************************************/
-          /* VAX host with variable length support               */
+          /* VAX host with variable-length support               */
           /*******************************************************/
     length = read(infile,ibuf,(size_t) 2048/* upper bound */);
     return (length);
 
   case 4: /*******************************************************/
-          /* VAX host, but not a variable length file            */
+          /* VAX host, but not a variable-length file            */
           /*******************************************************/
     length = 0;
     result = read(infile,&length,(size_t) 2);
     nlen =   read(infile,ibuf,(size_t) length+(length%2));
 
-    /* check to see if we crossed a vax record boundary          */
+    /* check to see if we crossed a VAX record boundary          */
     while (nlen < length)
       nlen += read(infile,ibuf+nlen,(size_t) length+(length%2)-nlen);
     return (length);
@@ -1061,6 +1087,7 @@
   return 0;
 }
 
+
 /*********************************************************************/
 /*                                                                   */
 /* subroutine check_host - find out what kind of machine we are on   */
@@ -1115,23 +1142,23 @@
 	   "Host 5 - 32 bit integers without swapping, no var len support.");
   }
 
-  if ((*outname)!='-') fprintf(stderr,"%s\n",hostname);
+  if ((*outname) != '-') fprintf(stderr, "%s\n", hostname);
   return(host);
 }
 
 
-int swap_int(inval)  /* swap 4 byte integer                       */
-     int inval;
+int swap_int(inval)  /* swap 4 byte integer */
+  int inval;
 {
-  union /* this union is used to swap 16 and 32 bit integers          */
+  union /* this union is used to swap 16 and 32 bit integers */
     {
       char  ichar[4];
       short slen;
       int   llen;
     } onion;
   char   temp;
-  
-  /* byte swap the input field                                      */
+
+  /* byte swap the input field */
   onion.llen   = inval;
   temp   = onion.ichar[0];
   onion.ichar[0]=onion.ichar[3];
@@ -1146,17 +1173,13 @@
 /****************************************************************************
 *_TITLE decompress - decompresses image lines stored in compressed format   *
 *_ARGS  TYPE       NAME      I/O        DESCRIPTION                         */
-        char *ibuf;        /* I         Compressed data buffer              */
-        char *obuf;        /* O         Decompressed image line             */
-        int       *nin;   /* I         Number of bytes on input buffer     */
-        int       *nout;  /* I         Number of bytes in output buffer    */
-
+        char       *ibuf;  /* I         Compressed data buffer              */
+        char       *obuf;  /* O         Decompressed image line             */
+        int        *nin;   /* I         Number of bytes on input buffer     */
+        int        *nout;  /* I         Number of bytes in output buffer    */
 {
-  /* The external root pointer to tree */
-  extern NODE *tree;
-
   dcmprs(ibuf,obuf,nin,nout,tree);
-  
+
   return;
 }
 
@@ -1165,10 +1188,8 @@
 /***************************************************************************
 *_TITLE decmpinit - initializes the Huffman tree                           *
 *_ARGS  TYPE       NAME      I/O        DESCRIPTION                        */
-        int      *hist;  /* I         First-difference histogram.        */
-
+        int        *hist;  /* I         First-difference histogram.        */
 {
-  extern NODE *tree;          /* Huffman tree root pointer */
   tree = huff_tree(hist);
   return;
 }
@@ -1178,8 +1199,7 @@
 /****************************************************************************
 *_TITLE huff_tree - constructs the Huffman tree; returns pointer to root    *
 *_ARGS  TYPE          NAME        I/O   DESCRIPTION                         */
-        int     *hist;     /* I    First difference histogram          */
-
+        int          *hist;     /* I    First difference histogram          */
 {
   /*  Local variables used */
   int freq_list[512];      /* Histogram frequency list */
@@ -1189,7 +1209,6 @@
   NODE **np;        /* Node list pointer */
 
   int num_freq;   /* Number non-zero frequencies in histogram */
-  int sum;                 /* Sum of all frequencies */
 
   short int num_nodes; /* Counter for DN initialization */
   short int cnt;       /* Miscellaneous counter */
@@ -1228,7 +1247,7 @@
 
     j = 0;
     for (i=4 ; --i >= 0 ; j = (j << 8) | *(cp+i));
-    
+
     /* Now make the assignment */
     *fp++ = j;
     temp = new_node(num_nodes);
@@ -1341,7 +1360,7 @@
       l--;
       if ( j <= freq_list) break;
     }
-    
+
   }
   return;
 }
@@ -1362,9 +1381,9 @@
   NODE *ptr = root;        /* pointer to position in tree */
   unsigned char test;      /* test byte for bit set */
   unsigned char idn;       /* input compressed byte */
-  
+
   char odn;                /* last dn value decompressed */
-  
+
   char *ilim = ibuf + *nin;         /* end of compressed bytes */
   char *olim = obuf + *nout;        /* end of output buffer */
 
@@ -1406,10 +1425,9 @@
 /****************************************************************************
 *_TITLE free_tree - free memory of all allocated nodes                      *
 *_ARGS  TYPE       NAME       I/O        DESCRIPTION                        */
-        int      *nfreed;  /* O        Return of total count of nodes     *
+        int        *nfreed;  /* O        Return of total count of nodes     *
 *                                        freed.                             */
-
-/*
+/*                                                                          *
 *_DESCR This routine is supplied to the programmer to free up all the       *
 *       allocated memory required to build the huffman tree.  The count     *
 *       of the nodes freed is returned in the parameter 'nfreed'.  The      *
@@ -1417,16 +1435,13 @@
 *       than one file per run, the program will not keep allocating new     *
 *       memory without first deallocating all previous nodes associated     *
 *       with the previous file decompression.                               *
-
+*                                                                           *
 *_HIST  16-AUG-89 Kris Becker   USGS, Flagstaff Original Version            *
 *_END                                                                       *
 ****************************************************************************/
-
 {
   int total_free = 0;
 
-  extern NODE *tree;      /* Huffman tree root pointer */
-
   *nfreed = free_node(tree,total_free);
 
   return;
@@ -1435,36 +1450,33 @@
 
 int free_node(pnode,total_free)
 /***************************************************************************
-*_TITLE free_node - deallocates an allocated NODE pointer
+*_TITLE free_node - deallocates an allocated NODE pointer                  *
 *_ARGS  TYPE     NAME          I/O   DESCRIPTION                           */
         NODE     *pnode;       /* I  Pointer to node to free               */
-        int       total_free;   /* I  Total number of freed nodes           */
-
-/*
+        int      total_free;   /* I  Total number of freed nodes           */
+/*                                                                         *
 *_DESCR  free_node will check both right and left pointers of a node       *
 *        and then free the current node using the free() C utility.        *
 *        Note that all nodes attached to the node via right or left        *
 *        pointers area also freed, so be sure that this is the desired     *
 *        result when calling this routine.                                 *
-
+*                                                                          *
 *        This routine is supplied to allow successive calls to the         *
 *        decmpinit routine.  It will free up the memory allocated          *
 *        by previous calls to the decmpinit routine.  The call to free     *
-*        a previous huffman tree is:  total = free_node(tree,(int) 0);    *
+*        a previous huffman tree is:  total = free_node(tree,(int) 0);     *
 *        This call must be done by the programmer application routine      *
 *        and is not done by any of these routines.                         *
 *_HIST   16-AUG-89  Kris Becker U.S.G.S  Flagstaff Original Version        */
 {
   if (pnode == (NODE *) NULL) return(total_free);
-  
+
   if (pnode->right != (NODE *) NULL)
     total_free = free_node(pnode->right,total_free);
   if (pnode->left != (NODE *) NULL)
     total_free = free_node(pnode->left,total_free);
-  
+
   free((char *) pnode);
   return(total_free + 1);
 }
 
-
-
diff -ru xv-3.10a/xcmap.c xv-3.10a-enhancements/xcmap.c
--- xv-3.10a/xcmap.c	1995-01-03 13:14:52.000000000 -0800
+++ xv-3.10a-enhancements/xcmap.c	2007-04-15 13:12:41.000000000 -0700
@@ -9,6 +9,9 @@
 
 /* include files */
 #include <stdio.h>
+#ifdef __STDC__
+#  include <stdlib.h>   /* exit(), abs() */
+#endif
 #include <sys/types.h>
 #include <ctype.h>
 
@@ -18,7 +21,7 @@
 #include <X11/cursorfont.h>
 
 #ifdef VMS
-#define index strchr
+#  define index strchr
 #endif
 
 typedef unsigned char byte;
@@ -58,7 +61,7 @@
        int  main             PARM((int, char **));
 static void HandleEvent      PARM((XEvent *));
 static void Syntax           PARM((void));
-static void FatalError       PARM((char *));
+static void FatalError       PARM((const char *));
 static void Quit             PARM((void));
 static void CreateMainWindow PARM((char *, char *, int, char **));
 static void DrawWindow       PARM((int,int,int,int));
@@ -75,50 +78,50 @@
   int        i;
   char      *display, *geom;
   XEvent     event;
-  
+
   cmd = argv[0];
   display = geom = NULL;
-  
-  
+
+
   /*********************Options*********************/
-  
+
   for (i = 1; i < argc; i++) {
     char *strind;
-    
+
     if (!strncmp(argv[i],"-g", (size_t)2)) {	/* geometry */
       i++;
       geom = argv[i];
       continue;
     }
-    
+
     if (argv[i][0] == '=') {		/* old-style geometry */
       geom = argv[i];
       continue;
     }
-    
+
     if (!strncmp(argv[i],"-d",(size_t) 2)) {	/* display */
       i++;
       display = argv[i];
       continue;
     }
-    
+
     strind = (char *) index(argv[i], ':');	/* old-style display */
     if(strind != NULL) {
       display = argv[i];
       continue;
     }
-    
+
     Syntax();
   }
-  
-  
+
+
   /*****************************************************/
-  
+
   /* Open up the display. */
-  
+
   if ( (theDisp=XOpenDisplay(display)) == NULL)
     FatalError("can't open display");
-  
+
   theScreen = DefaultScreen(theDisp);
   theCmap   = DefaultColormap(theDisp, theScreen);
   rootW     = RootWindow(theDisp,theScreen);
@@ -126,9 +129,9 @@
   fcol      = WhitePixel(theDisp,theScreen);
   bcol      = BlackPixel(theDisp,theScreen);
   theVisual = DefaultVisual(theDisp,theScreen);
-  
+
   dispcells = DisplayCells(theDisp, theScreen);
-  
+
   if (dispcells>256) {
     sprintf(tmpstr,"dispcells = %d.  %s",
 	    dispcells, "This program can only deal with <= 8-bit displays.");
@@ -140,27 +143,32 @@
     nxcells = nycells = 8;
   else if (dispcells>4)
     nxcells = nycells = 4;
-  else
+  else if (dispcells>2)
     nxcells = nycells = 2;
-  
+  else
+  {
+    nxcells = 2;
+    nycells = 1;
+  }
+
   /**************** Create/Open X Resources ***************/
   if ((mfinfo = XLoadQueryFont(theDisp,FONT))==NULL) {
     sprintf(tmpstr,"couldn't open '%s' font",FONT);
     FatalError(tmpstr);
   }
-  
+
   mfont=mfinfo->fid;
   XSetFont(theDisp,theGC,mfont);
   XSetForeground(theDisp,theGC,fcol);
   XSetBackground(theDisp,theGC,bcol);
-  
+
   CreateMainWindow(cmd,geom,argc,argv);
-  Resize(WIDE,HIGH);
-  
-  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
+  Resize((int)WIDE,(int)HIGH);
+
+  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask
 	       | StructureNotifyMask | ButtonPressMask);
   XMapWindow(theDisp,mainW);
-  
+
   /**************** Main loop *****************/
   while (1) {
     XNextEvent(theDisp, &event);
@@ -177,41 +185,41 @@
   switch (event->type) {
   case Expose: {
     XExposeEvent *exp_event = (XExposeEvent *) event;
-    
-    if (exp_event->window==mainW) 
+
+    if (exp_event->window==mainW)
       DrawWindow(exp_event->x,exp_event->y,
 		 exp_event->width, exp_event->height);
   }
     break;
-    
+
   case ButtonPress: {
     XButtonEvent *but_event = (XButtonEvent *) event;
-    
-    if (but_event->window == mainW && but_event->button == Button1) 
+
+    if (but_event->window == mainW && but_event->button == Button1)
       TrackMouse(but_event->x, but_event->y);
   }
     break;
-    
+
   case KeyPress: {
     XKeyEvent *key_event = (XKeyEvent *) event;
     KeySym ks;
     XComposeStatus status;
-    
+
     XLookupString(key_event,tmpstr,128,&ks,&status);
     if (tmpstr[0]=='q' || tmpstr[0]=='Q') Quit();
   }
     break;
-    
+
   case ConfigureNotify: {
     XConfigureEvent *conf_event = (XConfigureEvent *) event;
-    
-    if (conf_event->window == mainW && 
-	(conf_event->width != WIDE || conf_event->height != HIGH))
-      Resize(conf_event->width, conf_event->height);
+    int w = conf_event->width, h = conf_event->height;
+
+    if (conf_event->window == mainW && (w != WIDE || h != HIGH))
+      Resize((int)(w ? w : WIDE), (int)(h ? h : HIGH));
   }
     break;
-    
-    
+
+
   case CirculateNotify:
   case MapNotify:
   case DestroyNotify:
@@ -220,7 +228,7 @@
   case UnmapNotify:
   case MappingNotify:
   case ClientMessage:         break;
-    
+
   default:		/* ignore unexpected events */
     break;
   }  /* end of switch */
@@ -237,10 +245,10 @@
 
 
 /***********************************/
-static void FatalError (identifier)
-     char *identifier;
+static void FatalError(identifier)
+     const char *identifier;
 {
-  fprintf(stderr, "%s: %s\n",cmd, identifier);
+  fprintf(stderr, "%s: %s\n", cmd, identifier);
   exit(-1);
 }
 
@@ -262,24 +270,33 @@
   XSizeHints hints;
   int i,x,y;
   unsigned int w,h;
-  
+
   WIDE = HIGH = 256;			/* default window size */
-  
+
   x=y=w=h=1;
+  hints.flags = 0;
+
   i=XParseGeometry(geom,&x,&y,&w,&h);
-  if (i&WidthValue)  WIDE = (int) w;
-  if (i&HeightValue) HIGH = (int) h;
-  
-  if (i&XValue || i&YValue) hints.flags = USPosition;  
-  else hints.flags = PPosition;
-  
-  hints.flags |= USSize;
-  
-  if (i&XValue && i&XNegative) 
-    x = XDisplayWidth(theDisp,theScreen)-WIDE-abs(x);
-  if (i&YValue && i&YNegative) 
-    y = XDisplayHeight(theDisp,theScreen)-HIGH-abs(y);
-  
+  if (i&WidthValue)
+  {
+    WIDE = (int) w;
+    hints.flags |= USSize;
+  }
+  if (i&HeightValue)
+  {
+    HIGH = (int) h;
+    hints.flags |= USSize;
+  }
+
+  if (i&XValue || i&YValue)
+  {
+    if (i&XNegative)
+      x = XDisplayWidth(theDisp,theScreen)-WIDE-abs(x);
+    if (i&YNegative)
+      y = XDisplayHeight(theDisp,theScreen)-HIGH-abs(y);
+    hints.flags |= USPosition;
+  }
+
   hints.x=x;             hints.y=y;
   hints.width  = WIDE;   hints.height = HIGH;
   hints.max_width  = DisplayWidth(theDisp,theScreen);
@@ -288,22 +305,22 @@
   hints.min_height = 16;
   hints.width_inc = hints.height_inc = 16;
   hints.flags |= PMaxSize | PMinSize | PResizeInc;
-  
+
   xswa.background_pixel = bcol;
   xswa.border_pixel     = fcol;
   xswa.cursor = XCreateFontCursor (theDisp, XC_top_left_arrow);
   xswamask = CWBackPixel | CWBorderPixel | CWCursor;
-  
+
   mainW = XCreateWindow(theDisp,rootW,x,y,(unsigned int) WIDE,
-			(unsigned int) HIGH, 2, 0, 
+			(unsigned int) HIGH, 2, 0,
 			(unsigned int) CopyFromParent,
 			CopyFromParent, xswamask, &xswa);
-  
+
   XSetStandardProperties(theDisp,mainW,"xcmap","xcmap",None,
 			 argv,argc,&hints);
-  
+
   if (!mainW) FatalError("Can't open main window");
-  
+
 }
 
 
@@ -312,11 +329,11 @@
      int x,y,w,h;
 {
   int i,j,x1,y1,x2,y2;
-  
+
   x1 = x / cWIDE;      y1 = y / cHIGH;	/* (x1,y1) (x2,y2): bounding */
   x2 = ((x+w) + cWIDE - 1) / cWIDE;		/*       rect in cell coords */
   y2 = ((y+h) + cHIGH - 1) / cHIGH;
-  
+
   for (i=y1; i<y2; i++) {
     for (j=x1; j<x2; j++) {
       XSetForeground(theDisp,theGC,(unsigned long) (i*nycells+j) );
@@ -343,18 +360,18 @@
 {
   /* called when there's a button press in the window.  draws the pixel
      value, and loops until button is released */
-  
+
   Window        rootW,childW;
   int           rx,ry,x,y;
   unsigned int  mask;
-  
+
   pvalup = 0;
   DrawPixValue(mx,my);
-  
+
   while (1) {
     if (XQueryPointer(theDisp,mainW,&rootW,&childW,&rx,&ry,&x,&y,&mask)) {
       if (!(mask & Button1Mask)) break;    /* button released */
-      
+
       DrawPixValue(x,y);
     }
   }
@@ -367,10 +384,10 @@
 {
   static unsigned long pix, lastpix;
   static int           pvaly;
-  
+
   if (x<0) x=0;  if (x>=WIDE) x=WIDE-1;
   if (y<0) y=0;  if (y>=HIGH) y=HIGH-1;
-  
+
   if (!pvalup) {	/* it's not up.  make it so */
     if (y >= HIGH/2) pvaly = 0;  else pvaly = HIGH - 12;
     pvalup = 1;
@@ -378,30 +395,30 @@
     XClearArea(theDisp,mainW,0,pvaly,
 	       (unsigned int) WIDE, (unsigned int) 13,True);
   }
-  
+
   x /= cWIDE;  y /= cHIGH;
-  
+
   pix = y * nxcells + x;
-  
+
   if (pix != lastpix) {
     XColor def;
     char  *sp;
-    
+
     XSetForeground(theDisp,theGC,fcol);
     lastpix = def.pixel = pix;
     if (pix<dispcells) {
       XQueryColor(theDisp, theCmap, &def);
       sprintf(tmpstr, "Pix %3ld = ($%04x, $%04x, $%04x)",
 	      pix, def.red, def.green, def.blue);
-      
-      /* make the hex uppercase */        
-      for (sp=tmpstr+4; *sp; sp++) 
+
+      /* make the hex uppercase */
+      for (sp=tmpstr+4; *sp; sp++)
 	if (islower(*sp)) *sp = toupper(*sp);
     }
     else {
       sprintf(tmpstr, "Pix %3ld is out of legal range. ", pix);
     }
-    
+
     XDrawImageString(theDisp,mainW,theGC,5,pvaly+10,tmpstr,
 		     (int) strlen(tmpstr));
   }
diff -ru xv-3.10a/xv.c xv-3.10a-enhancements/xv.c
--- xv-3.10a/xv.c	1995-01-19 10:08:43.000000000 -0800
+++ xv-3.10a-enhancements/xv.c	2007-05-13 18:44:55.000000000 -0700
@@ -33,9 +33,9 @@
 
 /* a mono-spaced font needed for the 'pixel value tracking' feature */
 #define MFONT1 "-misc-fixed-medium-r-normal-*-13-*"
-#define MFONT2 "6x13"   
+#define MFONT2 "6x13"
 #define MFONT3 "-*-courier-medium-r-*-*-12-*"
-#define MFONT4 "fixed"   
+#define MFONT4 "fixed"
 
 
 /* default positions for various windows */
@@ -54,14 +54,35 @@
 static int    randomShow = 0;   /* do a 'random' slideshow */
 static int    startIconic = 0;  /* '-iconic' option */
 static int    defaultVis  = 0;  /* true if using DefaultVisual */
+#ifdef HAVE_G3
+static int    fax = 0;          /* temporary(?) kludge */
+int           highresfax = 0;
+#endif
 static double hexpand = 1.0;    /* '-expand' argument */
 static double vexpand = 1.0;    /* '-expand' argument */
-static char  *maingeom = NULL;
-static char  *icongeom = NULL;
+static const char *maingeom = NULL;
+static const char *icongeom = NULL;
 static Atom   __SWM_VROOT = None;
 
 static char   basefname[128];   /* just the current fname, no path */
 
+#ifdef TV_L10N
+#  ifndef TV_FONTSET
+#    define TV_FONTSET "-*-fixed-medium-r-normal--%d-*"
+#  endif
+#  ifndef TV_FONTSIZE
+#    define TV_FONTSIZE 14,16
+#  endif
+static int    mfontsize[] = { TV_FONTSIZE, 0 };
+static char   mfontset[256];
+#endif
+
+#ifdef HAVE_JP2K
+static byte jp2k_magic[12] =
+  { 0, 0, 0, 0x0c, 'j', 'P', ' ', ' ', 0x0d, 0x0a, 0x87, 0x0a };
+#endif
+
+
 /* things to do upon successfully loading an image */
 static int    autoraw    = 0;   /* force raw if using stdcmap */
 static int    autodither = 0;   /* dither */
@@ -78,6 +99,12 @@
 
 static int    force8     = 0;   /* force 8-bit mode */
 static int    force24    = 0;   /* force 24-bit mode */
+#ifdef HAVE_PCD
+static int    PcdSize    = -1;  /* force dialog to ask */
+#endif
+
+static float  waitsec_nonfinal = -1;  /* "normal" waitsec value */
+static float  waitsec_final = -1;     /* final-image waitsec value */
 
 /* used in DeleteCmd() and Quit() */
 static char  **mainargv;
@@ -92,7 +119,7 @@
 static void parseResources           PARM((int, char **));
 static void parseCmdLine             PARM((int, char **));
 static void verifyArgs               PARM((void));
-static void printoption              PARM((char *));
+static void printoption              PARM((const char *));
 static void cmdSyntax                PARM((void));
 static void rmodeSyntax              PARM((void));
 static int  openPic                  PARM((int));
@@ -103,32 +130,34 @@
 static void openNextLoop             PARM((void));
 static void openPrevPic              PARM((void));
 static void openNamedPic             PARM((void));
-static int  findRandomPic            PARM((void));
 static void mainLoop                 PARM((void));
-static void createMainWindow         PARM((char *, char *));
-static void setWinIconNames          PARM((char *));
+static void createMainWindow         PARM((const char *, const char *));
+static void setWinIconNames          PARM((const char *));
 static void makeDispNames            PARM((void));
 static void fixDispNames             PARM((void));
 static void deleteFromList           PARM((int));
-static int  argcmp                   PARM((char *, char *, int, int, int *));
+static int  argcmp                   PARM((const char *, const char *,
+                                           int, int, int *));
 static void add_filelist_to_namelist PARM((char *, char **, int *, int));
 
 
 /* formerly local vars in main, made local to this module when
    parseResources() and parseCmdLine() were split out of main() */
-   
-int   imap, ctrlmap, gmap, browmap, cmtmap, clrroot, nopos, limit2x;
-char *display, *whitestr, *blackstr, *histr, *lostr,
-     *infogeom, *fgstr, *bgstr, *ctrlgeom, *gamgeom, *browgeom, *tmpstr;
-char *rootfgstr, *rootbgstr, *visualstr, *textgeom, *cmtgeom;
-char *monofontname, *flistName;
-int  curstype, stdinflag, browseMode, savenorm, preview, pscomp, preset, 
-     rmodeset, gamset, cgamset, perfect, owncmap, rwcolor, stdcmap;
-int  nodecor;
-double gamval, rgamval, ggamval, bgamval;
-
-
 
+static int   imap, ctrlmap, gmap, browmap, cmtmap, clrroot, nopos, limit2x;
+static const char *histr, *lostr, *fgstr, *bgstr, *tmpstr;
+static const char *infogeom, *ctrlgeom, *gamgeom, *browgeom, *textgeom, *cmtgeom;
+static char *display, *whitestr, *blackstr;
+static char *rootfgstr, *rootbgstr, *imagebgstr, *visualstr;
+static char *monofontname, *flistName;
+#ifdef TV_L10N
+static char **misscharset, *defstr;
+static int nmisscharset;
+#endif
+static int  curstype, stdinflag, browseMode, savenorm, preview, pscomp, preset,
+            rmodeset, gamset, cgamset, perfect, owncmap, rwcolor, stdcmap;
+static int  nodecor;
+static double gamval, rgamval, ggamval, bgamval;
 
 /*******************************************/
 int main(argc, argv)
@@ -137,6 +166,9 @@
 /*******************************************/
 {
   int    i;
+#ifdef TV_L10N
+  int    j;
+#endif
   XColor ecdef;
   Window rootReturn, parentReturn, *children;
   unsigned int numChildren, rootDEEP;
@@ -153,6 +185,13 @@
   /*** variable Initialization                       ***/
   /*****************************************************/
 
+#ifdef TV_L10N
+  /* setlocale(LC_ALL, localeList[LOCALE_EUCJ]); */
+  setlocale(LC_ALL, "");
+  xlocale = (int)XSupportsLocale();	/* assume that (Bool) is (int) */
+	/* if X doesn't support ja_JP.ujis text viewer l10n doesn't work. */
+#endif
+
   xv_getwd(initdir, sizeof(initdir));
   searchdir[0] = '\0';
   fullfname[0] = '\0';
@@ -162,7 +201,7 @@
 
   /* init internal variables */
   display = NULL;
-  fgstr = bgstr = rootfgstr = rootbgstr = NULL;
+  fgstr = bgstr = rootfgstr = rootbgstr = imagebgstr = NULL;
   histr = lostr = whitestr = blackstr = NULL;
   visualstr = monofontname = flistName = NULL;
   winTitle = NULL;
@@ -172,21 +211,26 @@
 
   picComments = (char *) NULL;
 
+  if (picExifInfo) free(picExifInfo);
+  picExifInfo = (byte *) NULL;
+  picExifInfoSize = 0;
+
   numPages = 1;  curPage = 0;
   pageBaseName[0] = '\0';
 
   LocalCmap = browCmap = 0;
   stdinflag = 0;
-  autoclose = autoDelete = 0; 
+  autoclose = autoDelete = 0;
   cmapInGam = 0;
   grabDelay = 0;
+  startGrab = 0;
   showzoomcursor = 0;
   perfect = owncmap = stdcmap = rwcolor = 0;
 
   ignoreConfigs = 0;
-  browPerfect = 1;  
+  browPerfect = 1;
   gamval = rgamval = ggamval = bgamval = 1.0;
-  
+
   picType = -1;              /* gets set once file is loaded */
   colorMapMode = CM_NORMAL;
   haveStdCmap  = STD_NONE;
@@ -221,24 +265,27 @@
   cmd = (char *) rindex(argv[0],'/');
   if (!cmd) cmd = argv[0]; else cmd++;
 
-  tmpstr = (char *) getenv("TMPDIR");
-  if (!tmpstr) tmpdir = "/tmp";
-  else {
-    tmpdir = (char *) malloc(strlen(tmpstr) + 1);
-    if (!tmpdir) FatalError("can't malloc 'tmpdir'\n");
-    strcpy(tmpdir, tmpstr);
-  }
+  tmpstr = (const char *) getenv("TMPDIR");
+  if (!tmpstr) tmpstr = "/tmp";
+  tmpdir = (char *) malloc(strlen(tmpstr) + 1);
+  if (!tmpdir) FatalError("can't malloc 'tmpdir'\n");
+  strcpy(tmpdir, tmpstr);
+
+#ifdef AUTO_EXPAND
+  Vdinit();
+  vd_handler_setup();
+#endif
 
   /* init command-line options flags */
-  infogeom = DEFINFOGEOM;  ctrlgeom = DEFCTRLGEOM;  
+  infogeom = DEFINFOGEOM;  ctrlgeom = DEFCTRLGEOM;
   gamgeom  = DEFGAMGEOM;   browgeom = DEFBROWGEOM;
   textgeom = DEFTEXTGEOM;  cmtgeom  = DEFCMTGEOM;
 
-  ncols = -1;  mono = 0;  
+  ncols = -1;  mono = 0;
   ninstall = 0;  fixedaspect = 0;  noFreeCols = nodecor = 0;
   DEBUG = 0;  bwidth = 2;
   nolimits = useroot = clrroot = noqcheck = 0;
-  waitsec = -1;  waitloop = 0;  automax = 0;
+  waitsec = waitsec_final = -1.0;  waitloop = 0;  automax = 0;
   rootMode = 0;  hsvmode = 0;
   rmodeset = gamset = cgamset = 0;
   nopos = limit2x = 0;
@@ -251,6 +298,10 @@
   preset = 0;
   viewonly = 0;
 
+#ifdef ENABLE_FIXPIX_SMOOTH
+  do_fixpix_smooth = 0;
+#endif
+
   /* init 'xormasks' array */
   xorMasks[0] = 0x01010101;
   xorMasks[1] = 0x02020203;
@@ -268,15 +319,38 @@
   defaspect = normaspect = 1.0;
   mainW = dirW = infoW = ctrlW = gamW = psW = (Window) NULL;
   anyBrowUp = 0;
+  incrementalSearchTimeout = 30;
 
 #ifdef HAVE_JPEG
   jpegW = (Window) NULL;  jpegUp = 0;
 #endif
 
+#ifdef HAVE_JP2K
+  jp2kW = (Window) NULL;  jp2kUp = 0; 
+#endif
+
 #ifdef HAVE_TIFF
   tiffW = (Window) NULL;  tiffUp = 0;
 #endif
 
+#ifdef HAVE_PNG
+  pngW = (Window) NULL;  pngUp = 0;
+#endif
+
+  pcdW = (Window) NULL;  pcdUp = 0;
+
+#ifdef HAVE_PIC2
+  pic2W = (Window) NULL;  pic2Up = 0;
+#endif
+
+#ifdef HAVE_PCD
+  pcdW = (Window) NULL;  pcdUp = 0;
+#endif
+
+#ifdef HAVE_MGCSFX
+  mgcsfxW = (Window) NULL;  mgcsfxUp = 0;
+#endif
+
   imap = ctrlmap = gmap = browmap = cmtmap = 0;
 
   ch_offx = ch_offy = p_offx = p_offy = 0;
@@ -303,13 +377,35 @@
   verifyArgs();
 
 
+#if 0
+#ifdef XVEXECPATH
+  /* set up path to search for external executables */
+  {
+    char *systempath = getenv("PATH");
+    char *xvexecpath = getenv("XVPATH");
+    if (xvexecpath == NULL) xvexecpath = XVEXECPATH;
+    /* FIXME: can systempath == NULL? */
+    strcat(systempath, ":");		/* FIXME: writing to mem we don't own */
+    strcat(systempath, xvexecpath);	/* FIXME: writing to mem we don't own */
+    /* FIXME:  was there supposed to be a setenv() call in here? */
+    if (DEBUG)
+      fprintf(stderr, "DEBUG: executable search path: %s\n", systempath);
+  }
+#endif
+#endif
+
+
   /*****************************************************/
   /*** X Setup                                       ***/
   /*****************************************************/
-  
+
   theScreen = DefaultScreen(theDisp);
   theCmap   = DefaultColormap(theDisp, theScreen);
-  rootW     = RootWindow(theDisp,theScreen);
+  if (spec_window) {
+	rootW = spec_window;
+  } else {
+	rootW = RootWindow(theDisp,theScreen);
+  }
   theGC     = DefaultGC(theDisp,theScreen);
   theVisual = DefaultVisual(theDisp,theScreen);
   ncells    = DisplayCells(theDisp, theScreen);
@@ -320,53 +416,67 @@
 
   rootDEEP = dispDEEP;
 
-  /* things dependant on theVisual:
-   *    dispDEEP, theScreen, rootW, ncells, theCmap, theGC, 
+  /* things dependent on theVisual:
+   *    dispDEEP, theScreen, rootW, ncells, theCmap, theGC,
    *    vrWIDE, dispWIDE, vrHIGH, dispHIGH, maxWIDE, maxHIGH
    */
 
 
-
   /* if we *haven't* had a non-default visual specified,
-     see if we have a TrueColor or DirectColor visual of 24 or 32 bits, 
+     see if we have a TrueColor or DirectColor visual of 24 or 32 bits,
      and if so, use that as the default visual (prefer TrueColor) */
 
   if (!visualstr && !useroot) {
+    VisualID     defvid;
     XVisualInfo *vinfo, rvinfo;
     int          best,  numvis;
     long         flags;
 
-    best = -1;
+    best          = -1;
     rvinfo.class  = TrueColor;
     rvinfo.screen = theScreen;
-    flags = VisualClassMask | VisualScreenMask;
-    
+    flags         = VisualClassMask | VisualScreenMask;
+    defvid        = XVisualIDFromVisual(DefaultVisual(theDisp,
+						      DefaultScreen(theDisp)));
+
     vinfo = XGetVisualInfo(theDisp, flags, &rvinfo, &numvis);
-    if (vinfo) {     /* look for a TrueColor, 24-bit or more (pref 24) */
-      for (i=0, best = -1; i<numvis; i++) {
+    if (vinfo) {
+      /* Check list, use 'default', first 24-bit, or first >24-bit */
+      for (i=0; i<numvis && best==-1; i++) {   /* default? */
+	if ((vinfo[i].visualid == defvid) && (vinfo[i].depth >= 24)) best=i;
+      }
+      for (i=0; i<numvis && best==-1; i++) {   /* 24-bit ? */
 	if (vinfo[i].depth == 24) best = i;
-	else if (vinfo[i].depth>24 && best<0) best = i;
+      }
+      for (i=0; i<numvis && best==-1; i++) {   /* >24-bit ? */
+	if (vinfo[i].depth >= 24) best = i;
       }
     }
 
     if (best == -1) {   /* look for a DirectColor, 24-bit or more (pref 24) */
       rvinfo.class = DirectColor;
       if (vinfo) XFree((char *) vinfo);
+
       vinfo = XGetVisualInfo(theDisp, flags, &rvinfo, &numvis);
       if (vinfo) {
-	for (i=0, best = -1; i<numvis; i++) {
+	for (i=0; i<numvis && best==-1; i++) {   /* default? */
+	  if ((vinfo[i].visualid == defvid) && (vinfo[i].depth >= 24)) best=i;
+	}
+	for (i=0; i<numvis && best==-1; i++) {   /* 24-bit ? */
 	  if (vinfo[i].depth == 24) best = i;
-	  else if (vinfo[i].depth>24 && best<0) best = i;
+	}
+	for (i=0; i<numvis && best==-1; i++) {   /* >24-bit ? */
+	  if (vinfo[i].depth >= 24) best = i;
 	}
       }
     }
-    
+
     if (best>=0 && best<numvis) useOtherVisual(vinfo, best);
     if (vinfo) XFree((char *) vinfo);
   }
 
 
-			   
+
   if (visualstr && useroot) {
     fprintf(stderr, "%s: %sUsing default visual.\n",
 	    cmd, "Warning:  Can't use specified visual on root.  ");
@@ -401,11 +511,11 @@
       long vinfomask;
       int numvis, best;
 
-      if (vclass >= 0) { 
+      if (vclass >= 0) {
 	rvinfo.class = vclass;   vinfomask = VisualClassMask;
       }
       else { rvinfo.visualid = vid;  vinfomask = VisualIDMask; }
-      
+
       rvinfo.screen = theScreen;
       vinfomask |= VisualScreenMask;
 
@@ -429,9 +539,9 @@
   /* make linear colormap for DirectColor visual */
   if (theVisual->class == DirectColor) makeDirectCmap();
 
-  defaultVis = (XVisualIDFromVisual(theVisual) == 
+  defaultVis = (XVisualIDFromVisual(theVisual) ==
        XVisualIDFromVisual(DefaultVisual(theDisp, DefaultScreen(theDisp))));
-    
+
 
   /* turn GraphicsExposures OFF in the default GC */
   {
@@ -441,9 +551,6 @@
   }
 
 
-  if (!useroot && limit2x) { maxWIDE *= 2;  maxHIGH *= 2; }
-  if (nolimits) { maxWIDE = 65000; maxHIGH = 65000; }
-
   XSetErrorHandler(xvErrorHandler);
 
   /* always search for virtual root window */
@@ -456,14 +563,14 @@
     Atom actual_type;
     int actual_format;
     unsigned long nitems, bytesafter;
-    Window *newRoot = NULL;
+    byte *newRoot = NULL;   /* byte instead of Window avoids type-pun warning */
     XWindowAttributes xwa;
     if (XGetWindowProperty (theDisp, children[i], __SWM_VROOT, 0L, 1L,
 	  False, XA_WINDOW, &actual_type, &actual_format, &nitems,
 	  &bytesafter, (unsigned char **) &newRoot) == Success && newRoot) {
-      vrootW = *newRoot;
+      vrootW = *(Window *)newRoot;
       XGetWindowAttributes(theDisp, vrootW, &xwa);
-      vrWIDE = xwa.width;  vrHIGH = xwa.height;
+      maxWIDE = vrWIDE = xwa.width;  maxHIGH = vrHIGH = xwa.height;
       dispDEEP = xwa.depth;
       break;
     }
@@ -472,7 +579,8 @@
   vrootW = pseudo_root(theDisp, theScreen);
 #endif
 
-
+  if (!useroot && limit2x) { maxWIDE *= 2;  maxHIGH *= 2; }
+  if (nolimits) { maxWIDE = 65000; maxHIGH = 65000; }
 
 
   if (clrroot || useroot) {
@@ -486,13 +594,14 @@
   arrow     = XCreateFontCursor(theDisp,(u_int) curstype);
   cross     = XCreateFontCursor(theDisp,XC_crosshair);
   tcross    = XCreateFontCursor(theDisp,XC_tcross);
+  tlcorner  = XCreateFontCursor(theDisp,XC_top_left_corner);
   zoom      = XCreateFontCursor(theDisp,XC_sizing);
 
   {
     XColor fc, bc;
     fc.red = fc.green = fc.blue = 0xffff;
     bc.red = bc.green = bc.blue = 0x0000;
-    
+
     XRecolorCursor(theDisp, zoom, &fc, &bc);
   }
 
@@ -541,7 +650,7 @@
 
 
   /* set up fg,bg colors */
-  fg = black;   bg = white;  
+  fg = black;   bg = white;
   if (fgstr && XParseColor(theDisp, theCmap, fgstr, &ecdef) &&
       xvAllocColor(theDisp, theCmap, &ecdef)) {
     fg = ecdef.pixel;
@@ -561,6 +670,18 @@
       xvAllocColor(theDisp, theCmap, &ecdef))  rootbg = ecdef.pixel;
 
 
+  /* GRR 19980308:  set up image bg color (for transparent images) */
+  have_imagebg = 0;
+  if (imagebgstr && XParseColor(theDisp, theCmap, imagebgstr, &ecdef) &&
+      xvAllocColor(theDisp, theCmap, &ecdef)) {
+    /* imagebg = ecdef.pixel; */
+    have_imagebg = 1;
+    imagebgR = ecdef.red;
+    imagebgG = ecdef.green;
+    imagebgB = ecdef.blue;
+  }
+
+
   /* set up hi/lo colors */
   i=0;
   if (dispDEEP > 1) {   /* only if we're on a reasonable display */
@@ -590,7 +711,7 @@
     if (theVisual->class == StaticGray || theVisual->class == GrayScale)
       mono = 1;
   }
-  
+
 
 
   iconPix  = MakePix1(rootW, icon_bits,     icon_width,    icon_height);
@@ -598,32 +719,32 @@
   riconPix = MakePix1(rootW, runicon_bits,  runicon_width, runicon_height);
   riconmask= MakePix1(rootW, runiconm_bits, runiconm_width,runiconm_height);
 
-  if (!iconPix || !iconmask || !riconPix || !riconmask) 
+  if (!iconPix || !iconmask || !riconPix || !riconmask)
     FatalError("Unable to create icon pixmaps\n");
 
-  gray50Tile = XCreatePixmapFromBitmapData(theDisp, rootW, 
+  gray50Tile = XCreatePixmapFromBitmapData(theDisp, rootW,
 				(char *) cboard50_bits,
-				cboard50_width, cboard50_height, 
+				cboard50_width, cboard50_height,
 				infofg, infobg, dispDEEP);
   if (!gray50Tile) FatalError("Unable to create gray50Tile bitmap\n");
 
-  gray25Tile = XCreatePixmapFromBitmapData(theDisp, rootW, 
+  gray25Tile = XCreatePixmapFromBitmapData(theDisp, rootW,
 				(char *) gray25_bits,
-				gray25_width, gray25_height, 
+				gray25_width, gray25_height,
 				infofg, infobg, dispDEEP);
   if (!gray25Tile) FatalError("Unable to create gray25Tile bitmap\n");
 
 
   /* try to load fonts */
-  if ( (mfinfo = XLoadQueryFont(theDisp,FONT1))==NULL && 
-       (mfinfo = XLoadQueryFont(theDisp,FONT2))==NULL && 
-       (mfinfo = XLoadQueryFont(theDisp,FONT3))==NULL && 
-       (mfinfo = XLoadQueryFont(theDisp,FONT4))==NULL && 
+  if ( (mfinfo = XLoadQueryFont(theDisp,FONT1))==NULL &&
+       (mfinfo = XLoadQueryFont(theDisp,FONT2))==NULL &&
+       (mfinfo = XLoadQueryFont(theDisp,FONT3))==NULL &&
+       (mfinfo = XLoadQueryFont(theDisp,FONT4))==NULL &&
        (mfinfo = XLoadQueryFont(theDisp,FONT5))==NULL) {
-    sprintf(str,
+    sprintf(dummystr,
 	    "couldn't open the following fonts:\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s",
 	    FONT1, FONT2, FONT3, FONT4, FONT5);
-    FatalError(str);
+    FatalError(dummystr);
   }
   mfont=mfinfo->fid;
   XSetFont(theDisp,theGC,mfont);
@@ -632,45 +753,100 @@
 
   if (monofontname) {
     monofinfo = XLoadQueryFont(theDisp, monofontname);
-    if (!monofinfo) fprintf(stderr,"xv: unable to load font '%s'\n", 
+    if (!monofinfo) fprintf(stderr,"xv: unable to load font '%s'\n",
 			    monofontname);
-  }    
+  }
 
   if (!monofinfo) {
-    if ((monofinfo = XLoadQueryFont(theDisp,MFONT1))==NULL && 
-	(monofinfo = XLoadQueryFont(theDisp,MFONT2))==NULL && 
-	(monofinfo = XLoadQueryFont(theDisp,MFONT3))==NULL && 
+    if ((monofinfo = XLoadQueryFont(theDisp,MFONT1))==NULL &&
+	(monofinfo = XLoadQueryFont(theDisp,MFONT2))==NULL &&
+	(monofinfo = XLoadQueryFont(theDisp,MFONT3))==NULL &&
 	(monofinfo = XLoadQueryFont(theDisp,MFONT4))==NULL) {
-      sprintf(str,"couldn't open %s fonts:\n\t%s\n\t%s\n\t%s\n\t%s",
+      sprintf(dummystr,"couldn't open %s fonts:\n\t%s\n\t%s\n\t%s\n\t%s",
 	      "any of the following",
 	      MFONT1, MFONT2, MFONT3, MFONT4);
-      FatalError(str);
+      FatalError(dummystr);
     }
   }
 
   monofont=monofinfo->fid;
-  
 
-  
-  
+#ifdef TV_L10N
+  if (xlocale) {
+    i = 0;
+    while (mfontsize[i]) {
+      xlocale = 1;	/* True */
+
+      sprintf(mfontset, TV_FONTSET, mfontsize[i]);
+/*fprintf(stderr, "FontSet: %s\n", mfontset);*/
+
+      monofset = XCreateFontSet(theDisp, mfontset,
+				&misscharset, &nmisscharset, &defstr);
+#  if 0	/* not useful */
+      if (!monofset) {
+	/* the current locale is not supported */
+/*fprintf(stderr, "Current locale `%s' is not supported.\n", localeList[i]);*/
+	xlocale = 0;
+	break;
+      }
+#  endif
+/*fprintf(stderr, "# of misscharset in mfontsize[%d]: %d\n", i,nmisscharset);*/
+
+      for (j = 0; j < nmisscharset; j++) {
+	if (!strncmp(misscharset[j], "jisx0208", 8)) {
+	  /* font for JIS X 0208 is not found */
+	  xlocale = 0;
+	  break;
+	}
+      }
+
+      if (xlocale) {
+	monofsetinfo = XExtentsOfFontSet(monofset);
+	monofsetinfo->max_logical_extent.width = mfontsize[i];
+		/* correct size of TextViewer
+		   in case that JIS X 0208 is not found */
+	break;
+      }
+
+      i++;
+    } /* while (mfontsize[i]) */
+
+#  if 0
+    if (nmisscharset > 0) {
+      sprintf(dummystr,"missing %d charset:\n", nmisscharset);
+      for (i = 0; i < nmisscharset; i++) {
+	sprintf(dummystr, "%s\t%s\n", dummystr, misscharset[i]);
+      }
+#    if 0
+      FatalError(dummystr);
+#    else
+      fprintf(stderr, "%s", dummystr);
+#    endif
+    }
+#  endif
+  }
+#endif	/* TV_L10N */
+
+
+
   /* if ncols wasn't set, set it to 2^dispDEEP, unless dispDEEP=1, in which
      case ncols = 0;  (ncols = max number of colors allocated.  on 1-bit
      displays, no colors are allocated */
-  
+
   if (ncols == -1) {
     if (dispDEEP>1) ncols = 1 << ((dispDEEP>8) ? 8 : dispDEEP);
     else ncols = 0;
   }
   else if (ncols>256) ncols = 256;       /* so program doesn't blow up */
-  
-  
+
+
   GenerateFSGamma();  /* has to be done before 'OpenBrowse()' is called */
-  
-  
-  
+
+
+
   /* no filenames.  build one-name (stdio) list (if stdinflag) */
   if (numnames==0) {
-    if (stdinflag) {  
+    if (stdinflag) {
       /* have to malloc namelist[0] so we can free it in deleteFromList() */
       namelist[0] = (char *) malloc(strlen(STDINSTR) + 1);
       if (!namelist[0]) FatalError("unable to to build namelist[0]");
@@ -679,16 +855,28 @@
     }
     else namelist[0] = NULL;
   }
-  
+  else if (randomShow) {
+    int i, j;
+    char *tmp;
+
+    srandom((int)time((time_t *)0));
+    for (i = numnames; i > 1; i--) {
+      j = random() % i;
+      tmp = namelist[i-1];
+      namelist[i-1] = namelist[j];
+      namelist[j] = tmp;
+    }
+  }
+
   if (numnames) makeDispNames();
-  
-  
-  if (viewonly || autoquit) { 
-    imap = ctrlmap = gmap = browmap = cmtmap = 0; 
+
+
+  if (viewonly || autoquit) {
+    imap = ctrlmap = gmap = browmap = cmtmap = 0;
     novbrowse = 1;
   }
-  
-  
+
+
   /* create the info box window */
   CreateInfo(infogeom);
   XSelectInput(theDisp, infoW, ExposureMask | ButtonPressMask | KeyPressMask
@@ -698,12 +886,12 @@
     RedrawInfo(0,0,1000,1000);  /* explicit draw if mapped */
     XFlush(theDisp);
   }
-  
-  
+
+
   /* create the control box window */
   CreateCtrl(ctrlgeom);
   epicMode = EM_RAW;   SetEpicMode();
-  
+
   XSelectInput(theDisp, ctrlW, ExposureMask | ButtonPressMask | KeyPressMask
 	       | StructureNotifyMask);
   if (ctrlmap < 0) {    /* map iconified */
@@ -719,22 +907,22 @@
     RedrawCtrl(0,0,1000,1000);   /* explicit draw if mapped */
     XFlush(theDisp);
   }
-  
+
   fixDispNames();
   ChangedCtrlList();
-  
+
   /* disable root modes if using non-default visual */
   if (!defaultVis) {
     for (i=RMB_ROOT; i<RMB_MAX; i++) rootMB.dim[i] = 1;
   }
-  
-  
+
+
   /* create the directory window */
   CreateDirW(NULL);
   XSelectInput(theDisp, dirW, ExposureMask | ButtonPressMask | KeyPressMask);
   browseCB.val = browseMode;
   savenormCB.val = savenorm;
-  
+
   /* create the gamma window */
   CreateGam(gamgeom, (gamset) ? gamval : -1.0,
 	    (cgamset) ? rgamval : -1.0,
@@ -744,60 +932,84 @@
   XSelectInput(theDisp, gamW, ExposureMask | ButtonPressMask | KeyPressMask
 	       | StructureNotifyMask
 	       | (cmapInGam ? ColormapChangeMask : 0));
-  
+
   GamBox(gmap);     /* map it (or not) */
-  
-  
-  
+
+
+
   stdnfcols = 0;   /* so we don't try to free any if we don't create any */
-  
+
   if (!novbrowse) {
     MakeBrowCmap();
     /* create the visual browser window */
     CreateBrowse(browgeom, fgstr, bgstr, histr, lostr);
-    
+
     if (browmap) OpenBrowse();
   }
   else windowMB.dim[WMB_BROWSE] = 1;    /* disable visual schnauzer */
-  
-  
+
+
   CreateTextWins(textgeom, cmtgeom);
   if (cmtmap) OpenCommentText();
-  
-  
+
+
   /* create the ps window */
   CreatePSD(NULL);
   XSetTransientForHint(theDisp, psW, dirW);
   encapsCB.val = preview;
   pscompCB.val = pscomp;
-  
-  
+
+
 #ifdef HAVE_JPEG
   CreateJPEGW();
   XSetTransientForHint(theDisp, jpegW, dirW);
 #endif
-  
+
+#ifdef HAVE_JP2K
+  CreateJP2KW();
+  XSetTransientForHint(theDisp, jp2kW, dirW);
+#endif
+
 #ifdef HAVE_TIFF
   CreateTIFFW();
   XSetTransientForHint(theDisp, tiffW, dirW);
 #endif
-  
-  
+
+#ifdef HAVE_PNG
+  CreatePNGW();
+  XSetTransientForHint(theDisp, pngW, dirW);
+#endif
+
+#ifdef HAVE_PCD
+  CreatePCDW();
+  XSetTransientForHint(theDisp, pcdW, dirW);
+#endif
+
+#ifdef HAVE_PIC2
+  CreatePIC2W();
+  XSetTransientForHint(theDisp, pic2W, dirW);
+#endif
+
+#ifdef HAVE_MGCSFX
+  CreateMGCSFXW();
+  XSetTransientForHint(theDisp, mgcsfxW, dirW);
+#endif
+
   LoadFishCursors();
   SetCursors(-1);
-  
-  
+
+
   /* if we're not on a colormapped display, turn off rwcolor */
   if (!CMAPVIS(theVisual)) {
     if (rwcolor) fprintf(stderr, "xv: not a colormapped display.  %s\n",
 			 "'rwcolor' turned off.");
-    
+
     allocMode = AM_READONLY;
     dispMB.flags[DMB_COLRW] = 0;  /* de-'check' */
     dispMB.dim[DMB_COLRW] = 1;    /* and dim it */
   }
-  
-  
+
+
   if (force24) {
     Set824Menus(PIC24);
     conv24MB.flags[CONV24_LOCK]  = 1;
@@ -812,15 +1024,15 @@
     Set824Menus(PIC8);     /* default mode */
     picType = PIC8;
   }
-  
-  
-  
+
+
+
   /* make std colormap, maybe */
   ChangeCmapMode(colorMapMode, 0, 0);
 
 
-  
-  
+
+
   /* Do The Thing... */
   mainLoop();
   Quit(0);
@@ -832,12 +1044,12 @@
 /*****************************************************/
 static void makeDirectCmap()
 {
-  int    i, j, cmaplen, numgot;
+  int    i, cmaplen, numgot;
   byte   origgot[256];
   XColor c;
   u_long rmask, gmask, bmask;
   int    rshift, gshift, bshift;
-  
+
 
   rmask = theVisual->red_mask;
   gmask = theVisual->green_mask;
@@ -849,22 +1061,22 @@
 
   if (rshift<0) rmask = rmask << (-rshift);
            else rmask = rmask >> rshift;
-  
+
   if (gshift<0) gmask = gmask << (-gshift);
            else gmask = gmask >> gshift;
-  
+
   if (bshift<0) bmask = bmask << (-bshift);
            else bmask = bmask >> bshift;
 
 
   cmaplen = theVisual->map_entries;
   if (cmaplen>256) cmaplen=256;
-  
+
 
   /* try to alloc a 'cmaplen' long grayscale colormap.  May not get all
      entries for whatever reason.  Build table 'directConv[]' that
      maps range [0..(cmaplen-1)] into set of colors we did get */
-  
+
   for (i=0; i<256; i++) {  origgot[i] = 0;  directConv[i] = 0; }
 
   for (i=numgot=0; i<cmaplen; i++) {
@@ -882,9 +1094,9 @@
     }
   }
 
-  
+
   if (numgot == 0) FatalError("Got no entries in DirectColor cmap!\n");
-  
+
   /* directConv may or may not have holes in it. */
   for (i=0; i<cmaplen; i++) {
     if (!origgot[i]) {
@@ -892,10 +1104,10 @@
       numbak = numfwd = 0;
       while ((i - numbak) >= 0       && !origgot[i-numbak]) numbak++;
       while ((i + numfwd) <  cmaplen && !origgot[i+numfwd]) numfwd++;
-      
+
       if (i-numbak<0        || !origgot[i-numbak]) numbak = 999;
       if (i+numfwd>=cmaplen || !origgot[i+numfwd]) numfwd = 999;
-      
+
       if      (numbak<numfwd) directConv[i] = directConv[i-numbak];
       else if (numfwd<999)    directConv[i] = directConv[i+numfwd];
       else FatalError("DirectColor cmap:  can't happen!");
@@ -926,14 +1138,14 @@
 {
   if (!vinfo || best<0) return;
 
-  if (vinfo[best].visualid == 
+  if (vinfo[best].visualid ==
       XVisualIDFromVisual(DefaultVisual(theDisp, theScreen))) return;
 
   theVisual = vinfo[best].visual;
 
   if (DEBUG) {
     fprintf(stderr,"%s: using %s visual (0x%0x), depth = %d, screen = %d\n",
-	    cmd, 
+	    cmd,
 	    (vinfo[best].class==StaticGray)  ? "StaticGray" :
 	    (vinfo[best].class==StaticColor) ? "StaticColor" :
 	    (vinfo[best].class==TrueColor)   ? "TrueColor" :
@@ -947,41 +1159,45 @@
 	    (int) vinfo[best].red_mask, (int) vinfo[best].green_mask,
 	    (int) vinfo[best].blue_mask, vinfo[best].bits_per_rgb);
   }
-  
+
   dispDEEP  = vinfo[best].depth;
   theScreen = vinfo[best].screen;
-  rootW     = RootWindow(theDisp, theScreen);
+  if (spec_window) {
+	rootW = spec_window;
+  } else {
+	rootW = RootWindow(theDisp,theScreen);
+  }
   ncells    = vinfo[best].colormap_size;
   theCmap   = XCreateColormap(theDisp, rootW, theVisual, AllocNone);
-  
+
   {
     /* create a temporary window using this visual so we can
        create a GC for this visual */
-    
-    Window win;  
+
+    Window win;
     XSetWindowAttributes xswa;
     XGCValues xgcv;
     unsigned long xswamask;
-    
+
     XFlush(theDisp);
     XSync(theDisp, False);
-    
+
     xswa.background_pixel = 0;
     xswa.border_pixel     = 1;
     xswa.colormap         = theCmap;
     xswamask = CWBackPixel | CWBorderPixel | CWColormap;
-    
+
     win = XCreateWindow(theDisp, rootW, 0, 0, 100, 100, 2, (int) dispDEEP,
 			InputOutput, theVisual, xswamask, &xswa);
-    
+
     XFlush(theDisp);
     XSync(theDisp, False);
-    
+
     theGC = XCreateGC(theDisp, win, 0L, &xgcv);
-    
+
     XDestroyWindow(theDisp, win);
   }
-  
+
   vrWIDE = dispWIDE  = DisplayWidth(theDisp,theScreen);
   vrHIGH = dispHIGH  = DisplayHeight(theDisp,theScreen);
   maxWIDE = dispWIDE;  maxHIGH = dispHIGH;
@@ -1000,25 +1216,25 @@
   /* once through the argument list to find the display name
      and DEBUG level, if any */
 
-  for (i=1; i<argc; i++) {
+  for (i=1; i<argc; ++i) {
     if (!strncmp(argv[i],"-help", (size_t) 5)) {  /* help */
       cmdSyntax();
       exit(0);
     }
 
     else if (!argcmp(argv[i],"-display",4,0,&pm)) {
-      i++;
+      ++i;
       if (i<argc) display = argv[i];
       break;
     }
 
-#ifdef VMS    /* in VMS, cmd-line-opts are in lower case */
+#ifdef VMS    /* in VMS, cmd-line opts are in lower case */
     else if (!argcmp(argv[i],"-debug",3,0,&pm)) {
-      { if (++i<argc) DEBUG = atoi(argv[i]); }
+      if (++i<argc) DEBUG = atoi(argv[i]);
     }
 #else
     else if (!argcmp(argv[i],"-DEBUG",2,0,&pm)) {
-      { if (++i<argc) DEBUG = atoi(argv[i]); }
+      if (++i<argc) DEBUG = atoi(argv[i]);
     }
 #endif
   }
@@ -1037,8 +1253,8 @@
       fprintf(stderr,"%s: unable to parse 'aspect' resource\n",cmd);
     else defaspect = (float) n / (float) d;
   }
-      
-  if (rd_flag("2xlimit"))        limit2x     = def_int;      
+
+  if (rd_flag("2xlimit"))        limit2x     = def_int;
   if (rd_flag("auto4x3"))        auto4x3     = def_int;
   if (rd_flag("autoClose"))      autoclose   = def_int;
   if (rd_flag("autoCrop"))       autocrop    = def_int;
@@ -1064,6 +1280,7 @@
   if (rd_flag("ctrlMap"))        ctrlmap     = def_int;
   if (rd_int ("cursor"))         curstype    = def_int;
   if (rd_int ("defaultPreset"))  preset      = def_int;
+  if (rd_int ("incrementalSearchTimeout"))  incrementalSearchTimeout = def_int;
 
   if (rd_str ("driftKludge")) {
     if (sscanf(def_str,"%d %d", &kludge_offx, &kludge_offy) != 2) {
@@ -1073,7 +1290,7 @@
 
   if (rd_str ("expand")) {
     if (index(def_str, ':')) {
-      if (sscanf(def_str, "%lf:%lf", &hexpand, &vexpand)!=2) 
+      if (sscanf(def_str, "%lf:%lf", &hexpand, &vexpand)!=2)
 	{ hexpand = vexpand = 1.0; }
     }
     else hexpand = vexpand = atof(def_str);
@@ -1081,6 +1298,9 @@
 
   if (rd_str ("fileList"))       flistName   = def_str;
   if (rd_flag("fixed"))          fixedaspect = def_int;
+#ifdef ENABLE_FIXPIX_SMOOTH
+  if (rd_flag("fixpix"))         do_fixpix_smooth = def_int;
+#endif
   if (rd_flag("force8"))         force8      = def_int;
   if (rd_flag("force24"))        force24     = def_int;
   if (rd_str ("foreground"))     fgstr       = def_str;
@@ -1092,23 +1312,39 @@
   if (rd_str ("highlight"))      histr       = def_str;
   if (rd_str ("iconGeometry"))   icongeom    = def_str;
   if (rd_flag("iconic"))         startIconic = def_int;
+  if (rd_str ("imageBackground")) imagebgstr = def_str;
   if (rd_str ("infoGeometry"))   infogeom    = def_str;
   if (rd_flag("infoMap"))        imap        = def_int;
   if (rd_flag("loadBrowse"))     browseMode  = def_int;
   if (rd_str ("lowlight"))       lostr       = def_str;
+#ifdef MACBINARY
+  if (rd_flag("macbinary"))      handlemacb  = def_int;
+#endif
+#ifdef HAVE_MGCSFX
+  if (rd_flag("mgcsfx"))         mgcsfx      = def_int;
+#endif
   if (rd_flag("mono"))           mono        = def_int;
   if (rd_str ("monofont"))       monofontname = def_str;
   if (rd_int ("ncols"))          ncols       = def_int;
   if (rd_flag("ninstall"))       ninstall    = def_int;
   if (rd_flag("nodecor"))        nodecor     = def_int;
   if (rd_flag("nolimits"))       nolimits    = def_int;
+#ifdef HAVE_MGCSFX
+  if (rd_flag("nomgcsfx"))       nomgcsfx    = def_int;
+#endif
+#if defined(HAVE_PIC) || defined(HAVE_PIC2)
+  if (rd_flag("nopicadjust"))    nopicadjust = def_int;
+#endif
   if (rd_flag("nopos"))          nopos       = def_int;
   if (rd_flag("noqcheck"))       noqcheck    = def_int;
   if (rd_flag("nostat"))         nostat      = def_int;
   if (rd_flag("ownCmap"))        owncmap     = def_int;
   if (rd_flag("perfect"))        perfect     = def_int;
+#ifdef HAVE_PIC2
+  if (rd_flag("pic2split"))      pic2split   = def_int;
+#endif
   if (rd_flag("popupKludge"))    winCtrPosKludge = def_int;
-  if (rd_str ("print"))          strncpy(printCmd, def_str, 
+  if (rd_str ("print"))          strncpy(printCmd, def_str,
 					 (size_t) PRINTCMDLEN);
   if (rd_flag("pscompress"))     pscomp      = def_int;
   if (rd_flag("pspreview"))      preview     = def_int;
@@ -1117,18 +1353,34 @@
   if (rd_flag("reverse"))        revvideo    = def_int;
   if (rd_str ("rootBackground")) rootbgstr   = def_str;
   if (rd_str ("rootForeground")) rootfgstr   = def_str;
-  if (rd_int ("rootMode"))       { rootMode    = def_int;  rmodeset++; }
+  if (rd_int ("rootMode"))       { rootMode    = def_int;  ++rmodeset; }
   if (rd_flag("rwColor"))        rwcolor     = def_int;
   if (rd_flag("saveNormal"))     savenorm    = def_int;
   if (rd_str ("searchDirectory"))  strcpy(searchdir, def_str);
   if (rd_str ("textviewGeometry")) textgeom  = def_str;
   if (rd_flag("useStdCmap"))     stdcmap     = def_int;
   if (rd_str ("visual"))         visualstr   = def_str;
+#ifdef VS_ADJUST
+  if (rd_flag("vsadjust"))       vsadjust    = def_int;
+#endif
   if (rd_flag("vsDisable"))      novbrowse   = def_int;
   if (rd_str ("vsGeometry"))     browgeom    = def_str;
   if (rd_flag("vsMap"))          browmap     = def_int;
   if (rd_flag("vsPerfect"))      browPerfect = def_int;
   if (rd_str ("white"))          whitestr    = def_str;
+  
+  /* Check for any command-bindings to the supported function keys */
+#define TMPLEN 80
+  for (i=0; i<FSTRMAX; ++i) {
+    char tmp[TMPLEN];
+
+    snprintf(tmp, TMPLEN, "F%dcommand", i+1);
+    if (rd_str(tmp))
+      fkeycmds[i] = def_str;
+    else
+      fkeycmds[i] = NULL;
+  }  
+#undef TMPLEN
 }
 
 
@@ -1146,7 +1398,7 @@
 
     not_in_first_half = 0;
 
-    if (argv[i][0] != '-' && argv[i][0] != '+') { 
+    if (argv[i][0] != '-' && argv[i][0] != '+') {
       /* a file name.  put it in list */
 
       if (!nostat) {
@@ -1158,24 +1410,30 @@
       }
 
       if (numnames<MAXNAMES) {
+#ifdef AUTO_EXPAND
+	if(Isarchive(argv[i]) == 0){ /* Not archive file */
+	  namelist[numnames++] = argv[i];
+	}
+#else
 	namelist[numnames++] = argv[i];
+#endif
 	if (numnames==MAXNAMES) {
-	  fprintf(stderr,"%s: too many filenames.  Only using first %d.\n",
+	  fprintf(stderr,"%s: too many filenames.  Using only first %d.\n",
 		  cmd, MAXNAMES);
 	}
       }
     }
 
-    else if (!strcmp(argv[i],  "-"))                    /* stdin flag */
+    else if (!strcmp(argv[i],  "-"))                       /* stdin flag */
       stdinflag++;
 
-    else if (!argcmp(argv[i],"-24",     3,1,&force24 ));  /* force24 */
-    else if (!argcmp(argv[i],"-2xlimit",3,1,&limit2x ));  /* 2xlimit */
-    else if (!argcmp(argv[i],"-4x3",    2,1,&auto4x3 ));  /* 4x3 */
-    else if (!argcmp(argv[i],"-8",      2,1,&force8  ));  /* force8 */
-    else if (!argcmp(argv[i],"-acrop",  3,1,&autocrop));  /* autocrop */
-
-    else if (!argcmp(argv[i],"-aspect",3,0,&pm)) {        /* def. aspect */
+    else if (!argcmp(argv[i],"-24",     3,1,&force24 ));   /* force24 */
+    else if (!argcmp(argv[i],"-2xlimit",3,1,&limit2x ));   /* 2xlimit */
+    else if (!argcmp(argv[i],"-4x3",    2,1,&auto4x3 ));   /* 4x3 */
+    else if (!argcmp(argv[i],"-8",      2,1,&force8  ));   /* force8 */
+    else if (!argcmp(argv[i],"-acrop",  3,1,&autocrop));   /* autocrop */
+                                                          
+    else if (!argcmp(argv[i],"-aspect",3,0,&pm)) {         /* def. aspect */
       int n,d;
       if (++i<argc) {
 	if (sscanf(argv[i],"%d:%d",&n,&d)!=2 || n<1 || d<1)
@@ -1184,57 +1442,65 @@
       }
     }
 
-    else if (!argcmp(argv[i],"-best24",3,0,&pm))          /* -best */
+    else if (!argcmp(argv[i],"-windowid",3,0,&pm)) {
+      if (++i<argc) {
+	if (sscanf(argv[i], "%ld", &spec_window) != 1) {
+		fprintf(stderr,"%s: bad argument to -windowid '%s'\n",cmd,argv[i]);
+        }
+      }
+    }
+
+    else if (!argcmp(argv[i],"-best24",3,0,&pm))           /* -best */
       conv24 = CONV24_BEST;
-    
-    else if (!argcmp(argv[i],"-bg",3,0,&pm))              /* bg color */
+
+    else if (!argcmp(argv[i],"-bg",3,0,&pm))               /* bg color */
       { if (++i<argc) bgstr = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-black",3,0,&pm))           /* black color */
+
+    else if (!argcmp(argv[i],"-black",3,0,&pm))            /* black color */
       { if (++i<argc) blackstr = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-bw",3,0,&pm))              /* border width */
+
+    else if (!argcmp(argv[i],"-bw",3,0,&pm))               /* border width */
       { if (++i<argc) bwidth=atoi(argv[i]); }
-    
-    else if (!argcmp(argv[i],"-cecmap",4,1,&cmapInGam));  /* cmapInGam */
-    
-    else if (!argcmp(argv[i],"-cegeometry",4,0,&pm))      /* gammageom */
+
+    else if (!argcmp(argv[i],"-cecmap",4,1,&cmapInGam));   /* cmapInGam */
+
+    else if (!argcmp(argv[i],"-cegeometry",4,0,&pm))       /* gammageom */
       { if (++i<argc) gamgeom = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-cemap",4,1,&gmap));        /* gmap */
-    
-    else if (!argcmp(argv[i],"-cgamma",4,0,&pm)) {        /* color gamma */
+
+    else if (!argcmp(argv[i],"-cemap",4,1,&gmap));         /* gmap */
+
+    else if (!argcmp(argv[i],"-cgamma",4,0,&pm)) {         /* color gamma */
       if (i+3<argc) {
-	rgamval = atof(argv[++i]); 
-	ggamval = atof(argv[++i]); 
-	bgamval = atof(argv[++i]); 
+	rgamval = atof(argv[++i]);
+	ggamval = atof(argv[++i]);
+	bgamval = atof(argv[++i]);
       }
       cgamset++;
     }
-    
-    else if (!argcmp(argv[i],"-cgeometry",4,0,&pm))	  /* ctrlgeom */
+
+    else if (!argcmp(argv[i],"-cgeometry",4,0,&pm))	   /* ctrlgeom */
       { if (++i<argc) ctrlgeom = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-clear",4,1,&clrroot));	  /* clear */
-    else if (!argcmp(argv[i],"-close",4,1,&autoclose));	  /* close */
-    else if (!argcmp(argv[i],"-cmap", 3,1,&ctrlmap));	  /* ctrlmap */
 
-    else if (!argcmp(argv[i],"-cmtgeometry",5,0,&pm))	  /* comment geom */
+    else if (!argcmp(argv[i],"-clear",4,1,&clrroot));	   /* clear */
+    else if (!argcmp(argv[i],"-close",4,1,&autoclose));	   /* close */
+    else if (!argcmp(argv[i],"-cmap", 3,1,&ctrlmap));	   /* ctrlmap */
+
+    else if (!argcmp(argv[i],"-cmtgeometry",5,0,&pm))	   /* comment geom */
       { if (++i<argc) cmtgeom = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-cmtmap",5,1,&cmtmap));	  /* map cmt window */
-    
-    else if (!argcmp(argv[i],"-crop",3,0,&pm)) {          /* crop */
+
+    else if (!argcmp(argv[i],"-cmtmap",5,1,&cmtmap));	   /* map cmt window */
+
+    else if (!argcmp(argv[i],"-crop",3,0,&pm)) {           /* crop */
       if (i+4<argc) {
-	acropX = atoi(argv[++i]); 
-	acropY = atoi(argv[++i]); 
-	acropW = atoi(argv[++i]); 
-	acropH = atoi(argv[++i]); 
+	acropX = atoi(argv[++i]);
+	acropY = atoi(argv[++i]);
+	acropW = atoi(argv[++i]);
+	acropH = atoi(argv[++i]);
       }
       acrop++;
     }
-    
-    else if (!argcmp(argv[i],"-cursor",3,0,&pm))	  /* cursor */
+
+    else if (!argcmp(argv[i],"-cursor",3,0,&pm))	   /* cursor */
       { if (++i<argc) curstype = atoi(argv[i]); }
 
 #ifdef VMS    /* in VMS, cmd-line-opts are in lower case */
@@ -1247,84 +1513,100 @@
     }
 #endif
 
-    else if (!argcmp(argv[i],"-dir",4,0,&pm))             /* search dir */
+    else if (!argcmp(argv[i],"-dir",4,0,&pm))              /* search dir */
       { if (++i<argc) strcpy(searchdir, argv[i]); }
 
-    else if (!argcmp(argv[i],"-display",4,0,&pm))         /* display */
+    else if (!argcmp(argv[i],"-display",4,0,&pm))          /* display */
       { if (++i<argc) display = argv[i]; }
 
-    else if (!argcmp(argv[i],"-dither",4,1,&autodither)); /* autodither */
+    else if (!argcmp(argv[i],"-dither",4,1,&autodither));  /* autodither */
 
-    else if (!argcmp(argv[i],"-drift",3,0,&pm)) {         /* drift kludge */
+    else if (!argcmp(argv[i],"-drift",3,0,&pm)) {          /* drift kludge */
       if (i<argc-2) {
 	kludge_offx = atoi(argv[++i]);
 	kludge_offy = atoi(argv[++i]);
       }
     }
 
-    else if (!argcmp(argv[i],"-expand",2,0,&pm)) {	  /* expand factor */
+    else if (!argcmp(argv[i],"-expand",2,0,&pm)) {	   /* expand factor */
       if (++i<argc) {
 	if (index(argv[i], ':')) {
-	  if (sscanf(argv[i], "%lf:%lf", &hexpand, &vexpand)!=2) 
+	  if (sscanf(argv[i], "%lf:%lf", &hexpand, &vexpand)!=2)
 	    { hexpand = vexpand = 1.0; }
 	}
 	else hexpand = vexpand = atof(argv[i]);
       }
     }
 
-    else if (!argcmp(argv[i],"-fg",3,0,&pm))              /* fg color */
+#ifdef HAVE_G3
+    else if (!argcmp(argv[i],"-fax",3,0,&highresfax));     /* fax */
+#endif
+
+    else if (!argcmp(argv[i],"-fg",3,0,&pm))               /* fg color */
       { if (++i<argc) fgstr = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-fixed",3,1,&fixedaspect)); /* fix asp. ratio */
-    
-    else if (!argcmp(argv[i],"-flist",3,0,&pm))           /* file list */
+
+    else if (!argcmp(argv[i],"-fixed",5,1,&fixedaspect));  /* fix asp. ratio */
+
+#ifdef ENABLE_FIXPIX_SMOOTH
+    else if (!argcmp(argv[i],"-fixpix",5,1,&do_fixpix_smooth)); /* dithering */
+#endif
+
+    else if (!argcmp(argv[i],"-flist",3,0,&pm))            /* file list */
       { if (++i<argc) flistName = argv[i]; }
 
-    else if (!argcmp(argv[i],"-gamma",3,0,&pm))	          /* gamma */
+    else if (!argcmp(argv[i],"-gamma",3,0,&pm))	           /* gamma */
       { if (++i<argc) gamval = atof(argv[i]);  gamset++; }
-    
-    else if (!argcmp(argv[i],"-geometry",3,0,&pm))	  /* geometry */
+
+    else if (!argcmp(argv[i],"-geometry",3,0,&pm))	   /* geometry */
       { if (++i<argc) maingeom = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-grabdelay",3,0,&pm))	  /* grabDelay */
+
+    else if (!argcmp(argv[i],"-grabdelay",3,0,&pm))	   /* grabDelay */
       { if (++i<argc) grabDelay = atoi(argv[i]); }
-    
-    else if (!argcmp(argv[i],"-gsdev",4,0,&pm))	          /* gsDevice */
+
+    else if (!argcmp(argv[i],"-gsdev",4,0,&pm))	           /* gsDevice */
       { if (++i<argc) gsDev = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-gsgeom",4,0,&pm))          /* gsGeometry */
+
+    else if (!argcmp(argv[i],"-gsgeom",4,0,&pm))           /* gsGeometry */
       { if (++i<argc) gsGeomStr = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-gsres",4,0,&pm))           /* gsResolution */
+
+    else if (!argcmp(argv[i],"-gsres",4,0,&pm))            /* gsResolution */
       { if (++i<argc) gsRes=abs(atoi(argv[i])); }
-    
-    else if (!argcmp(argv[i],"-hflip",3,1,&autohflip));   /* hflip */
 
-    else if (!argcmp(argv[i],"-hi",3,0,&pm))	          /* highlight */
+    else if (!argcmp(argv[i],"-hflip",3,1,&autohflip));    /* hflip */
+
+    else if (!argcmp(argv[i],"-hi",3,0,&pm))	           /* highlight */
       { if (++i<argc) histr = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-hist", 4,1,&autohisteq));  /* hist eq */
+
+#ifdef HAVE_G3
+    else if (!argcmp(argv[i],"-highresfax",4,0,&highresfax));/* high res. fax */
+#endif
+
+    else if (!argcmp(argv[i],"-hist", 4,1,&autohisteq));   /* hist eq */
 
     else if (!argcmp(argv[i],"-hsv",   3,1,&hsvmode));     /* hsvmode */
 
     else if (!argcmp(argv[i],"-icgeometry",4,0,&pm))       /* icon geometry */
       { if (++i<argc) icongeom = argv[i]; }
-    
+
     else if (!argcmp(argv[i],"-iconic",4,1,&startIconic)); /* iconic */
-    
+
     else if (!argcmp(argv[i],"-igeometry",3,0,&pm))        /* infogeom */
       { if (++i<argc) infogeom = argv[i]; }
-    
-    else if (!argcmp(argv[i],"-imap",     3,1,&imap));        /* imap */
-    else if (!argcmp(argv[i],"-lbrowse",  3,1,&browseMode));  /* browse mode */
 
-    else if (!argcmp(argv[i],"-lo",3,0,&pm))	        /* lowlight */
+    else if (!argcmp(argv[i],"-imap",3,1,&imap));          /* imap */
+
+    else if (!argcmp(argv[i],"-ibg",3,0,&pm))             /* image bkgd color */
+      { if (++i<argc) imagebgstr = argv[i]; }
+
+    else if (!argcmp(argv[i],"-lbrowse",3,1,&browseMode)); /* browse mode */
+
+    else if (!argcmp(argv[i],"-lo",3,0,&pm))	           /* lowlight */
       { if (++i<argc) lostr = argv[i]; }
 
     else if (!argcmp(argv[i],"-loadclear",4,1,&clearonload)); /* clearonload */
 
-    
-    else not_in_first_half = 1;     
+
+    else not_in_first_half = 1;
 
 
 
@@ -1339,103 +1621,130 @@
     if (!argcmp(argv[i],"-max",4,1,&automax));	        /* auto maximize */
     else if (!argcmp(argv[i],"-maxpect",5,1,&pm))       /* auto maximize */
       { automax=pm; fixedaspect=pm; }
-    
+
+#ifdef MACBINARY
+    else if (!argcmp(argv[i],"-macbinary",3,1,&handlemacb)); /* macbinary */
+#endif
+
     else if (!argcmp(argv[i],"-mfn",3,0,&pm))           /* mono font name */
       { if (++i<argc) monofontname = argv[i]; }
 
+#ifdef HAVE_MGCSFX
+    else if (!argcmp(argv[i],"-mgcsfx", 4,1,&mgcsfx));  /* mgcsfx */
+#endif
+
     else if (!argcmp(argv[i],"-mono",3,1,&mono));	/* mono */
-    
+
     else if (!argcmp(argv[i],"-name",3,0,&pm))          /* name */
       { if (++i<argc) winTitle = argv[i]; }
-    
+
     else if (!argcmp(argv[i],"-ncols",3,0,&pm))        /* ncols */
       { if (++i<argc) ncols=abs(atoi(argv[i])); }
-    
-    else if (!argcmp(argv[i],"-ninstall",  3,1,&ninstall));   /* inst cmaps?*/
+
+    else if (!argcmp(argv[i],"-ninstall",  3,1,&ninstall));   /* inst cmaps? */
     else if (!argcmp(argv[i],"-nodecor",   4,1,&nodecor));
     else if (!argcmp(argv[i],"-nofreecols",4,1,&noFreeCols));
     else if (!argcmp(argv[i],"-nolimits",  4,1,&nolimits));   /* nolimits */
+#ifdef HAVE_MGCSFX
+    else if (!argcmp(argv[i],"-nomgcsfx", 4,1,&nomgcsfx));    /* nomgcsfx */
+#endif
+#if defined(HAVE_PIC) || defined(HAVE_PIC2)
+    else if (!argcmp(argv[i],"-nopicadjust", 4,1,&nopicadjust));/*nopicadjust*/
+#endif
     else if (!argcmp(argv[i],"-nopos",     4,1,&nopos));      /* nopos */
     else if (!argcmp(argv[i],"-noqcheck",  4,1,&noqcheck));   /* noqcheck */
-    else if (!argcmp(argv[i],"-noresetroot",5,1,&resetroot)); /* reset root*/
+    else if (!argcmp(argv[i],"-noresetroot",5,1,&resetroot)); /* reset root */
     else if (!argcmp(argv[i],"-norm",      5,1,&autonorm));   /* norm */
     else if (!argcmp(argv[i],"-nostat",    4,1,&nostat));     /* nostat */
     else if (!argcmp(argv[i],"-owncmap",   2,1,&owncmap));    /* own cmap */
+#ifdef HAVE_PCD
+    else if (!argcmp(argv[i],"-pcd",       4,0,&pm))         /* pcd with size */
+      { if (i+1<argc) PcdSize = atoi(argv[++i]); }
+#endif
     else if (!argcmp(argv[i],"-perfect",   3,1,&perfect));    /* -perfect */
+#ifdef HAVE_PIC2
+    else if (!argcmp(argv[i],"-pic2split", 3,1,&pic2split));  /* pic2split */
+#endif
     else if (!argcmp(argv[i],"-pkludge",   3,1,&winCtrPosKludge));
     else if (!argcmp(argv[i],"-poll",      3,1,&polling));    /* chk mod? */
 
     else if (!argcmp(argv[i],"-preset",3,0,&pm))      /* preset */
       { if (++i<argc) preset=abs(atoi(argv[i])); }
-    
+
     else if (!argcmp(argv[i],"-quick24",5,0,&pm))     /* quick 24-to-8 conv */
       conv24 = CONV24_FAST;
-    
+
     else if (!argcmp(argv[i],"-quit",   2,1,&autoquit));   /* auto-quit */
     else if (!argcmp(argv[i],"-random", 4,1,&randomShow)); /* random */
     else if (!argcmp(argv[i],"-raw",    4,1,&autoraw));    /* force raw */
 
     else if (!argcmp(argv[i],"-rbg",3,0,&pm))      /* root background color */
       { if (++i<argc) rootbgstr = argv[i]; }
-    
+
     else if (!argcmp(argv[i],"-rfg",3,0,&pm))      /* root foreground color */
       { if (++i<argc) rootfgstr = argv[i]; }
-    
+
     else if (!argcmp(argv[i],"-rgb",4,1,&pm))      /* rgb mode */
       hsvmode = !pm;
-    
+
     else if (!argcmp(argv[i],"-RM",3,0,&pm))	   /* auto-delete */
       autoDelete = 1;
-    
+
     else if (!argcmp(argv[i],"-rmode",3,0,&pm))	   /* root pattern */
-      { if (++i<argc) rootMode = atoi(argv[i]); 
+      { if (++i<argc) rootMode = atoi(argv[i]);
 	useroot++;  rmodeset++;
       }
-    
+
     else if (!argcmp(argv[i],"-root",4,1,&useroot));  /* use root window */
-    
+
     else if (!argcmp(argv[i],"-rotate",4,0,&pm))      /* rotate */
       { if (++i<argc) autorotate = atoi(argv[i]); }
-    
+
     else if (!argcmp(argv[i],"-rv",3,1,&revvideo));   /* reverse video */
     else if (!argcmp(argv[i],"-rw",3,1,&rwcolor));    /* use r/w color */
 
     else if (!argcmp(argv[i],"-slow24",3,0,&pm))      /* slow 24->-8 conv.*/
       conv24 = CONV24_SLOW;
-    
+
     else if (!argcmp(argv[i],"-smooth",3,1,&autosmooth));  /* autosmooth */
+    else if (!argcmp(argv[i],"-startgrab",3,1,&startGrab)); /* startGrab */
     else if (!argcmp(argv[i],"-stdcmap",3,1,&stdcmap));    /* use stdcmap */
 
     else if (!argcmp(argv[i],"-tgeometry",2,0,&pm))	   /* textview geom */
       { if (++i<argc) textgeom = argv[i]; }
-    
+
     else if (!argcmp(argv[i],"-vflip",3,1,&autovflip));	   /* vflip */
     else if (!argcmp(argv[i],"-viewonly",4,1,&viewonly));  /* viewonly */
 
     else if (!argcmp(argv[i],"-visual",4,0,&pm))           /* visual */
       { if (++i<argc) visualstr = argv[i]; }
-    
+
+#ifdef VS_ADJUST
+    else if (!argcmp(argv[i],"-vsadjust", 3,1,&vsadjust));  /* vsadjust */
+#endif
+
     else if (!argcmp(argv[i],"-vsdisable",4,1,&novbrowse)); /* disable sch? */
-    
+
     else if (!argcmp(argv[i],"-vsgeometry",4,0,&pm))	/* visSchnauzer geom */
       { if (++i<argc) browgeom = argv[i]; }
-    
+
     else if (!argcmp(argv[i],"-vsmap",4,1,&browmap));	/* visSchnauzer map */
-    
+
     else if (!argcmp(argv[i],"-vsperfect",3,1,&browPerfect));	/* vs perf. */
 
     else if (!argcmp(argv[i],"-wait",3,0,&pm)) {        /* secs betwn pics */
       if (++i<argc) {
-	waitsec = abs(atoi(argv[i]));
-	if (waitsec<0) waitsec = 0;
+	char *comma = strchr(argv[i], ',');
+	waitsec_nonfinal = fabs(atof(argv[i]));
+	waitsec_final = comma? fabs(atof(comma+1)) : waitsec_nonfinal;
       }
     }
-    
+
     else if (!argcmp(argv[i],"-white",3,0,&pm))	        /* white color */
       { if (++i<argc) whitestr = argv[i]; }
-    
+
     else if (!argcmp(argv[i],"-wloop",3,1,&waitloop));	/* waitloop */
-    
+
     else if (not_in_first_half) cmdSyntax();
   }
 
@@ -1453,7 +1762,11 @@
   /* check options for validity */
 
   if (strlen(searchdir)) {  /* got a search directory */
+#ifdef AUTO_EXPAND
+    if (Chvdir(searchdir)) {
+#else
     if (chdir(searchdir)) {
+#endif
       fprintf(stderr,"xv: unable to cd to directory '%s'.\n",searchdir);
       fprintf(stderr,
        "    Ignoring '-dir' option and/or 'xv.searchDirectory' resource\n");
@@ -1462,7 +1775,7 @@
   }
 
 
-  if (flistName) 
+  if (flistName)
     add_filelist_to_namelist(flistName, namelist, &numnames, MAXNAMES);
 
   RANGE(curstype,0,254);
@@ -1475,16 +1788,16 @@
 
   /* if using root, generally gotta map ctrl window, 'cause there won't be
      any way to ask for it.  (no kbd or mouse events from rootW) */
-  if (useroot && !autoquit) ctrlmap = -1;    
+  if (useroot && !autoquit) ctrlmap = -1;
+
 
-  
   if (abs(autorotate) !=   0 && abs(autorotate) != 90 &&
       abs(autorotate) != 180 && abs(autorotate) != 270) {
     fprintf(stderr,"Invalid auto rotation value (%d) ignored.\n", autorotate);
     fprintf(stderr,"  (Valid values:  0, +-90, +-180, +-270)\n");
 
     autorotate = 0;
-  } 
+  }
 
 
   if (grabDelay < 0 || grabDelay > 15) {
@@ -1498,9 +1811,9 @@
     fprintf(stderr,"  (Valid values:  1, 2, 3, 4)\n");
 
     preset = 0;
-  } 
+  }
 
-  if (waitsec < 0) noFreeCols = 0;   /* disallow nfc if not doing slideshow */
+  if (waitsec < 0.0) noFreeCols = 0;   /* disallow nfc if not doing slideshow */
   if (noFreeCols && perfect) { perfect = 0;  owncmap = 1; }
 
   /* decide what default color allocation stuff we've settled on */
@@ -1512,24 +1825,24 @@
 
   defaultCmapMode = colorMapMode;  /* default mode for 8-bit images */
 
-  if (nopos) { 
-    maingeom = infogeom = ctrlgeom = gamgeom = browgeom = textgeom = NULL;
-    cmtgeom = NULL;
+  if (nopos) {
+    maingeom = infogeom = ctrlgeom = gamgeom = browgeom = textgeom = cmtgeom =
+      (const char *) NULL;
   }
 
   /* if -root and -maxp, disallow 'integer' tiling modes */
-  if (useroot && fixedaspect && automax && !rmodeset && 
+  if (useroot && fixedaspect && automax && !rmodeset &&
       (rootMode == RM_TILE || rootMode == RM_IMIRROR))
     rootMode = RM_CSOLID;
 }
 
 
 
+static int cpos = 0;
 
 /***********************************/
-static int cpos = 0;
 static void printoption(st)
-     char *st;
+     const char *st;
 {
   if (strlen(st) + cpos > 78) {
     fprintf(stderr,"\n   ");
@@ -1540,8 +1853,26 @@
   cpos = cpos + strlen(st) + 1;
 }
 
+
 static void cmdSyntax()
 {
+  /* GRR 19980605:  added version info for most common libraries */
+  fprintf(stderr, "XV - %s.\n", REVDATE);
+#ifdef HAVE_JPEG
+  VersionInfoJPEG();
+#endif
+#ifdef HAVE_JP2K
+  VersionInfoJP2K();
+#endif
+#ifdef HAVE_TIFF
+  VersionInfoTIFF();
+#endif
+#ifdef HAVE_PNG
+  VersionInfoPNG();
+#endif
+  /* pbm/pgm/ppm support is native, not via pbmplus/netpbm libraries */
+  fprintf(stderr, "\n");
+
   fprintf(stderr, "Usage:\n");
   printoption(cmd);
   printoption("[-]");
@@ -1579,8 +1910,14 @@
   printoption("[-/+dither]");
   printoption("[-drift dx dy]");
   printoption("[-expand exp | hexp:vexp]");
+#ifdef HAVE_G3
+  printoption("[-fax]");
+#endif
   printoption("[-fg color]");
   printoption("[-/+fixed]");
+#ifdef ENABLE_FIXPIX_SMOOTH
+  printoption("[-/+fixpix]");
+#endif
   printoption("[-flist fname]");
   printoption("[-gamma val]");
   printoption("[-geometry geom]");
@@ -1591,8 +1928,12 @@
   printoption("[-help]");
   printoption("[-/+hflip]");
   printoption("[-hi color]");
+#ifdef HAVE_G3
+  printoption("[-highresfax]");
+#endif
   printoption("[-/+hist]");
   printoption("[-/+hsv]");
+  printoption("[-ibg color]");  /* GRR 19980314 */
   printoption("[-icgeometry geom]");
   printoption("[-/+iconic]");
   printoption("[-igeometry geom]");
@@ -1600,9 +1941,15 @@
   printoption("[-/+lbrowse]");
   printoption("[-lo color]");
   printoption("[-/+loadclear]");
+#ifdef MACBINARY
+  printoption("[-/+macbinary]");
+#endif
   printoption("[-/+max]");
   printoption("[-/+maxpect]");
   printoption("[-mfn font]");
+#ifdef HAVE_MGCSFX
+  printoption("[-/+mgcsfx]");
+#endif
   printoption("[-/+mono]");
   printoption("[-name str]");
   printoption("[-ncols #]");
@@ -1610,13 +1957,25 @@
   printoption("[-/+nodecor]");
   printoption("[-/+nofreecols]");
   printoption("[-/+nolimits]");
+#ifdef HAVE_MGCSFX
+  printoption("[-/+nomgcsfx]");
+#endif
+#if defined(HAVE_PIC) || defined(HAVE_PIC2)
+  printoption("[-/+nopicadjust]");
+#endif
   printoption("[-/+nopos]");
   printoption("[-/+noqcheck]");
   printoption("[-/+noresetroot]");
   printoption("[-/+norm]");
   printoption("[-/+nostat]");
   printoption("[-/+owncmap]");
+#ifdef HAVE_PCD
+  printoption("[-pcd size(0=192*128,1,2,3,4=3072*2048)]");
+#endif
   printoption("[-/+perfect]");
+#ifdef HAVE_PIC2
+  printoption("[-/+pic2split]");
+#endif
   printoption("[-/+pkludge]");
   printoption("[-/+poll]");
   printoption("[-preset #]");
@@ -1635,17 +1994,22 @@
   printoption("[-/+rw]");
   printoption("[-slow24]");
   printoption("[-/+smooth]");
+  printoption("[-/+startgrab]");
   printoption("[-/+stdcmap]");
   printoption("[-tgeometry geom]");
   printoption("[-/+vflip]");
   printoption("[-/+viewonly]");
   printoption("[-visual type]");
+#ifdef VS_ADJUST
+  printoption("[-/+vsadjust]");
+#endif
   printoption("[-/+vsdisable]");
   printoption("[-vsgeometry geom]");
   printoption("[-/+vsmap]");
   printoption("[-/+vsperfect]");
-  printoption("[-wait seconds]");
+  printoption("[-wait secs[,final_secs]]");
   printoption("[-white color]");
+  printoption("[-windowid windowid]");
   printoption("[-/+wloop]");
   printoption("[filename ...]");
   fprintf(stderr,"\n\n");
@@ -1656,7 +2020,7 @@
 /***********************************/
 static void rmodeSyntax()
 {
-  fprintf(stderr,"%s: unknown root mode '%d'.  Valid modes are:\n", 
+  fprintf(stderr,"%s: unknown root mode '%d'.  Valid modes are:\n",
 	  cmd, rootMode);
   fprintf(stderr,"\t0: tiling\n");
   fprintf(stderr,"\t1: integer tiling\n");
@@ -1668,6 +2032,7 @@
   fprintf(stderr,"\t7: centered on a 'brick' background\n");
   fprintf(stderr,"\t8: symmetrical tiling\n");
   fprintf(stderr,"\t9: symmetrical mirrored tiling\n");
+  fprintf(stderr,"\t10: upper left corner\n");
   fprintf(stderr,"\n");
   Quit(1);
 }
@@ -1675,17 +2040,15 @@
 
 /***********************************/
 static int argcmp(a1, a2, minlen, plusallowed, plusminus)
-     char *a1, *a2;
+     const char *a1, *a2;
      int  minlen, plusallowed;
      int *plusminus;
 {
-  /* does a string compare between a1 and a2.  To return '0', a1 and a2 
-     must match to the length of a2, and that length has to
+  /* does a string compare between a1 and a2.  To return '0', a1 and a2
+     must match to the length of a1, and that length has to
      be at least 'minlen'.  Otherwise, return non-zero.  plusminus set to '1'
      if '-option', '0' if '+option' */
 
-  int i;
-
   if ((strlen(a1) < (size_t) minlen) || (strlen(a2) < (size_t) minlen))
     return 1;
   if (strlen(a1) > strlen(a2)) return 1;
@@ -1694,7 +2057,7 @@
 
   if (a1[0]=='-' || (plusallowed && a1[0]=='+')) {
     /* only set if we match */
-    *plusminus = (a1[0] == '-');    
+    *plusminus = (a1[0] == '-');
     return 0;
   }
 
@@ -1721,8 +2084,11 @@
   int   oldCXOFF, oldCYOFF, oldCWIDE, oldCHIGH, wascropped;
   char *tmp;
   char *fullname,       /* full name of the original file */
-        filename[512],  /* full name of file to load (could be /tmp/xxx)*/
-        globnm[512];    /* globbed version of fullname of orig file */
+        filename[512];  /* full name of file to load (could be /tmp/xxx)*/
+#ifdef MACBINARY
+  char origname[512];	/* file name of original file (NO processing) */
+  origname[0] = '\0';
+#endif
 
   xvbzero((char *) &pinfo, sizeof(PICINFO));
 
@@ -1748,7 +2114,7 @@
 
   /* if we're not loading next or prev page in a multi-page doc, kill off
      page files */
-  if (strlen(pageBaseName) && filenum!=OP_PAGEDN && filenum!=OP_PAGEUP) 
+  if (strlen(pageBaseName) && filenum!=OP_PAGEDN && filenum!=OP_PAGEUP)
     killpage = 1;
 
 
@@ -1799,14 +2165,13 @@
   }
 
   else if (filenum == PADDED) {
-    /* need fullfname (used for window/icon name), 
+    /* need fullfname (used for window/icon name),
        basefname(compute from fullfname) */
 
     i = LoadPad(&pinfo, fullfname);
     fullname = fullfname;
     strcpy(filename, fullfname);
-    tmp = BaseName(fullfname);
-    strcpy(basefname, tmp);
+    strcpy(basefname, BaseName(fullfname));
 
     if (!i) goto FAILED;   /* shouldn't happen */
 
@@ -1855,33 +2220,48 @@
       frompipe = 1;
     }
   }
+#ifdef AUTO_EXPAND
+  else {
+    fullname = (char *) malloc(MAXPATHLEN+2);
+    strcpy(fullname, namelist[filenum]);   // 1 of 2 places fullname != const
+    freename = 1;
+  }
+  tmp = (char *) rindex(fullname, '/');
+  if (tmp) {
+    *tmp = '\0';			   // 2 of 2 places fullname != const
+    Mkvdir(fullname);
+    *tmp = '/';
+  }
+  Dirtovd(fullname);
+#else
   else fullname = namelist[filenum];
-
+#endif
 
   strcpy(fullfname, fullname);
-  tmp = BaseName(fullname);
-  strcpy(basefname, tmp);
+  strcpy(basefname, BaseName(fullname));
 
 
   /* chop off trailing ".Z", ".z", or ".gz" from displayed basefname, if any */
-  if (strlen(basefname) > (size_t) 2     && 
-      strcmp(basefname+strlen(basefname)-2,".Z")==0)
+  if (strlen(basefname)>2 && strcmp(basefname+strlen(basefname)-2,".Z")==0)
     basefname[strlen(basefname)-2]='\0';
   else {
 #ifdef GUNZIP
-    if (strlen(basefname)>2 && strcmp(basefname+strlen(basefname)-2,".Z")==0)
+    if (strlen(basefname)>2 && strcmp(basefname+strlen(basefname)-2,".z")==0)
       basefname[strlen(basefname)-2]='\0';
-
-    else if (strlen(basefname)>3 && 
-	     strcmp(basefname+strlen(basefname)-3,".gz")==0)
+    else
+    if (strlen(basefname)>3 && strcmp(basefname+strlen(basefname)-3,".gz")==0)
       basefname[strlen(basefname)-3]='\0';
-#endif /* GUNZIP */
+#endif
+#ifdef BUNZIP2
+    if (strlen(basefname)>4 && strcmp(basefname+strlen(basefname)-4,".bz2")==0)
+      basefname[strlen(basefname)-4]='\0';
+#endif
   }
 
 
   if (filenum == LOADPIC && ISPIPE(fullname[0])) {
     /* if we're reading from a pipe, 'filename' will have the /tmp/xvXXXXXX
-       filename, and we can skip a lot of stuff:  (such as prepending 
+       filename, and we can skip a lot of stuff:  (such as prepending
        'initdir' to relative paths, dealing with reading from stdin, etc. */
 
     /* at this point, fullname = "! do some commands",
@@ -1891,11 +2271,11 @@
 
   else {  /* NOT reading from a PIPE */
 
-    /* if fullname doesn't start with a '/' (ie, it's a relative path), 
-       (and it's not LOADPIC and it's not the special case '<stdin>') 
+    /* if fullname doesn't start with a '/' (ie, it's a relative path),
+       (and it's not LOADPIC and it's not the special case '<stdin>')
        then we need to prepend a directory name to it:
-       
-       prepend 'initdir', 
+
+       prepend 'initdir',
        if we have a searchdir (ie, we have multiple places to look),
              see if such a file exists (via fopen()),
        if it does, we're done.
@@ -1904,7 +2284,7 @@
        if it does, we're done.
        if it doesn't, remove all prepended directories, and fall through
              to error code below.  */
-    
+
     if (filenum!=LOADPIC && fullname[0]!='/' && strcmp(fullname,STDINSTR)!=0) {
       char *tmp1;
 
@@ -1954,28 +2334,40 @@
 	}
       }
     }
-    
+
     strcpy(filename, fullname);
-    
-    
+
+
     /* if the file is STDIN, write it out to a temp file */
 
     if (strcmp(filename,STDINSTR)==0) {
-      FILE *fp;
+      FILE *fp = NULL;
+#ifndef USE_MKSTEMP
+      int tmpfd;
+#endif
 
-#ifndef VMS      
+#ifndef VMS
       sprintf(filename,"%s/xvXXXXXX",tmpdir);
 #else /* it is VMS */
       sprintf(filename, "[]xvXXXXXX");
 #endif
+
+#ifdef USE_MKSTEMP
+      fp = fdopen(mkstemp(filename), "w");
+#else
       mktemp(filename);
+      tmpfd = open(filename,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR);
+      if (tmpfd < 0) FatalError("openPic(): can't create temporary file");
+      fp = fdopen(tmpfd,"w");
+#endif
+      if (!fp) FatalError("openPic(): can't write temporary file");
 
       clearerr(stdin);
-      fp = fopen(filename,"w");
-      if (!fp) FatalError("openPic(): can't write temporary file");
-    
       while ( (i=getchar()) != EOF) putc(i,fp);
       fclose(fp);
+#ifndef USE_MKSTEMP
+      close(tmpfd);
+#endif
 
       /* and remove it from list, since we can never reload from stdin */
       if (strcmp(namelist[0], STDINSTR)==0) deleteFromList(0);
@@ -1990,20 +2382,26 @@
     (no pipes or stdin, though it could be compressed) to be loaded */
   filetype = ReadFileType(filename);
 
+#ifdef HAVE_MGCSFX
+  if (mgcsfx && filetype == RFT_UNKNOWN){ /* force use MgcSfx */
+    if(getInputCom() != 0) filetype = RFT_MGCSFX;
+  }
+#endif
 
-  if (filetype == RFT_COMPRESS) {   /* a compressed file.  uncompress it */
+  /* if it's a compressed file, uncompress it: */
+  if ((filetype == RFT_COMPRESS) || (filetype == RFT_BZIP2)) {
     char tmpname[128];
 
     if (
 #ifndef VMS
-	UncompressFile(filename, tmpname)
+	UncompressFile(filename, tmpname, filetype)
 #else
-	UncompressFile(basefname, tmpname)
+	UncompressFile(basefname, tmpname, filetype)
 #endif
 	) {
 
       filetype = ReadFileType(tmpname);    /* and try again */
-      
+
       /* if we made a /tmp file (from stdin, etc.) won't need it any more */
       if (strcmp(fullname,filename)!=0) unlink(filename);
 
@@ -2013,7 +2411,58 @@
 
     WaitCursor();
   }
-
+
+#ifdef MACBINARY
+  if (handlemacb && macb_file == True) {
+    char tmpname[128];
+
+    if (RemoveMacbinary(filename, tmpname)) {
+      if (strcmp(fullname,filename)!=0) unlink(filename);
+      strcpy(origname, filename);
+      strcpy(filename, tmpname);
+    }
+    else filetype = RFT_ERROR;
+
+    WaitCursor();
+  }
+#endif
+
+#ifdef HAVE_MGCSFX_AUTO
+  if (filetype == RFT_MGCSFX) {
+      char tmpname[128], tmp[256];
+      char *icom;
+
+      if ((icom = mgcsfx_auto_input_com(filename)) != NULL) {
+	sprintf(tmpname, "%s/xvmsautoXXXXXX", tmpdir);
+#ifdef USE_MKSTEMP
+	close(mkstemp(tmpname));
+#else
+	mktemp(tmpname);
+#endif
+	SetISTR(ISTR_INFO, "Converting to known format by MgcSfx auto...");
+	sprintf(tmp,"%s >%s", icom, tmpname);
+      }
+      else goto ms_auto_no;
+
+#ifndef VMS
+      if (system(tmp))
+#else
+      if (!system(tmp))
+#endif
+      {
+	SetISTR(ISTR_INFO, "Unable to convert '%s' by MgcSfx auto.",
+	  BaseName(filename));
+	Warning();
+	filetype = RFT_ERROR;
+	goto ms_auto_no;
+      }
+
+      filetype = ReadFileType(tmpname);
+      if (strcmp(fullname,filename)!=0) unlink(filename);
+      strcpy(filename, tmpname);
+  }
+ms_auto_no:
+#endif /* HAVE_MGCSFX_AUTO */
 
   if (filetype == RFT_ERROR) {
     char  foostr[512];
@@ -2027,10 +2476,16 @@
 
   if (filetype == RFT_UNKNOWN) {
     /* view as a text/hex file */
-    TextView(filename);
+#ifdef MACBINARY
+    if (origname[0])
+      i = TextView(origname);
+    else
+#endif
+      i = TextView(filename);
     SetISTR(ISTR_INFO,"'%s' not in a recognized format.", basefname);
     /* Warning();  */
-    goto SHOWN_AS_TEXT;
+    if (i) goto SHOWN_AS_TEXT;
+    else   goto FAILED;
   }
 
   if (filetype < RFT_ERROR) {
@@ -2058,8 +2513,9 @@
   if (filetype == RFT_XBM && (!i || pinfo.w==0 || pinfo.h==0)) {
     /* probably just a '.h' file or something... */
     SetISTR(ISTR_INFO," ");
-    TextView(filename);
-    goto SHOWN_AS_TEXT;
+    i = TextView(filename);
+    if (i) goto SHOWN_AS_TEXT;
+    else   goto FAILED;
   }
 
   if (!i) {
@@ -2084,7 +2540,7 @@
   /**************/
   /* SUCCESS!!! */
   /**************/
-    
+
 
  GOTIMAGE:
   /* successfully read this picture.  No failures from here on out
@@ -2097,7 +2553,7 @@
   if (conv24MB.flags[CONV24_LOCK]) {  /* locked */
     if (pinfo.type==PIC24 && picType==PIC8) {           /* 24 -> 8 bit */
       byte *pic8;
-      pic8 = Conv24to8(pinfo.pic, pinfo.w, pinfo.h, ncols, 
+      pic8 = Conv24to8(pinfo.pic, pinfo.w, pinfo.h, ncols,
 		       pinfo.r, pinfo.g, pinfo.b);
       free(pinfo.pic);
       pinfo.pic = pic8;
@@ -2108,7 +2564,7 @@
 
     else if (pinfo.type!=PIC24 && picType==PIC24) {    /* 8 -> 24 bit */
       byte *pic24;
-      pic24 = Conv8to24(pinfo.pic, pinfo.w, pinfo.h, 
+      pic24 = Conv8to24(pinfo.pic, pinfo.w, pinfo.h,
 			pinfo.r, pinfo.g, pinfo.b);
       free(pinfo.pic);
       pinfo.pic  = pic24;
@@ -2144,7 +2600,7 @@
 
   if (mainW && !useroot) {
     /* avoid generating excess configure events while we resize the window */
-    XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
+    XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask
 		 | StructureNotifyMask
                  | ButtonPressMask | KeyReleaseMask
                  | EnterWindowMask | LeaveWindowMask);
@@ -2162,11 +2618,13 @@
   pHIGH = pinfo.h;
   if (pinfo.frmType >=0) SetDirSaveMode(F_FORMAT, pinfo.frmType);
   if (pinfo.colType >=0) SetDirSaveMode(F_COLORS, pinfo.colType);
-  
+
   SetISTR(ISTR_FORMAT, pinfo.fullInfo);
   strcpy(formatStr, pinfo.shrtInfo);
   picComments = pinfo.comment;
   ChangeCommentText();
+  picExifInfo = pinfo.exifInfo;
+  picExifInfoSize = pinfo.exifInfoSize;
 
   for (i=0; i<256; i++) {
     rMap[i] = pinfo.r[i];
@@ -2194,12 +2652,15 @@
   if (fullname && strcmp(fullname,filename)!=0) unlink(filename);
 
 
-  SetISTR(ISTR_INFO,formatStr);
-	
+  SetISTR(ISTR_INFO, "%s", formatStr);
+
   SetInfoMode(INF_PART);
-  SetISTR(ISTR_FILENAME, 
-	  (filenum==DFLTPIC || filenum==GRABBED || frompipe)
-	  ? "<none>" : basefname);
+  if (filenum==DFLTPIC || filenum==GRABBED || frompipe)
+    SetISTR(ISTR_FILENAME, "<none>");
+  else if (numPages > 1)
+    SetISTR(ISTR_FILENAME, "%s  Page %d of %d", basefname, curPage+1, numPages);
+  else
+    SetISTR(ISTR_FILENAME, "%s", basefname);
 
   SetISTR(ISTR_RES,"%d x %d",pWIDE,pHIGH);
   SetISTR(ISTR_COLOR, "");
@@ -2219,7 +2680,7 @@
 
 
   /* handle various 'auto-whatever' command line options
-     Note that if 'frompoll' is set, things that have to do with 
+     Note that if 'frompoll' is set, things that have to do with
      setting the expansion factor are skipped, as we'll want it to
      display in the (already-existing) window at the same size */
 
@@ -2254,7 +2715,7 @@
       w = eWIDE;  h = (w*3) / 4;
       eWIDE = w;  eHIGH = h;
     }
-    
+
 
     if (eWIDE != cWIDE || eHIGH != cHIGH) epic = (byte *) NULL;
 
@@ -2306,14 +2767,14 @@
     aspWIDE = eWIDE;  aspHIGH = eHIGH;   /* aspect-corrected eWIDE,eHIGH */
 
     if (hexpand < 0.0) eWIDE=(int)(aspWIDE / -hexpand);  /* neg:  reciprocal */
-                  else eWIDE=(int)(aspWIDE *  hexpand);  
+                  else eWIDE=(int)(aspWIDE *  hexpand);
     if (vexpand < 0.0) eHIGH=(int)(aspHIGH / -vexpand);  /* neg:  reciprocal */
-                  else eHIGH=(int)(aspHIGH *  vexpand);  
+                  else eHIGH=(int)(aspHIGH *  vexpand);
 
     if (maingeom) {
       /* deal with geometry spec.  Note, they shouldn't have given us
        *both* an expansion factor and a geomsize.  The geomsize wins out */
-    
+
       int i,x,y,gewide,gehigh;  u_int w,h;
 
       gewide = eWIDE;  gehigh = eHIGH;
@@ -2321,11 +2782,11 @@
 
       if (i&WidthValue)  gewide = (int) w;
       if (i&HeightValue) gehigh = (int) h;
-      
+
       /* handle case where the pinheads only specified width *or * height */
       if (( i&WidthValue && ~i&HeightValue) ||
 	  (~i&WidthValue &&  i&HeightValue)) {
-    
+
 	if (i&WidthValue) { gehigh = (aspHIGH * gewide) / pWIDE; }
 	             else { gewide = (aspWIDE * gehigh) / pHIGH; }
       }
@@ -2391,7 +2852,7 @@
 
     /* if we're using an integer tiled root mode, truncate eWIDE/eHIGH to
        be an integer divisor of the display size */
-      
+
     if (useroot && (rootMode == RM_TILE || rootMode == RM_IMIRROR)) {
       /* make picture size a divisor of the rootW size.  round down */
       i = (dispWIDE + eWIDE-1) / eWIDE;   eWIDE = (dispWIDE + i-1) / i;
@@ -2409,7 +2870,7 @@
     if (autodither && ncols>0) epicMode = EM_DITH;
 
     /* if in CM_STDCMAP mode, and *not* in '-wait 0', then autodither */
-    if (colorMapMode == CM_STDCMAP && waitsec != 0) epicMode = EM_DITH;
+    if (colorMapMode == CM_STDCMAP && waitsec != 0.0) epicMode = EM_DITH;
 
     /* if -smooth or image has been shrunk to fit screen */
     if (autosmooth || (pWIDE >maxWIDE || pHIGH>maxHIGH)
@@ -2419,7 +2880,7 @@
 
     /* 'dithering' makes no sense in 24-bit mode */
     if (picType == PIC24 && epicMode == EM_DITH) epicMode = EM_RAW;
-    
+
     SetEpicMode();
   } /* end of !frompoll */
 
@@ -2450,7 +2911,7 @@
   if (useroot) mainW = vrootW;
   if (eWIDE != cWIDE || eHIGH != cHIGH) epic = (byte *) NULL;
 
-  NewPicGetColors(autonorm, autohisteq); 
+  NewPicGetColors(autonorm, autohisteq);
 
   GenerateEpic(eWIDE, eHIGH);     /* want to dither *after* color allocs */
   CreateXImage();
@@ -2474,7 +2935,7 @@
   SetISTR(ISTR_INFO,"%s  %s  %s", formatStr,
 	  (picType==PIC8) ? "8-bit mode." : "24-bit mode.",
 	  tmp);
-	
+
   SetInfoMode(INF_FULL);
   if (freename) free(fullname);
 
@@ -2495,20 +2956,24 @@
      to generate the correct exposes (particularly with 'BitGravity' turned
      on */
 
-  if (mainW && !useroot) GenExpose(mainW, 0, 0, (u_int) eWIDE, (u_int) eHIGH);
+  /*Brian T. Schellenberger: fix for X 4.2 refresh problem*/
+  if (mainW && !useroot) {
+    XSync(theDisp, False);
+    GenExpose(mainW, 0, 0, (u_int) eWIDE, (u_int) eHIGH);
+  }
 
   return 1;
 
-  
+
  FAILED:
   SetCursors(-1);
   KillPageFiles(pinfo.pagebname, pinfo.numpages);
 
-  if (fullname && strcmp(fullname,filename)!=0) 
+  if (fullname && strcmp(fullname,filename)!=0)
     unlink(filename);   /* kill /tmp file */
   if (freename) free(fullname);
 
-  if (!fromint && !polling && filenum>=0 && filenum<nList.nstr) 
+  if (!fromint && !polling && filenum>=0 && filenum<nList.nstr)
     deleteFromList(filenum);
 
   if (polling) sleep(1);
@@ -2527,6 +2992,9 @@
 }
 
 
+extern byte ZXheader[128];	/* [JCE] Spectrum screen magic number is
+                                  defined in xvzx.c */
+
 
 /********************************/
 int ReadFileType(fname)
@@ -2539,76 +3007,118 @@
 
   FILE *fp;
   byte  magicno[30];    /* first 30 bytes of file */
-  int   rv, n;
+  int   rv=RFT_UNKNOWN, n;
+#ifdef MACBINARY
+  int   macbin_alrchk = False;
+#endif
 
   if (!fname) return RFT_ERROR;   /* shouldn't happen */
 
   fp = xv_fopen(fname, "r");
   if (!fp) return RFT_ERROR;
 
-  n = fread(magicno, (size_t) 1, (size_t) 30, fp);  
+  if (strlen(fname) > 4 &&
+      strcasecmp(fname+strlen(fname)-5, ".wbmp")==0)          rv = RFT_WBMP;
+
+  n = fread(magicno, (size_t) 1, sizeof(magicno), fp);
   fclose(fp);
 
-  if (n<30) return RFT_UNKNOWN;    /* files less than 30 bytes long... */
+  if (n<=0) return RFT_UNKNOWN;
+
+  /* it is just barely possible that a few files could legitimately be as small
+     as 30 bytes (e.g., binary P{B,G,P}M format), so zero out rest of "magic
+     number" buffer and don't quit immediately if we read something small but
+     not empty */
+  if (n<30) memset(magicno+n, 0, sizeof(magicno)-n);
 
-  rv = RFT_UNKNOWN;
+#ifdef MACBINARY
+  macb_file = False;
+  while (1) {
+#endif
 
-  if (strncmp((char *) magicno,"GIF87a", (size_t) 6)==0 ||
-      strncmp((char *) magicno,"GIF89a", (size_t) 6)==0)        rv = RFT_GIF;
+#ifdef HAVE_MGCSFX
+  if (is_mgcsfx(fname, magicno, 30) != 0) rv = RFT_MGCSFX;
+  else
+#endif
+       if (strncmp((char *) magicno,"GIF87a", (size_t) 6)==0 ||
+	   strncmp((char *) magicno,"GIF89a", (size_t) 6)==0) rv = RFT_GIF;
 
   else if (strncmp((char *) magicno,"VIEW", (size_t) 4)==0 ||
-	   strncmp((char *) magicno,"WEIV", (size_t) 4)==0)     rv = RFT_PM;
+	   strncmp((char *) magicno,"WEIV", (size_t) 4)==0)   rv = RFT_PM;
+
+#ifdef HAVE_PIC2
+  else if (magicno[0]=='P' && magicno[1]=='2' &&
+	   magicno[2]=='D' && magicno[3]=='T')                rv = RFT_PIC2;
+#endif
 
-  else if (magicno[0] == 'P' && magicno[1]>='1' && 
-	   magicno[1]<='6')                             rv = RFT_PBM;
+  else if (magicno[0] == 'P' && magicno[1]>='1' &&
+	   (magicno[1]<='6' || magicno[1]=='8'))              rv = RFT_PBM;
 
   /* note: have to check XPM before XBM, as first 2 chars are the same */
   else if (strncmp((char *) magicno, "/* XPM */", (size_t) 9)==0) rv = RFT_XPM;
 
   else if (strncmp((char *) magicno,"#define", (size_t) 7)==0 ||
-	   (magicno[0] == '/' && magicno[1] == '*'))    rv = RFT_XBM;
+	   (magicno[0] == '/' && magicno[1] == '*'))          rv = RFT_XBM;
 
   else if (magicno[0]==0x59 && (magicno[1]&0x7f)==0x26 &&
-	   magicno[2]==0x6a && (magicno[3]&0x7f)==0x15) rv = RFT_SUNRAS;
+	   magicno[2]==0x6a && (magicno[3]&0x7f)==0x15)       rv = RFT_SUNRAS;
 
-  else if (magicno[0] == 'B' && magicno[1] == 'M')      rv = RFT_BMP;
+  else if (magicno[0] == 'B' && magicno[1] == 'M')            rv = RFT_BMP;
 
-  else if (magicno[0]==0x52 && magicno[1]==0xcc)        rv = RFT_UTAHRLE;
+  else if (magicno[0]==0x52 && magicno[1]==0xcc)              rv = RFT_UTAHRLE;
 
   else if ((magicno[0]==0x01 && magicno[1]==0xda) ||
-	   (magicno[0]==0xda && magicno[1]==0x01))      rv = RFT_IRIS;
+	   (magicno[0]==0xda && magicno[1]==0x01))            rv = RFT_IRIS;
 
-  else if (magicno[0]==0x1f && magicno[1]==0x9d)        rv = RFT_COMPRESS;
+  else if (magicno[0]==0x1f && magicno[1]==0x9d)              rv = RFT_COMPRESS;
 
 #ifdef GUNZIP
-  else if (magicno[0]==0x1f && magicno[1]==0x8b)        rv = RFT_COMPRESS;
+  else if (magicno[0]==0x1f && magicno[1]==0x8b)              rv = RFT_COMPRESS;
+#endif
+
+#ifdef BUNZIP2
+  else if (magicno[0]==0x42 && magicno[1]==0x5a)              rv = RFT_BZIP2;
 #endif
 
-  else if (magicno[0]==0x0a && magicno[1] <= 5)         rv = RFT_PCX;
+  else if (magicno[0]==0x0a && magicno[1] <= 5)               rv = RFT_PCX;
 
-  else if (strncmp((char *) magicno,   "FORM", (size_t) 4)==0 && 
-	   strncmp((char *) magicno+8, "ILBM", (size_t) 4)==0)   rv = RFT_IFF;
+  else if (strncmp((char *) magicno,   "FORM", (size_t) 4)==0 &&
+	   strncmp((char *) magicno+8, "ILBM", (size_t) 4)==0) rv = RFT_IFF;
 
   else if (magicno[0]==0 && magicno[1]==0 &&
 	   magicno[2]==2 && magicno[3]==0 &&
 	   magicno[4]==0 && magicno[5]==0 &&
-	   magicno[6]==0 && magicno[7]==0)              rv = RFT_TARGA;
+	   magicno[6]==0 && magicno[7]==0)                    rv = RFT_TARGA;
 
   else if (magicno[4]==0x00 && magicno[5]==0x00 &&
-	   magicno[6]==0x00 && magicno[7]==0x07)        rv = RFT_XWD;
+	   magicno[6]==0x00 && magicno[7]==0x07)              rv = RFT_XWD;
 
-  else if (strncmp((char *) magicno,"SIMPLE  ", (size_t) 8)==0 && 
-	   magicno[29] == 'T')                          rv = RFT_FITS;
-  
+  else if (strncmp((char *) magicno,"SIMPLE  ", (size_t) 8)==0 &&
+	   magicno[29] == 'T')                                rv = RFT_FITS;
+
+  /* [JCE] Spectrum screen */
+  else if (memcmp(magicno, ZXheader, (size_t) 18)==0)         rv = RFT_ZX;
 
 #ifdef HAVE_JPEG
-  else if (magicno[0]==0xff && magicno[1]==0xd8 && 
-	   magicno[2]==0xff)                            rv = RFT_JFIF;
+  else if (magicno[0]==0xff && magicno[1]==0xd8 &&
+	   magicno[2]==0xff)                                  rv = RFT_JFIF;
+#endif
+
+#ifdef HAVE_JP2K
+  else if (magicno[0]==0xff && magicno[1]==0x4f && 
+           magicno[2]==0xff && magicno[3]==0x51)              rv = RFT_JPC;
+
+  else if (memcmp(magicno, jp2k_magic, sizeof(jp2k_magic))==0) rv = RFT_JP2;
 #endif
 
 #ifdef HAVE_TIFF
   else if ((magicno[0]=='M' && magicno[1]=='M') ||
-	   (magicno[0]=='I' && magicno[1]=='I'))        rv = RFT_TIFF;
+	   (magicno[0]=='I' && magicno[1]=='I'))              rv = RFT_TIFF;
+#endif
+
+#ifdef HAVE_PNG
+  else if (magicno[0]==0x89 && magicno[1]=='P' &&
+           magicno[2]=='N'  && magicno[3]=='G')               rv = RFT_PNG;
 #endif
 
 #ifdef HAVE_PDS
@@ -2620,11 +3130,67 @@
       rv = RFT_PDSVICAR;
 #endif
 
-#ifdef GS_PATH
+#ifdef GS_PATH   /* Ghostscript handles both PostScript and PDF */
   else if (strncmp((char *) magicno, "%!",     (size_t) 2)==0 ||
-	   strncmp((char *) magicno, "\004%!", (size_t) 3)==0)   rv = RFT_PS;
+	   strncmp((char *) magicno, "\004%!", (size_t) 3)==0 ||
+           strncmp((char *) magicno, "%PDF",   (size_t) 4)==0) rv = RFT_PS;
+#endif
+
+#ifdef HAVE_G3
+  else if ((magicno[0]==  1 && magicno[1]==  1 &&
+            magicno[2]== 77 && magicno[3]==154 &&
+            magicno[4]==128 && magicno[5]==  0 &&
+            magicno[6]==  1 && magicno[7]== 77)
+           || highresfax || fax) /* kludge! */                rv = RFT_G3;
+#endif
+
+#ifdef HAVE_MAG
+  else if (strncmp((char *) magicno,"MAKI02  ", (size_t) 8)==0) rv = RFT_MAG;
+#endif
+
+#ifdef HAVE_MAKI
+  else if (strncmp((char *) magicno,"MAKI01A ", (size_t) 8)==0 ||
+	   strncmp((char *) magicno,"MAKI01B ", (size_t) 8)==0) rv = RFT_MAKI;
+#endif
+
+#ifdef HAVE_PIC
+  else if (magicno[0]=='P' && magicno[1]=='I'&&magicno[2]=='C') rv = RFT_PIC;
+#endif
+
+#ifdef HAVE_PI
+  else if (magicno[0]=='P' && magicno[1]=='i')                rv = RFT_PI;
+#endif
+
+#ifdef HAVE_HIPS
+  else if (strstr((char *) magicno, "./digest"))              rv = RFT_HIPS;
+#endif
+
+#ifdef HAVE_PCD
+  else if (magicno[0]==0xff && magicno[1]==0xff &&
+           magicno[2]==0xff && magicno[3]==0xff)              rv = RFT_PCD;
 #endif
 
+#ifdef MACBINARY
+    /* Now we try to handle MacBinary files, but the method is VERY dirty... */
+    if (macbin_alrchk == True) {
+      macb_file = True;
+      break;
+    }
+
+    if (rv != RFT_UNKNOWN)
+      break;
+
+    /* Skip MACBSIZE and recheck */
+    macbin_alrchk = True;
+    fp = xv_fopen(fname, "r");
+    if (!fp) return RFT_ERROR;
+    fseek(fp, MACBSIZE, SEEK_SET);
+    n = fread(magicno, (size_t) 1, (size_t) 30, fp);
+    fclose(fp);
+
+    if (n<30) return RFT_UNKNOWN;    /* files less than 30 bytes long... */
+  }
+#endif
   return rv;
 }
 
@@ -2637,9 +3203,10 @@
      PICINFO *pinfo;
 {
   /* if quick is set, we're being called to generate icons, or something
-     like that.  We should load the image as quickly as possible.  Currently,
-     this only affects the LoadPS routine, which, if quick is set, only
-     generates the page file for the first page of the document */
+     like that.  We should load the image as quickly as possible.  Previously,
+     this affected only the LoadPS routine, which, if quick is set, only
+     generates the page file for the first page of the document.  Now it
+     also affects PCD, which loads only a thumbnail. */
 
   int rv = 0;
 
@@ -2650,7 +3217,11 @@
   switch (ftype) {
   case RFT_GIF:     rv = LoadGIF   (fname, pinfo);         break;
   case RFT_PM:      rv = LoadPM    (fname, pinfo);         break;
+#ifdef HAVE_MGCSFX
+  case RFT_PBM:     rv = LoadPBM   (fname, pinfo, -1);     break;
+#else
   case RFT_PBM:     rv = LoadPBM   (fname, pinfo);         break;
+#endif
   case RFT_XBM:     rv = LoadXBM   (fname, pinfo);         break;
   case RFT_SUNRAS:  rv = LoadSunRas(fname, pinfo);         break;
   case RFT_BMP:     rv = LoadBMP   (fname, pinfo);         break;
@@ -2662,21 +3233,69 @@
   case RFT_XPM:     rv = LoadXPM   (fname, pinfo);         break;
   case RFT_XWD:     rv = LoadXWD   (fname, pinfo);         break;
   case RFT_FITS:    rv = LoadFITS  (fname, pinfo, quick);  break;
+  case RFT_ZX:      rv = LoadZX    (fname, pinfo);         break; /* [JCE] */
+  case RFT_WBMP:    rv = LoadWBMP  (fname, pinfo);         break;
+
+#ifdef HAVE_PCD
+  /* if quick is switched on, use the smallest image size; don't ask the user */
+  case RFT_PCD:     rv = LoadPCD   (fname, pinfo, quick ? 0 : PcdSize);  break;
+#endif
 
 #ifdef HAVE_JPEG
-  case RFT_JFIF:    rv = LoadJFIF  (fname, pinfo, quick);    break;
+  case RFT_JFIF:    rv = LoadJFIF  (fname, pinfo, quick);  break;
+#endif
+
+#ifdef HAVE_JP2K
+  case RFT_JPC:     rv = LoadJPC   (fname, pinfo, quick);  break;
+  case RFT_JP2:     rv = LoadJP2   (fname, pinfo, quick);  break;
 #endif
 
 #ifdef HAVE_TIFF
-  case RFT_TIFF:    rv = LoadTIFF  (fname, pinfo);           break;
+  case RFT_TIFF:    rv = LoadTIFF  (fname, pinfo, quick);  break;
+#endif
+
+#ifdef HAVE_PNG
+  case RFT_PNG:     rv = LoadPNG   (fname, pinfo);         break;
 #endif
 
 #ifdef HAVE_PDS
-  case RFT_PDSVICAR: rv = LoadPDS  (fname, pinfo);           break;
+  case RFT_PDSVICAR: rv = LoadPDS  (fname, pinfo);         break;
+#endif
+
+#ifdef HAVE_G3
+  case RFT_G3:      rv = LoadG3    (fname, pinfo);         break;
 #endif
 
 #ifdef GS_PATH
-  case RFT_PS:      rv = LoadPS    (fname, pinfo, quick);    break;
+  case RFT_PS:      rv = LoadPS    (fname, pinfo, quick);  break;
+#endif
+
+#ifdef HAVE_MAG
+  case RFT_MAG:     rv = LoadMAG   (fname, pinfo);         break;
+#endif
+
+#ifdef HAVE_MAKI
+  case RFT_MAKI:    rv = LoadMAKI  (fname, pinfo);         break;
+#endif
+
+#ifdef HAVE_PIC
+  case RFT_PIC:     rv = LoadPIC   (fname, pinfo);         break;
+#endif
+
+#ifdef HAVE_PI
+  case RFT_PI:      rv = LoadPi    (fname, pinfo);         break;
+#endif
+
+#ifdef HAVE_PIC2
+  case RFT_PIC2:    rv = LoadPIC2  (fname, pinfo, quick);  break;
+#endif
+
+#ifdef HAVE_HIPS
+  case RFT_HIPS:    rv = LoadHIPS  (fname, pinfo);         break;
+#endif
+
+#ifdef HAVE_MGCSFX
+  case RFT_MGCSFX:  rv = LoadMGCSFX (fname, pinfo);        break;
 #endif
 
   }
@@ -2685,13 +3304,17 @@
 
 
 /********************************/
-int UncompressFile(name, uncompname)
+int UncompressFile(name, uncompname, filetype)
      char *name, *uncompname;
+     int filetype;
 {
   /* returns '1' on success, with name of uncompressed file in uncompname
      returns '0' on failure */
 
   char namez[128], *fname, buf[512];
+#ifndef USE_MKSTEMP
+  int tmpfd;
+#endif
 
   fname = name;
   namez[0] = '\0';
@@ -2703,7 +3326,7 @@
      to what it was.  necessary because uncompress doesn't handle files
      that don't end with '.Z' */
 
-  if (strlen(name) >= (size_t) 2            && 
+  if (strlen(name) >= (size_t) 2            &&
       strcmp(name + strlen(name)-2,".Z")!=0 &&
       strcmp(name + strlen(name)-2,".z")!=0) {
     strcpy(namez, name);
@@ -2721,34 +3344,50 @@
 #endif   /* not VMS and not GUNZIP */
 
 
-  
 #ifndef VMS
   sprintf(uncompname, "%s/xvuXXXXXX", tmpdir);
-  mktemp(uncompname);
-  sprintf(buf,"%s -c %s >%s", UNCOMPRESS, fname, uncompname);
-#else /* it IS VMS */
+#else
   strcpy(uncompname, "[]xvuXXXXXX");
+#endif
+
+#ifdef USE_MKSTEMP
+  close(mkstemp(uncompname));
+#else
   mktemp(uncompname);
-#  ifdef GUNZIP
-  sprintf(buf,"%s %s %s", UNCOMPRESS, fname, uncompname);
-#  else
-  sprintf(buf,"%s %s", UNCOMPRESS, fname);
-#  endif
+  tmpfd = open(uncompname,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR);
+  if (tmpfd < 0) FatalError("UncompressFile(): can't create temporary file");
+  close(tmpfd);
+#endif
+
+#ifndef VMS
+  if (filetype == RFT_COMPRESS)
+    sprintf(buf,"%s -c '%s' > '%s'", UNCOMPRESS, fname, uncompname);
+# ifdef BUNZIP2
+  else if (filetype == RFT_BZIP2)
+    sprintf(buf,"%s -c '%s' > '%s'", BUNZIP2, fname, uncompname);
+# endif
+#else /* it IS VMS */
+# ifdef GUNZIP
+  sprintf(buf,"%s '%s' '%s'", UNCOMPRESS, fname, uncompname);
+# else
+  sprintf(buf,"%s '%s'", UNCOMPRESS, fname);
+# endif
 #endif
 
   SetISTR(ISTR_INFO, "Uncompressing '%s'...", BaseName(fname));
 #ifndef VMS
-  if (system(buf)) {
+  if (system(buf))
 #else
-  if (!system(buf)) {
+  if (!system(buf))
 #endif
+  {
     SetISTR(ISTR_INFO, "Unable to uncompress '%s'.", BaseName(fname));
     Warning();
     return 0;
   }
 
-#ifndef VMS  
-  /* if we renamed the file to end with a .Z for the sake of 'uncompress', 
+#ifndef VMS
+  /* if we renamed the file to end with a .Z for the sake of 'uncompress',
      rename it back to what it once was... */
 
   if (strlen(namez)) {
@@ -2769,9 +3408,65 @@
     }
    */
 #endif /* not VMS */
-  
+
+  return 1;
+}
+
+
+#ifdef MACBINARY
+/********************************/
+int RemoveMacbinary(src, dst)
+     char *src, *dst;
+{
+  char buffer[8192]; /* XXX */
+  int n, eof;
+#ifndef USE_MKSTEMP
+  int tmpfd;
+#endif
+  FILE *sfp, *dfp;
+
+  sprintf(dst, "%s/xvmXXXXXX", tmpdir);
+#ifdef USE_MKSTEMP
+  close(mkstemp(dst));
+#else
+  mktemp(dst);
+  tmpfd = open(dst,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR);
+  if (tmpfd < 0) FatalError("RemoveMacbinary(): can't create temporary file");
+#endif
+
+  SetISTR(ISTR_INFO, "Removing MacBinary...");
+
+  sfp = xv_fopen(src, "r");
+#ifdef USE_MKSTEMP
+  dfp = xv_fopen(dst, "w");
+#else
+  dfp = fdopen(tmpfd, "w");
+#endif
+  if (!sfp || !dfp) {
+    SetISTR(ISTR_INFO, "Unable to remove a InfoFile header form '%s'.", src);
+    Warning();
+    return 0;
+  }
+  fseek(sfp, MACBSIZE, SEEK_SET);
+  while ((n = fread(buffer, 1, sizeof(buffer), sfp)) == 8192) /* XXX */
+    fwrite(buffer, 1, n, dfp);
+  if ((eof = feof(sfp)))
+    fwrite(buffer, 1, n, dfp);
+  fclose(sfp);
+  fflush(dfp);
+  fclose(dfp);
+#ifndef USE_MKSTEMP
+  close(tmpfd);
+#endif
+  if (!eof) {
+    SetISTR(ISTR_INFO, "Unable to remove a InfoFile header form '%s'.", src);
+    Warning();
+    return 0;
+  }
+
   return 1;
 }
+#endif
 
 
 /********************************/
@@ -2789,6 +3484,10 @@
     sprintf(tmp, "%s%d", bname, i);
     unlink(tmp);
   }
+
+  /* GRR 20070506:  basename file doesn't go away, at least on Linux and for
+   *   GIF and TIFF images, so explicitly unlink() it, too */
+  unlink(bname);
 }
 
 
@@ -2798,11 +3497,11 @@
 {
   int i;
 
-  /* some stuff that necessary whenever running an algorithm or 
+  /* some stuff that necessary whenever running an algorithm or
      installing a new 'pic' (or switching 824 modes) */
 
   numcols = 0;   /* gets set by SortColormap:  set to 0 for PIC24 images */
-  for (i=0; i<256; i++) cols[i]=infobg;   
+  for (i=0; i<256; i++) cols[i]=infobg;
 
   if (picType == PIC8) {
     byte trans[256];
@@ -2811,18 +3510,18 @@
   }
 
   if (picType == PIC8) {
-    /* see if image is a b/w bitmap.  
+    /* see if image is a b/w bitmap.
        If so, use '-black' and '-white' colors */
     if (numcols == 2) {
       if ((rMap[0] == gMap[0] && rMap[0] == bMap[0] && rMap[0] == 255) &&
 	  (rMap[1] == gMap[1] && rMap[1] == bMap[1] && rMap[1] ==   0)) {
 	/* 0=wht, 1=blk */
-	rMap[0] = (whtRGB>>16)&0xff;  
-	gMap[0] = (whtRGB>>8)&0xff;  
+	rMap[0] = (whtRGB>>16)&0xff;
+	gMap[0] = (whtRGB>>8)&0xff;
 	bMap[0] = whtRGB&0xff;
 
 	rMap[1] = (blkRGB>>16)&0xff;
-	gMap[1] = (blkRGB>>8)&0xff;  
+	gMap[1] = (blkRGB>>8)&0xff;
 	bMap[1] = blkRGB&0xff;
       }
 
@@ -2852,10 +3551,10 @@
     }
 
     /* save the desired RGB colormap (before dicking with it) */
-    for (i=0; i<numcols; i++) { 
-      rorg[i] = rcmap[i] = rMap[i];  
-      gorg[i] = gcmap[i] = gMap[i];  
-      borg[i] = bcmap[i] = bMap[i];  
+    for (i=0; i<numcols; i++) {
+      rorg[i] = rcmap[i] = rMap[i];
+      gorg[i] = gcmap[i] = gMap[i];
+      borg[i] = bcmap[i] = bMap[i];
     }
   }
 
@@ -2888,19 +3587,29 @@
 {
   /* cmd is something like: "! bggen 100 0 0"
    *
-   * runs command (with "> /tmp/xv******" appended).  
+   * runs command (with "> /tmp/xv******" appended).
    * returns "/tmp/xv******" in fname
    * returns '0' if everything's cool, '1' on error
    */
 
   char fullcmd[512], tmpname[64], str[512];
   int i;
+#ifndef USE_MKSTEMP
+  int tmpfd;
+#endif
 
   if (!cmd || (strlen(cmd) < (size_t) 2)) return 1;
 
   sprintf(tmpname,"%s/xvXXXXXX", tmpdir);
+#ifdef USE_MKSTEMP
+  close(mkstemp(tmpname));
+#else
   mktemp(tmpname);
-  if (tmpname[0] == '\0') {   /* mktemp() blew up */
+  tmpfd = open(tmpname,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR);
+  if (tmpfd < 0) FatalError("openPic(): can't create temporary file");
+  close(tmpfd);
+#endif
+  if (tmpname[0] == '\0') {   /* mktemp() or mkstemp() blew up */
     sprintf(str,"Unable to create temporary filename.");
     ErrPopUp(str, "\nHow unlikely!");
     return 1;
@@ -2939,26 +3648,21 @@
 {
   int i;
 
+  waitsec = (numnames <= 1)? waitsec_final : waitsec_nonfinal;
+
   if (!numnames) {  openPic(DFLTPIC);  return; }
 
   i = 0;
-  if (!randomShow) {
-    while (numnames>0) {
-      if (openPic(0)) return;  /* success */
-      else {
-	if (polling && !i) 
-	  fprintf(stderr,"%s: POLLING: Waiting for file '%s' \n\tto %s\n",
-		  cmd, namelist[0], "be created, or whatever...");
-	i = 1;
-      }
+  while (numnames>0) {
+    if (openPic(0)) return;  /* success */
+    else {
+      if (polling && !i)
+	fprintf(stderr,"%s: POLLING: Waiting for file '%s' \n\tto %s\n",
+		cmd, namelist[0], "be created, or whatever...");
+      i = 1;
     }
   }
 
-  else {    /* pick random first picture */
-    for (i=findRandomPic();  i>=0;  i=findRandomPic())
-      if (openPic(i)) return;    /* success */
-  }
-
   if (numnames>1) FatalError("couldn't open any pictures");
   else Quit(-1);
 }
@@ -2970,11 +3674,11 @@
   int i;
 
   if (curname>=0) i = curname+1;
-  else if (nList.selected >= 0 && nList.selected < numnames) 
+  else if (nList.selected >= 0 && nList.selected < numnames)
        i = nList.selected;
   else i = 0;
 
- 
+
   while (i<numnames && !openPic(i));
   if (i<numnames) return;    /* success */
 
@@ -2987,19 +3691,15 @@
 {
   int i;
 
-  if (!randomShow) {
-    if (curname>=0) i = curname+1;
-    else if (nList.selected >= 0 && nList.selected < numnames) 
-      i = nList.selected;
-    else i = 0;
+  if (curname>=0) i = curname+1;
+  else if (nList.selected >= 0 && nList.selected < numnames)
+    i = nList.selected;
+  else i = 0;
 
-    while (i<numnames && !openPic(i));
-    if (i<numnames) return;    /* success */
-  }
-  else {
-    for (i=findRandomPic(); i>=0; i=findRandomPic())
-      if (openPic(i)) return;
-  }
+  waitsec = (i == numnames-1)? waitsec_final : waitsec_nonfinal;
+
+  while (i<numnames && !openPic(i));
+  if (i<numnames) return;    /* success */
 
   Quit(0);
 }
@@ -3012,25 +3712,21 @@
 
   j = loop = 0;
   while (1) {
-    if (!randomShow) {
 
-      if (curname>=0) i = curname+1;
-      else if (nList.selected >= 0 && nList.selected < numnames) 
-	i = nList.selected;
-      else i = 0;
+    if (curname>=0) i = curname+1;
+    else if (nList.selected >= 0 && nList.selected < numnames)
+      i = nList.selected;
+    else i = 0;
+
+    if (loop) {  i = 0;   loop = 0; }
 
-      if (loop) {  i = 0;   loop = 0; }
+    waitsec = (i == numnames-1)? waitsec_final : waitsec_nonfinal;
 
-      while (i<numnames && !openPic(i));
-      if (i<numnames) return;
-    }
-    else {
-      for (i=findRandomPic(); i>=0; i=findRandomPic())
-	if (openPic(i)) return;
-    }
+    while (i<numnames && !openPic(i));
+    if (i<numnames) return;
 
     loop = 1;        /* back to top of list */
-    if (j) break;                         /* we're in a 'failure loop' */
+    if (j) break;    /* we're in a 'failure loop' */
     j++;
   }
 
@@ -3044,7 +3740,7 @@
   int i;
 
   if (curname>0) i = curname-1;
-  else if (nList.selected>0 && nList.selected < numnames) 
+  else if (nList.selected>0 && nList.selected < numnames)
     i = nList.selected - 1;
   else i = numnames-1;
 
@@ -3063,64 +3759,24 @@
   openPic(LOADPIC);
 }
 
-
-
-
-/****************/
-static int findRandomPic()
-/****************/
-{
-  static byte *loadList;
-  static int   left_to_load, listLen = -1;
-  int          k;
-  time_t       t;
-
-  /* picks a random name out of the list, and returns it's index.  If there
-     are no more names to pick, it returns '-1' and resets itself */
-
-  if (!loadList || numnames!=listLen) {
-    if (loadList) free(loadList);
-    else {
-      time(&t);
-      srandom((unsigned int) t); /* seed the random */
-    }
-
-    left_to_load = listLen = numnames;
-    loadList = (byte *) malloc((size_t) listLen);
-    for (k=0; k<listLen; k++) loadList[k] = 0;
-  }
-  
-  if (left_to_load <= 0) {   /* we've loaded all the pics */
-    for (k=0; k<listLen; k++) loadList[k] = 0;   /* clear flags */
-    left_to_load = listLen;
-    return -1;   /* 'done' return */
-  }
-
-  for (k=abs(random()) % listLen;  loadList[k];  k = (k+1) % listLen);
-  
-  left_to_load--;
-  loadList[k] = TRUE;
-
-  return k;
-}
-
 /****************/
 static void mainLoop()
 {
-  /* search forward until we manage to display a picture, 
-     then call EventLoop.  EventLoop will eventually return 
+  /* search forward until we manage to display a picture,
+     then call EventLoop.  EventLoop will eventually return
      NEXTPIC, PREVPIC, NEXTQUIT, QUIT, or, if >= 0, a filenum to GOTO */
 
   int i;
 
-  /* if curname<0 (there is no 'current' file), 'Next' means view the 
+  /* if curname<0 (there is no 'current' file), 'Next' means view the
      selected file (or the 0th file, if no selection either), and 'Prev' means
      view the one right before the selected file */
 
-  openFirstPic();   /* find first displayable picture, exit if none */
+  /* find first displayable picture, exit if none */
+  if (!startGrab) openFirstPic();
 
   if (!pic)  {  /* must've opened a text file...  display dflt pic */
-    openPic(DFLTPIC);
+    if (!startGrab) openPic(DFLTPIC);
     if (mainW && !useroot) RaiseTextWindows();
   }
 
@@ -3133,7 +3789,7 @@
     }
 
     else if (i==PREVPIC) {
-      if (curname>0 || (curname<0 && nList.selected>0)) 
+      if (curname>0 || (curname<0 && nList.selected>0))
 	openPrevPic();
     }
 
@@ -3151,7 +3807,7 @@
 
     else if (i==THISNEXT) {  /* open current sel, 'next' until success */
       int j;
-      j = nList.selected;  
+      j = nList.selected;
       if (j<0) j = 0;
       while (j<numnames && !openPic(j));
       if (!pic) openPic(DFLTPIC);
@@ -3169,7 +3825,7 @@
 
 /***********************************/
 static void createMainWindow(geom, name)
-     char *geom, *name;
+     const char *geom, *name;
 {
   XSetWindowAttributes xswa;
   unsigned long        xswamask;
@@ -3195,22 +3851,35 @@
   i = XParseGeometry(geom,&x,&y,&w,&h);
 
   hints.flags = 0;
-  if ((i&XValue || i&YValue)) hints.flags = USPosition;
+  if (i&XValue || i&YValue)
+      hints.flags |= USPosition;
 
-  if (i&XValue && i&XNegative) x = vrWIDE - eWIDE - abs(x);
-  if (i&YValue && i&YNegative) y = vrHIGH - eHIGH - abs(y);
+  hints.win_gravity = NorthWestGravity;
+  if (i&XValue && i&XNegative) {
+    hints.win_gravity = NorthEastGravity;
+    x = vrWIDE - (eWIDE + 2 * bwidth) - x;
+  }
+  if (i&YValue && i&YNegative) {
+    hints.win_gravity = (hints.win_gravity == NorthWestGravity) ?
+      SouthWestGravity : SouthEastGravity;
+    y = vrHIGH - (eHIGH + 2 * bwidth) - y;
+  }
+  hints.flags |= PWinGravity;
 
-  if (x+eWIDE > vrWIDE) x = vrWIDE - eWIDE;   /* keep on screen */
+  /* keep on screen */
+  if (x+eWIDE > vrWIDE) x = vrWIDE - eWIDE;
   if (y+eHIGH > vrHIGH) y = vrHIGH - eHIGH;
-
+  if (x < 0) x = 0;
+  if (y < 0) y = 0;
 
 #define VROOT_TRANS
 #ifdef VROOT_TRANS
-  if (vrootW != rootW) { /* virtual window manager running */
+  if (vrootW != rootW && !(hints.flags & USPosition)) { /* virtual window manager running */
     int x1,y1;
     Window child;
+
     XTranslateCoordinates(theDisp, rootW, vrootW, x, y, &x1, &y1, &child);
-    if (DEBUG) fprintf(stderr,"translate:  %d,%d -> %d,%d\n",x,y,x1,y1);
+    if (DEBUG) fprintf(stderr,"translate:  %d,%d -> %d,%d\n", x, y, x1, y1);
     x = x1;  y = y1;
   }
 #endif
@@ -3218,13 +3887,13 @@
   hints.x = x;                  hints.y = y;
   hints.width = eWIDE;          hints.height = eHIGH;
   hints.max_width  = maxWIDE;   hints.max_height = maxHIGH;
-  hints.flags |= USSize | PMaxSize;
-    
-  xswa.bit_gravity = StaticGravity;
+  hints.flags |= PSize | PMaxSize;
+
+  xswa.bit_gravity      = StaticGravity;
   xswa.background_pixel = bg;
   xswa.border_pixel     = fg;
   xswa.colormap         = theCmap;
-  
+
   xswa.backing_store    = WhenMapped;
 
   /* NOTE: I've turned 'backing-store' off on the image window, as some
@@ -3233,9 +3902,9 @@
      improvement anyway (for the image window), unless you're on a slow
      network.  In any event, I'm not *turning off* backing store, I'm
      just not explicitly turning it *on*.  If your X server is set up
-     that windows, by default, have backing-store turned on, then the 
+     that windows, by default, have backing-store turned on, then the
      image window will, too */
-  
+
   xswamask = CWBackPixel | CWBorderPixel | CWColormap /* | CWBackingStore */;
   if (!clearonload) xswamask |= CWBitGravity;
 
@@ -3244,18 +3913,18 @@
     xwa.width = eWIDE;  xwa.height = eHIGH;
 
     /* try to keep the damned thing on-screen, if possible */
-    if (xwa.x + xwa.width  > dispWIDE) xwa.x = dispWIDE - xwa.width;
-    if (xwa.y + xwa.height > dispHIGH) xwa.y = dispHIGH - xwa.height;
+    if (xwa.x + xwa.width  > vrWIDE) xwa.x = vrWIDE - xwa.width;
+    if (xwa.y + xwa.height > vrHIGH) xwa.y = vrHIGH - xwa.height;
     if (xwa.x < 0) xwa.x = 0;
     if (xwa.y < 0) xwa.y = 0;
 
     SetWindowPos(&xwa);
     hints.flags = PSize | PMaxSize;
-  } 
+  }
 
   else {
     mainW = XCreateWindow(theDisp,rootW,x,y, (u_int) eWIDE, (u_int) eHIGH,
-			  (u_int) bwidth, (int) dispDEEP, InputOutput, 
+			  (u_int) bwidth, (int) dispDEEP, InputOutput,
 			  theVisual, xswamask, &xswa);
     if (!mainW) FatalError("can't create window!");
 
@@ -3267,15 +3936,11 @@
     }
   }
 
-
-  XSetStandardProperties(theDisp,mainW,"","",None,NULL,0,&hints);
-  setWinIconNames(name);
-
   xwmh.input = True;
   xwmh.flags = InputHint;
 
-  xwmh.icon_pixmap = iconPix;  
-  xwmh.icon_mask   = iconmask;  
+  xwmh.icon_pixmap = iconPix;
+  xwmh.icon_mask   = iconmask;
   xwmh.flags |= (IconPixmapHint | IconMaskHint);
 
 
@@ -3295,14 +3960,15 @@
       }
     }
   }
-  XSetWMHints(theDisp, mainW, &xwmh);
 
   classh.res_name = "xv";
   classh.res_class = "XVroot";
-  XSetClassHint(theDisp, mainW, &classh);
 
+  XmbSetWMProperties(theDisp, mainW, NULL, NULL, NULL, 0, &hints, &xwmh,
+                     &classh);
+  setWinIconNames(name);
 
-  if (nodecor) {   /* turn of image window decorations (in MWM) */ 
+  if (nodecor) {   /* turn of image window decorations (in MWM) */
     Atom mwm_wm_hints;
     struct s_mwmhints {
       long   flags;
@@ -3311,7 +3977,7 @@
       u_long input_mode;
       long   status;
     } mwmhints;
-    
+
     mwm_wm_hints = XInternAtom(theDisp, "_MOTIF_WM_HINTS", False);
     if (mwm_wm_hints != None) {
       xvbzero((char *) &mwmhints, sizeof(mwmhints));
@@ -3319,20 +3985,20 @@
       mwmhints.decorations = 4;
 
       XChangeProperty(theDisp, mainW, mwm_wm_hints, mwm_wm_hints, 32,
-		      PropModeReplace, (byte *) &mwmhints, 
-		      (int) (sizeof(mwmhints))/4); 
+		      PropModeReplace, (byte *) &mwmhints,
+		      (int) (sizeof(mwmhints))/4);
       XSync(theDisp, False);
     }
   }
 
-    
+
   firstTime = 0;
 }
 
 
 /***********************************/
 static void setWinIconNames(name)
-     char *name;
+     const char *name;
 {
   char winname[256], iconname[256];
 
@@ -3362,12 +4028,12 @@
 
 /***********************************/
 void FixAspect(grow,w,h)
-int   grow;
-int   *w, *h;
+     int   grow;
+     int   *w, *h;
 {
   /* computes new values of eWIDE and eHIGH which will have aspect ratio
-     'normaspect'.  If 'grow' it will preserve aspect by enlarging, 
-     otherwise, it will shrink to preserve aspect ratio.  
+     'normaspect'.  If 'grow' it will preserve aspect by enlarging,
+     otherwise, it will shrink to preserve aspect ratio.
      Returns these values in 'w' and 'h' */
 
   float xr,yr,curaspect,a,exp;
@@ -3380,14 +4046,14 @@
   curaspect  = xr / yr;
 
   /* if too narrow & shrink, shrink height.  too wide and grow, grow height */
-  if ((curaspect < normaspect && !grow) || 
+  if ((curaspect < normaspect && !grow) ||
       (curaspect > normaspect &&  grow)) {    /* modify height */
     exp = curaspect / normaspect;
     *h = (int) (eHIGH * exp + .5);
   }
 
   /* if too narrow & grow, grow width.  too wide and shrink, shrink width */
-  if ((curaspect < normaspect &&  grow) || 
+  if ((curaspect < normaspect &&  grow) ||
       (curaspect > normaspect && !grow)) {    /* modify width */
     exp = normaspect / curaspect;
     *w = (int) (eWIDE * exp + .5);
@@ -3423,22 +4089,22 @@
   suffix = namelist[0];
   prelen = 0;   /* length of prefix to be removed */
   n = i = 0;    /* shut up pesky compiler warnings */
-  
+
   done = 0;
   while (!done) {
     suffix = (char *) index(suffix,'/');    /* find next '/' in file name */
     if (!suffix) break;
-    
+
     suffix++;                       /* go past it */
     n = suffix - namelist[0];
     for (i=1; i<numnames; i++) {
       if (strncmp(namelist[0], namelist[i], (size_t) n)!=0) { done=1; break; }
     }
-    
+
     if (!done) prelen = n;
   }
-  
-  for (i=0; i<numnames; i++) 
+
+  for (i=0; i<numnames; i++)
     dispnames[i] = namelist[i] + prelen;
 }
 
@@ -3447,20 +4113,20 @@
 static void fixDispNames()
 {
   /* fix dispnames array so that names don't go off right edge */
-  
+
   int   i,j;
   char *tmp;
-  
+
   for (i=j=0; i<numnames; i++) {
     char *dname;
-    
+
     dname = dispnames[i];
     if (StringWidth(dname) > (nList.w-10-16)) {  /* have to trunc. */
       tmp = dname;
       while (1) {
 	tmp = (char *) index(tmp,'/'); /* find next '/' in filename */
 	if (!tmp) { tmp = dname;  break; }
-	
+
 	tmp++;                   /* move to char following the '/' */
 	if (StringWidth(tmp) <= (nList.w-10-16)) { /* is cool now */
 	  j++;  break;
@@ -3484,9 +4150,9 @@
 
   name = GetDirFName();
   GetDirPath(cwd);
-  
+
   AddFNameToCtrlList(cwd, name);
-  
+
   if (select) {
     nList.selected = numnames-1;
     curname = numnames - 1;
@@ -3498,35 +4164,35 @@
 
 /***********************************/
 void AddFNameToCtrlList(fpath,fname)
-     char *fpath, *fname;
+     const char *fpath, *fname;
 {
   /* stick given path/name into 'namelist'.  Doesn't redraw list */
-  
-  char *fullname, *dname;
+
+  char *fullname;
   char cwd[MAXPATHLEN], globnm[MAXPATHLEN+100];
   int i;
-  
+
   if (!fpath) fpath = "";  /* bulletproofing... */
-  if (!fname) fname = "";  
-  
+  if (!fname) fname = "";
+
   if (numnames == MAXNAMES) return;  /* full up */
-  
+
   /* handle globbing */
   if (fname[0] == '~') {
     strcpy(globnm, fname);
     Globify(globnm);
     fname = globnm;
   }
-  
+
   if (fname[0] != '/') {  /* prepend path */
     strcpy(cwd, fpath);   /* copy it to a modifiable place */
-    
+
     /* make sure fpath has a trailing '/' char */
     if (strlen(cwd)==0 || cwd[strlen(cwd)-1]!='/') strcat(cwd, "/");
-    
+
     fullname = (char *) malloc(strlen(cwd) + strlen(fname) + 2);
     if (!fullname) FatalError("couldn't alloc name in AddFNameToCtrlList()\n");
-    
+
     sprintf(fullname, "%s%s", cwd, fname);
   }
   else {                 /* copy name to fullname */
@@ -3534,15 +4200,15 @@
     if (!fullname) FatalError("couldn't alloc name in AddFNameToCtrlList()\n");
     strcpy(fullname, fname);
   }
-  
-  
+
+
   /* see if this name is a duplicate.  Don't add it if it is. */
   for (i=0; i<numnames; i++)
     if (strcmp(fullname, namelist[i]) == 0) {
       free(fullname);
       return;
     }
-  
+
   namelist[numnames] = fullname;
   numnames++;
   makeDispNames();
@@ -3578,7 +4244,7 @@
   /* called to enable/disable the Prev/Next buttons whenever curname and/or
      numnames and/or nList.selected change */
 
-  /* if curname<0 (there is no 'current' file), 'Next' means view the 
+  /* if curname<0 (there is no 'current' file), 'Next' means view the
      selected file (or the 0th file, if no selection either), and 'Prev' means
      view the one right before the selected file */
 
@@ -3591,18 +4257,19 @@
     BTSetActive(&but[BPREV], (curname>0));
   }
 }
-  
+
 
 /***********************************/
 int DeleteCmd()
 {
   /* 'delete' button was pressed.  Pop up a dialog box to determine
      what should be deleted, then do it.
-     returns '1' if THE CURRENTLY VIEWED entry was deleted from the list, 
-     in which case the 'selected' filename on the ctrl list is now 
+     returns '1' if THE CURRENTLY VIEWED entry was deleted from the list,
+     in which case the 'selected' filename on the ctrl list is now
      different, and should be auto-loaded, or something */
 
-  static char *bnames[] = { "\004Disk File", "\nList Entry", "\033Cancel" };
+  static const char *bnames[] =
+    { "\004Disk File", "\nList Entry", "\033Cancel" };
   char str[512];
   int  del, i, delnum, rv;
 
@@ -3610,15 +4277,14 @@
   delnum = nList.selected;
   if (delnum < 0 || delnum >= numnames) return 0;
 
-  sprintf(str,"Delete '%s'?\n\n%s%s",
-	  namelist[delnum],
+  sprintf(str, "Delete '%s'?\n\n%s%s", namelist[delnum],
 	  "'List Entry' deletes selection from list.\n",
 	  "'Disk File' deletes file associated with selection.");
 
   del = PopUp(str, bnames, 3);
-  
+
   if (del == 2) return 0;   /* cancel */
-  
+
   if (del == 0) {           /* 'Disk File' */
     char *name;
     if (namelist[delnum][0] != '/') {    /* prepend 'initdir' */
@@ -3669,13 +4335,13 @@
 
   if (delnum != numnames-1) {
     /* snip out of namelist and dispnames lists */
-    xvbcopy((char *) &namelist[delnum+1], (char *) &namelist[delnum], 
+    xvbcopy((char *) &namelist[delnum+1], (char *) &namelist[delnum],
 	  (numnames - delnum - 1) * sizeof(namelist[0]));
 
-    xvbcopy((char *) &dispnames[delnum+1], (char *) &dispnames[delnum], 
+    xvbcopy((char *) &dispnames[delnum+1], (char *) &dispnames[delnum],
 	  (numnames - delnum - 1) * sizeof(dispnames[0]));
   }
-  
+
   numnames--;
   if (numnames==0) BTSetActive(&but[BDELETE],0);
   windowMB.dim[WMB_TEXTVIEW] = (numnames==0);
@@ -3686,7 +4352,7 @@
   if (nList.selected >= numnames) nList.selected = numnames-1;
   if (nList.selected < 0) nList.selected = 0;
 
-  SCSetRange(&nList.scrl, 0, numnames - nList.nlines, 
+  SCSetRange(&nList.scrl, 0, numnames - nList.nlines,
 	     nList.scrl.val, nList.nlines-1);
   ScrollToCurrent(&nList);
   DrawCtrlNumFiles();
@@ -3753,7 +4419,7 @@
     if (useroot && resetroot) ClearRoot();
 
     if (mainW == (Window) NULL || useroot) {  /* window not visible */
-      useroot = 0;  
+      useroot = 0;
 
       if (haveoldinfo) {             /* just remap mainW and resize it */
 	XWMHints xwmh;
@@ -3771,8 +4437,8 @@
 	xwmh.input = True;
 	xwmh.flags = InputHint;
 
-	xwmh.icon_pixmap = iconPix;  
-	xwmh.icon_mask   = iconmask;  
+	xwmh.icon_pixmap = iconPix;
+	xwmh.icon_mask   = iconmask;
 	xwmh.flags |= ( IconPixmapHint | IconMaskHint) ;
 
 	xwmh.flags |= StateHint;
@@ -3787,7 +4453,7 @@
       else {                         /* first time.  need to create mainW */
 	mainW = (Window) NULL;
 	createMainWindow(maingeom, fnam);
-	XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
+	XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask
 		     | StructureNotifyMask | ButtonPressMask
 		     | KeyReleaseMask | ColormapChangeMask
 		     | EnterWindowMask | LeaveWindowMask );
@@ -3802,7 +4468,7 @@
 
     else {                            /* mainW already visible */
       createMainWindow(maingeom, fnam);
-      XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
+      XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask
 		   | StructureNotifyMask | ButtonPressMask
 		   | KeyReleaseMask | ColormapChangeMask
 		   | EnterWindowMask | LeaveWindowMask );
@@ -3845,13 +4511,13 @@
       if (LocalCmap) regen=1;
 
       /* this reallocs the colors */
-      if (colorMapMode==CM_PERFECT || colorMapMode==CM_OWNCMAP) 
+      if (colorMapMode==CM_PERFECT || colorMapMode==CM_OWNCMAP)
 	ChangeCmapMode(CM_NORMAL, 0, 0);
-      
-      
+
+
       XUnmapWindow(theDisp, mainW);
       mainW = vrootW;
-      
+
       if (!ctrlUp) {    /* make sure ctrl is up when going to 'root' mode */
 	XWMHints xwmh;
 	xwmh.input         = True;
@@ -3861,7 +4527,7 @@
 	CtrlBox(1);
       }
     }
-      
+
     useroot = 1;
     rootMode = dispMode - RMB_ROOT;
     ew = eWIDE;  eh = eHIGH;
@@ -3877,7 +4543,7 @@
       GenerateEpic(ew, eh);
       CreateXImage();
     }
-    else if (regen) CreateXImage();                    
+    else if (regen) CreateXImage();
 
     KillOldRootInfo();
     MakeRootPic();
@@ -3923,7 +4589,7 @@
 
 
   if (*numn == maxn) {
-    fprintf(stderr, "%s: too many filenames.  Only using first %d.\n",
+    fprintf(stderr, "%s: too many filenames.  Using only first %d.\n",
 	    flist, maxn);
   }
 
@@ -3947,14 +4613,14 @@
 
 /***********************************/
 int rd_int(name)
-     char *name;
+     const char *name;
 {
   /* returns '1' if successful.  result in def_int */
 
   if (rd_str_cl(name, "", 0)) {     /* sets def_str */
     if (sscanf(def_str, "%d", &def_int) == 1) return 1;
     else {
-      fprintf(stderr, "%s: couldn't read integer value for %s resource\n", 
+      fprintf(stderr, "%s: couldn't read integer value for %s resource\n",
 	      cmd, name);
       return 0;
     }
@@ -3965,7 +4631,7 @@
 
 /***********************************/
 int rd_str(name)
-     char *name;
+     const char *name;
 {
   return rd_str_cl(name, "", 0);
 }
@@ -3973,17 +4639,17 @@
 
 /***********************************/
 int rd_flag(name)
-char *name;
+     const char *name;
 {
   /* returns '1' if successful.  result in def_int */
-  
+
   char buf[256];
 
   if (rd_str_cl(name, "", 0)) {  /* sets def_str */
     strcpy(buf, def_str);
     lower_str(buf);
 
-    def_int = (strcmp(buf, "on")==0) || 
+    def_int = (strcmp(buf, "on")==0) ||
               (strcmp(buf, "1")==0) ||
 	      (strcmp(buf, "true")==0) ||
 	      (strcmp(buf, "yes")==0);
@@ -3992,16 +4658,16 @@
 
   else return 0;
 }
-    
+
 
 
 
 static int xrm_initted = 0;
- 
+
 /***********************************/
 int rd_str_cl (name_str, class_str, reinit)
-     char *name_str;
-     char *class_str;
+     const char *name_str;
+     const char *class_str;
      int  reinit;
 {
   /* note: *all* X resource reading goes through this routine... */
@@ -4043,16 +4709,30 @@
       unsigned long nitems, nleft;
       byte *data;
 
-      i = XGetWindowProperty(theDisp, RootWindow(theDisp, 0),
-			     resAtom, 0L, 1L, False, 
-			     XA_STRING, &actType, &actFormat, &nitems, &nleft, 
-			     (unsigned char **) &data);
+      if (spec_window) {
+        i = XGetWindowProperty(theDisp, spec_window,
+			       resAtom, 0L, 1L, False,
+			       XA_STRING, &actType, &actFormat, &nitems, &nleft,
+			       (unsigned char **) &data);
+      } else {
+        i = XGetWindowProperty(theDisp, RootWindow(theDisp, 0),
+			       resAtom, 0L, 1L, False,
+			       XA_STRING, &actType, &actFormat, &nitems, &nleft,
+			       (unsigned char **) &data);
+      }
       if (i==Success && actType==XA_STRING && actFormat==8) {
 	if (nitems>0 && data) XFree(data);
-	i = XGetWindowProperty(theDisp, RootWindow(theDisp, 0), resAtom, 0L, 
-			       (long) ((nleft+4+3)/4),
-			       False, XA_STRING, &actType, &actFormat, 
-			       &nitems, &nleft, (unsigned char **) &data);
+        if (spec_window) {
+	  i = XGetWindowProperty(theDisp, spec_window, resAtom, 0L,
+			         (long) ((nleft+4+3)/4),
+			         False, XA_STRING, &actType, &actFormat,
+			         &nitems, &nleft, (unsigned char **) &data);
+        } else {
+	  i = XGetWindowProperty(theDisp, RootWindow(theDisp, 0), resAtom, 0L,
+			         (long) ((nleft+4+3)/4),
+			         False, XA_STRING, &actType, &actFormat,
+			         &nitems, &nleft, (unsigned char **) &data);
+        }
 	if (i==Success && actType==XA_STRING && actFormat==8 && data) {
 	  def_resource = XrmGetStringDatabase((char *) data);
 	  XFree(data);
@@ -4064,50 +4744,51 @@
 
 
     if (!gotit) {
-      xrm_str = XResourceManagerString(theDisp); 
-      
+      xrm_str = XResourceManagerString(theDisp);
+
       if (xrm_str) {
 	def_resource = XrmGetStringDatabase(xrm_str);
 	if (DEBUG) fprintf(stderr,"rd_str_cl: Using RESOURCE_MANAGER prop.\n");
       }
       else {    /* no RESOURCE_MANAGER prop.  read from 'likely' file */
-	char foo[256], *homedir, *xenviron;
+	char foo[256], *xenviron;
+	const char *homedir;
 	XrmDatabase res1;
-	
+
 #ifdef VMS
 	strcpy(foo, "SYS$LOGIN:DECW$XDEFAULTS.DAT");
 #else
-	homedir = (char *) getenv("HOME");
+	homedir = (const char *) getenv("HOME");
 	if (!homedir) homedir = ".";
 	sprintf(foo,"%s/.Xdefaults", homedir);
 #endif
-	
+
 	def_resource = XrmGetFileDatabase(foo);
-	
+
 	if (DEBUG) {
 	  fprintf(stderr,"rd_str_cl: No RESOURCE_MANAGER prop.\n");
 	  fprintf(stderr,"rd_str_cl: Using file '%s' (%s)  ",
 		  foo, (def_resource) ? "success" : "failure");
 	}
-	
-	
+
+
 	/* merge file pointed to by XENVIRONMENT */
 	xenviron = (char *) getenv("XENVIRONMENT");
 	if (xenviron) {
 	  res1 = XrmGetFileDatabase(xenviron);
-	  
+
 	  if (DEBUG) {
 	    fprintf(stderr,"merging XENVIRONMENT='%s' (%s)  ",
 		    xenviron, (res1) ? "success" : "failure");
 	  }
-	  
+
 	  if (res1) {    /* merge databases */
 	    if (!def_resource) def_resource = res1;
 	    else XrmMergeDatabases(res1, &def_resource);
 	  }
 	}
-	
-	
+
+
 	if (DEBUG) fprintf(stderr,"\n\n");
       }
     }
@@ -4120,16 +4801,15 @@
   strcpy (q_name, PROGNAME);
   strcat (q_name, ".");
   strcat (q_name, name_str);
-  
+
   strcpy (q_class, "Program");
   strcat (q_class, ".");
   strcat (q_class, class_str);
 
   (void) XrmGetResource(def_resource, q_name, q_class, &type, &result);
-  
+
   def_str = result.addr;
-  if (def_str) return (1);
-  else return (0);
+  if (def_str) return 1;
+  else return 0;
 }
 
-
diff -ru xv-3.10a/xv.h xv-3.10a-enhancements/xv.h
--- xv-3.10a/xv.h	1995-01-23 12:22:23.000000000 -0800
+++ xv-3.10a-enhancements/xv.h	2007-05-20 21:26:40.000000000 -0700
@@ -1,6 +1,6 @@
 /*
  *  xv.h  -  header file for xv, but you probably guessed as much
- * 
+ *
  *  Author:    John Bradley  (bradley@cis.upenn.edu)
  */
 
@@ -8,8 +8,16 @@
 #include "config.h"
 
 
-#define REVDATE   "Version 3.10a  Rev: 12/29/94"
-#define VERSTR    "3.10a"
+/* xv 3.10a:				19941229 */
+/* PNG patch 1.2d:			19960731 */
+/* GRR orig jumbo fixes patch:		20000213 */
+/* GRR orig jumbo enhancements patch:	20000220 */
+/* GRR 1st public jumbo F+E patches:	20040531 */
+/* GRR 2nd public jumbo F+E patches:	20050410 */
+/* GRR 3rd public jumbo F+E patches:	20050501 */
+/* GRR 4th public jumbo F+E patch:  	20070520 */
+#define REVDATE   "version 3.10a-jumboFix+Enh of 20070520"
+#define VERSTR    "3.10a-20070520"
 
 /*
  * uncomment the following, and modify for your site, but only if you've
@@ -43,6 +51,10 @@
 /* START OF MACHINE-DEPENDENT CONFIGURATION INFO */
 /*************************************************/
 
+
+#define ENABLE_FIXPIX_SMOOTH	/* GRR 19980607 */
+
+
 /* Things to make xv more likely to just build, without the user tweaking
    the makefile */
 
@@ -61,16 +73,38 @@
 #  define SVR4
 #endif
 
+#if defined(__sony_news) && defined(bsd43) && !defined(__bsd43)
+#  define __bsd43
+#elif defined(__sony_news) && (defined(SYSTYPE_BSD) || defined(__SYSTYPE_BSD)) && !defined(bsd43) && !defined(__bsd43)
+#  define bsd43
+#  define __bsd43
+#endif
+
+#include <signal.h>      /* for interrupt handling */
+
+/* at least on Linux, the following file (1) includes sys/types.h and
+ * (2) defines __USE_BSD (which was not defined before here), so __linux__
+ * block is now moved after this #include */
+#include <X11/Xos.h>     /* need type declarations immediately */
+
 
-#ifdef LINUX
+#ifdef __linux__
 #  ifndef _LINUX_LIMITS_H
 #    include <linux/limits.h>
 #  endif
+#  ifndef USLEEP
+#    define USLEEP
+#  endif
+   /* want only one or the other defined, not both: */
+#  if !defined(BSDTYPES) && !defined(__USE_BSD)
+#    define BSDTYPES
+#  endif
+#  if defined(BSDTYPES) && defined(__USE_BSD)
+#    undef BSDTYPES
+#  endif
 #endif
 
 
-#include <X11/Xos.h>     /* need type declarations immediately */
-
 /*********************************************************/
 
 
@@ -99,6 +133,16 @@
 #endif
 
 
+#if defined(__sony_news) && defined(__bsd43)
+#  include <unistd.h>
+#endif
+
+
+#if defined(__FreeBSD__)
+#  include <sys/param.h>
+#endif
+
+
 /* include files */
 #include <stdio.h>
 #include <math.h>
@@ -114,18 +158,24 @@
 
 #ifndef VMS
 #  include <errno.h>
-   extern int   errno;             /* SHOULD be in errno.h, but often isn't */
 #  ifndef __NetBSD__
-     extern char *sys_errlist[];     /* this too... */
+#    if !(defined __GLIBC__ && __GLIBC__ >= 2)
+       extern int   errno;         /* SHOULD be in errno.h, but often isn't */
+       extern char *sys_errlist[]; /* this too... */
+#    endif
 #  endif
 #endif
 
 
 /* not everyone has the strerror() function, or so I'm told */
-#ifndef VMS
-#  define ERRSTR(x) sys_errlist[x]
-#else
+#ifdef VMS
 #  define ERRSTR(x) strerror(x, vaxc$errno)
+#else
+#  if defined(__BEOS__) || defined(__linux__) /* or all modern/glibc systems? */
+#    define ERRSTR(x) strerror(x)
+#  else
+#    define ERRSTR(x) sys_errlist[x]
+#  endif
 #endif
 
 
@@ -146,28 +196,20 @@
 #endif
 
 
-/* lots of things don't have <malloc.h> */
-/* A/UX systems include it from stdlib, from Xos.h */
-#ifndef VMS   /* VMS hates multi-line '#if's */
-# if !defined(ibm032)                    && \
-     !defined(__convex__)                && \
-     !(defined(vax) && !defined(ultrix)) && \
-     !defined(mips)                      && \
-     !defined(apollo)                    && \
-     !defined(pyr)                       && \
-     !defined(__UMAXV__)                 && \
-     !defined(bsd43)                     && \
-     !defined(aux)                       && \
-     !defined(__bsdi__)                  && \
-     !defined(sequent)
-
+/* GRR 20070512:  Very few modern systems even have a malloc.h anymore;
+ *                stdlib.h is, well, the standard.  (Former explicitly listed
+ *                "don't include" systems:  ibm032, __convex__, non-ultrix vax,
+ *                mips, apollo, pyr, sequent, __UMAXV__, aux, bsd43, __bsd43,
+ *                __bsdi__, __386BSD__, __FreeBSD__, __OpenBSD__, __NetBSD__,
+ *                __DARWIN__, VMS.)  Anyone who _does_ need it can explicitly
+ *                define NEED_MALLOC_H in the makefile. */
+#ifdef NEED_MALLOC_H
 #  if defined(hp300) || defined(hp800) || defined(NeXT)
-#   include <sys/malloc.h>                /* it's in 'sys' on HPs and NeXT */
+#    include <sys/malloc.h>    /* it's in "sys" on HPs and NeXT */
 #  else
-#   include <malloc.h>
+#    include <malloc.h>
 #  endif
-# endif
-#endif /* !VMS */
+#endif
 
 
 
@@ -179,9 +221,10 @@
 #include <X11/Xatom.h>
 #include <X11/Xmd.h>
 
+#ifdef TV_L10N
+#  include <X11/Xlocale.h>
+#endif
 
-#undef SIGCHLD           /* defined in both Xos.h and signal.h */
-#include <signal.h>      /* for interrupt handling */
 
 #include <sys/types.h>
 
@@ -205,6 +248,10 @@
 #    include <limits.h>
 #  endif
 
+#  ifdef __BEOS__
+#    include <socket.h>
+#  endif
+
 /*** for select() call ***/
 #  ifdef __hpux
 #    define XV_FDTYPE (int *)
@@ -259,7 +306,7 @@
  * make them if missing, along with a few fictitious ones
  *      Cameron Simpson  (cameron@cse.unsw.edu.au)
  */
- 
+
 #ifndef         S_ISDIR         /* missing POSIX-type macros */
 #  define       S_ISDIR(mode)   (((mode)&S_IFMT) == S_IFDIR)
 #  define       S_ISBLK(mode)   (((mode)&S_IFMT) == S_IFBLK)
@@ -288,7 +335,9 @@
 #  endif
 #endif
 
-
+#ifndef S_IRWUSR
+#  define S_IRWUSR	(S_IRUSR|S_IWUSR)	/* or (S_IREAD|S_IWRITE) */
+#endif
 
 #ifndef MAXPATHLEN
 #  define MAXPATHLEN 256
@@ -308,36 +357,90 @@
 
 #ifndef VMS       /* VMS hates multi-line definitions */
 #  if defined(SVR4)  || defined(SYSV) || defined(sco) || \
-      defined(XENIX) || defined(__osf__) 
+      defined(XENIX) || defined(__osf__) || defined(__linux__)
 #    undef  USE_GETCWD
 #    define USE_GETCWD          /* use 'getcwd()' instead of 'getwd()' */
+#  endif                        /* >> SECURITY ISSUE << */
+#endif
+
+
+/* GRR 20040430:  This is new and still not fully deployed.  No doubt there
+ *                are other systems that have mkstemp() (SUSv3); we can add
+ *                them later. */
+#ifndef VMS       /* VMS hates multi-line definitions */
+#  if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
+      defined(__bsdi__)
+#    ifndef USE_MKSTEMP
+#      define USE_MKSTEMP       /* use 'mkstemp()' instead of 'mktemp()' */
+#    endif                      /* >> SECURITY ISSUE << */
 #  endif
 #endif
 
 
+/* GRR 20040503:  This is new and so far tested only under Linux.  But it
+ *                allows -wait to work with subsecond values as long as
+ *                times() exists and clock_t is a long int (latter matters
+ *                only if/when clocks wrap, which for Linux is multiples of
+ *                497.11 days since the last reboot). */
+#if defined(__linux__)
+#  define USE_TICKS             /* use times()/Timer(), not time()/sleep() */
+#  include <limits.h>           /* LONG_MAX (really want CLOCK_T_MAX) */
+#  include <sys/times.h>        /* times() */
+#  ifndef CLK_TCK               /* can be undefined in strict-ANSI mode */
+#    define CLK_TCK CLOCKS_PER_SEC   /* claimed to be same thing in time.h */
+#  endif
+#endif
+
+#if (defined(SYSV) || defined(SVR4) || defined(linux)) && !defined(USE_GETCWD)
+#  define USE_GETCWD
+#endif
+
+#ifndef SEEK_SET
+#  define SEEK_SET 0
+#  define SEEK_CUR 1
+#  define SEEK_END 2
+#endif
+
+#if defined(__mips) && defined(__SYSTYPE_BSD43)
+#  define strstr(A,B) pds_strstr((A),(B))
+#  undef S_IFIFO
+#endif /* !mips_bsd */
+
 /*****************************/
 /* END OF CONFIGURATION INFO */
 /*****************************/
 
+
 #ifdef DOJPEG
-#define HAVE_JPEG
+#  define HAVE_JPEG
+#endif
+
+#ifdef DOJP2K
+#  define HAVE_JP2K
 #endif
 
 #ifdef DOTIFF
-#define HAVE_TIFF
+#  define HAVE_TIFF
+#endif
+
+#ifdef DOPNG
+#  define HAVE_PNG
 #endif
 
 #ifdef DOPDS
-#define HAVE_PDS
+#  define HAVE_PDS
 #endif
 
+#ifdef DOG3
+#  define HAVE_G3
+#endif
 
 
-#define PROGNAME  "xv"             /* used in resource database */
+#define PROGNAME   "xv"            /* used in resource database */
 
-#define MAXNAMES 4096              /* max # of files in ctrlW list */
+#define MAXNAMES   65536           /* max # of files in ctrlW list */
 
-#define MAXBRWIN   4               /* max # of vis browser windows */
+#define MAXBRWIN   16              /* max # of vis browser windows */
 
 /* strings in the INFOBOX (used in SetISTR and GetISTR) */
 #define NISTR         10    /* number of ISTRs */
@@ -432,7 +535,7 @@
 #define F_COLORS    0
 #define F_FORMAT    1
 
-/* the following list give indicies into saveColors[] array in xvdir.c */
+/* the following list give indices into saveColors[] array in xvdir.c */
 #define F_FULLCOLOR 0
 #define F_GREYSCALE 1
 #define F_BWDITHER  2
@@ -440,49 +543,115 @@
 #define F_MAXCOLORS 4   /* length of saveColors[] array */
 
 
-/* following list gives indicies into 'saveFormats[]' array in xvdir.c
-   note that JPEG and TIFF entries may or may not exist, and following
-   constants have to be adjusted accordingly.  Also, don't worry about 
-   duplicate cases if JPGINC or TIFINC = 0.  All code that references
-   F_JPEG or F_TIFF is #ifdef'd, so it won't be a problem */
+/* The following list gives indices into 'saveFormats[]' array in xvdir.c.
+   Note that JPEG, TIFF, and other entries may or may not exist, so the
+   following constants have to be adjusted accordingly.  Also, don't worry
+   about duplicate cases if, e.g., JPGINC or TIFINC = 0.  All code that
+   references F_JPEG, F_TIFF, etc., is #ifdef'd, so it won't be a problem. */
 
 #ifdef HAVE_JPEG
-#define F_JPGINC  1
+#  define F_JPGINC  1
 #else
-#define F_JPGINC  0
+#  define F_JPGINC  0
+#endif
+
+#ifdef HAVE_JP2K
+#  define F_JP2INC  1   /* provides both JPC and JP2 */
+#else
+#  define F_JP2INC  0
 #endif
 
 #ifdef HAVE_TIFF
-#define F_TIFINC  1
+#  define F_TIFINC  1
+#else
+#  define F_TIFINC  0
+#endif
+
+#ifdef HAVE_PNG
+#  define F_PNGINC  1
+#else
+#  define F_PNGINC  0
+#endif
+
+#ifdef HAVE_MAG
+#  define F_MAGINC  1
+#else
+#  define F_MAGINC  0
+#endif
+
+#ifdef HAVE_PIC
+#  define F_PICINC  1
+#else
+#  define F_PICINC  0
+#endif
+
+#ifdef HAVE_MAKI
+#  define F_MAKINC  1
+#else
+#  define F_MAKINC  0
+#endif
+
+#ifdef HAVE_PI
+#  define F_PAIINC  1
+#else
+#  define F_PAIINC  0
+#endif
+
+#ifdef HAVE_PIC2
+#  define F_PC2INC  1
 #else
-#define F_TIFINC  0
+#  define F_PC2INC  0
 #endif
 
+#ifdef HAVE_MGCSFX
+#  define F_MGCSFXINC  1
+#else
+#  define F_MGCSFXINC  0
+#endif
 
-#define F_GIF         0
-#define F_JPEG      ( 0 + F_JPGINC)
-#define F_TIFF      ( 0 + F_JPGINC + F_TIFINC)
-#define F_PS        ( 1 + F_JPGINC + F_TIFINC)
-#define F_PBMRAW    ( 2 + F_JPGINC + F_TIFINC)
-#define F_PBMASCII  ( 3 + F_JPGINC + F_TIFINC)
-#define F_XBM       ( 4 + F_JPGINC + F_TIFINC)
-#define F_XPM       ( 5 + F_JPGINC + F_TIFINC)
-#define F_BMP       ( 6 + F_JPGINC + F_TIFINC)
-#define F_SUNRAS    ( 7 + F_JPGINC + F_TIFINC)
-#define F_IRIS      ( 8 + F_JPGINC + F_TIFINC)
-#define F_TARGA     ( 9 + F_JPGINC + F_TIFINC)
-#define F_FITS      (10 + F_JPGINC + F_TIFINC)
-#define F_PM        (11 + F_JPGINC + F_TIFINC)
-#define F_DELIM1    (12 + F_JPGINC + F_TIFINC)     /* ----- */
-#define F_FILELIST  (13 + F_JPGINC + F_TIFINC)
-#define F_MAXFMTS   (14 + F_JPGINC + F_TIFINC)     /* 15, normally */
+#ifdef MACBINARY
+#  define MACBSIZE 128
+#endif
+
+/* NOTE:  order must match saveFormats[] in xvdir.c */
+/* [this works best when first one is always present, but...we like PNG :-) ] */
+#define F_PNG         0
+#define F_JPEG      ( 0 + F_PNGINC)
+#define F_JPC       ( 0 + F_PNGINC + F_JPGINC)
+#define F_JP2       ( 0 + F_PNGINC + F_JPGINC + F_JP2INC)
+#define F_GIF       ( 0 + F_PNGINC + F_JPGINC + F_JP2INC + F_JP2INC)  /* always avail; index varies */
+#define F_TIFF      ( 0 + F_PNGINC + F_JPGINC + F_JP2INC + F_JP2INC + F_TIFINC)
+#define F_PS        ( 1 + F_TIFF)
+#define F_PBMRAW    ( 2 + F_TIFF)
+#define F_PBMASCII  ( 3 + F_TIFF)
+#define F_XBM       ( 4 + F_TIFF)
+#define F_XPM       ( 5 + F_TIFF)
+#define F_BMP       ( 6 + F_TIFF)
+#define F_SUNRAS    ( 7 + F_TIFF)
+#define F_IRIS      ( 8 + F_TIFF)
+#define F_TARGA     ( 9 + F_TIFF)
+#define F_FITS      (10 + F_TIFF)
+#define F_PM        (11 + F_TIFF)
+#define F_ZX        (12 + F_TIFF)   /* [JCE] */
+#define F_WBMP      (13 + F_TIFF)
+#define JP_EXT_F    (F_WBMP)
+#define F_MAG       (JP_EXT_F + F_MAGINC)
+#define F_PIC       (JP_EXT_F + F_MAGINC + F_PICINC)
+#define F_MAKI      (JP_EXT_F + F_MAGINC + F_PICINC + F_MAKINC)
+#define F_PI        (JP_EXT_F + F_MAGINC + F_PICINC + F_MAKINC + F_PAIINC)
+#define F_PIC2      (JP_EXT_F + F_MAGINC + F_PICINC + F_MAKINC + F_PAIINC + F_PC2INC)
+#define F_MGCSFX    (JP_EXT_F + F_MAGINC + F_PICINC + F_MAKINC + F_PAIINC + F_PC2INC + F_MGCSFXINC)
+#define JP_EXT_F_END (F_MGCSFX)
+#define F_DELIM1    (JP_EXT_F_END + 1)   /* ----- */
+#define F_FILELIST  (JP_EXT_F_END + 2)
+#define F_MAXFMTS   (JP_EXT_F_END + 3)   /* 27, normally (with all formats) */
 
 
 
 /* return values from ReadFileType()
  * positive values are *definitely* readable formats (HAVE_*** is defined)
  * negative values are random files that XV can't read, but display as
- *   different icons in the visual browser 
+ *   different icons in the visual browser
  */
 #define RFT_ERROR    -1    /* couldn't open file, or whatever... */
 #define RFT_UNKNOWN   0
@@ -505,6 +674,22 @@
 #define RFT_XPM      17
 #define RFT_XWD      18
 #define RFT_FITS     19
+#define RFT_PNG      20
+#define RFT_ZX       21    /* [JCE] */
+#define RFT_WBMP     22
+#define RFT_PCD      23
+#define RFT_HIPS     24
+#define RFT_BZIP2    25
+#define RFT_JPC      26
+#define RFT_JP2      27
+#define RFT_G3       28
+#define JP_EXT_RFT   (RFT_G3)
+#define RFT_MAG      (JP_EXT_RFT + 1)
+#define RFT_MAKI     (JP_EXT_RFT + 2)
+#define RFT_PIC      (JP_EXT_RFT + 3)
+#define RFT_PI       (JP_EXT_RFT + 4)
+#define RFT_PIC2     (JP_EXT_RFT + 5)
+#define RFT_MGCSFX   (JP_EXT_RFT + 6)
 
 /* definitions for page up/down, arrow up/down list control */
 #define LS_PAGEUP   0
@@ -563,7 +748,8 @@
 #define RM_CBRICK  7     /* centered on a 'brick' bg */
 #define RM_ECENTER 8     /* symmetrical tiled */
 #define RM_ECMIRR  9     /* symmetrical mirror tiled */
-#define RM_MAX     RM_ECMIRR
+#define RM_UPLEFT 10     /* just in upper left corner */
+#define RM_MAX     RM_UPLEFT
 
 
 /* values of colorMapMode */
@@ -613,10 +799,11 @@
 #define RMB_CBRICK   8
 #define RMB_ECENTER  9
 #define RMB_ECMIRR   10
-#define RMB_MAX      11
+#define RMB_UPLEFT   11
+#define RMB_MAX      12
 
 
-/* indicies into conv24MB */
+/* indices into conv24MB */
 #define CONV24_8BIT  0
 #define CONV24_24BIT 1
 #define CONV24_SEP1  2
@@ -631,7 +818,7 @@
 #define PIC8  CONV24_8BIT
 #define PIC24 CONV24_24BIT
 
-/* indicies into algMB */
+/* indices into algMB */
 #define ALG_NONE      0
 #define ALG_SEP1      1  /* separator */
 #define ALG_BLUR      2
@@ -648,7 +835,7 @@
 #define ALG_MAX       13
 
 
-/* indicies into sizeMB */
+/* indices into sizeMB */
 #define SZMB_NORM     0
 #define SZMB_MAXPIC   1
 #define SZMB_MAXPECT  2
@@ -663,7 +850,7 @@
 #define SZMB_INTEXP   11
 #define SZMB_MAX      12
 
-/* indicies into windowMB */
+/* indices into windowMB */
 #define WMB_BROWSE    0
 #define WMB_COLEDIT   1
 #define WMB_INFO      2
@@ -742,15 +929,15 @@
 
 typedef unsigned char byte;
 
-typedef struct scrl { 
+typedef struct scrl {
                  Window win;            /* window ID */
 		 int x,y,w,h;           /* window coords in parent */
 		 int len;               /* length of major axis */
 		 int vert;              /* true if vertical, else horizontal */
 		 int active;            /* true if scroll bar can do anything*/
-		 int min,max;           /* min/max values 'pos' can take */
-		 int val;               /* 'value' of scrollbar */
-		 int page;              /* amt val change on pageup/pagedown */
+		 double min,max;        /* min/max values 'pos' can take */
+		 double val;            /* 'value' of scrollbar */
+		 double page;           /* amt val change on pageup/pagedown */
 		 int tpos;              /* thumb pos. (pixels from tmin) */
 		 int tmin,tmax;         /* min/max thumb offsets (from 0,0) */
 		 int tsize;             /* size of thumb (in pixels) */
@@ -765,11 +952,12 @@
 typedef struct { Window win;            /* window ID */
 		 int x,y,w,h;           /* window coords in parent */
 		 int active;            /* true if can do anything*/
-		 int min,max;           /* min/max values 'pos' can take */
-		 int val;               /* 'value' of dial */
-		 int page;              /* amt val change on pageup/pagedown */
-		 char *title;           /* title for this guage */
-		 char *units;           /* string appended to value */
+		 double min,max;        /* min/max values 'pos' can take */
+		 double val;            /* 'value' of dial */
+		 double inc;            /* amt val change on up/down */
+		 double page;           /* amt val change on pageup/pagedown */
+		 const char *title;     /* title for this gauge */
+		 const char *units;     /* string appended to value */
 		 u_long fg,bg,hi,lo;    /* colors */
 		 int rad, cx, cy;       /* internals */
 		 int bx[4], by[4];      /* more internals */
@@ -785,7 +973,7 @@
 		 int active;            /* if false, stipple gray */
 		 int toggle;            /* if true, clicking toggles state */
 		 u_long fg,bg,hi,lo;    /* colors */
-		 char *str;             /* string in button */
+		 const char *str;       /* string in button */
 		 Pixmap pix;            /* use pixmap instead of string */
 		 u_int pw,ph;           /* size of pixmap */
 		 int colorpix;          /* multi-color pixmap */
@@ -797,21 +985,23 @@
 typedef struct rbutt {
                  Window        win;      /* parent window */
 		 int           x,y;      /* position in parent */
-		 char         *str;      /* the message string */
+		 const char    *str;     /* the message string */
 		 int           selected; /* selected or not */
 		 int           active;   /* selectable? */
 		 struct rbutt *next;     /* pointer to next in group */
-		 u_long fg,bg,hi,lo;     /* colors */
+		 u_long        fg,bg;    /* colors */
+		 u_long        hi,lo;    /* colors */
 	       } RBUTT;
 
 
 
 typedef struct { Window        win;      /* parent window */
 		 int           x,y;      /* position in parent */
-		 char         *str;      /* the message string */
+		 const char   *str;      /* the message string */
 		 int           val;      /* 1=selected, 0=not */
 		 int           active;   /* selectable? */
-		 u_long fg,bg,hi,lo;     /* colors */
+		 u_long        fg,bg;    /* colors */
+		 u_long        hi,lo;    /* colors */
 	       } CBUTT;
 
 
@@ -819,11 +1009,11 @@
 typedef struct { Window        win;            /* parent window */
 		 int           x,y;            /* position in parent */
 		 unsigned int  w,h;
-		 char         *title;          /* title string in norm state */
+		 const char   *title;          /* title string in norm state */
 		 int           active;         /* selectable? */
-		 char        **list;           /* list of strings in menu */
+		 const char  **list;           /* list of strings in menu */
 		 int           nlist;          /* # of strings in menu */
-		 byte          flags[MAXMBLEN];  /* checkmarks on items */
+		 byte          flags[MAXMBLEN]; /* checkmarks on items */
 		 int           hascheck;       /* leave room for checkmark? */
 		 byte          dim[MAXMBLEN];  /* dim individual choices */
 		 Pixmap        pix;            /* use pixmap instd of string */
@@ -833,17 +1023,18 @@
 	       } MBUTT;
 
 
-typedef struct { Window win;            /* window */
-		 int x,y;               /* size of window */
+typedef struct { Window       win;       /* window */
+		 int          x,y;       /* size of window */
 		 unsigned int w,h;
-		 u_long fg,bg,hi,lo;    /* colors */
-		 char **str;            /* ptr to list of strings */
-		 int   nstr;            /* number of strings */
-		 int   selected;        /* number of 'selected' string */
-		 int   nlines;          /* number of lines shown at once */
-		 SCRL  scrl;            /* scrollbar that controls list */
-		 int   filetypes;       /* true if filetype icons to be drawn*/
-		 int   dirsonly;        /* if true, only dirs selectable */
+		 u_long       fg,bg;     /* colors */
+		 u_long       hi,lo;     /* colors */
+		 /* const? */ char **str;   /* ptr to list of strings */
+		 int          nstr;      /* number of strings */
+		 int          selected;  /* number of 'selected' string */
+		 int          nlines;    /* number of lines shown at once */
+		 SCRL         scrl;      /* scrollbar that controls list */
+		 int          filetypes; /* true if filetype icons to be drawn*/
+		 int          dirsonly;  /* if true, only dirs selectable */
 	       } LIST;
 
 
@@ -865,6 +1056,9 @@
 		 char  shrtInfo[128];        /* short format info */
 		 char *comment;              /* comment text */
 
+		 byte *exifInfo;             /* image info from digicam */
+		 int   exifInfoSize;         /* size of image info */
+
 		 int   numpages;             /* # of page files, if >1 */
 		 char  pagebname[64];        /* basename of page files */
 	       } PICINFO;
@@ -881,18 +1075,18 @@
 
 #define GVMAX 8
 
-typedef struct {  Window win;          /* window ID */
-		  Window gwin;         /* graph subwindow */
-		  int    spline;       /* spline curve or lines? */
-		  int    entergamma;   /* currently entering gamma value */
-		  int    gammamode;    /* currently using gamma function */
-		  double gamma;        /* gamma value (if gammamode) */
-		  int    nhands;       /* current # of handles */
-		  XPoint hands[MAX_GHANDS];   /* positions of handles */
-		  byte   func[256];    /* output function of GRAF */
-		  BUTT   butts[N_GFB]; /* control buttons */
-		  u_long fg,bg;        /* colors */
-		  char   *str;         /* title string */
+typedef struct {  Window win;               /* window ID */
+		  Window gwin;              /* graph subwindow */
+		  int    spline;            /* spline curve or lines? */
+		  int    entergamma;        /* currently entering gamma value */
+		  int    gammamode;         /* currently using gamma function */
+		  double gamma;             /* gamma value (if gammamode) */
+		  int    nhands;            /* current # of handles */
+		  XPoint hands[MAX_GHANDS]; /* positions of handles */
+		  byte   func[256];         /* output function of GRAF */
+		  BUTT   butts[N_GFB];      /* control buttons */
+		  u_long fg,bg;             /* colors */
+		  const char *str;          /* title string */
 		  char   gvstr[GVMAX+1];    /* gamma value input string */
 		  void   (*drawobj)PARM((void));
 		} GRAF;
@@ -932,18 +1126,23 @@
 /* X stuff */
 WHERE Display       *theDisp;
 WHERE int           theScreen;
-WHERE unsigned int  ncells, dispWIDE, dispHIGH, dispDEEP;
-WHERE unsigned int  vrWIDE, vrHIGH, maxWIDE, maxHIGH;
+WHERE unsigned int  ncells, dispDEEP; /* root color sizes */
+WHERE unsigned int  dispWIDE, dispHIGH; /* screen sizes */
+WHERE unsigned int  vrWIDE, vrHIGH, maxWIDE, maxHIGH; /* virtual root and max image sizes */
 WHERE Colormap      theCmap, LocalCmap;
-WHERE Window        rootW, mainW, vrootW;
+WHERE Window        spec_window, rootW, mainW, vrootW;
 WHERE GC            theGC;
 WHERE u_long        black, white, fg, bg, infofg, infobg;
 WHERE u_long        hicol, locol;
 WHERE u_long        blkRGB, whtRGB;
 WHERE Font          mfont, monofont;
 WHERE XFontStruct   *mfinfo, *monofinfo;
+#ifdef TV_L10N
+WHERE XFontSet      monofset;
+WHERE XFontSetExtents *monofsetinfo;
+#endif
 WHERE Visual        *theVisual;
-WHERE Cursor        arrow, cross, tcross, zoom, inviso;
+WHERE Cursor        arrow, cross, tcross, zoom, inviso, tlcorner;
 WHERE Pixmap        iconPix, iconmask;
 WHERE Pixmap        riconPix, riconmask;
 WHERE int           showzoomcursor;
@@ -959,6 +1158,12 @@
 WHERE char           formatStr[80];         /* short-form 'file format' */
 WHERE int            picType;               /* CONV24_8BIT,CONV24_24BIT,etc.*/
 WHERE char          *picComments;           /* text comments on current pic */
+WHERE byte          *picExifInfo;           /* image info from digicam */
+WHERE int            picExifInfoSize;       /* size of image info */
+
+#ifdef TV_L10N
+WHERE int            xlocale;		    /* true if Xlib supports locale */
+#endif
 
 WHERE int            numPages, curPage;     /* for multi-page files */
 WHERE char           pageBaseName[64];      /* basename for multi-page files */
@@ -972,12 +1177,12 @@
                                    /* this is converted to 'theImage' */
 WHERE int           eWIDE, eHIGH;  /* size of epic */
 
-WHERE byte          *egampic;      /* expanded, gammified cpic 
+WHERE byte          *egampic;      /* expanded, gammified cpic
 				      (only used in 24-bit mode) */
 
 WHERE int           p_offx, p_offy;  /* offset of reparented windows */
 WHERE int           ch_offx,ch_offy; /* ChngAttr ofst for reparented windows */
-WHERE int           kludge_offx,     /* WM kludges for SetWindowPos routine */ 
+WHERE int           kludge_offx,     /* WM kludges for SetWindowPos routine */
                     kludge_offy;
 WHERE int           winCtrPosKludge; /* kludge for popup positioning... */
 
@@ -993,6 +1198,26 @@
 WHERE unsigned long  cols[256];    /* maps pic pixel values to X pixel vals */
 WHERE int            fc2pcol[256]; /* maps freecols into pic pixel values */
 WHERE int            numcols;      /* # of desired colors in picture */
+#ifdef MACBINARY
+WHERE char           macb_file;    /* True if this file type is MacBinary */
+WHERE int            handlemacb;   /* True if we want to handle MacBinary */
+#endif
+#if defined(HAVE_PIC) || defined(HAVE_PIC2)
+WHERE int            nopicadjust;  /* True if we don't want to adjust aspect */
+#endif
+#ifdef HAVE_PIC2
+WHERE int            pic2split;    /* True if we want to split multiblocks */
+#endif
+#ifdef VS_ADJUST
+WHERE int            vsadjust; /* True if we want to adjust aspect of icons */
+#endif
+#ifdef HAVE_MGCSFX
+WHERE int            mgcsfx;    /* True if we want to force use MgcSfx */
+WHERE int            nomgcsfx;  /* True if we don't want to use MgcSfx */
+#endif
+
+#define FSTRMAX 12   /* Number of function keys to support. */
+WHERE char          *fkeycmds[FSTRMAX]; /* command to run when F# is pressed */
 
 /* Std Cmap stuff */
 WHERE byte           stdr[256], stdg[256], stdb[256];  /* std 3/3/2 cmap */
@@ -1025,7 +1250,7 @@
 
 WHERE int           ncols;         /* max # of (different) colors to alloc */
 
-WHERE char          str[128];      /* dummy string used for error messages */
+WHERE char          dummystr[128]; /* dummy string used for error messages */
 WHERE char          initdir[MAXPATHLEN];   /* cwd when xv was started */
 WHERE char          searchdir[MAXPATHLEN]; /* '-dir' option */
 WHERE char          fullfname[MAXPATHLEN]; /* full name of current file */
@@ -1047,42 +1272,47 @@
                     noFreeCols,    /* don't free colors when loading new pic */
                     autoquit,      /* quit in '-root' or when click on win */
                     xerrcode,      /* errorcode of last X error */
-                    grabDelay;     /* # of seconds to sleep at start of Grab */
+                    grabDelay,     /* # of seconds to sleep at start of Grab */
+                    startGrab;     /* start immediate grab ? */
 
 WHERE int           state824;      /* displays warning when going 8->24 */
 
 WHERE float         defaspect,     /* default aspect ratio to use */
                     normaspect;    /* normal aspect ratio of this picture */
 
-WHERE unsigned long rootbg, rootfg;   /* fg/bg for root border */
-WHERE int           waitsec;          /* secs btwn pics. -1=wait for event */
-WHERE int           waitloop;         /* loop at end of slide show? */
-WHERE int           automax;          /* maximize pic on open */
-WHERE int           rootMode;         /* mode used for -root images */
+WHERE u_long        rootbg, rootfg; /* fg/bg for root border */
+WHERE u_short       imagebgR;
+WHERE u_short       imagebgG;      /* GRR 19980308:  bg for transpar. images */
+WHERE u_short       imagebgB;
+WHERE int           have_imagebg;
+WHERE double        waitsec;       /* secs btwn pics. -1.0=wait for event */
+WHERE int           waitloop;      /* loop at end of slide show? */
+WHERE int           automax;       /* maximize pic on open */
+WHERE int           rootMode;      /* mode used for -root images */
 
-WHERE int           nostat;           /* if true, don't stat() in LdCurDir */
+WHERE int           nostat;        /* if true, don't stat() in LdCurDir */
 
-WHERE int           ctrlColor;        /* whether or not to use colored butts */
+WHERE int           ctrlColor;     /* whether or not to use colored butts */
 
-WHERE char         *def_str;          /* used by rd_*() routines */
+WHERE char         *def_str;       /* used by rd_*() routines */
 WHERE int           def_int;
-WHERE char         *tmpdir;           /* equal to "/tmp" or $TMPDIR env var */
-WHERE Pixmap        gray25Tile,       /* used for 3d effect on 1-bit disp's */
+WHERE char         *tmpdir;        /* equal to "/tmp" or $TMPDIR env var */
+WHERE Pixmap        gray25Tile,    /* used for 3d effect on 1-bit disp's */
                     gray50Tile;
-WHERE int           autoDelete;       /* delete cmd-line files on exit? */
+WHERE int           autoDelete;    /* delete cmd-line files on exit? */
 
 #define PRINTCMDLEN 256
-WHERE char          printCmd[PRINTCMDLEN]; 
+WHERE char          printCmd[PRINTCMDLEN];
 
 /* stuff used for 'info' box */
 WHERE Window        infoW;
-WHERE int           infoUp;       /* boolean:  whether infobox is visible */
+WHERE int           infoUp;        /* boolean:  whether infobox is visible */
 WHERE int           infoMode;
 
 
 /* stuff used for 'ctrl' box */
 WHERE Window        ctrlW;
-WHERE int           ctrlUp;       /* boolean:  whether ctrlbox is visible */
+WHERE int           ctrlUp;        /* boolean:  whether ctrlbox is visible */
 WHERE char         *namelist[MAXNAMES];  /* list of file names from argv */
 WHERE char         *origlist[MAXNAMES];  /* only names from argv (autoDelete)*/
 WHERE int           orignumnames;
@@ -1121,25 +1351,31 @@
 
 
 /* stuff used for 'browse' box */
-WHERE int           anyBrowUp;            /* whether *any* browser visible */
+WHERE int           anyBrowUp;              /* whether *any* browser visible */
+WHERE int           incrementalSearchTimeout;
 
 /* stuff used for textview windows */
-WHERE int           anyTextUp;            /* are any text windows visible? */
-WHERE int           commentUp;            /* comment window up? */
+WHERE int           anyTextUp;              /* are any text windows visible? */
+WHERE int           commentUp;              /* comment window up? */
 
 /* stuff used for xvcut.c */
-WHERE int           forceClipFile;        /* don't use property clipboard */
-WHERE int           clearR, clearG, clearB;  /* clear color in 24-bit mode */
+WHERE int           forceClipFile;          /* don't use property clipboard */
+WHERE int           clearR, clearG, clearB; /* clear color in 24-bit mode */
 
 
 /* stuff used for 'ps' box */
 WHERE Window        psW;
-WHERE int           psUp;       /* is psW mapped, or what? */
-WHERE CBUTT         encapsCB, pscompCB;   
-WHERE char         *gsDev, *gsGeomStr;
+WHERE int           psUp;         /* is psW mapped, or what? */
+WHERE CBUTT         encapsCB, pscompCB;
+WHERE const char   *gsDev, *gsGeomStr;
 WHERE int           gsRes;
 
 
+/* stuff used for 'pcd' box */
+WHERE Window        pcdW;
+WHERE int           pcdUp;        /* is pcdW mapped, or what? */
+
+
 #ifdef HAVE_JPEG
 /* stuff used for 'jpeg' box */
 WHERE Window        jpegW;
@@ -1147,6 +1383,13 @@
 #endif
 
 
+#ifdef HAVE_JP2K
+/* stuff used for 'jp2k' box */
+WHERE Window        jp2kW;
+WHERE int           jp2kUp;       /* is jp2kW mapped, or what? */
+#endif
+
+
 #ifdef HAVE_TIFF
 /* stuff used for 'tiff' box */
 WHERE Window        tiffW;
@@ -1154,6 +1397,91 @@
 #endif
 
 
+#ifdef HAVE_PNG
+/* stuff used for 'png' box */
+WHERE Window        pngW;
+WHERE int           pngUp;        /* is pngW mapped, or what? */
+#endif
+
+
+#ifdef ENABLE_FIXPIX_SMOOTH
+WHERE int           do_fixpix_smooth;  /* GRR 19980607: runtime FS dithering */
+#endif
+
+#ifdef HAVE_PIC2
+/* stuff used for 'pic2' box */
+WHERE Window        pic2W;
+WHERE int           pic2Up;      /* is pic2W mapped, or what? */
+#endif /* HAVE_PIC2 */
+
+#ifdef HAVE_PCD
+/* stuff used for 'pcd' box */
+WHERE Window        pcdW;
+WHERE int           pcdUp;       /* is pcdW mapped, or what? */
+#endif /* HAVE_PCD */
+
+#ifdef HAVE_MGCSFX
+/* stuff used for 'mgcsfx' box */
+WHERE Window        mgcsfxW;
+WHERE Window        mgcsfxNameW;
+WHERE int           mgcsfxUp;      /* is mgcsfxW mapped, or what? */
+#endif /* HAVE_MGCSFX */
+
+#ifdef TV_L10N
+/* stuff used for TextViewer Japanization */
+#  define LOCALE_USASCII    0
+#  define LOCALE_EUCJ       1
+#  define LOCALE_JIS        2
+#  define LOCALE_MSCODE     3
+
+#  ifndef LOCALE_DEFAULT
+#    define LOCALE_DEFAULT  0
+#  endif /* !LOCALE_DEFAULT */
+
+#  ifndef MAIN
+     extern char *localeList[];
+#  else
+#    ifndef LOCALE_NAME_EUC
+#      ifndef X_LOCALE
+#        if defined(__FreeBSD__)
+	   char *localeList[] = {"", "ja_JP.EUC", "none", "none"};
+#        elif defined(__linux__)
+	   char *localeList[] = {"", "ja_JP.eucJP", "none", "ja_JP.SJIS"};
+#        elif defined(__sun) || defined(sun)
+	   char *localeList[] = {"", "ja", "none", "none"};
+#        elif defined(__sgi)	/* sgi, __sgi, __sgi__ (gcc) */
+	   char *localeList[] = {"", "ja_JP.EUC", "none", "none"};
+#        elif defined(sony_news)
+	   char *localeList[] = {"", "ja_JP.EUC", "none", "ja_JP.SJIS"};
+#        elif defined(nec)
+	   char *localeList[] = {"", "japan", "none", "none"};
+#        elif defined(__hpux)
+	   char *localeList[] = {"", "japanese.euc", "none", "japanese"};
+#        elif defined(__osf__)
+	   char *localeList[] = {"", "ja_JP.deckanji", "none", "ja_JP.SJIS"};
+#        elif defined(_AIX)
+	   char *localeList[] = {"", "ja_JP", "none", "Ja_JP" };
+#        elif defined(__bsdi)
+	   char *localeList[] = {"", "Japanese-EUC", "none", "none" };
+#        else
+	   char *localeList[] = {"", "ja_JP.EUC", "ja_JP.JIS", "ja_JP.SJIS"};
+#        endif
+#      else
+#        if (XlibSpecificationRelease > 5)
+           char *localeList[] = {"", "ja_JP.eucJP", "ja_JP.JIS7",
+				 "ja_JP.SJIS"};
+#        else
+           char *localeList[] = {"", "ja_JP.ujis", "ja_JP.jis7",
+				 "ja_JP.mscode"};
+#        endif
+#      endif /* X_LOCALE */
+#    else
+       char *localeList[] = {"", LOCALE_NAME_EUC,
+			     LOCALE_NAME_JIS, LOCALE_NAME_MSCODE};
+#    endif /* LOCALE_NAME_EUC */
+#  endif /* MAIN */
+#endif /* TV_L10N */
+
 #undef WHERE
 
 
@@ -1161,172 +1489,115 @@
 /* function declarations for externally-callable functions */
 
 /****************************** XV.C ****************************/
-int   ReadFileType      PARM((char *));
-int   ReadPicFile       PARM((char *, int, PICINFO *, int));
-int   UncompressFile    PARM((char *, char *));
-void  KillPageFiles     PARM((char *, int));
-
-void NewPicGetColors    PARM((int, int));
-void FixAspect          PARM((int, int *, int *));
-void ActivePrevNext     PARM((void));
-int  DeleteCmd          PARM((void));
-void StickInCtrlList    PARM((int));
-void AddFNameToCtrlList PARM((char *, char *));
-void ChangedCtrlList    PARM((void));
-void HandleDispMode     PARM((void));
-char *lower_str         PARM((char *));
-int  rd_int             PARM((char *));
-int  rd_str             PARM((char *));
-int  rd_flag            PARM((char *));
-int  rd_str_cl          PARM((char *, char *, int));
+int   ReadFileType         PARM((char *));
+int   ReadPicFile          PARM((char *, int, PICINFO *, int));
+int   UncompressFile       PARM((char *, char *, int));
+void  KillPageFiles        PARM((char *, int));
+#ifdef MACBINARY          
+int   RemoveMacbinary      PARM((char *, char *));
+#endif                    
+
+void NewPicGetColors       PARM((int, int));
+void FixAspect             PARM((int, int *, int *));
+void ActivePrevNext        PARM((void));
+int  DeleteCmd             PARM((void));
+void StickInCtrlList       PARM((int));
+void AddFNameToCtrlList    PARM((const char *, const char *));
+void ChangedCtrlList       PARM((void));
+void HandleDispMode        PARM((void));
+char *lower_str            PARM((char *));
+int  rd_int                PARM((const char *));
+int  rd_str                PARM((const char *));
+int  rd_flag               PARM((const char *));
 
-/****************************** XVEVENT.C ****************************/
-int  EventLoop          PARM((void));
-int  HandleEvent        PARM((XEvent *, int *));
 
-void SelectDispMB       PARM((int));
-void Select24to8MB      PARM((int));
-void SelectRootMB       PARM((int));
-void SelectWindowMB     PARM((int));
-void SelectSizeMB       PARM((int));
-
-void DoPrint            PARM((void));
-void NewCutBuffer       PARM((char *));
-void DrawWindow         PARM((int,int,int,int));
-void WResize            PARM((int, int));
-void WRotate            PARM((void));
-void WCrop              PARM((int, int, int, int));
-void WUnCrop            PARM((void));
-void GetWindowPos       PARM((XWindowAttributes *));
-void SetWindowPos       PARM((XWindowAttributes *));
-void SetEpicMode        PARM((void));
-int  xvErrorHandler     PARM((Display *, XErrorEvent *));
-
-/****************************** XVROOT.C ****************************/
-void MakeRootPic        PARM((void));
-void ClearRoot          PARM((void));
-void SaveRootInfo       PARM((void));
-void KillOldRootInfo    PARM((void));
+/*************************** XV24TO8.C **************************/
+void Init24to8             PARM((void));
+byte *Conv24to8            PARM((byte *, int, int, int,
+				 byte *, byte *, byte *));
 
-/*************************** XVMISC.C ***************************/
-void StoreDeleteWindowProp  PARM((Window));
-Window CreateWindow         PARM((char *, char *, char *, int, int, 
-				  u_long, u_long, int));
-void DrawString             PARM((Window, int, int, char *));
-void CenterString           PARM((Window, int, int, char *));
-void ULineString            PARM((Window, int, int, char *));
-int  StringWidth            PARM((char *));
-int  CursorKey              PARM((KeySym, int, int));
-void FakeButtonPress        PARM((BUTT *));
-void FakeKeyPress           PARM((Window, KeySym));
-void GenExpose              PARM((Window, int, int, u_int, u_int));
-void DimRect                PARM((Window, int, int, u_int, u_int, u_long));
-
-void Draw3dRect             PARM((Window, int, int, u_int, u_int, int, int, 
-				    u_long, u_long, u_long));
-
-void RemapKeyCheck          PARM((KeySym, char *, int *));
-void xvDestroyImage         PARM((XImage *));
-void SetCropString          PARM((void));
-void SetSelectionString     PARM((void));
-void Warning                PARM((void));
-void FatalError             PARM((char *));
-void Quit                   PARM((int));
-void LoadFishCursors        PARM((void));
-void WaitCursor             PARM((void));
-void SetCursors             PARM((int));
-char *BaseName              PARM((char *));
-
-void DrawTempGauge          PARM((Window, int, int, int, int, double, 
-				  u_long, u_long, u_long, u_long, char *));
-void ProgressMeter          PARM((int, int, int, char *));
-void XVDeletedFile          PARM((char *));
-void XVCreatedFile          PARM((char *));
-void xvbcopy                PARM((char *, char *, size_t));
-int  xvbcmp                 PARM((char *, char *, size_t));
-void xvbzero                PARM((char *, size_t));
-void xv_getwd               PARM((char *, size_t));
-char *xv_strstr             PARM((char *, char *));
-FILE *xv_fopen              PARM((char *, char *));
-void Timer                  PARM((int));
+byte *Conv8to24            PARM((byte *, int, int, byte *, byte *, byte *));
 
-/*************************** XVCOLOR.C ***************************/
-void   SortColormap         PARM((byte *, int, int, int *, byte*,byte*,byte*,
-				  byte *, byte *));
-void   ColorCompress8       PARM((byte *));
-void   AllocColors          PARM((void));
-Status xvAllocColor         PARM((Display *, Colormap, XColor *));
-void   xvFreeColors         PARM((Display *, Colormap, u_long *, int, u_long));
-void   FreeColors           PARM((void));
-void   ApplyEditColor       PARM((int));
-int    MakeStdCmaps         PARM((void));
-void   MakeBrowCmap         PARM((void));
-void   ChangeCmapMode       PARM((int, int, int));
 
-/*************************** XVIMAGE.C ***************************/
-void Resize                 PARM((int, int));
-void GenerateCpic           PARM((void));
-void GenerateEpic           PARM((int, int));
-void DoZoom                 PARM((int, int, u_int));
-void Crop                   PARM((void));
-void UnCrop                 PARM((void));
-void AutoCrop               PARM((void));
-int  DoAutoCrop             PARM((void));
-void DoCrop                 PARM((int, int, int, int));
-void Rotate                 PARM((int));
-void DoRotate               PARM((int));
-void RotatePic              PARM((byte *, int, int *, int *, int));
-void Flip                   PARM((int));
-void FlipPic                PARM((byte *, int, int, int));
-void InstallNewPic          PARM((void));
-void DrawEpic               PARM((void));
-void KillOldPics            PARM((void));
-
-byte *FSDither              PARM((byte *, int, int, int, 
-				  byte *, byte *, byte *, int, int));
-
-void CreateXImage           PARM((void));
-XImage *Pic8ToXImage        PARM((byte *, u_int, u_int, u_long *, 
-				  byte *, byte *, byte *));
-
-XImage *Pic24ToXImage       PARM((byte *, u_int, u_int));
-
-void Set824Menus            PARM((int));
-void Change824Mode          PARM((int));
-void FreeEpic               PARM((void));
-void InvertPic24            PARM((byte *, int, int));
+/*************************** XVALG.C ***************************/
+void AlgInit               PARM((void));
+void DoAlg                 PARM((int));
 
-byte *XVGetSubImage         PARM((byte *, int, int,int, int,int,int,int));
 
-int  DoPad                  PARM((int, char *, int, int, int, int));
-int  LoadPad                PARM((PICINFO *, char *));
+/*************************** XVBROWSE.C ************************/
+void CreateBrowse          PARM((const char *, const char *, const char *,
+				 const char *, const char *));
+void OpenBrowse            PARM((void));
+void HideBrowseWindows     PARM((void));
+void UnHideBrowseWindows   PARM((void));
+void SetBrowseCursor       PARM((Cursor));
+void KillBrowseWindows     PARM((void));
+int  BrowseCheckEvent      PARM((XEvent *, int *, int *));
+int  BrowseDelWin          PARM((Window));
+void SetBrowStr            PARM((const char *));
+void RegenBrowseIcons      PARM((void));
+void BRDeletedFile         PARM((char *));
+void BRCreatedFile         PARM((char *));
 
-/*************************** XVALG.C ***************************/
-void AlgInit                PARM((void));
-void DoAlg                  PARM((int));
 
-/*************************** XVSMOOTH.C ***************************/
-byte *SmoothResize          PARM((byte *, int, int, int, int, byte *, byte *, 
-				  byte *, byte *, byte *, byte *, int));
+/**************************** XVBUTT.C ***************************/
+void BTCreate              PARM((BUTT *, Window, int, int, u_int, u_int,
+				 const char *, u_long, u_long, u_long, u_long));
 
-byte *Smooth24              PARM((byte *, int, int, int, int, int, 
-				  byte *, byte *, byte *));
+void BTSetActive           PARM((BUTT *, int));
+void BTRedraw              PARM((BUTT *));
+int  BTTrack               PARM((BUTT *));
 
-byte *DoColorDither         PARM((byte *, byte *, int, int, byte *, byte *, 
-				  byte *, byte *, byte *, byte *, int));
 
-byte *Do332ColorDither      PARM((byte *, byte *, int, int, byte *, byte *, 
-				  byte *, byte *, byte *, byte *, int));
+RBUTT *RBCreate            PARM((RBUTT *, Window, int, int, const char *,
+				 u_long, u_long, u_long, u_long));
 
-/*************************** XV24TO8.C **************************/
-void Init24to8             PARM((void));
-byte *Conv24to8            PARM((byte *, int, int, int, 
-				 byte *, byte *, byte *));
+void   RBRedraw            PARM((RBUTT *, int));
+void   RBSelect            PARM((RBUTT *, int));
+int    RBWhich             PARM((RBUTT *));
+int    RBCount             PARM((RBUTT *));
+void   RBSetActive         PARM((RBUTT *, int, int));
+int    RBClick             PARM((RBUTT *, int, int));
+int    RBTrack             PARM((RBUTT *, int));
+
+
+void   CBCreate            PARM((CBUTT *, Window, int, int, const char *,
+				 u_long, u_long, u_long, u_long));
+
+void   CBRedraw            PARM((CBUTT *));
+void   CBSetActive         PARM((CBUTT *, int));
+int    CBClick             PARM((CBUTT *,int,int));
+int    CBTrack             PARM((CBUTT *));
+
+
+void   MBCreate            PARM((MBUTT *, Window, int, int, u_int, u_int,
+				 const char *, const char * const *, int,
+				 u_long, u_long, u_long, u_long));
+
+void   MBRedraw            PARM((MBUTT *));
+void   MBSetActive         PARM((MBUTT *, int));
+int    MBWhich             PARM((MBUTT *));
+void   MBSelect            PARM((MBUTT *, int));
+int    MBClick             PARM((MBUTT *, int, int));
+int    MBTrack             PARM((MBUTT *));
+
+
+/*************************** XVCOLOR.C ***************************/
+void   SortColormap        PARM((byte *, int, int, int *, byte*,byte*,byte*,
+				 byte *, byte *));
+void   ColorCompress8      PARM((byte *));
+void   AllocColors         PARM((void));
+Status xvAllocColor        PARM((Display *, Colormap, XColor *));
+void   xvFreeColors        PARM((Display *, Colormap, u_long *, int, u_long));
+void   FreeColors          PARM((void));
+void   ApplyEditColor      PARM((int));
+int    MakeStdCmaps        PARM((void));
+void   MakeBrowCmap        PARM((void));
+void   ChangeCmapMode      PARM((int, int, int));
 
-byte *Conv8to24            PARM((byte *, int, int, byte *, byte *, byte *));
 
 /**************************** XVCTRL.C **************************/
-void   CreateCtrl          PARM((char *));
+void   CreateCtrl          PARM((const char *));
 void   SetButtPix          PARM((BUTT *, Pixmap, int, int));
 Pixmap MakePix1            PARM((Window, byte *, int, int));
 
@@ -1337,7 +1608,7 @@
 void DrawCtrlStr           PARM((void));
 void ScrollToCurrent       PARM((LIST *));
 
-void LSCreate              PARM((LIST *, Window, int, int, int, int, int, 
+void LSCreate              PARM((LIST *, Window, int, int, int, int, int,
 				 char **, int, u_long, u_long, u_long, u_long,
 				 void (*)(int, SCRL *), int, int));
 
@@ -1346,20 +1617,56 @@
 void LSChangeData          PARM((LIST *, char **, int));
 void LSNewData             PARM((LIST *, char **, int));
 void LSKey                 PARM((LIST *, int));
+int  rd_str_cl             PARM((const char *, const char *, int));
 
 
-/*************************** XVINFO.C ***************************/
-void  CreateInfo           PARM((char *));
-void  InfoBox              PARM((int));
-void  RedrawInfo           PARM((int, int, int, int));
-void  SetInfoMode          PARM((int));
-char *GetISTR              PARM((int));
+/**************************** XVCUT.C ***************************/
+int  CutAllowed            PARM((void));
+int  PasteAllowed          PARM((void));
+void DoImgCopy             PARM((void));
+void DoImgCut              PARM((void));
+void DoImgClear            PARM((void));
+void DoImgPaste            PARM((void));
 
-#if defined(__STDC__) && !defined(NOSTDHDRS)
-void  SetISTR(int, ...);
-#else
-void  SetISTR();
-#endif
+void SaveToClip            PARM((byte *));
+void InitSelection         PARM((void));
+int  HaveSelection         PARM((void));
+int  GetSelType            PARM((void));
+void GetSelRCoords         PARM((int *, int *, int *, int *));
+void EnableSelection       PARM((int));
+void DrawSelection         PARM((int));
+int  DoSelection           PARM((XButtonEvent *));
+void MoveGrowSelection     PARM((int, int, int, int));
+void BlinkSelection        PARM((int));
+void FlashSelection        PARM((int));
+
+void CropRect2Rect         PARM((int*,int*,int*,int*, int,int,int,int));
+void CoordE2C              PARM((int, int, int *, int *));
+void CoordC2E              PARM((int, int, int *, int *));
+void CoordP2C              PARM((int, int, int *, int *));
+void CoordC2P              PARM((int, int, int *, int *));
+void CoordP2E              PARM((int, int, int *, int *));
+void CoordE2P              PARM((int, int, int *, int *));
+
+
+/*************************** XVDFLT.C ***************************/
+void LoadDfltPic           PARM((PICINFO *));
+void xbm2pic               PARM((byte *, int, int, byte *, int, int, int, int,
+				 int));
+void DrawStr2Pic           PARM((char *, int, int, byte *, int, int, int));
+
+
+/*************************** XVDIAL.C ***************************/
+void DCreate               PARM((DIAL *, Window, int, int, int, int,
+                                 double, double, double, double, double,
+                                 u_long, u_long, u_long, u_long,
+                                 const char *, const char *));
+
+void DSetRange             PARM((DIAL *, double,double,double,double,double));
+void DSetVal               PARM((DIAL *, double));
+void DSetActive            PARM((DIAL *, int));
+void DRedraw               PARM((DIAL *));
+int  DTrack                PARM((DIAL *, int, int));
 
 
 /**************************** XVDIR.C ***************************/
@@ -1376,15 +1683,15 @@
 void TrackDDirW            PARM((int,int));
 int  DirKey                PARM((int));
 int  DoSave                PARM((void));
-void SetDirFName           PARM((char *));
+void SetDirFName           PARM((const char *));
 char *GetDirFName          PARM((void));
 char *GetDirFullName       PARM((void));
 void SetDirSaveMode        PARM((int, int));
 int  Globify               PARM((char *));
-FILE *OpenOutFile          PARM((char *));
-int  CloseOutFile          PARM((FILE *, char *, int));
+FILE *OpenOutFile          PARM((const char *));
+int  CloseOutFile          PARM((FILE *, const char *, int));
 
-byte *GenSavePic           PARM((int*, int*,int*, int*, int*, 
+byte *GenSavePic           PARM((int*, int*,int*, int*, int*,
 				 byte**, byte**, byte**));
 void GetSaveSize           PARM((int *, int *));
 
@@ -1392,47 +1699,30 @@
 int  CheckPoll             PARM((int));
 void DIRDeletedFile        PARM((char *));
 void DIRCreatedFile        PARM((char *));
+FILE *pic2_OpenOutFile     PARM((char *, int *));
+void pic2_KillNullFile     PARM((FILE *));
+int  OpenOutFileDesc       PARM((char *));
 
 
-/*************************** XVBROWSE.C ************************/
-void CreateBrowse          PARM((char *, char *, char *, char *, char *));
-void OpenBrowse            PARM((void));
-void HideBrowseWindows     PARM((void));
-void UnHideBrowseWindows   PARM((void));
-void SetBrowseCursor       PARM((Cursor));
-void KillBrowseWindows     PARM((void));
-int  BrowseCheckEvent      PARM((XEvent *, int *, int *));
-int  BrowseDelWin          PARM((Window));
-void SetBrowStr            PARM((char *));
-void RegenBrowseIcons      PARM((void));
-void BRDeletedFile         PARM((char *));
-void BRCreatedFile         PARM((char *));
-
-
-/*************************** XVTEXT.C ************************/
-void CreateTextWins        PARM((char *, char *));
-void TextView              PARM((char *));
-void OpenTextView          PARM((char *, int, char *, int));
-
-void OpenCommentText       PARM((void));
-void CloseCommentText      PARM((void));
-void ChangeCommentText     PARM((void));
-
-void ShowLicense           PARM((void));
-void ShowKeyHelp           PARM((void));
-
-void HideTextWindows       PARM((void));
-void UnHideTextWindows     PARM((void));
-void RaiseTextWindows      PARM((void));
-void SetTextCursor         PARM((Cursor));
-void KillTextWindows       PARM((void));
-int  TextCheckEvent        PARM((XEvent *, int *, int *));
-int  TextDelWin            PARM((Window));
+/****************************** XVEVENT.C ****************************/
+int  EventLoop             PARM((void));
+int  HandleEvent           PARM((XEvent *, int *));
 
+void NewCutBuffer          PARM((char *));
+void DrawWindow            PARM((int,int,int,int));
+void WResize               PARM((int, int));
+void WRotate               PARM((void));
+void WCrop                 PARM((int, int, int, int));
+void WUnCrop               PARM((void));
+void GetWindowPos          PARM((XWindowAttributes *));
+void SetWindowPos          PARM((XWindowAttributes *));
+void SetEpicMode           PARM((void));
+int  xvErrorHandler        PARM((Display *, XErrorEvent *));
 
 
 /**************************** XVGAM.C **************************/
-void CreateGam             PARM((char *, double, double, double, double, int));
+void CreateGam             PARM((const char *, double, double, double, double,
+				 int));
 int  GamCheckEvent         PARM((XEvent *));
 void GamBox                PARM((int));
 void NewCMap               PARM((void));
@@ -1450,173 +1740,344 @@
 byte *GammifyPic24         PARM((byte *, int, int));
 void GamSetAutoApply       PARM((int));
 
-/*************************** XVSCRL.C ***************************/
-void SCCreate              PARM((SCRL *, Window, int, int, int, int, 
-				 int, int, int, int, u_long, u_long, 
-				 u_long, u_long, void (*)(int, SCRL *)));
 
-void SCChange              PARM((SCRL *, int, int, int, int, int, 
-				 int, int, int));
+/**************************** XVGRAB.C ***************************/
+int Grab                   PARM((void));
+int LoadGrab               PARM((PICINFO *));
 
-void SCSetRange            PARM((SCRL *, int, int, int, int));
-int  SCSetVal              PARM((SCRL *, int));
-void SCRedraw              PARM((SCRL *));
-void SCTrack               PARM((SCRL *, int, int));
 
+/**************************** XVGRAF.C ***************************/
+void   CreateGraf          PARM((GRAF *, Window, int, int,
+				 u_long, u_long, const char *));
 
-/*************************** XVDIAL.C ***************************/
-void DCreate               PARM((DIAL *, Window, int, int, int, int, int, 
-				 int, int, int, u_long, u_long, u_long, 
-				 u_long, char *, char *));
+void   InitGraf            PARM((GRAF *));
+void   RedrawGraf          PARM((GRAF *, int));
+int    ClickGraf           PARM((GRAF *, Window, int, int));
+int    GrafKey             PARM((GRAF *, char *));
+void   GenerateGrafFunc    PARM((GRAF *, int));
+void   Graf2Str            PARM((GRAF_STATE *, char *));
+int    Str2Graf            PARM((GRAF_STATE *, const char *));
+void   GetGrafState        PARM((GRAF *, GRAF_STATE *));
+int    SetGrafState        PARM((GRAF *, GRAF_STATE *));
+void   InitSpline          PARM((int *, int *, int, double *));
+double EvalSpline          PARM((int *, int *, double *, int, double));
 
-void DSetRange             PARM((DIAL *, int, int, int, int));
-void DSetVal               PARM((DIAL *, int));
-void DSetActive            PARM((DIAL *, int));
-void DRedraw               PARM((DIAL *));
-int  DTrack                PARM((DIAL *, int, int));
 
+/*************************** XVIMAGE.C ***************************/
+void Resize                PARM((int, int));
+void GenerateCpic          PARM((void));
+void GenerateEpic          PARM((int, int));
+void DoZoom                PARM((int, int, u_int));
+void Crop                  PARM((void));
+void UnCrop                PARM((void));
+void AutoCrop              PARM((void));
+int  DoAutoCrop            PARM((void));
+void DoCrop                PARM((int, int, int, int));
+void Rotate                PARM((int));
+void DoRotate              PARM((int));
+void RotatePic             PARM((byte *, int, int *, int *, int));
+void Flip                  PARM((int));
+void FlipPic               PARM((byte *, int, int, int));
+void InstallNewPic         PARM((void));
+void DrawEpic              PARM((void));
+void KillOldPics           PARM((void));
 
-/**************************** XVBUTT.C ***************************/
-void BTCreate              PARM((BUTT *, Window, int, int, u_int, u_int, 
-				 char *, u_long, u_long, u_long, u_long));
+byte *FSDither             PARM((byte *, int, int, int,
+				 byte *, byte *, byte *, int, int));
 
-void BTSetActive           PARM((BUTT *, int));
-void BTRedraw              PARM((BUTT *));
-int  BTTrack               PARM((BUTT *));
+void CreateXImage          PARM((void));
+XImage *Pic8ToXImage       PARM((byte *, u_int, u_int, u_long *,
+				 byte *, byte *, byte *));
 
+XImage *Pic24ToXImage      PARM((byte *, u_int, u_int));
 
-RBUTT *RBCreate            PARM((RBUTT *, Window, int, int, char *, 
-				 u_long, u_long, u_long, u_long));
+void Set824Menus           PARM((int));
+void Change824Mode         PARM((int));
+void FreeEpic              PARM((void));
+void InvertPic24           PARM((byte *, int, int));
 
-void   RBRedraw            PARM((RBUTT *, int));
-void   RBSelect            PARM((RBUTT *, int));
-int    RBWhich             PARM((RBUTT *));
-int    RBCount             PARM((RBUTT *));
-void   RBSetActive         PARM((RBUTT *, int, int));
-int    RBClick             PARM((RBUTT *, int, int));
-int    RBTrack             PARM((RBUTT *, int));
+byte *XVGetSubImage        PARM((byte *, int, int,int, int,int,int,int));
 
+int  DoPad                 PARM((int, char *, int, int, int, int));
+int  LoadPad               PARM((PICINFO *, char *));
 
-void   CBCreate            PARM((CBUTT *, Window, int, int, char *, 
-				 u_long, u_long, u_long, u_long));
 
-void   CBRedraw            PARM((CBUTT *));
-void   CBSetActive         PARM((CBUTT *, int));
-int    CBClick             PARM((CBUTT *,int,int));
-int    CBTrack             PARM((CBUTT *));
+/*************************** XVINFO.C ***************************/
+void  CreateInfo           PARM((const char *));
+void  InfoBox              PARM((int));
+void  RedrawInfo           PARM((int, int, int, int));
+void  SetInfoMode          PARM((int));
+char *GetISTR              PARM((int));
 
+#if defined(__STDC__) && !defined(NOSTDHDRS)
+void  SetISTR(int, ...);
+#else
+void  SetISTR();
+#endif
 
-void   MBCreate            PARM((MBUTT *, Window, int, int, u_int, u_int, 
-				 char *, 
-				 char **, int,u_long,u_long, u_long, u_long));
 
-void   MBRedraw            PARM((MBUTT *));
-void   MBSetActive         PARM((MBUTT *, int));
-int    MBWhich             PARM((MBUTT *));
-void   MBSelect            PARM((MBUTT *, int));
-int    MBClick             PARM((MBUTT *, int, int));
-int    MBTrack             PARM((MBUTT *));
+/*************************** XVMISC.C ***************************/
+void StoreDeleteWindowProp PARM((Window));
+Window CreateWindow        PARM((const char *, const char *, const char *,
+				 int, int, u_long, u_long, int));
+void DrawString            PARM((Window, int, int, const char *));
+void CenterString          PARM((Window, int, int, const char *));
+void ULineString           PARM((Window, int, int, const char *));
+int  StringWidth           PARM((const char *));
+int  CursorKey             PARM((KeySym, int, int));
+void FakeButtonPress       PARM((BUTT *));
+void FakeKeyPress          PARM((Window, KeySym));
+void GenExpose             PARM((Window, int, int, u_int, u_int));
+void DimRect               PARM((Window, int, int, u_int, u_int, u_long));
+
+void Draw3dRect            PARM((Window, int, int, u_int, u_int, int, int,
+				 u_long, u_long, u_long));
+
+void RemapKeyCheck         PARM((KeySym, char *, int *));
+void xvDestroyImage        PARM((XImage *));
+void SetCropString         PARM((void));
+void SetSelectionString    PARM((void));
+void Warning               PARM((void));
+void FatalError            PARM((const char *));
+void Quit                  PARM((int));
+void LoadFishCursors       PARM((void));
+void WaitCursor            PARM((void));
+void SetCursors            PARM((int));
+const char *BaseName       PARM((const char *));
+
+void DrawTempGauge         PARM((Window, int, int, int, int, double, u_long,
+				 u_long, u_long, u_long, const char *));
+void ProgressMeter         PARM((int, int, int, const char *));
+void XVDeletedFile         PARM((char *));
+void XVCreatedFile         PARM((char *));
+void xvbcopy               PARM((const char *, char *, size_t));
+int  xvbcmp                PARM((const char *, const char *, size_t));
+void xvbzero               PARM((char *, size_t));
+void xv_getwd              PARM((char *, size_t));
+char *xv_strstr            PARM((const char *, const char *));
+FILE *xv_fopen             PARM((const char *, const char *));
+void xv_mktemp             PARM((char *, const char *));
+void Timer                 PARM((int));
 
 
-/**************************** XVGRAF.C ***************************/
-void   CreateGraf          PARM((GRAF *, Window, int, int, 
-				 u_long, u_long, char *));
+/*************************** XVPOPUP.C ***************************/
+void  CenterMapWindow      PARM((Window, int, int, int, int));
+int   PopUp                PARM((const char *, const char **, int));
+void  ErrPopUp             PARM((const char *, const char *));
+int   GetStrPopUp          PARM((const char *, const char **, int, char *, int,
+				 const char *, int));
+int   GrabPopUp            PARM((int *, int *));
+int   PadPopUp             PARM((int *, char **, int *, int *, int *, int *));
+void  ClosePopUp           PARM((void));
+void  OpenAlert            PARM((const char *));
+void  CloseAlert           PARM((void));
+int   PUCheckEvent         PARM((XEvent *));
 
-void   InitGraf            PARM((GRAF *));
-void   RedrawGraf          PARM((GRAF *, int));
-int    ClickGraf           PARM((GRAF *, Window, int, int));
-int    GrafKey             PARM((GRAF *, char *));
-void   GenerateGrafFunc    PARM((GRAF *, int));
-void   Graf2Str            PARM((GRAF_STATE *, char *));
-int    Str2Graf            PARM((GRAF_STATE *, char *));
-void   GetGrafState        PARM((GRAF *, GRAF_STATE *));
-int    SetGrafState        PARM((GRAF *, GRAF_STATE *));
-void   InitSpline          PARM((int *, int *, int, double *));
-double EvalSpline          PARM((int *, int *, double *, int, double));
 
+/**************************** XVROOT.C ****************************/
+void MakeRootPic           PARM((void));
+void ClearRoot             PARM((void));
+void SaveRootInfo          PARM((void));
+void KillOldRootInfo       PARM((void));
 
-/**************************** XVGIF.C ***************************/
-int LoadGIF                PARM((char *, PICINFO *));
 
-/*************************** XVGIFWR.C **************************/
-int WriteGIF               PARM((FILE *, byte *, int, int, int, 
-				 byte *, byte *, byte *, int, int, char *));
+/*************************** XVSCRL.C ***************************/
+void SCCreate              PARM((SCRL *, Window, int, int, int, int,
+				 int, int, int, int, u_long, u_long,
+				 u_long, u_long, void (*)(int, SCRL *)));
 
-/**************************** XVPM.C ****************************/
-int LoadPM                 PARM((char *, PICINFO *));
-int WritePM                PARM((FILE *, byte *, int, int, int, byte *, 
-				 byte *, byte *, int, int, char *));
+void SCChange              PARM((SCRL *, int, int, int, int, int,
+				 int, int, int));
 
-/**************************** XVPBM.C ***************************/
-int LoadPBM                PARM((char *, PICINFO *));
-int WritePBM               PARM((FILE *, byte *, int, int, int, byte *, 
-				 byte *, byte *, int, int, int, char *));
+void SCSetRange            PARM((SCRL *, int, int, int, int));
+int  SCSetVal              PARM((SCRL *, int));
+void SCRedraw              PARM((SCRL *));
+void SCTrack               PARM((SCRL *, int, int));
 
-/**************************** XVXBM.C ***************************/
-int LoadXBM                PARM((char *, PICINFO *));
-int WriteXBM               PARM((FILE *, byte *, int, int, byte *, byte *, 
-				 byte *, char *));
 
-/**************************** XVSUNRAS.C ***************************/
-int LoadSunRas             PARM((char *, PICINFO *));
-int WriteSunRas            PARM((FILE *, byte *, int, int, int, byte *, 
-				 byte *, byte*, int, int, int));
+/*************************** XVSMOOTH.C ***************************/
+byte *SmoothResize         PARM((byte *, int, int, int, int, byte *, byte *,
+				 byte *, byte *, byte *, byte *, int));
 
-/**************************** XVBMP.C ***************************/
-int LoadBMP                PARM((char *, PICINFO *));
-int WriteBMP               PARM((FILE *, byte *, int, int, int, byte *, 
-				 byte *, byte *, int, int));
+byte *Smooth24             PARM((byte *, int, int, int, int, int,
+				 byte *, byte *, byte *));
 
-/**************************** XVRLE.C ***************************/
-int LoadRLE                PARM((char *, PICINFO *));
+byte *DoColorDither        PARM((byte *, byte *, int, int, byte *, byte *,
+				 byte *, byte *, byte *, byte *, int));
 
-/**************************** XVIRIS.C ***************************/
-int LoadIRIS               PARM((char *, PICINFO *));
-int WriteIRIS              PARM((FILE *, byte *, int, int, int, byte *, 
-				 byte *, byte *, int, int));
+byte *Do332ColorDither     PARM((byte *, byte *, int, int, byte *, byte *,
+				 byte *, byte *, byte *, byte *, int));
 
-/**************************** XVPCX.C ***************************/
-int LoadPCX                PARM((char *, PICINFO *));
 
-/**************************** XVIFF.C ***************************/
-int LoadIFF                PARM((char *, PICINFO *));
+/*************************** XVTEXT.C ************************/
+void CreateTextWins        PARM((const char *, const char *));
+int  TextView              PARM((const char *));
+void OpenTextView          PARM((const char *, int, const char *, int));
 
-/**************************** XVTARGA.C ***************************/
-int LoadTarga              PARM((char *, PICINFO *));
-int WriteTarga             PARM((FILE *, byte *, int, int, int, byte *, 
-				 byte *, byte *, int, int));
+void OpenCommentText       PARM((void));
+void CloseCommentText      PARM((void));
+void ChangeCommentText     PARM((void));
 
-/**************************** XVXPM.C ***************************/
-int LoadXPM                PARM((char *, PICINFO *));
-int WriteXPM               PARM((FILE *, byte *, int, int, int, byte *, 
-				 byte *, byte *, int, int, char *, char *));
+void ShowLicense           PARM((void));
+void ShowKeyHelp           PARM((void));
 
-/**************************** XVXWD.C ***************************/
-int LoadXWD                PARM((char *, PICINFO *));
+void HideTextWindows       PARM((void));
+void UnHideTextWindows     PARM((void));
+void RaiseTextWindows      PARM((void));
+void SetTextCursor         PARM((Cursor));
+void KillTextWindows       PARM((void));
+int  TextCheckEvent        PARM((XEvent *, int *, int *));
+int  TextDelWin            PARM((Window));
+
+int  CharsetCheckEvent     PARM((XEvent *));
+int  CharsetDelWin         PARM((Window));
+
+
+/**************************** XVVD.C ****************************/
+void  Vdinit               PARM((void));
+void  Vdsettle             PARM((void));
+int   Chvdir               PARM((char *));
+void  Dirtovd              PARM((char *));
+void  Vdtodir              PARM((char *));
+void  Dirtosubst           PARM((char *));
+int   Mkvdir               PARM((char *));
+void  Mkvdir_force         PARM((char *));
+int   Rmvdir               PARM((char *));
+int   Movevdir             PARM((char *, char *));
+int   Isarchive            PARM((char *));
+int   Isvdir               PARM((char *));
+void  vd_HUPhandler        PARM((void));
+void  vd_handler           PARM((int));
+int   vd_Xhandler          PARM((Display *, XErrorEvent *));
+int   vd_XIOhandler        PARM((Display *));
+void  vd_handler_setup     PARM((void));
+
+
+
+/*=======================================================================*/
+/*                             IMAGE FORMATS                             */
+/*=======================================================================*/
+
+/**************************** XVBMP.C ***************************/
+int LoadBMP                PARM((char *, PICINFO *));
+int WriteBMP               PARM((FILE *, byte *, int, int, int, byte *,
+				 byte *, byte *, int, int));
 
 /**************************** XVFITS.C ***************************/
 int LoadFITS               PARM((char *, PICINFO *, int));
 int WriteFITS              PARM((FILE *, byte *, int, int, int, byte *,
 				 byte *, byte *, int, int, char *));
 
+/**************************** XVGIF.C ***************************/
+int LoadGIF                PARM((char *, PICINFO *));
+
+/**************************** XVGIFWR.C **************************/
+int WriteGIF               PARM((FILE *, byte *, int, int, int,
+				 byte *, byte *, byte *, int, int, char *));
+
+/**************************** XVHIPS.C ***************************/
+int   LoadHIPS             PARM((char *, PICINFO *));
+
+/**************************** XVIFF.C ***************************/
+int LoadIFF                PARM((char *, PICINFO *));
+
+/**************************** XVIRIS.C ***************************/
+int LoadIRIS               PARM((char *, PICINFO *));
+int WriteIRIS              PARM((FILE *, byte *, int, int, int, byte *,
+				 byte *, byte *, int, int));
+
+/**************************** XVJP2K.C ***************************/
+int  LoadJPC               PARM((char *, register PICINFO *, int));
+int  LoadJP2               PARM((char *, register PICINFO *, int));
+void CreateJP2KW           PARM((void));
+void JP2KSaveParams        PARM((int, char *, int));
+void JP2KDialog            PARM((int vis));
+int  JP2KCheckEvent        PARM((register XEvent *));
+void VersionInfoJP2K       PARM((void));		/* GRR 20070304 */
+
 /**************************** XVJPEG.C ***************************/
 int  LoadJFIF              PARM((char *, PICINFO *, int));
 void CreateJPEGW           PARM((void));
 void JPEGDialog            PARM((int));
 int  JPEGCheckEvent        PARM((XEvent *));
 void JPEGSaveParams        PARM((char *, int));
+void VersionInfoJPEG       PARM((void));		/* GRR 19980605 */
 
-/**************************** XVTIFF.C ***************************/
-int   LoadTIFF             PARM((char *, PICINFO *));
-void  CreateTIFFW          PARM((void));
-void  TIFFDialog           PARM((int));
-int   TIFFCheckEvent       PARM((XEvent *));
-void  TIFFSaveParams       PARM((char *, int));
+/**************************** XVMAG.C ***************************/
+int   LoadMAG              PARM((char *, PICINFO *));
+int   WriteMAG             PARM((FILE *, byte *, int, int, int,
+				 byte *, byte *, byte *, int, int, char *));
+
+/**************************** XVMAKI.C ***************************/
+int   LoadMAKI             PARM((char *, PICINFO *));
+int   WriteMAKI            PARM((FILE *, byte *, int, int, int,
+				 byte *, byte *, byte *, int, int));
+
+/**************************** XVMGCSFX.C ***************************/
+int   is_mgcsfx            PARM((char *, unsigned char *, int));
+char *mgcsfx_auto_input_com PARM((char *));
+int   LoadMGCSFX           PARM((char *, PICINFO *));
+void  CreateMGCSFXW        PARM((void));
+void  MGCSFXDialog         PARM((int));
+int   MGCSFXCheckEvent     PARM((XEvent *));
+int   MGCSFXSaveParams     PARM((char *, int));
+
+int getInputCom            PARM((void));
+int getOutputCom           PARM((void));
+
+/**************************** XVPBM.C ***************************/
+#ifdef HAVE_MGCSFX
+int LoadPBM                PARM((char *, PICINFO *, int));
+#else
+int LoadPBM                PARM((char *, PICINFO *));
+#endif
+int WritePBM               PARM((FILE *, byte *, int, int, int, byte *,
+				 byte *, byte *, int, int, int, char *));
+
+/**************************** XVPCD.C ***************************/
+int   LoadPCD              PARM((char *, PICINFO *, int));
+void  CreatePCDW           PARM((void));
+void  PCDDialog            PARM((int));
+int   PCDCheckEvent        PARM((XEvent *));
+void  PCDSetParamOptions   PARM((const char *));
+
+/**************************** XVPCX.C ***************************/
+int LoadPCX                PARM((char *, PICINFO *));
 
 /**************************** XVPDS.C ***************************/
 int LoadPDS                PARM((char *, PICINFO *));
 
-/*************************** XVPS.C ***************************/
+/**************************** XVPI.C ***************************/
+int   LoadPi               PARM((char *, PICINFO *));
+int   WritePi              PARM((FILE *, byte *, int, int, int,
+				 byte *, byte *, byte *, int, int, char *));
+
+/**************************** XVPIC.C ***************************/
+int   LoadPIC              PARM((char *, PICINFO *));
+int   WritePIC             PARM((FILE *, byte *, int, int, int,
+				 byte *, byte *, byte *, int, int, char *));
+
+/**************************** XVPIC2.C ***************************/
+int   LoadPIC2             PARM((char *, PICINFO *, int));
+void  CreatePIC2W          PARM((void));
+void  PIC2Dialog           PARM((int));
+int   PIC2CheckEvent       PARM((XEvent *));
+int   PIC2SetParamOptions  PARM((char *));
+
+/**************************** XVPM.C ****************************/
+int LoadPM                 PARM((char *, PICINFO *));
+int WritePM                PARM((FILE *, byte *, int, int, int, byte *,
+				 byte *, byte *, int, int, char *));
+
+/**************************** XVPNG.C ***************************/
+int  LoadPNG               PARM((char *, PICINFO *));
+void CreatePNGW            PARM((void));
+void PNGDialog             PARM((int));
+int  PNGCheckEvent         PARM((XEvent *));
+void PNGSaveParams         PARM((char *, int));
+void VersionInfoPNG        PARM((void));		/* GRR 19980605 */
+
+/**************************** XVPS.C ****************************/
 void  CreatePSD            PARM((char *));
 void  PSDialog             PARM((int));
 int   PSCheckEvent         PARM((XEvent *));
@@ -1624,56 +2085,46 @@
 void  PSResize             PARM((void));
 int   LoadPS               PARM((char *, PICINFO *, int));
 
-/*************************** XVPOPUP.C ***************************/
-void  CenterMapWindow      PARM((Window, int, int, int, int));
-int   PopUp                PARM((char *, char **, int));
-void  ErrPopUp             PARM((char *, char *));
-int   GetStrPopUp          PARM((char *, char **, int, char *, int, 
-				 char *, int));
-int   GrabPopUp            PARM((int *, int *));
-int   PadPopUp             PARM((int *, char **, int *, int *, int *, int *));
-void  ClosePopUp           PARM((void));
-void  OpenAlert            PARM((char *));
-void  CloseAlert           PARM((void));
-int   PUCheckEvent         PARM((XEvent *));
-void  TextRect             PARM((Window, char *, int, int, int, int, u_long));
+/**************************** XVRLE.C ***************************/
+int LoadRLE                PARM((char *, PICINFO *));
 
-/*************************** XVDFLT.C ***************************/
-void LoadDfltPic           PARM((PICINFO *));
-void xbm2pic               PARM((byte *, int, int, byte *, int, int, int, int,
-				 int));
-void DrawStr2Pic           PARM((char *, int, int, byte *, int, int, int));
+/**************************** XVSUNRAS.C ***************************/
+int LoadSunRas             PARM((char *, PICINFO *));
+int WriteSunRas            PARM((FILE *, byte *, int, int, int, byte *,
+				 byte *, byte*, int, int, int));
 
-/**************************** XVGRAB.C ***************************/
-int Grab                   PARM((void));
-int LoadGrab               PARM((PICINFO *));
+/**************************** XVTARGA.C ***************************/
+int LoadTarga              PARM((char *, PICINFO *));
+int WriteTarga             PARM((FILE *, byte *, int, int, int, byte *,
+				 byte *, byte *, int, int));
 
+/**************************** XVTIFF.C ***************************/
+int   LoadTIFF             PARM((char *, PICINFO *, int));
+void  CreateTIFFW          PARM((void));
+void  TIFFDialog           PARM((int));
+int   TIFFCheckEvent       PARM((XEvent *));
+void  TIFFSaveParams       PARM((char *, int));
+void  VersionInfoTIFF      PARM((void));		/* GRR 19980605 */
 
-/**************************** XVCUT.C ***************************/
-int  CutAllowed            PARM((void));
-int  PasteAllowed          PARM((void));
-void DoImgCopy             PARM((void));
-void DoImgCut              PARM((void));
-void DoImgClear            PARM((void));
-void DoImgPaste            PARM((void));
+/**************************** XVWBMP.C ***************************/
+int LoadWBMP               PARM((char *, PICINFO *));
+int WriteWBMP              PARM((FILE *, byte *, int, int, int, byte *,
+				 byte *, byte *, int, int));
 
-void SaveToClip            PARM((byte *));
-void InitSelection         PARM((void));
-int  HaveSelection         PARM((void));
-int  GetSelType            PARM((void));
-void GetSelRCoords         PARM((int *, int *, int *, int *));
-void EnableSelection       PARM((int));
-void DrawSelection         PARM((int));
-int  DoSelection           PARM((XButtonEvent *));
-void MoveGrowSelection     PARM((int, int, int, int));
-void BlinkSelection        PARM((int));
-void FlashSelection        PARM((int));
+/**************************** XVXBM.C ***************************/
+int LoadXBM                PARM((char *, PICINFO *));
+int WriteXBM               PARM((FILE *, byte *, int, int, byte *, byte *,
+				 byte *, char *));
 
-void CropRect2Rect         PARM((int*,int*,int*,int*, int,int,int,int));
-void CoordE2C              PARM((int, int, int *, int *));
-void CoordC2E              PARM((int, int, int *, int *));
-void CoordP2C              PARM((int, int, int *, int *));
-void CoordC2P              PARM((int, int, int *, int *));
-void CoordP2E              PARM((int, int, int *, int *));
-void CoordE2P              PARM((int, int, int *, int *));
+/**************************** XVXPM.C ***************************/
+int LoadXPM                PARM((char *, PICINFO *));
+int WriteXPM               PARM((FILE *, byte *, int, int, int, byte *,
+				 byte *, byte *, int, int, char *, char *));
 
+/**************************** XVXWD.C ***************************/
+int LoadXWD                PARM((char *, PICINFO *));
+
+/**************************** XVZX.C [JCE] **********************/
+int LoadZX                 PARM((char *, PICINFO *));
+int WriteZX                PARM((FILE *, byte *, int, int, int, byte *,
+				 byte *, byte *, int, int, char *));
diff -ru xv-3.10a/xv24to8.c xv-3.10a-enhancements/xv24to8.c
--- xv-3.10a/xv24to8.c	1995-01-13 11:49:21.000000000 -0800
+++ xv-3.10a-enhancements/xv24to8.c	2007-05-12 13:56:44.000000000 -0700
@@ -14,15 +14,15 @@
  *
  * The Conv24to8 procedure will set up the following:  it will allocate, make
  * & return 'pic8', a 'w' by 'h' (passed in values) 8-bit picture.
- * it will load up the rmap, gmap and bmap colormap arrays.  it will NOT 
+ * it will load up the rmap, gmap and bmap colormap arrays.  it will NOT
  * calculate numcols, since the cmap sort procedure has to be called anyway
  *
- * Conv24to8 returns 'pic8' if successful, 'NULL' on failure (presumably on a 
+ * Conv24to8 returns 'pic8' if successful, 'NULL' on failure (presumably on a
  * malloc())
  *
- * The 'slow' code, while still based on Heckbert's Median Cut algorithm, 
+ * The 'slow' code, while still based on Heckbert's Median Cut algorithm,
  * has been shamelessly lifted from the Independent JPEG Group's software
- * (jquant2.c), as (for a variety of reasons) theirs was far better than 
+ * (jquant2.c), as (for a variety of reasons) theirs was far better than
  * the version I was previously using.  Thanks guys!
  *
  * Also, as is my way, I've stripped out most of the IJG's well-written
@@ -65,10 +65,10 @@
 {
   /* returns pointer to new 8-bit-per-pixel image (w*h) if successful, or
      NULL if unsuccessful */
-  
+
   int   i;
   byte *pic8;
-  
+
   if (!pic24) return NULL;
 
   pic8 = (byte *) malloc((size_t) (w * h));
@@ -79,9 +79,9 @@
 
   if (nc<=0) nc = 255;  /* 'nc == 0' breaks code */
 
-  if (!noqcheck && quick_check(pic24, w,h, pic8, rm,gm,bm, nc)) { 
+  if (!noqcheck && quick_check(pic24, w,h, pic8, rm,gm,bm, nc)) {
     SetISTR(ISTR_INFO,"No color compression was necessary.\n");
-    return pic8;   
+    return pic8;
   }
 
   switch (conv24) {
@@ -89,19 +89,19 @@
     SetISTR(ISTR_INFO,"Doing 'quick' 24-bit to 8-bit conversion.");
     i = quick_quant(pic24, w, h, pic8, rm, gm, bm, nc);
     break;
-    
+
   case CONV24_BEST:
     SetISTR(ISTR_INFO,"Doing 'best' 24-bit to 8-bit conversion.");
     i = ppm_quant(pic24, w, h, pic8, rm, gm, bm, nc);
     break;
-    
+
   case CONV24_SLOW:
   default:
     SetISTR(ISTR_INFO,"Doing 'slow' 24-bit to 8-bit conversion.");
     i = slow_quant(pic24, w, h, pic8, rm, gm, bm, nc);
     break;
   }
-  
+
   if (i) { free(pic8);  pic8 = NULL; }
   return pic8;
 }
@@ -134,7 +134,7 @@
 
   return pic24;
 }
-  
+
 
 /****************************/
 static int quick_check(pic24, w,h, pic8, rmap,gmap,bmap, maxcol)
@@ -154,10 +154,10 @@
   if (maxcol>256) maxcol = 256;
 
   /* put the first color in the table by hand */
-  nc = 0;  mid = 0;  
+  nc = 0;  mid = 0;
 
   for (i=w*h,p=pic24; i; i--) {
-    col  = (((u_long) *p++) << 16);  
+    col  = (((u_long) *p++) << 16);
     col += (((u_long) *p++) << 8);
     col +=  *p++;
 
@@ -184,7 +184,7 @@
      pic24 into colormap offsets into 'colors' */
 
   for (i=w*h,p=pic24, pix=pic8; i; i--,pix++) {
-    col  = (((u_long) *p++) << 16);  
+    col  = (((u_long) *p++) << 16);
     col += (((u_long) *p++) << 8);
     col +=  *p++;
 
@@ -206,7 +206,7 @@
 
   /* and load up the 'desired colormap' */
   for (i=0; i<nc; i++) {
-    rmap[i] =  colors[i]>>16;  
+    rmap[i] =  colors[i]>>16;
     gmap[i] = (colors[i]>>8) & 0xff;
     bmap[i] =  colors[i]     & 0xff;
   }
@@ -224,7 +224,7 @@
 {
   /* called after 'pic8' has been alloced, pWIDE,pHIGH set up, mono/1-bit
      checked already */
-  
+
 /* up to 256 colors:     3 bits R, 3 bits G, 2 bits B  (RRRGGGBB) */
 #define RMASK      0xe0
 #define RSHIFT        0
@@ -252,7 +252,7 @@
     gmap[i] = (((i<<GSHIFT) & GMASK) * 255 + GMASK/2) / GMASK;
     bmap[i] = (((i<<BSHIFT) & BMASK) * 255 + BMASK/2) / BMASK;
   }
-  
+
 
   thisline = (int *) malloc(pwide3 * sizeof(int));
   nextline = (int *) malloc(pwide3 * sizeof(int));
@@ -262,40 +262,40 @@
     fprintf(stderr,"%s: unable to allocate memory in quick_quant()\n", cmd);
     return(1);
   }
-  
+
   /* get first line of picture */
   for (j=pwide3, tmpptr=nextline; j; j--) *tmpptr++ = (int) *p24++;
-  
+
   for (i=0; i<h; i++) {
     tmpptr = thisline;  thisline = nextline;  nextline = tmpptr;   /* swap */
-    
+
     if ((i&0x3f) == 0) WaitCursor();
 
     if (i!=imax)   /* get next line */
       for (j=pwide3, tmpptr=nextline; j; j--)
 	*tmpptr++ = (int) *p24++;
-    
+
     for (j=0, thisptr=thisline, nextptr=nextline; j<w; j++,pp++) {
       r1 = *thisptr++;  g1 = *thisptr++;  b1 = *thisptr++;
-      RANGE(r1,0,255);  RANGE(g1,0,255);  RANGE(b1,0,255);  
-      
+      RANGE(r1,0,255);  RANGE(g1,0,255);  RANGE(b1,0,255);
+
       /* choose actual pixel value */
-      val = (((r1&RMASK)>>RSHIFT) | ((g1&GMASK)>>GSHIFT) | 
+      val = (((r1&RMASK)>>RSHIFT) | ((g1&GMASK)>>GSHIFT) |
 	     ((b1&BMASK)>>BSHIFT));
       *pp = val;
-      
+
       /* compute color errors */
       r1 -= rmap[val];
       g1 -= gmap[val];
       b1 -= bmap[val];
-      
+
       /* Add fractions of errors to adjacent pixels */
       if (j!=jmax) {  /* adjust RIGHT pixel */
 	thisptr[0] += (r1*7) / 16;
 	thisptr[1] += (g1*7) / 16;
 	thisptr[2] += (b1*7) / 16;
       }
-      
+
       if (i!=imax) {	/* do BOTTOM pixel */
 	nextptr[0] += (r1*5) / 16;
 	nextptr[1] += (g1*5) / 16;
@@ -316,7 +316,7 @@
       }
     }
   }
-  
+
   free(thisline);
   free(nextline);
   return 0;
@@ -329,7 +329,7 @@
 #undef BMASK
 #undef BSHIFT
 }
-      
+
 
 
 
@@ -381,7 +381,7 @@
 
 /* Luminance macro. */
 
-/* 
+/*
  * #define PPM_LUMIN(p) \
  *   ( 0.299 * PPM_GETR(p) + 0.587 * PPM_GETG(p) + 0.114 * PPM_GETB(p) )
  */
@@ -449,18 +449,18 @@
      byte *pic24, *pic8, *rmap, *gmap, *bmap;
      int  cols, rows, newcolors;
 {
-  pixel**          pixels;
-  register pixel*  pP;
-  int              row;
-  register int     col, limitcol;
-  pixval           maxval, newmaxval;
-  int              colors;
-  register int     index;
-  chist_vec chv, colormap;
-  chash_table  cht;
-  int              i;
-  unsigned char    *picptr;
-  static char      *fn = "ppmquant()";
+  pixel**           pixels;
+  register pixel*   pP;
+  int               row;
+  register int      col, limitcol;
+  pixval            maxval, newmaxval;
+  int               colors;
+  register int      index;
+  chist_vec         chv, colormap;
+  chash_table       cht;
+  int               i;
+  unsigned char     *picptr;
+  static const char *fn = "ppmquant()";
 
   index = 0;
   maxval = 255;
@@ -472,7 +472,7 @@
 
   if (DEBUG) fprintf(stderr,"%s: remapping to ppm-style internal fmt\n", fn);
   WaitCursor();
-  
+
   pixels = (pixel **) malloc(rows * sizeof(pixel *));
   if (!pixels) FatalError("couldn't allocate 'pixels' array");
   for (row=0; row<rows; row++) {
@@ -488,7 +488,7 @@
   if (DEBUG) fprintf(stderr,"%s: done format remapping\n", fn);
 
 
-    
+
 
   /*
    *  attempt to make a histogram of the colors, unclustered.
@@ -503,7 +503,7 @@
 
     chv = ppm_computechist(pixels, cols, rows, MAXCOLORS, &colors);
     if (chv != (chist_vec) 0) break;
-    
+
     if (DEBUG) fprintf(stderr, "%s: too many colors!\n", fn);
     newmaxval = maxval / 2;
     if (DEBUG) fprintf(stderr, "%s: rescaling colors (maxval=%d) %s\n",
@@ -635,7 +635,7 @@
   int boxes;
 
   bv = (box_vector) malloc(sizeof(struct box) * newcolors);
-  colormap = (chist_vec) 
+  colormap = (chist_vec)
              malloc(sizeof(struct chist_item) * newcolors );
 
   if (!bv || !colormap) FatalError("unable to malloc in mediancut()");
@@ -723,7 +723,7 @@
       else if (gl >= bl)
 	qsort((char*) &(chv[indx]), (size_t) clrs, sizeof(struct chist_item),
 	      greencompare );
-      else 
+      else
 	qsort((char*) &(chv[indx]), (size_t) clrs, sizeof(struct chist_item),
 	      bluecompare );
     }
@@ -750,7 +750,7 @@
     ++boxes;
     qsort((char*) bv, (size_t) boxes, sizeof(struct box), sumcompare);
   }  /* while (boxes ... */
-  
+
   /*
    ** Ok, we've got enough boxes.  Now choose a representative color for
    ** each box.  There are a number of possible ways to make this choice.
@@ -761,7 +761,7 @@
    ** method is used by switching the commenting on the REP_ defines at
    ** the beginning of this source file.
    */
-  
+
   for (bi=0; bi<boxes; bi++) {
     /* REP_AVERAGE_PIXELS version */
     register int indx = bv[bi].index;
@@ -791,7 +791,7 @@
 static int redcompare(p1, p2)
      const void *p1, *p2;
 {
-  return (int) PPM_GETR( ((chist_vec)p1)->color ) - 
+  return (int) PPM_GETR( ((chist_vec)p1)->color ) -
          (int) PPM_GETR( ((chist_vec)p2)->color );
 }
 
@@ -799,7 +799,7 @@
 static int greencompare(p1, p2)
      const void *p1, *p2;
 {
-  return (int) PPM_GETG( ((chist_vec)p1)->color ) - 
+  return (int) PPM_GETG( ((chist_vec)p1)->color ) -
          (int) PPM_GETG( ((chist_vec)p2)->color );
 }
 
@@ -807,7 +807,7 @@
 static int bluecompare(p1, p2)
      const void *p1, *p2;
 {
-  return (int) PPM_GETB( ((chist_vec)p1)->color ) - 
+  return (int) PPM_GETB( ((chist_vec)p1)->color ) -
          (int) PPM_GETB( ((chist_vec)p2)->color );
 }
 
@@ -821,7 +821,7 @@
 
 
 /****************************************************************************/
-static chist_vec 
+static chist_vec
   ppm_computechist(pixels, cols, rows, maxcolors, colorsP)
      pixel** pixels;
      int cols, rows, maxcolors;
@@ -840,7 +840,7 @@
 
 
 /****************************************************************************/
-static chash_table ppm_computechash(pixels, cols, rows, 
+static chash_table ppm_computechash(pixels, cols, rows,
 					    maxcolors, colorsP )
      pixel** pixels;
      int cols, rows, maxcolors;
@@ -861,14 +861,14 @@
 
       for (chl = cht[hash]; chl != (chist_list) 0; chl = chl->next)
 	if (PPM_EQUAL(chl->ch.color, *pP)) break;
-      
+
       if (chl != (chist_list) 0) ++(chl->ch.value);
       else {
 	if ((*colorsP)++ > maxcolors) {
 	  ppm_freechash(cht);
 	  return (chash_table) 0;
 	}
-	
+
 	chl = (chist_list) malloc(sizeof(struct chist_list_item));
 	if (!chl) FatalError("ran out of memory computing hash table");
 
@@ -878,7 +878,7 @@
 	cht[hash] = chl;
       }
     }
-  
+
   return cht;
 }
 
@@ -1114,7 +1114,7 @@
   register int i;
   register long maxc = 0;
   boxptr which = NULL;
-  
+
   for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
     if (boxp->colorcount > maxc && boxp->volume > 0) {
       which = boxp;
@@ -1133,7 +1133,7 @@
   register int i;
   register INT32 maxv = 0;
   boxptr which = NULL;
-  
+
   for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
     if (boxp->volume > maxv) {
       which = boxp;
@@ -1153,11 +1153,11 @@
   int c0min,c0max,c1min,c1max,c2min,c2max;
   INT32 dist0,dist1,dist2;
   long ccount;
-  
+
   c0min = boxp->c0min;  c0max = boxp->c0max;
   c1min = boxp->c1min;  c1max = boxp->c1max;
   c2min = boxp->c2min;  c2max = boxp->c2max;
-  
+
   if (c0max > c0min)
     for (c0 = c0min; c0 <= c0max; c0++)
       for (c1 = c1min; c1 <= c1max; c1++) {
@@ -1229,7 +1229,7 @@
   dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
   dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
   boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
-  
+
   ccount = 0;
   for (c0 = c0min; c0 <= c0max; c0++)
     for (c1 = c1min; c1 <= c1max; c1++) {
@@ -1315,11 +1315,11 @@
   long c0total = 0;
   long c1total = 0;
   long c2total = 0;
-  
+
   c0min = boxp->c0min;  c0max = boxp->c0max;
   c1min = boxp->c1min;  c1max = boxp->c1max;
   c2min = boxp->c2min;  c2max = boxp->c2max;
-  
+
   for (c0 = c0min; c0 <= c0max; c0++)
     for (c1 = c1min; c1 <= c1max; c1++) {
       histp = & histogram[c0][c1][c2min];
@@ -1332,7 +1332,7 @@
 	}
       }
     }
-  
+
   sl_colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
   sl_colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
   sl_colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
@@ -1505,12 +1505,12 @@
   bptr = bestdist;
   for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
     *bptr++ = 0x7FFFFFFFL;
-  
+
   /* Nominal steps between cell centers ("x" in Thomas article) */
 #define STEP_C0  ((1 << C0_SHIFT) * C0_SCALE)
 #define STEP_C1  ((1 << C1_SHIFT) * C1_SCALE)
 #define STEP_C2  ((1 << C2_SHIFT) * C2_SCALE)
-  
+
   for (i = 0; i < numcolors; i++) {
     icolor = colorlist[i];
     /* Compute (square of) distance from minc0/c1/c2 to this color */
@@ -1576,7 +1576,7 @@
   minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
   minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
   minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
-  
+
   numcolors = find_nearby_colors(minc0, minc1, minc2, colorlist);
 
   /* Determine the actually nearest colors. */
diff -ru xv-3.10a/xvalg.c xv-3.10a-enhancements/xvalg.c
--- xv-3.10a/xvalg.c	1994-12-22 14:34:47.000000000 -0800
+++ xv-3.10a-enhancements/xvalg.c	2007-05-12 16:07:37.000000000 -0700
@@ -38,7 +38,7 @@
 				 double, int));
 static void doPixel        PARM((byte *,int,int,byte *, int,int,int,int,
 				 int, int));
-static void doSpread       PARM((byte *,int,int,byte *, int,int,int,int, 
+static void doSpread       PARM((byte *,int,int,byte *, int,int,int,int,
 				 int, int));
 static void doMedianFilter PARM((byte *,int,int,byte *, int,int,int,int, int));
 
@@ -53,7 +53,7 @@
 static int  start24bitAlg  PARM((byte **, byte **));
 static void end24bitAlg    PARM((byte *, byte *));
 
-static void printUTime     PARM((char *));
+static void printUTime     PARM((const char *));
 
 static byte *origPic = (byte *) NULL;
 static int  origPicType;
@@ -70,10 +70,11 @@
 
 /***************************/
 static void printUTime(str)
-     char *str;
+     const char *str;
 {
 #ifdef TIMING_TEST
-  int i;  struct rusage ru;
+  int i;
+  struct rusage ru;
 
   i = getrusage(RUSAGE_SELF, &ru);
   fprintf(stderr,"%s: utime = %d.%d seconds\n",
@@ -89,7 +90,7 @@
 /************************************************************/
 void AlgInit()
 {
-  /* called whenver an image file is loaded.  disposes of origPic 
+  /* called whenver an image file is loaded.  disposes of origPic
      if neccessary, and points it to null */
 
   if (origPic) free(origPic);
@@ -160,16 +161,16 @@
 {
   /* runs a n*n convolution mask (all 1's) over 'pic',
      producing a 24-bit version.  Then calls 24to8 to generate a new 8-bit
-     image, and installs it. 
+     image, and installs it.
 
      Note that 'n' must be odd for things to work properly */
 
-  byte        *pic24, *tmpPic;
-  int          i, sx,sy,sw,sh, n;
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  char         txt[256];
-  static char  buf[64] = { '3', '\0' };
-  
+  byte              *pic24, *tmpPic;
+  int                i, sx,sy,sw,sh, n;
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  char               txt[256];
+  static char        buf[64] = { '3', '\0' };
+
   sprintf(txt, "Blur:                                   \n\n%s",
 	  "Enter mask size (ex. 3, 5, 7, ...)");
 
@@ -178,7 +179,7 @@
   n = atoi(buf);
 
   if (n < 1 || (n&1)!=1) {
-    ErrPopUp("Error:  The value entered must be odd and greater than zero.", 
+    ErrPopUp("Error:  The value entered must be odd and greater than zero.",
 	     "\nOh!");
     return;
   }
@@ -194,7 +195,7 @@
 
   if (start24bitAlg(&pic24, &tmpPic)) return;
   xvbcopy((char *) pic24, (char *) tmpPic, (size_t) (pWIDE*pHIGH*3));
-    
+
   doBlurConvolv(pic24, pWIDE,pHIGH, tmpPic, sx,sy,sw,sh, n);
 
   end24bitAlg(pic24, tmpPic);
@@ -207,12 +208,12 @@
 {
   /* runs an edge-enhancment algorithm */
 
-  byte        *pic24, *tmpPic;
-  int          i, sx,sy,sw,sh, n;
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  char         txt[256];
-  static char  buf[64] = { '7', '5', '\0' };
-  
+  byte              *pic24, *tmpPic;
+  int                i, sx,sy,sw,sh, n;
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  char               txt[256];
+  static char        buf[64] = { '7', '5', '\0' };
+
   sprintf(txt, "Sharpen:                                   \n\n%s",
 	  "Enter enhancement factor (0-99%)");
 
@@ -236,7 +237,7 @@
 
   if (start24bitAlg(&pic24, &tmpPic)) return;
   xvbcopy((char *) pic24, (char *) tmpPic, (size_t) (pWIDE*pHIGH*3));
-    
+
   doSharpConvolv(pic24, pWIDE,pHIGH, tmpPic, sx,sy,sw,sh, n);
 
   end24bitAlg(pic24, tmpPic);
@@ -248,7 +249,7 @@
 static void EdgeDetect()
 {
   byte *pic24, *p24, *tmpPic, *tlp;
-  char *str;
+  const char *str;
   int  i, j, v, maxv, sx,sy,sw,sh;
 
   WaitCursor();
@@ -264,7 +265,7 @@
   xvbcopy((char *) pic24, (char *) tmpPic, (size_t) (pWIDE*pHIGH*3));
 
   doEdgeConvolv(pic24, pWIDE, pHIGH, tmpPic, sx,sy,sw,sh);
-  
+
   SetISTR(ISTR_INFO, "%snormalizing...", str);
 
   /* Normalize results */
@@ -292,19 +293,19 @@
 /************************/
 static void TinFoil()
 {
-  byte *pic24, *p24, *tmpPic, *tp, *tlp;
-  char *str;
-  int  i, j, v, maxv,sx,sy,sw,sh;
-  
+  byte *pic24, *tmpPic, *tp, *tlp;
+  const char *str;
+  int  i, j, v, sx,sy,sw,sh;
+
   WaitCursor();
-  
+
   str = "Doing cheesy embossing effect...";
   SetISTR(ISTR_INFO, str);
-  
+
   if (HaveSelection()) GetSelRCoords(&sx,&sy,&sw,&sh);
   else { sx = 0;  sy = 0;  sw = pWIDE;  sh = pHIGH; }
   CropRect2Rect(&sx,&sy,&sw,&sh, 0,0,pWIDE,pHIGH);
-  
+
   if (start24bitAlg(&pic24, &tmpPic)) return;
   xvbcopy((char *) pic24, (char *) tmpPic, (size_t) (pWIDE*pHIGH*3));
 
@@ -315,9 +316,9 @@
       *tp++ = 128;  *tp++ = 128;  *tp++ = 128;
     }
   }
-  
+
   doAngleConvolv(pic24, pWIDE, pHIGH, tmpPic, sx,sy,sw,sh);
-  
+
   /* mono-ify selected area of tmpPic */
   for (i=sy; i<sy+sh; i++) {
     tp = tlp = tmpPic + (i*pWIDE + sx) * 3;
@@ -327,9 +328,9 @@
       tp[0] = tp[1] = tp[2] = (byte) v;
     }
   }
-    
+
   end24bitAlg(pic24, tmpPic);
-}  
+}
 
 
 /************************/
@@ -345,7 +346,7 @@
   if (HaveSelection()) GetSelRCoords(&sx,&sy,&sw,&sh);
   else { sx = 0;  sy = 0;  sw = pWIDE;  sh = pHIGH; }
   CropRect2Rect(&sx,&sy,&sw,&sh, 0,0,pWIDE,pHIGH);
-  
+
   if (start24bitAlg(&pic24, &tmpPic)) return;
   xvbcopy((char *) pic24, (char *) tmpPic, (size_t) (pWIDE*pHIGH*3));
 
@@ -365,7 +366,7 @@
   if (HaveSelection()) GetSelRCoords(&sx,&sy,&sw,&sh);
   else { sx = 0;  sy = 0;  sw = pWIDE;  sh = pHIGH; }
   CropRect2Rect(&sx,&sy,&sw,&sh, 0,0,pWIDE,pHIGH);
-  
+
   WaitCursor();
 
   if (start24bitAlg(&pic24, &tmpPic)) return;
@@ -381,12 +382,12 @@
 static void FineRotate(clr)
      int clr;
 {
-  byte        *pic24, *tmpPic;
-  int          i,sx,sy,sw,sh;
-  double       rotval;
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  char         txt[256];
-  static char  buf[64] = { '\0' };
+  byte              *pic24, *tmpPic;
+  int                i,sx,sy,sw,sh;
+  double             rotval;
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  char               txt[256];
+  static char        buf[64] = { '\0' };
 
   sprintf(txt, "Rotate (%s):\n\nEnter rotation angle, in degrees:  (>0 = CCW)",
 	  (clr ? "Clear" : "Copy"));
@@ -396,12 +397,12 @@
   rotval = atof(buf);
 
   if (rotval == 0.0) return;
-  
+
 
   if (HaveSelection()) GetSelRCoords(&sx,&sy,&sw,&sh);
   else { sx = 0;  sy = 0;  sw = pWIDE;  sh = pHIGH; }
   CropRect2Rect(&sx,&sy,&sw,&sh, 0,0,pWIDE,pHIGH);
-  
+
   WaitCursor();
 
   if (start24bitAlg(&pic24, &tmpPic)) return;
@@ -416,11 +417,11 @@
 /************************/
 static void Pixelize()
 {
-  byte        *pic24, *tmpPic;
-  int          i,sx,sy,sw,sh, pixX,pixY,err;
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  char         txt[256];
-  static char  buf[64] = { '4', '\0' };
+  byte              *pic24, *tmpPic;
+  int                i,sx,sy,sw,sh, pixX,pixY,err;
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  char               txt[256];
+  static char        buf[64] = { '4', '\0' };
 
   sprintf(txt, "Pixelize:\n\nEnter new pixel size, in image pixels:  %s",
 	  "(ex. '3', '5x8')");
@@ -443,11 +444,11 @@
     return;
   }
 
-  
+
   if (HaveSelection()) GetSelRCoords(&sx,&sy,&sw,&sh);
   else { sx = 0;  sy = 0;  sw = pWIDE;  sh = pHIGH; }
   CropRect2Rect(&sx,&sy,&sw,&sh, 0,0,pWIDE,pHIGH);
-  
+
   WaitCursor();
 
   if (start24bitAlg(&pic24, &tmpPic)) return;
@@ -463,11 +464,11 @@
 /************************/
 static void Spread()
 {
-  byte        *pic24, *tmpPic;
-  int          i,sx,sy,sw,sh, pixX,pixY,err;
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  char         txt[256];
-  static char  buf[64] = { '5', '\0' };
+  byte              *pic24, *tmpPic;
+  int                i,sx,sy,sw,sh, pixX,pixY,err;
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  char               txt[256];
+  static char        buf[64] = { '5', '\0' };
 
   sprintf(txt, "Spread:\n\nEnter spread factor (or x,y factors):  %s",
 	  "(ex. '10', '1x5')");
@@ -493,11 +494,11 @@
     return;
   }
 
-  
+
   if (HaveSelection()) GetSelRCoords(&sx,&sy,&sw,&sh);
   else { sx = 0;  sy = 0;  sw = pWIDE;  sh = pHIGH; }
   CropRect2Rect(&sx,&sy,&sw,&sh, 0,0,pWIDE,pHIGH);
-  
+
   WaitCursor();
 
   if (start24bitAlg(&pic24, &tmpPic)) return;
@@ -516,12 +517,12 @@
   /* runs median filter algorithm (for n*n rect centered around each pixel,
      replace with median value */
 
-  byte        *pic24, *tmpPic;
-  int          i, sx,sy,sw,sh, n;
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  char         txt[256];
-  static char  buf[64] = { '3', '\0' };
-  
+  byte              *pic24, *tmpPic;
+  int                i, sx,sy,sw,sh, n;
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  char               txt[256];
+  static char        buf[64] = { '3', '\0' };
+
   sprintf(txt, "DeSpeckle (median filter):                          \n\n%s",
 	  "Enter mask size (ex. 3, 5, 7, ...)");
 
@@ -530,7 +531,7 @@
   n = atoi(buf);
 
   if (n < 1 || (n&1)!=1) {
-    ErrPopUp("Error:  The value entered must be odd and greater than zero.", 
+    ErrPopUp("Error:  The value entered must be odd and greater than zero.",
 	     "\nOh!");
     return;
   }
@@ -546,7 +547,7 @@
 
   if (start24bitAlg(&pic24, &tmpPic)) return;
   xvbcopy((char *) pic24, (char *) tmpPic, (size_t) (pWIDE*pHIGH*3));
-    
+
   doMedianFilter(pic24, pWIDE,pHIGH, tmpPic, sx,sy,sw,sh, n);
 
   end24bitAlg(pic24, tmpPic);
@@ -560,7 +561,7 @@
      int   w,h, selx,sely,selw,selh, n;
 {
 
-  /* convolves with an n*n array, consisting of only 1's.  
+  /* convolves with an n*n array, consisting of only 1's.
      Operates on rectangular region 'selx,sely,selw,selh' (in pic coords)
      Region is guaranteed to be completely within pic boundaries
      'n' must be odd */
@@ -568,7 +569,7 @@
   register byte *p24;
   register int   rsum,gsum,bsum;
   byte          *rp;
-  int            i,j,k,x,y,x1,y1,count,n2;
+  int            x,y,x1,y1,count,n2;
 
 
   printUTime("start of blurConvolv");
@@ -589,7 +590,7 @@
       for (y1=y-n2; y1<=y+n2; y1++) {
 
 	if (y1>=sely && y1<sely+selh) {
-	  p24 = pic24 + y1*w*3 +(x-n2)*3; 
+	  p24 = pic24 + y1*w*3 +(x-n2)*3;
 
 	  for (x1=x-n2; x1<=x+n2; x1++) {
 	    if (x1>=selx && x1<selx+selw) {
@@ -631,7 +632,7 @@
   byte  *p24;
   int    rv, gv, bv;
   byte  *rp;
-  int    i,j,k,x,y,x1,y1;
+  int    i,x,y;
   double fact, ifact, hue,sat,val, vsum;
   double *linem1, *line0, *linep1, *tmpptr;
 
@@ -673,7 +674,7 @@
   for (y=sely+1; y<(sely+selh)-1; y++) {
     ProgressMeter(sely+1, (sely+selh)-2, y, "Sharpen");
     if ((y & 15) == 0) WaitCursor();
-    
+
     tmpptr = linem1;   linem1 = line0;   line0 = linep1;   linep1 = tmpptr;
 
     /* get next line */
@@ -691,7 +692,7 @@
       vsum = linem1[i-1] + linem1[i] + linem1[i+1] +
 	     line0 [i-1] + line0 [i] + line0 [i+1] +
 	     linep1[i-1] + linep1[i] + linep1[i+1];
-      
+
       rgb2hsv((int) p24[0], (int) p24[1], (int) p24[2], &hue, &sat, &val);
 
       val = ((val - (fact * vsum) / 9) / ifact);
@@ -723,22 +724,22 @@
 {
 
   /* convolves with two edge detection masks (vertical and horizontal)
-     simultaneously, taking Max(abs(results)) 
-     
+     simultaneously, taking Max(abs(results))
+
      The two masks are (hard coded):
 
           -1 0 1             -1 -1 -1
       H = -1 0 1     and V =  0  0  0
           -1 0 1              1  1  1
 
-     divided into 
+     divided into
            -1 0 0         0 0 0         0 0 1        0  1 0
        a =  0 0 0 ,  b = -1 0 1 ,  c =  0 0 0 ,  d = 0  0 0 .
             0 0 1         0 0 0        -1 0 0        0 -1 0
 
      So H = a + b + c,  V = a - c - d.
      gradient = max(abs(H),abs(V)).
-          
+
      Also, only does pixels in which the masks fit fully onto the picture
      (no pesky boundary conditionals)  */
 
@@ -746,7 +747,7 @@
   register byte *p24;
   register int   bperlin, a, b, c, d, rsum, gsum, bsum;
   byte          *rp;
-  int            i, x, y;
+  int            x, y;
 
 
   printUTime("start of edgeConvolv");
@@ -818,13 +819,13 @@
 {
 
   /* convolves with edge detection mask, at 45 degrees to horizontal.
-     
+
      The mask is (hard coded):
 
              -2 -1 0
              -1  0 1
               0  1 2
-          
+
      Also, only does pixels in which the masks fit fully onto the picture
      (no pesky boundary conditionals)
 
@@ -833,7 +834,7 @@
   register byte *p24;
   register int   bperlin,rsum,gsum,bsum;
   byte          *rp;
-  int            i, x,y;
+  int            x,y;
 
 
   printUTime("start of doAngleConvolv");
@@ -912,14 +913,14 @@
      for each pixel in the image (assume, for a second, a grayscale image),
      compute a histogram of the n*n rectangle centered on the pixel.
      replace the pixel with the color that had the greatest # of hits in
-     the histogram.  Note that 'n' should be odd. 
+     the histogram.  Note that 'n' should be odd.
 
      I've modified the algorithm to do the *right* thing for RGB images.
      (jhb, 6/94)  */
 
 
   register byte *pp;
-  register int   bperlin, rsum,gsum,bsum;
+  register int   bperlin;
   byte          *rp, *p24, *plin;
   int            i,j,k,x,y,n2,col,cnt,maxcnt;
   int           *nnrect;
@@ -933,7 +934,7 @@
 
   /* nnrect[] is an n*n array of ints, with '-1' meaning 'outside the region'
      otherwise they'll have 24-bit RGB values */
-  
+
   nnrect = (int *) malloc(n * n * sizeof(int));
   if (!nnrect) FatalError("can't malloc nnrect[] in doOilPaint()\n");
 
@@ -943,13 +944,13 @@
 
     p24 = pic24 + ((y-n2)*w + selx-n2)*3;   /* pts to top-left of mask */
     rp  = results + (y*w + selx)*3;
-    
+
     for (x=selx; x<selx+selw; x++) {
       /* fill 'nnrect' with valid pixels from n*n region centered round x,y */
       pp = plin = p24;
       for (i=y-n2, k=0; i<y+n2; i++) {
 	for (j=x-n2; j<x+n2; j++, k++, pp+=3) {
-	  if (i>=sely && i<sely+selh && j>=selx && j<selx+selw) { 
+	  if (i>=sely && i<sely+selh && j>=selx && j<selx+selw) {
 	    nnrect[k] = (((int) pp[0])<<16) | (((int) pp[1])<<8) | pp[2];
 	  }
 	  else nnrect[k] = -1;
@@ -957,7 +958,7 @@
 	plin += bperlin;  pp = plin;
       }
 
-      
+
       /* find 'most popular color' in nnrect, not counting '-1' */
       maxcnt = cnt = col = 0;
       for (i=0; i<n*n; i++) {
@@ -1021,7 +1022,7 @@
     p24 = pic24 + (y*w + selx) * 3;
     rf += (double) p24[0];  gf += (double) p24[1];  bf += (double) p24[2];
     i++;
-    
+
     p24 = pic24 + (y*w + (selx+selw-1)) * 3;
     rf += (double) p24[0];  gf += (double) p24[1];  bf += (double) p24[2];
     i++;
@@ -1047,7 +1048,7 @@
       if (dx==0 && dy==0) { ex = selx;  ey = sely; }  /* don't care */
       else if (dx==0) {	ex = cx;  ey = (dy<0) ? sely : sely+selh-1; }
       else if (dy==0) {	ey = cy;  ex = (dx<0) ? selx : selx+selw-1; }
-      else { 
+      else {
 	slope = ((double) dy) / dx;
 	if (fabs(slope) > fabs(dslope)) {   /* y axis is major */
 	  ey = (dy<0) ? sely : sely+selh-1;
@@ -1092,7 +1093,7 @@
   printUTime("end of blend");
 }
 
-  
+
 
 /************************/
 static void doRotate(pic24, w, h, results, selx,sely,selw,selh, rotval, clear)
@@ -1104,7 +1105,7 @@
      by the amount specified in degrees (rotval), and stores the result in
      'results', which is also a w*h 24-bit image.  The rotated bits are
      clipped to fit in 'results'.  If 'clear', the (unrotated) rectangular
-     region is cleared (in results) first.  
+     region is cleared (in results) first.
      sel[x,y,w,h] is guaranteed to be within image bounds */
 
   byte  *pp, *dp;
@@ -1118,7 +1119,7 @@
   printUTime("start of rotate");
 
   /*
-   * cfx,cfy  -  center point of sel rectangle (double) 
+   * cfx,cfy  -  center point of sel rectangle (double)
    * rx1,ry1  -  top-left  of sel, rotated
    * rx2,ry2  -  bot-left  of sel, rotated
    * rx3,ry3  -  top-right of sel, rotated
@@ -1174,7 +1175,7 @@
   /* now, for each pixel in rb[x,y,w,h], do the inverse rotation to see if
      it would be in the original unrotated selection rectangle.  if it *is*,
      compute and store an appropriate color, otherwise skip it */
- 
+
   for (y=rby; y<rby+rbh; y++) {
     dp = results + (y * w + rbx) * 3;
 
@@ -1194,7 +1195,7 @@
 	int    p0r,p0g,p0b, p1r,p1g,p1b, p2r,p2g,p2b, p3r,p3g,p3b;
 	int    rv,gv,bv;
 	double rd,gd,bd, p0wgt, p1wgt, p2wgt, p3wgt;
-	
+
 	/* compute the color, same idea as in Smooth**().  The color
 	   will be a linear combination of the colors of the center pixel,
 	   its left-or-right neighbor, its top-or-bottom neighbor, and
@@ -1265,9 +1266,9 @@
 }
 #endif /* ROTATE_FOO */
 
-	dp[0] = (byte) (rv&0xff);  
-	dp[1] = (byte) (gv&0xff);  
-	dp[2] = (byte) (bv&0xff);  
+	dp[0] = (byte) (rv&0xff);
+	dp[1] = (byte) (gv&0xff);
+	dp[2] = (byte) (bv&0xff);
       }
     }
   }
@@ -1311,11 +1312,11 @@
 #ifdef FOO
   fprintf(stderr,"rotXfer:  rotating (%4d,%4d) %7.2f degrees around",
 	  x,y, rad*180.0 / M_PI);
-  fprintf(stderr,"(%4d,%4d) -> %7.2f %7.2f  (d=%f ang=%f)\n", 
+  fprintf(stderr,"(%4d,%4d) -> %7.2f %7.2f  (d=%f ang=%f)\n",
 	  cx,cy, *rx,*ry, d, ang);
 #endif
 }
-  
+
 
 
 /************************/
@@ -1323,29 +1324,29 @@
      byte *pic24, *results;
      int   w, h, selx,sely,selw,selh, pixX,pixY;
 {
-  /* runs 'pixelization' algorithm.  replaces each pixX-by-pixY region 
+  /* runs 'pixelization' algorithm.  replaces each pixX-by-pixY region
      (smaller on edges) with the average color within that region */
-  
+
   byte  *pp;
   int    nwide, nhigh, i,j, x,y, x1,y1, stx,sty;
   int    nsum, rsum, gsum, bsum;
-  
+
   printUTime("start of pixelize");
-  
+
   /* center grid on selection */
   nwide = (selw + pixX-1) / pixX;
   nhigh = (selh + pixY-1) / pixY;
-  
+
   stx = selx - (nwide*pixX - selw)/2;
   sty = sely - (nhigh*pixY - selh)/2;
-  
+
   y = sty;
   for (i=0; i<nhigh; i++, y+=pixY) {
     ProgressMeter(0, nhigh-1, i, "Pixelize");
-    
+
     x = stx;
     for (j=0; j<nwide; j++, x+=pixX) {
-      
+
       /* COMPUTE AVERAGE COLOR FOR RECT:[x,y,pixX,pixY] */
       nsum = rsum = gsum = bsum = 0;
       for (y1=y; y1<y+pixY; y1++) {
@@ -1357,17 +1358,17 @@
 	  }
 	}
       }
-      
+
       if (nsum>0) {   /* just to be safe... */
 	rsum /= nsum;  gsum /= nsum;  bsum /= nsum;
 	RANGE(rsum,0,255);  RANGE(gsum,0,255);  RANGE(bsum,0,255);
       }
-      
-      
+
+
       /* STORE color in rect:[x,y,pixX,pixY] */
       for (y1=y; y1<y+pixY; y1++) {
 	if (!j && (y1 & 255)==0) WaitCursor();
-	
+
 	pp = results + (y1 * w + x) * 3;
 	for (x1=x; x1<x+pixX; x1++, pp+=3) {
 	  if (PTINRECT(x1,y1, selx,sely,selw,selh)) {
@@ -1381,7 +1382,7 @@
   printUTime("end of pixelize");
 }
 
-  
+
 
 /************************/
 static void doSpread(pic24, w, h, results, selx,sely,selw,selh, pixX, pixY)
@@ -1393,17 +1394,17 @@
      by pixX,pixY.  If pixX<0, it is treated as a single 'distance' value
      (after being abs()'d). */
 
-  /* assumes that initially 'results' is a copy of pic24.  Doesn't 
+  /* assumes that initially 'results' is a copy of pic24.  Doesn't
      even look at pic24 */
-  
+
   byte  *pp, *dp, r,g,b;
-  int    x,y, dx,dy, x1,y1, d, xrng, xoff, yrng, yoff, i,j;
+  int    x,y, x1,y1, d;
   int    minx, maxx, miny, maxy, rdist;
   time_t nowT;
 
   time(&nowT);
   srandom((unsigned int) nowT);
-  
+
   printUTime("start of spread");
 
   for (y=sely; y<sely+selh; y++) {
@@ -1453,7 +1454,7 @@
   printUTime("end of spread");
 }
 
-  
+
 
 /************************/
 static void doMedianFilter(pic24, w, h, results, selx,sely,selw,selh, n)
@@ -1468,7 +1469,7 @@
   register byte *p24;
   register int   rsum,gsum,bsum;
   byte          *rp;
-  int            i,j,k,x,y,x1,y1,count,n2,nsq,c2;
+  int            x,y,x1,y1,count,n2,nsq,c2;
   int           *rtab, *gtab, *btab;
 
   printUTime("start of doMedianFilter");
@@ -1494,7 +1495,7 @@
       for (y1=y-n2; y1<=y+n2; y1++) {
 
 	if (y1>=sely && y1<sely+selh) {
-	  p24 = pic24 + y1*w*3 +(x-n2)*3; 
+	  p24 = pic24 + y1*w*3 +(x-n2)*3;
 
 	  for (x1=x-n2; x1<=x+n2; x1++) {
 	    if (x1>=selx && x1<selx+selw) {
@@ -1509,12 +1510,12 @@
       }
 
 
-      /* now sort the rtab,gtab,btab arrays, (using shell sort) 
-	 and pick the middle value.  doing it in-line, rather than 
+      /* now sort the rtab,gtab,btab arrays, (using shell sort)
+	 and pick the middle value.  doing it in-line, rather than
 	 as a function call (ie, 'qsort()') , for speed */
-      {  
+      {
 	int i,j,t,d;
-	
+
 	for (d=count/2;  d>0;  d=d/2) {
 	  for (i=d; i<count; i++) {
 	    for (j=i-d;  j>=0 && rtab[j]>rtab[j+d];  j-=d) {
@@ -1531,14 +1532,14 @@
 	  }
 	}
       }
-      
+
       c2 = count/2;
       *rp++ = (byte) ( (count&1) ? rtab[c2] : (rtab[c2] + rtab[c2-1])/2);
       *rp++ = (byte) ( (count&1) ? gtab[c2] : (gtab[c2] + gtab[c2-1])/2);
       *rp++ = (byte) ( (count&1) ? btab[c2] : (btab[c2] + btab[c2-1])/2);
     }
   }
-  
+
   free(rtab);  free(gtab);  free(btab);
   printUTime("end of doMedianFilter");
 }
@@ -1549,7 +1550,7 @@
 static void intsort(a, n)
      int *a, n;
 {
-  /* uses the shell-sort algorithm.  for the relatively small data sets 
+  /* uses the shell-sort algorithm.  for the relatively small data sets
      we'll be using, should be quicker than qsort() because of all the
      function calling overhead associated with qsort(). */
 
@@ -1571,7 +1572,7 @@
      byte **pic24, **tmpPic;
 {
   /* generates a 24-bit version of 'pic', if neccessary, and also mallocs
-   * a pWIDE*pHIGH*3 24-bit output pic.  
+   * a pWIDE*pHIGH*3 24-bit output pic.
    *
    * Returns '1' if there's some sort of screwup, '0' if cool
    */
@@ -1588,7 +1589,7 @@
   *tmpPic = (byte *) calloc((size_t) (pWIDE * pHIGH * 3), (size_t) 1);
   if (!(*tmpPic)) {
     SetCursors(-1);
-    ErrPopUp("Unable to malloc() tmp 24-bit image in start24bitAlg()", 
+    ErrPopUp("Unable to malloc() tmp 24-bit image in start24bitAlg()",
 	     "\nTough!");
     if (picType == PIC8) free(*pic24);
     return 1;
@@ -1609,16 +1610,16 @@
   saveOrigPic();  /* also kills pic/cpic/epic/egampic/theImage, NOT pic24 */
 
   /* copy results to pic24 */
-  xvbcopy((char *) outPic, (char *) pic24, (size_t) (pWIDE*pHIGH*3)); 
+  xvbcopy((char *) outPic, (char *) pic24, (size_t) (pWIDE*pHIGH*3));
   free(outPic);
 
   if (picType == PIC8) {
     pic = Conv24to8(pic24, pWIDE, pHIGH, ncols, rMap,gMap,bMap);
     free(pic24);
-    if (!pic) { 
+    if (!pic) {
       SetCursors(-1);
       ErrPopUp("Some sort of failure occured in 24to8 conversion\n","\nDamn!");
-      NoAlg(); 
+      NoAlg();
       return;
     }
   }
@@ -1632,7 +1633,7 @@
 static void saveOrigPic()
 {
   /* saves original picture into origPic, if it hasn't already been done.
-     This allows us to undo algorithms...  
+     This allows us to undo algorithms...
 
      Also, frees all pics, (except 'pic', if we're in PIC24 mode) */
 
@@ -1649,7 +1650,7 @@
     /* make a backup copy of 'pic' */
     origPic = (byte *) malloc((size_t)(pWIDE*pHIGH*((picType==PIC8) ? 1 : 3)));
     if (!origPic) FatalError("out of memory in 'saveOrigPic()'");
-    xvbcopy((char *) pic, (char *) origPic, 
+    xvbcopy((char *) pic, (char *) origPic,
 	    (size_t) (pWIDE * pHIGH * ((picType==PIC8) ? 1 : 3)));
 
     origPicType = picType;
diff -ru xv-3.10a/xvbmp.c xv-3.10a-enhancements/xvbmp.c
--- xv-3.10a/xvbmp.c	1994-12-22 14:34:42.000000000 -0800
+++ xv-3.10a-enhancements/xvbmp.c	2007-05-13 17:46:16.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * xvbmp.c - i/o routines for .BMP files (MS Windows 3.x)
+ * xvbmp.c - I/O routines for .BMP files (MS Windows 3.x and later; OS/2)
  *
  * LoadBMP(fname, numcols)
  * WriteBMP(fp, pic, ptype, w, h, r, g, b, numcols, style);
@@ -9,30 +9,39 @@
 
 #include "xv.h"
 
-/* comments on error handling:
-   a truncated file is not considered a Major Error.  The file is loaded, the
-   rest of the pic is filled with 0's.
-
-   a file with garbage characters in it is an unloadable file.  All allocated
-   stuff is tossed, and LoadPBM returns non-zero
-
-   not being able to malloc is a Fatal Error.  The program is aborted. */
-
-
-#define BI_RGB  0
-#define BI_RLE8 1
-#define BI_RLE4 2
+/* Comments on error-handling:
+   A truncated file is not considered a Major Error.  The file is loaded,
+   and the rest of the pic is filled with 0's.
+
+   A file with garbage characters in it is an unloadable file.  All allocated
+   stuff is tossed, and LoadBMP returns non-zero.
+
+   Not being able to malloc is a Fatal Error.  The program is aborted. */
+
+
+#define BI_RGB       0   /* a.k.a. uncompressed */
+#define BI_RLE8      1
+#define BI_RLE4      2
+#define BI_BITFIELDS 3   /* BMP version 4 */
+#define BI_JPEG      4   /* BMP version 5 (not yet supported) */
+#define BI_PNG       5   /* BMP version 5 (not yet supported) */
 
 #define WIN_OS2_OLD 12
 #define WIN_NEW     40
 #define OS2_NEW     64
 
+#if (defined(UINT_MAX) && UINT_MAX != 0xffffffffU)
+#  error XV's BMP code requires 32-bit unsigned integer type, but u_int isn't
+#endif
+
 static long filesize;
 
 static int   loadBMP1   PARM((FILE *, byte *, u_int, u_int));
 static int   loadBMP4   PARM((FILE *, byte *, u_int, u_int, u_int));
 static int   loadBMP8   PARM((FILE *, byte *, u_int, u_int, u_int));
-static int   loadBMP24  PARM((FILE *, byte *, u_int, u_int));
+static int   loadBMP16  PARM((FILE *, byte *, u_int, u_int, u_int *));
+static int   loadBMP24  PARM((FILE *, byte *, u_int, u_int, u_int));
+static int   loadBMP32  PARM((FILE *, byte *, u_int, u_int, u_int *));
 static u_int getshort   PARM((FILE *));
 static u_int getint     PARM((FILE *));
 static void  putshort   PARM((FILE *, int));
@@ -41,7 +50,7 @@
 static void  writeBMP4  PARM((FILE *, byte *, int, int));
 static void  writeBMP8  PARM((FILE *, byte *, int, int));
 static void  writeBMP24 PARM((FILE *, byte *, int, int));
-static int   bmpError   PARM((char *, char *));
+static int   bmpError   PARM((const char *, const char *));
 
 
 #define FERROR(fp) (ferror(fp) || feof(fp))
@@ -52,15 +61,15 @@
      PICINFO *pinfo;
 /*******************************************/
 {
-  FILE         *fp;
-  int          i, c, c1, rv;
-  unsigned int bfSize, bfOffBits, biSize, biWidth, biHeight, biPlanes;
-  unsigned int biBitCount, biCompression, biSizeImage, biXPelsPerMeter;
-  unsigned int biYPelsPerMeter, biClrUsed, biClrImportant;
-  int bPad;
-  char         *cmpstr;
-  byte         *pic24, *pic8;
-  char          buf[512], *bname;
+  FILE       *fp;
+  int        i, c, c1, rv, bPad;
+  u_int      bfSize, bfOffBits, biSize, biWidth, biHeight, biPlanes;
+  u_int      biBitCount, biCompression, biSizeImage, biXPelsPerMeter;
+  u_int      biYPelsPerMeter, biClrUsed, biClrImportant;
+  u_int      colormask[3];
+  char       buf[512], rgb_bits[16];
+  const char *cmpstr, *bname;
+  byte       *pic24, *pic8;
 
   /* returns '1' on success */
 
@@ -69,7 +78,7 @@
 
   fp = xv_fopen(fname,"r");
   if (!fp) return (bmpError(bname, "couldn't open file"));
-  
+
   fseek(fp, 0L, 2);      /* figure out the file size */
   filesize = ftell(fp);
   fseek(fp, 0L, 0);
@@ -98,17 +107,16 @@
     biClrUsed       = getint(fp);
     biClrImportant  = getint(fp);
   }
-
   else {    /* old bitmap format */
     biWidth         = getshort(fp);          /* Types have changed ! */
     biHeight        = getshort(fp);
     biPlanes        = getshort(fp);
     biBitCount      = getshort(fp);
-    
-    /* Not in old versions so have to compute them*/
+
+    /* not in old versions, so have to compute them */
     biSizeImage = (((biPlanes * biBitCount*biWidth)+31)/32)*4*biHeight;
-    
-    biCompression   = BI_RGB; 
+
+    biCompression   = BI_RGB;
     biXPelsPerMeter = biYPelsPerMeter = 0;
     biClrUsed       = biClrImportant  = 0;
   }
@@ -126,22 +134,39 @@
   if (FERROR(fp)) { bmpError(bname,"EOF reached in file header"); goto ERROR; }
 
 
-  /* error checking */
-  if ((biBitCount!=1 && biBitCount!=4 && biBitCount!=8 && biBitCount!=24) || 
-      biPlanes!=1 || biCompression>BI_RLE4) {
+  /* error-checking */
+  if ((biBitCount!=1 && biBitCount!=4 && biBitCount!=8 &&
+       biBitCount!=16 && biBitCount!=24 && biBitCount!=32) ||
+      biPlanes!=1 || biCompression>BI_PNG ||
+      biWidth<=0 || biHeight<=0 ||
+      (biClrUsed && biClrUsed > (1 << biBitCount))) {
+
+    sprintf(buf,
+	    "Unsupported BMP type (%dx%d, Bits=%d, Colors=%d, Planes=%d, "
+	    "Compr=%d)",
+	    biWidth, biHeight, biBitCount, biClrUsed, biPlanes, biCompression);
 
-    sprintf(buf,"Bogus BMP File!  (bitCount=%d, Planes=%d, Compression=%d)",
-	    biBitCount, biPlanes, biCompression);
+    bmpError(bname, buf);
+    goto ERROR;
+  }
+
+  if (biCompression>BI_BITFIELDS) {
+    sprintf(buf, "Unsupported BMP compression method (%s)",
+	    biCompression == BI_JPEG? "JPEG" :
+	    biCompression == BI_PNG? "PNG" :
+	    "unknown/newer than v5");
 
     bmpError(bname, buf);
     goto ERROR;
   }
 
   if (((biBitCount==1 || biBitCount==24) && biCompression != BI_RGB) ||
-      (biBitCount==4 && biCompression==BI_RLE8) ||
-      (biBitCount==8 && biCompression==BI_RLE4)) {
+      (biBitCount==4 && biCompression!=BI_RGB && biCompression!=BI_RLE4) ||
+      (biBitCount==8 && biCompression!=BI_RGB && biCompression!=BI_RLE8) ||
+      ((biBitCount==16 || biBitCount==32) &&
+       biCompression!=BI_RGB && biCompression!=BI_BITFIELDS)) {
 
-    sprintf(buf,"Bogus BMP File!  (bitCount=%d, Compression=%d)",
+    sprintf(buf,"Unsupported BMP type (bitCount=%d, Compression=%d)",
 	    biBitCount, biCompression);
 
     bmpError(bname, buf);
@@ -153,13 +178,21 @@
   if (biSize != WIN_OS2_OLD) {
     /* skip ahead to colormap, using biSize */
     c = biSize - 40;    /* 40 bytes read from biSize to biClrImportant */
-    for (i=0; i<c; i++) getc(fp);
-    
+    for (i=0; i<c; i++)
+      getc(fp);
     bPad = bfOffBits - (biSize + 14);
   }
 
+  /* 16-bit or 32-bit color mask */
+  if (biCompression==BI_BITFIELDS) {
+    colormask[0] = getint(fp);
+    colormask[1] = getint(fp);
+    colormask[2] = getint(fp);
+    bPad -= 12;
+  }
+
   /* load up colormap, if any */
-  if (biBitCount!=24) {
+  if (biBitCount == 1 || biBitCount == 4 || biBitCount == 8) {
     int i, cmaplen;
 
     cmaplen = (biClrUsed) ? biClrUsed : 1 << biBitCount;
@@ -173,7 +206,7 @@
       }
     }
 
-    if (FERROR(fp)) 
+    if (FERROR(fp))
       { bmpError(bname,"EOF reached in BMP colormap"); goto ERROR; }
 
     if (DEBUG>1) {
@@ -188,7 +221,7 @@
   if (biSize != WIN_OS2_OLD) {
     /* Waste any unused bytes between the colour map (if present)
        and the start of the actual bitmap data. */
-    
+
     while (bPad > 0) {
       (void) getc(fp);
       bPad--;
@@ -197,31 +230,57 @@
 
   /* create pic8 or pic24 */
 
-  if (biBitCount==24) {
-    pic24 = (byte *) calloc((size_t) biWidth * biHeight * 3, (size_t) 1);
+  if (biBitCount==16 || biBitCount==24 || biBitCount==32) {
+    u_int npixels = biWidth * biHeight;
+    u_int count = 3 * npixels;
+
+    if (biWidth == 0 || biHeight == 0 || npixels/biWidth != biHeight ||
+        count/3 != npixels)
+      return (bmpError(bname, "image dimensions too large"));
+    pic24 = (byte *) calloc((size_t) count, (size_t) 1);
     if (!pic24) return (bmpError(bname, "couldn't malloc 'pic24'"));
   }
   else {
-    pic8 = (byte *) calloc((size_t) biWidth * biHeight, (size_t) 1);
+    u_int npixels = biWidth * biHeight;
+
+    if (biWidth == 0 || biHeight == 0 || npixels/biWidth != biHeight)
+      return (bmpError(bname, "image dimensions too large"));
+    pic8 = (byte *) calloc((size_t) npixels, (size_t) 1);
     if (!pic8) return(bmpError(bname, "couldn't malloc 'pic8'"));
   }
 
   WaitCursor();
 
   /* load up the image */
-  if      (biBitCount == 1) rv = loadBMP1(fp,pic8,biWidth,biHeight);
-  else if (biBitCount == 4) rv = loadBMP4(fp,pic8,biWidth,biHeight,
-					  biCompression);
-  else if (biBitCount == 8) rv = loadBMP8(fp,pic8,biWidth,biHeight,
-					  biCompression);
-  else                      rv = loadBMP24(fp,pic24,biWidth,biHeight);
+  switch (biBitCount) {
+  case 1:
+    rv = loadBMP1(fp, pic8, biWidth, biHeight);
+    break;
+  case 4:
+    rv = loadBMP4(fp, pic8, biWidth, biHeight, biCompression);
+    break;
+  case 8:
+    rv = loadBMP8(fp, pic8, biWidth, biHeight, biCompression);
+    break;
+  case 16:
+    rv = loadBMP16(fp, pic24, biWidth, biHeight,           /*  v-- BI_RGB */
+                   biCompression == BI_BITFIELDS? colormask : NULL);
+    break;
+  default:
+    if (biBitCount == 32 && biCompression == BI_BITFIELDS)
+      rv = loadBMP32(fp, pic24, biWidth, biHeight, colormask);
+    else /* 24 or (32 and BI_RGB) */
+      rv = loadBMP24(fp, pic24, biWidth, biHeight, biBitCount);
+    break;
+  }
+
+  if (rv) bmpError(bname, "File appears truncated.  Winging it.");
 
-  if (rv) bmpError(bname, "File appears truncated.  Winging it.\n");
 
   fclose(fp);
 
 
-  if (biBitCount == 24) {
+  if (biBitCount > 8) {
     pinfo->pic  = pic24;
     pinfo->type = PIC24;
   }
@@ -233,6 +292,22 @@
   cmpstr = "";
   if      (biCompression == BI_RLE4) cmpstr = ", RLE4 compressed";
   else if (biCompression == BI_RLE8) cmpstr = ", RLE8 compressed";
+  else if (biCompression == BI_BITFIELDS) {
+    int    bit, c[3], i;
+    u_int  mask;
+
+    for (i = 0; i < 3; ++i) {
+      mask = colormask[i];
+      c[i] = 0;
+      for (bit = 0; bit < 32; ++bit) {
+        if (mask & 1)
+          ++c[i];
+        mask >>= 1;
+      }
+    }
+    sprintf(rgb_bits, ", RGB%d%d%d", c[0], c[1], c[2]);
+    cmpstr = rgb_bits;
+  }
 
   pinfo->w = biWidth;  pinfo->h = biHeight;
   pinfo->normw = pinfo->w;   pinfo->normh = pinfo->h;
@@ -254,7 +329,7 @@
  ERROR:
   fclose(fp);
   return 0;
-}  
+}
 
 
 /*******************************************/
@@ -264,12 +339,13 @@
      u_int  w,h;
 {
   int   i,j,c,bitnum,padw;
-  byte *pp;
+  byte *pp = pic8 + ((h - 1) * w);
+  size_t l = w*h;
 
   c = 0;
   padw = ((w + 31)/32) * 32;  /* 'w', padded to be a multiple of 32 */
 
-  for (i=h-1; i>=0; i--) {
+  for (i=h-1; i>=0 && (pp - pic8 <= l); i--) {
     pp = pic8 + (i * w);
     if ((i&0x3f)==0) WaitCursor();
     for (j=bitnum=0; j<padw; j++,bitnum++) {
@@ -277,7 +353,7 @@
 	c = getc(fp);
 	bitnum = 0;
       }
-      
+
       if (j<w) {
 	*pp++ = (c & 0x80) ? 1 : 0;
 	c <<= 1;
@@ -287,7 +363,7 @@
   }
 
   return (FERROR(fp));
-}  
+}
 
 
 
@@ -298,25 +374,25 @@
      u_int  w,h,comp;
 {
   int   i,j,c,c1,x,y,nybnum,padw,rv;
-  byte *pp;
-  
-  
+  byte *pp = pic8 + ((h - 1) * w);
+  size_t l = w*h;
+
   rv = 0;
   c = c1 = 0;
-  
+
   if (comp == BI_RGB) {   /* read uncompressed data */
     padw = ((w + 7)/8) * 8; /* 'w' padded to a multiple of 8pix (32 bits) */
-    
-    for (i=h-1; i>=0; i--) {
+
+    for (i=h-1; i>=0 && (pp - pic8 <= l); i--) {
       pp = pic8 + (i * w);
       if ((i&0x3f)==0) WaitCursor();
-      
+
       for (j=nybnum=0; j<padw; j++,nybnum++) {
 	if ((nybnum & 1) == 0) { /* read next byte */
 	  c = getc(fp);
 	  nybnum = 0;
 	}
-	
+
 	if (j<w) {
 	  *pp++ = (c & 0xf0) >> 4;
 	  c <<= 4;
@@ -325,55 +401,55 @@
       if (FERROR(fp)) break;
     }
   }
-  
+
   else if (comp == BI_RLE4) {  /* read RLE4 compressed data */
-    x = y = 0;  
+    x = y = 0;
     pp = pic8 + x + (h-y-1)*w;
-    
+
     while (y<h) {
       c = getc(fp);  if (c == EOF) { rv = 1;  break; }
-      
+
       if (c) {                                   /* encoded mode */
 	c1 = getc(fp);
-	for (i=0; i<c; i++,x++,pp++) 
+	for (i=0; i<c && (pp - pic8 <= l); i++,x++,pp++)
 	  *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
       }
-      
+
       else {    /* c==0x00  :  escape codes */
 	c = getc(fp);  if (c == EOF) { rv = 1;  break; }
-	
+
 	if      (c == 0x00) {                    /* end of line */
 	  x=0;  y++;  pp = pic8 + x + (h-y-1)*w;
-	} 
-	
+	}
+
 	else if (c == 0x01) break;               /* end of pic8 */
-	
+
 	else if (c == 0x02) {                    /* delta */
 	  c = getc(fp);  x += c;
 	  c = getc(fp);  y += c;
 	  pp = pic8 + x + (h-y-1)*w;
 	}
-	
+
 	else {                                   /* absolute mode */
-	  for (i=0; i<c; i++, x++, pp++) {
+	  for (i=0; i<c && (pp - pic8 <= l); i++, x++, pp++) {
 	    if ((i&1) == 0) c1 = getc(fp);
 	    *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
 	  }
-	  
+
 	  if (((c&3)==1) || ((c&3)==2)) getc(fp);  /* read pad byte */
 	}
       }  /* escape processing */
       if (FERROR(fp)) break;
     }  /* while */
   }
-  
+
   else {
     fprintf(stderr,"unknown BMP compression type 0x%0x\n", comp);
   }
-  
+
   if (FERROR(fp)) rv = 1;
   return rv;
-}  
+}
 
 
 
@@ -384,14 +460,18 @@
      u_int  w,h,comp;
 {
   int   i,j,c,c1,padw,x,y,rv;
-  byte *pp;
-  
+  byte *pp = pic8 + ((h - 1) * w);
+  size_t l = w*h;
+  byte *pend;
+
   rv = 0;
 
+  pend = pic8 + w * h;
+
   if (comp == BI_RGB) {   /* read uncompressed data */
     padw = ((w + 3)/4) * 4; /* 'w' padded to a multiple of 4pix (32 bits) */
 
-    for (i=h-1; i>=0; i--) {
+    for (i=h-1; i>=0 && (pp - pic8 <= l); i--) {
       pp = pic8 + (i * w);
       if ((i&0x3f)==0) WaitCursor();
 
@@ -404,15 +484,15 @@
   }
 
   else if (comp == BI_RLE8) {  /* read RLE8 compressed data */
-    x = y = 0;  
+    x = y = 0;
     pp = pic8 + x + (h-y-1)*w;
 
-    while (y<h) {
+    while (y<h && pp<=pend) {
       c = getc(fp);  if (c == EOF) { rv = 1;  break; }
 
       if (c) {                                   /* encoded mode */
 	c1 = getc(fp);
-	for (i=0; i<c; i++,x++,pp++) *pp = c1;
+	for (i=0; i<c && pp<=pend; i++,x++,pp++) *pp = c1;
       }
 
       else {    /* c==0x00  :  escape codes */
@@ -420,7 +500,7 @@
 
 	if      (c == 0x00) {                    /* end of line */
 	  x=0;  y++;  pp = pic8 + x + (h-y-1)*w;
-	} 
+	}
 
 	else if (c == 0x01) break;               /* end of pic8 */
 
@@ -431,49 +511,156 @@
 	}
 
 	else {                                   /* absolute mode */
-	  for (i=0; i<c; i++, x++, pp++) {
+	  for (i=0; i<c && pp<=pend; i++, x++, pp++) {
 	    c1 = getc(fp);
 	    *pp = c1;
 	  }
-	  
+
 	  if (c & 1) getc(fp);  /* odd length run: read an extra pad byte */
 	}
       }  /* escape processing */
       if (FERROR(fp)) break;
     }  /* while */
   }
-  
+
   else {
     fprintf(stderr,"unknown BMP compression type 0x%0x\n", comp);
   }
 
   if (FERROR(fp)) rv = 1;
   return rv;
-}  
+}
 
 
 
 /*******************************************/
-static int loadBMP24(fp, pic24, w, h)
+static int loadBMP16(fp, pic24, w, h, mask)
+     FILE  *fp;
+     byte  *pic24;
+     u_int w, h, *mask;
+{
+  int	 x, y;
+  byte	*pp = pic24 + ((h - 1) * w * 3);
+  size_t l = w*h*3;
+  u_int	 buf, colormask[6];
+  int	 i, bit, bitshift[6], colorbits[6], bitshift2[6];
+
+  if (mask == NULL) {  /* RGB555 */
+    colormask[0] = 0x00007c00;
+    colormask[1] = 0x000003e0;
+    colormask[2] = 0x0000001f;
+    colormask[3] = 0x7c000000;
+    colormask[4] = 0x03e00000;
+    colormask[5] = 0x001f0000;
+    bitshift[0] =  7;	bitshift2[0] = 0;
+    bitshift[1] =  2;	bitshift2[1] = 0;
+    bitshift[2] =  0;	bitshift2[2] = 3;
+    bitshift[3] = 23;	bitshift2[3] = 0;
+    bitshift[4] = 18;	bitshift2[4] = 0;
+    bitshift[5] = 13;	bitshift2[5] = 0;
+  } else {
+    colormask[0] = mask[0];
+    colormask[1] = mask[1];
+    colormask[2] = mask[2];
+    colormask[3] = (mask[0] & 0xffff) << 16;
+    colormask[4] = (mask[1] & 0xffff) << 16;
+    colormask[5] = (mask[2] & 0xffff) << 16;
+
+    for (i = 0; i < 3; ++i) {
+      buf = colormask[i];
+
+      bitshift[i] = 0;
+      for (bit = 0; bit < 32; ++bit) {
+	if (buf & 1)
+	  break;
+	else
+	  ++bitshift[i];
+	buf >>= 1;
+      }
+      bitshift[i+3] = bitshift[i] + 16;
+
+      colorbits[i] = 0;
+      for (; bit < 32; ++bit) {
+	if (buf & 1)
+	  ++colorbits[i];
+	else
+	  break;
+	buf >>= 1;
+      }
+      if (colorbits[i] > 8) { /* over 8-bit depth */
+	bitshift[i] += (colorbits[i] - 8);
+	bitshift[i+3] = bitshift[i] + 16;
+	bitshift2[i] = bitshift2[i+3] = 0;
+      } else
+	bitshift2[i] = bitshift2[i+3] = 8 - colorbits[i];
+    }
+  }
+
+  if (DEBUG > 1)
+    fprintf(stderr, "loadBMP16: bitfields\n"
+	    "\tR: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n"
+	    "\t             (mask = %08x, shift >>%2d, <<%2d)\n"
+	    "\tG: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n"
+	    "\t             (mask = %08x, shift >>%2d, <<%2d)\n"
+	    "\tB: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n"
+	    "\t             (mask = %08x, shift >>%2d, <<%2d)\n",
+	    colorbits[0], colormask[0], bitshift[0], bitshift2[0],
+	    colormask[3], bitshift[3], bitshift2[3],
+	    colorbits[1], colormask[1], bitshift[1], bitshift2[1],
+	    colormask[4], bitshift[4], bitshift2[4],
+	    colorbits[2], colormask[2], bitshift[2], bitshift2[2],
+	    colormask[5], bitshift[5], bitshift2[5]);
+
+  for (y = h-1; y >= 0 && (pp - pic24 <= l); y--) {
+    pp = pic24 + (3 * w * y);
+    if ((y&0x3f)==0) WaitCursor();
+
+    for (x = w; x > 1; x -= 2) {
+      buf = getint(fp);
+      *(pp++) = (buf & colormask[0]) >> bitshift[0] << bitshift2[0];
+      *(pp++) = (buf & colormask[1]) >> bitshift[1] << bitshift2[1];
+      *(pp++) = (buf & colormask[2]) >> bitshift[2] << bitshift2[2];
+      *(pp++) = (buf & colormask[3]) >> bitshift[3] << bitshift2[3];
+      *(pp++) = (buf & colormask[4]) >> bitshift[4] << bitshift2[4];
+      *(pp++) = (buf & colormask[5]) >> bitshift[5] << bitshift2[5];
+    }
+    if (w & 1) { /* padded to 2 pix */
+      buf = getint(fp);
+      *(pp++) = (buf & colormask[0]) >> bitshift[0];
+      *(pp++) = (buf & colormask[1]) >> bitshift[1];
+      *(pp++) = (buf & colormask[2]) >> bitshift[2];
+    }
+  }
+
+  return FERROR(fp)? 1 : 0;
+}
+
+
+
+/*******************************************/
+static int loadBMP24(fp, pic24, w, h, bits)   /* also handles 32-bit BI_RGB */
      FILE *fp;
      byte *pic24;
-     u_int  w,h;
+     u_int  w,h, bits;
 {
   int   i,j,padb,rv;
-  byte *pp;
+  byte *pp = pic24 + ((h - 1) * w * 3);
+  size_t l = w*h*3;
 
   rv = 0;
 
   padb = (4 - ((w*3) % 4)) & 0x03;  /* # of pad bytes to read at EOscanline */
+  if (bits==32) padb = 0;
 
   for (i=h-1; i>=0; i--) {
     pp = pic24 + (i * w * 3);
     if ((i&0x3f)==0) WaitCursor();
-    
-    for (j=0; j<w; j++) {
+
+    for (j=0; j<w && (pp - pic24 <= l); j++) {
       pp[2] = getc(fp);   /* blue */
       pp[1] = getc(fp);   /* green */
       pp[0] = getc(fp);   /* red */
+      if (bits==32) getc(fp);
       pp += 3;
     }
 
@@ -484,30 +671,94 @@
   }
 
   return rv;
-}  
+}
+
+
+
+/*******************************************/
+static int loadBMP32(fp, pic24, w, h, colormask) /* 32-bit BI_BITFIELDS only */
+     FILE  *fp;
+     byte  *pic24;
+     u_int w, h, *colormask;
+{
+  int	 x, y;
+  byte	*pp;
+  u_int	 buf;
+  int	 i, bit, bitshift[3], colorbits[3], bitshift2[3];
+
+  for (i = 0; i < 3; ++i) {
+    buf = colormask[i];
+
+    bitshift[i] = 0;
+    for (bit = 0; bit < 32; ++bit) {
+      if (buf & 1)
+	break;
+      else
+	++bitshift[i];
+      buf >>= 1;
+    }
+
+    colorbits[i] = 0;
+    for (; bit < 32; ++bit) {
+      if (buf & 1)
+	++colorbits[i];
+      else
+	break;
+      buf >>= 1;
+    }
+    if (colorbits[i] > 8) {  /* over 8-bit depth */
+      bitshift[i] += (colorbits[i] - 8);
+      bitshift2[i] = 0;
+    } else
+      bitshift2[i] = 8 - colorbits[i];
+  }
+
+  if (DEBUG > 1)
+    fprintf(stderr, "loadBMP32: bitfields\n"
+	    "\tR: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n"
+	    "\tG: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n"
+	    "\tB: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n",
+	    colorbits[0], colormask[0], bitshift[0], bitshift2[0],
+	    colorbits[1], colormask[1], bitshift[1], bitshift2[1],
+	    colorbits[2], colormask[2], bitshift[2], bitshift2[2]);
+
+  for (y = h-1; y >= 0; y--) {
+    pp = pic24 + (3 * w * y);
+    if ((y&0x3f)==0) WaitCursor();
+
+    for(x = w; x > 0; x --) {
+      buf = getint(fp);
+      *(pp++) = (buf & colormask[0]) >> bitshift[0] << bitshift2[0];
+      *(pp++) = (buf & colormask[1]) >> bitshift[1] << bitshift2[1];
+      *(pp++) = (buf & colormask[2]) >> bitshift[2] << bitshift2[2];
+    }
+  }
+
+  return FERROR(fp)? 1 : 0;
+}
 
 
 
 /*******************************************/
-static unsigned int getshort(fp)
+static u_int getshort(fp)
      FILE *fp;
 {
   int c, c1;
   c = getc(fp);  c1 = getc(fp);
-  return ((unsigned int) c) + (((unsigned int) c1) << 8);
+  return ((u_int) c) + (((u_int) c1) << 8);
 }
 
 
 /*******************************************/
-static unsigned int getint(fp)
+static u_int getint(fp)
      FILE *fp;
 {
   int c, c1, c2, c3;
   c = getc(fp);  c1 = getc(fp);  c2 = getc(fp);  c3 = getc(fp);
-  return ((unsigned int) c) +
-         (((unsigned int) c1) << 8) + 
-	 (((unsigned int) c2) << 16) +
-	 (((unsigned int) c3) << 24);
+  return  ((u_int) c) +
+	 (((u_int) c1) << 8) +
+	 (((u_int) c2) << 16) +
+	 (((u_int) c3) << 24);
 }
 
 
@@ -518,7 +769,7 @@
 {
   int c, c1;
 
-  c = ((unsigned int ) i) & 0xff;  c1 = (((unsigned int) i)>>8) & 0xff;
+  c = ((u_int) i) & 0xff;  c1 = (((u_int) i)>>8) & 0xff;
   putc(c, fp);   putc(c1,fp);
 }
 
@@ -529,10 +780,10 @@
      int i;
 {
   int c, c1, c2, c3;
-  c  = ((unsigned int ) i)      & 0xff;  
-  c1 = (((unsigned int) i)>>8)  & 0xff;
-  c2 = (((unsigned int) i)>>16) & 0xff;
-  c3 = (((unsigned int) i)>>24) & 0xff;
+  c  =  ((u_int) i)      & 0xff;
+  c1 = (((u_int) i)>>8)  & 0xff;
+  c2 = (((u_int) i)>>16) & 0xff;
+  c3 = (((u_int) i)>>24) & 0xff;
 
   putc(c, fp);   putc(c1,fp);  putc(c2,fp);  putc(c3,fp);
 }
@@ -562,11 +813,11 @@
    *    8-bit image
    * note that PIC24 and F_BWDITHER/F_REDUCED won't happen
    *
-   * if colorstyle == F_BWDITHER, it writes a 1-bit image 
+   * if colorstyle == F_BWDITHER, it writes a 1-bit image
    *
    */
 
-  int i,j, nc, nbits, bperlin, cmaplen;
+  int i,j, nc, nbits, bperlin, cmaplen, npixels;
   byte *graypic, *sp, *dp, graymap[256];
 
   nc = nbits = cmaplen = 0;
@@ -576,10 +827,16 @@
     /* generate a faked 8-bit per pixel image with a grayscale cmap,
        so that it can just fall through existing 8-bit code */
 
-    graypic = (byte *) malloc((size_t) w*h);
+    npixels = w * h;
+    if (w <= 0 || h <= 0 || npixels/w != h) {
+      SetISTR(ISTR_WARNING, "image dimensions too large");
+      return -1;
+    }
+
+    graypic = (byte *) malloc((size_t) npixels);
     if (!graypic) FatalError("unable to malloc in WriteBMP()");
 
-    for (i=0,sp=pic824,dp=graypic; i<w*h; i++,sp+=3, dp++) {
+    for (i=0,sp=pic824,dp=graypic; i<npixels; i++,sp+=3, dp++) {
       *dp = MONO(sp[0],sp[1],sp[2]);
     }
 
@@ -611,7 +868,7 @@
     for (i=0; i<numcols; i++) {
       /* see if color #i is a duplicate */
       for (j=0; j<i; j++) {
-	if (rmap[i] == rmap[j] && gmap[i] == gmap[j] && 
+	if (rmap[i] == rmap[j] && gmap[i] == gmap[j] &&
 	    bmap[i] == bmap[j]) break;
       }
 
@@ -689,13 +946,13 @@
 #else
   if (!FERROR(fp)) return -1;
 #endif
-  
+
   return 0;
 }
 
 
-	  
-	  
+
+
 /*******************************************/
 static void writeBMP1(fp, pic8, w, h)
      FILE *fp;
@@ -708,7 +965,7 @@
   padw = ((w + 31)/32) * 32;  /* 'w', padded to be a multiple of 32 */
 
   for (i=h-1; i>=0; i--) {
-    pp = pic8 + (i * w);  
+    pp = pic8 + (i * w);
     if ((i&0x3f)==0) WaitCursor();
 
     for (j=bitnum=c=0; j<=padw; j++,bitnum++) {
@@ -716,7 +973,7 @@
 	putc(c,fp);
 	bitnum = c = 0;
       }
-      
+
       c <<= 1;
 
       if (j<w) {
@@ -724,7 +981,7 @@
       }
     }
   }
-}  
+}
 
 
 
@@ -758,7 +1015,7 @@
       }
     }
   }
-}  
+}
 
 
 
@@ -768,7 +1025,7 @@
      byte *pic8;
      int  w,h;
 {
-  int   i,j,c,padw;
+  int   i,j,padw;
   byte *pp;
 
   padw = ((w + 3)/4) * 4; /* 'w' padded to a multiple of 4pix (32 bits) */
@@ -780,7 +1037,7 @@
     for (j=0; j<w; j++) putc(pc2nc[*pp++], fp);
     for ( ; j<padw; j++) putc(0, fp);
   }
-}  
+}
 
 
 /*******************************************/
@@ -789,7 +1046,7 @@
      byte *pic24;
      int  w,h;
 {
-  int   i,j,c,padb;
+  int   i,j,padb;
   byte *pp;
 
   padb = (4 - ((w*3) % 4)) & 0x03;  /* # of pad bytes to write at EOscanline */
@@ -807,7 +1064,7 @@
 
     for (j=0; j<padb; j++) putc(0, fp);
   }
-}  
+}
 
 
 
@@ -816,7 +1073,7 @@
 
 /*******************************************/
 static int bmpError(fname, st)
-     char *fname, *st;
+     const char *fname, *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", fname, st);
   return 0;
diff -ru xv-3.10a/xvbrowse.c xv-3.10a-enhancements/xvbrowse.c
--- xv-3.10a/xvbrowse.c	1995-01-19 09:49:17.000000000 -0800
+++ xv-3.10a-enhancements/xvbrowse.c	2007-05-13 17:50:18.000000000 -0700
@@ -1,6 +1,6 @@
 /*
  *  xvbrowse.c  -  visual schnauzer routines
- * 
+ *
  *  includes:
  *      void CreateBrowse(char *, char *, char *, char *, char *);
  *      void OpenBrowse();
@@ -19,11 +19,16 @@
 
 #define NEEDSDIR
 #include "xv.h"
+#include <unistd.h>   /* access() */
 
 #if defined(VMS) || defined(isc)
 typedef unsigned int mode_t;  /* file mode bits */
 #endif
 
+#ifndef MAX
+#  define MAX(a,b) (((a)>(b))?(a):(b))   /* used only for wheelmouse support */
+#endif
+
 
 /* load up built-in icons */
 #include "bits/br_file"
@@ -34,27 +39,40 @@
 #include "bits/br_sock"
 #include "bits/br_fifo"
 #include "bits/br_error"
-#include "bits/br_unknown"
+/* #include "bits/br_unknown"	commented out (near line 492) */
+
 #include "bits/br_cmpres"
+#include "bits/br_bzip2"
 
-#include "bits/br_gif"
-#include "bits/br_pm"
-#include "bits/br_pbm"
-#include "bits/br_xbm"
-#include "bits/br_sunras"
 #include "bits/br_bmp"
-#include "bits/br_utah"
+#include "bits/br_fits"
+#include "bits/br_gif"
+#include "bits/br_iff"
 #include "bits/br_iris"
-#include "bits/br_pcx"
 #include "bits/br_jfif"
-#include "bits/br_tiff"
+#include "bits/br_jp2"
+#include "bits/br_jpc"
+#include "bits/br_mag"
+#include "bits/br_maki"
+#include "bits/br_mgcsfx"
+#include "bits/br_pbm"
+#include "bits/br_pcd"
+#include "bits/br_pcx"
 #include "bits/br_pds"
+#include "bits/br_pi"
+#include "bits/br_pic"
+#include "bits/br_pic2"
+#include "bits/br_pm"
+#include "bits/br_png"
 #include "bits/br_ps"
-#include "bits/br_iff"
+#include "bits/br_sunras"
 #include "bits/br_targa"
+#include "bits/br_tiff"
+#include "bits/br_utah"
+#include "bits/br_xbm"
 #include "bits/br_xpm"
 #include "bits/br_xwd"
-#include "bits/br_fits"
+#include "bits/br_zx"	/* [JCE] The Spectrum+3 icon */
 
 #include "bits/br_trash"
 #include "bits/fcurs"
@@ -90,17 +108,28 @@
 #define BF_COMPRESS 21
 #define BF_PS       22
 #define BF_IFF      23
-#define BF_TARGA    24
+#define BF_TGA      24
 #define BF_XPM      25
 #define BF_XWD      26
 #define BF_FITS     27
-#define BF_MAX      28    /* # of built-in icons */
+#define BF_PNG      28
+#define BF_ZX       29    /* [JCE] Spectrum SCREEN$ */
+#define BF_PCD      30
+#define BF_BZIP2    31
+#define BF_JP2      32
+#define BF_JPC      33
+#define JP_EXT_BF   (BF_JPC)
+#define BF_MAG      (JP_EXT_BF + 1)
+#define BF_MAKI     (JP_EXT_BF + 2)
+#define BF_PIC      (JP_EXT_BF + 3)
+#define BF_PI       (JP_EXT_BF + 4)
+#define BF_PIC2     (JP_EXT_BF + 5)
+#define BF_MGCSFX   (JP_EXT_BF + 6)
+#define JP_EXT_BF_END  (BF_MGCSFX)
+#define BF_MAX      (JP_EXT_BF_END + 1)    /* # of built-in icons */
 
 #define ISLOADABLE(ftyp) (ftyp!=BF_DIR  && ftyp!=BF_CHR && ftyp!=BF_BLK && \
-			  ftyp!=BF_SOCK && ftyp!=BF_FIFO) 
-
-#define DEF_BROWWIDE 615   /* default size of window */
-#define DEF_BROWHIGH 356
+			  ftyp!=BF_SOCK && ftyp!=BF_FIFO)
 
 #define SCROLLVERT  8      /* height of scroll region at top/bottom of iconw */
 #define PAGEVERT    40     /* during rect drag, if further than this, page */
@@ -113,59 +142,93 @@
 #define BOTMARGIN 58       /* room for a row of buttons and a line of text */
 #define LRMARGINS 5        /* left and right margins */
 
-#define ISIZE_WIDE   80    /* maximum size of an icon */
-#define ISIZE_HIGH   60
+/* some people like bigger icons; 4:3 aspect ratio is recommended
+ * (NOTE:  standard XV binaries will not be able to read larger icons!) */
+#ifndef ISIZE_WIDE
+#  define ISIZE_WIDE 80    /* maximum size of an icon */
+#endif
+#ifndef ISIZE_HIGH
+#  define ISIZE_HIGH 60
+#endif
+
+#ifndef ISIZE_WPAD
+#  define ISIZE_WPAD 16    /* extra horizontal padding between icons */
+#endif
+
+#ifndef INUM_WIDE
+#  define INUM_WIDE 6      /* size initial window to hold this many icons */
+#endif
+#ifndef INUM_HIGH
+#  define INUM_HIGH 3
+#endif
 
-#define ISPACE_WIDE (ISIZE_WIDE+16)   /* icon spacing */
+#define ISPACE_WIDE (ISIZE_WIDE+ISIZE_WPAD)   /* icon spacing */
 #define ISPACE_TOP  4                 /* dist btwn top of ISPACE and ISIZE */
 #define ISPACE_TTOP 4                 /* dist btwn bot of icon and title */
 #define ISPACE_HIGH (ISIZE_HIGH+ISPACE_TOP+ISPACE_TTOP+16+4)
 
 #define DBLCLICKTIME 300  /* milliseconds */
 
-/* button/menu indicies */
-#define BR_CHDIR    0
-#define BR_DELETE   1
-#define BR_MKDIR    2
-#define BR_RENAME   3
-#define BR_RESCAN   4
-#define BR_UPDATE   5
-#define BR_NEWWIN   6
-#define BR_GENICON  7
-#define BR_SELALL   8
-#define BR_TEXTVIEW 9
-#define BR_RECURSUP 10
-#define BR_QUIT     11
-#define BR_CLOSE    12
-#define BR_NBUTTS   13   /* # of command buttons */
-#define BR_SEP1     13   /* separator */
-#define BR_HIDDEN   14
-#define BR_SELFILES 15
-#define BR_NCMDS    16   /* # of menu commands */
+#define COUNT(x) (sizeof (x) / sizeof (x)[0])
+
+/* button/menu indices */
+#define BR_CHDIR      0
+#define BR_DELETE     1
+#define BR_MKDIR      2
+#define BR_RENAME     3
+#define BR_RESCAN     4
+#define BR_UPDATE     5
+#define BR_NEWWIN     6
+#define BR_GENICON    7
+#define BR_SELALL     8
+#define BR_TEXTVIEW   9
+#define BR_RECURSUP   10
+#define BR_QUIT       11
+#define BR_CLOSE      12
+#define BR_NBUTTS     13   /* # of command buttons */
+#define BR_SEP1       13   /* separator */
+#define BR_HIDDEN     14
+#define BR_SELFILES   15
+#define BR_CLIPBRD    16
+#ifdef AUTO_EXPAND
+#  define BR_CLEARVD  17
+#  define BR_NCMDS    18   /* # of menu commands */
+#else
+#  define BR_NCMDS    17   /* # of menu commands */
+#endif
 
 #define BUTTW 80
 #define BUTTH 24
 
-static char *showHstr = "Show hidden files";
-static char *hideHstr = "Hide 'hidden' files";
-
-static char *cmdMList[] = { "Change directory...\t^c",
-		            "Delete file(s)\t^d",  
-			    "New directory...\t^n",   
-			    "Rename file...\t^r",     
-			    "Rescan directory\t^s",
-			    "Update icons\t^u",    
-			    "Open new window\t^w", 
-			    "Generate icon(s)\t^g",
-			    "Select all files\t^a",
-			    "Text view\t^t",
-			    "Recursive Update\t^e",
-			    "Quit xv\t^q",
-			    "Close window\t^c",
-			    MBSEP,
-			    "Show hidden files",     /* no equiv */
-			    "Select files...\t^f"
-			    };
+/* original size of window was 615 x 356 (for 80x60 thumbnails in 6x3 array) */
+#define DEF_BROWWIDE  (ISPACE_WIDE * INUM_WIDE + LRMARGINS * 2 + 29)
+#define DEF_BROWHIGH  (ISPACE_HIGH * INUM_HIGH + BUTTH * 2 + 16 + 28)
+/* last number is a fudge--e.g., extra spaces, borders, etc. -----^  */
+
+static const char *showHstr = "Show hidden files";
+static const char *hideHstr = "Hide 'hidden' files";
+
+static const char *cmdMList[] = { "Change directory...\t^c",
+				  "Delete file(s)\t^d",
+				  "New directory...\t^n",
+				  "Rename file...\t^r",
+				  "Rescan directory\t^s",
+				  "Update icons\t^u",
+				  "Open new window\t^w",
+				  "Generate icon(s)\t^g",
+				  "Select all files\t^a",
+				  "Text view\t^t",
+				  "Recursive Update\t^e",
+				  "Quit xv\t^q",
+				  "Close window\t^c",
+				  MBSEP,
+				  "Show hidden files",     /* no equiv */
+				  "Select files...\t^f",
+				  "Clipboard\t^x"
+#ifdef AUTO_EXPAND
+				  , "Clear virtual directory"
+#endif
+				  };
 
 
 #define MAXDEEP 30     /* maximum directory depth */
@@ -183,32 +246,43 @@
 	       } BFIL;
 
 /* data needed per schnauzer window */
-typedef struct {  Window win, iconW;
-		  int    vis, wasvis;
+typedef struct {  Window        win, iconW;
+		  int           vis, wasvis;
 
-		  int    wide, high;
-		  int    iwWide, iwHigh;
-		  int    numWide, numHigh, visHigh;
-
-		  SCRL   scrl;
-		  BUTT   but[BR_NBUTTS];
-		  MBUTT  dirMB, cmdMB;
-		  char   dispstr[256];
-		  int    numbutshown;
-		  int    showhidden;
-
-		  int    numlit;
-		  BFIL  *bfList;
-		  int    bfLen;
-		  int    lastIconClicked;
+		  int           wide, high;
+		  int           iwWide, iwHigh;
+		  int           numWide, numHigh, visHigh;
+
+		  SCRL          scrl;
+		  BUTT          but[BR_NBUTTS];
+		  MBUTT         dirMB, cmdMB;
+		  char          dispstr[256];
+		  int           numbutshown;
+		  int           showhidden;
+
+		  int           numlit;
+		  BFIL         *bfList;
+		  int           bfLen;
+		  int           lastIconClicked;
 		  unsigned long lastClickTime;
 
-		  int    ndirs;
-		  char  *mblist[MAXDEEP];
-		  char   path[MAXPATHLEN+2];   /* '/' terminated */
+		  int           ndirs;
+		  const char   *mblist[MAXDEEP];
+		  char          path[MAXPATHLEN+2];   /* '/' terminated */
+
+		  char         *str;
+		  int           siz, len;
+		  time_t        lst;
 		} BROWINFO;
 
 
+/* keep track of last icon visible in each path */
+typedef struct IVIS IVIS;
+    struct IVIS { IVIS   *next;
+                  char   *name;
+                  int    icon;
+                };
+
 static Cursor   movecurs, copycurs, delcurs;
 static BROWINFO binfo[MAXBRWIN];
 static Pixmap   bfIcons[BF_MAX], trashPix;
@@ -220,7 +294,7 @@
 static void closeBrowse      PARM((BROWINFO *));
 static int  brChkEvent       PARM((BROWINFO *, XEvent *));
 static void resizeBrowse     PARM((BROWINFO *, int, int));
-static void setBrowStr       PARM((BROWINFO *, char *));
+static void setBrowStr       PARM((BROWINFO *, const char *));
 static void doCmd            PARM((BROWINFO *, int));
 static void drawBrow         PARM((BROWINFO *));
 static void drawNumfiles     PARM((BROWINFO *));
@@ -255,12 +329,12 @@
 static void rescanDir        PARM((BROWINFO *));
 static int  namcmp           PARM((const void *, const void *));
 static void freeBfList       PARM((BROWINFO *br));
-static char **getDirEntries  PARM((char *, int *, int));
+static char **getDirEntries  PARM((const char *, int *, int));
 static void computeScrlVals  PARM((BROWINFO *, int *, int *));
 static void genSelectedIcons PARM((BROWINFO *));
 static void genIcon          PARM((BROWINFO *, BFIL *));
 static void loadThumbFile    PARM((BROWINFO *, BFIL *));
-static void writeThumbFile   PARM((BROWINFO *, BFIL *, byte *, int, 
+static void writeThumbFile   PARM((BROWINFO *, BFIL *, byte *, int,
 				      int, char *));
 
 static void makeThumbDir     PARM((BROWINFO *));
@@ -278,14 +352,14 @@
 static void doSelFilesCmd    PARM((BROWINFO *));
 
 static void doRecurseCmd     PARM((BROWINFO *));
-static void recurseUpdate    PARM((BROWINFO *, char *));
+static void recurseUpdate    PARM((BROWINFO *, const char *));
 
 static void rm_file          PARM((BROWINFO *, char *));
 static void rm_dir           PARM((BROWINFO *, char *));
 static void rm_dir1          PARM((BROWINFO *));
 
-static void dragFiles        PARM((BROWINFO *, BROWINFO *, char *, char *, 
-				   char *, char **, int, int));
+static void dragFiles        PARM((BROWINFO *, BROWINFO *, char *, char *,
+				   const char *, char **, int, int));
 static int  moveFile         PARM((char *, char *));
 static int  copyFile         PARM((char *, char *));
 static void cp               PARM((void));
@@ -294,16 +368,25 @@
 static void cp_special       PARM((struct stat *, int));
 static void cp_fifo          PARM((struct stat *, int));
 
+#ifdef AUTO_EXPAND
+static int  stat2bf          PARM((u_int, char *));
+#else
 static int  stat2bf          PARM((u_int));
+#endif
 
 static int  selmatch         PARM((char *, char *));
 static int  selmatch1        PARM((char *, char *));
+static void recIconVisible   PARM((char *, int));
+static void restIconVisible  PARM((BROWINFO *));
+
+static void clipChanges      PARM((BROWINFO *));
 
 
 
 /***************************************************************/
 void CreateBrowse(geom, fgstr, bgstr, histr, lostr)
-     char *geom, *fgstr, *bgstr, *histr, *lostr;
+     const char *geom;
+     const char *fgstr, *bgstr, *histr, *lostr;
 {
   int                   i;
   XSizeHints            hints;
@@ -369,8 +452,8 @@
       if (gset & YNegative) gy1 = gy - i * 20;
 	               else gy1 = gy + i * 20;
 
-      if ((gset & WidthValue) && (gset & HeightValue)) 
-	sprintf(wgeom, "%dx%d%s%d%s%d", gw, gh, 
+      if ((gset & WidthValue) && (gset & HeightValue))
+	sprintf(wgeom, "%dx%d%s%d%s%d", gw, gh,
 		(gset & XNegative) ? "-" : "+", abs(gx1),
 		(gset & YNegative) ? "-" : "+", abs(gy1));
       else
@@ -402,11 +485,11 @@
 
     /* note: everything is sized and positioned in ResizeBrowse() */
 
-    br->iconW = XCreateSimpleWindow(theDisp, br->win, 1,1, 100,100, 
+    br->iconW = XCreateSimpleWindow(theDisp, br->win, 1,1, 100,100,
 				     1,browfg,browbg);
     if (!br->iconW) FatalError("can't create schnauzer icon window!");
 
-    SCCreate(&(br->scrl), br->win, 0,0, 1,100, 0,0,0,0, 
+    SCCreate(&(br->scrl), br->win, 0,0, 1,100, 0,0,0,0,
 	     browfg, browbg, browhi, browlo, drawIconWin);
 
 
@@ -448,10 +531,12 @@
 	     "Text view",browfg,browbg,browhi,browlo);
     BTCreate(&(br->but[BR_RECURSUP]), br->win, 0,0,BUTTW,BUTTH,
 	     "RecursUpd",browfg,browbg,browhi,browlo);
-    BTCreate(&(br->but[BR_QUIT]),  br->win, 0,0,BUTTW,BUTTH,
+    BTCreate(&(br->but[BR_QUIT]), br->win, 0,0,BUTTW,BUTTH,
 	     "Quit xv",browfg,browbg,browhi,browlo);
-    BTCreate(&(br->but[BR_CLOSE]),  br->win, 0,0,BUTTW,BUTTH,
+    BTCreate(&(br->but[BR_CLOSE]), br->win, 0,0,BUTTW,BUTTH,
 	     "Close",browfg,browbg,browhi,browlo);
+    BTCreate(&(br->but[BR_CLIPBRD]), br->win, 0,0,BUTTW,BUTTH,
+	     "Clipboard",browfg,browbg,browhi,browlo);
 
     XMapSubwindows(theDisp, br->win);
 
@@ -486,55 +571,62 @@
   bfIcons[BF_SOCK]=MakePix1(br->win,br_sock_bits,br_sock_width,br_sock_height);
   bfIcons[BF_FIFO]=MakePix1(br->win,br_fifo_bits,br_fifo_width,br_fifo_height);
 
-  bfIcons[BF_ERROR]   = MakePix1(br->win, br_error_bits, 
+  bfIcons[BF_ERROR]   = MakePix1(br->win, br_error_bits,
 			       br_error_width,     br_error_height);
 
 /* bfIcons[BF_UNKNOWN] = MakePix1(br->win, br_unknown_bits,
                                 br_unknown_width, br_unknown_height); */
-
   bfIcons[BF_UNKNOWN] = bfIcons[BF_FILE];
 
-  bfIcons[BF_GIF] =MakePix1(br->win,br_gif_bits, br_gif_width, br_gif_height);
-  bfIcons[BF_PM]  =MakePix1(br->win,br_pm_bits,  br_pm_width,  br_pm_height);
-  bfIcons[BF_PBM] =MakePix1(br->win,br_pbm_bits, br_pbm_width, br_pbm_height);
-  bfIcons[BF_XBM] =MakePix1(br->win,br_xbm_bits, br_xbm_width, br_xbm_height);
-
-  bfIcons[BF_SUNRAS]  = MakePix1(br->win, br_sunras_bits,
-				 br_sunras_width, br_sunras_height);
-  bfIcons[BF_BMP]     = MakePix1(br->win,br_bmp_bits, 
-				 br_bmp_width, br_bmp_height);
-  bfIcons[BF_UTAHRLE] = MakePix1(br->win, br_utahrle_bits, 
-				 br_utahrle_width, br_utahrle_height);
+  bfIcons[BF_COMPRESS] = MakePix1(br->win, br_cmpres_bits,
+				  br_cmpres_width, br_cmpres_height);
+  bfIcons[BF_BZIP2]    = MakePix1(br->win, br_bzip2_bits,
+				  br_bzip2_width, br_bzip2_height);
 
+  bfIcons[BF_BMP] =MakePix1(br->win,br_bmp_bits, br_bmp_width, br_bmp_height);
+  bfIcons[BF_FITS]=MakePix1(br->win,br_fits_bits,br_fits_width,br_fits_height);
+  bfIcons[BF_GIF] =MakePix1(br->win,br_gif_bits, br_gif_width, br_gif_height);
+  bfIcons[BF_IFF] =MakePix1(br->win,br_iff_bits, br_iff_width, br_iff_height);
   bfIcons[BF_IRIS]=MakePix1(br->win,br_iris_bits,br_iris_width,br_iris_height);
-  bfIcons[BF_PCX] =MakePix1(br->win,br_pcx_bits, br_pcx_width, br_pcx_height);
   bfIcons[BF_JFIF]=MakePix1(br->win,br_jfif_bits,br_jfif_width,br_jfif_height);
-  bfIcons[BF_TIFF]=MakePix1(br->win,br_tiff_bits,br_tiff_width,br_tiff_height);
+  bfIcons[BF_JP2] =MakePix1(br->win,br_jp2_bits, br_jp2_width, br_jp2_height);
+  bfIcons[BF_JPC] =MakePix1(br->win,br_jpc_bits, br_jpc_width, br_jpc_height);
+  bfIcons[BF_MAG] =MakePix1(br->win,br_mag_bits, br_mag_width, br_mag_height);
+  bfIcons[BF_MAKI]=MakePix1(br->win,br_maki_bits,br_maki_width,br_maki_height);
+  bfIcons[BF_PBM] =MakePix1(br->win,br_pbm_bits, br_pbm_width, br_pbm_height);
+  bfIcons[BF_PCD] =MakePix1(br->win,br_pcd_bits, br_pcd_width, br_pcd_height);
+  bfIcons[BF_PCX] =MakePix1(br->win,br_pcx_bits, br_pcx_width, br_pcx_height);
   bfIcons[BF_PDS] =MakePix1(br->win,br_pds_bits, br_pds_width, br_pds_height);
-
-  bfIcons[BF_COMPRESS]= MakePix1(br->win, br_cmpres_bits,
-				 br_cmpres_width, br_cmpres_height);
-
+  bfIcons[BF_PIC2]=MakePix1(br->win,br_pic2_bits,br_pic2_width,br_pic2_height);
+  bfIcons[BF_PIC] =MakePix1(br->win,br_pic_bits, br_pic_width, br_pic_height);
+  bfIcons[BF_PI]  =MakePix1(br->win,br_pi_bits,  br_pi_width,  br_pi_height);
+  bfIcons[BF_PM]  =MakePix1(br->win,br_pm_bits,  br_pm_width,  br_pm_height);
+  bfIcons[BF_PNG] =MakePix1(br->win,br_png_bits, br_png_width, br_png_height);
   bfIcons[BF_PS]  =MakePix1(br->win,br_ps_bits,  br_ps_width,  br_ps_height);
-  bfIcons[BF_IFF] =MakePix1(br->win,br_iff_bits, br_iff_width, br_iff_height);
-
-  bfIcons[BF_TARGA]   = MakePix1(br->win, br_targa_bits,
-				 br_targa_width, br_targa_height);
-
+  bfIcons[BF_TGA] =MakePix1(br->win,br_tga_bits, br_tga_width, br_tga_height);
+  bfIcons[BF_TIFF]=MakePix1(br->win,br_tiff_bits,br_tiff_width,br_tiff_height);
+  bfIcons[BF_XBM] =MakePix1(br->win,br_xbm_bits, br_xbm_width, br_xbm_height);
   bfIcons[BF_XPM] =MakePix1(br->win,br_xpm_bits, br_xpm_width, br_xpm_height);
   bfIcons[BF_XWD] =MakePix1(br->win,br_xwd_bits, br_xwd_width, br_xwd_height);
-  bfIcons[BF_FITS]=MakePix1(br->win,br_fits_bits,br_fits_width,br_fits_height);
+  bfIcons[BF_ZX]  =MakePix1(br->win,br_zx_bits,  br_zx_width,  br_zx_height);
+
+  bfIcons[BF_SUNRAS]  = MakePix1(br->win, br_sunras_bits,
+				 br_sunras_width, br_sunras_height);
+  bfIcons[BF_UTAHRLE] = MakePix1(br->win, br_utahrle_bits,
+				 br_utahrle_width, br_utahrle_height);
+  bfIcons[BF_MGCSFX]  = MakePix1(br->win, br_mgcsfx_bits,
+				 br_mgcsfx_width, br_mgcsfx_height);
 
 
   /* check that they all got built */
   for (i=0; i<BF_MAX && bfIcons[i]; i++);
-  if (i<BF_MAX) 
+  if (i<BF_MAX)
     FatalError("unable to create all built-in icons for schnauzer");
 
   for (i=0; i<MAXBRWIN; i++) {
     resizeBrowse(&binfo[i], DEF_BROWWIDE, DEF_BROWHIGH);
 
-    XSelectInput(theDisp, binfo[i].win, ExposureMask | ButtonPressMask | 
+    XSelectInput(theDisp, binfo[i].win, ExposureMask | ButtonPressMask |
 		 KeyPressMask | StructureNotifyMask);
   }
 
@@ -557,7 +649,7 @@
     movecurs = XCreatePixmapCursor(theDisp,mcpix,fcmpix,&cursfg,&cursbg,13,13);
     copycurs = XCreatePixmapCursor(theDisp,ccpix,fcmpix,&cursfg,&cursbg,13,13);
     delcurs  = XCreatePixmapCursor(theDisp,dcpix,fcmpix,&cursbg,&cursfg,13,13);
-    if (!movecurs || !copycurs || !delcurs) 
+    if (!movecurs || !copycurs || !delcurs)
       FatalError("unable to create schnauzer cursors...");
   }
   else FatalError("unable to create schnauzer cursors...");
@@ -566,7 +658,7 @@
   XFreePixmap(theDisp, ccpix);
   XFreePixmap(theDisp, dcpix);
   XFreePixmap(theDisp, fcmpix);
-    
+
 
   hasBeenSized = 1;  /* we can now start looking at browse events */
 }
@@ -576,9 +668,10 @@
 void OpenBrowse()
 {
   /* opens up a single browser window */
-  int i;
+
+  int       i;
   BROWINFO *br;
-  char     path[MAXPATHLEN+1];
+  char      path[MAXPATHLEN+1];
 
   /* find next browser to be opened */
   for (i=0; i<MAXBRWIN; i++) {
@@ -586,11 +679,11 @@
     if (!br->vis) break;
   }
   if (i==MAXBRWIN) return;  /* full up: shouldn't happen */
-  
+
   anyBrowUp = 1;
   XMapRaised(theDisp, br->win);
   br->vis = 1;
-  
+
   freeBfList(br);
 
   /* see if some browser is pointing to the same path as CWD.  If so,
@@ -645,7 +738,7 @@
   /* free all info for this browse window */
   freeBfList(br);
   sprintf(br->path, BOGUSPATH);
-  
+
   /* turn on 'open new window' command doodads */
   windowMB.dim[WMB_BROWSE] = 0;
   for (i=0; i<MAXBRWIN; i++) {
@@ -698,6 +791,9 @@
   }
 }
 
+#ifdef VS_RESCMAP
+static int _IfTempOut=0;
+#endif
 
 /***************************************************************/
 void KillBrowseWindows()
@@ -730,7 +826,6 @@
   return 0;
 }
 
-
 /***************************************************************/
 static int brChkEvent(br, xev)
      BROWINFO *br;
@@ -739,22 +834,36 @@
   /* checks event to see if it's a browse-window related thing.  If it
      is, it eats the event and returns '1', otherwise '0'. */
 
-  int    i, rv;
-  char buf[1024];
-
-  rv = 1;
+  int rv = 1;
 
   if (!hasBeenSized) return 0;  /* ignore evrythng until we get 1st Resize */
 
+
+#ifdef VS_RESCMAP
+  /* force change color map if have LocalCmap */
+  if (browPerfect && browCmap && (_IfTempOut==2)) {
+    int i;
+    XSetWindowAttributes xswa;
+
+    xswa.colormap = LocalCmap? LocalCmap : theCmap;
+    for (i=0; i<MAXBRWIN; ++i)
+      XChangeWindowAttributes(theDisp, binfo[i].win, CWColormap, &xswa);
+    XFlush(theDisp);
+    _IfTempOut=1;
+  }
+#endif
+
   if (xev->type == Expose) {
     int x,y,w,h;
     XExposeEvent *e = (XExposeEvent *) xev;
     x = e->x;  y = e->y;  w = e->width;  h = e->height;
 
     /* throw away excess redraws for 'dumb' windows */
-    if (e->count > 0 && (e->window == br->scrl.win)) {}
+    if (e->count > 0 && (e->window == br->scrl.win))
+      ;
 
-    else if (e->window == br->scrl.win) SCRedraw(&(br->scrl));
+    else if (e->window == br->scrl.win)
+      SCRedraw(&(br->scrl));
 
     else if (e->window == br->win || e->window == br->iconW) { /* smart wins */
       /* group individual expose rects into a single expose region */
@@ -788,7 +897,7 @@
 	fprintf(stderr,"grouped %d expose events into %d,%d %dx%d rect\n",
 		count, rect.x, rect.y, rect.width, rect.height);
       }
-      
+
       if      (e->window == br->win)   drawBrow(br);
 
       else if (e->window == br->iconW)
@@ -807,13 +916,55 @@
     int i,x,y;
     x = e->x;  y = e->y;
 
+#ifdef VS_RESCMAP
+    if (browCmap && browPerfect && (_IfTempOut!=0)) {
+      XSetWindowAttributes  xswa;
+      _IfTempOut--;
+      xswa.colormap = browCmap;
+      for(i=0;i<MAXBRWIN;i++)
+        XChangeWindowAttributes(theDisp, binfo[i].win, CWColormap, &xswa);
+      XFlush(theDisp);
+    }
+#endif
+
     if (e->button == Button1) {
       if      (e->window == br->win)      clickBrow(br,x,y);
       else if (e->window == br->scrl.win) SCTrack(&(br->scrl),x,y);
       else if (e->window == br->iconW) {
-	i = clickIconWin(br, x,y,(unsigned long) e->time, 
+	i = clickIconWin(br, x,y,(unsigned long) e->time,
 			 (e->state&ControlMask) || (e->state&ShiftMask));
-
+      }
+      else rv = 0;
+    }
+    else if (e->button == Button4) {   /* note min vs. max, + vs. - */
+      /* scroll regardless of where we are in the browser window */
+      if (e->window == br->win ||
+	  e->window == br->scrl.win ||
+	  e->window == br->iconW)
+      {
+	SCRL *sp=&(br->scrl);
+	int  halfpage=MAX(1,sp->page/2); /* user resize to 1 line? */
+
+	if (sp->val > sp->min+halfpage)
+	  SCSetVal(sp,sp->val-halfpage);
+	else
+	  SCSetVal(sp,sp->min);
+      }
+      else rv = 0;
+    }
+    else if (e->button == Button5) {   /* note max vs. min, - vs. + */
+      /* scroll regardless of where we are in the browser window */
+      if (e->window == br->win ||
+	  e->window == br->scrl.win ||
+	  e->window == br->iconW)
+      {
+	SCRL *sp=&(br->scrl);
+	int  halfpage=MAX(1,sp->page/2); /* user resize to 1 line? */
+
+	if (sp->val < sp->max-halfpage)
+	  SCSetVal(sp,sp->val+halfpage);
+	else
+	  SCSetVal(sp,sp->max);
       }
       else rv = 0;
     }
@@ -837,7 +988,7 @@
 
       if (br->wide != e->width || br->high != e->height) {
 	if (DEBUG) fprintf(stderr,"Forcing a redraw!  (from configure)\n");
-	XClearArea(theDisp, br->win, 0, 0, 
+	XClearArea(theDisp, br->win, 0, 0,
 		   (u_int) e->width, (u_int) e->height, True);
 	resizeBrowse(br, e->width, e->height);
       }
@@ -877,7 +1028,7 @@
      int w,h;
 {
   XSizeHints hints;
-  int        i, minv, maxv, curv, page, maxh;
+  int        i, maxv, page, maxh;
 
   if (br->wide == w && br->high == h) return;  /* no change in size */
 
@@ -895,7 +1046,7 @@
   br->iwHigh = (maxh / ISPACE_HIGH) * ISPACE_HIGH;
   if (br->iwHigh < ISPACE_HIGH) br->iwHigh = ISPACE_HIGH;
 
-  XMoveResizeWindow(theDisp, br->iconW, LRMARGINS, TOPMARGIN, 
+  XMoveResizeWindow(theDisp, br->iconW, LRMARGINS, TOPMARGIN,
 		    (u_int) br->iwWide, (u_int) br->iwHigh);
 
 
@@ -907,11 +1058,11 @@
   for (i=0; i<BR_NBUTTS; i++) {
     /* 'close' always goes on right-most edge */
 
-    if (i<br->numbutshown) 
+    if (i<br->numbutshown)
       br->but[i].x = br->wide - (1+br->numbutshown-i) * (BUTTW+5);
     else if (i==BR_CLOSE)
       br->but[i].x = br->wide - (BUTTW+5);
-    else 
+    else
       br->but[i].x = br->wide + 10;    /* offscreen */
 
     br->but[i].y = br->high - BUTTH - 5;
@@ -928,11 +1079,11 @@
   br->numWide = br->iwWide / ISPACE_WIDE;
   br->visHigh = br->iwHigh / ISPACE_HIGH;
 
-  /* compute minv,maxv,curv,page values based on new current size */
+  /* compute maxv,page values based on new current size */
   computeScrlVals(br, &maxv, &page);
   if (br->scrl.val>maxv) br->scrl.val = maxv;
-  
-  SCChange(&br->scrl, LRMARGINS+br->iwWide+1, TOPMARGIN, 
+
+  SCChange(&br->scrl, LRMARGINS+br->iwWide+1, TOPMARGIN,
 	   1, br->iwHigh, 0, maxv, br->scrl.val, page);
 }
 
@@ -940,12 +1091,12 @@
 
 /***************************************************************/
 void SetBrowStr(str)
-     char *str;
+     const char *str;
 {
   /* put string in *all* browse windows */
   int i;
 
-  for (i=0; i<MAXBRWIN; i++) 
+  for (i=0; i<MAXBRWIN; i++)
     setBrowStr(&binfo[i], str);
 }
 
@@ -953,9 +1104,10 @@
 /***************************************************************/
 static void setBrowStr(br, str)
      BROWINFO *br;
-     char *str;
+     const char *str;
 {
   strncpy(br->dispstr, str, (size_t) 256);
+  br->dispstr[255] = '\0';
   drawBrowStr(br);
   XFlush(theDisp);
 }
@@ -992,7 +1144,7 @@
 
 	char tmp[64];
 
-	sprintf(tmp, "Re-coloring icons:  processed %d out of %d...", 
+	sprintf(tmp, "Re-coloring icons:  processed %d out of %d...",
 		i+1, br->bfLen);
 	setBrowStr(br, tmp);
       }
@@ -1011,14 +1163,14 @@
 {
   /* called when file 'name' has been deleted.  If any of the browsers
      were showing the directory that the file was in, does a rescan() */
-  
+
   int  i;
   char buf[MAXPATHLEN + 2], *tmp;
 
   strcpy(buf, name);
-  tmp = BaseName(buf);
+  tmp = (char *) BaseName(buf);  /* intentionally losing constness */
   *tmp = '\0';     /* truncate after last '/' */
-  
+
   for (i=0; i<MAXBRWIN; i++) {
     if (strcmp(binfo[i].path, buf)==0) rescanDir(&binfo[i]);
   }
@@ -1043,6 +1195,8 @@
      BROWINFO *br;
      int cmd;
 {
+  br->lst = 0;
+
   switch (cmd) {
   case BR_CHDIR:   doChdirCmd(br);
                    break;
@@ -1070,9 +1224,9 @@
   case BR_GENICON: genSelectedIcons(br);  break;
 
   case BR_SELALL:  {
-                     int i;  char buf[128];
+                     int i;
 
-		     for (i=0; i<br->bfLen; i++) 
+		     for (i=0; i<br->bfLen; i++)
 		       br->bfList[i].lit = 1;
 		     br->numlit = br->bfLen;
 
@@ -1087,20 +1241,25 @@
                    break;
 
   case BR_TEXTVIEW: doTextCmd(br);       break;
- 
+
   case BR_QUIT:     Quit(0);             break;
 
   case BR_CLOSE:    closeBrowse(br);     break;
 
   case BR_HIDDEN:   br->showhidden = !br->showhidden;
-                    br->cmdMB.list[cmd] = (br->showhidden) 
-		                              ? hideHstr : showHstr;
+                    br->cmdMB.list[cmd] = br->showhidden ? hideHstr : showHstr;
                     rescanDir(br);
                     break;
 
   case BR_SELFILES: doSelFilesCmd(br);   break;
 
   case BR_RECURSUP: doRecurseCmd(br);    break;
+
+  case BR_CLIPBRD:  clipChanges(br);     break;
+
+#ifdef AUTO_EXPAND
+  case BR_CLEARVD:  Vdsettle();          break;
+#endif
   }
 }
 
@@ -1137,16 +1296,16 @@
 
   if (br->bfLen != 1) sprintf(foo, "%d files", br->bfLen);
   else strcpy(foo, "1 file");
-    
+
   XSetForeground(theDisp, theGC, browbg);
-  XFillRectangle(theDisp,br->win, theGC, x+1,y+1, 
+  XFillRectangle(theDisp,br->win, theGC, x+1,y+1,
 		 (u_int) StringWidth(foo)+6, (u_int) br->dirMB.h-1);
 
   XSetForeground(theDisp,theGC,browfg);
   XDrawRectangle(theDisp,br->win, theGC, x,y,
 		 (u_int) StringWidth(foo)+7, (u_int) br->dirMB.h);
 
-  Draw3dRect(br->win, x+1, y+1, (u_int) StringWidth(foo)+5, 
+  Draw3dRect(br->win, x+1, y+1, (u_int) StringWidth(foo)+5,
 	     (u_int) br->dirMB.h-2, R3D_IN, 2,  browhi, browlo, browbg);
 
   XSetForeground(theDisp,theGC,browfg);
@@ -1163,7 +1322,7 @@
 
   if (nf != 1) sprintf(foo,"%d files",nf);
   else strcpy(foo,"1 file");
-    
+
   XClearArea(theDisp,br->win, 30, br->dirMB.y,
 	     (u_int) StringWidth(foo)+8, (u_int) br->dirMB.h+1, False);
 }
@@ -1185,13 +1344,13 @@
 
   XSetForeground(theDisp,theGC,browfg);
   XDrawRectangle(theDisp,br->win, theGC, x,y, (u_int) w, (u_int) h);
-  Draw3dRect(br->win, x+1, y+1, (u_int) w-2, (u_int) h-2, 
+  Draw3dRect(br->win, x+1, y+1, (u_int) w-2, (u_int) h-2,
 	     R3D_IN, 2,  browhi, browlo, browbg);
 
   XSetForeground(theDisp,theGC,browfg);
   XSetBackground(theDisp,theGC,browbg);
-  XCopyPlane(theDisp, trashPix, br->win, theGC, 
-	     0,0,(u_int) br_trash_width, (u_int) br_trash_height, 
+  XCopyPlane(theDisp, trashPix, br->win, theGC,
+	     0,0,(u_int) br_trash_width, (u_int) br_trash_height,
 	     x+(w-br_trash_width)/2, y+(h-br_trash_height)/2,
 	     1L);
 }
@@ -1222,7 +1381,7 @@
   y = br->high - (BUTTH+10) - (CHIGH + 6);
 
   XSetForeground(theDisp, theGC, browbg);
-  XFillRectangle(theDisp, br->win, theGC, 0, y+3, 
+  XFillRectangle(theDisp, br->win, theGC, 0, y+3,
 		 (u_int) br->wide, (u_int) CHIGH+1);
 
   XSetForeground(theDisp, theGC, browfg);
@@ -1250,6 +1409,19 @@
   int i, allowtext;
 
   if (!nostr) setSelInfoStr(br, sel);
+#ifdef AUTO_EXPAND
+  if (Isvdir(br->path)) {
+    BTSetActive(&br->but[BR_DELETE],  0);
+    br->cmdMB.dim[BR_DELETE] = 1;
+
+    BTSetActive(&br->but[BR_RENAME],  0);
+    br->cmdMB.dim[BR_RENAME] = 1;
+
+    BTSetActive(&br->but[BR_MKDIR],  0);
+    br->cmdMB.dim[BR_MKDIR] = 1;
+  }
+  else {
+#endif
   BTSetActive(&br->but[BR_DELETE],  br->numlit>0);
   br->cmdMB.dim[BR_DELETE] = !(br->numlit>0);
 
@@ -1258,6 +1430,11 @@
 
   BTSetActive(&br->but[BR_GENICON], br->numlit>0);
   br->cmdMB.dim[BR_GENICON] = !(br->numlit>0);
+#ifdef AUTO_EXPAND
+  BTSetActive(&br->but[BR_MKDIR],  1);
+  br->cmdMB.dim[BR_MKDIR] = 0;
+  }
+#endif
 
   /* turn on 'text view' cmd if exactly one non-dir is lit */
   allowtext = 0;
@@ -1277,7 +1454,7 @@
 {
   /* sets the '# files selected' string in the brow window appropriately */
 
-  /* criteria:  
+  /* criteria:
    *    if no files are lit, display ''
    *    if 1 file is lit, pretend it was selected, fall through...
    *    if 1 or more files are lit
@@ -1316,10 +1493,13 @@
 
 	else if (bf->ftype != BF_DIR) {     /* no info.  display file size */
 	  struct stat st;
-	      
+
 	  sprintf(buf, "%s%s", br->path, bf->name);  /* build filename */
+#ifdef AUTO_EXPAND
+	  Dirtovd(buf);
+#endif
 	  if (stat(buf, &st) == 0) {
-	    sprintf(buf, "%s:  %ld bytes", bf->name, st.st_size);
+	    sprintf(buf, "%s:  %ld bytes", bf->name, (long)st.st_size);
 	    strcat(buf, buf1);
 	  }
 	}
@@ -1360,8 +1540,8 @@
       if (j>=0 && j < br->bfLen) drawIcon(br,j);
     }
   }
-      
-  Draw3dRect(br->iconW, 0, 0, (u_int) br->iwWide-1, (u_int) br->iwHigh-1, 
+
+  Draw3dRect(br->iconW, 0, 0, (u_int) br->iwWide-1, (u_int) br->iwHigh-1,
 	     R3D_IN, 2, browhi, browlo, browbg);
 }
 
@@ -1371,10 +1551,8 @@
      int delta;
      SCRL *sptr;
 {
-  int   i,indx, x,y, ix,iy, num;
-  BFIL     *bf;
+  int   i,indx, num;
   BROWINFO *br;
-  char  tmpstr[64], *nstr;
 
   /* figure out BROWINFO pointer from SCRL pointer */
   for (i=0; i<MAXBRWIN; i++) {
@@ -1385,7 +1563,7 @@
   br = &binfo[i];
 
   /* make sure we've been sized.  Necessary, as creating/modifying the
-     scrollbar calls this routine directly, rather than through 
+     scrollbar calls this routine directly, rather than through
      BrowseCheckEvent() */
 
   if (!hasBeenSized) return;
@@ -1413,12 +1591,12 @@
 	if (y+h > br->iwHigh-4) h = (br->iwHigh-4)-y + 2;
       }
       XFillRectangle(theDisp, br->iconW, theGC, x, y, ISPACE_WIDE, (u_int) h);
-	
+
       if (indx>=0 && indx < br->bfLen) drawIcon(br, indx);
     }
   }
 
-  Draw3dRect(br->iconW, 0, 0, (u_int) br->iwWide-1, (u_int) br->iwHigh-1, 
+  Draw3dRect(br->iconW, 0, 0, (u_int) br->iwWide-1, (u_int) br->iwHigh-1,
 	     R3D_IN, 2, browhi, browlo, browbg);
 }
 
@@ -1431,7 +1609,11 @@
 {
   int i,x,y,ix,iy,sw,sh,sx,sy;
   BFIL *bf;
-  char  tmpstr[64], fixedname[64], *nstr, *str;
+  const char  *nstr, *cstr;
+  char  tmpstr[64];
+#ifdef VMS
+  char  fixedname[64];
+#endif
 
 
   if (num<0 || num >= br->bfLen) return;
@@ -1463,49 +1645,51 @@
   }
 
   else if (bf->ftype == BF_HAVEIMG && bf->ximage) {
-    XPutImage(theDisp, br->iconW, theGC, bf->ximage, 0,0, ix,iy, 
+    XPutImage(theDisp, br->iconW, theGC, bf->ximage, 0,0, ix,iy,
 	      (u_int) bf->w, (u_int) bf->h);
   }
 
   else {  /* shouldn't happen */
-    XDrawRectangle(theDisp, br->iconW, theGC, ix, iy, 
+    XDrawRectangle(theDisp, br->iconW, theGC, ix, iy,
 		   (u_int) bf->w, (u_int) bf->h);
   }
 
 
-  str = bf->name;
+  cstr = bf->name;
 #ifdef VMS
   if (bf->ftype == BF_DIR) {
+    char  *vstr;
     strcpy(fixedname, bf->name);
-    str = rindex(fixedname, '.');   /* lop off '.DIR' suffix, if any */
-    if (str) *str = '\0';
-    str = fixedname;
+    vstr = rindex(fixedname, '.');   /* lop off '.DIR' suffix, if any */
+    if (vstr) *vstr = '\0';
+    cstr = fixedname;
   }
 #endif /* VMS */
 
-  if (!strcmp(bf->name,"..")) str = "<parent>";
+  if (!strcmp(bf->name,"..")) cstr = "<parent>";
 
 
   /* decide if the title is too big, and shorten if neccesary */
-  if (StringWidth(str) > ISPACE_WIDE-6) {
-    int dotpos; 
-    strncpy(tmpstr, str, (size_t) 56);
+  if (StringWidth(cstr) > ISPACE_WIDE-6) {
+    int dotpos;
+    strncpy(tmpstr, cstr, (size_t) 56);
+    tmpstr[56] = '\0'; /* MR: otherwise it dies on long file names */
     dotpos = strlen(tmpstr);
     strcat(tmpstr,"...");
 
     while(StringWidth(tmpstr) > ISPACE_WIDE-6 && dotpos>0) {
       /* change last non-dot char in tmpstr to a dot, and lop off
 	 last dot */
-	    
+
       dotpos--;
       tmpstr[dotpos] = '.';
       tmpstr[dotpos+3] = '\0';
     }
-    
+
     nstr = tmpstr;
   }
-  else nstr = str;
-  
+  else nstr = cstr;
+
 
   /* draw the title */
   sw = StringWidth(nstr);
@@ -1516,12 +1700,12 @@
 
   XSetForeground(theDisp, theGC,
 		 (bf->lit && bf->lit!=ICON_ONLY) ? browfg : browbg);
-  XFillRectangle(theDisp, br->iconW, theGC, sx, sy, 
+  XFillRectangle(theDisp, br->iconW, theGC, sx, sy,
 		 (u_int) sw + 4, (u_int) sh + 2);
 
   XSetForeground(theDisp, theGC,
 		 (bf->lit && bf->lit!=ICON_ONLY) ? browbg : browfg);
-  CenterString(br->iconW, x + ISPACE_WIDE/2, 
+  CenterString(br->iconW, x + ISPACE_WIDE/2,
 	       y + ISPACE_TOP + ISIZE_HIGH + ISPACE_TTOP + CHIGH/2, nstr);
 }
 
@@ -1535,7 +1719,6 @@
 
   int i,x,y,ix,iy,w,h;
   BFIL *bf;
-  char  tmpstr[64], *nstr;
 
   if (num<0 || num >= br->bfLen) return;
   bf = &(br->bfList[num]);
@@ -1579,12 +1762,12 @@
   y = (i / br->numWide) * ISPACE_HIGH;
 
   XSetForeground(theDisp, theGC, browbg);
-  XFillRectangle(theDisp, br->iconW, theGC, 
+  XFillRectangle(theDisp, br->iconW, theGC,
 		 x, y + ISPACE_TOP + ISIZE_HIGH + ISPACE_TTOP - 1,
 		 (u_int) ISPACE_WIDE, (u_int) LINEHIGH);
 
-  if (ctrlColor) 
-    Draw3dRect(br->iconW, 0, 0, (u_int) br->iwWide-1, (u_int) br->iwHigh-1, 
+  if (ctrlColor)
+    Draw3dRect(br->iconW, 0, 0, (u_int) br->iwWide-1, (u_int) br->iwHigh-1,
 	       R3D_IN, 2, browhi, browlo, browbg);
 }
 
@@ -1597,6 +1780,10 @@
 {
   int sval, first, numvis;
 
+  /* if we know what path we have, remember last visible icon for this path */
+  if (br->path)
+    recIconVisible(br->path, num);
+
   /* if icon #i isn't visible, adjust scrollbar so it *is* */
 
   sval = br->scrl.val;
@@ -1648,29 +1835,14 @@
   return;
 }
 
-
 /***************************************************************/
-static int clickIconWin(br, mx, my, mtime, multi)
-     BROWINFO *br;
-     int mx,my,multi;
-     unsigned long mtime;
+static int updateSel(br, sel, multi, mtime)
+  BROWINFO *br;
+  int sel, multi;
+  unsigned long mtime;
 {
-  /* returns '-1' normally, returns an index into bfList[] if the user
-     double-clicks an icon */
-
-  int       i,j, base, num, x,y,ix,iy, rv, sel, cpymode, dodel;
-  BROWINFO *destBr;
-  BFIL     *bf;
-  char      buf[256], *destFolderName;
-
-  rv = -1;     /* default return value */
-  if (!br->bfList || !br->bfLen) return rv;
-
-  destBr = br;  destFolderName = ".";
-
-  sel = mouseInWhichIcon(br, mx, my);
-
-  dodel = 0;
+  int i;
+  BFIL *bf;
 
   if (sel == -1) {  /* clicked on nothing */
     if (!multi) {   /* deselect all */
@@ -1681,7 +1853,7 @@
     }
 
     changedNumLit(br, sel, 0);
-    br->lastIconClicked = -1;  
+    br->lastIconClicked = -1;
   }
 
 
@@ -1725,14 +1897,14 @@
 
     changedNumLit(br, sel, 0);
 
-    
+
     /* see if we've double-clicked something */
-    if (sel==br->lastIconClicked && mtime-br->lastClickTime < DBLCLICKTIME) {
-      int k;
+    if (mtime &&
+        sel==br->lastIconClicked && mtime-br->lastClickTime < DBLCLICKTIME) {
       br->lastIconClicked = -1;    /* YES */
 
       doubleClick(br, sel);
-      return rv;
+      return -1;
     }
 
     else {
@@ -1741,9 +1913,37 @@
     }
   }
 
-
   changedNumLit(br, -1, 0);
+  return 0;
+}
+
+
+/***************************************************************/
+static int clickIconWin(br, mx, my, mtime, multi)
+     BROWINFO *br;
+     int mx,my,multi;
+     unsigned long mtime;
+{
+  /* returns '-1' normally, returns an index into bfList[] if the user
+     double-clicks an icon */
+
+  int         i,j, sel, cpymode, dodel;
+  BROWINFO   *destBr;
+  BFIL       *bf;
+  char        buf[256];
+  const char *destFolderName;
+
+  if (!br->bfList || !br->bfLen) return -1;
+
+  destBr = br;  destFolderName = ".";
 
+  sel = mouseInWhichIcon(br, mx, my);
+  dodel = 0;
+
+  recIconVisible(br->path, sel);
+
+  if (updateSel(br, sel, multi, mtime))
+    return -1;
 
 
   {    /* track mouse until button1 is released */
@@ -1759,10 +1959,10 @@
     first = 1;  hasrect = 0;  cpymode = 0;
     origsval = br->scrl.val;
 
-    if ( (sel>=0 && !multi) || sel==-1) {  
+    if ( (sel>=0 && !multi) || sel==-1) {
       /* clicked on an icon, or clicked on nothing... */
 
-      while (!XQueryPointer(theDisp, rootW, &rW, &cW, &rootx, &rooty, 
+      while (!XQueryPointer(theDisp, rootW, &rW, &cW, &rootx, &rooty,
 			    &x,&y,&mask));
       if (mask & Button1Mask) {  /* still held down */
 
@@ -1773,7 +1973,7 @@
 	else curs = movecurs;
 
 	/* change cursors */
-	for (i=0; i<MAXBRWIN; i++) 
+	for (i=0; i<MAXBRWIN; i++)
 	  XDefineCursor(theDisp,binfo[i].iconW, curs);
 
 	samepos = oldx = oldy = oldbrnum = 0;
@@ -1785,43 +1985,43 @@
 
 	  if (sel>=0) {  /* see if changed copy/move status (and cursor) */
 	    int cmod;
-	    
+
 	    cmod = (mask&ControlMask || mask&ShiftMask) ? 1 : 0;
 
 	    if (cmod != cpymode && !dodel) {
 	      curs = (cmod) ? copycurs : movecurs;
-	      	for (i=0; i<MAXBRWIN; i++) 
+	      	for (i=0; i<MAXBRWIN; i++)
 		  XDefineCursor(theDisp,binfo[i].iconW, curs);
 	    }
 	    cpymode = cmod;
-	    
-	    
+
+
 	    /* see if cursor is in any of the trash can areas */
 	    for (i=0; i<MAXBRWIN; i++) {
 	      if (binfo[i].vis) {
-		XTranslateCoordinates(theDisp, rW, binfo[i].win, rootx,rooty, 
+		XTranslateCoordinates(theDisp, rW, binfo[i].win, rootx,rooty,
 				      &bwx,&bwy, &cW);
 		if (inTrash(&binfo[i], bwx, bwy)) break;
 	      }
 	    }
-	    
+
 	    if (dodel && i==MAXBRWIN) {        /* moved out */
 	      dodel = 0;
 	      curs = (cpymode) ? copycurs : movecurs;
-	      for (i=0; i<MAXBRWIN; i++) 
+	      for (i=0; i<MAXBRWIN; i++)
 		XDefineCursor(theDisp,binfo[i].iconW, curs);
 	    }
-	    
+
 	    else if (!dodel && i<MAXBRWIN) {   /* moved in */
 	      dodel = 1;
-	      for (i=0; i<MAXBRWIN; i++) 
+	      for (i=0; i<MAXBRWIN; i++)
 		XDefineCursor(theDisp,binfo[i].iconW, delcurs);
 	    }
 	  }
 
 
 
-	  XTranslateCoordinates(theDisp, rW, br->iconW, rootx,rooty, 
+	  XTranslateCoordinates(theDisp, rW, br->iconW, rootx,rooty,
 				&iwx,&iwy, &cW);
 
 	  /* find deepest child that the mouse is in */
@@ -1837,12 +2037,12 @@
 	  /* if it's in any icon window, and we're doing icon-dragging
 	     OR we're doing a rectangle-drag */
 
-	  if (i<MAXBRWIN || sel == -1) {  
+	  if (i<MAXBRWIN || sel == -1) {
 	    if (i<MAXBRWIN) destBr = &binfo[i];
 	    if (sel == -1)  destBr = br;
 
-	    /* AUTO-SCROLLING:  scroll any icon window if we're doing an 
-	       icon-drag.  Only scroll the original window if we're doing 
+	    /* AUTO-SCROLLING:  scroll any icon window if we're doing an
+	       icon-drag.  Only scroll the original window if we're doing
 	       a rect drag */
 
 	    if (sel>=0 && (oldx!=x || oldy!=y || oldbrnum!=i)) {  /* moved */
@@ -1873,7 +2073,7 @@
 	      }
 	    }
 
-	    
+
 	    /* if we clicked on an icon (originally), and therefore are
 	       showing the 'move files' cursor, see if the cursor is within
 	       the icon region of any folders.  If so, light up *the icon
@@ -1904,9 +2104,9 @@
 
 	    /* Dragging a selection rectangle. */
 
-	    else { 
+	    else {
 	      static int prevx, prevy, prevcnt;
-	      int        origy, top, left, wide, high, cnt;
+	      int        origy, cnt;
 
 	      if (first) { prevx = mx;  prevy = my;  first=0;  prevcnt = -1; }
 
@@ -1922,18 +2122,18 @@
 
 		rx  = (mx    < x) ? mx    : x;
 		ry  = (origy < y) ? origy : y;
-		rw  = abs(mx - x);  
+		rw  = abs(mx - x);
 		rh  = abs(origy - y);
 
 		/* figure out which icons need to be lit/unlit.  Only
 		   redraw those that have changed state */
-		
+
 		for (i=0,cnt=0, bf=br->bfList; i<br->bfLen; i++,bf++) {
-		  int ix, iy, isin, light;
+		  int ix, iy, isin;
 
-		  ix = ((i%br->numWide) * ISPACE_WIDE) 
+		  ix = ((i%br->numWide) * ISPACE_WIDE)
 		                  + ISPACE_WIDE/2 - bf->w/2;
-		  iy = ((i/br->numWide) * ISPACE_HIGH) 
+		  iy = ((i/br->numWide) * ISPACE_HIGH)
 		                  + ISPACE_TOP + ISIZE_HIGH - bf->h;
 
 		  iy = iy - br->scrl.val * ISPACE_HIGH;
@@ -1994,7 +2194,7 @@
 	}
 
 	/* RELEASED BUTTON:  back to normal arrow cursor */
-	for (i=0; i<MAXBRWIN; i++) 
+	for (i=0; i<MAXBRWIN; i++)
 	  XDefineCursor(theDisp, binfo[i].iconW, None);
 
 	if (sel == -1) {  /* was dragging rectangle */
@@ -2007,7 +2207,7 @@
 	    if (bf->lit == TEMP_LIT || bf->lit == TEMP_LIT1) {
 	      bf->lit = 1;  drawIcon(br, i);
 	    }
-	    
+
 	    if (bf->lit) br->numlit++;
 	  }
 
@@ -2020,7 +2220,6 @@
 
   /* if doing a copy or a move, do the thing to the files */
   if (sel >= 0) {
-    char *destFolder;
 
     if (DEBUG) {
       fprintf(stderr,"---------------\n");
@@ -2029,7 +2228,7 @@
       fprintf(stderr,"Dest Folder: '%s'\n", destFolderName);
     }
 
-    
+
     if (!br->numlit) {
       if (DEBUG) fprintf(stderr, "no selected files.  Nothing to do!\n");
     }
@@ -2042,7 +2241,7 @@
       if (DEBUG) fprintf(stderr, "no destination.  Nothing to do!\n");
     }
 
-    else if (strcmp(destFolderName,".")     == 0 && 
+    else if (strcmp(destFolderName,".")     == 0 &&
 	     strcmp(br->path, destBr->path) == 0) {
       if (DEBUG) fprintf(stderr,"source == destination.  Nothing to do!\n");
     }
@@ -2067,20 +2266,20 @@
 	}
       }
       if (DEBUG) fprintf(stderr,"\n\n");
- 
+
 #ifdef VMS
       /*
-       * For VMS, our directory file names are identifed by the 
-       * special filename extension, ".DIR".  Unfortunately, this 
-       * needs to be stripped before we ever actually use the name 
+       * For VMS, our directory file names are identifed by the
+       * special filename extension, ".DIR".  Unfortunately, this
+       * needs to be stripped before we ever actually use the name
        * in a copy command... :(     RLD 26-FEB-1993
        */
 
-      *rindex ( destFolderName, '.' ) = '\0';
+      *rindex ( destFolderName, '.' ) = '\0';  /* FIXME: potentially writing into static strings! */
 #endif
 
 
-      dragFiles(br, destBr, br->path, destBr->path, destFolderName, nlist, 
+      dragFiles(br, destBr, br->path, destBr->path, destFolderName, nlist,
 		ncnt, cpymode);
 
       /* free namelist */
@@ -2099,7 +2298,7 @@
     }
   }      /* end of 'tracking' sub-function */
 
-  return rv;
+  return -1;
 }
 
 /*******************************************/
@@ -2113,6 +2312,8 @@
 
   /* called to 'open' icon #sel, which could be a file or a dir */
 
+  br->lst = 0;
+
   /* if sel == -1, then called via RETURN key.  just use first lit item
      as thing that was double clicked on */
 
@@ -2155,7 +2356,7 @@
   }
 
 
-  
+
   /* double-clicked something.  We should do something about it */
   if (br->bfList[sel].ftype == BF_DIR) {  /* try to cd */
 #ifndef VMS
@@ -2165,15 +2366,36 @@
     else sprintf(buf, "%s%s", br->path, br->bfList[sel].name);
 #endif
 
+#ifdef AUTO_EXPAND
+    if (Chvdir(buf)) {
+#else
     if (chdir(buf)) {
+#endif
       char str[512];
       sprintf(str,"Unable to cd to '%s'\n", br->bfList[sel].name);
       setBrowStr(br, str);
       XBell(theDisp, 50);
     }
     else {
+#ifdef AUTO_EXPAND
+      if (Isvdir(buf)) {
+	BTSetActive(&br->but[BR_DELETE],  0);
+	br->cmdMB.dim[BR_DELETE] = 1;
+
+	BTSetActive(&br->but[BR_RENAME],  0);
+	br->cmdMB.dim[BR_RENAME] = 1;
+
+	BTSetActive(&br->but[BR_MKDIR],  0);
+	br->cmdMB.dim[BR_MKDIR] = 1;
+      }
+      else {
+	BTSetActive(&br->but[BR_MKDIR],  1);
+	br->cmdMB.dim[BR_MKDIR] = 0;
+      }
+#endif
       scanDir(br);
       SCSetVal(&(br->scrl), 0);  /* reset to top on a chdir */
+      restIconVisible(br);
     }
   }
 
@@ -2193,7 +2415,26 @@
       *event_retP = THISNEXT;
     }
     else { *event_retP = LOADPIC;  SetDirFName(buf);  }
-    
+
+#ifdef VS_RESCMAP
+    /* Change Colormap for browser */
+    if (browPerfect && browCmap) {
+      int i;
+      XSetWindowAttributes  xswa;
+      if(LocalCmap) {
+	xswa.colormap = LocalCmap;
+	_IfTempOut=2;
+      }
+      else {
+	xswa.colormap = theCmap;
+	_IfTempOut=2;
+      }
+      for(i=0;i<MAXBRWIN;i++)
+	XChangeWindowAttributes(theDisp, binfo[i].win, CWColormap, &xswa);
+      XFlush(theDisp);
+    }
+#endif
+
     *event_doneP = 1;     /* make MainLoop load image */
   }
 }
@@ -2259,7 +2500,7 @@
   stlen = XLookupString(kevt, buf, 128, &ks, (XComposeStatus *) NULL);
   shift = kevt->state & ShiftMask;
   ck    = CursorKey(ks, shift, 1);
-  dealt = 1;  
+  dealt = 1;
 
   RemapKeyCheck(ks, buf, &stlen);
 
@@ -2289,6 +2530,7 @@
   case '\021': doCmd(br, BR_QUIT);     break;      /* ^Q = Quit xv */
 
   case '\006': doCmd(br, BR_SELFILES); break;      /* ^F = Select Files */
+  case '\030': doCmd(br, BR_CLIPBRD);  break;      /* ^X = Copy to clipboard */
 
 
   /* case '\003': FakeButtonPress(&but[BCMTVIEW]); break; */    /* ^C */
@@ -2299,6 +2541,9 @@
   case '\n':   doubleClick(br, -1);   break;      /* RETURN = load selected */
 
   case ' ':
+    if (br->lst && (time(NULL) <= br->lst + incrementalSearchTimeout))
+      goto do_default;
+    /* else fall through... */
   case '\010':
   case '\177':   /* SPACE = load next, BS/DEL = load prev */
     if (br->bfLen && br->numlit >= 1) {
@@ -2306,7 +2551,7 @@
       char fname[MAXPATHLEN];
 
       /* if 'shift-space' find last lit icon, select the next one after it,
-	 and load it.  If 'space' do the same, but lose prior lit.  These 
+	 and load it.  If 'space' do the same, but lose prior lit.  These
 	 are the only cases where br->numlit >1 allowed */
 
       if (br->numlit>1  && buf[0] != ' ') return;
@@ -2314,7 +2559,7 @@
       if (buf[0]==' ' && (br->numlit>1 || (br->numlit==1 && shift))) {
 	for (i=br->bfLen-1; i>=0 && !br->bfList[i].lit; i--);  /* i=last lit */
 	if (i==br->bfLen-1) return;
-	
+
 	i++;
 	if (!shift) {
 	  for (j=0; j<br->bfLen; j++) {
@@ -2348,6 +2593,9 @@
 
 	  /* try to open this file */
 	  sprintf(foo, "%s%s", br->path, br->bfList[i].name);
+#ifdef AUTO_EXPAND
+	Dirtovd(foo);
+#endif
 	  for (j=0; j<numnames && strcmp(namelist[j],foo); j++);
 	  if (j<numnames) {
 	    curname = nList.selected = j;
@@ -2363,8 +2611,11 @@
       else {          /* not SPACE, or SPACE and lit=1 and not shift */
 	for (i=0; i<br->bfLen && !br->bfList[i].lit; i++);  /* find lit one */
 	sprintf(fname, "%s%s", br->path, br->bfList[i].name);
+#ifdef AUTO_EXPAND
+	Dirtovd(fname);
+#endif
 	viewsel = !(strcmp(fname, fullfname));
-	
+
 	if (viewsel) {
 	  if (buf[0]==' ') browKey(br, CK_RIGHT);
 	              else browKey(br, CK_LEFT);
@@ -2372,7 +2623,7 @@
 
 	if (!br->bfList[i].lit || !viewsel) {   /* changed selection */
 	  for (i=0; i<br->bfLen && !br->bfList[i].lit; i++);  /* find it */
-	  if (br->bfList[i].ftype != BF_DIR) 
+	  if (br->bfList[i].ftype != BF_DIR)
 	    doubleClick(br, -1);
 	}
       }
@@ -2381,7 +2632,8 @@
 
 
   default:  /* unknown character.  Take it as an alpha accelerator */
-    if (buf[0] > 32) browAlpha(br, buf[0]);
+  do_default:  /* (goto-label, not switch-label) */
+    if (buf[0] >= 32) browAlpha(br, buf[0]);
                 else XBell(theDisp, 0);
     break;
   }
@@ -2401,6 +2653,8 @@
   /* an arrow key (or something like that) was pressed in icon window.
      change selection/scrollbar accordingly */
 
+  br->lst = 0;
+
   /* handle easy keys */
   if (key == CK_PAGEUP)   SCSetVal(&br->scrl, br->scrl.val - br->scrl.page);
   if (key == CK_PAGEDOWN) SCSetVal(&br->scrl, br->scrl.val + br->scrl.page);
@@ -2410,10 +2664,10 @@
   /* handle up/down/left/right keys
    *
    * if precisely *one* item is lit, than the up/down/left/right keys move
-   * the selection.  
+   * the selection.
    *
    * if NO items are lit, then left/right select the first/last fully-displayed
-   * icon, and up/down simply scroll window up or down, without selecting 
+   * icon, and up/down simply scroll window up or down, without selecting
    * anything
    *
    * if more than one item is lit, up/down/left/right keys BEEP
@@ -2443,8 +2697,8 @@
 	if (key == CK_DOWN)  j = i + br->numWide;
 	if (key == CK_LEFT)  j = i - 1;
 	if (key == CK_RIGHT) j = i + 1;
-	
-	if (j >= 0 && j < br->bfLen) {  
+
+	if (j >= 0 && j < br->bfLen) {
 	  br->bfList[i].lit = 0;
 	  br->bfList[j].lit = 1;
 	  makeIconVisible(br,j);
@@ -2455,7 +2709,7 @@
       }
     }
 
-  
+
     if (br->numlit == 0) {   /* no current selection */
       if (key == CK_UP)   SCSetVal(&br->scrl, br->scrl.val - 1);
       if (key == CK_DOWN) SCSetVal(&br->scrl, br->scrl.val + 1);
@@ -2482,15 +2736,28 @@
   /* find first 'plain' file that is lexically >= than the given ch */
 
   int i,j;
+  time_t now = time(NULL);
 
   if (!br->bfLen) return;
-  if (ch <= ' ' || ch > '\177')  return;    /* ignore 'funny' keys */
+  if (ch < ' ' || ch > '\177')  return;    /* ignore 'funny' keys */
 
   for (i=0; i<br->bfLen && br->bfList[i].ftype==BF_DIR; i++);
   if (i==br->bfLen) return;    /* only directories in this dir */
 
+  if (!br->lst || (br->lst + incrementalSearchTimeout < now)) br->len = 0;
+  br->lst = now;
+  
+  if (br->len + 2 > br->siz)
+    if ((br->str = (char *)realloc(br->str, (br->siz = br->len + 32))) == NULL)
+       br->siz = br->len = 0;
+  
+  if (br->len + 2 <= br->siz) {
+    br->str[br->len++] = ch;
+    br->str[br->len] = '\0';
+  }
+
   for ( ; i<br->bfLen; i++) {
-    if (br->bfList[i].name[0] >= ch) break;
+    if (strncmp(br->bfList[i].name, br->str, br->len) >= 0) break;
   }
 
   if (i==br->bfLen) i--;
@@ -2541,20 +2808,24 @@
        *  The VMS chdir always needs 2 components (device and directory),
        *  so convert "/device" to "/device/000000" and convert
        *  "/" to "/XV_Root_Device/000000" (XV_RootDevice will need to be
-       *  a special concealed device setup to provide list of available 
+       *  a special concealed device setup to provide list of available
        *  disks).
        *
        *  End 'tmppath' by changing trailing '/' (of dir name) to a '\0'
        */
       *rindex ( tmppath, '/') = '\0';
-      if ( ((br->ndirs-sel) == 2) && (strlen(tmppath) > 1) ) 
+      if ( ((br->ndirs-sel) == 2) && (strlen(tmppath) > 1) )
 	strcat ( tmppath, "/000000" ); /* add root dir for device */
       else if  ((br->ndirs-sel) == 1 )
 	strcpy ( tmppath, "/XV_Root_Device/000000" );  /* fake top level */
     }
 #endif
 
+#ifdef AUTO_EXPAND
+    if (Chvdir(tmppath)) {
+#else
     if (chdir(tmppath)) {
+#endif
       char str[512];
       sprintf(str,"Unable to cd to '%s'\n", tmppath);
       MBRedraw(&(br->dirMB));
@@ -2562,8 +2833,25 @@
       XBell(theDisp, 50);
     }
     else {
+#ifdef AUTO_EXPAND
+      if (Isvdir(tmppath)) {
+	BTSetActive(&br->but[BR_DELETE],  0);
+	br->cmdMB.dim[BR_DELETE] = 1;
+
+	BTSetActive(&br->but[BR_RENAME],  0);
+	br->cmdMB.dim[BR_RENAME] = 1;
+
+	BTSetActive(&br->but[BR_MKDIR],  0);
+	br->cmdMB.dim[BR_MKDIR] = 1;
+      }
+      else {
+	BTSetActive(&br->but[BR_MKDIR],  1);
+	br->cmdMB.dim[BR_MKDIR] = 0;
+      }
+#endif
       scanDir(br);
       SCSetVal(&br->scrl, 0);  /* reset to top of window on a chdir */
+      restIconVisible(br);
     }
   }
 }
@@ -2582,7 +2870,11 @@
   if ((strlen(br->path) > (size_t) 2) && br->path[strlen(br->path)-1] == '/')
     br->path[strlen(br->path)-1] = '\0';
 
+#ifdef AUTO_EXPAND
+  rv = Chvdir(br->path);
+#else
   rv = chdir(br->path);
+#endif
   if (rv) {
     char str[512];
     sprintf(str, "Unable to cd to '%s'\n", br->path);
@@ -2590,6 +2882,24 @@
     XBell(theDisp, 50);
   }
 
+#ifdef AUTO_EXPAND
+  if (Isvdir(br->path)) {
+    BTSetActive(&br->but[BR_DELETE],  0);
+    br->cmdMB.dim[BR_DELETE] = 1;
+
+    BTSetActive(&br->but[BR_RENAME],  0);
+    br->cmdMB.dim[BR_RENAME] = 1;
+
+    BTSetActive(&br->but[BR_MKDIR],  0);
+    br->cmdMB.dim[BR_MKDIR] = 1;
+  }
+  else {
+    BTSetActive(&br->but[BR_MKDIR],  1);
+    br->cmdMB.dim[BR_MKDIR] = 0;
+  }
+#endif
+
+  restIconVisible(br);
   strcat(br->path, "/");   /* put trailing '/' back on */
   return rv;
 }
@@ -2599,7 +2909,7 @@
 static void copyDirInfo(srcbr, dstbr)
      BROWINFO *srcbr, *dstbr;
 {
-  /* copies br info from an already existing browser window 
+  /* copies br info from an already existing browser window
      (ie, one that is already showing the same directory) */
 
   int i, oldnum, maxv, page;
@@ -2611,15 +2921,19 @@
   /* copy mblist */
   dstbr->ndirs = srcbr->ndirs;
   for (i=0;  i<dstbr->ndirs;  i++) {
-    dstbr->mblist[i] = (char *) malloc(strlen(srcbr->mblist[i]) + 1);
+    dstbr->mblist[i] = strdup(srcbr->mblist[i]);
     if (!dstbr->mblist[i]) FatalError("unable to malloc brMBlist[]");
-    strcpy(dstbr->mblist[i], srcbr->mblist[i]);
   }
 
-  dstbr->dirMB.list  = srcbr->mblist;
+#if 0
+  dstbr->dirMB.list  = srcbr->mblist;  /* original bug..? */
   dstbr->dirMB.nlist = srcbr->ndirs;
+#else
+  dstbr->dirMB.list  = dstbr->mblist;  /* fixed by        */
+  dstbr->dirMB.nlist = dstbr->ndirs;   /*   jp-extension. */
+#endif
 
-  XClearArea(theDisp, dstbr->dirMB.win, dstbr->dirMB.x, dstbr->dirMB.y, 
+  XClearArea(theDisp, dstbr->dirMB.win, dstbr->dirMB.x, dstbr->dirMB.y,
 	     dstbr->dirMB.w+3, dstbr->dirMB.h+3, False);
 
   i = StringWidth(dstbr->mblist[0]) + 10;
@@ -2644,7 +2958,7 @@
 
     if ((i&0x03) == 0) drawTemp(dstbr, i, dstbr->bfLen);
     if ((i & 0x3f) == 0) WaitCursor();
-    
+
     sbf = &(srcbr->bfList[i]);
     dbf = &(dstbr->bfList[i]);
 
@@ -2670,7 +2984,7 @@
     if (sbf->pimage) {
       dbf->pimage = (byte *) malloc((size_t) dbf->w * dbf->h);
       if (!dbf->pimage) FatalError("ran out of memory for dbf->pimage");
-      xvbcopy((char *) sbf->pimage, (char *) dbf->pimage, 
+      xvbcopy((char *) sbf->pimage, (char *) dbf->pimage,
 	      (size_t) (dbf->w * dbf->h));
     }
     else dbf->pimage = (byte *) NULL;
@@ -2681,10 +2995,10 @@
       xvbcopy((char *) sbf->ximage, (char *) dbf->ximage, sizeof(XImage));
 
       if (sbf->ximage->data) {
-	dbf->ximage->data = (char *) malloc((size_t) dbf->ximage->height * 
+	dbf->ximage->data = (char *) malloc((size_t) dbf->ximage->height *
 					    dbf->ximage->bytes_per_line);
 	if (!dbf->ximage->data) FatalError("ran out of memory for ximg data");
-	xvbcopy((char *) sbf->ximage->data, (char *) dbf->ximage->data, 
+	xvbcopy((char *) sbf->ximage->data, (char *) dbf->ximage->data,
 		(size_t) dbf->ximage->height * dbf->ximage->bytes_per_line);
       }
     }
@@ -2701,15 +3015,15 @@
   computeScrlVals(dstbr, &maxv, &page);
   if (dstbr->scrl.val > maxv) dstbr->scrl.val = maxv;
 
-  XClearArea(theDisp, dstbr->iconW, 0, 0, (u_int) dstbr->iwWide, 
+  XClearArea(theDisp, dstbr->iconW, 0, 0, (u_int) dstbr->iwWide,
 	     (u_int) dstbr->iwHigh, True);
   SCSetRange(&dstbr->scrl, 0, maxv, dstbr->scrl.val, page);
 
   SetCursors(-1);
 }
 
-    
-  
+
+
 
 /***************************************************************/
 static void scanDir(br)
@@ -2726,7 +3040,7 @@
    * and it's reasonable to expect folks to want to add their own bitmaps
    */
 
-  int   i,j,k,oldbflen,vmsparent;
+  int   i,j,oldbflen,vmsparent;
   BFIL *bf;
 
   DIR           *dirp;
@@ -2753,7 +3067,7 @@
   xv_getwd(path, sizeof(path));
   if (path[strlen(path)-1] != '/') strcat(path,"/");   /* add trailing '/' */
 
-  for (i=0; i<br->ndirs; i++) free(br->mblist[i]);  /* clear old dir names */
+  for (i=0; i<br->ndirs; i++) free((char *) br->mblist[i]);  /* clear old dir names */
 
   /* path will be something like: "/u3/bradley/src/weiner/whatever/" */
 
@@ -2775,22 +3089,24 @@
 
   /* build brMBlist */
   for (i = br->ndirs-1,j=0; i>=0; i--,j++) {
-    size_t stlen = (i<(br->ndirs-1)) ? dirnames[i+1] - dirnames[i] 
+    size_t  stlen = (i<(br->ndirs-1)) ? dirnames[i+1] - dirnames[i]
                                   : strlen(dirnames[i]);
+    char   *copy;
 
-    br->mblist[j] = (char *) malloc(stlen+1);
-    if (!br->mblist[j]) FatalError("unable to malloc brMBlist[]");
+    copy = malloc(stlen+1);
+    if (!copy) FatalError("unable to malloc brMBlist[]");
 
-    strncpy(br->mblist[j], dirnames[i], stlen);
-    br->mblist[j][stlen] = '\0';
+    strncpy(copy, dirnames[i], stlen);
+    copy[stlen] = '\0';
+    br->mblist[j] = copy;
   }
-    
+
 
   /* refresh the brdirMB button */
   br->dirMB.list  = br->mblist;
   br->dirMB.nlist = br->ndirs;
 
-  XClearArea(theDisp, br->dirMB.win, br->dirMB.x, br->dirMB.y, 
+  XClearArea(theDisp, br->dirMB.win, br->dirMB.x, br->dirMB.y,
 	     br->dirMB.w+3, br->dirMB.h+3, False);
 
   i = StringWidth(br->mblist[0]) + 10;
@@ -2815,7 +3131,7 @@
   /* count how many files are in the list */
 
   dirp = opendir(".");
-  if (!dirp) {  
+  if (!dirp) {
     endScan(br, oldbflen);
     setBrowStr(br, "Couldn't read current directory.");
     SetCursors(-1);
@@ -2827,11 +3143,11 @@
 #endif
 
   while ( (dp = readdir(dirp)) != NULL) {
-    if (strcmp(dp->d_name, ".") && 
+    if (strcmp(dp->d_name, ".") &&
 	strcmp(dp->d_name, THUMBDIR)) {
-      if (!br->showhidden && dp->d_name[0] == '.' && 
+      if (!br->showhidden && dp->d_name[0] == '.' &&
 	  strcmp(dp->d_name,"..")!=0) continue;
-      else 
+      else
 	br->bfLen++;
     }
     if ((br->bfLen & 0x3f) == 0) WaitCursor();
@@ -2877,13 +3193,13 @@
       }
       else {
 	do { dp = readdir(dirp); }
-	while (dp && (strcmp(dp->d_name, ".")==0                    || 
+	while (dp && (strcmp(dp->d_name, ".")==0                    ||
 		      strcmp(dp->d_name, THUMBDIR)==0               ||
 		      strcmp(dp->d_name, THUMBDIRNAME)==0           ||
 		      (br->ndirs==1 && strcmp(dp->d_name,"..")==0)  ||
-		      (!br->showhidden && dp->d_name[0] == '.' && 
+		      (!br->showhidden && dp->d_name[0] == '.' &&
 		       strcmp(dp->d_name,"..")!=0)));
-      
+
 	if (!dp) { br->bfLen = i;  break; }   /* dir got shorter... */
       }
 
@@ -2940,11 +3256,11 @@
   if (w<1) w = 1;
   if (h<1) h = 1;
 
-  XClearArea(theDisp, br->iconW, (ctrlColor) ? 2 : 0, (ctrlColor) ? 2 : 0, 
+  XClearArea(theDisp, br->iconW, (ctrlColor) ? 2 : 0, (ctrlColor) ? 2 : 0,
 	     (u_int) w, (u_int) h, False);
 
   SCSetRange(&br->scrl, 0, maxv, br->scrl.val, page);
-  
+
   SetCursors(-1);
 }
 
@@ -2972,10 +3288,14 @@
   bf->pimage = (byte *) NULL;
   bf->ximage = (XImage *) NULL;
   bf->lit    = 0;
-	
+
 
   if (stat(bf->name, &st)==0) {
+#ifdef AUTO_EXPAND
+    bf->ftype = stat2bf((u_int) st.st_mode , bf->name);
+#else
     bf->ftype = stat2bf((u_int) st.st_mode);
+#endif
     if (bf->ftype == BF_FILE && (st.st_mode & 0111)) bf->ftype = BF_EXE;
 
     switch (bf->ftype) {
@@ -3007,6 +3327,7 @@
     case RFT_XBM:      bf->ftype = BF_XBM;      break;
     case RFT_SUNRAS:   bf->ftype = BF_SUNRAS;   break;
     case RFT_BMP:      bf->ftype = BF_BMP;      break;
+    case RFT_WBMP:     bf->ftype = BF_BMP;      break;
     case RFT_UTAHRLE:  bf->ftype = BF_UTAHRLE;  break;
     case RFT_IRIS:     bf->ftype = BF_IRIS;     break;
     case RFT_PCX:      bf->ftype = BF_PCX;      break;
@@ -3014,12 +3335,22 @@
     case RFT_TIFF:     bf->ftype = BF_TIFF;     break;
     case RFT_PDSVICAR: bf->ftype = BF_PDS;      break;
     case RFT_COMPRESS: bf->ftype = BF_COMPRESS; break;
+    case RFT_BZIP2:    bf->ftype = BF_BZIP2;    break;
     case RFT_PS:       bf->ftype = BF_PS;       break;
     case RFT_IFF:      bf->ftype = BF_IFF;      break;
-    case RFT_TARGA:    bf->ftype = BF_TARGA;    break;
+    case RFT_TARGA:    bf->ftype = BF_TGA;      break;
     case RFT_XPM:      bf->ftype = BF_XPM;      break;
     case RFT_XWD:      bf->ftype = BF_XWD;      break;
     case RFT_FITS:     bf->ftype = BF_FITS;     break;
+    case RFT_PNG:      bf->ftype = BF_PNG;      break;
+    case RFT_ZX:       bf->ftype = BF_ZX;       break;	/* [JCE] */
+    case RFT_PCD:      bf->ftype = BF_PCD;      break;
+    case RFT_MAG:      bf->ftype = BF_MAG;      break;
+    case RFT_MAKI:     bf->ftype = BF_MAKI;     break;
+    case RFT_PIC:      bf->ftype = BF_PIC;      break;
+    case RFT_PI:       bf->ftype = BF_PI;       break;
+    case RFT_PIC2:     bf->ftype = BF_PIC2;     break;
+    case RFT_MGCSFX:   bf->ftype = BF_MGCSFX;   break;
     }
   }
 }
@@ -3048,11 +3379,11 @@
   bfcompares++;
   if ((bfcompares & 0x7f)==0) WaitCursor();
 
-  /* sort critera:  directories first, in alphabetical order, 
+  /* sort critera:  directories first, in alphabetical order,
      followed by everything else, in alphabetical order */
-  
+
   if ((b1->ftype == BF_DIR && b2->ftype == BF_DIR) ||
-      (b1->ftype != BF_DIR && b2->ftype != BF_DIR)) 
+      (b1->ftype != BF_DIR && b2->ftype != BF_DIR))
     return strcmp(b1->name, b2->name);
 
   else if (b1->ftype == BF_DIR && b2->ftype != BF_DIR) return -1;
@@ -3108,7 +3439,7 @@
     for (i=0; i<bflen; i++) {
       bfnames[i] = (char *) malloc(strlen(br->bfList[i].name) + 1);
       if (!bfnames[i]) FatalError("couldn't alloc bfnames in rescanDir()");
-      
+
       strcpy(bfnames[i], br->bfList[i].name);
     }
   }
@@ -3121,7 +3452,7 @@
 
   /* note, either (or both) dirnames/bfnames can be NULL, in which case
      their respective 'len's will be zero */
-  
+
   /* sort the two name lists */
   if (bflen)  qsort((char *) bfnames,  (size_t) bflen, sizeof(char *),namcmp);
   if (dirlen) qsort((char *) dirnames, (size_t) dirlen,sizeof(char *),namcmp);
@@ -3153,7 +3484,7 @@
     }
   }
   bflen = j;
-  
+
 
   for (i=j=0; i<dirlen; i++) {
     if (dirnames[i] && strcmp(dirnames[i],".") && strcmp(dirnames[i],"..") &&
@@ -3162,21 +3493,21 @@
     }
   }
   dirlen = j;
-  
+
 
   if (DEBUG) {
     fprintf(stderr,"%d files seem to have gone away:  ", bflen);
-    for (i=0; i<bflen; i++) 
+    for (i=0; i<bflen; i++)
       fprintf(stderr,"%s ", bfnames[i]);
     fprintf(stderr,"\n\n");
 
     fprintf(stderr,"%d files seem to have appeared:  ", dirlen);
-    for (i=0; i<dirlen; i++) 
+    for (i=0; i<dirlen; i++)
       fprintf(stderr,"%s ", dirnames[i]);
     fprintf(stderr,"\n\n");
   }
-   
-  
+
+
   /* create a new bfList */
   newlen = br->bfLen - bflen + dirlen;  /* oldlen - #del'd + #created */
   if (newlen>0) {
@@ -3241,7 +3572,7 @@
       if (bf->pimage)  free(bf->pimage);
       if (bf->ximage)  xvDestroyImage(bf->ximage);
     }
-    
+
     free(br->bfList);
   }
 
@@ -3263,17 +3594,17 @@
 
 /***************************************************************/
 static char **getDirEntries(dir, lenP, dohidden)
-     char *dir;
+     const char *dir;
      int  *lenP;
      int   dohidden;
 {
-  /* loads up all directory entries into an array.  This *isn't* a great 
-     way to do it, but I can't count on 'scandir()' existing on 
+  /* loads up all directory entries into an array.  This *isn't* a great
+     way to do it, but I can't count on 'scandir()' existing on
      every system.  Returns 'NULL' on failure, or pointer to array of
      'lenP' strings on success.  '.' and '..' ARE included in list
      if !dohidden, all '.*' files are skipped (except . and ..) */
 
-  int    i, j, dirlen;
+  int    i, dirlen;
   DIR   *dirp;
   char **names;
 #ifdef NODIRENT
@@ -3294,9 +3625,9 @@
   /* count # of entries in dir (worst case) */
   for (dirlen=0;  (dp = readdir(dirp)) != NULL;  dirlen++);
   if (!dirlen) {
-    closedir(dirp);  
+    closedir(dirp);
     *lenP = dirlen;
-    return (char **) NULL; 
+    return (char **) NULL;
   }
 
 
@@ -3312,7 +3643,7 @@
 
     if (!dohidden) {
 #ifndef VMS
-      if (dp->d_name[0] == '.' && 
+      if (dp->d_name[0] == '.' &&
 	  strcmp(dp->d_name,"." )!=0 &&
 	  strcmp(dp->d_name,"..")!=0) continue;
 #endif
@@ -3324,7 +3655,7 @@
     strcpy(names[i], dp->d_name);
     i++;
   }
-  
+
   if (i<dirlen) dirlen = i;     /* dir got shorter... */
 
   closedir(dirp);
@@ -3359,7 +3690,7 @@
 static void genSelectedIcons(br)
      BROWINFO *br;
 {
-  int i, sval, first, numvis, cnt;
+  int i, cnt;
 
   setBrowStr(br, "");
 
@@ -3395,7 +3726,7 @@
      BFIL *bf;
 {
   /* given a BFIL entry, load up the file.
-   * if we succeeded in loading up the file, 
+   * if we succeeded in loading up the file,
    *      generate an aspect-correct 8-bit image using brow Cmap
    * otherwise
    *      replace this icon with the BF_UNKNOWN, or BF_ERR icons
@@ -3406,22 +3737,22 @@
   double  wexpand,hexpand;
   int     iwide, ihigh;
   byte   *icon24, *icon8;
-  char    str[256], str1[256], *readname, uncompname[128];
+  char    str[256], str1[256], readname[128], uncompname[128];
   char    basefname[128], *uncName;
-  
-  
+
+
   if (!bf || !bf->name || bf->name[0] == '\0') return;   /* shouldn't happen */
   str[0] = '\0';
   basefname[0] = '\0';
   pinfo.pic = (byte *) NULL;
   pinfo.comment = (char *) NULL;
-  readname = bf->name;
-  
+  strncpy(readname, bf->name, sizeof(readname) - 1);
+
   /* free any old info in 'bf' */
   if (bf->imginfo) free          (bf->imginfo);
   if (bf->pimage)  free          (bf->pimage);
   if (bf->ximage)  xvDestroyImage(bf->ximage);
-  
+
   bf->imginfo = (char *)   NULL;
   bf->pimage  = (byte *)   NULL;
   bf->ximage  = (XImage *) NULL;
@@ -3429,10 +3760,10 @@
 
   /* skip all 'special' files */
   if (!ISLOADABLE(bf->ftype)) return;
-  
+
   filetype = ReadFileType(bf->name);
-  
-  if (filetype == RFT_COMPRESS) {
+
+  if ((filetype == RFT_COMPRESS) || (filetype == RFT_BZIP2)) {
 #if (defined(VMS) && !defined(GUNZIP))
     /* VMS decompress doesn't like the file to have a trailing .Z in fname
        however, GUnZip is OK with it, which we are calling UnCompress */
@@ -3442,10 +3773,10 @@
 #else
     uncName = bf->name;
 #endif
-    
-    if (UncompressFile(uncName, uncompname)) {
+
+    if (UncompressFile(uncName, uncompname, filetype)) {
       filetype = ReadFileType(uncompname);
-      readname = uncompname;
+      strncpy(readname, uncompname, sizeof(readname) - 1);
     }
     else {
       sprintf(str, "Couldn't uncompress file '%s'", bf->name);
@@ -3453,71 +3784,139 @@
       bf->ftype = BF_ERROR;
     }
   }
-  
+
+#ifdef MACBINARY
+  if (handlemacb && macb_file == True && bf->ftype != BF_ERROR) {
+    if (RemoveMacbinary(readname, uncompname)) {
+      if (strcmp(readname, bf->name)!=0) unlink(readname);
+      strncpy(readname, uncompname, sizeof(readname) - 1);
+    }
+    else {
+      sprintf(str, "Unable to remove a InfoFile header form '%s'.", bf->name);
+      setBrowStr(br, str);
+      bf->ftype = BF_ERROR;
+    }
+  }
+#endif
+
+#ifdef HAVE_MGCSFX_AUTO
+  if (bf->ftype != BF_ERROR) {
+    if(filetype == RFT_MGCSFX){
+      char tmpname[128];
+      char *icom;
+
+      if((icom = mgcsfx_auto_input_com(bf->name)) != NULL){
+	sprintf(tmpname, "%s/xvmsautoXXXXXX", tmpdir);
+#ifdef USE_MKSTEMP
+	close(mkstemp(tmpname));
+#else
+	mktemp(tmpname);
+#endif
+	SetISTR(ISTR_INFO, "Converting to known format by MgcSfx auto...");
+	sprintf(str,"%s >%s", icom, tmpname);
+      }else goto ms_auto_no;
+
+#ifndef VMS
+      if (system(str))
+#else
+      if (!system(str))
+#endif
+      {
+        sprintf(str, "Unable to convert '%s' by MgcSfx auto.", bf->name);
+        setBrowStr(br, str);
+        bf->ftype = BF_ERROR;
+      }
+      else {
+        filetype = ReadFileType(tmpname);
+        if (strcmp(readname, bf->name)!=0) unlink(readname);
+        strncpy(readname, tmpname, sizeof(readname) - 1);
+      }
+    }
+  }
+ms_auto_no:
+#endif /* HAVE_MGCSFX_AUTO */
+
   /* get rid of comments.  don't need 'em */
   if (pinfo.comment) free(pinfo.comment);  pinfo.comment = (char *) NULL;
-  
-  if (filetype == RFT_ERROR) { 
+
+  if (filetype == RFT_ERROR) {
     sprintf(str,"Couldn't open file '%s'", bf->name);
     setBrowStr(br, str);
     bf->ftype = BF_ERROR;
   }
-  
+
   else if (filetype == RFT_UNKNOWN) {
     /* if it *was* an 'exe', leave it that way */
     if (bf->ftype != BF_EXE) bf->ftype = BF_UNKNOWN;
   }
-  
+
   else {
     /* otherwise it's a known filetype... do the *hard* part now... */
-    
+
+#ifdef VS_ADJUST
+    normaspect = defaspect;
+#endif
     i = ReadPicFile(readname, filetype, &pinfo, 1);
     KillPageFiles(pinfo.pagebname, pinfo.numpages);
-    
+
     if (!i) bf->ftype = BF_ERROR;
-    
+
     if (i && (pinfo.w<=0 || pinfo.h<=0)) {        /* bogus size */
       bf->ftype = BF_ERROR;
       free(pinfo.pic);  pinfo.pic = (byte *) NULL;
     }
-    
+
     if (bf->ftype==BF_ERROR && filetype==RFT_XBM) bf->ftype = BF_UNKNOWN;
   }
-  
+
   /* get rid of comment, as we don't need it */
-  if (pinfo.comment) { 
+  if (pinfo.comment) {
     free(pinfo.comment);  pinfo.comment = (char *) NULL;
   }
-  
+
   /* if we made an uncompressed file, we can rm it now */
-  if (readname != bf->name) unlink(readname);
-  
-  
+  if (strcmp(readname, bf->name)!=0) unlink(readname);
+
+
   /* at this point either BF_ERROR, BF_UNKNOWN, BF_EXE or pic */
-  
+
   if (!pinfo.pic) {
     if (bf->ftype == BF_EXE) return;  /* don't write thumbfiles for exe's */
-    
+
     bf->w = br_file_width;  bf->h = br_file_height;
     writeThumbFile(br, bf, NULL, 0, 0, NULL);   /* BF_ERROR, BF_UNKNOWN */
     return;
   }
-  
+
   /* at this point, we have a pic, so it must be an image file */
-  
-  
+
+
   /* compute size of icon  (iwide,ihigh) */
-  
+
+#ifdef VS_ADJUST
+  if (!vsadjust) normaspect = 1;
+
+  wexpand = (double) (pinfo.w * normaspect) / (double) ISIZE_WIDE;
+#else
   wexpand = (double) pinfo.w / (double) ISIZE_WIDE;
+#endif /* VS_ADJUST */
   hexpand = (double) pinfo.h / (double) ISIZE_HIGH;
 
   if (wexpand >= 1.0 || hexpand >= 1.0) {   /* don't expand small icons */
     if (wexpand>hexpand) {
+#ifdef VS_ADJUST
+      iwide = (int) ((pinfo.w * normaspect) / wexpand + 0.5);
+#else
       iwide = (int) (pinfo.w / wexpand + 0.5);
+#endif
       ihigh = (int) (pinfo.h / wexpand + 0.5);
     }
     else {
+#ifdef VS_ADJUST
+      iwide = (int) ((pinfo.w * normaspect) / hexpand + 0.5);
+#else
       iwide = (int) (pinfo.w / hexpand + 0.5);
+#endif
       ihigh = (int) (pinfo.h / hexpand + 0.5);
     }
   }
@@ -3527,13 +3926,13 @@
 
 
   /* generate icon */
-  icon24 = Smooth24(pinfo.pic, pinfo.type==PIC24, pinfo.w, pinfo.h, 
+  icon24 = Smooth24(pinfo.pic, pinfo.type==PIC24, pinfo.w, pinfo.h,
 		    iwide, ihigh, pinfo.r,pinfo.g,pinfo.b);
   if (!icon24) { bf->ftype = BF_FILE;  free(pinfo.pic); return; }
 
   sprintf(str, "%dx%d ", pinfo.normw, pinfo.normh);
   switch (filetype) {
-  case RFT_GIF:      if (xv_strstr(pinfo.shrtInfo, "GIF89")) 
+  case RFT_GIF:      if (xv_strstr(pinfo.shrtInfo, "GIF89"))
                        strcat(str,"GIF89 file");
                      else
 		       strcat(str,"GIF87 file");
@@ -3543,12 +3942,12 @@
 
   case RFT_PBM:      if (xv_strstr(pinfo.fullInfo, "raw")) strcat(str,"Raw ");
                      else strcat(str,"Ascii ");
-    
+
                      for (i=0; i<3 && (strlen(pinfo.fullInfo)>(size_t)3); i++){
 		       str1[0] = pinfo.fullInfo[i];  str1[1] = '\0';
 		       strcat(str, str1);
 		     }
-         
+
                      strcat(str," file");
                      break;
 
@@ -3567,21 +3966,30 @@
   case RFT_XPM:      strcat(str,"XPM file");              break;
   case RFT_XWD:      strcat(str,"XWD file");              break;
   case RFT_FITS:     strcat(str,"FITS file");             break;
+  case RFT_PNG:      strcat(str,"PNG file");              break;
+  case RFT_ZX:       strcat(str,"Spectrum SCREEN$");      break; /* [JCE] */
+  case RFT_PCD:      strcat(str,"PhotoCD file");          break;
+  case RFT_MAG:      strcat(str,"MAG file");              break;
+  case RFT_MAKI:     strcat(str,"MAKI file");             break;
+  case RFT_PIC:      strcat(str,"PIC file");              break;
+  case RFT_PI:       strcat(str,"PI file");               break;
+  case RFT_PIC2:     strcat(str,"PIC2 file");             break;
+  case RFT_MGCSFX:   strcat(str,"Magic Suffix file");     break;
   default:           strcat(str,"file of unknown type");  break;
   }
-  
-  
+
+
   /* find out length of original file */
   {  FILE *fp;
      long  filesize;
      char  buf[64];
-     
+
      fp = fopen(bf->name, "r");
      if (fp) {
        fseek(fp, 0L, 2);
        filesize = ftell(fp);
        fclose(fp);
-       
+
        sprintf(buf,"  (%ld bytes)", filesize);
        strcat(str, buf);
      }
@@ -3609,17 +4017,17 @@
   bf->w       = iwide;
   bf->h       = ihigh;
   bf->ftype   = BF_HAVEIMG;
-  
+
   bf->ximage = Pic8ToXImage(icon8, (u_int) iwide, (u_int) ihigh, browcols,
 			    browR, browG, browB);
-  
+
   free(icon24);
   free(pinfo.pic);
 }
 
 
 
-    
+
 
 
 /*
@@ -3670,6 +4078,10 @@
 
   sprintf(thFname, "%s%s/%s", br->path, THUMBDIR, bf->name);
 
+#ifdef AUTO_EXPAND
+  Dirtovd(thFname);
+#endif
+
   fp = fopen(thFname, "r");
   if (!fp) return;            /* nope, it doesn't have one */
 
@@ -3682,7 +4094,7 @@
   /* read comments until we see '#END_OF_COMMENTS', or hit EOF */
   while (1) {
     if (!fgets(buf, 256, fp)) goto errexit;
-    
+
     if      (!strncmp(buf, "#END_OF_COMMENTS", strlen("#END_OF_COMMENTS")))
       break;
 
@@ -3714,7 +4126,7 @@
 
 
   /* read width, height, maxval */
-  if (!fgets(buf, 256, fp) || sscanf(buf, "%d %d %d", &w, &h, &mv) != 3) 
+  if (!fgets(buf, 256, fp) || sscanf(buf, "%d %d %d", &w, &h, &mv) != 3)
     goto errexit;
 
 
@@ -3738,14 +4150,14 @@
     bf->h       = h;
     bf->ftype   = BF_HAVEIMG;
     bf->imginfo = info;
-    
-    bf->ximage = Pic8ToXImage(icon8, (u_int) w, (u_int) h, browcols, 
+
+    bf->ximage = Pic8ToXImage(icon8, (u_int) w, (u_int) h, browcols,
 			      browR, browG, browB);
   }
   else {
     if (info) free(info);
   }
-  
+
   fclose(fp);
   return;
 
@@ -3757,7 +4169,7 @@
 }
 
 
-  
+
 /***************************************************************/
 static void writeThumbFile(br, bf, icon8, w, h, info)
      BROWINFO *br;
@@ -3785,9 +4197,14 @@
 
   sprintf(thFname, "%s%s/%s", br->path, THUMBDIR, bf->name);
 
+#ifdef AUTO_EXPAND
+  Dirtovd(thFname);
+#endif
+
+  unlink(thFname);  /* just in case there's already an unwritable one */
   fp = fopen(thFname, "w");
   if (!fp) {
-    sprintf(buf, "Can't create thumbnail file '%s':  %s", thFname, 
+    sprintf(buf, "Can't create thumbnail file '%s':  %s", thFname,
 	    ERRSTR(errno));
     setBrowStr(br, buf);
     return;            /* can't write... */
@@ -3829,9 +4246,9 @@
     setBrowStr(br, buf);
     return;            /* can't write... */
   }
-  
+
   fclose(fp);
-  
+
   chmod(thFname, (mode_t) perm);
 }
 
@@ -3849,15 +4266,29 @@
 
   sprintf(thFname, "%s%s", br->path, THUMBDIRNAME);
 
+#ifdef AUTO_EXPAND
+  Dirtovd(thFname);
+#endif
+
   i = stat(thFname, &st);
   if (i) {                      /* failed, let's create it */
     sprintf(thFname, "%s.", br->path);
+#ifdef AUTO_EXPAND
+    Dirtovd(thFname);
+#endif
     i = stat(thFname, &st);     /* get permissions of parent dir */
     if (!i) perm = st.st_mode & 07777;
        else perm = 0755;
 
     sprintf(thFname, "%s%s", br->path, THUMBDIRNAME);
-    mkdir(thFname, (mode_t) perm);
+#ifdef AUTO_EXPAND
+    Dirtovd(thFname);
+#endif
+    i = mkdir(thFname, (mode_t) perm);
+#ifdef VIRTUAL_TD
+    if (i < 0)
+      Mkvdir_force(thFname);
+#endif
   }
 }
 
@@ -3899,7 +4330,7 @@
   for (i=0, bf=br->bfList; i<br->bfLen; i++, bf++) {
     if (bf->ftype <= BF_FILE || bf->ftype >= BF_ERROR || bf->ftype==BF_EXE) {
 
-      /* ie, not a 'special' file */
+      /* i.e., not a 'special' file */
 
       int  s1, s2;
       char thfname[256];
@@ -3913,10 +4344,9 @@
       sprintf(thfname, "%s/%s", THUMBDIR, bf->name);
       s2 = stat(thfname, &thumbst);
 
-      if (s1 || s2 || filest.st_mtime > thumbst.st_mtime ||
-	              filest.st_ctime > thumbst.st_ctime) {
-	/* either stat'ing the file or the thumbfile failed, or 
-	   both stat's succeeded and the file has a newer mod or creation
+      if (s1 || s2 || filest.st_mtime > thumbst.st_mtime) {
+	/* either stat'ing the file or the thumbfile failed, or
+	   both stat's succeeded and the file has a newer mod
 	   time than the thumbnail file */
 
 	makeIconVisible(br, i);
@@ -3926,11 +4356,16 @@
 
 	if (bf->ftype != BF_EXE) {
 	  iconsBuilt++;
-	  if (DEBUG) 
-	    fprintf(stderr,"icon made:fname='%s' thfname='%s' %d,%d,%d,%d\n",
-		    bf->name, thfname, s1,s2,filest.st_mtime,thumbst.st_mtime);
+	  if (DEBUG)
+	    fprintf(stderr,"icon made:fname='%s' thfname='%s' %d,%d,%ld,%ld\n",
+		    bf->name, thfname, s1, s2,
+		    (long)filest.st_mtime, (long)thumbst.st_mtime);
 	}
       }
+      else if (filest.st_ctime > thumbst.st_ctime) {
+        /* update protections */
+        chmod(thfname, (mode_t) (filest.st_mode & 07777));
+      }
     }
     statcount++;
 
@@ -3964,7 +4399,11 @@
       sprintf(thfname, "%s/%s", THUMBDIR, dp->d_name);
       if (stat(thfname, &thumbst)==0) {  /* success */
 	int tmp;
+#ifdef AUTO_EXPAND
+	tmp  = stat2bf((u_int) thumbst.st_mode , thfname);
+#else
 	tmp  = stat2bf((u_int) thumbst.st_mode);
+#endif
 
 	if (tmp == BF_FILE) {  /* a plain file */
 	  /* see if this thumbfile has an associated pic file */
@@ -3974,7 +4413,7 @@
 	}
       }
       statcount++;
-      
+
       if ((statcount % 30)==0) WaitCursor();
     }
     closedir(dirp);
@@ -3998,16 +4437,16 @@
 {
   if (maxcnt<1) return;   /* none of that naughty ol' divide by zero stuff */
 
-  DrawTempGauge(br->win, 5, br->dirMB.y, 
+  DrawTempGauge(br->win, 5, br->dirMB.y,
 		(int) br->dirMB.x-10, (int) br->dirMB.h,
 		(double) cnt / (double) maxcnt,
 		browfg, browbg, browhi, browlo, "");
 }
- 
+
 static void clearTemp(br)
   BROWINFO *br;
 {
-  XClearArea(theDisp, br->win, 5, br->dirMB.y, 
+  XClearArea(theDisp, br->win, 5, br->dirMB.y,
 	     (u_int) br->dirMB.x-10+1, (u_int) br->dirMB.h + 1, True);
 }
 
@@ -4038,17 +4477,26 @@
      pops up a 'what do you want to rename it to' box, and attempts to
      do the trick... */
 
-  int  i, num;
-  char buf[128], txt[256], *origname, txt1[256];
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  struct stat st;
+  int                i, num;
+  char               buf[128], txt[256], *origname, txt1[256];
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  struct stat        st;
+
+#ifdef AUTO_EXPAND
+  if (Isvdir(br->path)) {
+    sprintf(buf,"Sorry, you can't rename file in the virtual directory, '%s'",
+	    br->path);
+    ErrPopUp(buf, "\nBummer!");
+    return;
+  }
+#endif
 
   if (cdBrow(br)) return;
 
   /* find the selected file */
   for (i=0; i<br->bfLen && !br->bfList[i].lit; i++);
   if (i==br->bfLen) return;    /* shouldn't happen */
-  
+
   origname = br->bfList[i].name;   num = i;
 
   if (strcmp(origname, "..")==0) {
@@ -4058,7 +4506,7 @@
     return;
   }
 
-  sprintf(txt, "Enter a new name for the %s '%s':", 
+  sprintf(txt, "Enter a new name for the %s '%s':",
 	  (br->bfList[i].ftype==BF_DIR) ? "directory" : "file",
 	  origname);
 
@@ -4107,7 +4555,7 @@
   drawIcon(br, num);
 
   for (i=0; i<MAXBRWIN; i++) {
-    if (&binfo[i] != br && strcmp(binfo[i].path, br->path)==0) 
+    if (&binfo[i] != br && strcmp(binfo[i].path, br->path)==0)
       rescanDir(&binfo[i]);
   }
 
@@ -4125,15 +4573,24 @@
      pops up a 'what do you want to call it' box, and attempts to
      do the trick... */
 
-  int          i;
-  char         buf[128], txt[256];
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  struct stat  st;
+  int                i;
+  char               buf[128], txt[256];
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  struct stat        st;
+
+#ifdef AUTO_EXPAND
+  if (Isvdir(br->path)) {
+    sprintf(buf,"Sorry, you can't mkdir in the virtual directory, '%s'",
+	    br->path);
+    ErrPopUp(buf, "\nBummer!");
+    return;
+  }
+#endif
 
   if (cdBrow(br)) return;
 
   buf[0] = '\0';
-  i = GetStrPopUp("Enter name for new directory:", labels, 2, 
+  i = GetStrPopUp("Enter name for new directory:", labels, 2,
 		  buf, 128, "/ |\'\"<>,", 0);
   if (i) return;     /* cancelled */
 
@@ -4161,7 +4618,7 @@
 
   /* rescan current br, and all other br's pointing to same directory */
   for (i=0; i<MAXBRWIN; i++) {
-    if (strcmp(binfo[i].path, br->path)==0) 
+    if (strcmp(binfo[i].path, br->path)==0)
       rescanDir(&binfo[i]);
   }
 
@@ -4176,10 +4633,10 @@
 static void doChdirCmd(br)
      BROWINFO *br;
 {
-  int          i;
-  static char  buf[MAXPATHLEN+100];
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  char str[512];		
+  int                i;
+  static char        buf[MAXPATHLEN+100];
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  char               str[512];
 
   buf[0] = '\0';
   i = GetStrPopUp("Change to directory:", labels, 2, buf, MAXPATHLEN, " ", 0);
@@ -4198,14 +4655,35 @@
     if (cdBrow(br)) return;     /* prints its own error message */
   }
 
+#ifdef AUTO_EXPAND
+  if (Chvdir(buf)) {
+#else
   if (chdir(buf)) {
+#endif
     sprintf(str,"Unable to cd to '%s'\n", buf);
     setBrowStr(br, str);
     XBell(theDisp, 50);
   }
   else {
+#ifdef AUTO_EXPAND
+      if (Isvdir(buf)) {
+	BTSetActive(&br->but[BR_DELETE],  0);
+	br->cmdMB.dim[BR_DELETE] = 1;
+
+	BTSetActive(&br->but[BR_RENAME],  0);
+	br->cmdMB.dim[BR_RENAME] = 1;
+
+	BTSetActive(&br->but[BR_MKDIR],  0);
+	br->cmdMB.dim[BR_MKDIR] = 1;
+      }
+      else {
+	BTSetActive(&br->but[BR_MKDIR],  1);
+	br->cmdMB.dim[BR_MKDIR] = 0;
+      }
+#endif
     scanDir(br);
     SCSetVal(&(br->scrl), 0);	/* reset to top on a chdir */
+    restIconVisible(br);
   }
 }
 
@@ -4225,10 +4703,19 @@
    * call 'rm_dir()' for each of the directories
    */
 
-  BFIL  *bf;
-  int    i, j, numdirs, numfiles, slen, firstdel;
-  char   buf[512];
-  static char *yesno[]  = { "\004Delete", "\033Cancel" };
+  BFIL              *bf;
+  int                i, numdirs, numfiles, slen, firstdel;
+  char               buf[512];
+  static const char *yesno[]  = { "\004Delete", "\033Cancel" };
+
+#ifdef AUTO_EXPAND
+  if (Isvdir(br->path)) {
+    sprintf(buf,"Sorry, you can't delete file at the virtual directory, '%s'",
+	    br->path);
+    ErrPopUp(buf, "\nBummer!");
+    return;
+  }
+#endif
 
   if (!br->bfLen || !br->bfList || !br->numlit) return;
 
@@ -4252,13 +4739,17 @@
   for (i=0, bf=br->bfList; i<br->bfLen; i++,bf++) {
     if (bf->lit) {
       if (firstdel == -1) firstdel = i;
-      if (bf->ftype == BF_DIR) numdirs++;
+      if (bf->ftype == BF_DIR
+#ifdef AUTO_EXPAND
+	  && (!Isarchive(bf->name))
+#endif
+			     ) numdirs++;
       else numfiles++;
     }
   }
 
 
-  /* if any plain files are being toasted, bring up the low-key 
+  /* if any plain files are being toasted, bring up the low-key
      confirmation box */
 
   if (numfiles) {
@@ -4266,7 +4757,12 @@
     slen = strlen(buf);
 
     for (i=0, bf=br->bfList;  i<br->bfLen;  i++,bf++) {
+#ifdef AUTO_EXPAND
+      if (bf->lit && (bf->ftype != BF_DIR || Isarchive(bf->name))) {
+#else
       if (bf->lit && bf->ftype != BF_DIR) {
+#endif
+
 	if ( (slen + strlen(bf->name) + 1) > 256) {
 	  strcat(buf,"...");
 	  break;
@@ -4278,10 +4774,10 @@
       }
     }
 
-    i = PopUp(buf, yesno, 2);
+    i = PopUp(buf, yesno, COUNT(yesno));
     if (i) return;              /* cancelled */
   }
-     
+
 
   /* if any directories are being toasted, bring up the are you REALLY sure
      confirmation box */
@@ -4291,7 +4787,11 @@
     slen = strlen(buf);
 
     for (i=0, bf=br->bfList;  i<br->bfLen;  i++,bf++) {
+#ifdef AUTO_EXPAND
+      if (bf->lit && (bf->ftype == BF_DIR || !Isarchive(bf->name))) {
+#else
       if (bf->lit && bf->ftype == BF_DIR) {
+#endif
 	if ( (slen + strlen(bf->name) + 1) > 256) {
 	  strcat(buf,"...");
 	  break;
@@ -4303,16 +4803,20 @@
       }
     }
 
-    i = PopUp(buf, yesno, 2);
+    i = PopUp(buf, yesno, COUNT(yesno));
     if (i) return;              /* cancelled */
   }
 
 
   /* okay, at this point they've been warned.  do the deletion */
-  
+
   for (i=0, bf=br->bfList;  i<br->bfLen;  i++,bf++) {
     if (bf->lit) {
-      if (bf->ftype == BF_DIR) rm_dir (br, bf->name);
+      if (bf->ftype == BF_DIR
+#ifdef AUTO_EXPAND
+	  && !Isarchive(bf->name)
+#endif
+			     ) rm_dir (br, bf->name);
                           else rm_file(br, bf->name);
     }
   }
@@ -4340,7 +4844,7 @@
 
   /* rescan other br's that are looking at this directory */
   for (i=0; i<MAXBRWIN; i++) {
-    if (&binfo[i] != br && strcmp(binfo[i].path, br->path)==0) 
+    if (&binfo[i] != br && strcmp(binfo[i].path, br->path)==0)
       rescanDir(&binfo[i]);
   }
 
@@ -4353,10 +4857,10 @@
 static void doSelFilesCmd(br)
      BROWINFO *br;
 {
-  int          i;
-  static char  buf[MAXPATHLEN+100];
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  char str[512];		
+  int                i;
+  static char        buf[MAXPATHLEN+100];
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  char               str[512];
 
   buf[0] = '\0';
   strcpy(str,"Select file name(s).  Wildcard '*' is allowed.  ");
@@ -4394,9 +4898,9 @@
 static void doRecurseCmd(br)
      BROWINFO *br;
 {
-  int          i;
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  char         str[512];		
+  int                i;
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+  char               str[512];
 
   strcpy(str,"Recursive Update:  This could take *quite* a while.\n");
   strcat(str,"Are you sure?");
@@ -4415,9 +4919,9 @@
 
 
 /*******************************************/
-static void recurseUpdate(br, subdir) 
-     BROWINFO *br;
-     char     *subdir;
+static void recurseUpdate(br, subdir)
+     BROWINFO   *br;
+     const char *subdir;
 {
   /* note:  'br->path + subdir' is the full path to recurse down from */
 
@@ -4430,7 +4934,7 @@
    *      and for each subdir in this dir, recurse
    *
    * if cur dir != orig dir, cd back to orig dir and reload 'br'
-   */ 
+   */
 
   int  i;
   char orgDir[MAXPATHLEN + 2];
@@ -4441,7 +4945,11 @@
   xv_getwd(orgDir, sizeof(orgDir));
 
   sprintf(curDir, "%s%s", br->path, subdir);
+#ifdef AUTO_EXPAND
+  if (Chvdir(curDir)) {
+#else
   if (chdir(curDir)) {
+#endif
     char str[512];
     sprintf(str, "Unable to cd to '%s'\n", curDir);
     setBrowStr(br, str);
@@ -4449,18 +4957,28 @@
   }
 
   xv_getwd(curDir, sizeof(curDir));
-  
+
   /* have we looped? */
   for (i=0; i<dirStackLen && strcmp(curDir, dirStack[i]); i++);
   if (i<dirStackLen) {   /* YES */
+#ifdef AUTO_EXPAND
+    Chvdir(orgDir);
+#else
     chdir(orgDir);
+#endif
+    restIconVisible(br);
     return;
   }
 
   sp = (char *) malloc((size_t) strlen(curDir) + 1);
   if (!sp) {
     setBrowStr(br, "malloc() error in recurseUpdate()\n");
+#ifdef AUTO_EXPAND
+    Chvdir(orgDir);
+#else
     chdir(orgDir);
+#endif
+    restIconVisible(br);
     return;
   }
 
@@ -4481,8 +4999,8 @@
   /* do subdirectories of this directory, not counting .  .. and .xvpics */
   for (i=0; i<br->bfLen; i++) {
     bf = &(br->bfList[i]);
-    if (bf                     && 
-	bf->ftype == BF_DIR    && 
+    if (bf                     &&
+	bf->ftype == BF_DIR    &&
 	strcmp(bf->name, ".")  &&
 	strcmp(bf->name, "..") &&
         strcmp(bf->name, THUMBDIRNAME) ) {
@@ -4495,7 +5013,12 @@
 
   xv_getwd(curDir, sizeof(curDir));
   if (strcmp(orgDir, curDir)) {   /* change back to orgdir */
+#ifdef AUTO_EXPAND
+    Chvdir(orgDir);
+#else
     chdir(orgDir);
+#endif
+    restIconVisible(br);
     scanDir(br);
   }
 }
@@ -4519,12 +5042,19 @@
     setBrowStr(br, buf);
   }
 
+#ifdef AUTO_EXPAND
+  if (Rmvdir(name)) {
+    sprintf(buf, "fail to remove virturl directory: %s", name);
+    setBrowStr(br, buf);
+  }
+#endif
+
   /* try to delete a thumbnail file, as well.  ignore errors */
   strcpy(buf1, name);          /* tmp1 = leading path of name */
   tmp = (char *) rindex(buf1, '/');
   if (!tmp) strcpy(buf1,".");
   else *tmp = '\0';
-  
+
   sprintf(buf, "%s/%s/%s", buf1, THUMBDIR, BaseName(name));
   if (DEBUG) fprintf(stderr,"   (%s)\n", buf);
 
@@ -4548,7 +5078,7 @@
      BROWINFO *br;
 {
   /* recursively delete this directory, and all things under it */
-  
+
   int    i, dirlen, longpath, oldpathlen;
   char **names, *name, buf[512];
   struct stat st;
@@ -4569,7 +5099,7 @@
       name = names[i];
 
       /* skip . and .. (not that we should ever see them... */
-      if (name[0] == '.' && (name[1]=='\0' || 
+      if (name[0] == '.' && (name[1]=='\0' ||
 			     (name[1]=='.' && name[2]=='\0'))) goto done;
 
       if (strlen(name) + oldpathlen >= (MAXPATHLEN-3)) {
@@ -4586,15 +5116,22 @@
 	rmdirPath[oldpathlen] = '\0';
 	goto done;
       }
-	
-      if (stat2bf((u_int) st.st_mode) == BF_DIR) {  /* skip, for now */
+
+#ifdef AUTO_EXPAND
+      if ((stat2bf((u_int) st.st_mode , rmdirPath) == BF_DIR)
+	  && !Isarchive(rmdirPath))                /* skip, for now */
+#else
+
+      if (stat2bf((u_int) st.st_mode) == BF_DIR)   /* skip, for now */
+#endif
+      {
 	rmdirPath[oldpathlen] = '\0';
 	continue;   /* don't remove from list */
       }
 
       rm_file(br, rmdirPath);
       rmdirPath[oldpathlen] = '\0';
-      
+
     done:     /* remove name from list */
       free(name);
       names[i] = (char *) NULL;
@@ -4640,30 +5177,35 @@
 
 static int overwrite;
 #define OWRT_ASK    0
-#define OWRT_NOASK  1
-#define OWRT_CANCEL 2
-
+#define OWRT_ALWAYS 1
+#define OWRT_NEVER  2
+#define OWRT_CANCEL 3
 
 /*******************************************/
-static void dragFiles(srcBr, dstBr, srcpath, dstpath, dstdir, 
+static void dragFiles(srcBr, dstBr, srcpath, dstpath, dstdir,
 		      names, nlen, cpymode)
-     BROWINFO *srcBr, *dstBr;
-     char     *srcpath, *dstpath, *dstdir, **names;
-     int       nlen, cpymode;
+     BROWINFO   *srcBr, *dstBr;
+     char       *srcpath, *dstpath, **names;
+     const char *dstdir;
+     int         nlen, cpymode;
 {
-  /* move or copy file(s) and their associated thumbnail files.  
+  /* move or copy file(s) and their associated thumbnail files.
      srcpath and dstpath will have trailing '/'s.  dstdir is name of
      folder in dstpath (or "." or "..") to write to.  names is an nlen
      long array of strings (the simple filenames of the files to move)
      if 'cpymode' copy files, otherwise move them */
 
-  int  i, j, k, dothumbs, fail;
+  int  i, j, dothumbs, fail;
   char dstp[MAXPATHLEN + 1];
   char src[MAXPATHLEN+1], dst[MAXPATHLEN+1];
   char buf[128];
   struct stat st;
 
 
+  /* if the source directory is read-only, don't move files; copy them */
+  if (!cpymode && (access(srcpath, W_OK) != 0))
+    cpymode = 1;
+
   /* build real destination dir */
   strcpy(dstp, dstpath);
 
@@ -4677,11 +5219,26 @@
   }
   else if (strcmp(dstdir,".")!=0) sprintf(dstp, "%s%s/", dstpath, dstdir);
 
+#ifdef AUTO_EXPAND
+  if (Isvdir(dstp)) {
+    sprintf(buf,"Sorry, you can't %s to the virtual directory, '%s'",
+	    cpymode ? "copy" : "move", dstp);
+    ErrPopUp(buf, "\nBummer!");
+    SetCursors(-1);
+    return;
+  }
+  if (Isvdir(srcpath))
+      cpymode = 1;
+#endif
+
 
 
   /* if there is a thumbnail directory in 'srcpath', make one for dstpath */
   sprintf(src,"%s%s", srcpath, THUMBDIR);
   dothumbs = 0;
+#ifdef AUTO_EXPAND
+  Dirtovd(src);
+#endif
   if (stat(src, &st)==0) {
     sprintf(dst,"%s%s", dstp, THUMBDIR);
     mkdir(dst, st.st_mode & 07777);
@@ -4712,6 +5269,14 @@
     if (overwrite == OWRT_CANCEL) break;         /* abort move */
     if (j==1) fail++;
 
+#ifdef AUTO_EXPAND
+    if (!cpymode && j==0)
+      if (Movevdir(src,dst)) {
+	sprintf(buf, "fail to move virturl directory: %s", names[i]);
+	setBrowStr(srcBr, buf);
+      }
+#endif
+
     if (dothumbs && j==0) {
       sprintf(src,"%s%s/%s", srcpath, THUMBDIR, names[i]);
       sprintf(dst,"%s%s/%s", dstp,    THUMBDIR, names[i]);
@@ -4749,8 +5314,17 @@
   }
 
 
+  if (!cpymode) {
+    /* clear all lit files in the source folder (as they've been moved)
+       note:  this won't be the optimal behavior if any files failed to
+       move, but screw it, that's not going to happen too often... */
+    for (i=0; i<srcBr->bfLen; i++) srcBr->bfList[i].lit = 0;
+    srcBr->numlit = 0;
+  }
+
+
   /* clear all files in the destination folder */
-  for (i=0; i<dstBr->bfLen; i++) { 
+  for (i=0; i<dstBr->bfLen; i++) {
     dstBr->bfList[i].lit = 0;
   }
   dstBr->numlit = 0;
@@ -4760,10 +5334,10 @@
   for (i=0; i<nlen; i++) {
     char *name;  BFIL *bf;
     name = names[i];
-    for (j=0, bf=dstBr->bfList; 
+    for (j=0, bf=dstBr->bfList;
 	 j<dstBr->bfLen && strcmp(name, bf->name)!=0; j++, bf++);
-    if (j<dstBr->bfLen) { 
-      bf->lit = 1;  dstBr->numlit++; 
+    if (j<dstBr->bfLen) {
+      bf->lit = 1;  dstBr->numlit++;
     }
   }
 
@@ -4783,10 +5357,10 @@
   changedNumLit(srcBr, -1, 0);
 
 
-  if (fail) sprintf(buf, "Some files were not %s because of errors.", 
+  if (fail) sprintf(buf, "Some files were not %s because of errors.",
 		    cpymode ? "copied" : "moved");
 
-  else if (nlen>1) sprintf(buf, "%d files %s", nlen, 
+  else if (nlen>1) sprintf(buf, "%d files %s", nlen,
 			   (cpymode) ? "copied" : "moved");
   else buf[0] = '\0';
   setBrowStr(srcBr, buf);
@@ -4794,7 +5368,51 @@
   SetCursors(-1);
 }
 
+static int recursive_remove(dir)
+     char *dir;
+{
+  DIR *dp = NULL;
+  struct dirent *di;
+  char name[MAXPATHLEN+1];
+
+  strncpy(name, dir, MAXPATHLEN);
+  name[MAXPATHLEN] = 0;
+
+  if (name[strlen(name) - 1] == '/')
+    name[strlen(name) - 1] = 0;
+
+  if ((dp = opendir(name)) == NULL)
+    goto err;
+
+  while ((di = readdir(dp)) != NULL) {
+    char buf[MAXPATHLEN+1];
+    struct stat st;
+
+    if (!strcmp(di->d_name, ".") || !strcmp(di->d_name, ".."))
+      continue;
+
+    snprintf(buf, MAXPATHLEN, "%s/%s", name, di->d_name);
+
+    if (stat(buf, &st) < 0)
+      continue;
+
+    if (S_ISDIR(st.st_mode)) {
+      if (recursive_remove(buf) < 0)
+	goto err;
+    } else
+      unlink(buf);
+  }
 
+  if (rmdir(name) < 0)
+    goto err;
+
+  closedir(dp);
+  return 0;
+
+err:
+  if (dp) closedir(dp);
+  return -1;
+}
 
 /*************************************************/
 static int moveFile(src,dst)
@@ -4809,34 +5427,48 @@
      One bit of noise:  if destination file exists, pop up a Overwrite?
      warning box.  */
 
-  int         i, srcdir, dstdir;
-  struct stat st;
-  char        buf[512];
-  static char  *owbuts[4]  = { "\nOk", "dDon't ask", "nNo", "\033Cancel" };
+  int                i, srcdir, dstdir;
+  struct stat        st;
+  char               buf[512];
+  static const char *owbuts[]  = { "\nOk", "aAlways", "nNo", "NNever", "\033Cancel" };
 
   if (DEBUG) fprintf(stderr,"moveFile %s %s\n", src, dst);
 
+#ifdef AUTO_EXPAND
+  Dirtosubst(src);
+#endif
+
   if (stat(src, &st)) return 0;    /* src doesn't exist, it would seem */
+#ifdef AUTO_EXPAND
+  srcdir = (stat2bf((u_int) st.st_mode , src) == BF_DIR);
+#else
   srcdir = (stat2bf((u_int) st.st_mode) == BF_DIR);
+#endif
 
   /* see if destination exists */
+
   if (stat(dst, &st)==0) {
+    if (overwrite==OWRT_NEVER) return -1;
+#ifdef AUTO_EXPAND
+    dstdir = (stat2bf((u_int) st.st_mode , dst) == BF_DIR);
+#else
     dstdir = (stat2bf((u_int) st.st_mode) == BF_DIR);
+#endif
 
     if (overwrite==OWRT_ASK) {
-      sprintf(buf, "%s '%s' exists.\n\nOverwrite?", 
+      snprintf(buf, sizeof(buf), "%s '%s' exists.\n\nOverwrite?",
 	      dstdir ? "Directory" : "File", dst);
-      i = PopUp(buf, owbuts, 4);
-
-      if      (i==1) overwrite = OWRT_NOASK;
-      else if (i==2) return -1;
-      else if (i==3) { overwrite = OWRT_CANCEL;  return 1; }
+      switch (PopUp(buf, owbuts, COUNT(owbuts))) {
+	case 1: overwrite = OWRT_ALWAYS; break;
+	case 2: return -1;
+	case 3: overwrite = OWRT_NEVER; return -1;
+	case 4: overwrite = OWRT_CANCEL;  return 1;
+      }
     }
 
     if (dstdir) {
 #ifndef VMS  /* we don't delete directories in VMS */
-      sprintf(buf, "rm -rf %s", dst);
-      if (system(buf)) {     /* okay, so it's cheating... */
+      if (recursive_remove(dst)) {   /* okay, so it's cheating... */
 	SetISTR(ISTR_WARNING, "Unable to remove directory %s", dst);
 	return 1;
       }
@@ -4848,7 +5480,7 @@
     }
   }
 
-  
+
   if (!rename(src, dst)) return 0;   /* Ok */
   if (errno != EXDEV) return 1;      /* failure, of some sort */
 
@@ -4859,9 +5491,8 @@
   if (i == 0) {    /* copied okay, kill the original */
     if (srcdir) {
 #ifndef VMS   /* we don't delete directories in VMS */
-      sprintf(buf, "rm -rf %s", src);
-      if (system(buf)) {     /* okay, so it's cheating... */
-	SetISTR(ISTR_WARNING, "Unable to remove directory %s", dst);
+      if (recursive_remove(src)) {   /* okay, so it's cheating... */
+	SetISTR(ISTR_WARNING, "Unable to remove directory %s", src);
 	return 1;
       }
 #endif /* VMS */
@@ -4896,7 +5527,7 @@
   /* possible cases:  source is either a file or a directory, or doesn't exist,
      destination is either a file, a directory, or doesn't exist.
 
-     if source doesn't exist, nothing to do.  
+     if source doesn't exist, nothing to do.
      if source is a file:
         if dest is a file, popup 'overwriting' question, delete file if ok
 	if dest is a dir,  popup 'overwriting dir' question, delete dir if ok
@@ -4907,38 +5538,51 @@
 	   fall through:  if dest doesn't exist, copy the directory, recurs */
 
 
-  int         i, dstExists, srcdir, dstdir;
-  struct stat srcSt, dstSt;
-  char        buf[1024];
-  static char *owdiff[3] = { "\nOk", "nNo", "\033Cancel" };
-  static char *owsame[4] = { "\nOk", "dDon't Ask", "nNo", "\033Cancel" };
+  int                dstExists, srcdir, dstdir;
+  struct stat        srcSt, dstSt;
+  char               buf[1024];
+  static const char *owdiff[] = { "\nOk", "nNo", "\033Cancel" };
+  static const char *owsame[] = { "\nOk", "aAlways", "nNo", "NNever", "\033Cancel" };
 
   if (DEBUG) fprintf(stderr,"copyFile %s %s\n", src, dst);
 
+#ifdef AUTO_EXPAND
+  Dirtosubst(src);
+#endif
+
   if (stat(src,&srcSt)) return 0;  /* source doesn't exist, it would seem */
 
   dstExists = (stat(dst, &dstSt)==0);
 
   if (dstExists) {   /* ask about overwriting... */
-    srcdir = (stat2bf((u_int) srcSt.st_mode) == BF_DIR);
-    dstdir = (stat2bf((u_int) dstSt.st_mode) == BF_DIR);
+#ifdef AUTO_EXPAND
+  srcdir = (stat2bf((u_int) srcSt.st_mode , src) == BF_DIR);
+  dstdir = (stat2bf((u_int) dstSt.st_mode , dst) == BF_DIR);
+#else
+  srcdir = (stat2bf((u_int) srcSt.st_mode) == BF_DIR);
+  dstdir = (stat2bf((u_int) dstSt.st_mode) == BF_DIR);
+#endif
 
     sprintf(buf, "%s '%s' already exists.  Replace it with %s '%s'?",
 	    (dstdir) ? "Directory" : "File", dst,
 	    (srcdir) ? "contents of directory" : "file", src);
 
     if (srcdir == dstdir) {
+      if (overwrite==OWRT_NEVER) return -1;
       if (overwrite==OWRT_ASK) {
-	i = PopUp(buf, owsame, 4);
-	if (i==1) overwrite = OWRT_NOASK;
-	if (i==2) return -1;
-	else if (i==3) { overwrite = OWRT_CANCEL;  return 1; }
+	switch (PopUp(buf, owsame, COUNT(owsame))) {
+	  case 1: overwrite = OWRT_ALWAYS; break;
+	  case 2: return -1;
+	  case 3: overwrite = OWRT_NEVER; return -1;
+	  case 4: overwrite = OWRT_CANCEL;  return 1;
+	}
       }
     }
     else {     /* one's a dir, the other's a file.  *ALWAYS* ask! */
-      i = PopUp(buf, owdiff, 3);
-      if (i==1) return -1;
-      else if (i==2) { overwrite = OWRT_CANCEL;  return 1; }
+      switch (PopUp(buf, owdiff, COUNT(owdiff))) {
+        case 1: return -1;
+        case 2: overwrite = OWRT_CANCEL;  return 1;
+      }
     }
 
 
@@ -4957,7 +5601,7 @@
   /* destination doesn't exist no more, if it ever did... */
   userMask = umask(0);  /* grab the umask */
   umask((mode_t) userMask);      /* put it back... */
-  
+
 
   strcpy(cpSrcPath, src);
   strcpy(cpDstPath, dst);
@@ -5017,7 +5661,7 @@
      called recursively by cp_dir, there are *no* guarantees that either file
      exists or not */
 
-  int         i, havedst;
+  int         havedst;
   struct stat srcSt, dstSt;
 
   if (stat(cpSrcPath, &srcSt)) {   /* src doesn't exist, usefully... */
@@ -5036,8 +5680,11 @@
     havedst = 1;
   }
 
-
-  switch(stat2bf((u_int) srcSt.st_mode)) {   
+#ifdef AUTO_EXPAND
+  switch(stat2bf((u_int) srcSt.st_mode , cpDstPath)) {
+#else
+  switch(stat2bf((u_int) srcSt.st_mode)) {
+#endif
     /* determine how to copy, by filetype */
 
     /* NOTE:  There is no S_IFLNK case here, since we're using 'stat()' and
@@ -5053,18 +5700,22 @@
     }
   }
   else {
+#ifdef AUTO_EXPAND
+    if (stat2bf((u_int) dstSt.st_mode , cpDstPath) != BF_DIR) {
+#else
     if (stat2bf((u_int) dstSt.st_mode) != BF_DIR) {
+#endif
       SetISTR(ISTR_WARNING,"%s: not a directory", cpDstPath);
       copyerr++;
       return;
     }
   }
-    
+
     cp_dir();
     if (!havedst) chmod(cpDstPath, srcSt.st_mode);
-    
+
     break;
-    
+
 
   case BF_CHR:
   case BF_BLK:   cp_special(&srcSt, havedst);    break;
@@ -5089,12 +5740,12 @@
 {
   int    i, dirlen, oldsrclen, olddstlen, longpath;
   char **names, *name;
-  struct stat  srcSt, dstSt;
+  struct stat  srcSt;
 
 
   /* src and dst directories both exists now.  copy entries */
 
-  if (DEBUG) fprintf(stderr,"cp_dir:   src='%s',  dst='%s'\n", 
+  if (DEBUG) fprintf(stderr,"cp_dir:   src='%s',  dst='%s'\n",
 		     cpSrcPath, cpDstPath);
 
   longpath  = 0;
@@ -5110,9 +5761,9 @@
 
   for (i=0; i<dirlen && overwrite!=OWRT_CANCEL; i++) {
     name = names[i];
-    if (name[0] == '.' && (name[1]=='\0' || 
+    if (name[0] == '.' && (name[1]=='\0' ||
 			   (name[1]=='.' && name[2]=='\0'))) goto done;
-    
+
     /* add name to src and dst paths */
     if ((strlen(name) + oldsrclen >= (MAXPATHLEN-3)) ||
 	(strlen(name) + olddstlen >= (MAXPATHLEN-3)))   {
@@ -5130,12 +5781,17 @@
       cpSrcPath[oldsrclen] = '\0';
       goto done;
     }
-     
-    if (stat2bf((u_int) srcSt.st_mode) == BF_DIR) {
+
+#ifdef AUTO_EXPAND
+    if (stat2bf((u_int) srcSt.st_mode , cpSrcPath) == BF_DIR)
+#else
+    if (stat2bf((u_int) srcSt.st_mode) == BF_DIR)
+#endif
+    {
       cpSrcPath[oldsrclen] = '\0';
       continue;                     /* don't remove from list, just skip */
     }
-     
+
     strcat(cpDstPath, "/");
     strcat(cpDstPath, name);
     cp();                         /* RECURSE */
@@ -5169,7 +5825,7 @@
     strcat(cpDstPath, name);
 
     cp();                        /* RECURSE */
-    
+
     cpSrcPath[oldsrclen] = '\0';
     cpDstPath[olddstlen] = '\0';
   }
@@ -5190,11 +5846,11 @@
      int exists;
 /*****************************/
 {
-  register int srcFd, dstFd, rcount, wcount, i;
-  char         str[512], buf[8192];
-  static char  *owbuts[4] = { "\nOk", "dDon't Ask", "nNo", "\033Cancel" };
+  register int       srcFd, dstFd, rcount, wcount;
+  char               buf[8192];
+  static const char *owbuts[] = { "\nOk", "aAlways", "nNo", "NNever", "\033Cancel" };
 
-  if (DEBUG) fprintf(stderr,"cp_file:  src='%s',  dst='%s'\n", 
+  if (DEBUG) fprintf(stderr,"cp_file:  src='%s',  dst='%s'\n",
 		     cpSrcPath, cpDstPath);
 
   if ((srcFd = open(cpSrcPath, O_RDONLY, 0)) == -1) {
@@ -5204,13 +5860,15 @@
   }
 
   if (exists) {
+    if (overwrite==OWRT_NEVER) return;
     if (overwrite==OWRT_ASK) {
       sprintf(buf, "File '%s' exists.\n\nOverwrite?", cpDstPath);
-      i = PopUp(buf, owbuts, 4);
-
-      if      (i==1) overwrite = OWRT_NOASK;
-      else if (i==2) return;
-      else if (i==3) { overwrite = OWRT_CANCEL;  return; }
+      switch (PopUp(buf, owbuts, 4)) {
+        case 1: overwrite = OWRT_ALWAYS; break;
+        case 2: return;
+        case 3: overwrite = OWRT_NEVER; return;
+        case 4: overwrite = OWRT_CANCEL;  return;
+      }
     }
     dstFd = open(cpDstPath, O_WRONLY|O_TRUNC, 0);
   }
@@ -5255,7 +5913,7 @@
      int exists;
 /*********************************/
 {
-  if (DEBUG) fprintf(stderr,"cp_spec:  src='%s',  dst='%s'\n", 
+  if (DEBUG) fprintf(stderr,"cp_spec:  src='%s',  dst='%s'\n",
 		     cpSrcPath, cpDstPath);
 
   if (exists && unlink(cpDstPath)) {
@@ -5281,7 +5939,7 @@
      int exists;
 /*********************************/
 {
-  if (DEBUG) fprintf(stderr,"cp_fifo:  src='%s',  dst='%s'\n", 
+  if (DEBUG) fprintf(stderr,"cp_fifo:  src='%s',  dst='%s'\n",
 		     cpSrcPath, cpDstPath);
 
 #ifdef S_IFIFO
@@ -5302,12 +5960,18 @@
 
 
 
-  
+
 /*********************************/
+#ifdef AUTO_EXPAND
+static int stat2bf(uistmode, path)
+     u_int uistmode;
+     char *path;
+#else
 static int stat2bf(uistmode)
      u_int uistmode;
+#endif
 {
-  /* given the 'st.st_mode' field from a successful stat(), returns 
+  /* given the 'st.st_mode' field from a successful stat(), returns
      BF_FILE, BF_DIR, BF_BLK, BF_CHR, BF_FIFO, or BF_SOCK.  Does *NOT*
      return BF_EXE */
 
@@ -5319,6 +5983,9 @@
   else if (S_ISBLK(stmode))  rv = BF_BLK;
   else if (S_ISFIFO(stmode)) rv = BF_FIFO;
   else if (S_ISSOCK(stmode)) rv = BF_SOCK;
+#ifdef AUTO_EXPAND
+  else if (Isarchive(path))  rv = BF_DIR;
+#endif
   else                       rv = BF_FILE;
 
   return rv;
@@ -5357,8 +6024,8 @@
 static int selmatch1(name, arg)
      char *name, *arg;
 {
-  /* returns non-zero if 'name' matches 'arg'.  Any '*' chars found in arg 
-     are considered wildcards that match any number of characters, 
+  /* returns non-zero if 'name' matches 'arg'.  Any '*' chars found in arg
+     are considered wildcards that match any number of characters,
      including zero. */
 
   char *sp, *oldnp;
@@ -5379,7 +6046,7 @@
 	while (*name) name++;
 	while (*arg ) arg++;
 	name--;  arg--;
-	
+
 	while (*arg != '*') {
 	  if (*arg != *name || name<oldnp) return 0;
 	  arg--;  name--;
@@ -5388,7 +6055,7 @@
       }
 
       else {  /* there are more '*'s in arg... */
-	/* find the first occurrence of the string between the two '*'s.  
+	/* find the first occurrence of the string between the two '*'s.
 	   if the '*'s are next to each other, just throw away the first one */
 
 	arg++;  /* points to char after  first  '*' */
@@ -5410,7 +6077,7 @@
 	  arg = sp+1;
 	}
       }
-    }	  
+    }
   }
 
   if (!*arg && !*name) return 1;
@@ -5419,4 +6086,98 @@
 }
 
 
+static IVIS *icon_vis_list = NULL;
+
+/***************************************************************/
+static void recIconVisible(name, icon)
+  char *name;
+  int   icon;
+{
+  IVIS *ptr, *prev = NULL;
+
+  for (ptr = icon_vis_list; ptr; prev = ptr, ptr = ptr->next) {
+    if (!strcmp(ptr->name, name)) {
+      ptr->icon = icon;
+      return;
+    }
+  }
+
+  ptr = calloc(sizeof(IVIS), 1);
+  if (!ptr)
+    return;
 
+  ptr->name = strdup(name);
+
+  if (!ptr->name) {
+    free(ptr);
+    return;
+  }
+
+  if (!prev) {
+    icon_vis_list = ptr;
+  } else {
+    prev->next = ptr;
+  }
+
+  ptr->next = NULL;
+  ptr->icon = icon;
+}
+
+/***************************************************************/
+static void restIconVisible(br)
+  BROWINFO *br;
+{
+  IVIS *ptr;
+
+  for (ptr = icon_vis_list; ptr; ptr = ptr->next) {
+    if (!strcmp(ptr->name, br->path)) {
+      if (ptr->icon >= 0) {
+        makeIconVisible(br, ptr->icon);
+        updateSel(br, ptr->icon, 0, 0);
+      }
+      return;
+    }
+  }
+}
+
+
+/*********************************/
+static void clipChanges(br)
+     BROWINFO *br;
+{
+  /* called whenever schnauzer activity should place file names in
+     the X11 clipboard, or change what it put there.
+
+     Implementation is simple because the UI is non-standard
+     (i.e., not like xterm(1)). The clipboard command causes the
+     current browser to dump all its currently selected files'
+     (if any) names to the clipboard, space-separated.
+     No effort is made to shell-escape blanks and other 'odd'
+     characters in the names. */
+
+  char buf[4000]; /* too much or too little, whatever... */
+  int n;
+  int i;
+
+  n = 0;
+  strcpy(buf, "");
+
+  for (i=0; i<br->bfLen; i++) {
+    if(br->bfList[i].lit == 1) {
+      int m;
+
+      m = strlen(br->bfList[i].name) + 1;
+
+      if(n+m+1 >= sizeof(buf)) return;  /* names probably won't fit in buf, abort */
+      strcat(buf, br->bfList[i].name);
+      strcat(buf, " ");
+      n += m;
+    }
+  }
+
+  if(n) {
+    buf[n-1] = 0; /* trim last space */
+
+    NewCutBuffer(buf);
+  }
+}
diff -ru xv-3.10a/xvbutt.c xv-3.10a-enhancements/xvbutt.c
--- xv-3.10a/xvbutt.c	1995-01-03 13:19:51.000000000 -0800
+++ xv-3.10a-enhancements/xvbutt.c	2007-04-15 20:59:15.000000000 -0700
@@ -1,4 +1,4 @@
-/* 
+/*
  * xvbutt.c - regular, 'radio', 'checkbox', and 'menu' pushbuttons
  *
  * callable functions:
@@ -16,7 +16,7 @@
  *   RBSetActive()          -  sets active status of an RBUTT
  *   RBClick()              -  finds clicked-on rb in a list
  *   RBTrack()              -  tracks rb after click, until release
- * 
+ *
  *   CBCreate()             -  create a CBUTT (checkbox button)
  *   CBRedraw()             -  redraw a CBUTT
  *   CBSetActive()          -  change active status of a CBUTT
@@ -26,7 +26,7 @@
  *   MBCreate()             -  create a MBUTT (menu button)
  *   MBRedraw()             -  redraw a MBUTT
  *   MBSetActive()          -  change active status of a MBUTT
- *   MBWhich()              -  returns # of first checked selection 
+ *   MBWhich()              -  returns # of first checked selection
  *   MBSelect()             -  similar to RBSelect() ...
  *   MBClick()              -  returns true if given MB was clicked on
  *   MBTrack()              -  tracks MBUTT after click, until release
@@ -76,7 +76,7 @@
      Window        win;
      int           x,y;
      unsigned int  w,h;
-     char         *str;
+     const char   *str;
      unsigned long fg,bg,hi,lo;
 {
   bp->win = win;
@@ -116,7 +116,7 @@
 void BTRedraw(bp)
 BUTT *bp;
 {
-  int          i,x,y,r,x1,y1;
+  int          x,y,r,x1,y1;
   unsigned int w,h;
   XPoint       tpts[10], bpts[10], ipts[5];
 
@@ -170,13 +170,13 @@
     XSetForeground(theDisp, theGC, bp->fg);
     XDrawLines(theDisp, bp->win, theGC, ipts, 5, CoordModeOrigin);  /* inset */
 
-    XDrawLine(theDisp, bp->win, theGC, x+1,             y + 1,  
+    XDrawLine(theDisp, bp->win, theGC, x+1,             y + 1,
 	      ipts[0].x, ipts[0].y);
     XDrawLine(theDisp, bp->win, theGC, x+1,             y + (int) h - 1,
 	      ipts[1].x, ipts[1].y);
     XDrawLine(theDisp, bp->win, theGC, x + (int) w - 1, y + (int) h - 1,
 	      ipts[2].x, ipts[2].y);
-    XDrawLine(theDisp, bp->win, theGC, x + (int) w - 1, y+1,  
+    XDrawLine(theDisp, bp->win, theGC, x + (int) w - 1, y+1,
 	      ipts[3].x, ipts[3].y);
 
     if (bp->lit) {
@@ -184,12 +184,12 @@
       XDrawRectangle(theDisp, bp->win, theGC, x+1, y+1, w-2, h-2);
     }
   }
-    
+
   else {   /* ctrlColor */
     XSetForeground(theDisp, theGC, bp->bg);
     XFillRectangle(theDisp, bp->win, theGC, x+1, y+1, w-1, h-1);
 
-    Draw3dRect(bp->win, x+1, y+1, w-2, h-2, R3D_OUT, bp->fwidth, 
+    Draw3dRect(bp->win, x+1, y+1, w-2, h-2, R3D_OUT, bp->fwidth,
 	       bp->hi, bp->lo, bp->bg);
 
     XSetForeground(theDisp, theGC, bp->fg);
@@ -198,7 +198,7 @@
     if (bp->lit)
       XDrawRectangle(theDisp, bp->win, theGC, x+1, y+1, w-2, h-2);
   }
-    
+
 
 
 
@@ -210,7 +210,7 @@
 
     XSetBackground(theDisp, theGC, bp->bg);
 
-    if (bp->colorpix) 
+    if (bp->colorpix)
       XCopyArea (theDisp,bp->pix, bp->win, theGC, 0,0,bp->pw,bp->ph, x1,y1);
     else
       XCopyPlane(theDisp,bp->pix, bp->win, theGC, 0,0,bp->pw,bp->ph, x1,y1,1L);
@@ -262,15 +262,15 @@
     if (bp->lit==inval && PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) {
       bp->lit = !inval;  BTRedraw(bp);  XFlush(theDisp);
     }
-    
+
     if (bp->lit!=inval && !PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) {
       bp->lit = inval;  BTRedraw(bp);  XFlush(theDisp);
     }
   }
 
   rval = (bp->lit != inval);
-  
-  if (bp->lit && !bp->toggle) 
+
+  if (bp->lit && !bp->toggle)
     { bp->lit = 0;  BTRedraw(bp);  XFlush(theDisp); }
 
   return(rval);
@@ -290,18 +290,18 @@
       RBUTT        *rblist;
       Window        win;
       int           x,y;
-      char         *str;
+      const char   *str;
       unsigned long fg,bg,hi,lo;
 {
   /* mallocs an RBUTT, fills in the fields, and appends it to rblist
      if rblist is NULL, this is the first rb in the list.  It will
-     be made the 'selected' one 
+     be made the 'selected' one
 
-     Note: no need to check return status.  It'll fatal error if it 
+     Note: no need to check return status.  It'll fatal error if it
      can't malloc */
 
   RBUTT *rb, *rbptr;
-  Pixmap rb_frame, rb_frame1, rb_top, rb_bot, rb_dtop, rb_dbot, rb_body, 
+  Pixmap rb_frame, rb_frame1, rb_top, rb_bot, rb_dtop, rb_dbot, rb_body,
          rb_dot;
 
   rb = (RBUTT *) malloc(sizeof(RBUTT));
@@ -348,7 +348,7 @@
     rb_off    = XCreatePixmap(theDisp, rootW, RBSIZE, RBSIZE, dispDEEP);
     rb_off1   = XCreatePixmap(theDisp, rootW, RBSIZE, RBSIZE, dispDEEP);
 
-    if (!rb_frame || !rb_frame1 || !rb_top || !rb_bot || !rb_dtop || 
+    if (!rb_frame || !rb_frame1 || !rb_top || !rb_bot || !rb_dtop ||
 	!rb_dbot  || !rb_body   || !rb_dot || !rb_on  || !rb_on1  ||
 	!rb_off   || !rb_off1)
       FatalError("unable to create radio-button pixmaps");
@@ -410,7 +410,7 @@
       XFillRectangle(theDisp, rb_on,   theGC, 0,0,RBSIZE,RBSIZE);
       XFillRectangle(theDisp, rb_on1,  theGC, 0,0,RBSIZE,RBSIZE);
     }
-      
+
     XSetStipple(theDisp, theGC, rb_frame);
     XSetForeground(theDisp, theGC, fg);
     XFillRectangle(theDisp, rb_on,   theGC, 0,0,RBSIZE,RBSIZE);
@@ -437,7 +437,7 @@
 
   return(rb);
 }
-  
+
 
 
 
@@ -475,23 +475,23 @@
      int   lit;
 {
   /* draws the rb being pointed at */
-  
+
   Pixmap pix;
-  
+
   if (!rb) return;  /* rb = NULL */
-  
+
   XSetForeground(theDisp, theGC, rb->fg);
-  
+
   if (rb->selected) { pix = (lit) ? rb_on1 : rb_on; }
   else { pix = (lit) ? rb_off1 : rb_off; }
-  
+
   XCopyArea(theDisp, pix, rb->win, theGC, 0,0,RBSIZE,RBSIZE, rb->x, rb->y);
-  DrawString(rb->win, rb->x + RBSIZE + 4, 
+  DrawString(rb->win, rb->x + RBSIZE + 4,
 	     rb->y + RBSIZE/2 - CHIGH/2 + ASCENT, rb->str);
 
   if (!rb->active) {  /* if non-active, dim button and string */
     DimRect(rb->win, rb->x, rb->y, RBSIZE, RBSIZE, rb->bg);
-    DimRect(rb->win, rb->x + RBSIZE + 4, rb->y + RBSIZE/2 - CHIGH/2, 
+    DimRect(rb->win, rb->x + RBSIZE + 4, rb->y + RBSIZE/2 - CHIGH/2,
 	    (u_int) StringWidth(rb->str), (u_int) CHIGH, rb->bg);
   }
 }
@@ -527,19 +527,19 @@
 }
 
 
-	      
+
 /***********************************************/
 int RBWhich(rblist)
      RBUTT *rblist;
 {
   int i;
-  
+
   /* returns index of currently selected rb.  if none, returns -1 */
-  
+
   i = 0;
-  while (rblist && !rblist->selected) 
+  while (rblist && !rblist->selected)
     { rblist = (RBUTT *) rblist->next;  i++; }
-  
+
   if (!rblist) return -1;             /* didn't find one */
   return i;
 }
@@ -550,9 +550,9 @@
      RBUTT *rblist;
 {
   int i;
-  
+
   /* returns # of rb's in the list */
-  
+
   i = 0;
   while (rblist) { rblist = (RBUTT *) rblist->next; i++; }
   return i;
@@ -566,13 +566,13 @@
 {
   RBUTT *rb;
   int    i;
-  
+
   /* sets 'active' status of rb #n.  does redrawing */
-  
+
   rb=rblist;  i=0;
   while (rb && i!=n) { rb = (RBUTT *) rb->next; i++; }
   if (!rb) return;                         /* n out of range.  do nothing */
-  
+
   if (rb->active != act) {
     rb->active = act;
     drawRB(rb, 0);
@@ -588,13 +588,13 @@
   int i;
 
   /* searches through rblist to see if mouse click at mx,my is in the
-     clickable region of any of the rb's.  If it finds one, it returns 
+     clickable region of any of the rb's.  If it finds one, it returns
      it's index in the list.  If not, returns -1 */
 
   i = 0;
   while (rblist) {
     if (PTINRECT(mx, my, rblist->x, rblist->y, RBSIZE, RBSIZE)) break;
-    
+
     rblist = (RBUTT *) rblist->next;
     i++;
   }
@@ -613,9 +613,9 @@
   Window       rW, cW;
   int          i, x, y, rx, ry, lit, rv;
   unsigned int mask;
-  
+
   /* returns '1' if selection changed */
-  
+
   rb=rblist;  i=0;
   while (rb && i!=n) { rb = (RBUTT *) rb->next; i++; }
   if (!rb) return 0;                    /* n out of range */
@@ -637,7 +637,7 @@
       drawRB(rb, lit);
       XFlush(theDisp);
     }
-    
+
     if (lit && !PTINRECT(x, y, rb->x, rb->y, RBSIZE, RBSIZE)) {
       lit=0;
       drawRB(rb, lit);
@@ -671,7 +671,7 @@
       CBUTT        *cb;
       Window        win;
       int           x,y;
-      char         *str;
+      const char   *str;
       unsigned long fg,bg,hi,lo;
 {
   /* fill in the fields of the structure */
@@ -690,14 +690,14 @@
      do so.  We'll be needing them, y'see... */
 
   if (!cbpixmade) {
-    cbcheck = XCreatePixmapFromBitmapData(theDisp, rootW, 
+    cbcheck = XCreatePixmapFromBitmapData(theDisp, rootW,
 	     (char *) cb_check_bits,
 	     cb_check_width, cb_check_height, fg, bg, dispDEEP);
 
     cbpixmade = 1;
   }
 }
-  
+
 
 
 
@@ -708,25 +708,25 @@
   /* draws the cb being pointed at */
 
   XSetForeground(theDisp, theGC, cb->bg);
-  XFillRectangle(theDisp, cb->win, theGC, cb->x+2, cb->y+2, 
+  XFillRectangle(theDisp, cb->win, theGC, cb->x+2, cb->y+2,
 		 XVCBSIZE-3,XVCBSIZE-3);
 
   XSetForeground(theDisp, theGC, cb->fg);
   XDrawRectangle(theDisp, cb->win, theGC, cb->x, cb->y, XVCBSIZE, XVCBSIZE);
   Draw3dRect(cb->win, cb->x+1, cb->y+1, XVCBSIZE-2, XVCBSIZE-2, R3D_OUT, 2,
-	     cb->hi, cb->lo, cb->bg); 
+	     cb->hi, cb->lo, cb->bg);
 
-  if (cb->val) XCopyArea(theDisp, cbcheck, cb->win, theGC, 
-			 0, 0, cb_check_width, cb_check_height, 
+  if (cb->val) XCopyArea(theDisp, cbcheck, cb->win, theGC,
+			 0, 0, cb_check_width, cb_check_height,
 			 cb->x+3, cb->y+3);
- 
+
   XSetForeground(theDisp, theGC, cb->fg);
-  DrawString(cb->win, cb->x + XVCBSIZE+4, 
+  DrawString(cb->win, cb->x + XVCBSIZE+4,
 	     cb->y+XVCBSIZE/2 - CHIGH/2 + ASCENT, cb->str);
 
   if (!cb->active) {  /* if non-active, dim button and string */
     DimRect(cb->win, cb->x, cb->y, XVCBSIZE, XVCBSIZE, cb->bg);
-    DimRect(cb->win, cb->x + XVCBSIZE+4, cb->y+XVCBSIZE/2 - CHIGH/2, 
+    DimRect(cb->win, cb->x + XVCBSIZE+4, cb->y+XVCBSIZE/2 - CHIGH/2,
 	    (u_int) StringWidth(cb->str), (u_int) CHIGH, cb->bg);
   }
 }
@@ -761,7 +761,6 @@
   Window       rW, cW;
   int          x, y, rx, ry, lit;
   unsigned int mask;
-  Pixmap litpix, darkpix;
 
   /* called once we've figured out that the mouse clicked in 'cb' */
 
@@ -782,7 +781,7 @@
       drawCB(cb,lit);
       XFlush(theDisp);
     }
-    
+
     if (lit && !PTINRECT(x, y, cb->x, cb->y, XVCBSIZE, XVCBSIZE)) {
       lit=0;
       drawCB(cb,lit);
@@ -809,28 +808,28 @@
 {
   /* draws highlighting */
   if (lit) {
-    if (ctrlColor) 
+    if (ctrlColor)
       Draw3dRect(cb->win, cb->x+1, cb->y+1, XVCBSIZE-2, XVCBSIZE-2, R3D_IN, 2,
 		 cb->hi, cb->lo, cb->bg);
     else {
       XSetForeground(theDisp, theGC, cb->fg);
-      XDrawRectangle(theDisp, cb->win, theGC, cb->x+1, cb->y+1, 
+      XDrawRectangle(theDisp, cb->win, theGC, cb->x+1, cb->y+1,
 		     XVCBSIZE-2, XVCBSIZE-2);
     }
   }
 
   else {
-    if (ctrlColor) 
+    if (ctrlColor)
       Draw3dRect(cb->win, cb->x+1, cb->y+1, XVCBSIZE-2, XVCBSIZE-2, R3D_OUT, 2,
 		 cb->hi, cb->lo, cb->bg);
     else {
       XSetForeground(theDisp, theGC, cb->bg);
-      XDrawRectangle(theDisp, cb->win, theGC, cb->x+1, cb->y+1, 
+      XDrawRectangle(theDisp, cb->win, theGC, cb->x+1, cb->y+1,
 		     XVCBSIZE-2, XVCBSIZE-2);
     }
   }
 }
-    
+
 
 
 /******************* MBUTT ROUTINES ************************/
@@ -838,20 +837,20 @@
 
 
 /***********************************************/
-void MBCreate(mb, win, x,y,w,h, str, list, nlist, fg, bg, hi, lo)
+void MBCreate(mb, win, x, y, w, h, title, list, nlist, fg, bg, hi, lo)
      MBUTT        *mb;
      Window        win;
      int           x,y;
      unsigned int  w,h;
-     char         *str;
-     char        **list;
+     const char   *title;
+     const char  * const *list;
      int           nlist;
      unsigned long fg,bg,hi,lo;
 {
   XSetWindowAttributes xswa;
   unsigned long        xswamask;
   int i;
-  
+
   if (!mbpixmade) {
     mbchk = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) mb_chk_bits,
 	     mb_chk_width, mb_chk_height, fg, bg, dispDEEP);
@@ -865,7 +864,7 @@
   mb->y        = y;
   mb->w        = w;
   mb->h        = h;
-  mb->title    = str;
+  mb->title    = title;
   mb->active   = 1;
   mb->list     = list;
   mb->nlist    = nlist;
@@ -889,7 +888,7 @@
   xswa.save_under       = True;
   xswamask = CWBackPixel | CWBorderPixel | CWSaveUnder;
 
-  mb->mwin = XCreateWindow(theDisp, mb->win, x, y, w, h, 
+  mb->mwin = XCreateWindow(theDisp, mb->win, x, y, w, h,
 			   (u_int) 2, (int) dispDEEP, InputOutput,
 			   theVisual, xswamask, &xswa);
 
@@ -898,7 +897,7 @@
   XSelectInput(theDisp, mb->mwin, ExposureMask | VisibilityChangeMask);
   XSetTransientForHint(theDisp, mb->mwin, mb->win);
 }
-  
+
 
 
 
@@ -908,15 +907,15 @@
 {
   /* draws a menu button in it's normal state.  (When it's actively being
      used (to select an item), all drawing is handled in MBTrack) */
-  
+
   int          x,y,i,r,x1,y1;
   unsigned int w,h;
-  
+
   r = 2;  /* amt of shadow */
   x = mb->x;  y = mb->y;  w = mb->w;  h = mb->h;
-  x1 = x + (int) w;  
+  x1 = x + (int) w;
   y1 = y + (int) h;
-  
+
   XSetForeground(theDisp, theGC, mb->bg);
   XFillRectangle(theDisp, mb->win, theGC, x+1, y+1, w-1, h-1);
 
@@ -940,12 +939,14 @@
     XSetBackground(theDisp, theGC, mb->bg);
     XCopyPlane(theDisp, mb->pix, mb->win, theGC, 0,0,
 	       (u_int) mb->pw, (u_int) mb->ph, x1,y1, 1L);
-    if (!mb->active) 
+    if (!mb->active)
       DimRect(mb->win, x1,y1, (u_int) mb->pw, (u_int) mb->ph, mb->bg);
   }
 
   else {                                    /* draw string centered in butt */
-    char *str, stbuf[256];
+    const char *str;
+    char       *tmp;
+    char        stbuf[256];
 
     if (mb->title) str = mb->title;
     else {  /* find first checked item, and show that as the title */
@@ -961,7 +962,7 @@
 
     /* truncate at TAB, if any */
     strcpy(stbuf, str);
-    if ((str = (char *) index(stbuf, '\t')) != NULL) *str = '\0';
+    if ((tmp = (char *) index(stbuf, '\t')) != NULL) *tmp = '\0';
     str = stbuf;
 
     x1 = CENTERX(mfinfo, x + w/2, str);
@@ -997,14 +998,14 @@
      MBUTT *mb;
 {
   /* returns index of first checked selection, or '-1' if nothing selected */
-  
+
   int i;
 
   if (!mb->hascheck) return -1;
 
   for (i=0; i<mb->nlist; i++)
     if (mb->flags[i]) return i;
-  
+
   return -1;
 }
 
@@ -1017,13 +1018,13 @@
   /* makes entry #n the selected entry (ie, the only one with a check mark)
      Does all redrawing.  Does nothing if entry #n already selected.
      Don't let it select 'dim' entries */
-  
+
   int i;
-  
+
   if (n<0 || n>mb->nlist) return;               /* # out of range */
   if (!mb->hascheck)      return;               /* shouldn't happen */
   if (mb->flags[n])       return;               /* already selected */
-  
+
   for (i=0; i<MAXMBLEN; i++) mb->flags[i] = 0;
 
   mb->flags[n] = 1;
@@ -1083,7 +1084,7 @@
     }
   }
   mwide += 8;                             /* extra room at edges */
-  
+
   /* make wider if any checked menu items */
   for (i=0; i<mb->nlist && !mb->flags[i]; i++);
   hascheck = (i<mb->nlist || mb->hascheck);
@@ -1091,7 +1092,7 @@
   if (hascheck && mb->title) mwide += 8;
 
   if (mwide < (mb->w+1)) mwide = mb->w+1; /* at least as wide as button */
-    
+
   mhigh = mb->nlist * LINEHIGH + 2 + extratop;
 
   mx = mb->x-1;  my = mb->y - 1;
@@ -1138,16 +1139,17 @@
   y = ASCENT + SPACING + extratop;
   for (i=0; i<mb->nlist; i++) {
     char txtstr[256], *tabstr;
+
     strcpy(txtstr, mb->list[i]);
     if ((tabstr = (char *) index(txtstr, '\t'))) {
       *tabstr = '\0';  tabstr++;
     }
 
     if (mb->flags[i]) {
-      XCopyArea(theDisp, mbchk, win, theGC, 0, 0, mb_chk_width, mb_chk_height, 
+      XCopyArea(theDisp, mbchk, win, theGC, 0, 0, mb_chk_width, mb_chk_height,
 		x - 10, y - 8);
     }
-    
+
     if (!strcmp(mb->list[i], MBSEP)) {
       mb->dim[i] = 1;    /* don't select this one */
       if (ctrlColor) {
@@ -1161,15 +1163,15 @@
 	XDrawLine(theDisp,win,theGC,4,y-(ASCENT/2)+1, mwide-5, y-(ASCENT/2)+1);
 	XSetForeground(theDisp, theGC, mb->fg);
       }
-      else 
+      else
 	XDrawLine(theDisp, win, theGC, 4, y-(ASCENT/2), mwide-5, y-(ASCENT/2));
     }
     else {
       DrawString(win, x, y, txtstr);
-      if (tabstr) 
+      if (tabstr)
 	DrawString(win, mwide - mtabwide - 4, y, tabstr);
 
-      if (mb->dim[i]) 
+      if (mb->dim[i])
 	DimRect(win, x, y-ASCENT, (u_int) mwide, (u_int) CHIGH, mb->bg);
       XSetForeground(theDisp, theGC, mb->fg);
     }
diff -ru xv-3.10a/xvcolor.c xv-3.10a-enhancements/xvcolor.c
--- xv-3.10a/xvcolor.c	1995-01-06 11:29:23.000000000 -0800
+++ xv-3.10a-enhancements/xvcolor.c	2007-05-12 13:55:36.000000000 -0700
@@ -52,7 +52,7 @@
      int   pwide, phigh, *pnumcols;
 {
   /* operates on 8-bit images.  sorts the colormap into 'best' order
-   * 'order' is the 'best' order to allocate the colors.  'trans' is a 
+   * 'order' is the 'best' order to allocate the colors.  'trans' is a
    * transformation to be done to pic, cpic, and epic (in PIC8 mode) to
    * compress the colormap
    */
@@ -67,22 +67,22 @@
   /* initialize histogram and compute it */
   for (i=0; i<256; i++) hist[i]=0;
   for (i=pwide*phigh, p=pic; i; i--, p++) hist[*p]++;
-  
+
   if (DEBUG>1) {
     fprintf(stderr,"%s: Desired colormap\n",cmd);
-    for (i=0; i<256; i++) 
+    for (i=0; i<256; i++)
       if (hist[i]) fprintf(stderr,"(%3d  %02x,%02x,%02x %d)\n",
 			   i,rmap[i],gmap[i],bmap[i], hist[i]);
     fprintf(stderr,"\n\n");
   }
-  
-  
+
+
   /* put the actually-used colors into the 'c' array in the order they occur
      also, while we're at it, calculate ncols, and close up gaps in
      colortable */
-  
+
   for (i=ncols=0; i<256; i++) {
-    if (hist[i]) { 
+    if (hist[i]) {
       rmap[ncols] = rmap[i];
       gmap[ncols] = gmap[i];
       bmap[ncols] = bmap[i];
@@ -104,8 +104,8 @@
   }
   xvbcopy((char *) &c[entry], (char *) &c1[0], sizeof(CMAPENT));
   c[entry].use = 0;   /* dealt with */
-  
-  
+
+
   /* sort rest of colormap.  Half of the entries are allocated on the
      basis of distance from already allocated colors, and half on the
      basis of usage.  (NB: 'taxicab' distance is used throughout this file.)
@@ -116,7 +116,7 @@
      To obtain O(n^2) performance, we keep each unselected color
      (in c[], with use>0) marked with the minimum distance to any of
      the selected colors (in c1[]).  Each time we select a color, we
-     can update the minimum distances in O(n) time. 
+     can update the minimum distances in O(n) time.
 
      mod by Tom Lane   Tom.Lane@g.gp.cs.cmu.edu */
 
@@ -134,8 +134,8 @@
       for (j=0, cj=c; j<ncols; j++,cj++) {
 	if (cj->use) {      /* this color has not been marked already */
 	  /* update mindist */
-          d = (cj->r - ckR)*(cj->r - ckR) + 
-	      (cj->g - ckG)*(cj->g - ckG) + 
+          d = (cj->r - ckR)*(cj->r - ckR) +
+	      (cj->g - ckG)*(cj->g - ckG) +
 	      (cj->b - ckB)*(cj->b - ckB);
           if (cj->mindist > d) cj->mindist = d;
 	  if (cj->mindist > mdist) { mdist = cj->mindist;  entry = j; }
@@ -148,8 +148,8 @@
       for (j=0, cj=c; j<ncols; j++,cj++) {
 	if (cj->use) {  /* this color has not been marked already */
 	  /* update mindist */
-          d = (cj->r - ckR)*(cj->r - ckR) + 
-	      (cj->g - ckG)*(cj->g - ckG) + 
+          d = (cj->r - ckR)*(cj->r - ckR) +
+	      (cj->g - ckG)*(cj->g - ckG) +
     	      (cj->b - ckB)*(cj->b - ckB);
           if (cj->mindist > d) cj->mindist = d;
 	  if (cj->use > mdist) { mdist = cj->use;  entry = j; }
@@ -162,18 +162,18 @@
     xvbcopy((char *) &c[entry], (char *) &c1[i], sizeof(CMAPENT));
     c[entry].use = 0;
   }
-  
+
 
   for (i=0; i<ncols; i++) order[i] = (byte) c1[i].oldindex;
 
   if (DEBUG>1) {
     fprintf(stderr,"%s: result of sorting colormap\n",cmd);
-    for (i=0; i<ncols; i++) 
+    for (i=0; i<ncols; i++)
       fprintf(stderr,"(%3d  %02x,%02x,%02x)     ",i,rmap[i],gmap[i],bmap[i]);
     fprintf(stderr,"\n\n");
-    
+
     fprintf(stderr,"%s: allocation order table\n",cmd);
-    for (i=0; i<ncols; i++) 
+    for (i=0; i<ncols; i++)
       fprintf(stderr,"order[%d] = -> %d\n", i, order[i]);
     fprintf(stderr,"\n");
   }
@@ -240,7 +240,7 @@
       SetISTR(ISTR_COLOR,"Using %s colormap.",
 	      (haveStdCmap == STD_111 ? "2x2x2" :
 	       haveStdCmap == STD_222 ? "4x4x4" :
-	       haveStdCmap == STD_232 ? "4x8x4" : 
+	       haveStdCmap == STD_232 ? "4x8x4" :
                haveStdCmap == STD_666 ? "6x6x6" : "8x8x4"));
 
       if (ncols>0) SetISTR(ISTR_COLOR2,stdCmapSuccess);
@@ -251,7 +251,7 @@
 
     for (i=0; i<numcols; i++) {
       int i332;
-      i332 = ((int)rMap[i]&0xe0) | (((int)gMap[i]&0xe0)>>3) | 
+      i332 = ((int)rMap[i]&0xe0) | (((int)gMap[i]&0xe0)>>3) |
 	     (((int)bMap[i]&0xc0)>>6);
 
       cols[i]  = stdcols[i332];
@@ -291,7 +291,7 @@
   }
 
   else {
-    for (i=0; i<nfcols; i++) 
+    for (i=0; i<nfcols; i++)
       xvFreeColors(theDisp, theCmap, &freecols[i], 1, 0L);
 
     nfcols = 0;
@@ -314,19 +314,19 @@
   unique = p2alloc = 0;
   rwthistime = 0;
 
-  /* FIRST PASS COLOR ALLOCATION:  
+  /* FIRST PASS COLOR ALLOCATION:
      for each color in the 'desired colormap', try to get it via
      xvAllocColor().  If for any reason it fails, mark that pixel
      'unallocated' and worry about it later.  Repeat. */
 
-  /* attempt to allocate first ncols entries in colormap 
+  /* attempt to allocate first ncols entries in colormap
      note: On displays with less than 8 bits per RGB gun, it's quite
      possible that different colors in the original picture will be
      mapped to the same color on the screen.  X does this for you
-     silently.  However, this is not-desirable for this application, 
+     silently.  However, this is not-desirable for this application,
      because when I say 'allocate me 32 colors' I want it to allocate
      32 different colors, not 32 instances of the same 4 shades... */
-  
+
 
   for (i=0; i<256; i++) failed[i] = 1;
 
@@ -334,7 +334,7 @@
 
   for (i=0; i<numcols && unique<ncols; i++) {
     c = colAllocOrder[i];
-    if (mono) { 
+    if (mono) {
       int intens = MONO(rMap[c], gMap[c], bMap[c]);
       defs[c].red = defs[c].green = defs[c].blue = intens<<8;
     }
@@ -346,8 +346,8 @@
 
     defs[c].flags = DoRed | DoGreen | DoBlue;
 
-    if (!(colorMapMode==CM_OWNCMAP && cmap==theCmap && CMAPVIS(theVisual)) 
-	&& xvAllocColor(theDisp,cmap,&defs[c])) { 
+    if (!(colorMapMode==CM_OWNCMAP && cmap==theCmap && CMAPVIS(theVisual))
+	&& xvAllocColor(theDisp,cmap,&defs[c])) {
       unsigned long pixel, *fcptr;
 
       pixel = cols[c] = defs[c].pixel;
@@ -355,7 +355,7 @@
       gdisp[c] = defs[c].green >> 8;
       bdisp[c] = defs[c].blue  >> 8;
       failed[c]= 0;
-      
+
       /* see if the newly allocated color is new and different */
       for (j=0, fcptr=freecols; j<nfcols && *fcptr!=pixel; j++,fcptr++);
       if (j==nfcols) unique++;
@@ -365,24 +365,24 @@
     }
 
     else {
-      /* the allocation failed.  If we want 'perfect' color, and we haven't 
+      /* the allocation failed.  If we want 'perfect' color, and we haven't
 	 already created our own colormap, we'll want to do so */
       if ((colorMapMode == CM_PERFECT || colorMapMode == CM_OWNCMAP)
 	  && !LocalCmap && CMAPVIS(theVisual)) {
 	LocalCmap = XCreateColormap(theDisp, vrootW, theVisual, AllocNone);
-	
+
 	if (LocalCmap) {  /* succeeded, presumably */
 	  /* free all colors that were allocated, and try again with the
 	     new colormap.  This is necessary because 'XCopyColormapAndFree()'
 	     has the unpleasant side effect of freeing up the various
 	     colors I need for the control panel, etc. */
 
-	  for (i=0; i<nfcols; i++) 
+	  for (i=0; i<nfcols; i++)
 	    xvFreeColors(theDisp, theCmap, &freecols[i], 1, 0L);
-	  
+
 	  if (mainW && !useroot) XSetWindowColormap(theDisp,mainW, LocalCmap);
 
-	  if (mainW && !useroot && cmapInGam) 
+	  if (mainW && !useroot && cmapInGam)
 	    XSetWindowColormap(theDisp,gamW, LocalCmap);
 	  cmap = LocalCmap;
 
@@ -402,9 +402,9 @@
       }
     }
   }  /* FIRST PASS */
-  
-  
-  
+
+
+
   if (nfcols==numcols) {
     if (numcols != unique)
       SetISTR(ISTR_COLOR,"Got all %d colors.  (%d unique)", numcols,
@@ -415,7 +415,7 @@
     SetISTR(ISTR_COLOR2,"");
     return;
   }
-  
+
 
 
   /* SECOND PASS COLOR ALLOCATION:
@@ -427,7 +427,7 @@
      is in the X colormap.  Try to allocate that color (read only).
      If that fails, the THIRD PASS will deal with it */
 
-  SetISTR(ISTR_COLOR,"Got %d of %d colors.  (%d unique)", 
+  SetISTR(ISTR_COLOR,"Got %d of %d colors.  (%d unique)",
 	  nfcols,numcols,unique);
 
   /* read entire colormap (or first 256 entries) into 'ctab' */
@@ -436,28 +436,28 @@
   if (dc>0) {  /* only do SECOND PASS if there IS a colormap to read */
     for (i=0; i<dc; i++) ctab[i].pixel = (unsigned long) i;
     XQueryColors(theDisp, cmap, ctab, dc);
-    
+
     for (i=0; i<numcols && unique<ncols; i++) {
       c = colAllocOrder[i];
-      
+
       if (failed[c]) {  /* an unallocated pixel */
 	int d, mdist, close;
 	int rd, gd, bd, ri, gi, bi;
-	
+
 	mdist = 1000000;   close = -1;
 	ri = rMap[c];  gi = gMap[c];  bi = bMap[c];
-	
+
 	for (j=0; j<dc; j++) {
 	  rd = ri - (ctab[j].red  >>8);
 	  gd = gi - (ctab[j].green>>8);
 	  bd = bi - (ctab[j].blue >>8);
-	  
+
 	  d = rd*rd + gd*gd + bd*bd;
 	  if (d<mdist) { mdist=d; close=j; }
 	}
-	
+
 	if (close<0) FatalError("This Can't Happen! (How reassuring.)");
-	if (xvAllocColor(theDisp, cmap, &ctab[close])) { 
+	if (xvAllocColor(theDisp, cmap, &ctab[close])) {
 	  xvbcopy((char *) &ctab[close], (char *) &defs[c], sizeof(XColor));
 	  failed[c]= 0;
 	  cols[c]  = ctab[close].pixel;
@@ -487,7 +487,7 @@
 
       mdist = 1000000;   close = -1;
       ri = rMap[c];  gi = gMap[c];  bi = bMap[c];
-      
+
       /* search the alloc'd colors */
       for (j=0; j<nfcols; j++) {
 	k = fc2pcol[j];
@@ -535,7 +535,7 @@
     unsigned long pmr[1], pix[1];
     c = colAllocOrder[i];
 
-    if (cellgroup[c]) {  
+    if (cellgroup[c]) {
       int n;
       /* this color is part of a group.  see if its group's
 	 been seen already, and if so, skip this */
@@ -548,11 +548,11 @@
       }
     }
 
-    if (!(colorMapMode==CM_OWNCMAP && cmap==theCmap && CMAPVIS(theVisual)) && 
+    if (!(colorMapMode==CM_OWNCMAP && cmap==theCmap && CMAPVIS(theVisual)) &&
 	XAllocColorCells(theDisp, cmap, False, pmr, 0, pix, 1)) {
       defs[c].pixel = cols[c] = pix[0];
       failed[c] = 0;
-      if (mono) { 
+      if (mono) {
 	int intens = MONO(rMap[c], gMap[c], bMap[c]);
 	defs[c].red = defs[c].green = defs[c].blue = intens<<8;
       }
@@ -573,20 +573,20 @@
     }
 
     else {
-      if ((colorMapMode == CM_PERFECT || colorMapMode == CM_OWNCMAP) 
+      if ((colorMapMode == CM_PERFECT || colorMapMode == CM_OWNCMAP)
 	  && !LocalCmap && CMAPVIS(theVisual)) {
 	LocalCmap = XCreateColormap(theDisp, vrootW, theVisual, AllocNone);
-	
+
 	/* free all colors that were allocated, and try again with the
 	   new colormap.  This is necessary because 'XCopyColormapAndFree()'
 	   has the unpleasant side effect of freeing up the various
 	   colors I need for the control panel, etc. */
 
-	for (i=0; i<nfcols; i++) 
+	for (i=0; i<nfcols; i++)
 	  xvFreeColors(theDisp, theCmap, &freecols[i], 1, 0L);
-	
+
 	if (mainW && !useroot) XSetWindowColormap(theDisp,mainW, LocalCmap);
-	if (mainW && !useroot && cmapInGam) 
+	if (mainW && !useroot && cmapInGam)
 	  XSetWindowColormap(theDisp,gamW, LocalCmap);
 	cmap = LocalCmap;
 
@@ -608,12 +608,12 @@
   }
 
   else {
-    /* Failed to allocate all colors in picture.  Map remaining desired 
+    /* Failed to allocate all colors in picture.  Map remaining desired
        colors into closest allocated desired colors */
 
       if (nfcols==0 && !LocalCmap) {
-	char tstr[128], *tmp,
-	    *foo = "No r/w cells available.  Using r/o color.";
+	char tstr[128], *tmp;
+	const char *foo = "No r/w cells available.  Using r/o color.";
 
 	tmp = GetISTR(ISTR_WARNING);
 	if (strlen(tmp) > (size_t) 0) sprintf(tstr, "%s  %s", tmp, foo);
@@ -623,7 +623,7 @@
 	allocROColors();
 	return;
       }
-	
+
       SetISTR(ISTR_COLOR,"Got %d of %d colors.",  nfcols,numcols);
 
       for (i=0; i<numcols; i++) {
@@ -662,7 +662,7 @@
     j = fc2pcol[i];
     defs[j].pixel = freecols[i];
 
-    if (mono) { 
+    if (mono) {
       int intens = MONO(rMap[j], gMap[j], bMap[j]);
       defs[j].red = defs[j].green = defs[j].blue = intens<<8;
     }
@@ -706,9 +706,9 @@
   if (theVisual->class == TrueColor || theVisual->class == DirectColor) {
     unsigned long r, g, b, rmask, gmask, bmask, origr, origg, origb;
     int rshift, gshift, bshift;
-    
-    /* shift r,g,b so that high bit of 16-bit color specification is 
-     * aligned with high bit of r,g,b-mask in visual, 
+
+    /* shift r,g,b so that high bit of 16-bit color specification is
+     * aligned with high bit of r,g,b-mask in visual,
      * AND each component with its mask,
      * and OR the three components together
      */
@@ -781,7 +781,7 @@
 	      "         mask=%04lx,%04lx,%04lx  pix=%08lx\n",
 	      rmask, gmask, bmask, cdef->pixel);
     }
-    
+
     return 1;
   }
   else {
@@ -811,7 +811,7 @@
 {
   int i, j;
 
-  /* if regroup is set, we *must* do a full realloc, as the cols[] array 
+  /* if regroup is set, we *must* do a full realloc, as the cols[] array
      isn't correct anymore.  (cell groupings changed) */
 
   ApplyECctrls();  /* set {r,g,b}cmap[editColor] based on dial settings */
@@ -830,16 +830,16 @@
     }
   }
 
-    
+
   /* do something clever if we're using R/W color and this colorcell isn't
      shared */
 
   if (!regroup && allocMode==AM_READWRITE && rwthistime) {
     /* let's try to be clever */
-    /* determine if the editColor cell is unique, or shared (among 
+    /* determine if the editColor cell is unique, or shared (among
        non-group members, that is) */
 
-    for (i=j=0; i<numcols; i++) 
+    for (i=j=0; i<numcols; i++)
       if (rwpc2pc[i] == rwpc2pc[editColor]) j++;
 
     /* if this is a group, subtract off the non-this-one pixels from group */
@@ -901,7 +901,7 @@
   }
 
   /* shift 0..i-1 down one position */
-  xvbcopy((char *) colAllocOrder, (char *) colAllocOrder+1, 
+  xvbcopy((char *) colAllocOrder, (char *) colAllocOrder+1,
 	  i * sizeof(colAllocOrder[0]));
   colAllocOrder[0] = editColor;
 }
@@ -930,9 +930,9 @@
    *   stdfreecols[256]    - list of colors to free on exit
    *   stdnfcols           - # of colors to free
    *
-   * possibly modifies browR, browG, browB, and browcols arrays 
+   * possibly modifies browR, browG, browB, and browcols arrays
    *     (if !browPerfect)
-   */       
+   */
 
   /* returns '1' if the colors were reallocated, '0' otherwise */
 
@@ -946,18 +946,18 @@
 
   /* note:
    *   if (ncols==0) (ie, we're either on, or emulating a b/w display),
-   *   build std*[], std*disp[], colormaps, but don't actually 
+   *   build std*[], std*disp[], colormaps, but don't actually
    *   allocate any colors.
    */
 
-  int i,j,r,g,b, desMode, screwed;
+  int i, r,g,b, desMode, screwed;
   XColor def;
   byte rmap[256],gmap[256],bmap[256],order[256];
   unsigned long descols[256];
   int des2got[256], failed[256];
   int maplen, exactCnt, nearCnt;
-  
-  
+
+
   /* generate stdr,stdg,stdb cmap.  Same in all cases */
   for (r=0, i=0; r<8; r++)
     for (g=0; g<8; g++)
@@ -966,10 +966,10 @@
 	stdg[i] = (g*255)/7;
 	stdb[i] = (b*255)/3;
       }
-  
-  
+
+
   /* determine what size cmap we should build */
-  if (theVisual->class == TrueColor || 
+  if (theVisual->class == TrueColor ||
       theVisual->class == DirectColor) desMode = STD_332;
   else if (colorMapMode == CM_STDCMAP) desMode = STD_232;
   else desMode = STD_222;
@@ -983,9 +983,9 @@
   }
 
 
-  if (DEBUG) fprintf(stderr,"MakeStdCmaps: have=%d, des=%d, ncols=%d\n", 
+  if (DEBUG) fprintf(stderr,"MakeStdCmaps: have=%d, des=%d, ncols=%d\n",
 		     haveStdCmap, desMode, ncols);
-  
+
   if (haveStdCmap != STD_NONE && haveStdCmap == desMode) return 0;
   freeStdCmaps();
 
@@ -997,7 +997,7 @@
   for (i=0; i<256; i++) des2got[i] = i;
   exactCnt = nearCnt = 0;
 
-  
+
   if (desMode == STD_111) {   /* try to alloc 8 colors */
     /* generate a 1/1/1 desired colormap */
     maplen = 8;
@@ -1009,7 +1009,7 @@
 	  bmap[i] = (b*255);
 	}
   }
-  
+
   else if (desMode == STD_222) {   /* try to alloc 64 colors */
     /* generate a 2/2/2 desired colormap */
     maplen = 64;
@@ -1021,7 +1021,7 @@
 	  bmap[i] = (b*255)/3;
 	}
   }
-  
+
   else if (desMode == STD_232) {   /* try to alloc 128 colors */
     /* generate a 2/3/2 desired colormap */
     maplen = 128;
@@ -1033,7 +1033,7 @@
 	  bmap[i] = (b*255)/3;
 	}
   }
-  
+
   else if (desMode == STD_666) {   /* try to alloc 216 colors */
     /* generate a 6*6*6 desired colormap */
     maplen = 216;
@@ -1045,14 +1045,14 @@
 	  bmap[i] = (b*255)/5;
 	}
   }
-  
+
   else {   /* desMode == STD_332 */
     maplen = 256;
     for (i=0; i<maplen; i++) {
       rmap[i] = stdr[i];  gmap[i] = stdg[i];  bmap[i] = stdb[i];
     }
   }
-  
+
 
   /* sort the colors according to the diversity algorithm... */
   diverseOrder(rmap,gmap,bmap,maplen,order);
@@ -1072,7 +1072,7 @@
       def.red   = rmap[order[i]] << 8;
       def.green = gmap[order[i]] << 8;
       def.blue  = bmap[order[i]] << 8;
-      
+
       def.flags = DoRed | DoGreen | DoBlue;
 
       if (xvAllocColor(theDisp, theCmap, &def)) {  /* success */
@@ -1090,34 +1090,34 @@
 
     if (numgot != maplen) {
       /* PHASE 2:  find 'close' colors in colormap, try to alloc those */
-      
+
       /* read entire colormap (or first 256 entries) into 'ctab' */
       dc = (ncells<256) ? ncells : 256;
       if (dc>0) {
 	for (i=0; i<dc; i++) ctab[i].pixel = (unsigned long) i;
 	XQueryColors(theDisp, theCmap, ctab, dc);
-	
+
 	for (i=0; i<maplen; i++) {
 	  if (failed[i]) {
-	    
+
 	    /* find closest color in colormap, and try to alloc it */
 	    mind = 1000000;   /* greater than 3 * (256^2) */
 	    for (j=0,num = -1; j<dc; j++) {
 	      rd = rmap[i] - (ctab[j].red  >>8);
 	      gd = gmap[i] - (ctab[j].green>>8);
 	      bd = bmap[i] - (ctab[j].blue >>8);
-	      
+
 	      d = CDIST(rd, gd, bd);
 	      if (d<mind) { mind = d;  num = j; }
 	    }
-	    
+
 	    if (num < 0) screwed = 1;
 	    else if (xvAllocColor(theDisp, theCmap, &ctab[num])) {  /*success*/
 	      des2got[i] = i;
 	      descols[i] = ctab[num].pixel;
 	      failed[i]  = 0;
-	      nearCnt++; 
-	      /* for (j=0; j<stdnfcols && stdfreecols[j]!=ctab[num].pixel; 
+	      nearCnt++;
+	      /* for (j=0; j<stdnfcols && stdfreecols[j]!=ctab[num].pixel;
 		 j++); */
 	      stdfreecols[stdnfcols++] = ctab[num].pixel;
 	    }
@@ -1125,12 +1125,12 @@
 	}
       }
     }
-      
-    /* PHASE 3:  map remaining unallocated colors into closest we got */  
-    
+
+    /* PHASE 3:  map remaining unallocated colors into closest we got */
+
     for (i=0; i<maplen; i++) {
       if (failed[i]) {
-	
+
 	/* find closest alloc'd color */
 	mind = 1000000;   /* greater than 3 * (256^2) */
 	for (j=0,num=0; j<maplen; j++) {
@@ -1139,7 +1139,7 @@
 	    if (d<mind) { mind = d;  num = j; }
 	  }
 	}
-	
+
 	if (failed[num]) screwed = 1;
 	else {
 	  descols[i] = descols[num];
@@ -1151,8 +1151,8 @@
   }
 
 
-  /* at this point, we have 'descols', a maplen long array of 
-     X pixel values that maps 1/1/1, 2/2/2, 6*6*6, or 3/3/2 values 
+  /* at this point, we have 'descols', a maplen long array of
+     X pixel values that maps 1/1/1, 2/2/2, 6*6*6, or 3/3/2 values
      into an X pixel value */
 
   /* build stdcols and stdrdisp,stdgdisp,stdbdisp colormap */
@@ -1170,7 +1170,7 @@
 
 	  stdcols[i332] = descols[des2got[i111]];
 	}
-  } 
+  }
 
   else if (desMode == STD_222) {
     for (r=0; r<8; r++)
@@ -1186,7 +1186,7 @@
 
 	  stdcols[i332] = descols[des2got[i222]];
 	}
-  } 
+  }
 
   else if (desMode == STD_232) {
     for (r=0; r<8; r++)
@@ -1201,7 +1201,7 @@
 	  stdbdisp[i332] = bmap[des2got[i232]];
 	  stdcols[i332]  = descols[des2got[i232]];
 	}
-  } 
+  }
 
   else if (desMode == STD_666) {
     for (r=0,i=0; r<8; r++)
@@ -1221,7 +1221,7 @@
 
 	  stdcols[i]  = descols[des2got[i666]];
 	}
-  } 
+  }
 
   else {  /* desMode == STD_332 */
     for (i=0; i<256; i++) {
@@ -1249,22 +1249,22 @@
   if (DEBUG > 1) {
     fprintf(stderr,"MakeStdCmaps:  ncols=%d  maplen=%d\n", ncols, maplen);
     fprintf(stderr,"  std*[]= ");
-    for (i=0; i<256; i++) 
+    for (i=0; i<256; i++)
       fprintf(stderr,"%02x,%02x,%02x  ",stdr[i],stdg[i],stdb[i]);
     fprintf(stderr,"\n\n");
 
     fprintf(stderr,"  disp[]= ");
-    for (i=0; i<256; i++) 
+    for (i=0; i<256; i++)
       fprintf(stderr,"%02x,%02x,%02x  ",stdrdisp[i],stdgdisp[i],stdbdisp[i]);
     fprintf(stderr,"\n\n");
 
     fprintf(stderr,"  stdcols[]= ");
-    for (i=0; i<256; i++) 
+    for (i=0; i<256; i++)
       fprintf(stderr,"%02lx ",stdcols[i]);
     fprintf(stderr,"\n\n");
 
     fprintf(stderr,"  stdfreecols[%d] = ", stdnfcols);
-    for (i=0; i<stdnfcols; i++) 
+    for (i=0; i<stdnfcols; i++)
       fprintf(stderr,"%02lx ",stdfreecols[i]);
     fprintf(stderr,"\n\n");
   }
@@ -1272,8 +1272,8 @@
   if (exactCnt == maplen)
     sprintf(stdCmapSuccess, "Got all %d colors.", exactCnt);
   else {
-    if (nearCnt>0) 
-      sprintf(stdCmapSuccess, "Got %d out of %d colors.  (%d close color%s)", 
+    if (nearCnt>0)
+      sprintf(stdCmapSuccess, "Got %d out of %d colors.  (%d close color%s)",
 	      exactCnt, maplen, nearCnt, (nearCnt>1) ? "s" : "");
     else
       sprintf(stdCmapSuccess, "Got %d out of %d colors.", exactCnt, maplen);
@@ -1292,11 +1292,11 @@
   /* This function should only be called once, at the start of the program.
    *
    * produces many things:
-   *   browR,browG,browB[256] 
+   *   browR,browG,browB[256]
    *                       - a 3/3/2 colormap used by genIcon
    *   browcols[256]       - maps 3/3/2 values into X colors
    *   browCmap            - local cmap used in browse window, if browPerfect
-   */       
+   */
 
   int    i,j,r,g,b, screwed, num, exactCnt, nearCnt;
   XColor def;
@@ -1306,8 +1306,8 @@
   long   d, mind;
 
 
-  if (DEBUG) 
-    fprintf(stderr,"MakeBrowCmap:  perfect = %d, ncols = %d\n", 
+  if (DEBUG)
+    fprintf(stderr,"MakeBrowCmap:  perfect = %d, ncols = %d\n",
 	    browPerfect, ncols);
 
   if (ncols == 0 || !CMAPVIS(theVisual)) browPerfect = 0;
@@ -1350,7 +1350,7 @@
     def.red   = rmap[order[i]] << 8;
     def.green = gmap[order[i]] << 8;
     def.blue  = bmap[order[i]] << 8;
-      
+
     def.flags = DoRed | DoGreen | DoBlue;
 
     if (xvAllocColor(theDisp, browCmap, &def)) {  /* success */
@@ -1358,14 +1358,14 @@
       descols[order[i]] = def.pixel;
 
       if (DEBUG>1)
-	fprintf(stderr,"makebrowcmap: Phase 1: Alloc %x,%x,%x succeeded!\n", 
+	fprintf(stderr,"makebrowcmap: Phase 1: Alloc %x,%x,%x succeeded!\n",
 		rmap[order[i]], gmap[order[i]], bmap[order[i]]);
     }
     else failed[order[i]] = 1;
   }
 
-    
-  /* PHASE 2:  map remaining unallocated colors into closest we got */  
+
+  /* PHASE 2:  map remaining unallocated colors into closest we got */
 
   for (i=0; i<256; i++) {
     if (failed[i]) {
@@ -1377,9 +1377,9 @@
 	  if (d<mind) { mind = d;  num = j; }
 	}
       }
-	  
+
       if (DEBUG>1)
-	fprintf(stderr,"makebrowcmap: closest to %x,%x,%x = %x,%x,%x\n", 
+	fprintf(stderr,"makebrowcmap: closest to %x,%x,%x = %x,%x,%x\n",
 		rmap[i],gmap[i],bmap[i], rmap[num], gmap[num], bmap[num]);
 
       if (failed[num]) screwed = 1;
@@ -1406,7 +1406,7 @@
      byte *rmap, *gmap, *bmap, *order;
      int   maplen;
 {
-  /* takes a colormap (maxlen 256) and produces an order array that 
+  /* takes a colormap (maxlen 256) and produces an order array that
      contains the most-diverse order for allocating these colors */
 
   int dist[256], i, pick, maxv, ocnt, d;
@@ -1422,7 +1422,7 @@
 
   ocnt = 0;
   order[ocnt++] = pick;
-  
+
   /* init dist[] array */
   for (i=0; i<maplen; i++) dist[i] = 1000000;
 
@@ -1509,14 +1509,14 @@
   else if (cmode == CM_NORMAL) {
     if (novbrowse || browPerfect || haveStdCmap != iconCmapSize)
       freeStdCmaps();
-    
+
     /* if using browser, and killed stdcmap, make icon stdcmap */
     if (!novbrowse && !browPerfect && haveStdCmap == STD_NONE) {
       if (MakeStdCmaps() && anyBrowUp && CMAPVIS(theVisual))
 	RegenBrowseIcons();
     }
   }
-  
+
   else if (cmode == CM_PERFECT) { }
   else if (cmode == CM_OWNCMAP) { }
 
@@ -1540,7 +1540,7 @@
     SetEpicMode();
     if (genepic) GenerateEpic(eWIDE, eHIGH);
   }
-  else { 
+  else {
     if (oldmode == CM_STDCMAP && cmode != CM_STDCMAP && epicMode != EM_RAW) {
       /* just left STDCMAP mode.  Switch to using 'RAW' */
       epicMode = EM_RAW;
diff -ru xv-3.10a/xvctrl.c xv-3.10a-enhancements/xvctrl.c
--- xv-3.10a/xvctrl.c	1994-12-22 14:34:41.000000000 -0800
+++ xv-3.10a-enhancements/xvctrl.c	2007-05-13 14:11:33.000000000 -0700
@@ -1,4 +1,4 @@
-/* 
+/*
  * xvctrl.c - Control box handling functions
  *
  * callable functions:
@@ -9,7 +9,7 @@
  *   RedrawCtrl(x,y,w,h)    -  called by 'expose' events
  *   ClickCtrl(x,y)
  *   DrawCtrlStr()          -  called to redraw 'ISTR_INFO' string in ctrlW
- *   ScrollToCurrent()      -  called when list selection is changed 
+ *   ScrollToCurrent()      -  called when list selection is changed
  *
  *   LSCreate()             -  creates a listbox
  *   LSRedraw()             -  redraws 'namelist' box
@@ -49,7 +49,10 @@
 #include "bits/uicon"
 #include "bits/oicon1"
 #include "bits/oicon2"
-#include "bits/icon"
+#ifdef REGSTR
+#  define OMIT_ICON_BITS
+#  include "bits/icon"
+#endif
 
 #define CTRLWIDE 440               /* (fixed) size of control window */
 #define CTRLHIGH 348 /* 379 */
@@ -80,73 +83,74 @@
    in xv.h */
 
 
-static char *dispMList[] = { "Raw\tr", 
-			     "Dithered\td",
-			     "Smooth\ts",
-			     MBSEP,
-			     "Read/Write Colors",
-			     MBSEP,
-			     "Normal Colors",
-			     "Perfect Colors",
-			     "Use Own Colormap",
-			     "Use Std. Colormap" };
-
-static char *rootMList[] = { "Window", 
-			     "Root: tiled",
-			     "Root: integer tiled",
-			     "Root: mirrored",
-			     "Root: integer mirrored",
-			     "Root: center tiled",
-			     "Root: centered",
-			     "Root: centered, warp",
-			     "Root: centered, brick",
-    		             "Root: symmetrical tiled",
-			     "Root: symmetrical mirrored" };
-
-static char *conv24MList[] = { "8-bit mode\t\2448",
-			       "24-bit mode\t\2448",
-			       MBSEP,
-			       "Lock current mode",
-			       MBSEP,
-                               "Quick 24->8",
-			       "Slow 24->8",
-			       "Best 24->8" };
-
-static char *algMList[]    = { "Undo All\t\244u",
-			       MBSEP,
- 			       "Blur...\t\244b",
-			       "Sharpen...\t\244s",
-			       "Edge Detect\t\244e",
-			       "Emboss\t\244m",
-			       "Oil Painting\t\244o",
-			       "Blend\t\244B",
-			       "Copy Rotate...\t\244t",
-			       "Clear Rotate...\t\244T",
-			       "Pixelize...\t\244p",
-			       "Spread...\t\244S",
-			       "DeSpeckle...\t\244k"};
-
-static char *sizeMList[]   = { "Normal\tn",
-			       "Max Size\tm",
-			       "Maxpect\tM",
-			       "Double Size\t>",
-			       "Half Size\t<",
-			       "10% Larger\t.",
-			       "10% Smaller\t,",
-			       MBSEP,
-			       "Set Size\tS",
-			       "Re-Aspect\ta",
-			       "4x3\t4",
-			       "Int. Expand\tI" };
-
-static char *windowMList[] = { "Visual Schnauzer\t^v",
-			       "Color Editor\te",
-			       "Image Info\ti",
-			       "Image Comments\t^c",
-			       "Text View\t^t",
-			       MBSEP,
-			       "About XV\t^a",
-			       "XV Keyboard Help"};
+static const char *dispMList[] = { "Raw\tr",
+				   "Dithered\td",
+				   "Smooth\ts",
+				   MBSEP,
+				   "Read/Write Colors",
+				   MBSEP,
+				   "Normal Colors",
+				   "Perfect Colors",
+				   "Use Own Colormap",
+				   "Use Std. Colormap" };
+
+static const char *rootMList[] = { "Window",
+				   "Root: tiled",
+				   "Root: integer tiled",
+				   "Root: mirrored",
+				   "Root: integer mirrored",
+				   "Root: center tiled",
+				   "Root: centered",
+				   "Root: centered, warp",
+				   "Root: centered, brick",
+				   "Root: symmetrical tiled",
+				   "Root: symmetrical mirrored",
+				   "Root: upper left corner" };
+
+static const char *conv24MList[] = { "8-bit mode\t\2448",
+				     "24-bit mode\t\2448",
+				     MBSEP,
+				     "Lock current mode",
+				     MBSEP,
+				     "Quick 24->8",
+				     "Slow 24->8",
+				     "Best 24->8" };
+
+static const char *algMList[] = { "Undo All\t\244u",
+				  MBSEP,
+				  "Blur...\t\244b",
+				  "Sharpen...\t\244s",
+				  "Edge Detect\t\244e",
+				  "Emboss\t\244m",
+				  "Oil Painting\t\244o",
+				  "Blend\t\244B",
+				  "Copy Rotate...\t\244t",
+				  "Clear Rotate...\t\244T",
+				  "Pixelize...\t\244p",
+				  "Spread...\t\244S",
+				  "DeSpeckle...\t\244k"};
+
+static const char *sizeMList[] = { "Normal\tn",
+				   "Max Size\tm",
+				   "Maxpect\tM",
+				   "Double Size\t>",
+				   "Half Size\t<",
+				   "10% Larger\t.",
+				   "10% Smaller\t,",
+				   MBSEP,
+				   "Set Size\tS",
+				   "Re-Aspect\ta",
+				   "4x3\t4",
+				   "Int. Expand\tI" };
+
+static const char *windowMList[] = { "Visual Schnauzer\t^v",
+				     "Color Editor\te",
+				     "Image Info\ti",
+				     "Image Comments\t^c",
+				     "Text View\t^t",
+				     MBSEP,
+				     "About XV\t^a",
+				     "XV Keyboard Help"};
 
 
 
@@ -157,14 +161,14 @@
 
 /***************************************************/
 void CreateCtrl(geom)
-     char *geom;
+     const char *geom;
 {
-  int i, listh, topskip;
+  int listh, topskip;
   double skip;
   XSetWindowAttributes xswa;
   Pixmap oicon1Pix, oicon2Pix;
 
-  ctrlW = CreateWindow("xv controls", "XVcontrols", geom, 
+  ctrlW = CreateWindow("xv controls", "XVcontrols", geom,
 		       CTRLWIDE, CTRLHIGH, infofg, infobg, 0);
   if (!ctrlW) FatalError("can't create controls window!");
 
@@ -205,10 +209,10 @@
   oicon2Pix = MakePix1(ctrlW, oicon2_bits,  oicon2_width,  oicon2_height);
 
   if (!grayTile  || !dimStip  || !fifoPix   || !chrPix    || !dirPix    ||
-      !blkPix    || !lnkPix   || !regPix    || !rotlPix   || !fliphPix  || 
+      !blkPix    || !lnkPix   || !regPix    || !rotlPix   || !fliphPix  ||
       !flipvPix  || !p10Pix   || !m10Pix    || !cutPix    || !copyPix   ||
       !pastePix  || !clearPix || !uiconPix  || !oiconPix  || !oicon1Pix ||
-      !oicon2Pix || !padPix   || !annotPix) 
+      !oicon2Pix || !padPix   || !annotPix)
     FatalError("unable to create all pixmaps in CreateCtrl()\n");
 
 
@@ -226,7 +230,7 @@
   XFreePixmap(theDisp, oicon1Pix);
   XFreePixmap(theDisp, oicon2Pix);
 
-  
+
 
   if (ctrlColor) XSetWindowBackground(theDisp, ctrlW, locol);
             else XSetWindowBackgroundPixmap(theDisp, ctrlW, grayTile);
@@ -234,7 +238,7 @@
   listh = LINEHIGH * NLINES;
 
   LSCreate(&nList, ctrlW, 5, 52, (CTRLWIDE-BUTTW-18),
-	   LINEHIGH*NLINES, NLINES, dispnames, numnames, 
+	   LINEHIGH*NLINES, NLINES, dispnames, numnames,
 	   infofg, infobg, hicol, locol, RedrawNList, 0, 0);
   nList.selected = 0;  /* default to first name selected */
 
@@ -245,8 +249,8 @@
 
   topskip = nList.y;
   skip =  ((double) (nList.h - (CHIGH+5))) / 6.0;
-  if (skip > SBUTTH+8) {  
-    skip = SBUTTH + 7;  
+  if (skip > SBUTTH+8) {
+    skip = SBUTTH + 7;
     topskip = nList.y + (nList.h - (6*skip + (CHIGH+5))) / 2;
   }
 
@@ -258,7 +262,7 @@
 #define R_BY3 (topskip + (int)(3*skip))
 #define R_BY4 (topskip + (int)(4*skip))
 #define R_BY5 (topskip + (int)(5*skip))
-  
+
   BTCreate(&but[BNEXT],    ctrlW, R_BX0, R_BY0, R_BW1, SBUTTH, "Next",   BCLS);
   BTCreate(&but[BPREV],    ctrlW, R_BX0, R_BY1, R_BW1, SBUTTH, "Prev",   BCLS);
   BTCreate(&but[BLOAD],    ctrlW, R_BX0, R_BY2, R_BW1, SBUTTH, "Load",   BCLS);
@@ -309,7 +313,7 @@
   BTCreate(&but[BABOUT],  ctrlW,BX4,  BY1,BUTTW,BUTTH,"About XV",BCLS);
   BTCreate(&but[BQUIT],   ctrlW,BX5,  BY1,BUTTW,BUTTH,"Quit",    BCLS);
 
-  BTCreate(&but[BXV],     ctrlW,5,5, 100, (u_int) nList.y - 5 - 2 - 5, 
+  BTCreate(&but[BXV],     ctrlW,5,5, 100, (u_int) nList.y - 5 - 2 - 5,
 	   "", BCLS);
 
   SetButtPix(&but[BCOPY],  copyPix,  copy_width,   copy_height);
@@ -329,7 +333,7 @@
   if (ctrlColor) {
     SetButtPix(&but[BXV], oiconPix, oicon1_width,  oicon1_height);
     but[BXV].colorpix = 1;
-  } 
+  }
   else SetButtPix(&but[BXV], iconPix, icon_width,  icon_height);
 #else
   SetButtPix(&but[BXV], uiconPix, uicon_width,  uicon_height);
@@ -338,21 +342,21 @@
   XMapSubwindows(theDisp, ctrlW);
 
 
-  /* have to create menu buttons after XMapSubWindows, as we *don't* want 
+  /* have to create menu buttons after XMapSubWindows, as we *don't* want
      the popup menus mapped */
 
-  MBCreate(&dispMB,   ctrlW, CTRLWIDE - 8 - 112 - 2*(112+2), 5,112,19, 
+  MBCreate(&dispMB,   ctrlW, CTRLWIDE - 8 - 112 - 2*(112+2), 5,112,19,
 	   "Display",    dispMList,   DMB_MAX,    BCLS);
-  MBCreate(&conv24MB, ctrlW, CTRLWIDE - 8 - 112 - (112+2),   5,112,19, 
+  MBCreate(&conv24MB, ctrlW, CTRLWIDE - 8 - 112 - (112+2),   5,112,19,
 	   "24/8 Bit",   conv24MList, CONV24_MAX, BCLS);
-  MBCreate(&algMB,    ctrlW, CTRLWIDE - 8 - 112,             5,112,19, 
+  MBCreate(&algMB,    ctrlW, CTRLWIDE - 8 - 112,             5,112,19,
 	   "Algorithms", algMList,    ALG_MAX,    BCLS);
 
-  MBCreate(&rootMB,   ctrlW, CTRLWIDE - 8 - 112 - 2*(112+2), 5+21,112,19, 
+  MBCreate(&rootMB,   ctrlW, CTRLWIDE - 8 - 112 - 2*(112+2), 5+21,112,19,
 	   "Root",       rootMList,   RMB_MAX,    BCLS);
-  MBCreate(&windowMB, ctrlW, CTRLWIDE - 8 - 112 - (112+2),   5+21,112,19, 
+  MBCreate(&windowMB, ctrlW, CTRLWIDE - 8 - 112 - (112+2),   5+21,112,19,
 	   "Windows",    windowMList, WMB_MAX,    BCLS);
-  MBCreate(&sizeMB,   ctrlW, CTRLWIDE - 8 - 112,             5+21,112,19, 
+  MBCreate(&sizeMB,   ctrlW, CTRLWIDE - 8 - 112,             5+21,112,19,
 	   "Image Size", sizeMList,   SZMB_MAX,   BCLS);
 
 
@@ -395,7 +399,7 @@
      byte *bits;
      int   w,h;
 {
-  return XCreatePixmapFromBitmapData(theDisp, win, (char *) bits, 
+  return XCreatePixmapFromBitmapData(theDisp, win, (char *) bits,
 				     (u_int) w, (u_int) h, 1L,0L,1);
 }
 
@@ -404,7 +408,7 @@
 void CtrlBox(vis)
 int vis;
 {
-  if (vis) XMapRaised(theDisp, ctrlW);  
+  if (vis) XMapRaised(theDisp, ctrlW);
   else     XUnmapWindow(theDisp, ctrlW);
 
   ctrlUp = vis;
@@ -416,7 +420,6 @@
 int x,y,w,h;
 {
   int i;
-  XRectangle xr;
 
   RANGE(w, 0, CTRLWIDE);
   RANGE(h, 0, CTRLHIGH);
@@ -452,7 +455,7 @@
 /***************************************************/
 void DrawCtrlNumFiles()
 {
-  int x,y,w,h;
+  int x,y,w;
   char foo[40];
 
   x  = but[BNEXT].x;
@@ -463,14 +466,14 @@
   XSetBackground(theDisp, theGC, infobg);
 
   sprintf(foo, "%d file%s", numnames, (numnames==1) ? "" : "s");
-    
+
   XSetForeground(theDisp, theGC, infobg);
   XFillRectangle(theDisp,ctrlW, theGC, x+1,y+1, (u_int) w-1, (u_int) CHIGH+5);
 
   XSetForeground(theDisp,theGC,infofg);
   XDrawRectangle(theDisp,ctrlW, theGC, x,y,     (u_int) w,   (u_int) CHIGH+6);
 
-  Draw3dRect(ctrlW, x+1,y+1,                    (u_int) w-2, (u_int) CHIGH+4, 
+  Draw3dRect(ctrlW, x+1,y+1,                    (u_int) w-2, (u_int) CHIGH+4,
 	     R3D_IN, 2, hicol, locol, infobg);
 
   XSetForeground(theDisp,theGC,infofg);
@@ -489,7 +492,7 @@
   st1 = GetISTR(ISTR_WARNING);
 
   XSetForeground(theDisp, theGC, infobg);
-  XFillRectangle(theDisp, ctrlW, theGC, 0, y+1, 
+  XFillRectangle(theDisp, ctrlW, theGC, 0, y+1,
 		 CTRLWIDE, (u_int)((CHIGH+4)*2+1));
 
   XSetForeground(theDisp, theGC, infofg);
@@ -501,7 +504,7 @@
     XSetForeground(theDisp, theGC, locol);
     XDrawLine(theDisp, ctrlW, theGC, 0, y+1,   CTRLWIDE, y+1);
     XDrawLine(theDisp, ctrlW, theGC, 0, y+CHIGH+5, CTRLWIDE, y+CHIGH+5);
-    XDrawLine(theDisp, ctrlW, theGC, 0, y+(CHIGH+4)*2+1, 
+    XDrawLine(theDisp, ctrlW, theGC, 0, y+(CHIGH+4)*2+1,
 	      CTRLWIDE, y+(CHIGH+4)*2+1);
   }
 
@@ -542,16 +545,16 @@
 void ScrollToCurrent(lst)
 LIST *lst;
 {
-  /* called when selected item on list is changed.  Makes the selected 
+  /* called when selected item on list is changed.  Makes the selected
      item visible.  If it already is, nothing happens.  Otherwise, it
-     attempts to scroll so that the selection appears in the middle of 
+     attempts to scroll so that the selection appears in the middle of
      the list window */
 
   int halfway;
 
   if (lst->selected < 0) return;  /* no selection, do nothing */
 
-  if (lst->selected > lst->scrl.val && 
+  if (lst->selected > lst->scrl.val &&
       lst->selected <  lst->scrl.val + lst->nlines-1) LSRedraw(lst, 0);
   else {
     halfway = (lst->nlines)/2;   /* offset to the halfway pt. of the list */
@@ -590,7 +593,7 @@
   lp->win = XCreateSimpleWindow(theDisp,win,x,y,(u_int) w, (u_int) h,1,fg,bg);
   if (!lp->win) FatalError("can't create list window!");
 
-  lp->x = x;    lp->y = y;   
+  lp->x = x;    lp->y = y;
   lp->w = w;    lp->h = h;
   lp->fg = fg;  lp->bg = bg;
   lp->hi = hi;  lp->lo = lo;
@@ -603,7 +606,7 @@
 
   XSelectInput(theDisp, lp->win, ExposureMask | ButtonPressMask);
 
-  SCCreate(&lp->scrl, lp->win, w-20, -1, 1, h, 0, 
+  SCCreate(&lp->scrl, lp->win, w-20, -1, 1, h, 0,
 	   nstr-nlines, 0, nlines-1, fg, bg, hi, lo, fptr);
 
   XMapSubwindows(theDisp, lp->win);
@@ -646,7 +649,7 @@
 LIST *lp;
 {
   /* redraws lists 3d-effect, which can be trounced by drawSel() */
-  Draw3dRect(lp->win, 0, 0, lp->w-1, lp->h-1, R3D_IN, 2, 
+  Draw3dRect(lp->win, 0, 0, lp->w-1, lp->h-1, R3D_IN, 2,
 	     lp->hi, lp->lo, lp->bg);
 }
 
@@ -675,43 +678,43 @@
   else { fg = lp->fg;  bg = lp->bg; }
 
   XSetForeground(theDisp, theGC, bg);
-  XFillRectangle(theDisp, lp->win, theGC, x0, y0+i*LINEHIGH, 
+  XFillRectangle(theDisp, lp->win, theGC, x0, y0+i*LINEHIGH,
 		 (u_int) wide+1, (u_int) LINEHIGH);
 
   if (j>=0 && j<lp->nstr) {   /* only draw string if valid */
     XSetForeground(theDisp, theGC, fg);
     XSetBackground(theDisp, theGC, bg);
 
-    if (!lp->filetypes) 
+    if (!lp->filetypes)
       DrawString(lp->win, x0+3, y0+i*LINEHIGH + ASCENT + 1, lp->str[j]);
     else {
       int ypos = y0 + i*LINEHIGH + (LINEHIGH - i_fifo_height)/2;
 
-      if (lp->str[j][0] == C_FIFO) 
+      if (lp->str[j][0] == C_FIFO)
 	XCopyPlane(theDisp, fifoPix, lp->win, theGC, 0, 0,
 		   i_fifo_width, i_fifo_height, x0+3, ypos, 1L);
 
-      else if (lp->str[j][0] == C_CHR) 
+      else if (lp->str[j][0] == C_CHR)
 	XCopyPlane(theDisp, chrPix, lp->win, theGC, 0, 0,
 		   i_chr_width, i_chr_height, x0+3, ypos, 1L);
 
-      else if (lp->str[j][0] == C_DIR) 
+      else if (lp->str[j][0] == C_DIR)
 	XCopyPlane(theDisp, dirPix, lp->win, theGC, 0, 0,
 		   i_dir_width, i_dir_height, x0+3, ypos, 1L);
 
-      else if (lp->str[j][0] == C_BLK) 
+      else if (lp->str[j][0] == C_BLK)
 	XCopyPlane(theDisp, blkPix, lp->win, theGC, 0, 0,
 		   i_blk_width, i_blk_height, x0+3, ypos, 1L);
 
-      else if (lp->str[j][0] == C_LNK) 
+      else if (lp->str[j][0] == C_LNK)
 	XCopyPlane(theDisp, lnkPix, lp->win, theGC, 0, 0,
 		   i_lnk_width, i_lnk_height, x0+3, ypos, 1L);
 
-      else if (lp->str[j][0] == C_SOCK) 
+      else if (lp->str[j][0] == C_SOCK)
 	XCopyPlane(theDisp, sockPix, lp->win, theGC, 0, 0,
 		   i_sock_width, i_sock_height, x0+3, ypos, 1L);
 
-      else if (lp->str[j][0] == C_EXE) 
+      else if (lp->str[j][0] == C_EXE)
 	XCopyPlane(theDisp, exePix, lp->win, theGC, 0, 0,
 		   i_exe_width, i_exe_height, x0+3, ypos, 1L);
 
@@ -720,8 +723,8 @@
 		   i_reg_width, i_reg_height, x0+3, ypos, 1L);
 
 
-      DrawString(lp->win, x0+3 + i_fifo_width + 3, 
-		  y0+i*LINEHIGH + ASCENT + 1, 
+      DrawString(lp->win, x0+3 + i_fifo_width + 3,
+		  y0+i*LINEHIGH + ASCENT + 1,
 		  lp->str[j]+1);
     }
   }
@@ -735,7 +738,7 @@
 {
   int  i;
 
-  for (i = lp->scrl.val; i < lp->scrl.val + lp->nlines; i++) 
+  for (i = lp->scrl.val; i < lp->scrl.val + lp->nlines; i++)
     drawSel(lp,i);
   ls3d(lp);
 }
@@ -762,7 +765,7 @@
   if (sel >= lp->nstr) sel = lp->selected;
 
   /* see if it's a double click */
-  if (ev->time - lasttime < DBLCLKTIME && sel==lastsel 
+  if (ev->time - lasttime < DBLCLKTIME && sel==lastsel
       && (lp->scrl.val + (y-y0)/LINEHIGH) < lp->nstr
       && !INACTIVE(lp,sel)) {
     return (sel);
@@ -782,7 +785,7 @@
   while (XQueryPointer(theDisp,lp->win,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
     if (!(mask & Button1Mask)) break;    /* button released */
 
-    if (y<y0) { /* scroll up in list */ 
+    if (y<y0) { /* scroll up in list */
       if (lp->scrl.val > lp->scrl.min) {
 	lp->selected = lp->scrl.val - 1;
 	SCSetVal(&lp->scrl, lp->scrl.val - 1);
@@ -804,7 +807,7 @@
       if (sel >= lp->nstr) sel = lp->nstr - 1;
 
       if (sel != lp->selected && sel >= lp->scrl.val &&
-	  sel < lp->scrl.val + lp->nlines) {  
+	  sel < lp->scrl.val + lp->nlines) {
 	/* dragged to another on current page */
 	oldsel = lp->selected;
 	lp->selected = sel;
@@ -829,17 +832,17 @@
   else if (key==LS_PAGEDOWN) SCSetVal(&lp->scrl,lp->scrl.val + (lp->nlines-1));
   else if (key==LS_HOME)     SCSetVal(&lp->scrl,lp->scrl.min);
   else if (key==LS_END)      SCSetVal(&lp->scrl,lp->scrl.max);
-  
+
   else if (key==LS_LINEUP)   {
     /* if the selected item visible, but not the top line */
-    if (lp->selected > lp->scrl.val && 
+    if (lp->selected > lp->scrl.val &&
 	lp->selected <= lp->scrl.val + lp->nlines - 1) {
       /* then just move it */
       lp->selected--;
       drawSel(lp, lp->selected);  drawSel(lp, lp->selected+1);
       ls3d(lp);
     }
-    
+
     /* if it's the top line... */
     else if (lp->selected == lp->scrl.val) {
       if (lp->selected > 0) {
@@ -847,7 +850,7 @@
 	SCSetVal(&lp->scrl, lp->selected);
       }
     }
-    
+
     /* if it's not visible, put it on the bottom line */
     else {
       lp->selected = lp->scrl.val + lp->nlines - 1;
@@ -856,10 +859,10 @@
       ls3d(lp);
     }
   }
-  
+
   else if (key==LS_LINEDOWN)   {
     /* if the selected item visible, but not the bottom line */
-    if (lp->selected >= lp->scrl.val && 
+    if (lp->selected >= lp->scrl.val &&
 	lp->selected < lp->scrl.val + lp->nlines - 1) {
       if (lp->selected < lp->nstr-1) {
 	/* then just move it */
@@ -868,7 +871,7 @@
 	ls3d(lp);
       }
     }
-    
+
     /* if it's the bottom line... */
     else if (lp->selected == lp->scrl.val + lp->nlines - 1) {
       if (lp->selected < lp->nstr-1) {
@@ -876,7 +879,7 @@
 	SCSetVal(&lp->scrl, lp->scrl.val+1);
       }
     }
-    
+
     /* if it's not visible, put it on the top line */
     else {
       lp->selected = lp->scrl.val;
diff -ru xv-3.10a/xvcut.c xv-3.10a-enhancements/xvcut.c
--- xv-3.10a/xvcut.c	1995-01-13 11:55:48.000000000 -0800
+++ xv-3.10a-enhancements/xvcut.c	2007-04-15 15:02:32.000000000 -0700
@@ -15,7 +15,7 @@
  *      static void  clearSelectedArea();
  *      static void  makeClipFName    ();
  *      static int   countcols24      (byte *, int,int, int,int,int,int));
- *      static int   countNewCols     (byte*, int, int, byte*, int, 
+ *      static int   countNewCols     (byte*, int, int, byte*, int,
  *                                     int, int, int, int);
  *
  *             void  InitSelection  ();
@@ -72,7 +72,7 @@
 static void clearSelectedArea  PARM((void));
 static void makeClipFName      PARM((void));
 static int  countcols24        PARM((byte *, int, int, int, int, int, int));
-static int  countNewCols       PARM((byte *, int, int, byte *, int, 
+static int  countNewCols       PARM((byte *, int, int, byte *, int,
 				     int, int, int, int));
 static int  dragHandle         PARM((XButtonEvent *));
 static void dragSelection      PARM((XButtonEvent *, u_int, int));
@@ -210,7 +210,7 @@
   if (!PasteAllowed()) { XBell(theDisp, 0);  return; }
 
   cimg = getFromClip();
-  if (!cimg) return;  
+  if (!cimg) return;
 
   /* if there's no selection, make one! */
   if (!HaveSelection()) makePasteSel(cimg);
@@ -231,7 +231,7 @@
 
   byte *dp, *dpic, *clippic, *clipcmap;
   int   clipw, cliph, clipis24, len, istran, trval;
-  int   i, j, sx,sy,sw,sh, cx,cy,cw,ch, dx,dy,dw,dh,dx2,dy2;
+  int   i, j, sx,sy,sw,sh, cx,cy,cw,ch, dx,dy,dw,dh;
 
 
   /*
@@ -245,7 +245,7 @@
 	((int) (cimg[CIMG_LEN + 2]<<16)) |
 	((int) (cimg[CIMG_LEN + 3]<<24));
 
-  if (len < CIMG_PIC24) return;        
+  if (len < CIMG_PIC24) return;
 
   istran    = cimg[CIMG_TRANS];
   trval     = cimg[CIMG_TRVAL];
@@ -268,7 +268,7 @@
    * already, because if we *are*, we'd prefer to do any clipboard rescaling
    * in 24-bit space for the obvious reasons.
    *
-   * possibilities:  
+   * possibilities:
    *   PIC24  -  easy, do clipboard rescale in 24-bit space
    *   PIC8, and clipboard is 8 bits, (or 24-bits, but with <=256 colors)
    *      and total unique colors < 256:
@@ -283,7 +283,7 @@
 
   /* dx,dy,dw,dh is the rectangle (in PIC coords) where the paste will occur
      (cropped to be entirely within PIC */
-  
+
   dx = sx;  dy = sy;  dw = sw;  dh = sh;
   CropRect2Rect(&dx, &dy, &dw, &dh, 0, 0, pWIDE, pHIGH);
 
@@ -291,7 +291,7 @@
   /* cx,cy,cw,ch is the rectangle of the clipboard data (in clipboard coords)
      that will actually be used in the paste operation */
 
-  cx = (sx>=0) ? 0 : ((-sx) * clipw) / sw;  
+  cx = (sx>=0) ? 0 : ((-sx) * clipw) / sw;
   cy = (sy>=0) ? 0 : ((-sy) * cliph) / sh;
   cw = (dw * clipw) / sw;
   ch = (dh * cliph) / sh;
@@ -302,27 +302,29 @@
   if (picType == PIC8) {
     int ncc, keep8;
     char buf[512];
-    
+
     if (clipis24) { /* pasting in a 24-bit image that *requires* promotion */
-      static char *bnames[] = { "\nOkay", "\033Cancel" };
+      static const char *labels[] = { "\nOkay", "\033Cancel" };
+
       strcpy(buf, "Warning:  Pasting this 24-bit image will require ");
       strcat(buf, "promoting the current image to 24 bits.");
-      
-      if (PopUp(buf, bnames, 2)) goto exit;   /* Cancelled */
+
+      if (PopUp(buf, labels, 2)) goto exit;   /* Cancelled */
       else Change824Mode(PIC24);              /* promote pic to 24 bits */
     }
 
     else {   /* clip is 8 bits */
       ncc = countNewCols(clippic,clipw,cliph,clipcmap,clipis24,cx,cy,cw,ch);
-      
+
       if (ncc + numcols > 256) {
-	static char *bnames[] = { "\nPromote", "8Keep 8-bit", "\033Cancel" };
+	static const char *labels[] = { "\nPromote", "8Keep 8-bit", "\033Cancel" };
+
 	strcpy(buf,"Warning:  The image and the clipboard combine to have ");
 	strcat(buf,"more than 256 unique colors.  Promoting the ");
 	strcat(buf,"image to 24 bits is recommended, otherwise the contents ");
 	strcat(buf,"of the clipboard will probably lose some colors.");
-	
-	keep8 = PopUp(buf, bnames, 3);
+
+	keep8 = PopUp(buf, labels, 3);
 	if      (keep8==2) goto exit;              /* Cancel */
 	else if (keep8==0) Change824Mode(PIC24);   /* promote pic to 24 bits */
       }
@@ -331,8 +333,8 @@
 
 
 
-  
-  
+
+
   /* legal possibilities at this point:
    *   pic is PIC24:  clip is 8 or 24
    *   pic is PIC8:   clip is 8, or clip is 24 but has 256 or fewer colors
@@ -342,18 +344,18 @@
 
   if (picType == PIC8) {
     int   clx, cly, r,g,b,k,mind,close,newcols;
-    byte *cp, *clp, *pp, *ccp, newr[256], newg[256], newb[256], remap[256];
+    byte *cp, *clp, *pp, newr[256], newg[256], newb[256], remap[256];
     byte  order[256], trans[256];
     int   bperpix, dpncols;
-    
+
     dpic = (byte *) malloc((size_t) dw * dh);
     if (!dpic) FatalError("Out of memory in DoImgPaste()\n");
-    
+
     bperpix = (clipis24) ? 3 : 1;
     newcols = 0;
-    
+
     /* dpic = a scaled, 8-bit representation of clippic[cx,cy,cw,ch] */
-    
+
     if (!clipis24) {   /* copy colormap from clip data into newr,g,b[] */
       for (i=0; i<256; i++) {
 	newr[i] = clipcmap[i*3];
@@ -366,22 +368,22 @@
       dp = dpic + i*dw;
       cly = cy + (i * ch) / dh;
       clp = clippic + (cly*clipw * bperpix);
-      
+
       for (j=0; j<dw; j++, dp++) {
 	/* get appropriate pixel from clippic */
 	clx = cx + (j * cw) / dw;
 	cp = clp + (clx * bperpix);
-	
+
 	if (!clipis24) *dp = *cp;
 	else {                            /* build colormap as we go... */
 	  r = *cp++;  g = *cp++;  b = *cp++;
-	  
+
 	  /* look it up in new colormap, add if not there */
 	  for (k=0; k<newcols && (r!=newr[k] || g!=newg[k] ||b!=newb[k]); k++);
 	  if (k==newcols && k<256) {
 	    newr[k]=r;  newg[k]=g;  newb[k]=b;  newcols++;
 	  }
-	  
+
 	  *dp = (byte) (k & 0xff);
 	}
       }
@@ -401,23 +403,23 @@
 	}
       }
     }
-    
-    
-    
+
+
+
     /* COLORMAP MERGING */
-    
+
     newcols = 0;
-    
+
     for (i=0; i<dpncols; i++) {
       if (istran && i==trval) continue;
-      
+
       for (j=0; j<numcols; j++) {              /* look for an exact match */
 	if (rMap[j]==newr[i] && gMap[j]==newg[i] && bMap[j]==newb[i]) break;
       }
       if (j<numcols) remap[i] = j;
       else {                                   /* no exact match */
 	newcols++;
-	
+
 	if (numcols < 256) {
 	  rMap[numcols] = newr[i];
 	  gMap[numcols] = newg[i];
@@ -429,7 +431,7 @@
 	  r = newr[i];  g=newg[i];  b=newb[i];
 	  mind = 256*256 + 256*256 + 256*256;
 	  for (j=close=0; j<numcols; j++) {
-	    k = ((rMap[j]-r) * (rMap[j]-r)) + 
+	    k = ((rMap[j]-r) * (rMap[j]-r)) +
 	      ((gMap[j]-g) * (gMap[j]-g)) +
 		((bMap[j]-b) * (bMap[j]-b));
 	    if (k<mind) { mind = k;  close = j; }
@@ -438,10 +440,10 @@
 	}
       }
     }
-    
-    
+
+
     /* copy the data into PIC */
-    
+
     dp = dpic;
     for (i=dy; i<dy+dh; i++) {
       pp = pic + (i*pWIDE) + dx;
@@ -451,7 +453,7 @@
       }
     }
     free(dpic);
-    
+
     if (newcols) InstallNewPic();      /* does color reallocation, etc. */
     else {
       GenerateCpic();
@@ -459,16 +461,16 @@
       DrawEpic();
     }
   }
-  
+
 
   /******************** PIC24 handling **********************/
-  
-  
+
+
   else {
     byte *tmppic, *cp, *pp, *clp;
     int   bperpix;
     int   trr, trg, trb, clx, cly;
-    
+
     trr = trg = trb = 0;
     if (istran) {
       if (clipis24) {
@@ -482,24 +484,24 @@
 	trb = clipcmap[trval*3+2];
       }
     }
-    
+
     bperpix = (clipis24) ? 3 : 1;
 
     if (!istran && (cw != dw || ch != dh)) {  /* need to resize, can smooth */
       byte rmap[256], gmap[256], bmap[256];
-      
+
       tmppic = (byte *) malloc((size_t) cw * ch * bperpix);
       if (!tmppic) FatalError("Out of memory in DoImgPaste()\n");
-      
-      /* copy relevant hunk of clippic into tmppic (Smooth24 only works on 
+
+      /* copy relevant hunk of clippic into tmppic (Smooth24 only works on
 	 complete images */
-      
+
       for (i=0; i<ch; i++) {
 	dp = tmppic + i*cw*bperpix;
 	cp = clippic + ((i+cy)*clipw + cx) * bperpix;
 	for (j=0; j<cw*bperpix; j++) *dp++ = *cp++;
       }
-      
+
       if (!clipis24) {
 	for (i=0; i<256; i++) {
 	  rmap[i] = clipcmap[i*3];
@@ -507,15 +509,15 @@
 	  bmap[i] = clipcmap[i*3+2];
 	}
       }
-      
+
       dpic = Smooth24(tmppic, clipis24, cw,ch, dw,dh, rmap,gmap,bmap);
       if (!dpic) FatalError("Out of memory (2) in DoImgPaste()\n");
       free(tmppic);
-      
+
       /* copy the resized, smoothed, 24-bit data into 'pic' */
-      
+
       /* XXX: (deal with smooth-resized transparent imgs) */
-      
+
       dp = dpic;
       for (i=dy; i<dy+dh; i++) {
 	pp = pic + (i*pWIDE + dx) * 3;
@@ -536,11 +538,11 @@
 	pp = pic + ((i+dy)*pWIDE + dx) * 3;
 	cly = cy + (i * ch) / dh;
 	clp = clippic + (cly*clipw * bperpix);
-	
+
 	for (j=0; j<dw; j++, pp+=3) {
 	  clx = cx + (j * cw) / dw;
 	  cp = clp + (clx * bperpix);
-	  
+
 	  if (clipis24) {
 	    if (!istran || cp[0]!=trr || cp[1]!=trg || cp[2]==trb) {
 	      pp[0] = *cp++;  pp[1] = *cp++;  pp[2] = *cp++;
@@ -557,14 +559,14 @@
       }
     }
 
-    
+
     GenerateCpic();
     GenerateEpic(eWIDE, eHIGH);
     DrawEpic();
   }
-  
-    
- exit:  
+
+
+ exit:
   SetCursors(-1);
 }
 
@@ -577,20 +579,20 @@
   XColor cfg, cbg;
 
   dragcurs = XCreateFontCursor(theDisp, XC_fleur);
-  p1 = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) cut_bits, 
+  p1 = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) cut_bits,
 				   cut_width,  cut_height, 1L, 0L, 1);
-  p2 = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) cutm_bits, 
+  p2 = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) cutm_bits,
 				   cutm_width, cutm_height, 1L, 0L, 1);
-  p3 = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) copy_bits, 
+  p3 = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) copy_bits,
 				   copy_width,  copy_height, 1L, 0L, 1);
-  p4 = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) copym_bits, 
+  p4 = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) copym_bits,
 				   copym_width, copym_height, 1L, 0L, 1);
   if (p1 && p2 && p3 && p4) {
     cfg.red = cfg.green = cfg.blue = 0;
     cbg.red = cbg.green = cbg.blue = 0xffff;
-    cutcurs = XCreatePixmapCursor(theDisp, p1,p2, &cfg, &cbg, 
+    cutcurs = XCreatePixmapCursor(theDisp, p1,p2, &cfg, &cbg,
 				  cut_x_hot, cut_y_hot);
-    copycurs = XCreatePixmapCursor(theDisp, p3,p4, &cfg, &cbg, 
+    copycurs = XCreatePixmapCursor(theDisp, p3,p4, &cfg, &cbg,
 				  copy_x_hot, copy_y_hot);
     if (!cutcurs || !copycurs) FatalError("can't create cut/copy cursors...");
   }
@@ -619,7 +621,7 @@
 
   if (!CutAllowed()) {  XBell(theDisp, 0);  return (byte *) NULL; }
   if (!HaveSelection()) return (byte *) NULL;
-  
+
   GetSelRCoords(&x,&y,&w,&h);
   CropRect2Rect(&x,&y,&w,&h, 0,0,pWIDE,pHIGH);
 
@@ -663,15 +665,15 @@
   if (picType == PIC24 && !do24) {                  /* 24-bit data as 8-bit */
     int nc,pr,pg,pb;
     byte *cm;
-    
+
     nc = 0;
     dp = cimg + CIMG_PIC8;
-    
+
     for (i=y; i<y+h; i++) {
       pp = pic + i*pWIDE*3 + x*3;
       for (j=x; j<x+w; j++, pp+=3) {
 	pr = pp[0];  pg = pp[1];  pb = pp[2];
-	
+
 	cm = cimg + CIMG_CMAP;
 	for (k=0; k<nc; k++,cm+=3) {
 	  if (pr==cm[0] && pg==cm[1] && pb==cm[2]) break;
@@ -682,12 +684,12 @@
 	  cimg[CIMG_CMAP + nc*3 + 1] = pg;
 	  cimg[CIMG_CMAP + nc*3 + 2] = pb;
 	}
-	
+
 	*dp++ = (byte) k;
       }
     }
   }
-  
+
 
   else if (picType == PIC24) {                     /* 24-bit data as 24-bit */
     dp = cimg + CIMG_PIC24;
@@ -705,26 +707,26 @@
   else if (picType == PIC8) {                       /* 8-bit selection */
     byte *cm = cimg + CIMG_CMAP;
     for (i=0; i<256; i++) {                         /* copy colormap */
-      if (i<numcols) { 
+      if (i<numcols) {
 	*cm++ = rMap[i];
 	*cm++ = gMap[i];
 	*cm++ = bMap[i];
       }
     }
-    
+
     dp = cimg + CIMG_PIC8;
     for (i=y; i<y+h; i++) {                         /* copy image */
       pp = pic + i*pWIDE + x;
       for (j=x; j<x+w; j++) *dp++ = *pp++;
     }
   }
-    
+
   return cimg;
 }
 
 
 
-  
+
 /********************************************/
 static byte *getFromClip()
 {
@@ -743,14 +745,14 @@
     clipAtom = XInternAtom(theDisp, CLIPPROP, True);
     if (clipAtom != None) XDeleteProperty(theDisp, rootW, clipAtom);
   }
-  
-  
+
+
   clipAtom = XInternAtom(theDisp, CLIPPROP, True);             /* find prop */
   if (clipAtom != None) {
 
     /* try to retrieve the length of the data in the property */
-    i = XGetWindowProperty(theDisp, rootW, clipAtom, 0L, 1L, False, XA_STRING, 
-		       &actType, &actFormat, &nitems, &nleft, 
+    i = XGetWindowProperty(theDisp, rootW, clipAtom, 0L, 1L, False, XA_STRING,
+		       &actType, &actFormat, &nitems, &nleft,
 		       (unsigned char **) &data);
 
     if (i==Success && actType==XA_STRING && actFormat==8 && nleft>0) {
@@ -763,9 +765,9 @@
       XFree((void *) data);
 
       /* read the rest of the data (len bytes) */
-      i = XGetWindowProperty(theDisp, rootW, clipAtom, 1L, 
-			     (long) ((len-4)+3)/4, 
-			     False, XA_STRING, &actType, &actFormat, &nitems, 
+      i = XGetWindowProperty(theDisp, rootW, clipAtom, 1L,
+			     (long) ((len-4)+3)/4,
+			     False, XA_STRING, &actType, &actFormat, &nitems,
 			     &nleft, (unsigned char **) &data);
 
       if (i==Success) {
@@ -791,8 +793,8 @@
     }
   }
 
-  
-  /* if we're still here, then the prop method was less than successful. 
+
+  /* if we're still here, then the prop method was less than successful.
      use the file method, instead */
 
   if (!clipfname) makeClipFName();
@@ -800,7 +802,7 @@
   fp = fopen(clipfname, "r");
   if (!fp) {
     unlink(clipfname);
-    sprintf(str, "Can't read clipboard file '%s'\n\n  %s.", 
+    sprintf(str, "Can't read clipboard file '%s'\n\n  %s.",
 	    clipfname, ERRSTR(errno));
     ErrPopUp(str,"\nBletch!");
     return (byte *) NULL;
@@ -877,19 +879,19 @@
     clipAtom = XInternAtom(theDisp, CLIPPROP, True);
     if (clipAtom != None) XDeleteProperty(theDisp, rootW, clipAtom);
   }
-  
-  
+
+
   if (!forceClipFile) {
     clipAtom = XInternAtom(theDisp, CLIPPROP, False);  /* find or make prop */
     if (clipAtom != None) {
       /* try to store the data in the property */
-      
+
       xerrcode = 0;
       XChangeProperty(theDisp, rootW, clipAtom, XA_STRING, 8, PropModeReplace,
 		      cimg, len);
       XSync(theDisp, False);                         /* make it happen *now* */
       if (!xerrcode) return;                         /* success! */
-      
+
       /* failed, use file method */
       XDeleteProperty(theDisp, rootW, clipAtom);
     }
@@ -903,7 +905,7 @@
   fp = fopen(clipfname, "w");
   if (!fp) {
     unlink(clipfname);
-    sprintf(str, "Can't write clipboard file '%s'\n\n  %s.", 
+    sprintf(str, "Can't write clipboard file '%s'\n\n  %s.",
 	    clipfname, ERRSTR(errno));
     ErrPopUp(str,"\nBletch!");
     return;
@@ -964,7 +966,7 @@
 /********************************************/
 static void makeClipFName()
 {
-  char *homedir;
+  const char *homedir;
 
   if (clipfname) return;
 
@@ -996,7 +998,7 @@
   byte *pp;
 
   nc = 0;
-  
+
   for (i=y; nc<257 && i<y+h; i++) {
     pp = pic + i*pwide*3 + x*3;
     for (j=x; nc<257 && j<x+w; j++, pp+=3) {
@@ -1022,7 +1024,7 @@
    */
 
   int   i, j, k, nc, r,g,b;
-  byte *pp, *cp;
+  byte *pp;
   byte  newr[257], newg[257], newb[257];
 
   if (picType != PIC8) return 0;           /* shouldn't happen */
@@ -1034,7 +1036,7 @@
       pp = newpic + i*w*3 + cx*3;
       for (j=cx; j<cx+cw; j++) {
 	r = *pp++;  g = *pp++;  b = *pp++;
-	
+
 	/* lookup r,g,b in 'pic's colormap and the newcolors colormap */
 	for (k=0; k<nc && (r!=newr[k] || g!=newg[k] || b!=newb[k]); k++);
 	if (k==nc) {
@@ -1062,11 +1064,11 @@
     /* now see which of the used colors are new */
     for (i=0, nc=0; i<256; i++) {
       if (!coluse[i]) continue;
-      
-      r = newcmap[i*3];  
-      g = newcmap[i*3+1];  
+
+      r = newcmap[i*3];
+      g = newcmap[i*3+1];
       b = newcmap[i*3+2];
-      
+
       /* lookup r,g,b in pic's colormap */
       for (k=0; k<numcols && (r!=rMap[k] || g!=gMap[k] || b!=bMap[k]);k++);
       if (k==numcols) {  /* it's a new color, alright */
@@ -1075,7 +1077,7 @@
       }
     }
   }
-  
+
   return nc;
 }
 
@@ -1143,7 +1145,7 @@
   /* NOTE:  SELECTION IS *NOT* GUARANTEED to be within the bounds of 'pic'.
      It is only guaranteed to *intersect* pic. */
 
-  *xp = selrx;  *yp = selry;  
+  *xp = selrx;  *yp = selry;
   *wp = selrw;  *hp = selrh;
 }
 
@@ -1200,7 +1202,7 @@
     if (lastClickButton==Button1 && (ev->time - lastClickTime) < DBLCLKTIME) {
       lastClickButton=Button3;
       if (HaveSelection() && PTINRECT(px, py, selrx, selry, selrw, selrh)) {
-	EnableSelection(0); 
+	EnableSelection(0);
 	rv = 1;
       }
       else {
@@ -1225,7 +1227,7 @@
   else if (ev->button == Button2) {      /* do a drag & drop operation */
     if (HaveSelection() && PTINRECT(px,py,selrx,selry,selrw,selrh)) {
       /* clip selection rect to pic */
-      EnableSelection(0);  
+      EnableSelection(0);
       CropRect2Rect(&selrx, &selry, &selrw, &selrh, 0, 0, pWIDE, pHIGH);
 
       if (selrw<1 || selrh<1) rv = 0;
@@ -1253,8 +1255,8 @@
    * holding SHIFT constrains selection to be square,
    * holding CTRL  constrains selection to keep original aspect ratio
    */
-  
-  int          i, mex, mey, mpx, mpy, offx,offy;
+
+  int          mex, mey, mpx, mpy, offx,offy;
   int          sex, sey, sex2, sey2, sew, seh, sew2, seh2, hs, h2;
   int          istp, isbt, islf, isrt, isvm, ishm;
   int          cnstsq, cnstasp;
@@ -1272,7 +1274,7 @@
   sew2 = sew/2;
   seh2 = seh/2;
   sex2--;  sey2--;
-  
+
   if      (sew>=35 && seh>=35) hs=7;
   else if (sew>=20 && seh>=20) hs=5;
   else if (sew>= 9 && seh>= 9) hs=3;
@@ -1307,7 +1309,7 @@
 
 
   /* it's definitely in a handle...  track 'til released */
-  
+
   DrawSelection(0);
   selFilled   = 1;
   selTracking = 1;
@@ -1366,12 +1368,12 @@
                        else { chwide=1;  newwide = (int) (seh*orgaspect); }
 	}
       }
-      
+
       if (chwide) {
 	if (islf) { sex = (sex+sew) - newwide; }
 	sew = newwide;
       }
-      
+
       if (chhigh) {
 	if (istp) { sey = (sey+seh) - newhigh; }
 	seh = newhigh;
@@ -1380,7 +1382,7 @@
 
     if (sew<1) sew=1;
     if (seh<1) seh=1;
-    
+
     if (sex!=selrx || sey!=selry || sew!=selrw || seh!=selrh) {
       DrawSelection(0);
       selrx = sex;  selry = sey;  selrw = sew;  selrh = seh;
@@ -1395,14 +1397,14 @@
       Timer(100);
     }
   }
-  
+
   EnableSelection(0);
 
   selFilled   = 0;
   selTracking = 0;
 
   /* only 'enable' the selection if it intersects CPIC */
-  if (selrx < cXOFF+cWIDE && selrx+selrw > cXOFF && 
+  if (selrx < cXOFF+cWIDE && selrx+selrw > cXOFF &&
       selry < cYOFF+cHIGH && selry+selrh > cYOFF) EnableSelection(1);
 
   return 1;
@@ -1422,7 +1424,7 @@
    *
    * if 'dragndrop', changes cursor, monitors CTRL status
    */
-  
+
   int          mpx, mpy, offx, offy;
   int          newsx, newsy, orgsx, orgsy, cnstrain, docopy, lastdocopy;
   Window       rW, cW;
@@ -1436,9 +1438,9 @@
 
   CoordE2P(ev->x, ev->y, &mpx, &mpy);
   offx = mpx - selrx;  offy = mpy - selry;
-  
+
   /* track rectangle until we get a release */
-  
+
   DrawSelection(0);
   selFilled   = 1;
   selTracking = 1;
@@ -1467,7 +1469,7 @@
       dx = newsx - orgsx;  dy = newsy - orgsy;
       if      (abs(dx) > abs(dy)) dy = 0;
       else if (abs(dy) > abs(dx)) dx = 0;
-      
+
       newsx = orgsx + dx;  newsy = orgsy + dy;
     }
 
@@ -1485,7 +1487,7 @@
       Timer(100);
     }
   }
-  
+
   EnableSelection(0);
 
   selFilled   = 0;
@@ -1495,7 +1497,7 @@
 
   /* only do <whatever> if the selection intersects CPIC */
 
- if (selrx < cXOFF+cWIDE && selrx+selrw > cXOFF && 
+ if (selrx < cXOFF+cWIDE && selrx+selrw > cXOFF &&
       selry < cYOFF+cHIGH && selry+selrh > cYOFF) {
 
     EnableSelection(1);
@@ -1503,10 +1505,10 @@
     if (dragndrop) {
       int   tmpsx, tmpsy;
       byte *data;
-      
+
       tmpsx = selrx;  tmpsy = selry;
       selrx = orgsx;  selry = orgsy;
-      
+
       data = getSelection();         /* copy old data */
       if (data) {
 	if (!docopy) clearSelectedArea();
@@ -1531,29 +1533,29 @@
   int          rx,ry,ox,oy,x,y,active, x1, y1, x2, y2, cnstrain;
   int          i, px,py,px2,py2,pw,ph;
   unsigned int mask;
-  
+
   /* called on a B1 press in mainW to draw a new rectangular selection.
    * any former selection has already been removed.  holding shift down
-   * while tracking constrains selection to a square 
+   * while tracking constrains selection to a square
    */
-  
+
   active = 0;
-  
+
   x1 = ox = ev->x;  y1 = oy = ev->y;               /* nail down one corner */
   selrx = selry = selrw = selrh = 0;
   selTracking = 1;
-  
+
   while (1) {
     if (!XQueryPointer(theDisp,mainW,&rW,&cW,&rx,&ry,&x,&y,&mask)) continue;
     if (!(mask & Button1Mask)) break;      /* button released */
     cnstrain = (mask & ShiftMask);
-    
+
     if (x!=ox || y!=oy) {                  /* moved.  erase and redraw (?) */
       x2 = x;  y2 = y;
-      
+
       /* x1,y1,x2,y2 are in epic coords.  sort, convert to pic coords,
 	 and if changed, erase+redraw */
-      
+
       CoordE2P(x1, y1, &px,  &py);
       CoordE2P(x2, y2, &px2, &py2);
       if (px>px2) { i=px; px=px2; px2=i; }
@@ -1561,17 +1563,17 @@
       pw = px2-px+1;  ph=py2-py+1;
 
       /* keep px,py,pw,ph inside 'pic' */
-      
+
       if (px<0) { pw+=px;  px=0; }
       if (py<0) { ph+=py;  py=0; }
       if (px>pWIDE-1) px = pWIDE-1;
       if (py>pHIGH-1) py = pHIGH-1;
-      
+
       if (pw<0) pw=0;
       if (ph<0) ph=0;
       if (px+pw>pWIDE) pw = pWIDE - px;
       if (py+ph>pHIGH) ph = pHIGH - py;
-      
+
       if (cnstrain) {          /* make a square at smaller of w,h */
 	if      (ph>pw) { if (y2<y1) py += (ph-pw);  ph=pw; }
 	else if (pw>ph) { if (x2<x1) px += (pw-ph);  pw=ph; }
@@ -1579,12 +1581,12 @@
 
       /* put x,y,w,h -> selr{x,y,w,h}
 	 if the rectangle has changed, erase old and draw new */
-      
+
       if (px!=selrx || py!=selry || pw!=selrw || ph!=selrh) {
 	DrawSelection(0);
 	selrx = px;  selry = py;  selrw = pw;  selrh = ph;
 	DrawSelection(1);
-	
+
 	haveSel = active = (pw>0 && ph>0);
 	if (infoUp) SetSelectionString();
 	XFlush(theDisp);
@@ -1615,7 +1617,7 @@
      set, pick a new 'color' to invert the selection with */
 
   int   x,y,x1,y1,w,h;
-  
+
   if (newcol) selColor = (selColor+1) & 0x7;
 
   /* convert selr{x,y,w,h} into epic coords */
@@ -1650,7 +1652,7 @@
   if (y<0 && y+h>eHIGH && selFilled!=1)
     XDrawLine(theDisp, mainW, theGC, x, eHIGH/2, x+w, eHIGH/2);
 
-  
+
   if (selFilled==0 || selFilled == 1) {
     /* one little kludge:  if w or h == eWIDE or eHIGH, make it one smaller */
     if (x+w == eWIDE) w--;
@@ -1664,17 +1666,17 @@
       else if (w>=20 && h>=20) { hs=5;  h1=4; h2=2; }
       else if (w>= 9 && h>= 9) { hs=3;  h1=2; h2=1; }
       else hs=h1=h2=0;
-      
+
       if (hs) {
 	XFillRectangle(theDisp,mainW,theGC,x+1,     y+1,  (u_int)h1,(u_int)h1);
 	XFillRectangle(theDisp,mainW,theGC,x+w/2-h2,y+1,  (u_int)hs,(u_int)h1);
 	XFillRectangle(theDisp,mainW,theGC,x+w-h1,  y+1,  (u_int)h1,(u_int)h1);
-	
+
 	XFillRectangle(theDisp,mainW,theGC,x+1,   y+h/2-h2,
 		       (u_int)h1, (u_int)hs);
 	XFillRectangle(theDisp,mainW,theGC,x+w-h1,y+h/2-h2,
 		       (u_int)h1, (u_int)hs);
-	
+
 	XFillRectangle(theDisp,mainW,theGC,x+1,     y+h-h1,
 		       (u_int)h1,(u_int)h1);
 	XFillRectangle(theDisp,mainW,theGC,x+w/2-h2,y+h-h1,
@@ -1683,7 +1685,7 @@
 		       (u_int)h1,(u_int)h1);
       }
     }
-	
+
     if (selFilled==1) {
       XDrawLine(theDisp, mainW, theGC, x+1, y+1,   x+w-1, y+h-1);
       XDrawLine(theDisp, mainW, theGC, x+1, y+h-1, x+w-1, y+1);
@@ -1692,8 +1694,8 @@
   else if (selFilled==2) {
     XFillRectangle(theDisp, mainW, theGC, x,y,(u_int) w, (u_int) h);
   }
-  
-  
+
+
   XSetFunction(theDisp,theGC,GXcopy);
   XSetPlaneMask(theDisp, theGC, AllPlanes);
 }
@@ -1703,7 +1705,7 @@
 void MoveGrowSelection(dx,dy,dw,dh)
      int dx,dy,dw,dh;
 {
-  /* moves and/or grows the selection by the specified amount 
+  /* moves and/or grows the selection by the specified amount
      (in pic coords).  keeps the selection entirely within 'pic'.
      (called by 'CropKey()') */
 
@@ -1729,7 +1731,7 @@
   }
 }
 
-  
+
 /***********************************/
 void BlinkSelection(cnt)
      int cnt;
diff -ru xv-3.10a/xvdflt.c xv-3.10a-enhancements/xvdflt.c
--- xv-3.10a/xvdflt.c	1994-12-22 14:34:42.000000000 -0800
+++ xv-3.10a-enhancements/xvdflt.c	2007-05-12 14:07:36.000000000 -0700
@@ -16,12 +16,12 @@
 #include "bits/xv_rev"
 #include "bits/xv_ver"
 #include "bits/xf_left"
-#include "bits/xf_right"
+/* #include "bits/xf_right"	not used */
 #include "bits/font5x9.h"
 
 
 #ifndef USEOLDPIC
-#  include "xvdflt.h"  
+#  include "xvdflt.h"
 #endif
 
 
@@ -62,7 +62,7 @@
   for (i=0; i<XVDFLT_HIGH; i++) {
     nbytes = 0;
     while (nbytes < XVDFLT_WIDE) {
-      char *sp;
+      const char *sp;
       byte *dp;
 
       j = XVDFLT_WIDE - nbytes;
@@ -100,21 +100,21 @@
   setcolor(pinfo, 252,   0,  0,  0);   /* black background for text */
 
 
-  xbm2pic((byte *) xv_cpyrt_bits, xv_cpyrt_width, xv_cpyrt_height, 
+  xbm2pic((byte *) xv_cpyrt_bits, xv_cpyrt_width, xv_cpyrt_height,
 	   dfltpic, DWIDE, DHIGH, DWIDE/2+1, 203+1, 252);
-  xbm2pic((byte *) xv_cpyrt_bits, xv_cpyrt_width, xv_cpyrt_height, 
+  xbm2pic((byte *) xv_cpyrt_bits, xv_cpyrt_width, xv_cpyrt_height,
 	   dfltpic, DWIDE, DHIGH, DWIDE/2,   203, 250);
 
   i = xv_ver_width + xv_rev_width + 30;
 
-  xbm2pic((byte *) xv_ver_bits, xv_ver_width, xv_ver_height, 
+  xbm2pic((byte *) xv_ver_bits, xv_ver_width, xv_ver_height,
        dfltpic, DWIDE, DHIGH, DWIDE/2 - (i/2) + xv_ver_width/2+1, 220+1,252);
-  xbm2pic((byte *) xv_rev_bits, xv_rev_width, xv_rev_height, 
+  xbm2pic((byte *) xv_rev_bits, xv_rev_width, xv_rev_height,
        dfltpic, DWIDE, DHIGH, DWIDE/2 + (i/2) - xv_rev_width/2+1, 220+1,252);
 
-  xbm2pic((byte *) xv_ver_bits, xv_ver_width, xv_ver_height, 
+  xbm2pic((byte *) xv_ver_bits, xv_ver_width, xv_ver_height,
 	   dfltpic, DWIDE, DHIGH, DWIDE/2 - (i/2) + xv_ver_width/2, 220, 250);
-  xbm2pic((byte *) xv_rev_bits, xv_rev_width, xv_rev_height, 
+  xbm2pic((byte *) xv_rev_bits, xv_rev_width, xv_rev_height,
 	   dfltpic, DWIDE, DHIGH, DWIDE/2 + (i/2) - xv_rev_width/2, 220, 250);
 
   strcpy(str,"Press <right> mouse button for menu.");
@@ -136,7 +136,11 @@
   pinfo->w       = XVDFLT_WIDE;
   pinfo->h       = XVDFLT_HIGH;
   pinfo->type    = PIC8;
+#ifdef HAVE_PNG
+  pinfo->frmType = F_PNG;
+#else
   pinfo->frmType = F_GIF;
+#endif
   pinfo->colType = F_FULLCOLOR;
 
   pinfo->normw   = pinfo->w;
@@ -169,7 +173,7 @@
     for (i=k=0; i<DHIGH; i+=xf_left_height) {
       for (j=0; j<DWIDE; j+=xf_left_width) {
 	k++;
-	if (k&1) 
+	if (k&1)
 	  xbm2pic((byte *) xf_left_bits, xf_left_width, xf_left_height,
 		  dfltpic, DWIDE, DHIGH, j + xf_left_width/2,
 		  i + xf_left_height/2, 1);
@@ -179,29 +183,29 @@
 
 
 
-  xbm2pic((byte *) xvpic_logo_out_bits, xvpic_logo_out_width, 
+  xbm2pic((byte *) xvpic_logo_out_bits, xvpic_logo_out_width,
 	  xvpic_logo_out_height, dfltpic, DWIDE, DHIGH, DWIDE/2 + 10, 80, 103);
 
-  xbm2pic((byte *) xvpic_logo_top_bits, xvpic_logo_top_width, 
+  xbm2pic((byte *) xvpic_logo_top_bits, xvpic_logo_top_width,
 	  xvpic_logo_top_height, dfltpic, DWIDE, DHIGH, DWIDE/2 + 10, 80, 100);
 
-  xbm2pic((byte *) xvpic_logo_bot_bits, xvpic_logo_bot_width, 
+  xbm2pic((byte *) xvpic_logo_bot_bits, xvpic_logo_bot_width,
 	  xvpic_logo_bot_height, dfltpic, DWIDE, DHIGH, DWIDE/2 + 10, 80, 101);
 
 
 
-  xbm2pic((byte *) xv_jhb_bits, xv_jhb_width, xv_jhb_height, 
+  xbm2pic((byte *) xv_jhb_bits, xv_jhb_width, xv_jhb_height,
 	   dfltpic, DWIDE, DHIGH, DWIDE/2, 160, 102);
 
-  xbm2pic((byte *) xv_cpyrt_bits, xv_cpyrt_width, xv_cpyrt_height, 
+  xbm2pic((byte *) xv_cpyrt_bits, xv_cpyrt_width, xv_cpyrt_height,
 	   dfltpic, DWIDE, DHIGH, DWIDE/2, 203, 102);
 
   i = xv_ver_width + xv_rev_width + 30;
 
-  xbm2pic((byte *) xv_ver_bits, xv_ver_width, xv_ver_height, 
+  xbm2pic((byte *) xv_ver_bits, xv_ver_width, xv_ver_height,
 	   dfltpic, DWIDE, DHIGH, DWIDE/2 - (i/2) + xv_ver_width/2, 220, 102);
 
-  xbm2pic((byte *) xv_rev_bits, xv_rev_width, xv_rev_height, 
+  xbm2pic((byte *) xv_rev_bits, xv_rev_width, xv_rev_height,
 	   dfltpic, DWIDE, DHIGH, DWIDE/2 + (i/2) - xv_rev_width/2, 220, 102);
 
   strcpy(str,"Press <right> mouse button for menu.");
@@ -240,7 +244,11 @@
   pinfo->w       = DWIDE;
   pinfo->h       = DHIGH;
   pinfo->type    = PIC8;
+#ifdef HAVE_PNG
+  pinfo->frmType = F_PNG;
+#else
   pinfo->frmType = F_GIF;
+#endif
   pinfo->colType = F_FULLCOLOR;
 
   sprintf(pinfo->fullInfo, "<8-bit internal>");
@@ -272,7 +280,7 @@
       x = cx - bwide/2;
 
       k = *bptr;
-      for (j=0,bit=0; j<bwide; j++, bit = (++bit)&7, x++) {
+      for (j=0,bit=0; j<bwide; j++, bit = (bit+1)&7, x++) {
 	if (!bit) k = *bptr++;
 	if ( (k&1) && (x>=0) && (x<pwide))
 	  pptr[x] = col;
@@ -281,7 +289,7 @@
       }
     }
   }
-}  
+}
 
 
 /*******************************************/
@@ -300,7 +308,7 @@
      byte    *dfltpic;
      PICINFO *pinfo;
 {
-  int i,j,k, dr, dg, db;
+  int i,j, dr, dg, db;
   byte *pp;
 
   pp = dfltpic;
@@ -357,7 +365,7 @@
 
   for ( ; *str; str++, cx+=6) {
     i = (byte) *str;
-    if (i >= 32 && i < 128) 
+    if (i >= 32 && i < 128)
       xbm2pic(font5x9[i - 32], 5, 9, pic, pw, ph, cx, cy, col);
   }
 }
diff -ru xv-3.10a/xvdflt.h xv-3.10a-enhancements/xvdflt.h
--- xv-3.10a/xvdflt.h	1994-12-22 14:34:56.000000000 -0800
+++ xv-3.10a-enhancements/xvdflt.h	2007-04-15 20:45:08.000000000 -0700
@@ -2,7 +2,7 @@
 #define XVDFLT_HIGH    270
 #define XVDFLT_NPARTS    5
 #define XVDFLT_PARTLEN 100
-char *xvdflt_pic[1350] = {
+const char *xvdflt_pic[1350] = {
 /*   0a */ "00000000000000000000000000000000000000000000000101010101010101010101010101010101010101010101010101010101010101000000000000000000000000000002020202020202020303030303030303030404040404040505050505060708",
 /*   0b */ "0809090a0b0c0d0e0e0f101111121213131313141414141515151515151515151616161616161616161616161616161616161616161616161616161616171717171717171717171717171717161616161616161616161616161616161616161616161617",
 /*   0c */ "171717181818181818181818181818181818181919181818181818191919191919191a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1b1b1b1b1b1b1b1b1b1c1c1c1c1c1c1c1c1d1d1d1d1d1d1d1d1d1c1c1c1c1c1c1c1c1c1c1c1c1c1c1b1b1b1b1b1b1b1b1b1a1a",
@@ -1356,9 +1356,9 @@
 };
 
 
-byte xvdflt_r[256] = { 83,83,84,84,84,85,92,94,100,109,119,124,133,137,145,157,163,168,175,183,191,202,203,255,254,253,252,251,250,249,145,114,83,106,129,249,250,251,250,243,216,226,241,222,222,132,61,82,244,249,243,248,173,59,247,102,252,241,244,244,57,241,216,239,6,17,157,244,139,236,250,246,84,213,121,240,70,30,99,91,38,73,105,123,82,40,30,38,114,81,44,35,37,35,30,33,1,0,5,1,1,4,3,0,0,11,0,0,6,15,7,3,8,0,0,4,8,11,15,0,10,11,14,11,0,14,0,28,6,1,22,17,8,1,8,7,7,13,0,9,10,6,7,10,11,11,18,7,2,8,7,9,5,10,8,16,6,6,5,8,8,6,10,8,4,30,22,5,33,33,11,6,10,15,19,13,28,21,35,28,10,25,26,27,29,3,27,14,21,30,31,27,31,35,6,33,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
+const byte xvdflt_r[256] = { 83,83,84,84,84,85,92,94,100,109,119,124,133,137,145,157,163,168,175,183,191,202,203,255,254,253,252,251,250,249,145,114,83,106,129,249,250,251,250,243,216,226,241,222,222,132,61,82,244,249,243,248,173,59,247,102,252,241,244,244,57,241,216,239,6,17,157,244,139,236,250,246,84,213,121,240,70,30,99,91,38,73,105,123,82,40,30,38,114,81,44,35,37,35,30,33,1,0,5,1,1,4,3,0,0,11,0,0,6,15,7,3,8,0,0,4,8,11,15,0,10,11,14,11,0,14,0,28,6,1,22,17,8,1,8,7,7,13,0,9,10,6,7,10,11,11,18,7,2,8,7,9,5,10,8,16,6,6,5,8,8,6,10,8,4,30,22,5,33,33,11,6,10,15,19,13,28,21,35,28,10,25,26,27,29,3,27,14,21,30,31,27,31,35,6,33,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
 
-byte xvdflt_g[256] = { 83,83,84,84,84,85,92,94,100,109,119,124,133,137,145,157,162,168,174,184,191,196,205,255,254,253,252,251,250,249,146,114,83,106,130,211,185,176,173,230,211,157,161,170,144,31,52,82,168,168,162,248,116,42,247,68,171,164,245,244,35,159,133,161,18,26,151,163,138,65,67,51,68,49,111,159,88,30,100,87,38,74,92,124,82,38,22,38,114,81,22,35,37,35,30,33,1,0,4,0,1,4,2,0,0,11,0,0,6,15,7,3,8,0,0,4,9,10,14,0,10,10,13,11,0,7,0,18,6,0,22,18,8,1,8,7,7,13,0,9,9,6,7,10,11,11,18,7,2,9,7,9,5,10,8,16,6,6,5,8,8,7,9,8,4,30,22,5,33,32,11,6,10,15,19,13,28,21,35,25,9,22,26,27,29,3,27,14,21,30,31,11,31,35,6,18,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
+const byte xvdflt_g[256] = { 83,83,84,84,84,85,92,94,100,109,119,124,133,137,145,157,162,168,174,184,191,196,205,255,254,253,252,251,250,249,146,114,83,106,130,211,185,176,173,230,211,157,161,170,144,31,52,82,168,168,162,248,116,42,247,68,171,164,245,244,35,159,133,161,18,26,151,163,138,65,67,51,68,49,111,159,88,30,100,87,38,74,92,124,82,38,22,38,114,81,22,35,37,35,30,33,1,0,4,0,1,4,2,0,0,11,0,0,6,15,7,3,8,0,0,4,9,10,14,0,10,10,13,11,0,7,0,18,6,0,22,18,8,1,8,7,7,13,0,9,9,6,7,10,11,11,18,7,2,9,7,9,5,10,8,16,6,6,5,8,8,7,9,8,4,30,22,5,33,32,11,6,10,15,19,13,28,21,35,25,9,22,26,27,29,3,27,14,21,30,31,11,31,35,6,18,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
 
-byte xvdflt_b[256] = { 251,250,252,253,254,255,254,255,254,253,254,254,252,255,255,253,251,253,253,253,254,249,252,255,254,253,252,251,250,249,252,255,249,253,250,162,99,79,81,225,239,113,92,147,72,43,37,248,84,88,91,248,83,34,247,80,84,86,245,244,30,90,74,92,10,55,239,85,250,90,88,72,125,68,206,92,190,87,245,230,133,216,199,248,247,105,73,108,252,244,62,97,119,143,150,134,57,49,64,64,72,78,72,40,75,98,66,59,110,110,80,89,95,86,34,87,80,88,77,48,100,80,98,89,33,60,29,75,91,73,111,87,120,89,103,103,126,111,23,121,108,147,111,142,105,111,111,140,107,107,118,113,112,110,114,123,140,120,141,132,124,130,98,127,151,102,124,132,108,119,123,159,124,135,123,124,114,135,126,100,122,126,132,140,126,164,119,149,149,137,113,75,127,114,131,78,107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
+const byte xvdflt_b[256] = { 251,250,252,253,254,255,254,255,254,253,254,254,252,255,255,253,251,253,253,253,254,249,252,255,254,253,252,251,250,249,252,255,249,253,250,162,99,79,81,225,239,113,92,147,72,43,37,248,84,88,91,248,83,34,247,80,84,86,245,244,30,90,74,92,10,55,239,85,250,90,88,72,125,68,206,92,190,87,245,230,133,216,199,248,247,105,73,108,252,244,62,97,119,143,150,134,57,49,64,64,72,78,72,40,75,98,66,59,110,110,80,89,95,86,34,87,80,88,77,48,100,80,98,89,33,60,29,75,91,73,111,87,120,89,103,103,126,111,23,121,108,147,111,142,105,111,111,140,107,107,118,113,112,110,114,123,140,120,141,132,124,130,98,127,151,102,124,132,108,119,123,159,124,135,123,124,114,135,126,100,122,126,132,140,126,164,119,149,149,137,113,75,127,114,131,78,107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
 
diff -ru xv-3.10a/xvdial.c xv-3.10a-enhancements/xvdial.c
--- xv-3.10a/xvdial.c	1995-01-03 13:20:31.000000000 -0800
+++ xv-3.10a-enhancements/xvdial.c	2007-04-15 17:55:50.000000000 -0700
@@ -1,11 +1,11 @@
-/* 
+/*
  * xvdial.c - DIAL handling functions
  *
  * callable functions:
  *
  *   DCreate()   -  creates a dial
  *   DSetRange() -  sets min/max/current values of control
- *   DSetVal()   -  sets value of control 
+ *   DSetVal()   -  sets value of control
  *   DSetActive() - turns dial '.active' on and off
  *   DRedraw()   -  redraws the dial
  *   DTrack()    -  called when clicked.  Operates control 'til mouseup
@@ -41,51 +41,53 @@
 
 
 /* local functions */
-static int  whereInDial     PARM((DIAL *, int, int));
-static void drawArrow       PARM((DIAL *));
-static void drawValStr      PARM((DIAL *));
-static void drawButt        PARM((DIAL *, int, int));
-static int  computeDialVal  PARM((DIAL *, int, int));
-static void dimDial         PARM((DIAL *));
+static int    whereInDial     PARM((DIAL *, int, int));
+static void   drawArrow       PARM((DIAL *));
+static void   drawValStr      PARM((DIAL *));
+static void   drawButt        PARM((DIAL *, int, int));
+static double computeDialVal  PARM((DIAL *, int, int));
+static void   dimDial         PARM((DIAL *));
 
 
 /***************************************************/
-void DCreate(dp, parent, x, y, w, h, minv, maxv, curv, page, 
+void DCreate(dp, parent, x, y, w, h, minv, maxv, curv, inc, page,
 	          fg, bg, hi, lo, title, units)
-DIAL         *dp;
-Window        parent;
-int           x,y,w,h,minv,maxv,curv,page;
-unsigned long fg,bg,hi,lo;
-char         *title, *units;
+DIAL          *dp;
+Window         parent;
+int            x, y, w, h;
+double         minv, maxv, curv, inc, page;
+unsigned long  fg, bg, hi, lo;
+const char    *title, *units;
 {
 
   if (!pixmaps_built) {
-    cw1Pix   = XCreatePixmapFromBitmapData(theDisp, parent, 
+    cw1Pix   = XCreatePixmapFromBitmapData(theDisp, parent,
 		(char *) dial_cw1_bits, PW, PH, fg, bg, dispDEEP);
-    ccw1Pix  = XCreatePixmapFromBitmapData(theDisp, parent, 
+    ccw1Pix  = XCreatePixmapFromBitmapData(theDisp, parent,
 	        (char *) dial_ccw1_bits, PW, PH, fg, bg, dispDEEP);
-    cw2Pix   = XCreatePixmapFromBitmapData(theDisp, parent, 
+    cw2Pix   = XCreatePixmapFromBitmapData(theDisp, parent,
                 (char *) dial_cw2_bits, PW, PH, fg, bg, dispDEEP);
-    ccw2Pix  = XCreatePixmapFromBitmapData(theDisp, parent, 
+    ccw2Pix  = XCreatePixmapFromBitmapData(theDisp, parent,
 	        (char *) dial_ccw2_bits, PW, PH, fg, bg, dispDEEP);
   }
 
-  dp->x     = x;
-  dp->y     = y;
-
-  dp->w     = w;
-  dp->h     = h;
-  dp->fg    = fg;
-  dp->bg    = bg;
-  dp->hi    = hi;
-  dp->lo    = lo;
-  dp->title = title;
-  dp->units = units;
-  dp->active = 1;
+  dp->x       = x;
+  dp->y       = y;
+  dp->w       = w;
+  dp->h       = h;
+  dp->fg      = fg;
+  dp->bg      = bg;
+  dp->hi      = hi;
+  dp->lo      = lo;
+  dp->title   = title;
+  dp->units   = units;
+  dp->active  = 1;
   dp->drawobj = NULL;
 
-  if (w < h-24-16) dp->rad = (w - 8) / 2;
-           else dp->rad = (h - 24 - 16 - 8) / 2;
+  if (w < h-24-16)
+    dp->rad = (w - 8) / 2;
+  else
+    dp->rad = (h - 24 - 16 - 8) / 2;
   dp->cx = w / 2;
   dp->cy = dp->rad + 4 + 16;
 
@@ -94,22 +96,22 @@
   dp->bx[INCW1]  = w-14-4;  dp->by[INCW1]  = h - 4 - 20;
   dp->bx[INCW2]  = w-14-4;  dp->by[INCW2]  = h - 4 - 10;
 
-  dp->win = XCreateSimpleWindow(theDisp, parent,x,y,(u_int) w,(u_int) h,
-				1,fg,bg);
+  dp->win = XCreateSimpleWindow(theDisp, parent, x, y, (u_int) w, (u_int) h,
+				1, fg, bg);
   if (!dp->win) FatalError("can't create dial window");
 
-  DSetRange(dp, minv, maxv, curv, page);
+  DSetRange(dp, minv, maxv, curv, inc, page);
   XSelectInput(theDisp, dp->win, ExposureMask | ButtonPressMask);
 }
 
 
 /***************************************************/
-void DSetRange(dp, minv, maxv, curv, page)
-DIAL *dp;
-int   minv, maxv, curv, page;
+void DSetRange(dp, minv, maxv, curv, inc, page)
+DIAL   *dp;
+double  minv, maxv, curv, inc, page;
 {
   if (maxv<minv) maxv=minv;
-  dp->min = minv;    dp->max = maxv;    dp->page = page;
+  dp->min = minv; dp->max = maxv; dp->inc = inc; dp->page = page;
   dp->active =  (minv < maxv);
 
   DSetVal(dp, curv);
@@ -118,22 +120,22 @@
 
 /***************************************************/
 void DSetVal(dp, curv)
-DIAL *dp;
-int   curv;
+DIAL  *dp;
+double curv;
 {
   RANGE(curv, dp->min, dp->max);   /* make sure curv is in-range */
 
   if (curv == dp->val) return;
 
   /* erase old arrow */
-  XSetForeground(theDisp, theGC, dp->bg); 
+  XSetForeground(theDisp, theGC, dp->bg);
   drawArrow(dp);
 
-  dp->val = curv;
+  dp->val = (double)((int)(curv / dp->inc + (curv > 0 ? 0.5 : -0.5))) * dp->inc;
 
   /* draw new arrow and string */
   XSetForeground(theDisp, theGC, dp->fg);
-  XSetBackground(theDisp, theGC, dp->bg); 
+  XSetBackground(theDisp, theGC, dp->bg);
   drawArrow(dp);
   drawValStr(dp);
   if (!dp->active) dimDial(dp);
@@ -202,7 +204,8 @@
 int mx,my;
 {
   Window       rW,cW;
-  int          rx,ry, x,y, ipos, pos, lit, i, origval;
+  int          rx, ry, x, y, ipos, pos, lit;
+  double       origval;
   unsigned int mask;
 
   lit = 0;
@@ -224,35 +227,36 @@
   if (ipos != INDIAL) {
     drawButt(dp, ipos, 1);
     switch (ipos) {
-    case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+1); break;
+    case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->inc);  break;
     case INCW2:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page); break;
-    case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-1); break;
+    case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->inc);  break;
     case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page); break;
     }
-    if (dp->drawobj != NULL) (dp->drawobj)();  
+    if (dp->drawobj != NULL) (dp->drawobj)();
     Timer(INC1WAIT);
     lit = 1;
   }
 
-  else { 
-    i = computeDialVal(dp, mx, my);
-    DSetVal(dp, i);
-    if (dp->drawobj != NULL) (dp->drawobj)();  
+  else {
+    double v;
+    v = computeDialVal(dp, mx, my);
+    DSetVal(dp, v);
+    if (dp->drawobj != NULL) (dp->drawobj)();
   }
 
-  
+
   /* loop until mouse is released */
   while (XQueryPointer(theDisp,dp->win,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
     if (!(mask & Button1Mask)) break;    /* button released */
 
     if (ipos == INDIAL) {
-      int j;
-      i = computeDialVal(dp, x, y);
-      j = dp->val;
-      DSetVal(dp, i);
-      if (j != dp->val) {
+      double v, w;
+      v = computeDialVal(dp, x, y);
+      w = dp->val;
+      DSetVal(dp, v);
+      if (w != dp->val) {
 	/* track whatever dial controls */
-	if (dp->drawobj != NULL) (dp->drawobj)();  
+	if (dp->drawobj != NULL) (dp->drawobj)();
       }
     }
 
@@ -266,18 +270,18 @@
 
       if (lit) {
 	switch (ipos) {
-	case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+1); 
+	case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->inc);
 	             break;
 	case INCW2:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page);
                      break;
-	case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-1);
+	case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->inc);
                      break;
 	case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page);
                      break;
 	}
 
 	/* track whatever dial controls */
-	if (dp->drawobj != NULL) (dp->drawobj)();  
+	if (dp->drawobj != NULL) (dp->drawobj)();
 
 	Timer(INC2WAIT);
       }
@@ -305,34 +309,35 @@
 
   /* returns region * that x,y is in.  returns -1 if none */
 
-  for (i=0; i<4; i++) 
+  for (i=0; i<4; i++)
     if (PTINRECT(x,y, dp->bx[i], dp->by[i], 14, 10)) return i;
 
-  if (PTINRECT(x,y, dp->cx - dp->rad, dp->cy - dp->rad, 
+  if (PTINRECT(x,y, dp->cx - dp->rad, dp->cy - dp->rad,
 	       2*dp->rad, 2*dp->rad))
     return INDIAL;
 
   return -1;
 }
 
-	  
+
 /***************************************************/
 static void drawArrow(dp)
 DIAL *dp;
 {
-  int i, rad, cx, cy;
+  int rad, cx, cy;
+  double v;
   XPoint arrow[4];
 
   rad = dp->rad;  cx = dp->cx;  cy = dp->cy;
 
   /* map pos (range minv..maxv) into degrees (range 240..-60) */
-  i = 240 + (-300 * (dp->val - dp->min)) / (dp->max - dp->min);
-  arrow[0].x = cx + (int) ((double) rad * .80 * cos(i * DEG2RAD));
-  arrow[0].y = cy - (int) ((double) rad * .80 * sin(i * DEG2RAD));
-  arrow[1].x = cx + (int) ((double) rad * .33 * cos((i+160) * DEG2RAD));
-  arrow[1].y = cy - (int) ((double) rad * .33 * sin((i+160) * DEG2RAD));
-  arrow[2].x = cx + (int) ((double) rad * .33 * cos((i-160) * DEG2RAD));
-  arrow[2].y = cy - (int) ((double) rad * .33 * sin((i-160) * DEG2RAD));
+  v = 240 + (-300 * (dp->val - dp->min)) / (dp->max - dp->min);
+  arrow[0].x = cx + (int) ((double) rad * .80 * cos(v * DEG2RAD));
+  arrow[0].y = cy - (int) ((double) rad * .80 * sin(v * DEG2RAD));
+  arrow[1].x = cx + (int) ((double) rad * .33 * cos((v+160) * DEG2RAD));
+  arrow[1].y = cy - (int) ((double) rad * .33 * sin((v+160) * DEG2RAD));
+  arrow[2].x = cx + (int) ((double) rad * .33 * cos((v-160) * DEG2RAD));
+  arrow[2].y = cy - (int) ((double) rad * .33 * sin((v-160) * DEG2RAD));
   arrow[3].x = arrow[0].x;
   arrow[3].y = arrow[0].y;
   XDrawLines(theDisp, dp->win, theGC, arrow, 4, CoordModeOrigin);
@@ -343,33 +348,47 @@
 static void drawValStr(dp)
 DIAL *dp;
 {
-  int  i, x1, x2;
+  int  tot, i, x1, x2;
   char foo[60], foo1[60];
 
   /* compute longest string necessary so we can right-align this thing */
-  sprintf(foo,"%d",dp->min);    x1 = strlen(foo);
-  sprintf(foo,"%d",dp->max);    x2 = strlen(foo);
+  sprintf(foo,"%d",(int)dp->min);    x1 = strlen(foo);
+  sprintf(foo,"%d",(int)dp->max);    x2 = strlen(foo);
   if (dp->min < 0 && dp->max > 0) x2++;   /* put '+' at beginning */
   i = x1;  if (x2>x1) i = x2;
   if (dp->units) i += strlen(dp->units);
 
-  if (dp->min < 0 && dp->max > 0) sprintf(foo,"%+d", dp->val);
-  else sprintf(foo,"%d", dp->val);
+  sprintf(foo,"%g",dp->inc);   /* space for decimal values */
+  tot = i + strlen(foo) - 1;   /* Take away the 0 from the beginning */
+
+  if (dp->min < 0.0 && dp->max > 0.0) sprintf(foo,"%+g", dp->val);
+  else sprintf(foo,"%g", dp->val);
+
+  if (dp->inc < 1.0)
+  {
+    int j;
+
+    if (dp->val == (double)((int)dp->val))
+      strcat(foo,".");
+
+    for (j = strlen(foo); j < tot; j++)
+      strcat(foo,"0");
+  }
 
   if (dp->units) strcat(foo,dp->units);
   foo1[0] = '\0';
   if (strlen(foo) < (size_t) i) {
-    for (i = i - strlen(foo); i>0; i--) strcat(foo1," ");
+    for (i-=strlen(foo);i>0;i--) strcat(foo1," ");
   }
   strcat(foo1, foo);
 
   XSetForeground(theDisp, theGC, dp->fg);
   XSetBackground(theDisp, theGC, dp->bg);
   XSetFont(theDisp, theGC, monofont);
-  XDrawImageString(theDisp, dp->win, theGC, 
+  XDrawImageString(theDisp, dp->win, theGC,
 		   dp->w/2 - XTextWidth(monofinfo, foo1, (int) strlen(foo1))/2,
 		   dp->h-14 - (monofinfo->ascent + monofinfo->descent)/2
-		                                 + monofinfo->ascent, 
+		                                 + monofinfo->ascent,
 		   foo1, (int) strlen(foo1));
   XSetFont(theDisp, theGC, mfont);
 }
@@ -411,12 +430,13 @@
 
 
 /***************************************************/
-static int computeDialVal(dp, x, y)
+static double computeDialVal(dp, x, y)
 DIAL *dp;
 int x, y;
 {
-  int dx, dy, val;
-  double angle;
+  int dx, dy;
+
+  double angle, val;
 
   /* compute dx, dy (distance from cx, cy).  Note: +dy is *up* */
   dx = x - dp->cx;  dy = dp->cy - y;
@@ -431,13 +451,15 @@
   }
   else if (dx>0) angle = atan((double)  dy / (double)  dx) * RAD2DEG;
   else           angle = atan((double) -dy / (double) -dx) * RAD2DEG + 180.0;
-    
+
   /* map angle into range: -90..270, then into to value */
   if (angle > 270.0) angle -= 360.0;
   if (angle < -90.0) angle += 360.0;
 
-  val = (int) ((dp->max - dp->min) * (240.0 - angle) / 300.0) + dp->min;
+  val = ((dp->max - dp->min) * (240.0 - angle) / 300.0) + dp->min;
 
+  /* round value to be an even multiple of dp->inc */
+  val = (double)((int)(val / dp->inc + 0.5)) * dp->inc;
   return val;
 }
 
diff -ru xv-3.10a/xvdir.c xv-3.10a-enhancements/xvdir.c
--- xv-3.10a/xvdir.c	1995-01-03 13:21:39.000000000 -0800
+++ xv-3.10a-enhancements/xvdir.c	2007-05-13 18:47:51.000000000 -0700
@@ -1,4 +1,4 @@
-/* 
+/*
  * xvdir.c - Directory changin', file i/o dialog box
  *
  * callable functions:
@@ -50,32 +50,63 @@
 #define COLWIDE  150               /* width of colMB */
 
 /* NOTE: make sure these match up with F_* definitions in xv.h */
-static char *saveColors[] = { "Full Color", 
-			      "Greyscale",
-			      "B/W Dithered",
-			      "Reduced Color" };
-
-static char *saveFormats[] = { "GIF",
+static const char *saveColors[] = { "Full Color",
+				    "Greyscale",
+				    "B/W Dithered",
+				    "Reduced Color" };
+
+static const char *saveFormats[] = {
+#ifdef HAVE_PNG
+					"PNG",
+#endif
 #ifdef HAVE_JPEG
-			       "JPEG",
+					"JPEG",
 #endif
+#ifdef HAVE_JP2K
+					"JPEG 2000",
+					"JP2",
+#endif 
+					"GIF",
 #ifdef HAVE_TIFF
-			       "TIFF",
+					"TIFF",
+#endif
+					"PostScript",
+					"PBM/PGM/PPM (raw)",
+					"PBM/PGM/PPM (ascii)",
+					"X11 Bitmap",
+					"XPM",
+					"BMP",
+					"Sun Rasterfile",
+					"IRIS RGB",
+					"Targa (24-bit)",
+					"FITS",
+					"PM",
+					"Spectrum SCREEN$",	/* [JCE] */
+					"WBMP",
+#ifdef HAVE_MAG
+					"MAG",
+#endif
+#ifdef HAVE_PIC
+					"PIC",
+#endif
+#ifdef HAVE_MAKI
+					"MAKI (640x400 only)",
+#endif
+#ifdef HAVE_PI
+					"PI",
+#endif
+#ifdef HAVE_PIC2
+					"PIC2",
+#endif
+#ifdef HAVE_MGCSFX
+					"MgcSfx",
 #endif
-			       "PostScript",
-			       "PBM/PGM/PPM (raw)",
-			       "PBM/PGM/PPM (ascii)",
-			       "X11 Bitmap",
-			       "XPM",
-			       "BMP",
-			       "Sun Rasterfile",
-			       "IRIS RGB",
-			       "Targa (24-bit)",
-			       "FITS",
-			       "PM",
-			       MBSEP,
-			       "Filename List"};
+					MBSEP,
+					"Filename List" };
 
+#ifdef HAVE_PIC2
+extern int PIC2SaveParams    PARM((char *, int));
+#endif
 
 static void arrangeButts     PARM((int));
 static void RedrawDList      PARM((int, SCRL *));
@@ -83,34 +114,37 @@
 static int  dnamcmp          PARM((const void *, const void *));
 static int  FNameCdable      PARM((void));
 static void loadCWD          PARM((void));
+#ifdef FOO
 static int  cd_able          PARM((char *));
+#endif
 static void scrollToFileName PARM((void));
-static void setFName         PARM((char *));
+static void setFName         PARM((const char *));
 static void showFName        PARM((void));
 static void changeSuffix     PARM((void));
 static int  autoComplete     PARM((void));
 
-static byte *handleBWandReduced   PARM((byte *, int,int,int, int, int *, 
+static byte *handleBWandReduced   PARM((byte *, int,int,int, int, int *,
 					byte **, byte **, byte **));
 static byte *handleNormSel        PARM((int *, int *, int *, int *));
 
 
-static char  *fnames[MAXNAMES];
-static int    numfnames = 0, ndirs = 0;
-static char   path[MAXPATHLEN+1];       /* '/' terminated */
-static char   loadpath[MAXPATHLEN+1];   /* '/' terminated */
-static char   savepath[MAXPATHLEN+1];   /* '/' terminated */
-static char  *dirs[MAXDEEP];            /* list of directory names */
-static char  *dirMBlist[MAXDEEP];       /* list of dir names in right order */
-static char  *lastdir;                  /* name of the directory we're in */
-static char   filename[MAXFNLEN+100];   /* filename being entered */
-static char   deffname[MAXFNLEN+100];   /* default filename */
-
-static int    savemode;                 /* if 0 'load box', if 1 'save box' */
-static int    curPos, stPos, enPos;     /* filename textedit stuff */
-static MBUTT  dirMB;                    /* popup path menu */
-static MBUTT  fmtMB;                    /* 'format' menu button (Save only) */
-static MBUTT  colMB;                    /* 'colors' menu button (Save only) */
+static char       *fnames[MAXNAMES];
+static int         numfnames = 0, ndirs = 0;
+static char        path[MAXPATHLEN+1];       /* '/' terminated */
+static char        loadpath[MAXPATHLEN+1];   /* '/' terminated */
+static char        savepath[MAXPATHLEN+1];   /* '/' terminated */
+static char       *dirs[MAXDEEP];            /* list of directory names */
+static const char *dirMBlist[MAXDEEP];       /* list of dir names in right order */
+static char       *lastdir;                  /* name of the directory we're in */
+static char        filename[MAXFNLEN+100];   /* filename being entered */
+static char        deffname[MAXFNLEN+100];   /* default filename */
+
+static int   savemode;                 /* if 0 'load box', if 1 'save box' */
+static int   curPos;                   /* insertion point in textedit filename */
+static int   stPos, enPos;             /* start and end of visible textedit filename */
+static MBUTT dirMB;                    /* popup path menu */
+static MBUTT fmtMB;                    /* 'format' menu button (Save only) */
+static MBUTT colMB;                    /* 'colors' menu button (Save only) */
 
 static Pixmap d_loadPix, d_savePix;
 
@@ -119,7 +153,7 @@
 static char oldfname[MAXFNLEN+100];
 
 /* the name of the file actually opened.  (the temp file if we are piping) */
-static char outFName[256];  
+static char outFName[256];
 static int  dopipe;
 
 
@@ -127,48 +161,46 @@
 void CreateDirW(geom)
      char *geom;
 {
-  int w, y;
-  
   path[0] = '\0';
 
   xv_getwd(loadpath, sizeof(loadpath));
   xv_getwd(savepath, sizeof(savepath));
 
-  
+
   dirW = CreateWindow("","XVdir", geom, DIRWIDE, DIRHIGH, infofg, infobg, 0);
   if (!dirW) FatalError("couldn't create 'directory' window!");
 
-  LSCreate(&dList, dirW, 10, 5 + 3*(6+LINEHIGH) + 6, LISTWIDE, 
-	   LINEHIGH*NLINES, NLINES, fnames, numfnames, infofg, infobg, 
+  LSCreate(&dList, dirW, 10, 5 + 3*(6+LINEHIGH) + 6, LISTWIDE,
+	   LINEHIGH*NLINES, NLINES, fnames, numfnames, infofg, infobg,
 	   hicol, locol, RedrawDList, 1, 0);
 
-  dnamW = XCreateSimpleWindow(theDisp, dirW, 80, dList.y + (int) dList.h + 30, 
-			      (u_int) DNAMWIDE+6, (u_int) LINEHIGH+5, 
+  dnamW = XCreateSimpleWindow(theDisp, dirW, 80, dList.y + (int) dList.h + 30,
+			      (u_int) DNAMWIDE+6, (u_int) LINEHIGH+5,
 			      1, infofg, infobg);
   if (!dnamW) FatalError("can't create name window");
   XSelectInput(theDisp, dnamW, ExposureMask);
 
 
-  CBCreate(&browseCB,   dirW, DIRWIDE/2, dList.y + (int) dList.h + 6, 
+  CBCreate(&browseCB,   dirW, DIRWIDE/2, dList.y + (int) dList.h + 6,
 	   "Browse", infofg, infobg, hicol,locol);
 
-  CBCreate(&savenormCB, dirW, 220, dList.y + (int) dList.h + 6, 
+  CBCreate(&savenormCB, dirW, 220, dList.y + (int) dList.h + 6,
 	   "Normal Size", infofg, infobg,hicol,locol);
 
-  CBCreate(&saveselCB,  dirW, 80,        dList.y + (int) dList.h + 6, 
+  CBCreate(&saveselCB,  dirW, 80,        dList.y + (int) dList.h + 6,
            "Selected Area", infofg, infobg,hicol,locol);
 
 
   /* y-coordinates get filled in when window is opened */
-  BTCreate(&dbut[S_BOK],     dirW, 259, 0, 80, BUTTH, 
+  BTCreate(&dbut[S_BOK],     dirW, 259, 0, 80, BUTTH,
 	   "Ok",        infofg, infobg,hicol,locol);
-  BTCreate(&dbut[S_BCANC],   dirW, 259, 0, 80, BUTTH, 
+  BTCreate(&dbut[S_BCANC],   dirW, 259, 0, 80, BUTTH,
 	   "Cancel",    infofg,infobg,hicol,locol);
-  BTCreate(&dbut[S_BRESCAN], dirW, 259, 0, 80, BUTTH, 
+  BTCreate(&dbut[S_BRESCAN], dirW, 259, 0, 80, BUTTH,
 	   "Rescan",    infofg,infobg,hicol,locol);
-  BTCreate(&dbut[S_BOLDSET], dirW, 259, 0, 80, BUTTH, 
+  BTCreate(&dbut[S_BOLDSET], dirW, 259, 0, 80, BUTTH,
 	   "Prev Set",  infofg,infobg,hicol,locol);
-  BTCreate(&dbut[S_BOLDNAM], dirW, 259, 0, 80, BUTTH, 
+  BTCreate(&dbut[S_BOLDNAM], dirW, 259, 0, 80, BUTTH,
 	   "Prev Name", infofg,infobg,hicol,locol);
 
   SetDirFName("");
@@ -180,33 +212,33 @@
    * create MBUTTs *after* calling XMapSubWindows() to keep popup unmapped
    */
 
-  MBCreate(&dirMB, dirW, 50, dList.y -(LINEHIGH+6), 
+  MBCreate(&dirMB, dirW, 50, dList.y -(LINEHIGH+6),
 	   (u_int) DDWIDE, (u_int) LINEHIGH, NULL, NULL, 0,
 	   infofg,infobg,hicol,locol);
 
-  MBCreate(&fmtMB, dirW, DIRWIDE-FMTWIDE-10, 5,            
-	   (u_int) FMTWIDE, (u_int) LINEHIGH, NULL, saveFormats, F_MAXFMTS, 
+  MBCreate(&fmtMB, dirW, DIRWIDE-FMTWIDE-10, 5,
+	   (u_int) FMTWIDE, (u_int) LINEHIGH, NULL, saveFormats, F_MAXFMTS,
 	   infofg,infobg,hicol,locol);
   fmtMB.hascheck = 1;
   MBSelect(&fmtMB, 0);
 
-  MBCreate(&colMB, dirW, DIRWIDE-COLWIDE-10, 5+LINEHIGH+6, 
-	   (u_int) COLWIDE, (u_int) LINEHIGH, NULL, saveColors, F_MAXCOLORS, 
+  MBCreate(&colMB, dirW, DIRWIDE-COLWIDE-10, 5+LINEHIGH+6,
+	   (u_int) COLWIDE, (u_int) LINEHIGH, NULL, saveColors, F_MAXCOLORS,
 	   infofg,infobg,hicol,locol);
   colMB.hascheck = 1;
   MBSelect(&colMB, 0);
 
 
-  d_loadPix = XCreatePixmapFromBitmapData(theDisp, dirW, 
-                 (char *) d_load_bits, d_load_width, d_load_height, 
+  d_loadPix = XCreatePixmapFromBitmapData(theDisp, dirW,
+                 (char *) d_load_bits, d_load_width, d_load_height,
 					  infofg, infobg, dispDEEP);
 
-  d_savePix = XCreatePixmapFromBitmapData(theDisp, dirW, 
-                 (char *) d_save_bits, d_save_width, d_save_height, 
+  d_savePix = XCreatePixmapFromBitmapData(theDisp, dirW,
+                 (char *) d_save_bits, d_save_width, d_save_height,
 					  infofg, infobg, dispDEEP);
 
 }
-  
+
 
 /***************************************************/
 void DirBox(mode)
@@ -261,7 +293,7 @@
 
     BTSetActive(&dbut[S_BOLDSET], haveoldinfo);
     BTSetActive(&dbut[S_BOLDNAM], haveoldinfo);
-    
+
     CBSetActive(&saveselCB, HaveSelection());
 
     MBSetActive(&fmtMB, 1);
@@ -303,15 +335,15 @@
   if (gap>16) {
     gap = 16;
     top = dList.y + (dList.h - (nbts*BUTTH) - (ngaps*gap))/2;
-    
+
     for (i=0; i<nbts; i++) dbut[i].y = top + i*(BUTTH+gap);
   }
   else {
-    for (i=0; i<nbts; i++) 
+    for (i=0; i<nbts; i++)
       dbut[i].y = dList.y + ((dList.h-BUTTH)*i) / ngaps;
   }
 }
-    
+
 
 
 /***************************************************/
@@ -319,24 +351,24 @@
      int x,y,w,h;
 {
   int        i, ypos, txtw;
-  char       foo[30], *str;
-  XRectangle xr;
+  char       foo[30];
+  const char *str;
 
   if (dList.nstr==1) strcpy(foo,"1 file");
                 else sprintf(foo,"%d files",dList.nstr);
 
   ypos = dList.y + dList.h + 8 + ASCENT;
   XSetForeground(theDisp, theGC, infobg);
-  XFillRectangle(theDisp, dirW, theGC, 10, ypos-ASCENT, 
+  XFillRectangle(theDisp, dirW, theGC, 10, ypos-ASCENT,
 		 (u_int) DIRWIDE, (u_int) CHIGH);
   XSetForeground(theDisp, theGC, infofg);
   DrawString(dirW, 10, ypos, foo);
 
 
-  if (dirUp == BLOAD) str = "Load file:";  
+  if (dirUp == BLOAD) str = "Load file:";
                  else str = "Save file:";
   DrawString(dirW, 10, dList.y + (int) dList.h + 30 + 4 + ASCENT, str);
-  
+
   /* draw dividing line */
   XSetForeground(theDisp,    theGC, infofg);
   XDrawLine(theDisp, dirW,   theGC, 0, dirMB.y-6, DIRWIDE, dirMB.y-6);
@@ -346,11 +378,11 @@
     XSetForeground(theDisp,  theGC, hicol);
   }
   XDrawLine(theDisp, dirW,   theGC, 0, dirMB.y-4, DIRWIDE, dirMB.y-4);
-  
-  
-  
+
+
+
   for (i=0; i<(savemode ? S_NBUTTS : S_LOAD_NBUTTS); i++) BTRedraw(&dbut[i]);
-  
+
   MBRedraw(&dirMB);
   MBRedraw(&fmtMB);
   MBRedraw(&colMB);
@@ -362,7 +394,7 @@
   if (StringWidth(COLLABEL) > txtw) txtw = StringWidth(COLLABEL);
 
   if (!savemode) {
-    XCopyArea(theDisp, d_loadPix, dirW, theGC, 0,0,d_load_width,d_load_height, 
+    XCopyArea(theDisp, d_loadPix, dirW, theGC, 0,0,d_load_width,d_load_height,
 	      10, (dirMB.y-6)/2 - d_load_height/2);
 
     XSetFillStyle(theDisp, theGC, FillStippled);
@@ -399,18 +431,18 @@
     i = v = 0;
     if      (MBClick(&fmtMB, x,y) && (v=MBTrack(&fmtMB))>=0) i=1;
     else if (MBClick(&colMB, x,y) && (v=MBTrack(&colMB))>=0) i=2;
-    
+
     if (i) {  /* changed one of them */
       if (i==1) SetDirSaveMode(F_FORMAT, v);
            else SetDirSaveMode(F_COLORS, v);
       changeSuffix();
     }
   }
-  
-  
+
+
   if (!savemode) {  /* LOAD */
     if (CBClick(&browseCB,x,y)) CBTrack(&browseCB);
-  } 
+  }
   else {            /* SAVE */
     if      (CBClick(&savenormCB,x,y)) CBTrack(&savenormCB);
     else if (CBClick(&saveselCB,x,y))  CBTrack(&saveselCB);
@@ -482,7 +514,7 @@
       }
 
       if (oldnumnames != numnames) {  /* added some */
-	if (numnames>0) BTSetActive(&but[BDELETE],1); 
+	if (numnames>0) BTSetActive(&but[BDELETE],1);
 	windowMB.dim[WMB_TEXTVIEW] = (numnames==0);
 
 	LSNewData(&nList, dispnames, numnames);
@@ -501,10 +533,35 @@
   }
 
 
-
   if (MBClick(&dirMB, x, y)) {
     i = MBTrack(&dirMB);
     if (i >= 0) changedDirMB(i);
+    return -1;
+  }
+
+  /* handle clicks inside the filename box */
+  if (x > 80 &&
+      y > dList.y + (int) dList.h + 30 &&
+      x < 80 + DNAMWIDE+6 &&
+      y < dList.y + (int) dList.h + 30 + LINEHIGH+5) {
+    int tx;
+    int dx;
+    int pos;
+
+    /* make coordinates relative to dnamW */
+    tx = x - (80 + 1 + 3); /* left side plus the border plus the space for the "more stuff" sign */
+
+    for (pos=stPos; pos+1 < enPos; pos++) {
+      if (XTextWidth(mfinfo, &filename[stPos], 1+pos-stPos) > tx)
+        break;
+    }
+    /* if we are more than halfway past this char, put the insertion point after it */
+    dx = tx - XTextWidth(mfinfo, &filename[stPos], pos-stPos);
+    if (dx > XTextWidth(mfinfo, &filename[pos], 1)/2)
+      pos++;
+
+    curPos = pos;
+    showFName();
   }
 
   return -1;
@@ -564,14 +621,18 @@
      *  a special concealed device setup to provide a list of available
      *  disks).
      */
-    if ( ((ndirs-sel) == 2) && (strlen(tmppath) > 1) ) 
+    if ( ((ndirs-sel) == 2) && (strlen(tmppath) > 1) )
       strcat ( tmppath, "/000000" ); /* add root dir for device */
     else if  ((ndirs-sel) == 1 ) {
       strcpy ( tmppath, "/XV_Root_Device/000000" );  /* fake top level */
     }
 #endif
 
+#ifdef AUTO_EXPAND
+    if (Chvdir(tmppath)) {
+#else
     if (chdir(tmppath)) {
+#endif
       char str[512];
       sprintf(str,"Unable to cd to '%s'\n", tmppath);
       *trunc_point = '/';  /* restore the path */
@@ -602,7 +663,7 @@
   xv_getwd(path, sizeof(path));
   LoadCurrentDirectory();
 }
-  
+
 
 
 /***************************************************/
@@ -621,14 +682,14 @@
 #else
   struct dirent *dp;
 #endif
-  
+
 
   /* get rid of previous file names */
   for (i=0; i<numfnames; i++) free(fnames[i]);
   numfnames = 0;
 
   /* get rid of old dirMBlist */
-  for (i=0; i<ndirs; i++) free(dirMBlist[i]);
+  for (i=0; i<ndirs; i++) free((char *) dirMBlist[i]);
 
 #ifndef VMS
   if (strlen(path) == 0) xv_getwd(path, sizeof(path));  /* no dir, use cwd */
@@ -636,7 +697,11 @@
   xv_getwd(path, sizeof(path));
 #endif
 
+#ifdef AUTO_EXPAND
+  if (Chvdir(path)) {
+#else
   if (chdir(path)) {
+#endif
     ErrPopUp("Current load/save directory seems to have gone away!",
 	     "\nYikes!");
 #ifdef apollo
@@ -644,7 +709,11 @@
 #else
     strcpy(path,"/");
 #endif
+#ifdef AUTO_EXPAND
+    Chvdir(path);
+#else
     chdir(path);
+#endif
   }
 
   changedDir = strcmp(path, oldpath);
@@ -673,19 +742,22 @@
 
   /* build dirMBlist */
   for (i=ndirs-1,j=0; i>=0; i--,j++) {
-    size_t stlen = (i<(ndirs-1)) ? dirs[i+1] - dirs[i] : strlen(dirs[i]);
-    dirMBlist[j] = (char *) malloc(stlen+1);
-    if (!dirMBlist[j]) FatalError("unable to malloc dirMBlist[]");
+    size_t  stlen = (i<(ndirs-1)) ? dirs[i+1] - dirs[i] : strlen(dirs[i]);
+    char   *copy;
+
+    copy = malloc(stlen+1);
+    if (!copy) FatalError("unable to malloc dirMBlist[]");
 
-    strncpy(dirMBlist[j], dirs[i], stlen);
-    dirMBlist[j][stlen] = '\0';
+    strncpy(copy, dirs[i], stlen);
+    copy[stlen] = '\0';
+    dirMBlist[j] = copy;
   }
-    
+
 
   lastdir = dirs[ndirs-1];
   dirMB.list = dirMBlist;
   dirMB.nlist = ndirs;
-  XClearArea(theDisp, dirMB.win, dirMB.x, dirMB.y, 
+  XClearArea(theDisp, dirMB.win, dirMB.x, dirMB.y,
 	     (u_int) dirMB.w+3, (u_int) dirMB.h+3, False);
   i = StringWidth(dirMBlist[0]) + 10;
   dirMB.x = dirMB.x + dirMB.w/2 - i/2;
@@ -704,8 +776,8 @@
 
   i=0;
   while ( (dp = readdir(dirp)) != NULL) {
-    if (strcmp(dp->d_name, ".")==0   || 
-	(strcmp(dp->d_name, "..")==0 && 
+    if (strcmp(dp->d_name, ".")==0   ||
+	(strcmp(dp->d_name, "..")==0 &&
 	 (strcmp(path,"/")==0 || strcmp(path,"//")==0)) ||
 	strcmp(dp->d_name, THUMBDIR)==0) {
       /* skip over '.' and '..' and THUMBDIR */
@@ -714,7 +786,7 @@
 
       if (i == MAXNAMES) {
 	fprintf(stderr,
-		"%s: too many directory entries.  Only using first %d.\n",
+		"%s: too many directory entries.  Using only first %d.\n",
 		cmd, MAXNAMES);
 	break;
       }
@@ -733,7 +805,7 @@
       /* For VMS we will default all files EXCEPT directories to avoid
 	 the high cost of the VAX C implementation of the stat function.
 	 Suggested by Kevin Oberman (OBERMAN@icdc.llnl.gov) */
- 
+
       if (xv_strstr (fnames[i]+1, ".DIR") != NULL) fnames[i][0] = C_DIR;
       if (xv_strstr (fnames[i]+1, ".EXE") != NULL) fnames[i][0] = C_EXE;
       if (xv_strstr (fnames[i]+1, ".OBJ") != NULL) fnames[i][0] = C_BLK;
@@ -749,6 +821,9 @@
 	else if (S_ISFIFO(ftype)) fnames[i][0] = C_FIFO;
 	else if (S_ISSOCK(ftype)) fnames[i][0] = C_SOCK;
         else if (fnames[i][0] == C_REG && (mode&0111)) fnames[i][0] = C_EXE;
+#ifdef AUTO_EXPAND
+	else if (Isarchive(fnames[i]+1)) fnames[i][0] = C_DIR;
+#endif
       }
       else {
 	/* fprintf(stderr,"problems 'stat-ing' files\n");*/
@@ -784,11 +859,13 @@
 
 
 /***************************************************/
+#ifdef FOO
 static int cd_able(str)
 char *str;
 {
   return ((str[0] == C_DIR || str[0] == C_LNK));
 }
+#endif /* FOO */
 
 
 /***************************************************/
@@ -829,24 +906,28 @@
   int len;
 
   len = strlen(filename);
-  
+
   if (c>=' ' && c<'\177') {             /* printable characters */
     /* note: only allow 'piped commands' in savemode... */
 
+#undef PREVENT_SPACES /* Spaces are fine in filenames. */
+#ifdef PREVENT_SPACES
     /* only allow spaces in 'piped commands', not filenames */
     if (c==' ' && (!ISPIPE(filename[0]) || curPos==0)) return (-1);
+#endif
 
     /* only allow vertbars in 'piped commands', not filenames */
     if (c=='|' && curPos!=0 && !ISPIPE(filename[0])) return(-1);
 
     if (len >= MAXFNLEN-1) return(-1);  /* max length of string */
+
     xvbcopy(&filename[curPos], &filename[curPos+1], (size_t) (len-curPos+1));
     filename[curPos]=c;  curPos++;
 
     scrollToFileName();
   }
 
-  else if (c=='\010' || c=='\177') {    /* BS or DEL */
+  else if (c=='\010') {                 /* BS */
     if (curPos==0) return(-1);          /* at beginning of str */
     xvbcopy(&filename[curPos], &filename[curPos-1], (size_t) (len-curPos+1));
     curPos--;
@@ -871,7 +952,7 @@
     curPos = len;
   }
 
-  else if (c=='\004') {                 /* ^D: delete character at curPos */
+  else if (c=='\004' || c=='\177') {    /* ^D or DEL: delete character at curPos */
     if (curPos==len) return(-1);
     xvbcopy(&filename[curPos+1], &filename[curPos], (size_t) (len-curPos));
   }
@@ -918,19 +999,19 @@
 {
   /* called to 'auto complete' a filename being entered.  If the name that
      has been entered so far is anything but a simple filename (ie, has
-     spaces, pipe char, '/', etc) fails.  If it is a simple filename, 
+     spaces, pipe char, '/', etc) fails.  If it is a simple filename,
      looks through the name list to find something that matches what's already
      been typed.  If nothing matches, it fails.  If more than one thing
      matches, it sets the name to the longest string that the multiple
-     matches have in common, and succeeds (and beeps).  
+     matches have in common, and succeeds (and beeps).
      If only one matches, sets the string to the match and succeeds.
-     
+
      returns zero on failure, non-zero on success */
-  
+
   int i, firstmatch, slen, nummatch, cnt;
 
   /* is filename a simple filename? */
-  if (strlen(filename)==0  || 
+  if (strlen(filename)==0  ||
       ISPIPE(filename[0])  ||
       index(filename, '/') ||
       filename[0]=='~'   ) return 0;
@@ -946,7 +1027,7 @@
   firstmatch = i;
 
   /* count # of matches */
-  for (i=firstmatch, nummatch=0; 
+  for (i=firstmatch, nummatch=0;
        i<dList.nstr && strncmp(filename, dList.str[i]+1, (size_t) slen)==0;
        i++, nummatch++);
 
@@ -960,14 +1041,14 @@
   while (dList.str[firstmatch][slen+1]!='\0') {
     filename[slen] = dList.str[firstmatch][slen+1];
     slen++;  filename[slen] = '\0';
-    
+
     for (i=firstmatch, cnt=0;
 	 i<dList.nstr && strncmp(filename, dList.str[i]+1, (size_t) slen)==0;
 	 i++, cnt++);
 
     if (cnt != nummatch) {  slen--;  filename[slen] = '\0';  break; }
-  }  
-  
+  }
+
   XBell(theDisp, 0);
 
   return 1;
@@ -1003,7 +1084,7 @@
   i = pos - (NLINES/2);
   SCSetVal(&dList.scrl, i);
 }
-  
+
 
 /***************************************************/
 void RedrawDNamW()
@@ -1012,7 +1093,7 @@
 
   /* draw substring filename[stPos:enPos] and cursor */
 
-  Draw3dRect(dnamW, 0, 0, (u_int) DNAMWIDE+5, (u_int) LINEHIGH+4, R3D_IN, 2, 
+  Draw3dRect(dnamW, 0, 0, (u_int) DNAMWIDE+5, (u_int) LINEHIGH+4, R3D_IN, 2,
 	     hicol, locol, infobg);
 
   XSetForeground(theDisp, theGC, infofg);
@@ -1023,7 +1104,7 @@
     XDrawLine(theDisp, dnamW, theGC, 2,0,2,LINEHIGH+5);
   }
 
-  if ((size_t) enPos < strlen(filename)) { 
+  if ((size_t) enPos < strlen(filename)) {
     /* draw a "there's more over here" doowah */
     XDrawLine(theDisp, dnamW, theGC, DNAMWIDE+5,0,DNAMWIDE+5,LINEHIGH+5);
     XDrawLine(theDisp, dnamW, theGC, DNAMWIDE+4,0,DNAMWIDE+4,LINEHIGH+5);
@@ -1032,6 +1113,7 @@
 
   XDrawString(theDisp, dnamW, theGC,3,ASCENT+3,filename+stPos, enPos-stPos);
 
+  /* draw insertion point */
   cpos = XTextWidth(mfinfo, &filename[stPos], curPos-stPos);
   XDrawLine(theDisp, dnamW, theGC, 3+cpos, 2, 3+cpos, 2+CHIGH+1);
   XDrawLine(theDisp, dnamW, theGC, 3+cpos, 2+CHIGH+1, 5+cpos, 2+CHIGH+3);
@@ -1054,10 +1136,29 @@
 
   fullname = GetDirFullName();
 
+#ifdef AUTO_EXPAND
+  {
+      char path[MAXPATHLEN];
+
+      GetDirPath(path);
+      Mkvdir(path);
+      if ((i = Isvdir(fullname)) & 01) {
+	  char buf[128];
+	  sprintf(buf,
+		  "Sorry, you can't save file in the virtual directory, '%s'",
+		  path);
+	  ErrPopUp(buf, "\nBummer!");
+	  return -1;
+      }
+      if (i & 06)
+	  Rmvdir(fullname);
+  }
+#endif
+
   fmt = MBWhich(&fmtMB);
   col = MBWhich(&colMB);
 
-  if (fmt<0 || col<0) 
+  if (fmt<0 || col<0)
     FatalError("xv: no 'checked' format or color.  shouldn't happen!\n");
 
 
@@ -1068,19 +1169,19 @@
       dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
       return -1;
     }
-    
+
     for (i=0; i<numnames; i++) {
       if ((i&0x3f)==0) WaitCursor();
       if (namelist[i][0] != '/') fprintf(fp, "%s/%s\n", initdir, namelist[i]);
                             else fprintf(fp, "%s\n", namelist[i]);
     }
-    
+
     i = (ferror(fp)) ? 1 : 0;
     if (CloseOutFile(fp, fullname, i) == 0) {
       DirBox(0);
       XVCreatedFile(fullname);
     }
-    
+
     SetCursors(-1);
     dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
     return i;
@@ -1100,7 +1201,16 @@
 #ifdef HAVE_JPEG
   else if (fmt == F_JPEG) {   /* JPEG */
     JPEGSaveParams(fullname, col);
-    JPEGDialog(1);                   /* open JPEGDialog box */
+    JPEGDialog(1);                 /* open JPEGDialog box */
+    dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
+    return 0;                      /* always 'succeeds' */
+  }
+#endif
+
+#ifdef HAVE_JP2K
+  else if (fmt == F_JPC || fmt == F_JP2) {   /* JPEG 2000 */
+    JP2KSaveParams(fmt, fullname, col);
+    JP2KDialog(1);                 /* open JP2KDialog box */
     dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
     return 0;                      /* always 'succeeds' */
   }
@@ -1109,13 +1219,40 @@
 #ifdef HAVE_TIFF
   else if (fmt == F_TIFF) {   /* TIFF */
     TIFFSaveParams(fullname, col);
-    TIFFDialog(1);                   /* open TIFF Dialog box */
+    TIFFDialog(1);                 /* open TIFF Dialog box */
+    dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
+    return 0;                      /* always 'succeeds' */
+  }
+#endif
+
+#ifdef HAVE_PNG
+  else if (fmt == F_PNG) {   /* PNG */
+    PNGSaveParams(fullname, col);
+    PNGDialog(1);                  /* open PNG Dialog box */
     dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
     return 0;                      /* always 'succeeds' */
   }
 #endif
 
+#ifdef HAVE_PIC2
+  else if (fmt == F_PIC2) {   /* PIC2 */
+    if (PIC2SaveParams(fullname, col) < 0)
+	return 0;
+    PIC2Dialog(1);                   /* open PIC2 Dialog box */
+    dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
+    return 0;                      /* always 'succeeds' */
+  }
+#endif /* HAVE_PIC2 */
 
+#ifdef HAVE_MGCSFX
+  else if (fmt == F_MGCSFX) {   /* MGCSFX */
+    if (MGCSFXSaveParams(fullname, col) < 0)
+	return 0;
+    MGCSFXDialog(1);                   /* open MGCSFX Dialog box */
+    dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
+    return 0;                      /* always 'succeeds' */
+  }
+#endif /* HAVE_MGCSFX */
 
 
   WaitCursor();
@@ -1147,34 +1284,74 @@
     rv = WritePBM   (fp, thepic, ptype, w, h, rp,gp,bp, nc,col,1,picComments);
     break;
 
-  case F_PBMASCII: 
+  case F_PBMASCII:
     rv = WritePBM   (fp, thepic, ptype, w, h, rp,gp,bp, nc,col,0,picComments);
     break;
 
   case F_XBM:
-    rv = WriteXBM   (fp, thepic, w, h, rp, gp, bp, fullname);          break;
+    rv = WriteXBM   (fp, thepic, w, h, rp, gp, bp, fullname);
+    break;
 
   case F_SUNRAS:
-    rv = WriteSunRas(fp, thepic, ptype, w, h, rp, gp, bp, nc, col,0);  break;
+    rv = WriteSunRas(fp, thepic, ptype, w, h, rp, gp, bp, nc, col,0);
+    break;
 
   case F_BMP:
-    rv = WriteBMP   (fp, thepic, ptype, w, h, rp, gp, bp, nc, col);    break;
+    rv = WriteBMP   (fp, thepic, ptype, w, h, rp, gp, bp, nc, col);
+    break;
+
+  case F_WBMP:
+    rv = WriteWBMP  (fp, thepic, ptype, w, h, rp, gp, bp, nc, col);
+    break;
 
   case F_IRIS:
-    rv = WriteIRIS  (fp, thepic, ptype, w, h, rp, gp, bp, nc, col);    break;
-    
+    rv = WriteIRIS  (fp, thepic, ptype, w, h, rp, gp, bp, nc, col);
+    break;
+
   case F_TARGA:
-    rv = WriteTarga (fp, thepic, ptype, w, h, rp, gp, bp, nc, col);    break;
-    
+    rv = WriteTarga (fp, thepic, ptype, w, h, rp, gp, bp, nc, col);
+    break;
+
   case F_XPM:
-    rv = WriteXPM   (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, 
-		     fullname, picComments);    
+    rv = WriteXPM   (fp, thepic, ptype, w, h, rp, gp, bp, nc, col,
+		     fullname, picComments);
+    break;
+
   case F_FITS:
-    rv = WriteFITS  (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, 
-		     picComments);    
+    rv = WriteFITS  (fp, thepic, ptype, w, h, rp, gp, bp, nc, col,
+		     picComments);
+    break;
+
+  case F_ZX:		/* [JCE] Spectrum SCREEN$ */
+    rv = WriteZX    (fp, thepic, ptype, w, h, rp, gp, bp, nc, col,
+		     picComments);
+    break;
+#ifdef HAVE_MAG
+  case F_MAG:
+    rv = WriteMAG   (fp, thepic, ptype, w, h, rp, gp, bp, nc, col,
+		     picComments);
+    break;
+#endif /* HAVE_MAG */
+#ifdef HAVE_PIC
+  case F_PIC:
+    rv = WritePIC   (fp, thepic, ptype, w, h, rp, gp, bp, nc, col,
+		     picComments);
     break;
+#endif /* HAVE_PIC */
+#ifdef HAVE_MAKI
+  case F_MAKI:
+    rv = WriteMAKI  (fp, thepic, ptype, w, h, rp, gp, bp, nc, col);
+    break;
+#endif /* HAVE_MAKI */
+
+#ifdef HAVE_PI
+  case F_PI:
+    rv = WritePi    (fp, thepic, ptype, w, h, rp, gp, bp, nc, col,
+		     picComments);
+    break;
+#endif /* HAVE_PI */
   }
-  
+
 
   if (CloseOutFile(fp, fullname, rv) == 0) {
     DirBox(0);
@@ -1184,12 +1361,12 @@
     }
   }
 
-  
+
   if (pfree) free(thepic);
-  
+
   SetCursors(-1);
   dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
-  
+
   return rv;
 }
 
@@ -1197,22 +1374,23 @@
 
 /***************************************************/
 void SetDirFName(st)
-     char *st;
+     const char *st;
 {
   strncpy(deffname, st, (size_t) MAXFNLEN-1);
+  deffname[MAXFNLEN-1] = '\0';
   setFName(st);
 }
 
 
 /***************************************************/
 static void setFName(st)
-     char *st;
+     const char *st;
 {
   strncpy(filename, st, (size_t) MAXFNLEN-1);
   filename[MAXFNLEN-1] = '\0';  /* make sure it's terminated */
   curPos = strlen(st);
   stPos = 0;  enPos = curPos;
-  
+
   showFName();
 }
 
@@ -1221,17 +1399,17 @@
 static void showFName()
 {
   int len;
-  
+
   len = strlen(filename);
-  
+
   if (curPos<stPos) stPos = curPos;
   if (curPos>enPos) enPos = curPos;
-  
+
   if (stPos>len) stPos = (len>0) ? len-1 : 0;
   if (enPos>len) enPos = (len>0) ? len-1 : 0;
-  
+
   /* while substring is shorter than window, inc enPos */
-  
+
   while (XTextWidth(mfinfo, &filename[stPos], enPos-stPos) < DNAMWIDE
 	 && enPos<len) { enPos++; }
 
@@ -1244,7 +1422,7 @@
   }
 
 
-  if (ctrlColor) XClearArea(theDisp, dnamW, 2,2, (u_int) DNAMWIDE+5-3, 
+  if (ctrlColor) XClearArea(theDisp, dnamW, 2,2, (u_int) DNAMWIDE+5-3,
 			    (u_int) LINEHIGH+4-3, False);
   else XClearWindow(theDisp, dnamW);
 
@@ -1270,7 +1448,7 @@
   else {
     strcpy(globname, filename);
     if (globname[0] == '~') Globify(globname);
-    
+
     if (globname[0] != '/') sprintf(fullname, "%s%s", path, globname);
     else strcpy(fullname, globname);
   }
@@ -1294,14 +1472,15 @@
 	MBRedraw(&fmtMB);
       }
     }
-    
+
     if (bnum>=0) MBSelect(&colMB, bnum);
   }
-  
+
 
   else if (group == F_FORMAT) {
     MBSelect(&fmtMB, bnum);
-    if (MBWhich(&fmtMB) == F_XBM) { /* turn off all but B/W */
+    if (MBWhich(&fmtMB) == F_XBM ||
+	MBWhich(&fmtMB) == F_WBMP) { /* turn off all but B/W */
       colMB.dim[F_FULLCOLOR] = 1;
       colMB.dim[F_GREYSCALE] = 1;
       colMB.dim[F_BWDITHER]  = 0;
@@ -1322,10 +1501,10 @@
       colMB.dim[F_GREYSCALE] = 0;
       colMB.dim[F_BWDITHER]  = 0;
       colMB.dim[F_REDUCED]   = (picType==PIC8) ? 0 : 1;
-      if (picType!=PIC8 && MBWhich(&colMB)==F_REDUCED) 
+      if (picType!=PIC8 && MBWhich(&colMB)==F_REDUCED)
 	MBSelect(&colMB, F_FULLCOLOR);
     }
-    
+
     if (MBWhich(&fmtMB) == F_FILELIST) {
       MBSetActive(&colMB,      0);
       CBSetActive(&savenormCB, 0);
@@ -1337,12 +1516,12 @@
   }
 }
 
-  
+
 
 /***************************************/
 static void changeSuffix()
 {
-  /* see if there's a common suffix at the end of the filename.  
+  /* see if there's a common suffix at the end of the filename.
      if there is, remember what case it was (all caps or all lower), lop
      it off, and replace it with a new appropriate suffix, in the
      same case */
@@ -1356,7 +1535,7 @@
   suffix++;  /* point to first letter of the suffix */
 
   /* check for all-caposity */
-  for (sp = suffix, allcaps=1; *sp; sp++) 
+  for (sp = suffix, allcaps=1; *sp; sp++)
     if (islower(*sp)) allcaps = 0;
 
   /* copy the suffix into an all-lower-case buffer */
@@ -1380,14 +1559,33 @@
       (strcmp(lowsuf,"eps" )==0) ||
       (strcmp(lowsuf,"rgb" )==0) ||
       (strcmp(lowsuf,"tga" )==0) ||
-      (strcmp(lowsuf,"xpm" )==0) ||
       (strcmp(lowsuf,"fits")==0) ||
       (strcmp(lowsuf,"fts" )==0) ||
+#ifdef HAVE_JPEG
       (strcmp(lowsuf,"jpg" )==0) ||
       (strcmp(lowsuf,"jpeg")==0) ||
       (strcmp(lowsuf,"jfif")==0) ||
+#endif
+#ifdef HAVE_JP2K
+      (strcmp(lowsuf,"jpc" )==0) ||
+      (strcmp(lowsuf,"jp2" )==0) ||
+#endif
+#ifdef HAVE_TIFF
       (strcmp(lowsuf,"tif" )==0) ||
-      (strcmp(lowsuf,"tiff")==0)) {
+      (strcmp(lowsuf,"tiff")==0) ||
+#endif
+#ifdef HAVE_PNG
+      (strcmp(lowsuf,"png" )==0) ||
+#endif
+      (strcmp(lowsuf,"wbmp")==0) ||
+      (strcmp(lowsuf,"xpm" )==0) ||
+      (strcmp(lowsuf,"tiff")==0) ||
+      (strcmp(lowsuf,"mag" )==0) ||
+      (strcmp(lowsuf,"pic" )==0) ||
+      (strcmp(lowsuf,"mki" )==0) ||
+      (strcmp(lowsuf,"pi"  )==0) ||
+      (strcmp(lowsuf,"p2"  )==0) ||
+      (strcmp(lowsuf,"pcd" )==0)) {
 
     /* found one.  set lowsuf = to the new suffix, and tack on to filename */
 
@@ -1401,7 +1599,7 @@
     case F_GIF:      strcpy(lowsuf,"gif");  break;
     case F_PM:       strcpy(lowsuf,"pm");   break;
     case F_PBMRAW:
-    case F_PBMASCII: if (col == F_FULLCOLOR || col == F_REDUCED) 
+    case F_PBMASCII: if (col == F_FULLCOLOR || col == F_REDUCED)
                                                   strcpy(lowsuf,"ppm");
                      else if (col == F_GREYSCALE) strcpy(lowsuf,"pgm");
                      else if (col == F_BWDITHER)  strcpy(lowsuf,"pbm");
@@ -1410,6 +1608,7 @@
     case F_XBM:      strcpy(lowsuf,"xbm");  break;
     case F_SUNRAS:   strcpy(lowsuf,"ras");  break;
     case F_BMP:      strcpy(lowsuf,"bmp");  break;
+    case F_WBMP:     strcpy(lowsuf,"wbmp"); break;
     case F_PS:       strcpy(lowsuf,"ps");   break;
     case F_IRIS:     strcpy(lowsuf,"rgb");  break;
     case F_TARGA:    strcpy(lowsuf,"tga");  break;
@@ -1420,16 +1619,46 @@
     case F_JPEG:     strcpy(lowsuf,"jpg");  break;
 #endif
 
+#ifdef HAVE_JP2K
+    case F_JPC:      strcpy(lowsuf,"jpc");  break;
+    case F_JP2:      strcpy(lowsuf,"jp2");  break;
+#endif
+
 #ifdef HAVE_TIFF
     case F_TIFF:     strcpy(lowsuf,"tif");  break;
 #endif
+
+#ifdef HAVE_PNG
+    case F_PNG:      strcpy(lowsuf,"png");  break;
+#endif
+
+#ifdef HAVE_MAG
+    case F_MAG:      strcpy(lowsuf,"mag");  break;
+#endif
+
+#ifdef HAVE_PIC
+    case F_PIC:      strcpy(lowsuf,"pic");  break;
+#endif
+
+#ifdef HAVE_MAKI
+    case F_MAKI:     strcpy(lowsuf,"mki");  break;
+#endif
+
+#ifdef HAVE_PI
+    case F_PI:       strcpy(lowsuf,"pi");   break;
+#endif
+
+#ifdef HAVE_PIC2
+    case F_PIC2:     strcpy(lowsuf,"p2");   break;
+#endif
     }
 
+
     if (allcaps) {  /* upper-caseify lowsuf */
-      for (sp=lowsuf; *sp; sp++) 
+      for (sp=lowsuf; *sp; sp++)
 	*sp = (islower(*sp)) ? toupper(*sp) : *sp;
     }
-    
+
     /* one other case:  if the original suffix started with a single
        capital letter, make the new suffix start with a single cap */
     if (isupper(suffix[0])) lowsuf[0] = toupper(lowsuf[0]);
@@ -1439,7 +1668,7 @@
   }
 
 }
-  
+
 
 /***************************************************/
 int DirCheckCD()
@@ -1462,7 +1691,7 @@
 static int FNameCdable()
 {
   /* returns '1' if filename is a directory, and goes there */
-  
+
   char newpath[1024];
   struct stat st;
   int retval = 0;
@@ -1490,6 +1719,11 @@
   }
 #endif
 
+#ifdef AUTO_EXPAND
+  Mkvdir(newpath);
+  Dirtovd(newpath);
+#endif
+
   if (stat(newpath, &st)==0) {
     int isdir;
 
@@ -1518,7 +1752,7 @@
       retval = 1;
     }
   }
-  
+
   return retval;
 }
 
@@ -1549,8 +1783,8 @@
   *up='\0';
 
   if (*uname=='\0') { /* no name.  substitute ~ with $HOME */
-    char *homedir;
-    homedir = (char *) getenv("HOME");  
+    const char *homedir;
+    homedir = (const char *) getenv("HOME");
     if (homedir == NULL) homedir = ".";
     strcpy(tmp,homedir);
     strcat(tmp,sp);
@@ -1574,12 +1808,12 @@
 
 /***************************************/
 FILE *OpenOutFile(filename)
-     char *filename;
+     const char *filename;
 {
   /* opens file for output.  does various error handling bits.  Returns
      an open file pointer if success, NULL if failure */
 
-  FILE *fp;
+  FILE *fp = NULL;
   struct stat st;
 
   if (!filename || filename[0] == '\0') return NULL;
@@ -1587,7 +1821,11 @@
   dopipe = 0;
 
   /* make sure we're in the correct directory */
+#ifdef AUTO_EXPAND
+  if (strlen(path)) Chvdir(path);
+#else
   if (strlen(path)) chdir(path);
+#endif
 
   if (ISPIPE(filename[0])) {   /* do piping */
     /* make up some bogus temp file to put this in */
@@ -1596,23 +1834,34 @@
 #else
     strcpy(outFName, "[]xvXXXXXX.lis");
 #endif
+#ifdef USE_MKSTEMP
+    fp = fdopen(mkstemp(outFName), "w");
+#else
     mktemp(outFName);
+#endif
     dopipe = 1;
   }
 
 
-  /* see if file exists (ie, we're overwriting) */
-  if (stat(outFName, &st)==0) {   /* stat succeeded, file must exist */
-    static char *foo[] = { "\nOk", "\033Cancel" };
-    char str[512];
+#ifdef USE_MKSTEMP  /* (prior) nonexistence of file is already guaranteed by */
+  if (!dopipe)      /*  mkstemp(), but now mkstemp() itself has created it */
+#endif
+    /* see if file exists (i.e., we're overwriting) */
+    if (stat(outFName, &st)==0) {   /* stat succeeded, file must exist */
+      static const char *labels[] = { "\nOk", "\033Cancel" };
+      char               str[512];
 
-    sprintf(str,"Overwrite existing file '%s'?", outFName);
-    if (PopUp(str, foo, 2)) return NULL;
-  }
-    
+      sprintf(str,"Overwrite existing file '%s'?", outFName);
+      if (PopUp(str, labels, 2)) return NULL;
+    }
+
+
+  /* Open file (if not already open via mkstemp()) */
+#ifdef USE_MKSTEMP
+  if (!dopipe)
+#endif
+    fp = fopen(outFName, "w");
 
-  /* Open file */
-  fp = fopen(outFName, "w");
   if (!fp) {
     char  str[512];
     sprintf(str,"Can't write file '%s'\n\n  %s.",outFName, ERRSTR(errno));
@@ -1622,12 +1871,12 @@
 
   return fp;
 }
-  
+
 
 /***************************************/
 int CloseOutFile(fp, filename, failed)
      FILE *fp;
-     char *filename;
+     const char *filename;
      int   failed;
 {
   char buf[64];
@@ -1642,9 +1891,8 @@
     return 1;
   }
 
-    
+
   if (fclose(fp) == EOF) {
-    static char *foo[] = { "\nWeird!" };
     char  str[512];
     sprintf(str,"Can't close file '%s'\n\n  %s.",outFName, ERRSTR(errno));
     ErrPopUp(str, "\nWeird!");
@@ -1666,7 +1914,7 @@
   }
 
   SetISTR(ISTR_INFO,"Successfully wrote '%s'%s", outFName, buf);
-  
+
   if (dopipe) {
     char cmd[512], str[1024];
     int  i;
@@ -1709,7 +1957,7 @@
   return 0;
 }
 
-      
+
 
 
 static byte rBW[2], gBW[2], bBW[2];
@@ -1732,7 +1980,7 @@
   bwpic = (byte *) NULL;
   *nc = numcols;  *rpp = rMap;  *gpp = gMap;  *bpp = bMap;
 
-  /* quick check:  if we're saving a 24-bit image, then none of this 
+  /* quick check:  if we're saving a 24-bit image, then none of this
      complicated 'reduced'/dithered/smoothed business comes into play.
      'reduced' is disabled, for semi-obvious reasons, in 24-bit mode,
      as is 'dithered'.  If 'smoothed', and we're saving at current
@@ -1744,32 +1992,32 @@
      if we're saving B/W DITHERED, and deal accordingly */
 
 
-  if (ptype == PIC24) {  
+  if (ptype == PIC24) {
     if (color != F_BWDITHER) return NULL;
     else {                                /* generate a bw-dithered version */
       byte *p24, *thepic;
-      
+
       thepic = pic;
       p24 = GammifyPic24(thepic, pw, ph);
       if (p24) thepic = p24;
-      
+
       /* generate a FSDithered 1-byte per pixel image */
       bwpic = FSDither(thepic, PIC24, pw, ph, NULL,NULL,NULL, 0, 1);
       if (!bwpic) FatalError("unable to malloc dithered picture (DoSave)");
-      
+
       if (p24) free(p24);  /* won't need it any more */
-      
+
       /* build a BW colormap */
       rBW[0] = gBW[0] = bBW[0] = 0;
       rBW[1] = gBW[1] = bBW[1] = 255;
-      
+
       *rpp = rBW;  *gpp = gBW;  *bpp = bBW;
       *nc = 2;
-      
+
       return bwpic;
     }
   }
-    
+
 
 
   /* ptype == PIC8 ... */
@@ -1777,7 +2025,7 @@
   *nc = numcols;  *rpp = rMap;  *gpp = gMap;  *bpp = bMap;
   if (color==F_REDUCED) { *rpp = rdisp;  *gpp = gdisp;  *bpp = bdisp; }
 
-  /* if DITHER or SMOOTH, and color==FULLCOLOR or GREY, 
+  /* if DITHER or SMOOTH, and color==FULLCOLOR or GREY,
      make color=REDUCED, so it will be written with the correct colortable  */
 
   if ((epicMode == EM_DITH || epicMode == EM_SMOOTH) && color != F_REDUCED) {
@@ -1789,7 +2037,7 @@
       *rpp = gray;  *gpp = gray;  *bpp = gray;
     }
   }
-  
+
 
 
 
@@ -1823,8 +2071,8 @@
    * and whether or not it should be freed when we're done with it.  The 'pic'
    * returned is the desired portion of 'cpic' or 'epic' if there is a
    * selection, and the saveselCB is enabled, or alternately, it's the
-   * whole cpic or epic.  
-   * 
+   * whole cpic or epic.
+   *
    * if selection does not intersect cpic/epic, returns cpic/epic
    * NEVER RETURNS NULL
    */
@@ -1837,7 +2085,7 @@
   if (savenormCB.val) { thepic = cpic;  pw = cWIDE;  ph = cHIGH; }
                  else { thepic = epic;  pw = eWIDE;  ph = eHIGH; }
 
-  *pwide = pw;  *phigh = ph;  
+  *pwide = pw;  *phigh = ph;
 
 
   if (saveselCB.active && saveselCB.val && HaveSelection()) {
@@ -1862,7 +2110,7 @@
       CoordP2E(x2,y2, &x2, &y2);
       slx = x1;  sly = y1;  slw = x2-x1;  slh = y2-y1;
       CropRect2Rect(&slx, &sly, &slw, &slh, 0,0,pw,ph);
-      
+
       if (slw<1 || slh<1) { slx = sly = 0;  slw=pw;  slh=ph; }
 
       if (slx!=0 || sly!=0 || slw!=pw || slh!=ph) {
@@ -1871,7 +2119,7 @@
       }
     }
 
-    *pwide = slw;  *phigh = slh;  
+    *pwide = slw;  *phigh = slh;
   }
 
   return thepic;
@@ -1884,11 +2132,11 @@
      byte **rmapP, **gmapP, **bmapP;
 {
   /* handles the whole ugly mess of the various save options.
-   * returns an image, of type 'ptypeP', size 'wP,hP'.  
+   * returns an image, of type 'ptypeP', size 'wP,hP'.
    * if (*ptypeP == PIC8), also returns numcols 'ncP', and the r,g,b map
    * to use rmapP, gmapP, bmapP.
    *
-   * if freeP is set, image can safely be freed after it is saved 
+   * if freeP is set, image can safely be freed after it is saved
    */
 
   byte *pic1, *pic2;
@@ -1896,9 +2144,9 @@
 
   pic1 = handleNormSel(&ptype, &w, &h, &pfree);
 
-  pic2 = handleBWandReduced(pic1, ptype, w,h, MBWhich(&colMB), 
+  pic2 = handleBWandReduced(pic1, ptype, w,h, MBWhich(&colMB),
 			      ncP, rmapP, gmapP, bmapP);
-  if (pic2) { 
+  if (pic2) {
     if (pfree) free(pic1);
     pic1  = pic2;
     pfree = 1;
@@ -1906,7 +2154,7 @@
   }
 
 
-  if (ptype == PIC24) {       
+  if (ptype == PIC24) {
     pic2 = GammifyPic24(pic1, w, h);
     if (pic2) {
       if (pfree) free(pic1);
@@ -1920,7 +2168,7 @@
   return pic1;
 }
 
-     
+
 /***************************************/
 void GetSaveSize(wP, hP)
      int *wP, *hP;
@@ -1947,7 +2195,7 @@
       CoordP2E(x2,y2, &x2, &y2);
       slx = x1;  sly = y1;  slw = x2-x1;  slh = y2-y1;
       CropRect2Rect(&slx, &sly, &slw, &slh, 0,0,eWIDE,eHIGH);
-      
+
       if (slw<1 || slh<1) { slx = sly = 0;  slw=eWIDE;  slh=eHIGH; }
     }
   }
@@ -1982,8 +2230,8 @@
 
     if (stat(namelist[curname], &origStat)==0) {
       haveStat = 1;
-      if (DEBUG) fprintf(stderr," origStat.size=%ld,  origStat.mtime=%d\n", 
-			 origStat.st_size, origStat.st_mtime);
+      if (DEBUG) fprintf(stderr," origStat.size=%ld,  origStat.mtime=%ld\n",
+			 (long)origStat.st_size, (long)origStat.st_mtime);
     }
   }
 }
@@ -1993,7 +2241,7 @@
 int CheckPoll(del)
      int del;
 {
-  /* returns '1' if the file has been modified, and either 
+  /* returns '1' if the file has been modified, and either
       A) the file has stabilized (st = lastStat), or
       B) 'del' seconds have gone by since the file last changed size
    */
@@ -2007,14 +2255,14 @@
       (strcmp(namelist[curname], STDINSTR)!=0)) {
 
     if (stat(namelist[curname], &st)==0) {
-      if (DEBUG) fprintf(stderr," st.size=%ld,  st.mtime=%d\n", 
-			 st.st_size, st.st_mtime);
+      if (DEBUG) fprintf(stderr," st.size=%ld,  st.mtime=%ld\n",
+			 (long)st.st_size, (long)st.st_mtime);
 
       if ((st.st_size  == origStat.st_size) &&
 	  (st.st_mtime == origStat.st_mtime)) return 0;  /* no change */
 
       /* if it's changed since last looked ... */
-      if (!haveLastStat || 
+      if (!haveLastStat ||
 	  st.st_size  != lastStat.st_size  ||
 	  st.st_mtime != lastStat.st_mtime)   {
 	xvbcopy((char *) &st, (char *) &lastStat, sizeof(struct stat));
@@ -2031,7 +2279,7 @@
       }
     }
   }
-  
+
   return 0;
 }
 
@@ -2042,14 +2290,13 @@
 {
   /* called when file 'name' has been deleted.  If any of the browsers
      were showing the directory that the file was in, does a rescan() */
-  
-  int  i;
+
   char buf[MAXPATHLEN + 2], *tmp;
 
   strcpy(buf, name);
-  tmp = BaseName(buf);
+  tmp = (char *) BaseName(buf);  /* intentionally losing constness */
   *tmp = '\0';     /* truncate after last '/' */
-  
+
   if (strcmp(path, buf)==0) LoadCurrentDirectory();
 }
 
@@ -2062,3 +2309,164 @@
 }
 
 
+#ifdef HAVE_PIC2
+/**** Stuff for PIC2Dialog box ****/
+FILE *pic2_OpenOutFile(filename, append)
+char *filename;
+int *append;
+{
+    /* opens file for output.  does various error handling bits.  Returns
+       an open file pointer if success, NULL if failure */
+
+    FILE *fp = NULL;
+    struct stat st;
+
+    if (!filename || filename[0] == '\0')
+	return (NULL);
+    strcpy(outFName, filename);
+    dopipe = 0;
+
+    /* make sure we're in the correct directory */
+#ifdef AUTO_EXPAND
+    if (strlen(path)) Chvdir(path);
+#else
+    if (strlen(path)) chdir(path);
+#endif
+
+    if (ISPIPE(filename[0])) {   /* do piping */
+	/* make up some bogus temp file to put this in */
+#ifndef VMS
+	sprintf(outFName, "%s/xvXXXXXX", tmpdir);
+#else
+	strcpy(outFName, "[]xvXXXXXX.lis");
+#endif
+#ifdef USE_MKSTEMP
+	fp = fdopen(mkstemp(outFName), "w");
+#else
+	mktemp(outFName);
+#endif
+	dopipe = 1;
+    }
+
+
+    /* see if file exists (i.e., we're overwriting) */
+    *append = 0;
+#ifdef USE_MKSTEMP
+    if (!dopipe)
+#endif
+    if (stat(outFName, &st)==0) {    /* stat succeeded, file must exist */
+	if (ReadFileType(outFName) != RFT_PIC2) {
+	    static const char *labels[] = { "\nOk", "\033Cancel" };
+	    char               str[512];
+
+	    sprintf(str,"Overwrite existing file '%s'?", outFName);
+	    if (PopUp(str, labels, 2))
+		return (NULL);
+	} else {
+	    static const char *labels[] = { "\nOk", "\033Cancel" };
+	    char               str[512];
+
+	    sprintf(str,"Append to existing file '%s'?", outFName);
+	    if (PopUp(str, labels, 2)) {
+		sprintf(str,"Overwrite existing file '%s'?", outFName);
+		if (PopUp(str, labels, 2))
+		    return (NULL);
+	    } else
+		*append = 1;
+	}
+    }
+
+    /* Open file */
+#ifdef USE_MKSTEMP
+    if (!dopipe)
+#endif
+    fp = *append ? fopen(outFName, "r+") : fopen(outFName, "w");
+    if (!fp) {
+	char  str[512];
+	sprintf(str,"Can't write file '%s'\n\n  %s.",outFName, ERRSTR(errno));
+	ErrPopUp(str, "\nBummer");
+	return (NULL);
+    }
+
+    return (fp);
+}
+
+
+/***************************************/
+void pic2_KillNullFile(fp)
+FILE *fp;
+{
+    fseek(fp, (size_t) 0, SEEK_END);
+    if (ftell(fp) > 0) {
+	fclose(fp);
+	return;
+    } else {
+	fclose(fp);
+	unlink(outFName);
+	return;
+    }
+}
+#endif /* HAVE_PIC2 */
+
+
+#ifdef HAVE_MGCSFX
+/**** Stuff for MGCSFX Dialog box ****/
+/***************************************/
+int OpenOutFileDesc(filename)
+     char *filename;
+{
+  /* opens file for output.  does various error handling bits.  Returns
+     an open file pointer if success, NULL if failure */
+
+  int         fd;
+  struct stat st;
+
+  if (!filename || filename[0] == '\0') return -1;
+  strcpy(outFName, filename);
+  dopipe = 0;
+
+  /* make sure we're in the correct directory */
+#ifdef AUTO_EXPAND
+  if (strlen(path)) Chvdir(path);
+#else
+  if (strlen(path)) chdir(path);
+#endif
+
+  if (ISPIPE(filename[0])) {   /* do piping */
+    /* make up some bogus temp file to put this in */
+#ifndef VMS
+    sprintf(outFName, "%s/xvXXXXXX", tmpdir);
+#else
+    strcpy(outFName, "[]xvXXXXXX.lis");
+#endif
+#ifdef USE_MKSTEMP
+    close(mkstemp(outFName));
+#else
+    mktemp(outFName);
+#endif
+    dopipe = 1;
+  }
+
+
+  /* if didn't just create it, see if file exists (i.e., we're overwriting) */
+  if (!dopipe && stat(outFName, &st)==0) {   /* stat succeeded, file exists */
+    static const char *labels[] = { "\nOk", "\033Cancel" };
+    char               str[512];
+
+    sprintf(str,"Overwrite existing file '%s'?", outFName);
+    if (PopUp(str, labels, 2)) return -1;
+  }
+
+
+  /* Open file */
+  fd = open(outFName, O_WRONLY | O_CREAT | O_TRUNC, (0644));
+  if (fd < 0) {
+    char  str[512];
+    sprintf(str,"Can't write file '%s'\n\n  %s.", outFName, ERRSTR(errno));
+    ErrPopUp(str, "\nBummer");
+    return -1;
+  }
+
+  return fd;
+}
+#endif /* HAVE_MGCSFX */
diff -ru xv-3.10a/xvevent.c xv-3.10a-enhancements/xvevent.c
--- xv-3.10a/xvevent.c	1995-01-23 15:20:24.000000000 -0800
+++ xv-3.10a-enhancements/xvevent.c	2007-05-12 15:27:11.000000000 -0700
@@ -39,8 +39,15 @@
 static Cursor dropper = 0, pen = 0, blur = 0;
 
 
+static void SelectDispMB       PARM((int));
+static void Select24to8MB      PARM((int));
+static void SelectRootMB       PARM((int));
+static void SelectWindowMB     PARM((int));
+static void SelectSizeMB       PARM((int));
+
+static void DoPrint            PARM((void));
 static void debugEvent         PARM((XEvent *));
-static char *win2name          PARM((Window));
+static const char *win2name    PARM((Window));
 static void handleButtonEvent  PARM((XEvent *, int *, int *));
 static void handleKeyEvent     PARM((XEvent *, int *, int *));
 static void zoomCurs           PARM((u_int));
@@ -64,6 +71,8 @@
 
 static void   annotatePic      PARM((void));
 
+static int    debkludge_offx;
+static int    debkludge_offy;
 
 /****************/
 int EventLoop()
@@ -71,13 +80,25 @@
 {
   XEvent event;
   int    retval,done,waiting;
-  time_t orgtime, curtime;
+#ifdef USE_TICKS
+  clock_t waitsec_ticks=0L, orgtime_ticks=0L, curtime_ticks;
+  clock_t elapsed_ticks=0L, remaining_interval;
+#else
+  time_t orgtime=0L, curtime;
+#endif
 
 
 #ifndef NOSIGNAL
   signal(SIGQUIT, onInterrupt);
 #endif
 
+  if (startGrab == 1) {
+     startGrab = 2;
+     FakeButtonPress(&but[BGRAB]);
+     FakeKeyPress(ctrlW, XK_Return);
+     return(1);
+  }
+
   /* note: there's no special event handling if we're using the root window.
      if we're using the root window, we will recieve NO events for mainW */
 
@@ -100,18 +121,24 @@
 
   while (!done) {
 
-    if (waitsec > -1 && canstartwait && !waiting && XPending(theDisp)==0) {
-      /* we wanna wait, we can wait, we haven't started waiting yet, and 
-	 all pending events (ie, drawing the image the first time) 
+    if (waitsec >= 0.0 && canstartwait && !waiting && XPending(theDisp)==0) {
+      /* we wanna wait, we can wait, we haven't started waiting yet, and
+	 all pending events (ie, drawing the image the first time)
 	 have been dealt with:  START WAITING */
-      time((time_t *) &orgtime);
+#ifdef USE_TICKS
+      waitsec_ticks = (clock_t)(waitsec * CLK_TCK);
+      orgtime_ticks = times(NULL);  /* unclear if NULL valid, but OK on Linux */
+#else
+      orgtime = time(NULL);
+#endif
       waiting = 1;
     }
 
 
-    /* if there's an XEvent pending *or* we're not doing anything 
+    /* if there's an XEvent pending *or* we're not doing anything
        in real-time (polling, flashing the selection, etc.) get next event */
-    if ((waitsec==-1 && !polling && !HaveSelection()) || XPending(theDisp)>0) {
+    if ((waitsec<0.0 && !polling && !HaveSelection()) || XPending(theDisp)>0)
+    {
       XNextEvent(theDisp, &event);
       retval = HandleEvent(&event,&done);
     }
@@ -121,7 +148,7 @@
 	DrawSelection(0);
 	DrawSelection(1);
 	XFlush(theDisp);
-	Timer(200);
+	Timer(200);             /* milliseconds */
       }
 
       if (polling) {
@@ -129,13 +156,32 @@
 	else if (!XPending(theDisp)) sleep(1);
       }
 
-      if (waitsec>-1 && waiting) {
-	time((time_t *) &curtime);
-	if (curtime - orgtime < waitsec) sleep(1);
-	else {
-	  if (waitloop) return NEXTLOOP;
-	  else return NEXTQUIT;
-	}
+      if (waitsec>=0.0 && waiting) {
+#ifdef USE_TICKS
+        curtime_ticks = times(NULL);   /* value in ticks */
+        if (curtime_ticks < orgtime_ticks) {
+          /* clock ticks rolled over:  need to correct for that (i.e.,
+           *  curtime_ticks is presumably quite small, while orgtime_ticks
+           *  should be close to LONG_MAX, so do math accordingly--any way
+           *  to check whether clock_t is *not* a signed long?) */
+          elapsed_ticks = curtime_ticks + (LONG_MAX - orgtime_ticks);
+        } else
+          elapsed_ticks = curtime_ticks - orgtime_ticks;
+        remaining_interval = waitsec_ticks - elapsed_ticks;
+        if (remaining_interval >= (clock_t)(1 * CLK_TCK))
+          sleep(1);
+        else {
+          /* less than one second remaining:  do delay in msec, then return */
+          Timer((remaining_interval * 1000L) / CLK_TCK);  /* can't overflow */
+          return waitloop? NEXTLOOP : NEXTQUIT;
+        }
+#else
+        curtime = time(NULL);          /* value in seconds */
+	if (curtime - orgtime < (time_t)waitsec)
+          sleep(1);
+	else
+          return waitloop? NEXTLOOP : NEXTQUIT;
+#endif
       }
     }
   }  /* while (!done) */
@@ -154,7 +200,27 @@
      int    *donep;
 {
   static int wasInfoUp=0, wasCtrlUp=0, wasDirUp=0, wasGamUp=0, wasPsUp=0;
-  static int wasJpegUp=0, wasTiffUp=0;
+#ifdef HAVE_JPEG
+  static int wasJpegUp=0;
+#endif
+#ifdef HAVE_JP2K
+  static int wasJp2kUp=0;
+#endif
+#ifdef HAVE_TIFF
+  static int wasTiffUp=0;
+#endif
+#ifdef HAVE_PNG
+  static int wasPngUp=0;
+#endif
+#ifdef HAVE_PCD
+  static int wasPcdUp=0;
+#endif
+#ifdef HAVE_PIC2
+  static int wasPic2Up=0;
+#endif
+#ifdef HAVE_MGCSFX
+  static int wasMgcSfxUp=0;
+#endif
 
   static int mainWKludge=0;  /* force first mainW expose after a mainW config
 				to redraw all of mainW */
@@ -187,7 +253,7 @@
 
 #ifdef VMS
     static int borders_sized = 0;
-  
+
     if (!borders_sized  && !useroot && exp_event->window == mainW) {
       /*
        * Initial expose of main window, find the size of the ancestor
@@ -198,13 +264,13 @@
       int status, count, mwid, mhgt, x, y, w, h, b, d, mbrd;
       Window root, parent, *children, crw = exp_event->window;
       borders_sized = 1;
-      status = XGetGeometry(theDisp, crw, 
+      status = XGetGeometry(theDisp, crw,
 			    &root, &x, &y, &mwid, &mhgt, &mbrd, &d);
-      
+
       for ( parent = crw, w=mwid, h=mhgt;
 	   status && (parent != root) && (parent != vrootW); ) {
 	crw = parent;
-	status = XQueryTree ( theDisp, crw, &root, &parent, 
+	status = XQueryTree ( theDisp, crw, &root, &parent,
 			     &children, &count );
 	if ( children != NULL ) XFree ( children );
       }
@@ -221,7 +287,7 @@
     win = exp_event->window;
     x = exp_event->x;      y = exp_event->y;
     w = exp_event->width;  h = exp_event->height;
-    
+
     if (PUCheckEvent  (event)) break;   /* event has been processed */
     if (PSCheckEvent  (event)) break;   /* event has been processed */
 
@@ -229,16 +295,42 @@
     if (JPEGCheckEvent(event)) break;   /* event has been processed */
 #endif
 
+#ifdef HAVE_JP2K
+    if (JP2KCheckEvent(event)) break;   /* event has been processed */
+#endif
+
 #ifdef HAVE_TIFF
     if (TIFFCheckEvent(event)) break;   /* event has been processed */
 #endif
 
+#ifdef HAVE_PNG
+    if (PNGCheckEvent (event)) break;   /* event has been processed */
+#endif
+
+    if (PCDCheckEvent(event)) break;    /* event has been processed */
+
+#ifdef HAVE_PIC2
+    if (PIC2CheckEvent(event)) break;   /* event has been processed */
+#endif
+
+#ifdef HAVE_PCD
+    if (PCDCheckEvent (event)) break;   /* event has been processed */
+#endif
+
+#ifdef HAVE_MGCSFX
+    if (MGCSFXCheckEvent(event)) break; /* event has been processed */
+#endif
+
+#ifdef TV_MULTILINGUAL
+    if (CharsetCheckEvent(event)) break; /* event has been processed */
+#endif
+
     if (GamCheckEvent (event)) break;   /* event has been processed */
     if (BrowseCheckEvent (event, &retval, &done)) break;   /* event eaten */
     if (TextCheckEvent   (event, &retval, &done)) break;   /* event eaten */
 
     /* if the window doesn't do intelligent redraw, drop but last expose */
-    if (exp_event->count>0 && 
+    if (exp_event->count>0 &&
 	win != mainW && win != ctrlW &&	win != dirW && win != infoW) break;
 
 
@@ -301,7 +393,7 @@
 	  if (DEBUG) fprintf(stderr,"No configs pending.\n");
 	  /* if (DEBUG) XClearArea(theDisp, mainW, x,y,w,h, False); */
 	  DrawWindow(x,y,w,h);
-	    
+
 	  if (HaveSelection()) DrawSelection(0);
 
 	  canstartwait = 1;  /* finished drawing */
@@ -314,7 +406,7 @@
       else if (win == infoW)          RedrawInfo(x,y,w,h);
       else if (win == ctrlW)          RedrawCtrl(x,y,w,h);
       else if (win == dirW)           RedrawDirW(x,y,w,h);
-      
+
       XSetClipMask(theDisp, theGC, None);
       XDestroyRegion(reg);
     }
@@ -324,10 +416,10 @@
     else if (win == dList.win)      LSRedraw(&dList,0);
     else if (win == dList.scrl.win) SCRedraw(&dList.scrl);
     else if (win == dnamW)          RedrawDNamW();
-  }      
+  }
     break;
 
-    
+
 
   case ClientMessage: {
     Atom proto, delwin;
@@ -344,6 +436,9 @@
 
       if (BrowseDelWin(client_event->window)) break;
       if (TextDelWin(client_event->window)) break;
+#ifdef TV_MULTILINGUAL
+      if (CharsetDelWin(client_event->window)) break;
+#endif
 
       if      (client_event->window == infoW) InfoBox(0);
       else if (client_event->window == gamW)  GamBox(0);
@@ -355,10 +450,32 @@
       else if (client_event->window == jpegW) JPEGDialog(0);
 #endif
 
+#ifdef HAVE_JP2K
+      else if (client_event->window == jp2kW) JP2KDialog(0);
+#endif
+
 #ifdef HAVE_TIFF
       else if (client_event->window == tiffW) TIFFDialog(0);
 #endif
 
+#ifdef HAVE_PNG
+      else if (client_event->window == pngW)  PNGDialog(0);
+#endif
+
+      else if (client_event->window == pcdW)  PCDDialog(0);
+
+#ifdef HAVE_PIC2
+      else if (client_event->window == pic2W) PIC2Dialog(0);
+#endif
+
+#ifdef HAVE_PCD
+      else if (client_event->window == pcdW)  PCDDialog(0);
+#endif
+
+#ifdef HAVE_MGCSFX
+      else if (client_event->window == mgcsfxW) MGCSFXDialog(0);
+#endif
+
       else if (client_event->window == mainW) Quit(0);
     }
   }
@@ -381,31 +498,35 @@
     if (win==ctrlW || win==gamW || win==infoW || win==mainW || win==dirW) {
       XSizeHints hints;
 
+#define BAD_IDEA
+#ifdef BAD_IDEA
       /*
-       * if there's a virtual window manager running (e.g. tvtwm / olvwm), 
-       * we're going to get 'cevt' values in terms of the 
+       * if there is a virtual window manager running (e.g., tvtwm / olvwm),
+       * we're going to get 'cevt' values in terms of the
        * 'real' root window (the one that is the size of the screen).
        * We'll want to translate them into values that are in terms of
        * the 'virtual' root window (the 'big' one)
        */
 
       if (vrootW != rootW) {
-	int x1,y1;  Window child;
+	int x1,y1;
+	Window child;
 
-	XTranslateCoordinates(theDisp, rootW, vrootW, cevt->x, cevt->y, 
+	XTranslateCoordinates(theDisp, rootW, vrootW, cevt->x, cevt->y,
 			      &x1, &y1, &child);
 	if (DEBUG) fprintf(stderr,"  CONFIG trans %d,%d root -> %d,%d vroot\n",
 			   cevt->x, cevt->y, x1, y1);
 	cevt->x = x1;  cevt->y = y1;
       }
+#endif
 
 #ifndef VMS
       /* read hints for this window and adjust any position hints, but
-         only if this is a 'synthetic' event sent to us by the WM 
+         only if this is a 'synthetic' event sent to us by the WM
 	 ('real' events from the server have useless x,y info, since the
 	 mainW has been reparented by the WM) */
 
-      if (cevt->send_event && 
+      if (cevt->send_event &&
 	  XGetNormalHints(theDisp, cevt->window, &hints)) {
 
 	if (DEBUG) fprintf(stderr,"  CONFIG got hints (0x%x  %d,%d)\n",
@@ -439,11 +560,11 @@
        * This sucks!
        *
        * So, if we have just loaded an image, and we get a Synthetic conf
-       * that is not the desired size (eWIDExeHIGH), ignore it, as it's 
+       * that is not the desired size (eWIDExeHIGH), ignore it, as it's
        * just the conf generated by moving the old window.  And stop
        * ignoring further config events
        *
-       * EVIL KLUDGE:  do *not* ignore configs that are <100x100.  Not 
+       * EVIL KLUDGE:  do *not* ignore configs that are <100x100.  Not
        * ignoring them won't be a big performance problem, and it'll get
        * around the 'I only got one config in the wrong size' problem when
        * initially displaying small images
@@ -453,7 +574,7 @@
 
 /* fprintf(stderr,"***mainw, ignore=%d, send_event=%d, evtSize=%d,%d, size=%d,%d\n", ignoreConfigs, cevt->send_event, cevt->width, cevt->height, eWIDE, eHIGH); */
 
-      if (ignoreConfigs==1 && cevt->send_event && 
+      if (ignoreConfigs==1 && cevt->send_event &&
 	  (cevt->width != eWIDE || cevt->height != eHIGH)) {
 	ignoreConfigs=0;        /* ignore this one only */
 	break;
@@ -470,7 +591,7 @@
 	else {
 	  XEvent xev;
 	  if (DEBUG) fprintf(stderr,"No configs pend.");
-	  
+
 	  if (cevt->width == eWIDE && cevt->height == eHIGH) {
 	    if (DEBUG) fprintf(stderr,"No redraw\n");
 	  }
@@ -478,12 +599,12 @@
 	    if (DEBUG) fprintf(stderr,"Do full redraw\n");
 
 	    Resize(cevt->width, cevt->height);
-	    
+
 	    /* eat any pending expose events and do a full redraw */
 	    while (XCheckTypedWindowEvent(theDisp, mainW, Expose, &xev)) {
 	      XExposeEvent *exp = (XExposeEvent *) &xev;
 
-	      if (DEBUG) 
+	      if (DEBUG)
 		fprintf(stderr,"  ate expose (%s) (count=%d) %d,%d %dx%d\n",
 			exp->send_event ? "synth" : "real", exp->count,
 			exp->x, exp->y, exp->width, exp->height);
@@ -508,9 +629,9 @@
 
   }
     break;
-	
 
-	
+
+
   case CirculateNotify:
   case DestroyNotify:
   case GravityNotify:       break;
@@ -534,10 +655,24 @@
 #ifdef HAVE_JPEG
 	if (wasJpegUp) { JPEGDialog(wasJpegUp);  wasJpegUp=0; }
 #endif
-
+#ifdef HAVE_JP2K
+	if (wasJp2kUp) { JP2KDialog(wasJpegUp);  wasJp2kUp=0; }
+#endif
 #ifdef HAVE_TIFF
 	if (wasTiffUp) { TIFFDialog(wasTiffUp);  wasTiffUp=0; }
 #endif
+#ifdef HAVE_PNG
+	if (wasPngUp)  { PNGDialog(wasPngUp);    wasPngUp=0; }
+#endif
+#ifdef HAVE_PCD
+	if (wasPcdUp)  { PCDDialog(wasPcdUp);    wasPcdUp=0; }
+#endif
+#ifdef HAVE_PIC2
+	if (wasPic2Up) { PIC2Dialog(wasPic2Up);  wasPic2Up=0; }
+#endif
+#ifdef HAVE_MGCSFX
+	if (wasMgcSfxUp) { MGCSFXDialog(wasMgcSfxUp);  wasMgcSfxUp=0; }
+#endif
       }
     }
   }
@@ -554,7 +689,7 @@
 
       /* don't do it if we've just switched to a root mode */
       if ((unmap_event->window == mainW && dispMode == 0) ||
-	  (unmap_event->window == ctrlW && dispMode != 0)) {  
+	  (unmap_event->window == ctrlW && dispMode != 0)) {
 
 	if (autoclose) {
 	  if (autoclose>1) autoclose -= 2;  /* grab kludge */
@@ -572,10 +707,24 @@
 #ifdef HAVE_JPEG
 	  if (jpegUp) { wasJpegUp = jpegUp;  JPEGDialog(0); }
 #endif
-
+#ifdef HAVE_JP2K
+	  if (jp2kUp) { wasJp2kUp = jp2kUp;  JP2KDialog(0); }
+#endif
 #ifdef HAVE_TIFF
 	  if (tiffUp) { wasTiffUp = tiffUp;  TIFFDialog(0); }
 #endif
+#ifdef HAVE_PNG
+	  if (pngUp)  { wasPngUp  = pngUp;   PNGDialog(0); }
+#endif
+#ifdef HAVE_PCD
+	  if (pcdUp)  { wasPcdUp = pcdUp;    PCDDialog(0); }
+#endif
+#ifdef HAVE_PIC2
+	  if (pic2Up) { wasPic2Up = pic2Up;  PIC2Dialog(0); }
+#endif
+#ifdef HAVE_MGCSFX
+	  if (mgcsfxUp) { wasMgcSfxUp = mgcsfxUp;  MGCSFXDialog(0); }
+#endif
 	}
       }
     }
@@ -586,8 +735,8 @@
     XReparentEvent *reparent_event = (XReparentEvent *) event;
 
     if (DEBUG) {
-      fprintf(stderr,"Reparent: mainW=%x ->win=%x ->ev=%x  ->parent=%x  ", 
-	      (u_int) mainW,                 (u_int) reparent_event->window, 
+      fprintf(stderr,"Reparent: mainW=%x ->win=%x ->ev=%x  ->parent=%x  ",
+	      (u_int) mainW,                 (u_int) reparent_event->window,
 	      (u_int) reparent_event->event, (u_int) reparent_event->parent);
       fprintf(stderr,"%d,%d\n", reparent_event->x, reparent_event->y);
     }
@@ -598,7 +747,7 @@
 
       p_offx = p_offy = 0;          /* topleft correction for WMs titlebar */
 
-      if (ch_offx == 0 && ch_offy == 0) {  
+      if (ch_offx == 0 && ch_offy == 0) {
 	/* looks like the user is running MWM or OLWM */
 
 	XWindowAttributes xwa;
@@ -609,8 +758,8 @@
 
 	XSync(theDisp, False);
 	XGetWindowAttributes(theDisp, mainW, &xwa);
-	
-	if (DEBUG) 
+
+	if (DEBUG)
 	  fprintf(stderr,"XGetAttr: mainW %d,%d %dx%d\n", xwa.x, xwa.y,
 		  xwa.width, xwa.height);
 
@@ -620,8 +769,8 @@
 
 	  XSync(theDisp, False);
 	  XGetWindowAttributes(theDisp, reparent_event->parent, &xwa);
-	
-	  if (DEBUG) 
+
+	  if (DEBUG)
 	    fprintf(stderr,"XGetAttr: parent %d,%d %dx%d\n", xwa.x, xwa.y,
 		    xwa.width, xwa.height);
 	}
@@ -641,42 +790,75 @@
 	p_offy = xwa.y;
       }
 
-      
+      /* Gather info to keep right border inside */
+      {
+	Window current;
+	Window root_r;
+	Window parent_r;
+	Window *children_r;
+	unsigned int nchildren_r;
+	XWindowAttributes xwa;
+
+	parent_r=mainW;
+	current=mainW;
+	do {
+	  current=parent_r;
+	  XQueryTree(theDisp, current, &root_r, &parent_r,
+		     &children_r, &nchildren_r);
+	  if (children_r!=NULL) {
+	    XFree(children_r);
+	  }
+	} while (parent_r!=root_r && parent_r!=vrootW);
+	XGetWindowAttributes(theDisp, current, &xwa);
+	debkludge_offx = eWIDE-xwa.width+p_offx;
+	debkludge_offy = eHIGH-xwa.height+p_offy;
+      }
+
+#if 0
+      /* FIXME: if we want to do this, we first have to wait for a configure
+       * notify to avoid a race condition because the location might be in-
+       * correct if the window manager does placement after managing the window.
+       */
       /* move window around a bit... */
       {
 	XWindowAttributes xwa;
+
 	GetWindowPos(&xwa);
+	//fprintf(stderr, "RAC: orig window pos %d,%d\n", xwa.x, xwa.y);
+
 	xwa.width = eWIDE;  xwa.height = eHIGH;
-	
+	//fprintf(stderr, "RAC: image size now %d,%d\n", xwa.width, xwa.height);
+
 	/* try to keep the damned thing on-screen, if possible */
-	if (xwa.x + xwa.width  > dispWIDE) xwa.x = dispWIDE - xwa.width;
-	if (xwa.y + xwa.height > dispHIGH) xwa.y = dispHIGH - xwa.height;
+	if (xwa.x + xwa.width  > vrWIDE) xwa.x = vrWIDE - xwa.width;
+	if (xwa.y + xwa.height > vrHIGH) xwa.y = vrHIGH - xwa.height;
 	if (xwa.x < 0) xwa.x = 0;
 	if (xwa.y < 0) xwa.y = 0;
-	
+
+	//fprintf(stderr, "RAC: moving window to %d,%d\n", xwa.x, xwa.y);
 	SetWindowPos(&xwa);
       }
-
+#endif
     }
   }
     break;
-    
+
 
   case EnterNotify:
   case LeaveNotify: {
     XCrossingEvent *cross_event = (XCrossingEvent *) event;
     if (cross_event->window == mainW || 0
 	/* (cross_event->window == gamW && cmapInGam) */ ) {
-      
+
       if (cross_event->type == EnterNotify && cross_event->window == mainW) {
 	zoomCurs(cross_event->state);
       }
 
 
-      if (cross_event->type == EnterNotify && LocalCmap && !ninstall) 
+      if (cross_event->type == EnterNotify && LocalCmap && !ninstall)
 	XInstallColormap(theDisp,LocalCmap);
 
-      if (cross_event->type == LeaveNotify && LocalCmap && !ninstall) 
+      if (cross_event->type == LeaveNotify && LocalCmap && !ninstall)
 	XUninstallColormap(theDisp,LocalCmap);
     }
   }
@@ -685,12 +867,12 @@
 
   case SelectionClear:  break;
 
-  case SelectionRequest: 
+  case SelectionRequest:
     {
       XSelectionRequestEvent *xsrevt = (XSelectionRequestEvent *) event;
       XSelectionEvent  xse;
 
-      if (xsrevt->owner     != ctrlW      || 
+      if (xsrevt->owner     != ctrlW      ||
 	  xsrevt->selection != XA_PRIMARY ||
 	  xsrevt->target    != XA_STRING) {  /* can't do it. */
 	xse.property = None;
@@ -702,7 +884,7 @@
 	if (xse.property != None) {
           xerrcode = 0;
 	  XChangeProperty(theDisp, xsrevt->requestor, xse.property,
-			  XA_STRING, 8, PropModeReplace, 
+			  XA_STRING, 8, PropModeReplace,
 			  (byte *) ((xevPriSel) ? xevPriSel           : "\0"),
 			  (int)    ((xevPriSel) ? strlen(xevPriSel)+1 : 1));
           XSync(theDisp, False);
@@ -721,9 +903,9 @@
       XSync(theDisp, False);
     }
     break;
-	
-      
-	
+
+
+
   default: break;		/* ignore unexpected events */
   }  /* switch */
 
@@ -734,11 +916,11 @@
 
 
 /***********************************/
-void SelectDispMB(i)
+static void SelectDispMB(i)
      int i;
 {
   /* called to handle selection of a dispMB item */
-  
+
   if (i<0 || i>=DMB_MAX) return;
 
   if (dispMB.dim[i]) return;    /* disabled */
@@ -747,36 +929,36 @@
     if      (i==DMB_RAW)  epicMode = EM_RAW;
     else if (i==DMB_DITH) epicMode = EM_DITH;
     else                  epicMode = EM_SMOOTH;
-    
-    SetEpicMode();	              
+
+    SetEpicMode();
     GenerateEpic(eWIDE, eHIGH);
     DrawEpic();
     SetCursors(-1);
   }
-  
+
   else if (i==DMB_COLRW) {   /* toggle rw on/off */
     dispMB.flags[i] = !dispMB.flags[i];
     allocMode = (dispMB.flags[i]) ? AM_READWRITE : AM_READONLY;
     ChangeCmapMode(colorMapMode, 1, 0);
   }
-  
+
   else if (i>=DMB_COLNORM && i<=DMB_COLSTDC && !dispMB.flags[i]) {
     switch (i) {
-    case DMB_COLNORM:  
-      ChangeCmapMode(CM_NORMAL, 1, 0);   
-      defaultCmapMode = CM_NORMAL;    
+    case DMB_COLNORM:
+      ChangeCmapMode(CM_NORMAL, 1, 0);
+      defaultCmapMode = CM_NORMAL;
       break;
-    case DMB_COLPERF:  
+    case DMB_COLPERF:
       ChangeCmapMode(CM_PERFECT,1, 0);
-      defaultCmapMode = CM_PERFECT;   
+      defaultCmapMode = CM_PERFECT;
       break;
-    case DMB_COLOWNC:  
+    case DMB_COLOWNC:
       ChangeCmapMode(CM_OWNCMAP,1, 0);
-      defaultCmapMode = CM_OWNCMAP;   
+      defaultCmapMode = CM_OWNCMAP;
       break;
-    case DMB_COLSTDC:  
+    case DMB_COLSTDC:
       ChangeCmapMode(CM_STDCMAP,1, 0);
-      defaultCmapMode = CM_STDCMAP;   
+      defaultCmapMode = CM_STDCMAP;
       break;
     }
   }
@@ -784,27 +966,27 @@
 
 
 /***********************************/
-void SelectRootMB(i)
+static void SelectRootMB(i)
      int i;
 {
   /* called to handle selection of a rootMB item */
-  
+
   if (i<0 || i>=RMB_MAX) return;
   if (rootMB.flags[i])   return;
   if (rootMB.dim[i])     return;
 
   dispMode = i;
-  
+
   /* move checkmark */
   for (i=RMB_WINDOW; i<RMB_MAX; i++) rootMB.flags[i] = 0;
   rootMB.flags[dispMode] = 1;
-  
+
   HandleDispMode();
 }
 
 
 /***********************************/
-void Select24to8MB(i)
+static void Select24to8MB(i)
      int i;
 {
   if (i<0 || i>=CONV24_MAX) return;
@@ -818,25 +1000,25 @@
       else if (i==CONV24_24BIT && state824==1) {
 	/* went 24->8->24 */
 	char buf[512];
-	
+
 	sprintf(buf,"Warning:  You appear to have taken a 24-bit ");
 	strcat(buf, "image, turned it to an 8-bit image, and turned ");
 	strcat(buf, "it back into a 24-bit image.  Understand that ");
 	strcat(buf, "image data has probably been lost in this ");
 	strcat(buf, "transformation.  You *may* want to reload the ");
 	strcat(buf, "original image to avoid this problem.");
-	
+
 	ErrPopUp(buf, "\nI Know!");
-	
+
 	state824 = 2;   /* shut up until next image is loaded */
       }
     }
   }
-  
+
   else if (i==CONV24_LOCK) {
     conv24MB.flags[i] = !conv24MB.flags[i];
   }
-  
+
   else if (i>=CONV24_FAST && i<=CONV24_BEST) {
     conv24 = i;
     for (i=CONV24_FAST; i<=CONV24_BEST; i++) {
@@ -847,7 +1029,7 @@
 
 
 /***********************************/
-void SelectWindowMB(i)
+static void SelectWindowMB(i)
      int i;
 {
   if (i<0 || i>=WMB_MAX) return;
@@ -859,15 +1041,15 @@
     else chdir(initdir);
     OpenBrowse();
     break;
-    
+
   case WMB_COLEDIT:  GamBox (!gamUp);   break;
   case WMB_INFO:     InfoBox(!infoUp);  break;
-    
-  case WMB_COMMENT:  
+
+  case WMB_COMMENT:
     if (!commentUp) OpenCommentText();
     else CloseCommentText();
     break;
-    
+
   case WMB_TEXTVIEW:  textViewCmd();  break;
   case WMB_ABOUTXV:   ShowLicense();  break;
   case WMB_KEYHELP:   ShowKeyHelp();  break;
@@ -878,7 +1060,7 @@
 
 
 /***********************************/
-void SelectSizeMB(i)
+static void SelectSizeMB(i)
      int i;
 {
   int w,h;
@@ -892,19 +1074,19 @@
       double r,wr,hr;
       wr = ((double) cWIDE) / maxWIDE;
       hr = ((double) cHIGH) / maxHIGH;
-      
+
       r = (wr>hr) ? wr : hr;   /* r is the max(wr,hr) */
       w = (int) ((cWIDE / r) + 0.5);
       h = (int) ((cHIGH / r) + 0.5);
     }
     else { w = cWIDE;  h = cHIGH; }
-    
+
     WResize(w, h);
     break;
 
   case SZMB_MAXPIC:   WMaximize();  break;
 
-  case SZMB_MAXPECT: 
+  case SZMB_MAXPECT:
     {
       int w1,h1;
       w1 = eWIDE;  h1 = eHIGH;
@@ -925,24 +1107,24 @@
     if (h==eHIGH) h++;
     WResize(w,h);
     break;
-    
-    
+
+
   case SZMB_SETSIZE:  setSizeCmd();  break;
   case SZMB_ASPECT:   FixAspect(1, &w, &h);  WResize(w,h);  break;
 
-  case SZMB_4BY3:   
+  case SZMB_4BY3:
     w = eWIDE;  h = (w * 3) / 4;
     if (h>maxHIGH) { h = eHIGH;  w = (h*4)/3; }
     WResize(w,h);
     break;
 
-  case SZMB_INTEXP:  
+  case SZMB_INTEXP:
     {
       /* round  (eWIDE/cWIDE),(eHIGH/cHIGH) to nearest
 	 integer expansion/compression values */
-      
+
       double w,h;
-      
+
       if (eWIDE >= cWIDE) {
 	w = ((double) eWIDE) / cWIDE;
 	w = floor(w + 0.5);
@@ -961,7 +1143,7 @@
 	}
 	w = pick;
       }
-      
+
       if (eHIGH >= cHIGH) {
 	h = ((double) eHIGH) / cHIGH;
 	h = floor(h + 0.5);
@@ -980,25 +1162,26 @@
 	}
 	h = pick;
       }
-      
+
       WResize((int) (w*cWIDE), (int) (h*cHIGH));
     }
     break;
-    
+
   default: break;
   }
 }
 
 
 /***********************************/
-void DoPrint()
+static void DoPrint()
 {
   /* pops open appropriate dialog boxes, issues print command */
 
-  int          i;
-  char         txt[512], str[PRINTCMDLEN + 10];
-  static char *labels[] = { " Color", " Grayscale", " B/W", "\033Cancel" };
-  
+  int                i;
+  char               txt[512], str[PRINTCMDLEN + 10];
+  static const char *labels[] = { "\03Color", "\07Grayscale", " B/W", "\033Cancel" };
+                          /* ^B ("\02") already used for moving cursor back */
+
   strcpy(txt, "Print:  Enter a command that will read a PostScript file ");
   strcat(txt, "from stdin and print it to the desired printer.\n\n");
 #ifndef VMS
@@ -1011,11 +1194,11 @@
   if (i == 3 || strlen(printCmd)==0) return;   /* CANCEL */
 
   if (dirUp == BLOAD) DirBox(0);
-  
+
   SetDirSaveMode(F_FORMAT, F_PS);
   SetDirSaveMode(F_COLORS, i);
 
-  if (printCmd[0] != '|' && printCmd[0] != '!') 
+  if (printCmd[0] != '|' && printCmd[0] != '!')
     sprintf(str, "| %s", printCmd);
   else strcpy(str, printCmd);
 
@@ -1086,11 +1269,11 @@
   }
 }
 
-static char *win2name(win)
+static const char *win2name(win)
      Window win;
 {
   static char foo[16];
-  
+
   if      (win == mainW)  return "mainW";
   else if (win == rootW)  return "rootW";
   else if (win == vrootW) return "vrootW";
@@ -1106,7 +1289,7 @@
   }
 }
 
-	    
+
 /***********************************/
 static void handleButtonEvent(event, donep, retvalp)
   XEvent *event;
@@ -1127,38 +1310,60 @@
   case ButtonPress:
     /* *always* check for pop-up events, as errors can happen... */
     if (PUCheckEvent  (event)) break;
-    
+
     if (autoquit && win == mainW) Quit(0);
-    
+
     if (viewonly) break;     /* ignore all other button presses */
-    
+
     if (win == mainW && !useroot && showzoomcursor) {
       DoZoom(x, y, but_event->button);
       break;
     }
-    
+
     if (PSCheckEvent  (event)) break;
-    
+
 #ifdef HAVE_JPEG
     if (JPEGCheckEvent(event)) break;
 #endif
-    
+
+#ifdef HAVE_JP2K
+    if (JP2KCheckEvent(event)) break;
+#endif
+
 #ifdef HAVE_TIFF
     if (TIFFCheckEvent(event)) break;
 #endif
-    
+
+#ifdef HAVE_PNG
+    if (PNGCheckEvent (event)) break;
+#endif
+
+#ifdef HAVE_PCD
+    if (PCDCheckEvent (event)) break;	/* event has been processed */
+#endif
+
+#ifdef HAVE_PIC2
+    if (PIC2CheckEvent(event)) break;
+#endif
+
+#ifdef HAVE_MGCSFX
+    if (MGCSFXCheckEvent(event)) break;
+#endif
+
+#ifdef TV_MULTILINGUAL
+    if (CharsetCheckEvent(event)) break;
+#endif
+
     if (GamCheckEvent (event)) break;
     if (BrowseCheckEvent (event, &retval, &done)) break;
     if (TextCheckEvent   (event, &retval, &done)) break;
-    
+
     switch (but_event->button) {
-      
-    case Button1:  
+
+    case Button1:
       if      (win == mainW) DoSelection(but_event);
-      
+
       else if (win == ctrlW) {
-	int   w,h;
-	
 	if      (MBClick(&dispMB,   x,y)) SelectDispMB  (MBTrack(&dispMB)  );
 	else if (MBClick(&conv24MB, x,y)) Select24to8MB (MBTrack(&conv24MB));
 	else if (MBClick(&rootMB,   x,y)) SelectRootMB  (MBTrack(&rootMB)  );
@@ -1170,9 +1375,9 @@
 	  if (i>=0) DoAlg(i);
 	  break;
 	}
-	
+
 	i=ClickCtrl(x,y);
-	
+
 	switch (i) {
 	case BNEXT:   retval= NEXTPIC;  done=1;     break;
 	case BPREV:   retval= PREVPIC;  done=1;     break;
@@ -1192,21 +1397,21 @@
 	case BROTR:   Rotate(0);                    break;
 	case BFLIPH:  Flip(0);                      break;
 	case BFLIPV:  Flip(1);                      break;
-	  
+
 	case BCROP:   Crop();                       break;
 	case BUNCROP: UnCrop();                     break;
 	case BACROP:  AutoCrop();                   break;
-	  
+
 	case BPAD:
 	  {
 	    int mode, wide, high, opaque, omode;  char *str;
-	    
+
 	    while (PadPopUp(&mode, &str, &wide, &high, &opaque, &omode)==0) {
-	      if (DoPad(mode, str, wide, high, opaque, omode)) { 
+	      if (DoPad(mode, str, wide, high, opaque, omode)) {
 		done = 1;  retval = PADDED;  break;
 	      }
-	    }     
-	  }  
+	    }
+	  }
 	  break;
 
 	case BANNOT:  annotatePic();                break;
@@ -1214,85 +1419,127 @@
 	case BABOUT:  SelectWindowMB(WMB_ABOUTXV);  break;
 	case BXV:     retval = DFLTPIC;  done=1;    break;
 	case BQUIT:   retval = QUIT;     done=1;    break;
-	  
+
 	default:      break;
 	}
-	
+
 	if (i==BFLIPH || i==BFLIPV) {
 	  DrawEpic();
 	  SetCursors(-1);
 	}
       }
-      
+
       else if (win == nList.win) {
 	i=LSClick(&nList,but_event);
 	if (curname<0) ActivePrevNext();
 	if (i>=0) { done = 1;  retval = i; }
       }
-      
+
       else if (win == nList.scrl.win) SCTrack(&nList.scrl, x, y);
-      
+
       else if (win == dirW) {
 	i=ClickDirW(x,y);
-	
+
 	switch (i) {
 	case S_BOK:   if (dirUp == BLOAD) {
-	  if (!DirCheckCD()) {
-	    retval = LOADPIC;
-	    done=1;
+	    if (!DirCheckCD()) {
+	      retval = LOADPIC;
+	      done=1;
+	    }
+	  }
+	  else if (dirUp == BSAVE) {
+	    DoSave();
 	  }
-	}
-	else if (dirUp == BSAVE) {
-	  DoSave();
-	}
 	  break;
-	  
+
 	case S_BCANC: DirBox(0);  break;
-	  
+
 	case S_BRESCAN:
 	  WaitCursor();  LoadCurrentDirectory();  SetCursors(-1);
 	  break;
 	}
       }
-      
+
       else if (win == dList.win) {
 	i=LSClick(&dList,but_event);
 	SelectDir(i);
       }
-      
+
       else if (win == dList.scrl.win) SCTrack(&dList.scrl, x,y);
       else if (win == infoW)          InfoBox(0);  /* close info */
-      
+
       break;
-      
-      
-    case Button2:  
+
+
+    case Button2:
       if (win == mainW && !useroot) {
 	if (!shift && !DoSelection(but_event)) TrackPicValues(x,y);
 	else if (shift) Paint();
       }
       break;
-      
+
     case Button3:  /* if using root, MUST NOT get rid of ctrlbox. */
-      if (!shift && !useroot) CtrlBox(!ctrlUp); 
+      if (!shift && !useroot) CtrlBox(!ctrlUp);
       else if (shift) BlurPaint();
       break;
-      
+
+    case Button4:   /* note min vs. max, + vs. - */
+      if (win == ctrlW || win == nList.win || win == nList.scrl.win) {
+	SCRL *sp=&nList.scrl;
+	int  halfpage=sp->page/2;
+
+	if (sp->val > sp->min+halfpage)
+	  SCSetVal(sp,sp->val-halfpage);
+	else
+	  SCSetVal(sp,sp->min);
+      }
+      else if (win ==  dirW || win == dList.win || win == dList.scrl.win) {
+	SCRL *sp=&dList.scrl;
+	int  halfpage=sp->page/2;
+
+	if (sp->val > sp->min+halfpage)
+	  SCSetVal(sp,sp->val-halfpage);
+	else
+	  SCSetVal(sp,sp->min);
+      }
+      break;
+
+    case Button5:   /* note max vs. min, - vs. + */
+      if (win == ctrlW || win == nList.win || win == nList.scrl.win) {
+	SCRL *sp=&nList.scrl;
+	int  halfpage=sp->page/2;
+
+	if (sp->val < sp->max-halfpage)
+	  SCSetVal(sp,sp->val+halfpage);
+	else
+	  SCSetVal(sp,sp->max);
+      }
+      else if (win ==  dirW || win == dList.win || win == dList.scrl.win) {
+	SCRL *sp=&dList.scrl;
+	int  halfpage=sp->page/2;
+
+	if (sp->val < sp->max-halfpage)
+	  SCSetVal(sp,sp->val+halfpage);
+	else
+	  SCSetVal(sp,sp->max);
+      }
+      break;
+
     default:       break;
     }
   }
-  
+
   *donep = done;  *retvalp = retval;
 }
 
-	
+
 /***********************************/
 static void handleKeyEvent(event, donep, retvalp)
   XEvent *event;
   int    *donep, *retvalp;
 {
   /* handles KeyPress and KeyRelease events, called from HandleEvent */
-  
+
   XKeyEvent *key_event;
   KeySym     ks;
   char       buf[128];
@@ -1306,26 +1553,26 @@
   switch (event->type) {
   case KeyRelease:
     if (viewonly) break;     /* ignore all user input */
-    
+
     stlen = XLookupString(key_event,buf,128,&ks,(XComposeStatus *) NULL);
     dealt = 0;
-    
+
     if (key_event->window == mainW) {
       u_int foo = key_event->state;
 
-      if (ks == XK_Shift_L   || ks == XK_Shift_R)   
+      if (ks == XK_Shift_L   || ks == XK_Shift_R)
 	foo = foo & (u_int) (~ShiftMask);
-      if (ks == XK_Control_L || ks == XK_Control_R) 
+      if (ks == XK_Control_L || ks == XK_Control_R)
 	foo = foo & (u_int) (~ControlMask);
-      if (ks == XK_Meta_L    || ks == XK_Meta_R)    
+      if (ks == XK_Meta_L    || ks == XK_Meta_R)
 	foo = foo & (u_int) (~Mod1Mask);
-      if (ks == XK_Alt_L     || ks == XK_Alt_R)     
+      if (ks == XK_Alt_L     || ks == XK_Alt_R)
 	foo = foo & (u_int) (~Mod1Mask);
 
       zoomCurs(foo);
     }
     break;
-    
+
 
   case KeyPress:
     svkeystate = key_event->state;
@@ -1343,11 +1590,11 @@
     if (PUCheckEvent  (event)) break;          /* always check popups */
 
     if (autoquit && key_event->window == mainW) Quit(0);
-    
+
     if (viewonly && !frominterrupt) break;     /* ignore all user input */
-    
+
     if (PSCheckEvent  (event)) break;
-    
+
     if (key_event->window == mainW) {
       u_int foo = key_event->state;
 
@@ -1362,20 +1609,43 @@
     if (JPEGCheckEvent(event)) break;
 #endif
 
+#ifdef HAVE_JP2K
+    if (JP2KCheckEvent(event)) break;
+#endif
+
 #ifdef HAVE_TIFF
     if (TIFFCheckEvent(event)) break;
 #endif
 
+#ifdef HAVE_PNG
+    if (PNGCheckEvent (event)) break;
+#endif
+
+    if (PCDCheckEvent (event)) break;
+
+#ifdef HAVE_PIC2
+    if (PIC2CheckEvent(event)) break;
+#endif
+
+#ifdef HAVE_PCD
+    if (PCDCheckEvent (event)) break;
+#endif
+
+#ifdef HAVE_MGCSFX
+    if (MGCSFXCheckEvent(event)) break;
+#endif
+
     if (GamCheckEvent (event)) break;
     if (BrowseCheckEvent (event, &retval, &done)) break;
     if (TextCheckEvent   (event, &retval, &done)) break;
 
 
-    /* check for pageup/pagedown, 'p' in main window 
-       (you can use shift-up or shift-down if no crop rectangle drawn)
-       (for viewing multipage docs) */
+    /* Support for multi-image files ("multipage docs").  Check for PgUp/PgDn
+       or 'p' in any window but control or directory; PgUp/PgDn are already
+       used to page through the file list in those windows.  If no cropping
+       rectangle is active, shift-Up and shift-Down also work. */
 
-    if (key_event->window == mainW) {
+    if (key_event->window != ctrlW && key_event->window != dirW) {
       dealt = 1;
 
       ck = CursorKey(ks, shift, 0);
@@ -1386,7 +1656,7 @@
 	else XBell(theDisp,0);
       }
 
-      else if (ck==CK_PAGEDOWN || 
+      else if (ck==CK_PAGEDOWN ||
 	       (ck==CK_DOWN && shift && !but[BCROP].active)) {
 	if (strlen(pageBaseName) && numPages>1) {
 	  done = 1;  retval = OP_PAGEDN;
@@ -1396,9 +1666,9 @@
 
       else if (buf[0] == 'p' && stlen>0) {
 	if (strlen(pageBaseName) && numPages>1) {
-	  int  i,j, okay;
-	  char buf[64], txt[512];
-	  static char *labels[] = { "\nOk", "\033Cancel" };
+	  int                i,j, okay;
+	  char               buf[64], txt[512];
+	  static const char *labels[] = { "\nOk", "\033Cancel" };
 
 	  /* ask what page to go to */
 	  sprintf(txt, "Go to page number...   (1-%d)", numPages);
@@ -1429,7 +1699,7 @@
 
       if (dealt) break;
     }
-	
+
 
 
     /* check for crop rect keys */
@@ -1468,15 +1738,17 @@
       if (theList == &dList && dealt) {  /* changed dir selection */
 	SelectDir(-1);  /* nothing was double-clicked */
       }
-      
+
       if (dealt) break;
     }
 
 
     /* check dir filename arrows */
-    ck = CursorKey(ks, shift, 1);
-    if (key_event->window == dirW && ck==CK_LEFT)  { DirKey('\002'); break; }
-    if (key_event->window == dirW && ck==CK_RIGHT) { DirKey('\006'); break; }
+    if (key_event->window == dirW) {
+      ck = CursorKey(ks, shift, 1);
+      if (ck==CK_LEFT)  { DirKey('\002'); break; }
+      if (ck==CK_RIGHT) { DirKey('\006'); break; }
+    }
 
 
     /* check for preset keys     (meta-1, meta-2, meta-3, meta-4, meta-0)
@@ -1491,7 +1763,7 @@
       else if (ks==XK_2) FakeButtonPress(&gbut[G_B2]);
       else if (ks==XK_3) FakeButtonPress(&gbut[G_B3]);
       else if (ks==XK_4) FakeButtonPress(&gbut[G_B4]);
-      else if (ks==XK_r || ks==XK_0) 
+      else if (ks==XK_r || ks==XK_0)
 	                 FakeButtonPress(&gbut[G_BRESET]);
 
       else if (ks==XK_x) FakeButtonPress(&but[BCUT]);
@@ -1521,7 +1793,7 @@
 
       else if (ks==XK_a) FakeButtonPress(&gbut[G_BAPPLY]);
 
-      else if (ks==XK_8) { 
+      else if (ks==XK_8) {
 	if (picType==PIC8) Select24to8MB(CONV24_24BIT);
 	              else Select24to8MB(CONV24_8BIT);
       }
@@ -1530,20 +1802,47 @@
 
       if (dealt) break;
     }
-    
+
+    /* Check for function keys */
+    if (key_event->window == ctrlW || key_event->window == mainW) {
+      if (ks >= XK_F1 && ks <= XK_F1 + FSTRMAX - 1) {
+        int fkey = ks - XK_F1;
+        if (fkeycmds[fkey] && fullfname[0]) {
+#define CMDLEN 4096
+          char cmd[CMDLEN];
+          /* If a command begins with '@', we do not reload the current file */
+          int noreload = (fkeycmds[fkey][0] == '@');
+          int x = 0, y = 0, w = 0, h = 0;
+          if (HaveSelection())
+            GetSelRCoords(&x, &y, &w, &h);
+          snprintf(cmd, CMDLEN, fkeycmds[fkey] + noreload, fullfname, x, y, w, h);
+#undef CMDLEN
+          if (DEBUG) fprintf(stderr, "Executing '%s'\n", cmd);
+          WaitCursor();
+          system(cmd);
+          SetCursors(-1);
+          if (!noreload) {
+            retval = RELOAD;
+            done = 1;
+          }
+          break;
+        }
+      }
+    }
+
     if (!stlen) break;
-    
+
     if (key_event->window == dirW) {
       if (DirKey(buf[0])) XBell(theDisp,0);
     }
     else {                               /* commands valid in any window */
       switch (buf[0]) {
-	
+
 	/* things in dispMB */
       case 'r':    SelectDispMB(DMB_RAW);           break;
       case 'd':    SelectDispMB(DMB_DITH);          break;
       case 's':    SelectDispMB(DMB_SMOOTH);        break;
-	
+
 	/* things in sizeMB */
       case 'n':    SelectSizeMB(SZMB_NORM);         break;
       case 'm':    SelectSizeMB(SZMB_MAXPIC);       break;
@@ -1556,7 +1855,7 @@
       case 'a':    SelectSizeMB(SZMB_ASPECT);       break;
       case '4':    SelectSizeMB(SZMB_4BY3);         break;
       case 'I':    SelectSizeMB(SZMB_INTEXP);       break;
-	
+
 	/* things in windowMB */
       case '\026':
       case 'V':    SelectWindowMB(WMB_BROWSE);      break;  /* ^V or V */
@@ -1565,36 +1864,36 @@
       case '\003': SelectWindowMB(WMB_COMMENT);     break;  /* ^C */
       case '\024': SelectWindowMB(WMB_TEXTVIEW);    break;  /* ^T */
       case '\001': SelectWindowMB(WMB_ABOUTXV);     break;  /* ^A */
-	
-	
-	
+
+
+
 	/* buttons in ctrlW */
       case '\t':
       case ' ':    FakeButtonPress(&but[BNEXT]);    break;
-	
+
       case '\r':
       case '\n':
 	if (nList.selected >= 0 && nList.selected < nList.nstr) {
-	  done = 1;  retval = nList.selected; 
+	  done = 1;  retval = nList.selected;
 	  if (frominterrupt) retval = RELOAD;
 	}
 	break;
-	
-      case '\010':
-      case '\177': FakeButtonPress(&but[BPREV]);    break;
-	
-	
+
+      case '\010': FakeButtonPress(&but[BPREV]);    break;
+
+
       case '\014': FakeButtonPress(&but[BLOAD]);    break;  /* ^L */
       case '\023': FakeButtonPress(&but[BSAVE]);    break;  /* ^S */
       case '\020': FakeButtonPress(&but[BPRINT]);   break;  /* ^P */
+      case '\177':
       case '\004': FakeButtonPress(&but[BDELETE]);  break;  /* ^D */
-	
+
 	/* BCOPY, BCUT, BPASTE, BCLEAR handled in 'meta' case */
-	
+
       case '\007': FakeButtonPress(&but[BGRAB]);    break;  /* ^G */
-	
+
 	/* BUP10, BDN10 handled in sizeMB case */
-	
+
       case 'T':    FakeButtonPress(&but[BROTL]);    break;
       case 't':    FakeButtonPress(&but[BROTR]);    break;
       case 'h':    FakeButtonPress(&but[BFLIPH]);   break;
@@ -1604,24 +1903,24 @@
       case 'C':    FakeButtonPress(&but[BACROP]);   break;
       case 'P':    FakeButtonPress(&but[BPAD]);     break;
       case 'A':    FakeButtonPress(&but[BANNOT]);   break;
-	
+
 	/* BABOUT handled in windowMB case */
-	
+
       case '\021': /* ^Q */
       case 'q':    FakeButtonPress(&but[BQUIT]);    break;
-	
+
       case '?':    if (!useroot) CtrlBox(!ctrlUp);  break;
-	
+
 	/* things in color editor */
       case 'R':    FakeButtonPress(&gbut[G_BRESET]);   break;
       case 'H':    FakeButtonPress(&gbut[G_BHISTEQ]);  break;
       case 'N':    FakeButtonPress(&gbut[G_BMAXCONT]); break;
-	
+
       default:     break;
       }
     }
   }
-  
+
   *donep = done;  *retvalp = retval;
 }
 
@@ -1657,7 +1956,7 @@
   else name = namelist[i];
 
   TextView(name);
-  
+
   if (name != namelist[i]) free(name);
 }
 
@@ -1668,10 +1967,10 @@
   /* open 'set size' prompt window, get a string, parse it, and try to
      set the window size accordingly */
 
-  int   i, arg1, arg2, numargs, pct1, pct2, state, neww, newh;
-  char  txt[512], buf[64], *sp, ch;
-  static char *labels[] = { "\nOk", "\033Cancel" };
-  
+  int                i, arg1, arg2, numargs, pct1, pct2, state, neww, newh;
+  char               txt[512], buf[64], *sp, ch;
+  static const char *labels[] = { "\nOk", "\033Cancel" };
+
   sprintf(txt, "Enter new image display size (ex. '400 x 300'),\n");
   strcat (txt, "expansion ratio (ex. '75%'),\n");
   strcat (txt, "or expansion ratios (ex. '200% x 125%'):");
@@ -1685,7 +1984,7 @@
 
 
   /* attempt to parse the string accordingly...
-   * parses strings of the type: <num> [%] [ x <num> [%] ] 
+   * parses strings of the type: <num> [%] [ x <num> [%] ]
    * (-ish.  <num> all by itself isn't legal)
    * there may be any # of spaces between items, including zero
    */
@@ -1825,7 +2124,7 @@
 
   if (theImage)
     XPutImage(theDisp,mainW,theGC,theImage,x,y,x,y, (u_int) w, (u_int) h);
-  else 
+  else
     if (DEBUG) fprintf(stderr,"Tried to DrawWindow when theImage was NULL\n");
 }
 
@@ -1845,12 +2144,14 @@
     return;
   }
 
+  GetWindowPos(&xwa);
+
   /* determine if new size goes off edge of screen.  if so move window so it
      doesn't go off screen */
-
-  GetWindowPos(&xwa);
   if (xwa.x + w > vrWIDE) xwa.x = vrWIDE - w;
   if (xwa.y + h > vrHIGH) xwa.y = vrHIGH - h;
+  if (xwa.x < 0) xwa.x = 0;
+  if (xwa.y < 0) xwa.y = 0;
 
   if (DEBUG) fprintf(stderr,"%s: resizing window to %d,%d at %d,%d\n",
 		     cmd,w,h,xwa.x,xwa.y);
@@ -1872,7 +2173,7 @@
     XWindowAttributes xwa;
     xvbzero((char *) &xwa, sizeof(XWindowAttributes));
     xwa.x = xwa.y = 0;
-    xwa.width  = dispWIDE;  
+    xwa.width  = dispWIDE;
     xwa.height = dispHIGH;
     SetWindowPos(&xwa);
   }
@@ -1898,14 +2199,14 @@
     rotatesLeft++;
     XClearWindow(theDisp, mainW);  /* get rid of old bits */
     GenExpose(mainW, 0, 0, (u_int) eWIDE, (u_int) eHIGH);
-    { int ew, eh; 
+    { int ew, eh;
       ew = eWIDE;  eh = eHIGH;
       WResize(eWIDE, eHIGH);
       if (ew>maxWIDE || eh>maxHIGH) {   /* rotated pic too big, scale down */
 	double r,wr,hr;
 	wr = ((double) ew) / maxWIDE;
 	hr = ((double) eh) / maxHIGH;
-	
+
 	r = (wr>hr) ? wr : hr;   /* r is the max(wr,hr) */
 	ew = (int) ((ew / r) + 0.5);
 	eh = (int) ((eh / r) + 0.5);
@@ -1920,7 +2221,7 @@
 void WCrop(w,h,dx,dy)
      int w,h,dx,dy;
 {
-  int cx, cy, cw, ch, ex, ey;
+  int ex, ey;
   XWindowAttributes xwa;
 
   if (useroot) {
@@ -1931,7 +2232,7 @@
   else {
     /* we want to move window to old x,y + dx,dy (in pic coords) */
     GetWindowPos(&xwa);
-  
+
     if (!origcropvalid) {  /* first crop.  remember win pos */
       origcropvalid = 1;
       origcropx = xwa.x;
@@ -1939,7 +2240,7 @@
     }
 
     CoordC2E(dx, dy, &ex, &ey);
-    
+
     xwa.x += ex;  xwa.y += ey;
     xwa.width = w;  xwa.height = h;
     GenExpose(mainW, 0, 0, (u_int) eWIDE, (u_int) eHIGH);
@@ -1974,13 +2275,14 @@
       xwa.y = origcropy;
     }
 
-    if (xwa.x + w > vrWIDE) xwa.x = vrWIDE - w;   /* keep on screen */
+    /* keep on screen */
+    if (xwa.x + w > vrWIDE) xwa.x = vrWIDE - w;
     if (xwa.y + h > vrHIGH) xwa.y = vrHIGH - h;
+    if (xwa.x < 0) xwa.x = 0;
+    if (xwa.y < 0) xwa.y = 0;
 
-    if (xwa.x<0) xwa.x = 0;
-    if (xwa.y<0) xwa.y = 0;
     xwa.width = w;  xwa.height = h;
-    
+
     if (!useroot) {
       SetWindowPos(&xwa);
       GenExpose(mainW, 0, 0, (u_int) eWIDE, (u_int) eHIGH);
@@ -1995,8 +2297,8 @@
 XWindowAttributes *xwa;
 {
   Window child;
-  
-  /* returns the x,y,w,h coords of mainW.  x,y are relative to rootW 
+
+  /* returns the x,y,w,h coords of mainW.  x,y are relative to rootW
      the border is not included (x,y map to top-left pixel in window) */
 
   /* Get the window width/height */
@@ -2023,36 +2325,58 @@
 
   /* if we're less than max size in one axis, allow window manager doohickeys
      on the screen */
-  
+
   if (xwa->width  < dispWIDE && xwc.x < p_offx) xwc.x = p_offx;
   if (xwa->height < dispHIGH && xwc.y < p_offy) xwc.y = p_offy;
 
+  /* Try to keep bottom right decorations inside */
+#ifdef CRAP
+  if (xwc.x+eWIDE-debkludge_offx>dispWIDE) {
+    xwc.x=dispWIDE-eWIDE+debkludge_offx;
+    if (xwc.x<0) xwc.x=0;
+  }
+  if (xwc.y+eHIGH-debkludge_offy>dispHIGH) {
+    xwc.y=dispHIGH-eHIGH+debkludge_offy;
+    if (xwc.y<0) xwc.y=0;
+  }
+#else
+  if (xwc.x+eWIDE+p_offx>dispWIDE) {
+    xwc.x=dispWIDE-(eWIDE+debkludge_offx);
+    if (xwc.x<0) xwc.x=0;
+  }
+  if (xwc.y+eHIGH+p_offy>dispHIGH) {
+    xwc.y=dispHIGH-(eHIGH+debkludge_offy);
+    if (xwc.y<0) xwc.y=0;
+  }
+#endif
+
   xwc.width  = xwa->width;
   xwc.height = xwa->height;
 
-
+#define BAD_IDEA
 #ifdef BAD_IDEA
   /* if there is a virtual window manager running, then we should translate
      the coordinates that are in terms of 'real' screen into coordinates
-     that are in terms of the 'virtual' root window 
+     that are in terms of the 'virtual' root window
      from: Daren W. Latham <dwl@mentat.udev.cdc.com> */
-  
+
   if (vrootW != rootW) { /* virtual window manager running */
     int x1,y1;
     Window child;
-    XTranslateCoordinates(theDisp, rootW, vrootW,xwc.x,xwc.y,&x1,&y1,&child);
+
+    XTranslateCoordinates(theDisp, rootW, vrootW, xwc.x, xwc.y, &x1, &y1, &child);
     if (DEBUG) fprintf(stderr,"SWP: translate: %d,%d -> %d,%d\n",
-		       xwc.x,xwc.y,x1,y1);
+		       xwc.x, xwc.y, x1, y1);
     xwc.x = x1;  xwc.y = y1;
   }
-#endif  
+#endif
 
 
   if (DEBUG) {
     fprintf(stderr,
 	    "SWP: xwa=%d,%d %dx%d xwc=%d,%d %dx%d off=%d,%d bw=%d klg=%d,%d\n",
 	    xwa->x, xwa->y, xwa->width, xwa->height,
-	    xwc.x, xwc.y, xwc.width, xwc.height, p_offx, p_offy, 
+	    xwc.x, xwc.y, xwc.width, xwc.height, p_offx, p_offy,
 	    xwa->border_width, kludge_offx, kludge_offy);
   }
 
@@ -2080,7 +2404,7 @@
 
   /* all non-DXWM window managers (?) */
   /* Move/Resize the window. */
-  XConfigureWindow(theDisp, mainW, 
+  XConfigureWindow(theDisp, mainW,
 		   CWX | CWY | CWWidth | CWHeight /*| CWBorderWidth*/, &xwc);
 }
 
@@ -2090,7 +2414,7 @@
 static void CropKey(dx,dy,grow,crop)
      int dx,dy,grow,crop;
 {
-  int x1,x2,y1,y2,active, ocx, ocy;
+  int ocx, ocy;
 
   if (crop) { /* chop off a pixel from the appropriate edge */
     int dealt=1;
@@ -2112,7 +2436,7 @@
     }
     return;
   }
-      
+
   if (grow) MoveGrowSelection(0,  0,  dx, dy);
        else MoveGrowSelection(dx, dy, 0,  0);
 }
@@ -2128,7 +2452,7 @@
   u_long       wh, bl;
   int          ty, w, ecol, done1;
   char         foo[128];
-  char         *str  = 
+  const char   *str  =
    "8888,8888 = 123,123,123  #123456  (123,123,123 HSV)  [-2345,-2345]";
 
   ecol = 0;  wh = infobg;  bl = infofg;
@@ -2136,14 +2460,14 @@
   if (!dropper) {
     Pixmap      pix, mask;
     XColor      cfg, cbg;
-    
+
     cfg.red = cfg.green = cfg.blue = 0x0000;
     cbg.red = cbg.green = cbg.blue = 0xffff;
-    
+
     pix = MakePix1(rootW, dropper_bits,  dropper_width,  dropper_height);
     mask= MakePix1(rootW, dropperm_bits, dropperm_width, dropperm_height);
-    if (pix && mask) 
-      dropper = XCreatePixmapCursor(theDisp, pix, mask, &cfg, &cbg, 
+    if (pix && mask)
+      dropper = XCreatePixmapCursor(theDisp, pix, mask, &cfg, &cbg,
 				    dropper_x_hot, dropper_y_hot);
     if (pix)  XFreePixmap(theDisp, pix);
     if (mask) XFreePixmap(theDisp, mask);
@@ -2151,7 +2475,7 @@
 
   if (dropper) XDefineCursor(theDisp, mainW, dropper);
 
-  /* do a colormap search for black and white if LocalCmap 
+  /* do a colormap search for black and white if LocalCmap
      and use those colors instead of infobg and infofg */
 
   if (LocalCmap) {
@@ -2159,7 +2483,7 @@
 
     for (i=0; i<nfcols; i++) ctab[i].pixel = freecols[i];
     XQueryColors(theDisp,LocalCmap,ctab,nfcols);
-    
+
     /* find 'blackest' pixel */
     cval = 0x10000 * 3;
     for (i=0; i<nfcols; i++)
@@ -2176,7 +2500,7 @@
 	wh = ctab[i].pixel;
       }
   }
-  
+
 
   XSetFont(theDisp, theGC, monofont);
   w = XTextWidth(monofinfo, str, (int) strlen(str));
@@ -2185,7 +2509,7 @@
                else ty = eHIGH-(monofinfo->ascent + mfinfo->descent)-4;
 
   XSetForeground(theDisp, theGC, bl);
-  XFillRectangle(theDisp, mainW, theGC, 0, ty, (u_int) w + 8, 
+  XFillRectangle(theDisp, mainW, theGC, 0, ty, (u_int) w + 8,
 		 (u_int) (monofinfo->ascent+monofinfo->descent) + 4);
   XSetForeground(theDisp, theGC, wh);
   XSetBackground(theDisp, theGC, bl);
@@ -2198,15 +2522,15 @@
 
     if (!XQueryPointer(theDisp,mainW,&rW,&cW,&rx,&ry,&x,&y,&mask)) continue;
     if (done1 && !(mask & Button2Mask)) break;    /* button released */
-    
+
     CoordE2P(x,y, &px, &py);
-    RANGE(px,0,pWIDE-1);  
+    RANGE(px,0,pWIDE-1);
     RANGE(py,0,pHIGH-1);
-    
+
     if (px!=ox || py!=oy || !done1) {  /* moved, or firsttime.  erase & draw */
       double h1, s1, v1;
       int    rval, gval, bval;
-      
+
       if (picType == PIC8) {
 	ecol = pix = pic[py * pWIDE + px];
 	rval = rcmap[pix];  gval = gcmap[pix];  bval = bcmap[pix];
@@ -2216,7 +2540,7 @@
 	gval = pic[py * pWIDE * 3 + px * 3 + 1];
 	bval = pic[py * pWIDE * 3 + px * 3 + 2];
       }
-      
+
       clearR = rval;  clearG = gval;  clearB = bval;
 
       rgb2hsv(rval, gval, bval, &h1, &s1, &v1);
@@ -2229,8 +2553,8 @@
 	      px, py, rval, gval, bval, rval, gval, bval,
 	      (int) h1, (int) (s1 * 100), (int) (v1 * 100),
 	      px-orgx, py-orgy);
-      
-      XDrawImageString(theDisp,mainW,theGC, 4, ty + 2 + monofinfo->ascent, 
+
+      XDrawImageString(theDisp,mainW,theGC, 4, ty + 2 + monofinfo->ascent,
 		       foo, (int) strlen(foo));
       ox = px;  oy = py;
       done1 = 1;
@@ -2275,7 +2599,7 @@
 
   /* returns true if there's a config event in which mainW changes size
      in the event queue */
-  
+
   XSync(theDisp, False);
   foo = 0;
   XCheckIfEvent(theDisp, &ev, IsConfig, &foo);
@@ -2328,7 +2652,7 @@
    *    BadMatch  errors on XGetImage
    */
 
-  if ((xerrcode == BadAlloc)                                               || 
+  if ((xerrcode == BadAlloc)                                               ||
       (xerrcode == BadAccess && err->request_code==88 /* X_FreeColors */ ) ||
       (err->request_code == 113                       /* X_KillClient */ ) ||
       (xerrcode == BadLength && err->request_code==18 /* X_ChangeProp */ ) ||
@@ -2361,17 +2685,39 @@
 {
   /* but first, if any input-grabbing popups are active, we have to 'cancel'
      them. */
-  
+
   if (psUp) PSDialog(0);      /* close PS window */
 
 #ifdef HAVE_JPEG
   if (jpegUp) JPEGDialog(0);  /* close jpeg window */
 #endif
 
+#ifdef HAVE_JP2K
+  if (jp2kUp) JP2KDialog(0);  /* close jpeg 2000 window */
+#endif
+
 #ifdef HAVE_TIFF
   if (tiffUp) TIFFDialog(0);  /* close tiff window */
 #endif
 
+#ifdef HAVE_PNG
+  if (pngUp) PNGDialog(0);    /* close png window */
+#endif
+
+  if (pcdUp) PCDDialog(0);    /* close pcd window */
+
+#ifdef HAVE_PIC2
+  if (pic2Up) PIC2Dialog(0);  /* close pic2 window */
+#endif
+
+#ifdef HAVE_PCD
+  if (pcdUp)  PCDDialog(0);   /* close pcd window */
+#endif
+
+#ifdef HAVE_MGCSFX
+  if (mgcsfxUp) MGCSFXDialog(0);  /* close mgcsfx window */
+#endif
+
   ClosePopUp();
 
   /* make the interrupt signal look like a '\n' keypress in ctrlW */
@@ -2400,14 +2746,14 @@
   if (!pen) {
     Pixmap      pix, pmask;
     XColor      cfg, cbg;
-    
+
     cfg.red = cfg.green = cfg.blue = 0x0000;
     cbg.red = cbg.green = cbg.blue = 0xffff;
-    
+
     pix = MakePix1(rootW, pen_bits,  pen_width,  pen_height);
     pmask= MakePix1(rootW, penm_bits, penm_width, penm_height);
-    if (pix && pmask) 
-      pen = XCreatePixmapCursor(theDisp, pix, pmask, &cfg, &cbg, 
+    if (pix && pmask)
+      pen = XCreatePixmapCursor(theDisp, pix, pmask, &cfg, &cbg,
 				    pen_x_hot, pen_y_hot);
     if (pix)   XFreePixmap(theDisp, pix);
     if (pmask) XFreePixmap(theDisp, pmask);
@@ -2416,7 +2762,7 @@
   if (pen) XDefineCursor(theDisp, mainW, pen);
 
 
-  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
+  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask
 	       | StructureNotifyMask /* | ButtonPressMask */
 	       | KeyReleaseMask | ColormapChangeMask
 	       | EnterWindowMask | LeaveWindowMask );
@@ -2435,7 +2781,7 @@
 
     switch (state) {
     case 0:               /* initial state:  make sure we do one pixel */
-      px1 = lx = px;  py1 = ly = py;  
+      px1 = lx = px;  py1 = ly = py;
       paintPixel(px, py);
 
       if      (nmask & ShiftMask  ) state = 99;
@@ -2444,7 +2790,7 @@
       else                          state = 10;
       break;
 
-      
+
     case 1:               /* waiting for click */
       if      (nmask & ShiftMask) state = 99;
       else if ( mask & Button2Mask) {
@@ -2459,7 +2805,7 @@
       }
       break;
 
-      
+
     case 10:               /* in freehand drawing mode */
       if      (nmask & ShiftMask  ) state = 99;
       else if (nmask & Button2Mask) state = 1;
@@ -2507,11 +2853,11 @@
 	  XSync(theDisp, False);
 	  Timer(100);
 	}
-	  
+
 	if (nmask & Button2Mask) seenRelease = 1;
       }
       break;
-      
+
     case 99:              /* EXIT loop:  cleanup */
       if (line) { /* erase old xor-line */
 	paintXLine(lx, ly, px1, py1, 0);
@@ -2521,11 +2867,11 @@
       break;
     }
   }
-    
-  
+
+
   WaitCursor();
-  
-  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
+
+  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask
 	       | StructureNotifyMask | ButtonPressMask
 	       | KeyReleaseMask | ColormapChangeMask
 	       | EnterWindowMask | LeaveWindowMask );
@@ -2557,17 +2903,17 @@
     byte *pp = pic + (y * pWIDE + x) * 3;
     pp[0] = clearR;  pp[1] = clearG;  pp[2] = clearB;
   }
-  
+
   /* visual feedback */
   CoordP2E(x,   y,   &ex,  &ey);
   CoordP2E(x+1, y+1, &ex1, &ey1);
-  
+
   ew = ex1-ex;  eh = ey1-ey;
-  
+
   if (picType == PIC8) XSetForeground(theDisp, theGC, cols[editColor]);
   else XSetForeground(theDisp, theGC, RGBToXColor(clearR, clearG, clearB));
-  
-  if (ew>0 && eh>0) 
+
+  if (ew>0 && eh>0)
     XFillRectangle(theDisp,mainW,theGC, ex,ey, (u_int) ew, (u_int) eh);
 }
 
@@ -2576,29 +2922,46 @@
 static void paintLine(x,y,x1,y1)
   int x,y,x1,y1;
 {
-  int dx,dy,i,lx,ly,adx,ady;
-  
-  dx = x1-x;  dy = y1-y;
-  adx = abs(dx);  ady = abs(dy);
-
-  if (dx == 0 && dy == 0) paintPixel(x,y);
-
-  else if (adx > ady) {           /* X is major axis */
-    for (i=0; i<=adx; i++) {
-      lx = x + (i * dx + (adx/2)) / abs(dx);
-      ly = y + (i * dy + (adx/2)) / abs(dx);
-      paintPixel(lx,ly);
+  int t,dx,dy,d,dd;
+
+  dx = abs(x1-x);  dy = abs(y1-y);
+
+  if (dx >= dy) {                       /* X is major axis */
+    if (x > x1) {
+       t = x; x = x1; x1 = t;
+       t = y; y = y1; y1 = t;
+     }
+    d = dy + dy - dx;
+    dd = y < y1 ? 1 : -1;
+    while (x <= x1) {
+      paintPixel(x,y);
+      if (d > 0) {
+        y += dd;
+        d -= dx + dx;
+      }
+      ++x;
+      d += dy + dy;
     }
   }
 
   else {                                /* Y is major axis */
-    for (i=0; i<=ady; i++) {
-      lx = x + (i * dx + (ady/2)) / ady;
-      ly = y + (i * dy + (ady/2)) / ady;
-      paintPixel(lx,ly);
+    if (y > y1) {
+       t = x; x = x1; x1 = t;
+       t = y; y = y1; y1 = t;
+     }
+    d = dx + dx - dy;
+    dd = x < x1 ? 1 : -1;
+    while (y <= y1) {
+      paintPixel(x,y);
+      if (d > 0) {
+        x += dd;
+        d -= dy + dy;
+      }
+      ++y;
+      d += dx + dx;
     }
   }
-  
+
 
 }
 
@@ -2618,14 +2981,14 @@
   CoordP2E(x+1,y+1,&tx1,&ty1);
   ex = tx + (tx1 - tx)/2;
   ey = ty + (ty1 - ty)/2;
-  
+
   CoordP2E(x1,  y1,  &tx, &ty);
   CoordP2E(x1+1,y1+1,&tx1,&ty1);
   ex1 = tx + (tx1 - tx)/2;
   ey1 = ty + (ty1 - ty)/2;
-  
+
   if (ex==ex1 && ey==ey1) return;
-  
+
   XSetPlaneMask(theDisp, theGC, xorMasks[pntxlcol]);
   XSetFunction(theDisp, theGC, GXinvert);
   XDrawLine(theDisp, mainW, theGC, ex, ey, ex1, ey1);
@@ -2638,10 +3001,8 @@
 static void BlurPaint()
 {
   Window  rW,cW;
-  int     rx,ry,ox,oy,x,y, px,py, ex,ey, ex1,ey1, ew, eh, done1, dragging;
-  int     uppedpic;
+  int     rx,ry,ox,oy,x,y, px,py, done1, dragging;
   u_int   mask;
-  byte   *pp;
 
   /* blurs pixels in either editCol (PIC8) or clear{R,G,B} (PIC24) until
      'shift' key is released.  */
@@ -2653,14 +3014,14 @@
   if (!blur) {
     Pixmap      pix, mask;
     XColor      cfg, cbg;
-    
+
     cfg.red = cfg.green = cfg.blue = 0x0000;
     cbg.red = cbg.green = cbg.blue = 0xffff;
-    
+
     pix = MakePix1(rootW, blur_bits,  blur_width,  blur_height);
     mask= MakePix1(rootW, blurm_bits, blurm_width, blurm_height);
-    if (pix && mask) 
-      blur = XCreatePixmapCursor(theDisp, pix, mask, &cfg, &cbg, 
+    if (pix && mask)
+      blur = XCreatePixmapCursor(theDisp, pix, mask, &cfg, &cbg,
 				    blur_x_hot, blur_y_hot);
     if (pix)  XFreePixmap(theDisp, pix);
     if (mask) XFreePixmap(theDisp, mask);
@@ -2669,7 +3030,7 @@
   if (blur) XDefineCursor(theDisp, mainW, blur);
 
 
-  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
+  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask
 	       | StructureNotifyMask /* | ButtonPressMask */
 	       | KeyReleaseMask | ColormapChangeMask
 	       | EnterWindowMask | LeaveWindowMask );
@@ -2682,12 +3043,12 @@
     if (!(mask & Button3Mask)) { dragging = 0;  continue; }
 
     CoordE2P(x,y, &px, &py);
-    
+
     if (!dragging || (dragging && (px!=ox || py!=oy))) {  /* click or drag */
       if (!dragging) blurPixel(px,py);
       else {
 	int dx,dy,i,lx,ly;
-	
+
 	dx = px-ox;  dy = py-oy;   /* at least one will be non-zero */
 	if (abs(dx) > abs(dy)) {   /* X is major axis */
 	  for (i=0; i<=abs(dx); i++) {
@@ -2707,10 +3068,10 @@
       done1 = 1;  dragging = 1;  ox = px;  oy = py;
     }
   }
-  
+
   WaitCursor();
-  
-  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
+
+  XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask
 	       | StructureNotifyMask | ButtonPressMask
 	       | KeyReleaseMask | ColormapChangeMask
 	       | EnterWindowMask | LeaveWindowMask );
@@ -2731,9 +3092,9 @@
 {
   /* returns position of highest set bit in 'ul' as an integer (0-31),
      or -1 if none */
-  
+
   int i;  unsigned long hb;
-  
+
   hb = 0x80;  hb = hb << 24;   /* hb = 0x80000000UL */
   for (i=31; ((ul & hb) == 0) && i>=0;  i--, ul<<=1);
   return i;
@@ -2757,7 +3118,7 @@
 
     d = 3*(256*256);  j=0;
     for (i=0; i<numcols; i++) {
-      di = ((r-rMap[i]) * (r-rMap[i])) + 
+      di = ((r-rMap[i]) * (r-rMap[i])) +
 	   ((g-gMap[i]) + (g-gMap[i])) +
            ((b-bMap[i]) * (b-bMap[i]));
       if (i==0 || di<d) { j=i;  d=di; }
@@ -2771,45 +3132,45 @@
     if (theVisual->class==TrueColor || theVisual->class==DirectColor) {
       unsigned long rmask, gmask, bmask;
       int           rshift, gshift, bshift, cshift, maplen;
-      
+
       /* compute various shifting constants that we'll need... */
-      
+
       rmask = theVisual->red_mask;
       gmask = theVisual->green_mask;
       bmask = theVisual->blue_mask;
-      
+
       rshift = 7 - highbit(rmask);
       gshift = 7 - highbit(gmask);
       bshift = 7 - highbit(bmask);
-      
+
       if (theVisual->class == DirectColor) {
 	maplen = theVisual->map_entries;
 	if (maplen>256) maplen=256;
 	cshift = 7 - highbit((u_long) (maplen-1));
-	
+
 	r = (u_long) directConv[(r>>cshift) & 0xff] << cshift;
 	g = (u_long) directConv[(g>>cshift) & 0xff] << cshift;
 	b = (u_long) directConv[(b>>cshift) & 0xff] << cshift;
       }
-      
-      
+
+
       /* shift the bits around */
       if (rshift<0) r = r << (-rshift);
       else r = r >> rshift;
-      
+
       if (gshift<0) g = g << (-gshift);
       else g = g >> gshift;
-      
+
       if (bshift<0) b = b << (-bshift);
       else b = b >> bshift;
-      
+
       r = r & rmask;
       g = g & gmask;
       b = b & bmask;
-      
+
       rv =r | g | b;
     }
-    
+
     else {                          /* non-TrueColor/DirectColor visual */
       if (!ncols)
 	rv = ((r + g + b >= 128*3) ? white : black);
@@ -2820,14 +3181,14 @@
 
   return rv;
 }
-      
-    
+
+
 /***********************/
 static void blurPixel(x,y)
      int x,y;
 {
   /* blurs pixel x,y (pic coords) into pic in editColor (PIC8) or clearR,G,B
-     (PIC24) and does appropriate screen feedback.  Does a 3x3 average 
+     (PIC24) and does appropriate screen feedback.  Does a 3x3 average
      around the pixel, and replaces it with the average value (PIC24), or
      the closest existing color to the average value (PIC8) */
 
@@ -2861,7 +3222,7 @@
   if (picType == PIC8) {  /* find nearest actual color */
     d = 3*(256*256);  j=0;
     for (i=0; i<numcols; i++) {
-      di = ((ar-rMap[i]) * (ar-rMap[i])) + 
+      di = ((ar-rMap[i]) * (ar-rMap[i])) +
 	   ((ag-gMap[i]) + (ag-gMap[i])) +
            ((ab-bMap[i]) * (ab-bMap[i]));
       if (i==0 || di<d) { j=i;  d=di; }
@@ -2874,17 +3235,17 @@
     pp = pic + (y * pWIDE + x) * 3;
     pp[0] = ar;  pp[1] = ag;  pp[2] = ab;
   }
-  
+
   /* visual feedback */
   CoordP2E(x,   y,   &ex,  &ey);
   CoordP2E(x+1, y+1, &ex1, &ey1);
-  
+
   ew = ex1-ex;  eh = ey1-ey;
-  
+
   if (picType == PIC8) XSetForeground(theDisp, theGC, cols[ac]);
   else XSetForeground(theDisp, theGC, RGBToXColor(ar, ag, ab));
-  
-  if (ew>0 && eh>0) 
+
+  if (ew>0 && eh>0)
     XFillRectangle(theDisp,mainW,theGC, ex,ey, (u_int) ew, (u_int) eh);
 }
 
@@ -2895,19 +3256,19 @@
 /***********************/
 static void annotatePic()
 {
-  int          i, w,h, len;
-  byte        *cimg;
-  char         txt[256];
-  static char  buf[256] = {'\0'};
-  static char *labels[] = {"\nOk", "\033Cancel" };
+  int                i, w,h, len;
+  byte              *cimg;
+  char               txt[256];
+  static char        buf[256] = {'\0'};
+  static const char *labels[] = {"\nOk", "\033Cancel" };
 
-  sprintf(txt, "Image Annotation:\n\n%s", 
+  sprintf(txt, "Image Annotation:\n\n%s",
 	  "Enter string to be placed on image.");
-  
+
   i = GetStrPopUp(txt, labels, 2, buf, 256, "", 0);
   if (i==1 || strlen(buf)==0) return;
-  
-  
+
+
   /* build a 'cimg' array to be pasted on clipboard */
   w = strlen(buf) * 6 - 1;  h = 9;
   len = CIMG_PIC8 + w*h;
diff -ru xv-3.10a/xvfits.c xv-3.10a-enhancements/xvfits.c
--- xv-3.10a/xvfits.c	1994-12-27 23:43:29.000000000 -0800
+++ xv-3.10a-enhancements/xvfits.c	2007-05-12 15:46:55.000000000 -0700
@@ -14,7 +14,7 @@
  * provided "as is" without express or implied warranty.
  */
 
-
+#define  NEEDSDIR /* for S_IRUSR|S_IWUSR */
 #include "xv.h"
 
 #define NCARDS    (36)
@@ -39,17 +39,17 @@
 static char *fits_block=NULL;
 
 
-static int   splitfits  PARM((byte *, char *, int, int, int, char *));
-static char *ftopen3d   PARM((FITS *, char *, int *, int *, int *, int *));
-static void  ftclose    PARM((FITS *));
-static int   ftgbyte    PARM((FITS *, byte *, int));
-static char *rdheader   PARM((FITS *));
-static char *wrheader   PARM((FILE *, int, int, char *));
-static char *rdcard     PARM((char *, char *, DATTYPE, long int *));
-static void  wrcard     PARM((char *, char *, DATTYPE, int, char *));
-static int   ftgdata    PARM((FITS *, void *, int));
-static void  ftfixdata  PARM((FITS *, void *, int));
-static void  flip       PARM((byte *, int, int));
+static       int   splitfits PARM((byte *, char *, int, int, int, char *));
+static const char *ftopen3d  PARM((FITS *, char *, int *, int *, int *, int *));
+static       void  ftclose   PARM((FITS *));
+static       int   ftgbyte   PARM((FITS *, byte *, int));
+static const char *rdheader  PARM((FITS *));
+static const char *wrheader  PARM((FILE *, int, int, char *));
+static const char *rdcard    PARM((char *, const char *, DATTYPE, long int *));
+static       void  wrcard    PARM((char *, const char *, DATTYPE, int, char *));
+static       int   ftgdata   PARM((FITS *, void *, int));
+static       void  ftfixdata PARM((FITS *, void *, int));
+static       void  flip      PARM((byte *, int, int));
 
 
 
@@ -63,16 +63,16 @@
   /* returns '1' on success */
 
   FITS  fs;
-  int   i, nx, ny, nz, bitpix, np, nrd, ioerror;
+  int   i, nx, ny, nz, bitpix, nrd, ioerror, npixels, bufsize;
   byte *image;
-  char *error;
+  const char *error;
   char  basename[64];
 
   if (fits_block == NULL) {
     fits_block = (char *) malloc((size_t) BLOCKSIZE);
     if (!fits_block) FatalError("Insufficient memory for FITS block buffer");
   }
-  
+
   error = ftopen3d(&fs, fname, &nx, &ny, &nz, &bitpix);
   if (error) {
     SetISTR(ISTR_WARNING, "%s", error);
@@ -80,9 +80,15 @@
   }
 
   if (quick) nz = 1;             /* only load first plane */
-  np = nx * ny * nz;
+  npixels = nx * ny;
+  bufsize = nz * npixels;
+  if (nx <= 0 || ny <= 0 || npixels/nx != ny || bufsize/nz != npixels) {
+    SetISTR(ISTR_WARNING, "FITS image dimensions out of range (%dx%dx%d)",
+      nx, ny, nz);
+    return 0;
+  }
 
-  image = (byte *) malloc((size_t) np);
+  image = (byte *) malloc((size_t) bufsize);
   if (!image) FatalError("Insufficient memory for image");
 
   /*
@@ -90,7 +96,7 @@
    * to ensure that we get that same scaling for all planes.
    */
 
-  nrd     = ftgbyte(&fs, image, np);
+  nrd     = ftgbyte(&fs, image, bufsize);
   ioerror = ferror(fs.fp);
   ftclose(&fs);
 
@@ -104,33 +110,32 @@
     return 0;
   }
 
-  else if (nrd < np) {       /* read partial image */
+  else if (nrd < bufsize) {       /* read partial image */
     if (ioerror)
       SetISTR(ISTR_WARNING, "%s", "Truncated FITS file due to I/O error");
     else
       SetISTR(ISTR_WARNING, "%s", "Truncated FITS file");
-    
+
     { byte *foo;
-      for (foo=image+nrd; foo<image+np; foo++) *foo=0x80;  /* pad with grey */
+      for (foo=image+nrd; foo<image+bufsize; foo++) *foo=0x80;  /* pad with grey */
     }
   }
 
   if (nz > 1) {
     /* how many planes do we actually have? */
-    nz = (nrd-1)/(nx*ny) + 1;
+    nz = (nrd-1)/(npixels) + 1;
 
     /* returns how many sub-files created */
     nz = splitfits(image, fs.comment, nx, ny, nz, basename);
-    np = nx * ny;
-    image = (byte *)realloc(image, (size_t) np);  /* toss all but first */
+    image = (byte *)realloc(image, (size_t) npixels);  /* toss all but first */
   }
-  
+
   /* There seems to be a convention that fits files be displayed using
    * a cartesian coordinate system. Thus the first pixel is in the lower left
    * corner. Fix this by reflecting in the line y=ny/2.
    */
   flip(image, nx, ny);
-  
+
   /* Success! */
   pinfo->pic  = image;
   pinfo->type = PIC8;
@@ -149,12 +154,12 @@
     pinfo->numpages = nz;
     strcpy(pinfo->pagebname, basename);
   }
-  
+
   return 1;
-}  
+}
+
 
 
-	  
 /*******************************************/
 int WriteFITS(fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle,comment)
      FILE *fp;
@@ -164,16 +169,16 @@
      int   numcols, colorstyle;
      char *comment;
 {
-  int   i, j, np, nend;
+  int   i, j, npixels, nend;
   byte *ptr;
-  char *error;
+  const char *error;
   byte  rgb[256];
-  
+
   if (!fits_block) {
     fits_block = (char *) malloc((size_t) BLOCKSIZE);
     if (!fits_block) FatalError("Insufficient memory for FITS block buffer");
   }
-  
+
   error = wrheader(fp, w, h, comment);
   if (error) {
     SetISTR(ISTR_WARNING, "%s", error);
@@ -197,12 +202,12 @@
     }
   }
 
-  np = w*h;
+  npixels = w*h;
 
   /* nend is the number of padding characters at the end of the last block */
-  nend = ((np+BLOCKSIZE-1)/BLOCKSIZE)*BLOCKSIZE - np;
+  nend = ((npixels+BLOCKSIZE-1)/BLOCKSIZE)*BLOCKSIZE - npixels;
   if (nend) for (i=0; i<nend; i++) putc('\0', fp);
-  
+
   return 0;
 }
 
@@ -216,17 +221,16 @@
      char *basename;
 {
   /*
-   * Given a 3 dimensional FITS image, this splits it up into nz 2-d files.
+   * Given a 3-dimensional FITS image, this splits it up into nz 2-d files.
    * It returns the number of files actually stored.
    * If only one file could be written, then no split files are created.
    * It returns the basename of the split files in bname.
    * If there was a problem writing files, then a error message will be set.
    */
-  
-  int   i, np=nx * ny, ioerror, nwrt;
+
+  int   i, npixels=nx * ny, nwrt, tmpfd;
   FILE *fp;
-  char *error;
-  byte *work;
+  const char *error;
   char  filename[70];
 
 #ifndef VMS
@@ -234,8 +238,12 @@
 #else
   sprintf(basename, "Sys$Disk:[]xvpgXXXXXX");
 #endif
-  
+
+#ifdef USE_MKSTEMP
+  close(mkstemp(basename));
+#else
   mktemp(basename);
+#endif
   if (basename[0] == '\0') {
     SetISTR(ISTR_WARNING, "%s", "Unable to build temporary filename");
     return 1;
@@ -246,28 +254,37 @@
 
   for (i=0; i < nz && !error; i++) {
     sprintf(filename, "%s%d", basename, i+1);
-    fp = xv_fopen(filename, "w");
+    tmpfd = open(filename,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR);
+    if (tmpfd < 0) {
+      error = "Unable to open temporary file";
+      break;
+    }
+    fp = fdopen(tmpfd, "w");
     if (!fp) {
       error = "Unable to open temporary file";
       break;
     }
-    
+
     if (wrheader(fp, nx, ny, comment)) {
       error = "I/O error writing temporary file";
+      fflush(fp);
       fclose(fp);
       unlink(filename);
+      close(tmpfd);
       break;
     }
 
-    nwrt = fwrite(image+i*np, sizeof(byte), (size_t) np, fp);
+    nwrt = fwrite(image+i*npixels, sizeof(byte), (size_t) npixels, fp);
+    fflush(fp);
     fclose(fp);
+    close(tmpfd);
 
     if (nwrt == 0) {  /* failed to write any data */
       error = "I/O error writing temporary file";
       unlink(filename);
       break;
-    } 
-    else if (nwrt < np)
+    }
+    else if (nwrt < npixels)
       error = "I/O error writing temporary file";
   }
 
@@ -285,19 +302,19 @@
 
 
 /************************************/
-static char *wrheader(fp, nx, ny, comment)
+static const char *wrheader(fp, nx, ny, comment)
      FILE *fp;
      int nx, ny;
      char *comment;
 {
   /* Writes a minimalist FITS file header */
-  
+
   char *block = fits_block, *bp;
-  int   i, j, wrotehist, lenhist;
+  int   i, j, lenhist;
   char  history[80];
 
   for (i=0, bp=block; i<BLOCKSIZE; i++, bp++) *bp = ' ';
-  
+
   sprintf(history, "Written by XV %s", VERSTR);
   lenhist = strlen(history);
 
@@ -309,7 +326,7 @@
   wrcard(&block[80*i++], "NAXIS2", T_INT, ny, NULL);  /* write NAXIS2 card */
 
   /* Write HISTORY keyword */
-  wrcard(&block[80*i++], "HISTORY", T_STR, lenhist, history); 
+  wrcard(&block[80*i++], "HISTORY", T_STR, lenhist, history);
 
   if (comment && *comment != '\0') {
     while (*comment == '\n') comment++;  /* Skip any blank lines */
@@ -317,7 +334,7 @@
       for (j=0; j<72; j++)
 	if (comment[j] == '\0' || comment[j] == '\n') break;
 
-      /* 
+      /*
        * Check to see if it is an xv history record; if so, then avoid
        * duplicating it.
        */
@@ -330,7 +347,7 @@
 	for (i=0, bp=block; i<BLOCKSIZE; i++, bp++) *bp = ' ';
 	i = 0;
       }
-      
+
       comment += j;
       while (*comment == '\n') comment++;  /* Skip any blank lines */
     }
@@ -346,7 +363,7 @@
 
 
 /************************************/
-static char *ftopen3d(fs, file, nx, ny, nz, bitpix)
+static const char *ftopen3d(fs, file, nx, ny, nz, bitpix)
      FITS *fs;
      char *file;
      int  *nx, *ny, *nz, *bitpix;
@@ -358,40 +375,40 @@
    * Will return an error message if the primary data unit is not a
    * 2 or 3-dimensional array.
    */
-  
+
   FILE *fp;
   int naxis, i;
-  char *error;
-  
+  const char *error;
+
   fp = xv_fopen(file, "r");
   if (!fp) return "Unable to open FITS file";
-  
+
   fs->fp     = fp;
   fs->bitpix = 0;
   fs->naxis  = 0;
   fs->cpos   = 0;
-  
+
   /* read header */
   error = rdheader(fs);
   if (error) {
     ftclose(fs);
     return error;
   }
-  
+
   naxis = fs->naxis;
-  
+
   /* get number of data */
   fs->ndata = 1;
-  for (i=0; i<naxis; i++) 
+  for (i=0; i<naxis; i++)
     fs->ndata = fs->ndata * fs->axes[i];
-  
+
   *nx = fs->axes[0];
   *ny = fs->axes[1];
   if (naxis == 2) *nz = 1;
              else *nz = fs->axes[2];
-  
+
   *bitpix = fs->bitpix;
-  
+
   return NULL;
 }
 
@@ -406,7 +423,7 @@
 
 
 /************************************/
-static char *rdheader(fs)
+static const char *rdheader(fs)
      FITS *fs;
 {
   /* reads the fits header, and updates the FITS structure fs.
@@ -416,13 +433,13 @@
   int i, j, res, commlen, commsize;
   char name[9];
   char *block=fits_block, *p;
-  char *error;
+  const char *error;
   long int val;         /* the value */
-  
+
   fs->comment = NULL;
   commlen     = 0;
   commsize    = 256;
-  
+
   res = fread(block, sizeof(char), (size_t) BLOCKSIZE, fs->fp);
   if (res != BLOCKSIZE) return "Error reading FITS file";
   i = 0;
@@ -464,13 +481,13 @@
       if (res != BLOCKSIZE) return "Error reading FITS file";
       i = 0;
     }
-    
+
     sprintf(name, "NAXIS%d", j+1);
     error = rdcard(&block[i*80], name, T_INT, &val);
     if (error)    return error;
     if (val < 0)  return "Bad NAXISn value in FITS file";
     if (val == 0) return "FITS file does not contain an image";
-    
+
     if (j < 3)    fs->axes[j] = val;
     else if (val != 1) return "FITS file has more than three dimensions";
     i++;
@@ -488,21 +505,21 @@
       if (res != BLOCKSIZE) return "Unexpected eof in FITS file";
       i = 0;
     }
-    
+
     p = &block[i*80];
     if (strncmp(p, "END     ", (size_t) 8) == 0) break;
-    if (strncmp(p, "HISTORY ", (size_t) 8) == 0 || 
+    if (strncmp(p, "HISTORY ", (size_t) 8) == 0 ||
 	strncmp(p, "COMMENT ", (size_t) 8) == 0) {
       p += 8;                       /* skip keyword */
       for (j=71; j >= 0; j--) if (p[j] != ' ') break;
       j++;                          /* make j length of comment */
       if (j > 0) {                  /* skip blank comment cards */
 	if (fs->comment == NULL) {
-	  fs->comment = (char *) malloc((size_t) commsize);
+	  fs->comment = (char *) malloc((size_t) commsize);  /* initially 256 */
 	  if (fs->comment == NULL)
 	    FatalError("Insufficient memory for comment buffer");
 	}
-	
+
 	if (commlen + j + 2 > commsize) { /* if too small */
 	  char *new;
 	  commsize += commsize;      /* double size of array */
@@ -515,7 +532,7 @@
 	  free(fs->comment);
 	  fs->comment = new;
 	}
-	
+
 	xvbcopy(p, &fs->comment[commlen], (size_t) j);  /* add string */
 	commlen += j;
 	fs->comment[commlen++] = '\n';       /* with trailing cr */
@@ -531,7 +548,8 @@
 
 /************************************/
 static void wrcard(card, name, dtype, kvalue, svalue)
-     char *card, *name;
+     char *card;
+     const char *name;
      DATTYPE dtype;   /* type of value */
      int kvalue;
      char *svalue;
@@ -556,9 +574,9 @@
 
   l = strlen(name);
   if (l) xvbcopy(name, card, (size_t) l);   /* copy name */
-  
+
   if (dtype == T_NOVAL) return;
-  
+
   if (dtype == T_STR) {
     l = kvalue;
     if (l <= 0) return;
@@ -566,9 +584,9 @@
     xvbcopy(svalue, &card[8], (size_t) l);
     return;
   }
-  
+
   card[8] = '=';
-  
+
   if (dtype == T_LOG)
     card[29] = kvalue ? 'T' : 'F';
   else { /* T_INT */
@@ -579,8 +597,9 @@
 
 
 /************************************/
-static char *rdcard(card, name, dtype, kvalue)
-     char *card, *name;
+static const char *rdcard(card, name, dtype, kvalue)
+     char *card;
+     const char *name;
      DATTYPE dtype;   /* type of value */
      long int *kvalue;
 {
@@ -599,7 +618,7 @@
   int         i, ptr;
   char        namestr[9];
   static char error[45];
-  
+
   xvbcopy(card, namestr, (size_t) 8);
 
   for (i=7; i>=0 && namestr[i] == ' '; i--);
@@ -609,24 +628,24 @@
     sprintf(error, "Keyword %s not found in FITS file", name);
     return error;
   }
-  
+
 
   /* get start of value */
   ptr = 10;
   while (ptr < 80 && card[ptr] == ' ') ptr++;
   if (ptr == 80) return "FITS file has missing keyword value"; /* no value */
-  
+
   if (dtype == T_LOG) {
     if (ptr != 29 || (card[29] != 'T' && card[29] != 'F'))
       return "Keyword has bad logical value in FITS file";
     *kvalue = (card[29] == 'T');
-  } 
+  }
 
   else {  /* an integer */
     int j;
     long int ival;
     char num[21];
-    
+
     if (ptr > 29) return "Keyword has bad integer value in FITS file";
     xvbcopy(&card[ptr], num, (size_t) (30-ptr));
     num[30-ptr] = '\0';
@@ -634,7 +653,7 @@
     if (j != 1) return "Keyword has bad integer value in FITS file";
     *kvalue = ival;
   }
-  
+
   return NULL;
 }
 
@@ -660,13 +679,13 @@
    */
 
   int res;
-  
+
   if (nelem == 0) return 0;
-  
+
   res = fread(buffer, (size_t) fs->size, (size_t) nelem, fs->fp);
   /* if failed to read all the data because at end of file */
   if (res != nelem && feof(fs->fp)) {
-    /* nblock is the number of elements in a record. 
+    /* nblock is the number of elements in a record.
        size is always a factor of BLOCKSIZE */
 
     int loffs, nblock=BLOCKSIZE/fs->size;
@@ -714,7 +733,7 @@
   byte *ptr=buffer;
 
   /*
-   * conversions. Although the data may be signed, reverse using unsigned 
+   * conversions. Although the data may be signed, reverse using unsigned
    * variables.
    * Because the native int types may be larger than the types in the file,
    * we start from the end and work backwards to avoid overwriting data
@@ -741,12 +760,12 @@
 	      ((unsigned int)ptr[2] << 8)  |
 	      ((unsigned int)ptr[3]);
   }
-  
+
   /* convert from IEE 754 single precision to native form */
   else if (fs->bitpix == -32) {
     int j, k, expo;
     static float *exps=NULL;
-    
+
     if (exps == NULL) {
       exps = (float *)malloc(256 * sizeof(float));
       if (exps == NULL) FatalError("Insufficient memory for exps store");
@@ -754,7 +773,7 @@
       for (i=151; i < 256; i++) exps[i] = 2.*exps[i-1];
       for (i=149; i >= 0; i--) exps[i] = 0.5*exps[i+1];
     }
-	      
+
     for (i=0; i < n; i++, ptr+=4) {
       k = (int)*ptr;
       j = ((int)ptr[1] << 16) | ((int)ptr[2] << 8) | (int)ptr[3];
@@ -765,13 +784,13 @@
     }
 
   }
-  
+
   /* convert from IEE 754 double precision to native form */
   else if (fs->bitpix == -64) {
     int expo, k, l;
     unsigned int j;
     static double *exps=NULL;
-    
+
     if (exps == NULL) {
       exps = (double *)malloc(2048 * sizeof(double));
       if (exps == NULL) FatalError("Insufficient memory for exps store");
@@ -779,7 +798,7 @@
       for (i=1076; i < 2048; i++) exps[i] = 2.*exps[i-1];
       for (i=1074; i >= 0; i--) exps[i] = 0.5*exps[i+1];
     }
-	      
+
     for (i=0; i < n; i++, ptr+=8) {
       k = (int)*ptr;
       j = ((unsigned int)ptr[1] << 24) | ((unsigned int)ptr[2] << 16) |
@@ -813,23 +832,36 @@
    */
 
   void *voidbuff;
-  int i, n, nrd;
+  int i, n, nrd, bufsize, overflow=0;
 
   /* if the data is byte, then read it directly */
   if (fs->bitpix == 8)
     return ftgdata(fs, cbuff, nelem);
-  
+
   /* allocate a buffer to store the image */
-  if (fs->bitpix == 16)
-    voidbuff = (void *)malloc(nelem * sizeof(short int));
-  else if (fs->bitpix == 32)
-    voidbuff = (void *)malloc(nelem * sizeof(int));
-  else
-    voidbuff = (void *)malloc(nelem * (size_t) fs->size);  /* float, double */
+  if (fs->bitpix == 16) {
+    bufsize = nelem * sizeof(short int);
+    if (bufsize/nelem != (int)sizeof(short int))
+      overflow = 1;
+  } else if (fs->bitpix == 32) {
+    bufsize = nelem * sizeof(int);
+    if (bufsize/nelem != (int)sizeof(short int))
+      overflow = 1;
+  } else {
+    bufsize = nelem * fs->size;  /* float, double */
+    if (bufsize/nelem != fs->size)
+      overflow = 1;
+  }
 
+  if (overflow) {
+    SetISTR(ISTR_WARNING, "FITS image dimensions out of range");
+    return 0;
+  }
+
+  voidbuff = (void *)malloc((size_t) bufsize);
   if (voidbuff == NULL) {
     char emess[60];
-    sprintf(emess, "Insufficient memory for raw image of %d bytes", 
+    sprintf(emess, "Insufficient memory for raw image of %d bytes",
 	    nelem*fs->size);
     FatalError(emess);
   }
@@ -843,28 +875,28 @@
     short int *buffer=voidbuff;
     int max, min, maxmin_t;
     float scale;
-    
+
     min = max = buffer[0];
     for (i=1; i < n; i++, buffer++) maxmin(*buffer, max, min);
     scale = (max == min) ? 0. : 255./(float)(max-min);
-    
+
     /* rescale and convert */
     for (i=0, buffer=voidbuff; i < n; i++)
       cbuff[i] = (byte)(scale*(float)((int)buffer[i]-min));
-    
+
     /* convert long int to byte */
-  } 
+  }
 
   else if (fs->bitpix == 32) {
     int *buffer=voidbuff;
     int max, min, maxmin_t;
     float scale, fmin;
-    
+
     min = max = buffer[0];
     for (i=1; i < n; i++, buffer++) maxmin(*buffer, max, min);
     scale = (max == min) ? 1. : 255./((double)max-(double)min);
     fmin = (float)min;
-    
+
     /* rescale and convert */
     if (scale < 255./2.1e9) /* is max-min too big for an int ? */
       for (i=0, buffer=voidbuff; i < n; i++)
@@ -872,34 +904,34 @@
     else /* use integer subtraction */
       for (i=0, buffer=voidbuff; i < n; i++)
 	cbuff[i] = (byte)(scale*(float)(buffer[i]-min));
-    
-   
-  } 
+
+
+  }
 
   /* convert float to byte */
   else if (fs->bitpix == -32) {
     float *buffer=voidbuff;
     float max, min, maxmin_t, scale;
-    
+
     min = max = buffer[0];
     for (i=1; i < n; i++, buffer++) maxmin(*buffer, max, min);
     scale = (max == min) ? 0. : 255./(max-min);
-    
+
     /* rescale and convert */
     for (i=0, buffer=voidbuff; i < n; i++)
       cbuff[i] = (byte)(scale*(buffer[i]-min));
-    
-  } 
+
+  }
 
   /* convert double to byte */
   else if (fs->bitpix == -64) {
     double *buffer=voidbuff;
     double max, min, maxmin_t, scale;
-    
+
     min = max = buffer[0];
     for (i=1; i < n; i++, buffer++) maxmin(*buffer, max, min);
     scale = (max == min) ? 0. : 255./(max-min);
-    
+
     /* rescale and convert */
     for (i=0, buffer=voidbuff; i < n; i++)
       cbuff[i] = (byte)(scale*(buffer[i]-min));
@@ -923,7 +955,7 @@
   int i;
   int j, v;
   byte *buff1, *buff2;
-  
+
   for (i=0; i < ny/2; i++) {
     buff1 = &buffer[i*nx];
     buff2 = &buffer[(ny-1-i)*nx];
diff -ru xv-3.10a/xvgam.c xv-3.10a-enhancements/xvgam.c
--- xv-3.10a/xvgam.c	1995-01-13 11:51:14.000000000 -0800
+++ xv-3.10a-enhancements/xvgam.c	2007-05-13 14:12:04.000000000 -0700
@@ -1,4 +1,4 @@
-/* 
+/*
  * xvgam.c
  *
  * callable functions:
@@ -87,7 +87,7 @@
 		  GRAF_STATE istate, rstate, gstate, bstate;
 		};
 
-static struct gamstate undo[MAXUNDO], preset[4], defstate; 
+static struct gamstate undo[MAXUNDO], preset[4], defstate;
 static struct gamstate *defLoadState;
 
 static int uptr, uhead, utail;
@@ -99,7 +99,7 @@
 		 int    stval;    /* start of range (ONLY val ifnot range) */
 		 int    enval;    /* end of range */
 		 int    ccwise;   /* 1 if range goes ccwise, 0 if cwise */
-		 char  *str;      /* title string */
+		 const char *str; /* title string */
 		 u_long fg,bg;    /* colors */
 		 int    satval;   /* saturation value on non-range dial */
 		 BUTT   hdbutt[N_HDBUTT];
@@ -122,7 +122,7 @@
 static int    defAutoApply;
 static int    hsvnonlinear = 0;
 
-static void printUTime       PARM((char *));
+static void printUTime       PARM((const char *));
 
 static void computeHSVlinear PARM((void));
 static void changedGam       PARM((void));
@@ -153,8 +153,8 @@
 static void dragHueDial      PARM((void));
 static void dragEditColor    PARM((void));
 
-static void HDCreate         PARM((HDIAL *, Window, int, int, int, int, 
-				   int, int, char *, u_long, u_long));
+static void HDCreate         PARM((HDIAL *, Window, int, int, int, int,
+				   int, int, const char *, u_long, u_long));
 
 static void HDRedraw         PARM((HDIAL *, int));
 static int  HDClick          PARM((HDIAL *, int, int));
@@ -191,10 +191,11 @@
 
 /***************************/
 static void printUTime(str)
-     char *str;
+     const char *str;
 {
 #ifdef TIMING_TEST
-  int i;  struct rusage ru;
+  int i;
+  struct rusage ru;
 
   i = getrusage(RUSAGE_SELF, &ru);
   fprintf(stderr,"%s: utime = %ld.%ld seconds\n",
@@ -206,19 +207,19 @@
 
 /***************************************************/
 void CreateGam(geom, gam, rgam, ggam, bgam, defpreset)
-     char   *geom;
-     double  gam, rgam, ggam, bgam;
-     int     defpreset;
+     const char *geom;
+     double      gam, rgam, ggam, bgam;
+     int         defpreset;
 {
   XSetWindowAttributes xswa;
 
-  gamW = CreateWindow("xv color editor", "XVcedit", geom, 
+  gamW = CreateWindow("xv color editor", "XVcedit", geom,
 		      GAMW, GAMH, infofg,infobg, 0);
   if (!gamW) FatalError("can't create cedit window!");
-  
+
   cmapF = XCreateSimpleWindow(theDisp,gamW, 10,   8,CMAPF_WIDE,CMAPF_HIGH,
 			      1,infofg,infobg);
-  butF  = XCreateSimpleWindow(theDisp,gamW, 10, 336,BUTF_WIDE,BUTF_HIGH, 
+  butF  = XCreateSimpleWindow(theDisp,gamW, 10, 336,BUTF_WIDE,BUTF_HIGH,
 			      1,infofg,infobg);
   modF  = XCreateSimpleWindow(theDisp,gamW, 10, 438,MODF_WIDE,MODF_HIGH,
 			      1,infofg,infobg);
@@ -227,7 +228,7 @@
   rgbF  = XCreateSimpleWindow(theDisp,gamW, 467,  8,RGBF_WIDE,RGBF_HIGH,
 			      1,infofg,infobg);
 
-  if (!cmapF || !butF || !modF || !hsvF || !rgbF) 
+  if (!cmapF || !butF || !modF || !hsvF || !rgbF)
     FatalError("couldn't create frame windows");
 
 #ifdef BACKING_STORE
@@ -251,25 +252,25 @@
   /********** COLORMAP editing doo-wahs ***********/
 
 
-  BTCreate(&gbut[G_BCOLUNDO], cmapF, 5, 165, 66, BUTTH, 
+  BTCreate(&gbut[G_BCOLUNDO], cmapF, 5, 165, 66, BUTTH,
 	   "ColUndo", infofg, infobg, hicol, locol);
-  BTCreate(&gbut[G_BCOLREV], cmapF,  5 + 66 + 1, 165, 67, BUTTH, 
+  BTCreate(&gbut[G_BCOLREV], cmapF,  5 + 66 + 1, 165, 67, BUTTH,
 	   "Revert", infofg, infobg, hicol, locol);
-  BTCreate(&gbut[G_BHSVRGB], cmapF,  5+66+67+2,  165, 66, BUTTH, 
+  BTCreate(&gbut[G_BHSVRGB], cmapF,  5+66+67+2,  165, 66, BUTTH,
 	   "RGB/HSV", infofg, infobg, hicol, locol);
 
-  BTCreate(&gbut[G_BMONO], cmapF,    5, 189, 66, BUTTH, 
+  BTCreate(&gbut[G_BMONO], cmapF,    5, 189, 66, BUTTH,
 	   "Grey", infofg, infobg, hicol, locol);
-  BTCreate(&gbut[G_BRV],   cmapF,    5 + 66 + 1, 189, 67, BUTTH, 
+  BTCreate(&gbut[G_BRV],   cmapF,    5 + 66 + 1, 189, 67, BUTTH,
 	   "RevVid", infofg, infobg, hicol, locol);
-  BTCreate(&gbut[G_BRNDCOL], cmapF,  5 + 66 + 67 + 2, 189, 66, BUTTH, 
+  BTCreate(&gbut[G_BRNDCOL], cmapF,  5 + 66 + 67 + 2, 189, 66, BUTTH,
 	   "Random", infofg, infobg, hicol, locol);
 
-  DCreate(&rhDial, cmapF, 5, 215, 66, 100,   0,360,180, 5, 
+  DCreate(&rhDial, cmapF, 5, 215, 66, 100,   0.0, 360.0, 180.0, 1.0, 5.0,
 	  infofg, infobg, hicol, locol, "Hue", NULL);
-  DCreate(&gsDial, cmapF, 72, 215, 66, 100,  0,360,180, 5, 
+  DCreate(&gsDial, cmapF, 72, 215, 66, 100,  0.0, 360.0, 180.0, 1.0, 5.0,
 	  infofg, infobg, hicol, locol, "Sat.", NULL);
-  DCreate(&bvDial, cmapF, 139, 215, 66, 100,   0,360,180, 5, 
+  DCreate(&bvDial, cmapF, 139, 215, 66, 100, 0.0, 360.0, 180.0, 1.0, 5.0,
 	  infofg, infobg, hicol, locol, "Value", NULL);
 
   rhDial.drawobj = gsDial.drawobj = bvDial.drawobj = dragEditColor;
@@ -291,44 +292,44 @@
 #define BY2 (BY0 + BYSPACE*2)
 #define BY3 (BY0 + BYSPACE*3)
 
-  BTCreate(&gbut[G_BAPPLY],  butF, BX0,BY0, 52,BUTTH,"Apply", 
+  BTCreate(&gbut[G_BAPPLY],  butF, BX0,BY0, 52,BUTTH,"Apply",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_BNOGAM],  butF, BX0,BY1, 52,BUTTH,"NoMod", 
+  BTCreate(&gbut[G_BNOGAM],  butF, BX0,BY1, 52,BUTTH,"NoMod",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_BMAXCONT],butF, BX0,BY2, 52,BUTTH,"Norm",  
+  BTCreate(&gbut[G_BMAXCONT],butF, BX0,BY2, 52,BUTTH,"Norm",
 	   infofg,infobg,hicol,locol);
   BTCreate(&gbut[G_BHISTEQ], butF, BX0,BY3, 52,BUTTH,"HistEq",
 	   infofg,infobg,hicol,locol);
 
   BTCreate(&gbut[G_BUP_BR],butF, BX1,BY0, 52,BUTTH,"Brite",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_BDN_BR],butF, BX1,BY1, 52,BUTTH,"Dim",  
+  BTCreate(&gbut[G_BDN_BR],butF, BX1,BY1, 52,BUTTH,"Dim",
 	   infofg,infobg,hicol,locol);
   BTCreate(&gbut[G_BUP_CN],butF, BX1,BY2, 52,BUTTH,"Sharp",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_BDN_CN],butF, BX1,BY3, 52,BUTTH,"Dull", 
+  BTCreate(&gbut[G_BDN_CN],butF, BX1,BY3, 52,BUTTH,"Dull",
 	   infofg,infobg,hicol,locol);
 
-  BTCreate(&gbut[G_BRESET],butF, BX2,   BY0, 52,BUTTH,"Reset", 
+  BTCreate(&gbut[G_BRESET],butF, BX2,   BY0, 52,BUTTH,"Reset",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_B1],    butF, BX2,   BY1, 25,BUTTH,"1",    
+  BTCreate(&gbut[G_B1],    butF, BX2,   BY1, 25,BUTTH,"1",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_B2],    butF, BX2+26,BY1, 26,BUTTH,"2",    
+  BTCreate(&gbut[G_B2],    butF, BX2+26,BY1, 26,BUTTH,"2",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_B3],    butF, BX2,   BY2, 25,BUTTH,"3",    
+  BTCreate(&gbut[G_B3],    butF, BX2,   BY2, 25,BUTTH,"3",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_B4],    butF, BX2+26,BY2, 26,BUTTH,"4",    
+  BTCreate(&gbut[G_B4],    butF, BX2+26,BY2, 26,BUTTH,"4",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_BSET],  butF, BX2,   BY3, 52,BUTTH,"Set",  
+  BTCreate(&gbut[G_BSET],  butF, BX2,   BY3, 52,BUTTH,"Set",
 	   infofg,infobg,hicol,locol);
 
-  BTCreate(&gbut[G_BUNDO], butF, BX3, BY0, 52,BUTTH,"Undo",   
+  BTCreate(&gbut[G_BUNDO], butF, BX3, BY0, 52,BUTTH,"Undo",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_BREDO], butF, BX3, BY1, 52,BUTTH,"Redo",   
+  BTCreate(&gbut[G_BREDO], butF, BX3, BY1, 52,BUTTH,"Redo",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_BGETRES],butF,BX3, BY2, 52,BUTTH,"CutRes", 
+  BTCreate(&gbut[G_BGETRES],butF,BX3, BY2, 52,BUTTH,"CutRes",
 	   infofg,infobg,hicol,locol);
-  BTCreate(&gbut[G_BCLOSE],butF, BX3, BY3, 52,BUTTH,"Close",  
+  BTCreate(&gbut[G_BCLOSE],butF, BX3, BY3, 52,BUTTH,"Close",
 	   infofg,infobg,hicol,locol);
 
 
@@ -338,11 +339,11 @@
 
   CBCreate(&enabCB, modF,2,2,     "Display with HSV/RGB mods.",
 	   infofg,infobg,hicol,locol);
-  CBCreate(&autoCB, modF,2,2+17,  "Auto-apply HSV/RGB mods.",  
+  CBCreate(&autoCB, modF,2,2+17,  "Auto-apply HSV/RGB mods.",
 	   infofg,infobg,hicol,locol);
   CBCreate(&dragCB, modF,2,2+17*2,"Auto-apply while dragging.",
 	   infofg,infobg,hicol,locol);
-  CBCreate(&resetCB,modF,2,2+17*3,"Auto-reset on new image.",  
+  CBCreate(&resetCB,modF,2,2+17*3,"Auto-reset on new image.",
 	   infofg,infobg,hicol,locol);
 
   enabCB.val = autoCB.val = resetCB.val = dragCB.val = 1;
@@ -359,23 +360,23 @@
 
   srcHD.drawobj = dstHD.drawobj = whtHD.drawobj = dragHueDial;
 
-  DCreate(&satDial, hsvF, 100, 199, 100, 121, -100, 100, 0, 5, 
+  DCreate(&satDial, hsvF, 100, 199, 100, 121, -100.0, 100.0, 0.0, 1.0, 5.0,
 	   infofg, infobg,hicol,locol, "Saturation", "%");
 
-  hueRB = RBCreate(NULL, hsvF,  7, 153, "1", 
+  hueRB = RBCreate(NULL, hsvF,  7, 153, "1",
 		   infofg, infobg,hicol,locol);
-  RBCreate        (hueRB,hsvF, 47, 153, "2", 
+  RBCreate        (hueRB,hsvF, 47, 153, "2",
 		   infofg, infobg,hicol,locol);
-  RBCreate        (hueRB,hsvF, 87, 153, "3", 
+  RBCreate        (hueRB,hsvF, 87, 153, "3",
 		   infofg, infobg,hicol,locol);
-  RBCreate        (hueRB,hsvF,  7, 170, "4", 
+  RBCreate        (hueRB,hsvF,  7, 170, "4",
 		   infofg, infobg,hicol,locol);
-  RBCreate        (hueRB,hsvF, 47, 170, "5", 
+  RBCreate        (hueRB,hsvF, 47, 170, "5",
 		   infofg, infobg,hicol,locol);
-  RBCreate        (hueRB,hsvF, 87, 170, "6", 
+  RBCreate        (hueRB,hsvF, 87, 170, "6",
 		   infofg, infobg,hicol,locol);
 
-  BTCreate(&hueclrB, hsvF, 127, 158, 70, BUTTH, "Reset", 
+  BTCreate(&hueclrB, hsvF, 127, 158, 70, BUTTH, "Reset",
 	   infofg, infobg,hicol,locol);
 
   initHmap();
@@ -394,13 +395,13 @@
 
   InitGraf(&gGraf);
   CreateGraf(&gGraf, rgbF, 10, 179, infofg, infobg, "Green");
-  
+
   InitGraf(&bGraf);
   CreateGraf(&bGraf, rgbF, 10, 338, infofg, infobg, "Blue");
 
   satDial.drawobj = dragGamma;
   intGraf.drawobj = rGraf.drawobj = gGraf.drawobj = bGraf.drawobj = dragGamma;
-  
+
   SetHSVmode();
 
   ctrls2gamstate(&defstate);
@@ -415,14 +416,14 @@
   Str2Graf(&preset[1].rstate,"L 4 : 0,0 : 127,0 : 128,255 : 255,255");
   Str2Graf(&preset[1].gstate,"L 4 : 0,0 : 127,0 : 128,255 : 255,255");
   Str2Graf(&preset[1].bstate,"L 4 : 0,0 : 127,0 : 128,255 : 255,255");
-  
+
 
   /* set up preset2 as a 'temperature' pseudo-color preset */
   ctrls2gamstate(&preset[2]);
   Str2Graf(&preset[2].rstate,"S 4 : 0,0 : 105,0 : 155,140 : 255,255");
   Str2Graf(&preset[2].gstate,"S 5 : 0,0 : 57,135 : 127,255 : 198,135 : 255,0");
   Str2Graf(&preset[2].bstate,"S 4 : 0,255 : 100,140 : 150,0 : 255,0");
-  
+
 
   /* set up preset3 as a 'map' pseudo-color preset */
   ctrls2gamstate(&preset[3]);
@@ -480,7 +481,7 @@
 
   computeHSVlinear();
 }
-  
+
 
 /***************************************************/
 int GamCheckEvent(xev)
@@ -492,14 +493,14 @@
   int rv;
 
   rv = 1;
-  
+
   if (xev->type == Expose) {
     int x,y,w,h;
     XExposeEvent *e = (XExposeEvent *) xev;
     x = e->x;  y = e->y;  w = e->width;  h = e->height;
 
     /* throw away excess redraws for 'dumb' windows */
-    if (e->count > 0 && 
+    if (e->count > 0 &&
 	(e->window == satDial.win || e->window == rhDial.win ||
 	 e->window == gsDial.win  || e->window == bvDial.win ||
 	 e->window == cmapF       || e->window == modF       ||
@@ -600,7 +601,7 @@
 
 
       else if (e->window == hsvF) {
-	if (HDClick(&srcHD, x,y) || HDClick(&dstHD, x,y)) { 
+	if (HDClick(&srcHD, x,y) || HDClick(&dstHD, x,y)) {
 	  dials2hmap();
 	  build_hremap();
 	  changedGam();
@@ -654,7 +655,7 @@
 	       e->window == gsDial.win ||
 	       e->window == bvDial.win) {
 
-	if ((e->window == rhDial.win && DTrack(&rhDial, x,y)) || 
+	if ((e->window == rhDial.win && DTrack(&rhDial, x,y)) ||
 	    (e->window == gsDial.win && DTrack(&gsDial, x,y)) ||
 	    (e->window == bvDial.win && DTrack(&bvDial, x,y))) {
 	  saveCMap(&prevcmap);
@@ -683,7 +684,7 @@
     XKeyEvent *e = (XKeyEvent *) xev;
     char buf[128];  KeySym ks;
     int stlen;
-	
+
     stlen = XLookupString(e,buf,128,&ks,(XComposeStatus *) NULL);
     buf[stlen] = '\0';
 
@@ -722,7 +723,7 @@
 
   if (whtHD.enabCB.val && whtHD.satval) hsvnonlinear++;
 
-  if (satDial.val != 0) hsvnonlinear++;
+  if (satDial.val != 0.0) hsvnonlinear++;
 
   /* check intensity graf */
   for (i=0; i<256 && intGraf.func[i]==i; i++);
@@ -792,7 +793,7 @@
 int x,y;
 {
   XPoint pts[8];
-  
+
   pts[0].x = x+10;     pts[0].y = y;
   pts[1].x = x-4;      pts[1].y = y-100;
   pts[2].x = x-4;      pts[2].y = y-40;
@@ -873,11 +874,11 @@
   XSetForeground(theDisp, theGC, infofg);
 
   if (picType != PIC8) {
-    CenterString(cmapF, CMAPX + CMAPW/2, CMAPY + CMAPH/2, 
+    CenterString(cmapF, CMAPX + CMAPW/2, CMAPY + CMAPH/2,
 		 "No colormap in 24-bit mode.");
     return;
   }
-      
+
 
 
   for (i=0; i<numcols; i++) {
@@ -941,14 +942,14 @@
     if (bp->win == butF && PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
   }
 
-  /* if 'Set' is lit, and we didn't click 'set' or 'Reset' or '1'..'4', 
+  /* if 'Set' is lit, and we didn't click 'set' or 'Reset' or '1'..'4',
      turn it off */
   if (i!=G_BSET && i!=G_B1 && i!=G_B2 && i!=G_B3 && i!=G_B4 && i!=G_BRESET
       && gbut[G_BSET].lit) {
-    gbut[G_BSET].lit = 0;  
+    gbut[G_BSET].lit = 0;
     BTRedraw(&gbut[G_BSET]);
   }
-  
+
 
   if (i<G_NBUTTS) {  /* found one */
     if (BTTrack(bp)) doCmd(i);
@@ -1003,7 +1004,7 @@
       } /* if i<numcols */
     } /* if but==1 */
 
-    
+
     else if (but==2) {   /* color smooth */
       int cellnum, delc, col1, j, delr, delg, delb;
 
@@ -1025,9 +1026,9 @@
 	    gcmap[col1 + i] = gcmap[col1] + (delg * i) / delc;
 	    bcmap[col1 + i] = bcmap[col1] + (delb * i) / delc;
 
-	    if (cellgroup[col1 + i]) { 
+	    if (cellgroup[col1 + i]) {
 	      /* propogate new color to all members of this group */
-	      for (j=0; j<numcols; j++) 
+	      for (j=0; j<numcols; j++)
 		if (cellgroup[j] == cellgroup[col1 + i]) {
 		  rcmap[j] = rcmap[col1 + i];
 		  gcmap[j] = gcmap[col1 + i];
@@ -1043,7 +1044,7 @@
 	  }
 
 	  if (i<numcols) {  /* something changed */
-	    xvbcopy((char *) &tmpcmap, (char *) &prevcmap, 
+	    xvbcopy((char *) &tmpcmap, (char *) &prevcmap,
 		    sizeof(struct cmapstate));
 	    BTSetActive(&gbut[G_BCOLUNDO],1);
 	    applyGamma(1);
@@ -1067,7 +1068,7 @@
 
 	lastcell = curcell;
 
-	j = XGrabPointer(theDisp, cmapF, False, 0, GrabModeAsync, 
+	j = XGrabPointer(theDisp, cmapF, False, 0, GrabModeAsync,
 			 GrabModeAsync, None, None, (Time) CurrentTime);
 	while (1) {
 	  Window       rW,cW;
@@ -1076,7 +1077,7 @@
 
 	  if (XQueryPointer(theDisp,cmapF,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
 	    /* if button3 and shift released */
-	    if (!(mask & (Button3Mask | ShiftMask))) break;  
+	    if (!(mask & (Button3Mask | ShiftMask))) break;
 
 	    /* if user lets go of B3, reset addonly/delonly flag & lastcell */
 	    if (!(mask & Button3Mask) && (mask & ShiftMask)) {
@@ -1112,7 +1113,7 @@
 
 	if (recolor) {
 	  /* colors changed.  save to color undo area */
-	  xvbcopy((char *) &tmpcmap, (char *) &prevcmap, 
+	  xvbcopy((char *) &tmpcmap, (char *) &prevcmap,
 		  sizeof(struct cmapstate));
 	  BTSetActive(&gbut[G_BCOLUNDO],1);
 	  applyGamma(1);   /* have to regen entire image when groupings chg */
@@ -1146,12 +1147,12 @@
   /* cases:  curgroup>0, clicked on something in same group
                          remove target from group
 	     curgroup>0, clicked on something in different group
-	                 merge groups.  (target group gets 
+	                 merge groups.  (target group gets
 			 set equal to current values)
              curgroup>0, clicked on something in no group
 	                 add target to curgroup
              curgroup=0, clicked on something in a group
-	                 add editColor to target group, 
+	                 add editColor to target group,
 			 set curgroup = target group
 			 target group gets current values
 	     curgroup=0, clicked on something in no group
@@ -1185,7 +1186,7 @@
       }
     }
 
-    else if ((mode!=DELONLY) && cellgroup[cnum] != curgroup && 
+    else if ((mode!=DELONLY) && cellgroup[cnum] != curgroup &&
 	     cellgroup[cnum]>0) {
       /* merge clicked-on group into curgroup */
       mode = ADDONLY;
@@ -1196,11 +1197,11 @@
 	  selectCell(i,1);
 	  rcmap[i] = rcmap[editColor];
 	  gcmap[i] = gcmap[editColor];
-	  bcmap[i] = bcmap[editColor]; 
+	  bcmap[i] = bcmap[editColor];
 	}
       }
     }
-	    
+
     else if ((mode!=DELONLY) && cellgroup[cnum] == 0) {
       /* merge clicked-on cell into curgroup */
       mode = ADDONLY;
@@ -1209,7 +1210,7 @@
       selectCell(cnum,1);
       rcmap[cnum] = rcmap[editColor];
       gcmap[cnum] = gcmap[editColor];
-      bcmap[cnum] = bcmap[editColor]; 
+      bcmap[cnum] = bcmap[editColor];
     }
   }
 
@@ -1224,14 +1225,14 @@
 	  selectCell(i,1);
 	  rcmap[i] = rcmap[editColor];
 	  gcmap[i] = gcmap[editColor];
-	  bcmap[i] = bcmap[editColor]; 
+	  bcmap[i] = bcmap[editColor];
 	}
       }
       curgroup = cellgroup[cnum];
       cellgroup[editColor] = curgroup;
     }
-	    
-    else if ((mode!=DELONLY) && (cellgroup[cnum] == 0) 
+
+    else if ((mode!=DELONLY) && (cellgroup[cnum] == 0)
 	     && (cnum != editColor)) {
       /* create new group for these two cells (cnum and editColor) */
       mode = ADDONLY;
@@ -1247,14 +1248,14 @@
   }
 
   return rv;
-}	    
-	    
+}
+
 
 /*********************/
 void ChangeEC(num)
 int num;
 {
-  /* given a color # that is to become the new editColor, do all 
+  /* given a color # that is to become the new editColor, do all
      highlighting/unhighlighting, copy editColor's rgb values to
      the rgb/hsv dials */
 
@@ -1291,18 +1292,18 @@
     rgb2hsv(rcmap[editColor], gcmap[editColor], bcmap[editColor], &h, &s, &v);
     if (h<0) h = 0;
 
-    DSetVal(&rhDial, (int) h);
-    DSetVal(&gsDial, (int) (s*100));
-    DSetVal(&bvDial, (int) (v*100));
+    DSetVal(&rhDial, h);
+    DSetVal(&gsDial, s*100);
+    DSetVal(&bvDial, v*100);
   }
   else {
-    DSetVal(&rhDial, rcmap[editColor]);
-    DSetVal(&gsDial, gcmap[editColor]);
-    DSetVal(&bvDial, bcmap[editColor]);
+    DSetVal(&rhDial, (double)rcmap[editColor]);
+    DSetVal(&gsDial, (double)gcmap[editColor]);
+    DSetVal(&bvDial, (double)bcmap[editColor]);
   }
 }
-  
-    
+
+
 /*********************/
 void ApplyECctrls()
 {
@@ -1310,16 +1311,15 @@
 
   if (hsvmode) {
     int rv, gv, bv;
-    hsv2rgb((double) rhDial.val, ((double) gsDial.val) / 100.0, 
-	    ((double) bvDial.val) / 100.0, &rv, &gv, &bv);
+    hsv2rgb(rhDial.val, gsDial.val / 100.0, bvDial.val / 100.0, &rv, &gv, &bv);
     rcmap[editColor] = rv;
     gcmap[editColor] = gv;
     bcmap[editColor] = bv;
   }
   else {
-    rcmap[editColor] = rhDial.val;
-    gcmap[editColor] = gsDial.val;
-    bcmap[editColor] = bvDial.val;
+    rcmap[editColor] = (int)rhDial.val;
+    gcmap[editColor] = (int)gsDial.val;
+    bcmap[editColor] = (int)bvDial.val;
   }
 }
 
@@ -1330,7 +1330,7 @@
 {
   /* this function generates the Floyd-Steinberg gamma curve (fsgamcr)
 
-     This function generates a 4 point spline curve to be used as a 
+     This function generates a 4 point spline curve to be used as a
      non-linear grey 'colormap'.  Two of the points are nailed down at 0,0
      and 255,255, and can't be changed.  You specify the other two.  If
      you specify points on the line (0,0 - 255,255), you'll get the normal
@@ -1345,7 +1345,7 @@
   double yf[4];
 
   InitSpline(x, y, 4, yf);
-  
+
   for (i=0; i<256; i++) {
     j = (int) EvalSpline(x, y, yf, 4, (double) i);
     if (j<0) j=0;
@@ -1364,14 +1364,14 @@
 
   switch (cmd) {
 
-  case G_BAPPLY: 
+  case G_BAPPLY:
     if (enabCB.val != 1) { enabCB.val = 1;  CBRedraw(&enabCB); }
-    applyGamma(0);           
+    applyGamma(0);
     break;
 
   case G_BNOGAM:
     if (enabCB.val != 0) { enabCB.val = 0;  CBRedraw(&enabCB); }
-    applyGamma(0);           
+    applyGamma(0);
     break;
 
   case G_BUNDO:  gamUndo();  break;
@@ -1383,7 +1383,7 @@
 
 
 
-  case G_BDN_BR: 
+  case G_BDN_BR:
   case G_BUP_BR: GetGrafState(&intGraf, &gs);
                  for (i=0; i < gs.nhands; i++) {
 		   if (cmd==G_BUP_BR) gs.hands[i].y += 10;
@@ -1434,7 +1434,7 @@
 	       else if (cmd==G_B3)     ptr = &preset[2];
 	       else if (cmd==G_B4)     ptr = &preset[3];
 	       else if (cmd==G_BRESET) ptr = &defstate;
-                
+
 	       if (gbut[G_BSET].lit) {
 		 ctrls2gamstate(ptr);
 		 gbut[G_BSET].lit = 0;
@@ -1454,7 +1454,7 @@
     break;
 
 
-  case G_BCOLREV: 
+  case G_BCOLREV:
     {
       struct cmapstate tmp1cmap;
       int gchg;
@@ -1463,9 +1463,9 @@
       gchg = (i!=numcols);
 
       saveCMap(&tmpcmap);         /* buffer current cmapstate */
-    
+
       for (i=0; i<numcols; i++) { /* do reversion */
-	rcmap[i] = rorg[i];  
+	rcmap[i] = rorg[i];
 	gcmap[i] = gorg[i];
 	bcmap[i] = borg[i];
 	cellgroup[i] = 0;
@@ -1473,12 +1473,12 @@
       curgroup = maxgroup = 0;
 
       saveCMap(&tmp1cmap);        /* buffer current cmapstate */
-    
+
       /* prevent multiple 'Undo All's from filling Undo buffer */
-      if (xvbcmp((char *) &tmpcmap, (char *) &tmp1cmap, 
+      if (xvbcmp((char *) &tmpcmap, (char *) &tmp1cmap,
 		 sizeof(struct cmapstate))) {
 	/* the reversion changed the cmapstate */
-	xvbcopy((char *) &tmpcmap, (char *) &prevcmap, 
+	xvbcopy((char *) &tmpcmap, (char *) &prevcmap,
 		sizeof(struct cmapstate));
 	BTSetActive(&gbut[G_BCOLUNDO],1);
 
@@ -1496,7 +1496,7 @@
     BTSetActive(&gbut[G_BCOLUNDO],1);
     rndCols();
     break;
-  
+
   case G_BRV:
     saveCMap(&prevcmap);
     BTSetActive(&gbut[G_BCOLUNDO],1);
@@ -1523,7 +1523,7 @@
     ChangeEC(editColor);
     applyGamma(1);
     break;
-  
+
 
   case G_BMONO:
     saveCMap(&prevcmap);
@@ -1534,7 +1534,7 @@
     ChangeEC(editColor);
     applyGamma(1);
     break;
-  
+
 
   case G_BCOLUNDO:
     for (i=0; i<numcols && cellgroup[i]==prevcmap.cellgroup[i]; i++);
@@ -1560,10 +1560,10 @@
     rhDial.title = "Red";
     gsDial.title = "Green";
     bvDial.title = "Blue";
-		   
-    DSetRange(&rhDial, 0, 255, rcmap[editColor], 16);
-    DSetRange(&gsDial, 0, 255, gcmap[editColor], 16);
-    DSetRange(&bvDial, 0, 255, bcmap[editColor], 16);
+
+    DSetRange(&rhDial, 0.0, 255.0, (double)rcmap[editColor], 1.0, 16.0);
+    DSetRange(&gsDial, 0.0, 255.0, (double)gcmap[editColor], 1.0, 16.0);
+    DSetRange(&bvDial, 0.0, 255.0, (double)bcmap[editColor], 1.0, 16.0);
 
     XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
     XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
@@ -1581,9 +1581,9 @@
 	    &h, &s, &v);
 
     if (h<0.0) h = 0.0;
-    DSetRange(&rhDial, 0, 360, (int) h, 5);
-    DSetRange(&gsDial, 0, 100, (int) (s*100), 5);
-    DSetRange(&bvDial, 0, 100, (int) (v*100), 5);
+    DSetRange(&rhDial, 0.0, 360.0,     h, 1.0, 5.0);
+    DSetRange(&gsDial, 0.0, 100.0, s*100, 1.0, 5.0);
+    DSetRange(&bvDial, 0.0, 100.0, v*100, 1.0, 5.0);
 
     XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
     XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
@@ -1615,12 +1615,12 @@
     GammifyColors();
 
     /* if current 'desired' colormap hasn't changed, don't DO anything */
-    if (!xvbcmp((char *) rMap, (char *) oldr, (size_t) numcols) && 
-	!xvbcmp((char *) gMap, (char *) oldg, (size_t) numcols) && 
+    if (!xvbcmp((char *) rMap, (char *) oldr, (size_t) numcols) &&
+	!xvbcmp((char *) gMap, (char *) oldg, (size_t) numcols) &&
 	!xvbcmp((char *) bMap, (char *) oldb, (size_t) numcols)) return;
 
     /* special case: if using R/W color, just modify the colors and leave */
-    if (allocMode==AM_READWRITE && rwthistime && 
+    if (allocMode==AM_READWRITE && rwthistime &&
 	(!cmapchange || nfcols==numcols)) {
       XColor ctab[256];
 
@@ -1647,10 +1647,10 @@
 	gdisp[i] = gMap[rwpc2pc[i]];
 	bdisp[i] = bMap[rwpc2pc[i]];
       }
-      
+
       return;
     }
-    
+
     FreeColors();
 
     {
@@ -1663,10 +1663,10 @@
     AllocColors();
 
 
-    if (epicMode != EM_RAW) {  
+    if (epicMode != EM_RAW) {
       /* regen image, as we'll probably want to dither differently, given
 	 new colors and such */
-      
+
       GenerateEpic(eWIDE, eHIGH);
     }
   }
@@ -1701,7 +1701,7 @@
     for (i=255; i>0 && !hist[i]; i--);
     *rmaxv = i;
   }
-  
+
   else {  /* PIC24 */
     int v,minv,maxv;
 
@@ -1724,7 +1724,7 @@
 	hist[v]++;
       }
     }
-    
+
     *rminv = minv;  *rmaxv = maxv;
   }
 
@@ -1764,13 +1764,13 @@
   int i, histeq[256], minv, maxv;
 
   calcHistEQ(histeq, &minv, &maxv);  /* ignore minv,maxv */
-    
-  for (i=0; i<256; i++) 
+
+  for (i=0; i<256; i++)
     intGraf.func[i] = histeq[i];
-    
+
   for (i=0; i< intGraf.nhands; i++)
     intGraf.hands[i].y = intGraf.func[intGraf.hands[i].x];
-    
+
   intGraf.entergamma = 0;
 
   if (gamUp) {
@@ -1797,7 +1797,7 @@
       if (v>maxv) maxv = v;
     }
   }
-  else { 
+  else {
     int histeq[256];
     calcHistEQ(histeq, &minv, &maxv);  /* ignore histeq */
   }
@@ -1833,11 +1833,11 @@
     for (i=0; i<numcols; i++) Gammify1(i);
   }
   else {
-    for (i=0; i<numcols; i++) { 
+    for (i=0; i<numcols; i++) {
       rMap[i] = rcmap[i];
       gMap[i] = gcmap[i];
       bMap[i] = bcmap[i];
-      if (!ncols) 
+      if (!ncols)
 	cols[i] = (((int)rMap[i]) + ((int)gMap[i]) + ((int)bMap[i]) >= 128*3)
 	  ? white : black;
     }
@@ -1875,7 +1875,7 @@
     if (DEBUG>1) fprintf(stderr," (v=%f)",v);
 
     if (h>=0) {
-      hi = (int) h;  
+      hi = (int) h;
       if (hi<0)    hi += 360;
       if (hi>=360) hi -= 360;
       h = (double) hremap[hi];
@@ -1884,14 +1884,14 @@
       if (whtHD.enabCB.val) {
 	h = (double) whtHD.stval;
 	s = (double) whtHD.satval / 100.0;
-	
+
 	/* special case:  if stval = satval = 0, set hue = -1 */
 	if (whtHD.stval == 0 && whtHD.satval == 0) h = -1.0;
       }
     }
 
     /* apply satDial value to s */
-    s = s + ((double) satDial.val) / 100.0;
+    s = s + satDial.val / 100.0;
     if (s<0.0) s = 0.0;
     if (s>1.0) s = 1.0;
 
@@ -1899,13 +1899,13 @@
     if (DEBUG>1) fprintf(stderr," -> %d,%d,%d",rv,gv,bv);
   }
 
-  rMap[col] = rGraf.func[rv];  
+  rMap[col] = rGraf.func[rv];
   gMap[col] = gGraf.func[gv];
   bMap[col] = bGraf.func[bv];
 
-  if (!ncols) 
-    cols[col] = 
-      (((int)rMap[col]) + ((int)gMap[col]) + ((int)bMap[col]) >= 128*3) 
+  if (!ncols)
+    cols[col] =
+      (((int)rMap[col]) + ((int)gMap[col]) + ((int)bMap[col]) >= 128*3)
 	? white : black;
 
   if (DEBUG>1) fprintf(stderr," -> %d,%d,%d\n",rMap[col],gMap[col],bMap[col]);
@@ -2001,13 +2001,13 @@
 {
   xvbcopy((char *) hmap, (char *) gs->hmap, sizeof(hmap));
 
-  gs->wht_stval = whtHD.stval;  
-  gs->wht_satval = whtHD.satval;  
+  gs->wht_stval = whtHD.stval;
+  gs->wht_satval = whtHD.satval;
   gs->wht_enab = whtHD.enabCB.val;
 
   gs->hueRBnum = RBWhich(hueRB);
 
-  gs->satval = satDial.val;
+  gs->satval = (int)satDial.val;
   GetGrafState(&intGraf,&gs->istate);
   GetGrafState(&rGraf,  &gs->rstate);
   GetGrafState(&gGraf,  &gs->gstate);
@@ -2042,7 +2042,7 @@
       srcHD.ccwise = hm->src_ccw;
       HDRedraw(&srcHD, HD_ALL | HD_CLEAR);
     }
-    
+
     if (dstHD.stval  != hm->dst_st ||
 	dstHD.enval  != hm->dst_en ||
 	dstHD.ccwise != hm->dst_ccw) {
@@ -2051,7 +2051,7 @@
       dstHD.ccwise = hm->dst_ccw;
       HDRedraw(&dstHD, HD_ALL | HD_CLEAR);
     }
-  }    
+  }
 
 
   if (whtHD.stval != gs->wht_stval || whtHD.satval != gs->wht_satval ||
@@ -2063,9 +2063,9 @@
     HDRedraw(&whtHD, HD_ALL | HD_CLEAR);
     changed++;
   }
-    
-  if (gs->satval != satDial.val) {
-    DSetVal(&satDial,gs->satval);
+
+  if (gs->satval != (int)satDial.val) {
+    DSetVal(&satDial,(double)gs->satval);
     changed++;
   }
 
@@ -2203,7 +2203,7 @@
 }
 
 
-    
+
 
 /*********************/
 static void parseResources()
@@ -2226,7 +2226,7 @@
     if (i) { sprintf(gname,"preset%d",i);  gsp = &preset[i-1]; }
       else { sprintf(gname,"default");     gsp = &defstate; }
 
-    xvbcopy((char *) gsp, (char *) &gs, 
+    xvbcopy((char *) gsp, (char *) &gs,
 	    sizeof(struct gamstate));   /* load 'gs' with defaults */
 
     for (j=0; j<6; j++) {                       /* xv.*.huemap resources */
@@ -2239,7 +2239,7 @@
 	lower_str(def_str);
 	if (sscanf(def_str,"%d %d %s %d %d %s",
 		   &fst, &fen, fcw, &tst, &ten, tcw) != 6) {
-	  fprintf(stderr,"%s: unable to parse resource 'xv.%s: %s'\n", 
+	  fprintf(stderr,"%s: unable to parse resource 'xv.%s: %s'\n",
 		  cmd, tmp, def_str);
 	}
 	else {
@@ -2260,7 +2260,7 @@
       int wst, wsat, enab;
       if (DEBUG) fprintf(stderr,"parseResource 'xv.%s: %s'\n",tmp, def_str);
       if (sscanf(def_str,"%d %d %d", &wst, &wsat, &enab) != 3) {
-	fprintf(stderr,"%s: unable to parse resource 'xv.%s: %s'\n", 
+	fprintf(stderr,"%s: unable to parse resource 'xv.%s: %s'\n",
 		cmd, tmp, def_str);
       }
       else {                                    /* successful parse */
@@ -2276,7 +2276,7 @@
       int sat;
       if (DEBUG) fprintf(stderr,"parseResource 'xv.%s: %s'\n",tmp, def_str);
       if (sscanf(def_str,"%d", &sat) != 1) {
-	fprintf(stderr,"%s: unable to parse resource 'xv.%s: %s'\n", 
+	fprintf(stderr,"%s: unable to parse resource 'xv.%s: %s'\n",
 		cmd, tmp, def_str);
       }
       else {                                    /* successful parse */
@@ -2304,7 +2304,7 @@
 	}
       }
     }
-    
+
     /* copy (potentially) modified gs back to default/preset */
     xvbcopy((char *) &gs, (char *) gsp, sizeof(struct gamstate));
   }
@@ -2324,16 +2324,16 @@
   /* write out current state */
   ctrls2gamstate(&gstate);
   strcpy(gname, "xv.default");
-  
+
   /* write out huemap resources */
   for (i=0; i<6; i++) {
     if (1 || gstate.hmap[i].src_st  != gstate.hmap[i].dst_st ||
 	gstate.hmap[i].src_en  != gstate.hmap[i].dst_en ||
 	gstate.hmap[i].src_ccw != gstate.hmap[i].dst_ccw) {
-      sprintf(tmp, "%s.huemap%d: %3d %3d %3s %3d %3d %3s\n", gname, i+1, 
-	      gstate.hmap[i].src_st, gstate.hmap[i].src_en, 
+      sprintf(tmp, "%s.huemap%d: %3d %3d %3s %3d %3d %3s\n", gname, i+1,
+	      gstate.hmap[i].src_st, gstate.hmap[i].src_en,
 	      gstate.hmap[i].src_ccw ? "CCW" : "CW",
-	      gstate.hmap[i].dst_st, gstate.hmap[i].dst_en, 
+	      gstate.hmap[i].dst_st, gstate.hmap[i].dst_en,
 	      gstate.hmap[i].dst_ccw ? "CCW" : "CW");
       strcat(rsrc, tmp);
     }
@@ -2341,7 +2341,7 @@
 
   /* write out whtmap resource */
   if (1 || gstate.wht_stval || gstate.wht_satval || gstate.wht_enab != 1) {
-    sprintf(tmp, "%s.whtmap:  %d %d %d\n", gname, gstate.wht_stval, 
+    sprintf(tmp, "%s.whtmap:  %d %d %d\n", gname, gstate.wht_stval,
 	    gstate.wht_satval, gstate.wht_enab);
     strcat(rsrc, tmp);
   }
@@ -2372,7 +2372,7 @@
 
   NewCutBuffer(rsrc);
 }
-    
+
 
 /*****************************/
 static void dragGamma ()
@@ -2381,14 +2381,14 @@
      while gamma ctrls are being dragged
      applies change to image if dragCB.val is set
      does NOT call saveGamState() (as changedGam does) */
-  
+
   if (dragCB.val && dragCB.active) {
     hsvnonlinear = 1;   /* force HSV calculations during drag */
     applyGamma(0);
   }
 }
 
-  
+
 /*****************************/
 static void dragHueDial()
 {
@@ -2396,7 +2396,7 @@
      while hue gamma ctrls are being dragged
      applies change to image if dragCB.val is set
      does NOT call saveGamState() (as changedGam does) */
-  
+
   if (dragCB.val && dragCB.active) {
     dials2hmap();
     build_hremap();
@@ -2413,14 +2413,14 @@
      while color editor ctrls are being dragged
      applies change to image if dragCB.val is set
      does NOT call saveCMap(&prevcmap); BTSetActive(&gbut[G_BCOLUNDO],1); */
-  
+
   if (dragCB.val && dragCB.active) ApplyEditColor(0);
 }
 
 
-    
-    
-        
+
+
+
 
 /**********************************************/
 /*************  HUE wheel functions ***********/
@@ -2435,11 +2435,11 @@
 
 /**************************************************/
 static void HDCreate(hd, win, x, y, r, st, en, ccwise, str, fg, bg)
-HDIAL *hd;
-Window win;
-int x,y,r,st,en,ccwise;
-char *str;
-u_long fg,bg;
+     HDIAL      *hd;
+     Window      win;
+     int         x, y, r, st, en, ccwise;
+     const char *str;
+     u_long      fg, bg;
 {
   int i;
 
@@ -2470,7 +2470,7 @@
     hdbpix2[HDB_ROTR]  = hdbpix1[HDB_ROTR];
   }
 
-    
+
 #define BCOLS fg,bg,hicol,locol
 
   if (hd->range) {
@@ -2520,13 +2520,13 @@
   }
 
   if (flags & HD_FRAME) {
-    static char *colstr = "RYGCBM";
+    static const char *colstr = "RYGCBM";
     char tstr[2];
 
     XSetForeground(theDisp, theGC, hd->fg);
     XDrawArc(theDisp, hd->win, theGC, hd->x - HD_RADIUS, hd->y - HD_RADIUS,
 	     HD_RADIUS*2, HD_RADIUS*2, 0, 360*64);
-    
+
     for (i=0; i<6; i++) {
       int kldg;
 
@@ -2553,8 +2553,8 @@
       a = hdg2xdg(hd->stval) * DEG2RAD;
       pol2xy(hd->x, hd->y, a, HD_RADIUS - 4, &x, &y);
       XDrawLine(theDisp, hd->win, theGC, hd->x, hd->y, x,y);
-      
-      if (flags & HD_CLHNDS) 
+
+      if (flags & HD_CLHNDS)
 	XFillRectangle(theDisp, hd->win, theGC, x-2,y-2, 5,5);
       else {
 	XSetForeground(theDisp, theGC, hd->bg);
@@ -2567,8 +2567,8 @@
       a = hdg2xdg(hd->enval) * DEG2RAD;
       pol2xy(hd->x, hd->y, a, HD_RADIUS - 4, &x, &y);
       XDrawLine(theDisp, hd->win, theGC, hd->x, hd->y, x,y);
-    
-      if (flags & HD_CLHNDS) 
+
+      if (flags & HD_CLHNDS)
 	XFillRectangle(theDisp, hd->win, theGC, x-2,y-2, 5,5);
       else {
 	XSetForeground(theDisp, theGC, hd->bg);
@@ -2587,7 +2587,7 @@
       r = ((HD_RADIUS - 4) * hd->satval) / 100;
       pol2xy(hd->x, hd->y, a, r, &x, &y);
 
-      if (flags & HD_CLHNDS) 
+      if (flags & HD_CLHNDS)
 	XFillRectangle(theDisp, hd->win, theGC, x-2,y-2, 5,5);
       else {
 	XFillRectangle(theDisp, hd->win, theGC, hd->x-1, hd->y-1, 3,3);
@@ -2600,7 +2600,7 @@
       }
     }
   }
-    
+
 
 
 
@@ -2653,13 +2653,13 @@
     XSetBackground(theDisp, theGC, hd->bg);
 
     if (hd->range) {
-      sprintf(vstr,"%3d\007,%3d\007 %s", hd->stval, hd->enval, 
+      sprintf(vstr,"%3d\007,%3d\007 %s", hd->stval, hd->enval,
 	      hd->ccwise ? "CCW" : " CW");
     }
     else {
       sprintf(vstr,"%3d\007 %3d%%", hd->stval, hd->satval);
     }
-      
+
     XDrawImageString(theDisp, hd->win, theGC,
 		     hd->x - XTextWidth(monofinfo, vstr, (int) strlen(vstr))/2,
 		     hd->y + HD_RADIUS + 24, vstr, (int) strlen(vstr));
@@ -2669,7 +2669,7 @@
 
   if (flags & HD_TITLE) {
     XSetForeground(theDisp, theGC, hd->fg);
-    ULineString(hd->win, hd->x - HD_RADIUS - 15, hd->y - HD_RADIUS - 4, 
+    ULineString(hd->win, hd->x - HD_RADIUS - 15, hd->y - HD_RADIUS - 4,
 		hd->str);
   }
 
@@ -2694,7 +2694,7 @@
 }
 
 
-    
+
 /**************************************************/
 static int HDClick(hd,mx,my)
 HDIAL *hd;
@@ -2716,7 +2716,7 @@
   if (!hd->range && !hd->enabCB.val) return 0;    /* disabled */
 
 
-  if ( ((mx - hd->x) * (mx - hd->x)  +  (my - hd->y) * (my - hd->y)) 
+  if ( ((mx - hd->x) * (mx - hd->x)  +  (my - hd->y) * (my - hd->y))
       < (HD_RADIUS * HD_RADIUS)) {
     return HDTrack(hd,mx,my);
   }
@@ -2816,14 +2816,14 @@
 	      hd->satval--;  if (hd->satval<0) hd->satval = 0;
 	      HDRedraw(hd, HD_HANDS | HD_VALS);
 	    }
-	      
+
 	    else if (bnum == HDB_SAT && hd->satval<100) {
 	      HDRedraw(hd, HD_CLHNDS);
 	      hd->satval++;  if (hd->satval>100) hd->satval = 100;
 	      HDRedraw(hd, HD_HANDS | HD_VALS);
 	    }
 	  }
-	      
+
 	  break;
 	}
 
@@ -2836,7 +2836,7 @@
   }
 
   if (bp->lit) {  bp->lit = 0;  BTRedraw(bp); }
-    
+
   return 1;
 }
 
@@ -2872,7 +2872,7 @@
 
       dx = x - hd->x;  dy = y - hd->y;
       dist = sqrt(dx*dx + dy*dy);
-      
+
       newsat = (int) (dist / ((double) (HD_RADIUS - 4)) * 100);
       RANGE(newsat,0,100);
 
@@ -2899,7 +2899,7 @@
     a = hdg2xdg(hd->enval) * DEG2RAD;
     pol2xy(hd->x, hd->y, a, HD_RADIUS-4, &x,&y);
     if (PTINRECT(mx,my,x-3,y-3,7,7)) handle = 2;
-    
+
 
 
     if (!handle) {  /* not in either, rotate both */
@@ -2939,7 +2939,7 @@
       }
       rv = (origj != j);
     }
-	    
+
 
     else {  /* in one of the handles */
       if (handle==1) valp = &(hd->stval);  else valp = &(hd->enval);
@@ -2958,22 +2958,22 @@
 
 	  if (!hd->ccwise) {
 	    ddist = (hd->enval - hd->stval + 360) % 360;
-	    if (handle==1) 
+	    if (handle==1)
 	      ndist = (hd->enval - j + 360) % 360;
 	    else
 	      ndist = (j - hd->stval + 360) % 360;
 	  }
 	  else {
 	    ddist = (hd->stval - hd->enval + 360) % 360;
-	    if (handle==1) 
+	    if (handle==1)
 	      ndist = (j - hd->enval + 360) % 360;
 	    else
 	      ndist = (hd->stval - j + 360) % 360;
 	  }
 
-	  if (abs(ddist - ndist) >= 180 && ddist<180) 
+	  if (abs(ddist - ndist) >= 180 && ddist<180)
 	    hd->ccwise = !hd->ccwise;
-	  
+
 	  *valp = j;
 	  HDRedraw(hd, HD_HANDS | HD_DIR | HD_VALS);
 
@@ -2986,8 +2986,8 @@
 
   return rv;
 }
-    
-      
+
+
 
 /**************************************************/
 static int hdg2xdg(hdg)
@@ -3012,7 +3012,7 @@
   *yp = cy - (int) (sin(ang) * (double) rad);
 }
 
-  
+
 /***************************************************/
 static int computeHDval(hd, x, y)
 HDIAL *hd;
@@ -3044,7 +3044,7 @@
 
 
 
-    
+
 /****************************************************/
 static void initHmap()
 {
@@ -3117,10 +3117,10 @@
 	(hmap[i].src_en  != hmap[i].dst_en) ||
 	(hmap[i].src_ccw != hmap[i].dst_ccw)) {   /* not a 1:1 mapping */
 
-      st1  = hmap[i].src_st;  
+      st1  = hmap[i].src_st;
       en1  = hmap[i].src_en;
       if (hmap[i].src_ccw) {
-	inc1 = -1; 
+	inc1 = -1;
 	len1 = (st1 - en1 + 360) % 360;
       }
       else {
@@ -3131,7 +3131,7 @@
       st2 = hmap[i].dst_st;
       en2 = hmap[i].dst_en;
       if (hmap[i].dst_ccw) {
-	inc2 = -1; 
+	inc2 = -1;
 	len2 = (st2 - en2 + 360) % 360;
       }
       else {
@@ -3179,7 +3179,7 @@
 
   byte *pp, *op;
   int   i,j;
-  int   rv, gv, bv, vi, hi;
+  int   rv, gv, bv;
   byte *outpic;
   int   min, max, del, h, s, v;
   int   f, p, q, t, vs100, vsf10000;
@@ -3200,7 +3200,7 @@
 
   if (whtHD.enabCB.val && whtHD.satval) hsvmod++;
 
-  if (satDial.val != 0) hsvmod++;
+  if (satDial.val != 0.0) hsvmod++;
 
   /* check intensity graf */
   for (i=0; i<256; i++) {
@@ -3270,7 +3270,7 @@
 
       /* map near-black to black to avoid weird effects */
       if (v <= 16) s = 0;
-      
+
       /* apply intGraf.func[] function to 'v' (the intensity) */
       v = intGraf.func[v];
 
@@ -3284,7 +3284,7 @@
       }
 
       /* apply satDial value to s */
-      s = s + satDial.val;
+      s = s + (int)satDial.val;
       if (s<  0) s =   0;
       if (s>100) s = 100;
 
@@ -3295,7 +3295,7 @@
       if (h==NOHUE || !s) { rv = gv = bv = v; }
       else {
 	if (h==360) h = 0;
-	
+
 	h        = (h*100) / 60;    /* h is in range 000..599 (0.0 - 5.99) */
 	j        = h - (h%100);     /* j = 000, 100, 200, 300, 400, 500 */
 	f        = h - j;           /* 'fractional' part of h (00..99) */
@@ -3305,7 +3305,7 @@
 	p = v - vs100;
 	q = v - vsf10000;
 	t = v - vs100 + vsf10000;
-	
+
 	switch (j) {
 	case 000:  rv = v;  gv = t;  bv = p;  break;
 	case 100:  rv = q;  gv = v;  bv = p;  break;
@@ -3319,7 +3319,7 @@
     }   /* if hsvmod */
 
 
-    *op++ = rGraf.func[rv];  
+    *op++ = rGraf.func[rv];
     *op++ = gGraf.func[gv];
     *op++ = bGraf.func[bv];
   }
diff -ru xv-3.10a/xvgif.c xv-3.10a-enhancements/xvgif.c
--- xv-3.10a/xvgif.c	1995-01-10 11:54:41.000000000 -0800
+++ xv-3.10a-enhancements/xvgif.c	2007-05-13 17:33:51.000000000 -0700
@@ -28,17 +28,19 @@
 typedef int boolean;
 
 #define NEXTBYTE (*dataptr++)
+#define SKIPBYTE (dataptr++)	/* quiet some compiler warnings */
 #define EXTENSION     0x21
-#define IMAGESEP      0x2c
+#define IMAGESEP      0x2c	/* a.k.a. Image Descriptor */
 #define TRAILER       0x3b
 #define INTERLACEMASK 0x40
 #define COLORMAPMASK  0x80
 
-  
 
-FILE *fp;
 
-int BitOffset = 0,		/* Bit Offset of next code */
+static FILE *fp;
+
+static int
+    BitOffset = 0,		/* Bit Offset of next code */
     XC = 0, YC = 0,		/* Output X and Y coords of current pixel */
     Pass = 0,			/* Used by output routine if interlaced pic */
     OutCount = 0,		/* Decompressor output 'stack count' */
@@ -46,9 +48,10 @@
     Width, Height,		/* image dimensions */
     LeftOfs, TopOfs,		/* image offset */
     BitsPerPixel,		/* Bits per pixel, read from GIF header */
-    BytesPerScanline,		/* bytes per scanline in output raster */
+/*  BytesPerScanline,	*/	/* bytes per scanline in output raster */
     ColorMapSize,		/* number of colors */
     Background,			/* background color */
+    Transparent,		/* transparent color (GRR 19980314) */
     CodeSize,			/* Code size, read from GIF header */
     InitCodeSize,		/* Starting code size, used during Clear */
     Code,			/* Value returned by ReadCode */
@@ -57,47 +60,49 @@
     EOFCode,			/* GIF end-of-information code */
     CurCode, OldCode, InCode,	/* Decompressor variables */
     FirstFree,			/* First free code, generated per GIF spec */
-    FreeCode,			/* Decompressor,next free slot in hash table */
+    FreeCode,			/* Decompressor, next free slot in hash table */
     FinChar,			/* Decompressor variable */
     BitMask,			/* AND mask for data size */
     ReadMask,			/* Code AND mask for current code size */
-    Misc;                       /* miscellaneous bits (interlace, local cmap)*/
+    Misc,                       /* miscellaneous bits (interlace, local cmap)*/
+    GlobalBitsPerPixel,		/* may have local colormap of different size */
+    GlobalColorMapSize,		/*   (ditto)  */
+    GlobalBitMask;		/*   (ditto)  */
 
 
-boolean Interlace, HasColormap;
+static boolean Interlace, HasGlobalColormap;
 
-byte *RawGIF;			/* The heap array to hold it, raw */
-byte *Raster;			/* The raster data stream, unblocked */
-byte *pic8;
+static byte *RawGIF;		/* The heap array to hold it, raw */
+static byte *Raster;		/* The raster data stream, unblocked */
+static byte *pic8;
 
     /* The hash table used by the decompressor */
-int Prefix[4096];
-int Suffix[4096];
+static int Prefix[4096];
+static int Suffix[4096];
 
     /* An output array used by the decompressor */
-int OutCode[4097];
+static int OutCode[4097];
 
-int   gif89 = 0;
-char *id87 = "GIF87a";
-char *id89 = "GIF89a";
+static int gif89 = 0;
+static const char *id87 = "GIF87a";
+static const char *id89 = "GIF89a";
 
-static int EGApalette[16][3] = {
-  {0,0,0},       {0,0,128},     {0,128,0},     {0,128,128}, 
+static int const EGApalette[16][3] = {
+  {0,0,0},       {0,0,128},     {0,128,0},     {0,128,128},
   {128,0,0},     {128,0,128},   {128,128,0},   {200,200,200},
   {100,100,100}, {100,100,255}, {100,255,100}, {100,255,255},
   {255,100,100}, {255,100,255}, {255,255,100}, {255,255,255} };
-  
+
 
 static int   readImage   PARM((PICINFO *));
 static int   readCode    PARM((void));
 static void  doInterlace PARM((int));
-static int   gifError    PARM((PICINFO *, char *));
-static void  gifWarning  PARM((char *));
+static int   gifError    PARM((PICINFO *, const char *));
+static void  gifWarning  PARM((const char *));
 
-int   filesize;
-char *bname;
-
-byte *dataptr;
+static int         filesize;
+static const char *bname;
+static byte       *dataptr;
 
 
 /*****************************/
@@ -108,17 +113,22 @@
 {
   /* returns '1' if successful */
 
-  register byte  ch, ch1, *origptr;
+  register byte  ch, *origptr;
   register int   i, block;
-  int            aspect, gotimage;
+  int            aspect;
+  char tmpname[256];
+  byte r[256], g[256], b[256];
 
   /* initialize variables */
-  BitOffset = XC = YC = Pass = OutCount = gotimage = 0;
+  BitOffset = XC = YC = OutCount = 0;
+  Pass = -1;
   RawGIF = Raster = pic8 = NULL;
   gif89 = 0;
+  Transparent = -1;
 
   pinfo->pic     = (byte *) NULL;
   pinfo->comment = (char *) NULL;
+  pinfo->numpages= 0;
 
   bname = BaseName(fname);
   fp = xv_fopen(fname,"r");
@@ -129,67 +139,87 @@
   fseek(fp, 0L, 2);
   filesize = ftell(fp);
   fseek(fp, 0L, 0);
-  
-  /* the +256's are so we can read truncated GIF files without fear of 
+
+  if (filesize + 256 < filesize)
+    return( gifError(pinfo, "GIF file size is too large") );
+
+  /* the +256's are so we can read truncated GIF files without fear of
      segmentation violation */
   if (!(dataptr = RawGIF = (byte *) calloc((size_t) filesize+256, (size_t) 1)))
-    return( gifError(pinfo, "not enough memory to read gif file") );
-  
-  if (!(Raster = (byte *) calloc((size_t) filesize+256,(size_t) 1))) 
-    return( gifError(pinfo, "not enough memory to read gif file") );
-  
-  if (fread(dataptr, (size_t) filesize, (size_t) 1, fp) != 1) 
-    return( gifError(pinfo, "GIF data read failed") );
+    FatalError("LoadGIF: not enough memory to read GIF file");
 
+  if (!(Raster = (byte *) calloc((size_t) filesize+256,(size_t) 1)))
+    FatalError("LoadGIF: not enough memory to read GIF file");
+
+  if (fread(dataptr, (size_t) filesize, (size_t) 1, fp) != 1)
+    return( gifError(pinfo, "GIF data read failed") );
+  fclose(fp);
 
   origptr = dataptr;
 
   if      (strncmp((char *) dataptr, id87, (size_t) 6)==0) gif89 = 0;
   else if (strncmp((char *) dataptr, id89, (size_t) 6)==0) gif89 = 1;
   else    return( gifError(pinfo, "not a GIF file"));
-  
+
   dataptr += 6;
-  
+
   /* Get variables from the GIF screen descriptor */
-  
+
   ch = NEXTBYTE;
   RWidth = ch + 0x100 * NEXTBYTE;	/* screen dimensions... not used. */
   ch = NEXTBYTE;
   RHeight = ch + 0x100 * NEXTBYTE;
-  
+  if (DEBUG) fprintf(stderr,"GIF89 logical screen = %d x %d\n",RWidth,RHeight);
+
   ch = NEXTBYTE;
-  HasColormap = ((ch & COLORMAPMASK) ? True : False);
-  
-  BitsPerPixel = (ch & 7) + 1;
-  numcols = ColorMapSize = 1 << BitsPerPixel;
-  BitMask = ColorMapSize - 1;
-  
+  HasGlobalColormap = ((ch & COLORMAPMASK) ? True : False);
+
+  /* GRR 20070318:  fix decoding bug when global and local color-table sizes
+   *                differ */
+  GlobalBitsPerPixel = BitsPerPixel = (ch & 7) + 1;
+  GlobalColorMapSize = ColorMapSize = numcols = 1 << BitsPerPixel;
+  GlobalBitMask = BitMask = ColorMapSize - 1;
+
   Background = NEXTBYTE;		/* background color... not used. */
-  
+
   aspect = NEXTBYTE;
   if (aspect) {
     if (!gif89) return(gifError(pinfo,"corrupt GIF file (screen descriptor)"));
     else normaspect = (float) (aspect + 15) / 64.0;   /* gif89 aspect ratio */
     if (DEBUG) fprintf(stderr,"GIF89 aspect = %f\n", normaspect);
+    /* FIXME:  apparently this _should_ apply to all frames in a multi-image
+     *         GIF (i.e., PgUp/PgDn), but it doesn't */
   }
-  
-  
+
+
   /* Read in global colormap. */
-  
-  if (HasColormap)
+
+  if (HasGlobalColormap)
     for (i=0; i<ColorMapSize; i++) {
-      pinfo->r[i] = NEXTBYTE;
-      pinfo->g[i] = NEXTBYTE;
-      pinfo->b[i] = NEXTBYTE;
+      r[i] = NEXTBYTE;
+      g[i] = NEXTBYTE;
+      b[i] = NEXTBYTE;
     }
-  else {  /* no colormap in GIF file */
+  else {  /* no _global_ colormap in GIF file (but may have local one(s)) */
     /* put std EGA palette (repeated 16 times) into colormap, for lack of
-       anything better to do */
+       anything better to do at the moment */
 
     for (i=0; i<256; i++) {
-      pinfo->r[i] = EGApalette[i&15][0];
-      pinfo->g[i] = EGApalette[i&15][1];
-      pinfo->b[i] = EGApalette[i&15][2];
+      r[i] = EGApalette[i&15][0];
+      g[i] = EGApalette[i&15][1];
+      b[i] = EGApalette[i&15][2];
+    }
+  }
+  memcpy(pinfo->r, r, sizeof r);
+  memcpy(pinfo->g, g, sizeof g);
+  memcpy(pinfo->b, b, sizeof b);
+
+  if (DEBUG > 1) {
+    fprintf(stderr,"  global color table%s:\n",
+      HasGlobalColormap? "":" (repeated EGA palette)");
+    for (i=0; i<ColorMapSize; i++) {
+      fprintf(stderr,"    (%3d  %02x,%02x,%02x)\n", i, pinfo->r[i],
+        pinfo->g[i], pinfo->b[i]);
     }
   }
 
@@ -221,19 +251,19 @@
 	if (blocksize == 2) {
 	  aspnum = NEXTBYTE;
 	  aspden = NEXTBYTE;
-	  if (aspden>0 && aspnum>0) 
+	  if (aspden>0 && aspnum>0)
 	    normaspect = (float) aspnum / (float) aspden;
 	  else { normaspect = 1.0;  aspnum = aspden = 1; }
 
-	  if (DEBUG) fprintf(stderr,"GIF87 aspect extension: %d:%d = %f\n\n", 
+	  if (DEBUG) fprintf(stderr,"GIF87 aspect extension: %d:%d = %f\n\n",
 			     aspnum, aspden,normaspect);
 	}
 	else {
-	  for (i=0; i<blocksize; i++) NEXTBYTE;
+	  for (i=0; i<blocksize; i++) SKIPBYTE;
 	}
 
 	while ((sbsize=NEXTBYTE)>0) {  /* eat any following data subblocks */
-	  for (i=0; i<sbsize; i++) NEXTBYTE;
+	  for (i=0; i<sbsize; i++) SKIPBYTE;
 	}
       }
 
@@ -254,9 +284,11 @@
 
 
 	if (cmtlen>0) {   /* build into one un-blocked comment */
+	  /* this can overflow iff cmtlen == 2G - 1, but then filesize
+	   * would have to be > 2GB, which was disallowed above */
 	  cmt = (byte *) malloc((size_t) (cmtlen + 1));
-	  if (!cmt) gifWarning("couldn't malloc space for comments\n");
-	  else {
+	  if (!cmt) FatalError("LoadGIF: couldn't malloc space for comments");
+	  /* else */ {
 	    sp = cmt;
 	    do {
 	      sbsize = (*ptr1++);
@@ -267,10 +299,10 @@
 	    if (pinfo->comment) {    /* have to strcat onto old comments */
 	      cmt1 = (byte *) malloc(strlen(pinfo->comment) + cmtlen + 2);
 	      if (!cmt1) {
-		gifWarning("couldn't malloc space for comments\n");
 		free(cmt);
+	        FatalError("LoadGIF: couldn't malloc space for comments");
 	      }
-	      else {
+	      /* else */ {
 		strcpy((char *) cmt1, (char *) pinfo->comment);
 		strcat((char *) cmt1, (char *) "\n");
 		strcat((char *) cmt1, (char *) cmt);
@@ -288,8 +320,8 @@
       else if (fn == 0x01) {  /* PlainText Extension */
 	int j,sbsize,ch;
 	int tgLeft, tgTop, tgWidth, tgHeight, cWidth, cHeight, fg, bg;
-      
-	SetISTR(ISTR_INFO, "%s:  %s", bname, 
+
+	SetISTR(ISTR_INFO, "%s:  %s", bname,
 		"PlainText extension found in GIF file.  Ignored.");
 
 	sbsize   = NEXTBYTE;
@@ -302,12 +334,12 @@
 	fg       = NEXTBYTE;
 	bg       = NEXTBYTE;
 	i=12;
-	for ( ; i<sbsize; i++) NEXTBYTE;   /* read rest of first subblock */
-      
+	for ( ; i<sbsize; i++) SKIPBYTE;   /* read rest of first subblock */
+
 	if (DEBUG) fprintf(stderr,
 	   "PlainText: tgrid=%d,%d %dx%d  cell=%dx%d  col=%d,%d\n",
 	   tgLeft, tgTop, tgWidth, tgHeight, cWidth, cHeight, fg, bg);
-	
+
 	/* read (and ignore) data sub-blocks */
 	do {
 	  j = 0;
@@ -326,16 +358,32 @@
 
 	if (DEBUG) fprintf(stderr,"Graphic Control extension\n\n");
 
-	SetISTR(ISTR_INFO, "%s:  %s", bname, 
-		"Graphic Control Extension in GIF file.  Ignored.");
-	
-	/* read (and ignore) data sub-blocks */
+	SetISTR(ISTR_INFO, "%s:  %s", bname,
+		"Graphic Control Extension ignored.");
+
+	/* read (and ignore) data sub-blocks, unless compositing with
+         * user-defined background */
 	do {
-	  j = 0; sbsize = NEXTBYTE;
-	  while (j<sbsize) { NEXTBYTE;  j++; }
+	  j = 0;
+	  sbsize = NEXTBYTE;
+	  /* GRR 19980314:  get transparent index out of block */
+	  if (have_imagebg && sbsize == 4 && Transparent < 0) {
+	    byte packed_fields = NEXTBYTE;
+
+	    j++;
+	    SKIPBYTE;  j++;
+	    SKIPBYTE;  j++;
+	    if (packed_fields & 1) {
+	      Transparent = NEXTBYTE;
+	      j++;
+	    }
+	  }
+	  while (j<sbsize) {
+	    SKIPBYTE;  j++;
+	  }
 	} while (sbsize);
       }
-      
+
 
       else if (fn == 0xFF) {  /* Application Extension */
 	int j, sbsize;
@@ -345,10 +393,10 @@
 	/* read (and ignore) data sub-blocks */
 	do {
 	  j = 0; sbsize = NEXTBYTE;
-	  while (j<sbsize) { NEXTBYTE;  j++; }
+	  while (j<sbsize) { SKIPBYTE;  j++; }
 	} while (sbsize);
       }
-      
+
 
       else { /* unknown extension */
 	int j, sbsize;
@@ -358,48 +406,68 @@
 	SetISTR(ISTR_INFO,
 		"%s:  Unknown extension 0x%02x in GIF file.  Ignored.",
 		bname, fn);
-	
+
 	/* read (and ignore) data sub-blocks */
 	do {
 	  j = 0; sbsize = NEXTBYTE;
-	  while (j<sbsize) { NEXTBYTE;  j++; }
+	  while (j<sbsize) { SKIPBYTE;  j++; }
 	} while (sbsize);
       }
     }
 
 
     else if (block == IMAGESEP) {
-      if (DEBUG) fprintf(stderr,"imagesep (got=%d)  ",gotimage);
-      if (DEBUG) fprintf(stderr,"  at start: offset=0x%lx\n",dataptr-RawGIF);
-
-      if (gotimage) {   /* just skip over remaining images */
-	int i,misc,ch,ch1;
-
-	/* skip image header */
-	NEXTBYTE;  NEXTBYTE;  /* left position */
-	NEXTBYTE;  NEXTBYTE;  /* top position */
-	NEXTBYTE;  NEXTBYTE;  /* width */
-	NEXTBYTE;  NEXTBYTE;  /* height */
-	misc = NEXTBYTE;      /* misc. bits */
-
-	if (misc & 0x80) {    /* image has local colormap.  skip it */
-	  for (i=0; i< 1 << ((misc&7)+1);  i++) {
-	    NEXTBYTE;  NEXTBYTE;  NEXTBYTE;
+      if (DEBUG) fprintf(stderr, "imagesep (page=%d)\n", pinfo->numpages+1);
+      if (DEBUG) fprintf(stderr, "  at start: offset=0x%lx\n",
+                         (unsigned long)(dataptr-RawGIF));
+
+      BitOffset = XC = YC = Pass = OutCount = 0;
+
+      if (pinfo->numpages > 0) {   /* do multipage stuff */
+	if (pinfo->numpages == 1) {    /* first time only... */
+	  xv_mktemp(pinfo->pagebname, "xvpgXXXXXX"); // a.k.a. close(mkstemp())
+	  if (pinfo->pagebname[0] == '\0') {
+	    ErrPopUp("LoadGIF: Unable to create temporary filename???",
+			"\nHow unlikely!");
+	    return 0;
+	  }
+	  /* GRR 20070328:  basename file doesn't go away, at least on Linux
+           *  (though all appended-number ones do); ergo, open for reading (see
+           *  if it's there), close, and explicitly unlink() if necessary */
+          /* GRR 20070506:  could/should call KillPageFiles() (xv.c) instead */
+	  fp = xv_fopen(pinfo->pagebname, "r");
+	  if (fp) {
+	    fclose(fp);
+	    unlink(pinfo->pagebname);  /* no errors during testing */
 	  }
 	}
-
-	NEXTBYTE;       /* minimum code size */
-
-	/* skip image data sub-blocks */
-	do {
-	  ch = ch1 = NEXTBYTE;
-	  while (ch--) NEXTBYTE;
-	  if ((dataptr - RawGIF) > filesize) break;      /* EOF */
-	} while(ch1);
-      }
-
-      else if (readImage(pinfo)) gotimage = 1;
-      if (DEBUG) fprintf(stderr,"  at end:   dataptr=0x%lx\n",dataptr-RawGIF);
+	sprintf(tmpname, "%s%d", pinfo->pagebname, pinfo->numpages);
+	fp = xv_fopen(tmpname, "w");
+	if (!fp) {
+	  ErrPopUp("LoadGIF: Unable to open temp file", "\nDang!");
+	  return 0;
+	}
+	if (WriteGIF(fp, pinfo->pic, pinfo->type, pinfo->w, pinfo->h, pinfo->r,
+		 pinfo->g, pinfo->b, numcols, pinfo->colType, NULL)) {
+	  fclose(fp);
+	  ErrPopUp("LoadGIF: Error writing temp file", "\nBummer!");
+	  return 0;
+	}
+	fclose(fp);
+	free(pinfo->pic);
+	pinfo->pic = (byte *) NULL;
+	if (HasGlobalColormap) {
+	  memcpy(pinfo->r, r, sizeof r);
+	  memcpy(pinfo->g, g, sizeof g);
+	  memcpy(pinfo->b, b, sizeof b);
+	}
+        BitsPerPixel = GlobalBitsPerPixel;
+        numcols = ColorMapSize = GlobalColorMapSize;
+        BitMask = GlobalBitMask;
+      }
+      if (readImage(pinfo)) ++pinfo->numpages;
+      if (DEBUG) fprintf(stderr, "  at end:   offset=0x%lx\n",
+                         (unsigned long)(dataptr-RawGIF));
     }
 
 
@@ -416,9 +484,9 @@
       /* don't mention bad block if file was trunc'd, as it's all bogus */
       if ((dataptr - origptr) < filesize) {
 	sprintf(str, "Unknown block type (0x%02x) at offset 0x%lx",
-		block, (dataptr - origptr) - 1);
+		block, (unsigned long)(dataptr - origptr) - 1);
 
-	if (!gotimage) return gifError(pinfo, str);
+	if (!pinfo->numpages) return gifError(pinfo, str);
 	else gifWarning(str);
       }
 
@@ -431,8 +499,34 @@
   free(RawGIF);	 RawGIF = NULL;
   free(Raster);  Raster = NULL;
 
-  if (!gotimage) 
+  if (!pinfo->numpages)
      return( gifError(pinfo, "no image data found in GIF file") );
+  if (pinfo->numpages > 1) {
+    /* write the last page temp file */
+    int numpages = pinfo->numpages;
+    char *comment = pinfo->comment;
+    sprintf(tmpname, "%s%d", pinfo->pagebname, pinfo->numpages);
+    fp = xv_fopen(tmpname, "w");
+    if (!fp) {
+      ErrPopUp("LoadGIF: Unable to open temp file", "\nDang!");
+      return 0;
+    }
+    if (WriteGIF(fp, pinfo->pic, pinfo->type, pinfo->w, pinfo->h, pinfo->r,
+		 pinfo->g, pinfo->b, numcols, pinfo->colType, NULL)) {
+      fclose(fp);
+      ErrPopUp("LoadGIF: Error writing temp file", "\nBummer!");
+      return 0;
+    }
+    fclose(fp);
+    free(pinfo->pic);
+    pinfo->pic = (byte *) NULL;
+
+    /* load the first page temp file */
+    sprintf(tmpname, "%s%d", pinfo->pagebname, 1);
+    i = LoadGIF(tmpname, pinfo);
+    pinfo->numpages = numpages;
+    pinfo->comment = comment;
+  }
 
   return 1;
 }
@@ -444,11 +538,12 @@
 {
   register byte ch, ch1, *ptr1, *picptr;
   int           i, npixels, maxpixels;
+  boolean       HasLocalColormap;
 
   npixels = maxpixels = 0;
 
   /* read in values from the image descriptor */
-  
+
   ch = NEXTBYTE;
   LeftOfs = ch + 0x100 * NEXTBYTE;
   ch = NEXTBYTE;
@@ -460,45 +555,68 @@
 
   Misc = NEXTBYTE;
   Interlace = ((Misc & INTERLACEMASK) ? True : False);
+  HasLocalColormap = ((Misc & COLORMAPMASK) ? True : False);
 
-  if (Misc & 0x80) {
-    for (i=0; i< 1 << ((Misc&7)+1); i++) {
+  if (HasLocalColormap) {
+    BitsPerPixel = (Misc & 7) + 1;
+    ColorMapSize = numcols = 1 << BitsPerPixel;  /* GRR 20070318 */
+    BitMask = ColorMapSize - 1;
+    if (DEBUG) fprintf(stderr,"  local color table, %d bits (%d entries)\n",
+      (Misc&7)+1, ColorMapSize);
+    for (i=0; i<ColorMapSize; i++) {
       pinfo->r[i] = NEXTBYTE;
       pinfo->g[i] = NEXTBYTE;
       pinfo->b[i] = NEXTBYTE;
     }
+    if (DEBUG > 1) {
+      for (i=0; i<ColorMapSize; i++) {
+        fprintf(stderr,"    (%3d  %02x,%02x,%02x)\n", i, pinfo->r[i],
+          pinfo->g[i], pinfo->b[i]);
+      }
+    }
   }
 
 
-  if (!HasColormap && !(Misc&0x80)) {
+  if (!HasGlobalColormap && !HasLocalColormap) {
     /* no global or local colormap */
-    SetISTR(ISTR_WARNING, "%s:  %s", bname, 
+    SetISTR(ISTR_WARNING, "%s:  %s", bname,
 	    "No colormap in this GIF file.  Assuming EGA colors.");
   }
-    
 
-  
+
+  /* GRR 19980314 */
+  /* need not worry about size of EGA palette:  full 256 colors */
+  if (have_imagebg && Transparent >= 0 &&
+      Transparent < ((Misc&0x80)? (1 << ((Misc&7)+1)) : ColorMapSize) )
+  {
+    pinfo->r[Transparent] = (imagebgR >> 8);
+    pinfo->g[Transparent] = (imagebgG >> 8);
+    pinfo->b[Transparent] = (imagebgB >> 8);
+  }
+
+
+
   /* Start reading the raster data. First we get the intial code size
    * and compute decompressor constant values, based on this code size.
    */
-  
+
   CodeSize = NEXTBYTE;
 
   ClearCode = (1 << CodeSize);
   EOFCode = ClearCode + 1;
   FreeCode = FirstFree = ClearCode + 2;
-  
+
   /* The GIF spec has it that the code size is the code size used to
    * compute the above values is the code size given in the file, but the
    * code size used in compression/decompression is the code size given in
    * the file plus one. (thus the ++).
    */
-  
+
   CodeSize++;
   InitCodeSize = CodeSize;
   MaxCode = (1 << CodeSize);
   ReadMask = MaxCode - 1;
-  
+
 
 
   /* UNBLOCK:
@@ -506,7 +624,7 @@
    * to the Raster array, turning it from a series of blocks into one long
    * data stream, which makes life much easier for readCode().
    */
-  
+
   ptr1 = Raster;
   do {
     ch = ch1 = NEXTBYTE;
@@ -522,21 +640,24 @@
 
 
   if (DEBUG) {
-    fprintf(stderr,"xv: LoadGIF() - picture is %dx%d, %d bits, %sinterlaced\n",
+    fprintf(stderr,"LoadGIF: image is %dx%d, %d bits, %sinterlaced\n",
 	    Width, Height, BitsPerPixel, Interlace ? "" : "non-");
   }
-  
+
 
   /* Allocate the 'pic' */
-  maxpixels = Width*Height;
+  maxpixels = Width*Height;  /* 65535*65535 max (but everything is int) */
+  if (Width <= 0 || Height <= 0 || maxpixels/Width != Height)
+    return( gifError(pinfo, "image dimensions out of range") );
   picptr = pic8 = (byte *) malloc((size_t) maxpixels);
-  if (!pic8) return( gifError(pinfo, "couldn't malloc 'pic8'") );
+  if (!pic8) FatalError("LoadGIF: couldn't malloc 'pic8'");
+
+
 
-  
   /* Decompress the file, continuing until you see the GIF EOF code.
    * One obvious enhancement is to add checking for corrupt files here.
    */
-  
+
   Code = readCode();
   while (Code != EOFCode) {
     /* Clear code sets everything back to its initial value, then reads the
@@ -563,58 +684,58 @@
 			    break; }
 
       CurCode = InCode = Code;
-      
+
       /* If greater or equal to FreeCode, not in the hash table yet;
        * repeat the last character decoded
        */
-      
+
       if (CurCode >= FreeCode) {
 	CurCode = OldCode;
 	if (OutCount > 4096) {  /* printf("outcount1 blew up\n"); */ break; }
 	OutCode[OutCount++] = FinChar;
       }
-      
+
       /* Unless this code is raw data, pursue the chain pointed to by CurCode
        * through the hash table to its end; each code in the chain puts its
        * associated output code on the output queue.
        */
-      
+
       while (CurCode > BitMask) {
 	if (OutCount > 4096) break;   /* corrupt file */
 	OutCode[OutCount++] = Suffix[CurCode];
 	CurCode = Prefix[CurCode];
       }
-      
+
       if (OutCount > 4096) { /* printf("outcount blew up\n"); */ break; }
-      
+
       /* The last code in the chain is treated as raw data. */
-      
+
       FinChar = CurCode & BitMask;
       OutCode[OutCount++] = FinChar;
-      
+
       /* Now we put the data out to the Output routine.
        * It's been stacked LIFO, so deal with it that way...
        */
 
       /* safety thing:  prevent exceeding range of 'pic8' */
       if (npixels + OutCount > maxpixels) OutCount = maxpixels-npixels;
-	
+
       npixels += OutCount;
       if (!Interlace) for (i=OutCount-1; i>=0; i--) *picptr++ = OutCode[i];
                 else  for (i=OutCount-1; i>=0; i--) doInterlace(OutCode[i]);
       OutCount = 0;
 
       /* Build the hash table on-the-fly. No table is stored in the file. */
-      
+
       Prefix[FreeCode] = OldCode;
       Suffix[FreeCode] = FinChar;
       OldCode = InCode;
-      
+
       /* Point to the next slot in the table.  If we exceed the current
        * MaxCode value, increment the code size unless it's already 12.  If it
        * is, do nothing: the next code decompressed better be CLEAR
        */
-      
+
       FreeCode++;
       if (FreeCode >= MaxCode) {
 	if (CodeSize < 12) {
@@ -627,20 +748,19 @@
     Code = readCode();
     if (npixels >= maxpixels) break;
   }
-  
+
   if (npixels != maxpixels) {
     SetISTR(ISTR_WARNING,"%s:  %s", bname,
 	    "This GIF file seems to be truncated.  Winging it.");
     if (!Interlace)  /* clear->EOBuffer */
-      xvbzero((char *) pic8+npixels, (size_t) (maxpixels-npixels));
+      xvbzero((char *) pic8+npixels,
+	      (size_t) (maxpixels-npixels<0 ? 0 : maxpixels-npixels));
   }
 
-  fclose(fp);
-
   /* fill in the PICINFO structure */
 
   pinfo->pic     = pic8;
-  pinfo->w       = Width;           
+  pinfo->w       = Width;
   pinfo->h       = Height;
   pinfo->type    = PIC8;
   pinfo->frmType = F_GIF;
@@ -650,8 +770,8 @@
 
   sprintf(pinfo->fullInfo,
 	  "GIF%s, %d bit%s per pixel, %sinterlaced.  (%d bytes)",
- 	  (gif89) ? "89" : "87", BitsPerPixel, 
-	  (BitsPerPixel==1) ? "" : "s", 
+ 	  (gif89) ? "89" : "87", BitsPerPixel,
+	  (BitsPerPixel==1) ? "" : "s",
  	  Interlace ? "" : "non-", filesize);
 
   sprintf(pinfo->shrtInfo, "%dx%d GIF%s.",Width,Height,(gif89) ? "89" : "87");
@@ -668,13 +788,13 @@
  * maintain our location in the Raster array as a BIT Offset.  We compute
  * the byte Offset into the raster array by dividing this by 8, pick up
  * three bytes, compute the bit Offset into our 24-bit chunk, shift to
- * bring the desired code to the bottom, then mask it off and return it. 
+ * bring the desired code to the bottom, then mask it off and return it.
  */
 
 static int readCode()
 {
   int RawCode, ByteOffset;
-  
+
   ByteOffset = BitOffset / 8;
   RawCode = Raster[ByteOffset] + (Raster[ByteOffset + 1] << 8);
   if (CodeSize >= 8)
@@ -692,42 +812,47 @@
 {
   static byte *ptr = NULL;
   static int   oldYC = -1;
-  
+
+  if (Pass == -1) {  /* first time through - init stuff */
+    oldYC = -1;
+    Pass = 0;
+  }
+
   if (oldYC != YC) {  ptr = pic8 + YC * Width;  oldYC = YC; }
-  
+
   if (YC<Height)
     *ptr++ = Index;
-  
+
   /* Update the X-coordinate, and if it overflows, update the Y-coordinate */
-  
+
   if (++XC == Width) {
-    
+
     /* deal with the interlace as described in the GIF
      * spec.  Put the decoded scan line out to the screen if we haven't gone
      * past the bottom of it
      */
-    
+
     XC = 0;
-    
+
     switch (Pass) {
     case 0:
       YC += 8;
       if (YC >= Height) { Pass++; YC = 4; }
       break;
-      
+
     case 1:
       YC += 8;
       if (YC >= Height) { Pass++; YC = 2; }
       break;
-      
+
     case 2:
       YC += 4;
       if (YC >= Height) { Pass++; YC = 1; }
       break;
-      
+
     case 3:
       YC += 2;  break;
-      
+
     default:
       break;
     }
@@ -735,11 +860,11 @@
 }
 
 
-      
+
 /*****************************/
 static int gifError(pinfo, st)
-     PICINFO *pinfo;
-     char    *st;
+     PICINFO    *pinfo;
+     const char *st;
 {
   gifWarning(st);
 
@@ -760,7 +885,7 @@
 
 /*****************************/
 static void gifWarning(st)
-     char *st;
+     const char *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", bname, st);
 }
diff -ru xv-3.10a/xvgifwr.c xv-3.10a-enhancements/xvgifwr.c
--- xv-3.10a/xvgifwr.c	1995-01-03 13:22:21.000000000 -0800
+++ xv-3.10a-enhancements/xvgifwr.c	2007-03-31 16:33:23.000000000 -0700
@@ -2,11 +2,11 @@
  * xvgifwr.c  -  handles writing of GIF files.  based on flgife.c and
  *               flgifc.c from the FBM Library, by Michael Maudlin
  *
- * Contains: 
+ * Contains:
  *   WriteGIF(fp, pic, ptype, w, h, rmap, gmap, bmap, numcols, colorstyle,
  *            comment)
  *
- * Note: slightly brain-damaged, in that it'll only write non-interlaced 
+ * Note: slightly brain-damaged, in that it'll only write non-interlaced
  *       GIF files (in the interests of speed, or something)
  *
  */
@@ -34,7 +34,7 @@
  *	James A. Woods          (decvax!ihnp4!ames!jaw)
  *	Joe Orost               (decvax!vax135!petsd!joe)
  *****************************************************************/
- 
+
 
 #include "xv.h"
 
@@ -44,7 +44,6 @@
 static int  curx, cury;
 static long CountDown;
 static int  Interlace;
-static byte bw[2] = {0, 0xff};
 
 static void putword     PARM((int, FILE *));
 static void compress    PARM((int, FILE *, byte *, int));
@@ -56,7 +55,7 @@
 static void flush_char  PARM((void));
 
 
-static byte pc2nc[256],r1[256],g1[256],b1[256];
+static byte pc2nc[256];
 
 
 /*************************************************************/
@@ -74,7 +73,8 @@
   int   ColorMapSize, InitCodeSize, Background, BitsPerPixel;
   int   i,j,nc;
   byte *pic8;
-  byte  rtemp[256],gtemp[256],btemp[256];
+  byte  rtemp[256],gtemp[256],btemp[256];  /* for 24-bit to 8-bit conversion */
+  byte  r1[256],g1[256],b1[256];           /* for duplicated-color remapping */
 
   if (ptype == PIC24) {  /* have to quantize down to 8 bits */
     pic8 = Conv24to8(pic, w, h, 256, rtemp,gtemp,btemp);
@@ -97,7 +97,7 @@
   for (i=0; i<numcols; i++) {
     /* see if color #i is already used */
     for (j=0; j<i; j++) {
-      if (rmap[i] == rmap[j] && gmap[i] == gmap[j] && 
+      if (rmap[i] == rmap[j] && gmap[i] == gmap[j] &&
 	  bmap[i] == bmap[j]) break;
     }
 
@@ -115,15 +115,15 @@
   /* figure out 'BitsPerPixel' */
   for (i=1; i<8; i++)
     if ( (1<<i) >= nc) break;
-  
+
   BitsPerPixel = i;
 
   ColorMapSize = 1 << BitsPerPixel;
-	
+
   RWidth  = Width  = w;
   RHeight = Height = h;
   LeftOfs = TopOfs = 0;
-	
+
   CountDown = w * h;    /* # of pixels we'll be doing */
 
   if (BitsPerPixel <= 1) InitCodeSize = 2;
@@ -137,7 +137,7 @@
     return (1);
   }
 
-  if (DEBUG) 
+  if (DEBUG)
     fprintf(stderr,"WrGIF: pic=%lx, w,h=%dx%d, numcols=%d, Bits%d,Cmap=%d\n",
 	    (u_long) pic8, w,h,numcols,BitsPerPixel,ColorMapSize);
 
@@ -152,7 +152,7 @@
   i = 0x80;	                 /* Yes, there is a color map */
   i |= (8-1)<<4;                 /* OR in the color resolution (hardwired 8) */
   i |= (BitsPerPixel - 1);       /* OR in the # of bits per pixel */
-  fputc(i,fp);          
+  fputc(i,fp);
 
   fputc(Background, fp);         /* background color */
 
@@ -290,7 +290,7 @@
 /*
  * compress stdin to stdout
  *
- * Algorithm:  use open addressing double hashing (no chaining) on the 
+ * Algorithm:  use open addressing double hashing (no chaining) on the
  * prefix code / next character combination.  We do a variant of Knuth's
  * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
  * secondary probe.  Here, the modular division first probe is gives way
@@ -370,7 +370,7 @@
   cl_hash( (count_int) hsize_reg);            /* clear hash table */
 
   output(ClearCode);
-    
+
   while (len) {
     c = pc2nc[*data++];  len--;
     in_count++;
@@ -399,7 +399,7 @@
       continue;
     }
 
-    if ( (long)HashTabOf (i) >= 0 ) 
+    if ( (long)HashTabOf (i) >= 0 )
       goto probe;
 
 nomatch:
@@ -454,7 +454,7 @@
     cur_accum |= ((long)code << cur_bits);
   else
     cur_accum = code;
-	
+
   cur_bits += n_bits;
 
   while( cur_bits >= 8 ) {
@@ -482,7 +482,7 @@
 	maxcode = MAXCODE(n_bits);
     }
   }
-	
+
   if( code == EOFCode ) {
     /* At EOF, write the rest of the buffer */
     while( cur_bits > 0 ) {
@@ -492,11 +492,11 @@
     }
 
     flush_char();
-	
+
     fflush( g_outfile );
 
 #ifdef FOO
-    if( ferror( g_outfile ) ) 
+    if( ferror( g_outfile ) )
       FatalError("unable to write GIF file");
 #endif
   }
@@ -582,7 +582,7 @@
 int c;
 {
   accum[ a_count++ ] = c;
-  if( a_count >= 254 ) 
+  if( a_count >= 254 )
     flush_char();
 }
 
@@ -596,4 +596,4 @@
     fwrite(accum, (size_t) 1, (size_t) a_count, g_outfile );
     a_count = 0;
   }
-}	
+}
diff -ru xv-3.10a/xvgrab.c xv-3.10a-enhancements/xvgrab.c
--- xv-3.10a/xvgrab.c	1994-12-22 14:34:47.000000000 -0800
+++ xv-3.10a-enhancements/xvgrab.c	2005-04-25 23:39:32.000000000 -0700
@@ -6,7 +6,7 @@
  *  Contains:
  *     int Grab()             - handles the GRAB command
  *     int LoadGrab();        - 'loads' the pic from the last succesful Grab
- *            
+ *
  */
 
 #include "copyright.h"
@@ -14,28 +14,60 @@
 #define NEEDSTIME
 #include "xv.h"
 
-static byte *grabPic = (byte *) NULL;
-static int  gbits;                              /* either '8' or '24' */
-static byte grabmapR[256], grabmapG[256], grabmapB[256];  /* colormap */
-static int  gWIDE,gHIGH;
-static int  grabInProgress=0;
-static int  hidewins = 0;
-static GC   rootGC;
-
-static void   flashrect       PARM((int, int, int, int, int));
-static void   startflash      PARM((void));
-static void   endflash        PARM((void));
-static int    grabImage       PARM((Window, int, int, int, int));
-static void   ungrabX         PARM((void));
-static int    convertImage    PARM((XImage *, XColor *, int, 
-				    XWindowAttributes *));
-
-static int    lowbitnum       PARM((unsigned long));
-static int    getxcolors      PARM((XWindowAttributes *, XColor **));
-static Window xvClientWindow  PARM((Display *, Window));
+/* Allow flexibility in use of buttons JPD */
+#define WINDOWGRABMASK Button1Mask  /* JPD prefers Button2Mask */
+#define RECTGTRACKMASK Button2Mask  /* JPD prefers Button1Mask*/
+#define CANCELGRABMASK Button3Mask
 
+#define DO_GRABFLASH  /* JPD prefers not to do that; just a loss of time ... */
 
 
+union swapun {
+  CARD32 l;
+  CARD16 s;
+  CARD8  b[sizeof(CARD32)];
+};
+
+
+struct rectlist {
+  int x,y,w,h;
+  struct rectlist *next;
+};
+
+
+static byte            *grabPic = (byte *) NULL;
+static int              gptype;
+static byte             grabmapR[256], grabmapG[256], grabmapB[256];
+static int              gXOFF, gYOFF, gWIDE,gHIGH;
+static int              grabInProgress=0;
+static int              hidewins = 0;
+static GC               rootGC;
+static struct rectlist *regrabList;
+
+
+static void   flashrect           PARM((int, int, int, int, int));
+static void   startflash          PARM((void));
+static void   endflash            PARM((void));
+static void   ungrabX             PARM((void));
+static int    lowbitnum           PARM((unsigned long));
+static int    getxcolors          PARM((XWindowAttributes *, XColor **));
+
+static void   printWinTree        PARM((Window, int));
+static void   errSpace            PARM((int));
+
+static int    grabRootRegion      PARM((int, int, int, int));
+static int    grabWinImage        PARM((Window, VisualID, Colormap, int));
+static int    convertImageAndStuff PARM((XImage *, XColor *, int,
+					 XWindowAttributes *,
+					 int,int,int,int));
+
+static int    RectIntersect       PARM((int,int,int,int, int,int,int,int));
+
+static int    CountColors24       PARM((byte *, int, int,
+					int, int, int, int));
+
+static int    Trivial24to8        PARM((byte *, int, int, byte *,
+					byte *, byte *, byte *, int));
 
 /***********************************/
 int Grab()
@@ -44,13 +76,15 @@
      0 if cancelled */
 
   int          i, x, y, x1, y1, x2, y2, ix, iy, iw, ih, rv;
-  int          rx, ry, pretendGotB1, autograb;
-  int          oldaclose;
-  Window       rW, cW, clickWin, tmpwin;
+  int          rx, ry, GotButton, autograb;
+  int          cancelled = 0;
+  Window       rW, cW, clickWin;
   unsigned int mask;
+#ifdef RECOLOR_GRAB_CURSOR
   XColor       fc, bc;
+#endif
 
-  pretendGotB1 = 0;
+  GotButton = 0;
 
   if (grabInProgress) return 0;      /* avoid recursive grabs during delay */
 
@@ -75,7 +109,7 @@
     grabInProgress = 1; /* guard against recursive grabs during delay */
     time(&startT);
     while (1) {
-      time(&t);  
+      time(&t);
       if (t >= startT + grabDelay) break;
       if (XPending(theDisp)>0) {
 	XEvent evt;
@@ -91,25 +125,33 @@
     grabInProgress = 0;
   }
 
-  
+
   rootGC   = DefaultGC(theDisp, theScreen);
-  
+
   if (grabPic) {  /* throw away previous 'grabbed' pic, if there is one */
     free(grabPic);  grabPic = (byte *) NULL;
   }
 
-
+  /* recolor cursor to indicate that grabbing is active? */
+  /* Instead, change cursor JPD */
+#ifdef RECOLOR_GRAB_CURSOR
   fc.flags = bc.flags = DoRed | DoGreen | DoBlue;
-  fc.red = fc.green = fc.blue = 0xffff;  
+  fc.red = fc.green = fc.blue = 0xffff;
   bc.red = bc.green = bc.blue = 0x0000;
   XRecolorCursor(theDisp, tcross, &fc, &bc);
+#endif
 
 
   XBell(theDisp, 0);		/* beep once at start of grab */
 
-  if (!autograb) XGrabButton(theDisp, (u_int) AnyButton, 0, rootW, False, 0, 
+  /* Change cursor to top_left_corner JPD */
+  XGrabPointer(theDisp, rootW, False,
+     PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
+     GrabModeAsync, GrabModeAsync, None, tlcorner, CurrentTime);
+
+  if (!autograb) XGrabButton(theDisp, (u_int) AnyButton, 0, rootW, False, 0,
 			     GrabModeAsync, GrabModeSync, None, tcross);
-  
+
   if (autograb) {
     XGrabServer(theDisp);	 /* until we've done the grabImage */
     if (!XQueryPointer(theDisp,rootW,&rW,&cW,&rx,&ry,&x1,&y1,&mask)) {
@@ -118,7 +160,7 @@
       rv = 0;
       goto exit;
     }
-    else { pretendGotB1 = 1;  mask = Button1Mask; }
+    else { GotButton = 1;  mask = WINDOWGRABMASK; }
   }
 
   else {   /* !autograb */
@@ -136,7 +178,7 @@
       XNextEvent(theDisp, &evt);
       i = HandleEvent(&evt, &done);
       if (done) {                    /* only 'new image' cmd accepted=quit */
-	if (i==QUIT) { 
+	if (i==QUIT) {
 	  XUngrabButton(theDisp, (u_int) AnyButton, 0, rootW);
 	  Quit(0);
 	}
@@ -145,99 +187,75 @@
 
     }
   }
-  
-  
+
+  XUngrabPointer(theDisp, CurrentTime);
+  /* Reset cursor to XC_tcross JPD */
+  XGrabPointer(theDisp, rootW, False,
+     PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
+     GrabModeAsync, GrabModeAsync, None, tcross, CurrentTime);
+
   /***
    ***  got button click (or pretending we did, if autograb)
    ***/
-  
 
-  if (mask & Button3Mask || rW!=rootW) {        /* Button3: CANCEL GRAB */
+  if (mask & CANCELGRABMASK || rW!=rootW) {        /* CANCEL GRAB */
     while (1) {      /* wait for button to be released */
       if (XQueryPointer(theDisp,rootW,&rW,&cW,&rx,&ry,&x1,&y1,&mask)) {
-	if (!(mask & Button3Mask)) break;
+	if (!(mask & CANCELGRABMASK)) break;
       }
     }
-    
+
     XUngrabButton(theDisp, (u_int) AnyButton, 0, rootW);
     XBell(theDisp, 0);
     XBell(theDisp, 0);
     rv = 0;
+    cancelled = 1;
     goto exit;
   }
 
 
-
-  if (mask & Button1Mask) {  /* Button1:  GRAB WINDOW (& FRAME, maybe)     */
-    while (!pretendGotB1) {  /* wait for button to be released, if clicked */
+  if (mask & WINDOWGRABMASK) {  /* GRAB WINDOW (& FRAME, maybe)     */
+    while (!GotButton) {  /* wait for button to be released, if clicked */
       int rx,ry,x1,y1;  Window rW, cW;
       if (XQueryPointer(theDisp,rootW,&rW,&cW,&rx,&ry,&x1,&y1,&mask)) {
-	if (!(mask & Button1Mask)) break;
+	if (!(mask & WINDOWGRABMASK)) break;
       }
     }
-    
-    if (!cW || cW == rootW) clickWin = rootW;
-    else {
-      int xr, yr;    Window chwin;
-      XTranslateCoordinates(theDisp, rW, cW, rx, ry, &xr, &yr, &chwin);
-      if (chwin != None) {
-	XWindowAttributes clickxwa, parentxwa;
-
-	clickWin = xvClientWindow(theDisp, chwin);
-
-	/* decide if we want to just grab clickWin, or cW.
-	   basically, if they're different in any important way 
-	   (depth, visual, colormap), grab 'clickWin' only, 
-	   as it's the important part */
-
-	if (!clickWin || 
-	    (XGetWindowAttributes(theDisp, clickWin, &clickxwa)  &&
-	     XGetWindowAttributes(theDisp, cW,       &parentxwa) &&
-	     clickxwa.visual->class == parentxwa.visual->class   &&
-	     clickxwa.colormap      == parentxwa.colormap        &&
-	     clickxwa.depth         == parentxwa.depth)
-	    )
-	  clickWin = cW;   	  /* close enough! */
-      }
-      else clickWin = cW;
-      
-      if (DEBUG) 
-	fprintf(stderr, "rW = %x, cW = %x, chwin = %x, clickWin = %x\n",
-		(u_int) rW, (u_int) cW, (u_int) chwin, (u_int) clickWin);
-    }
-    
-    
+
+  grabwin:
+
+    clickWin = (cW) ? cW : rootW;
+
     if (clickWin == rootW) {   /* grab entire screen */
       if (DEBUG) fprintf(stderr,"Grab: clicked on root window.\n");
       ix = iy = 0;  iw = dispWIDE;  ih = dispHIGH;
     }
     else {
       int x,y;  Window win;   unsigned int rw,rh,rb,rd;
-      
+
       if (XGetGeometry(theDisp,clickWin,&rW, &x, &y, &rw, &rh, &rb, &rd)) {
 	iw = (int) rw;  ih = (int) rh;
-	
+
 	XTranslateCoordinates(theDisp, clickWin, rootW, 0, 0, &ix,&iy, &win);
-	
-	if (DEBUG) fprintf(stderr,"clickWin=0x%x: %d,%d %dx%d depth=%ud\n", 
-			   (u_int) clickWin, ix, iy, iw, ih, rd);    
+
+	if (DEBUG) fprintf(stderr,"clickWin=0x%x: %d,%d %dx%d depth=%ud\n",
+			   (u_int) clickWin, ix, iy, iw, ih, rd);
       }
       else {
 	ix = iy = 0;  iw = dispWIDE;  ih = dispHIGH;  clickWin = rootW;
 	if (DEBUG) fprintf(stderr,"XGetGeometry failed? (using root win)\n");
       }
     }
-    
-    
+
     /* range checking:  keep rectangle fully on-screen */
     if (ix<0) { iw += ix;  ix = 0; }
     if (iy<0) { ih += iy;  iy = 0; }
     if (ix+iw>dispWIDE) iw = dispWIDE-ix;
     if (iy+ih>dispHIGH) ih = dispHIGH-iy;
-    
-    
+
+
     if (DEBUG) fprintf(stderr,"using %d,%d (%dx%d)\n", ix, iy, iw, ih);
-    
+
     /* flash the rectangle a bit... */
     startflash();
     for (i=0; i<5; i++) {
@@ -249,23 +267,21 @@
     endflash();
   }
 
-
-  else {  /* Button2:  TRACK A RECTANGLE */
+  else {  /* TRACK A RECTANGLE */
     int    origrx, origry;
-    Window origcW;
 
-    clickWin = rootW;  origcW = cW;
+    clickWin = rootW;
     origrx = ix = x2 = rx;
     origry = iy = y2 = ry;
     iw = ih = 0;
-    
+
     XGrabServer(theDisp);
     startflash();
 
     /* Wait for button release while tracking rectangle on screen */
     while (1) {
       if (XQueryPointer(theDisp,rootW,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
-	if (!(mask & Button2Mask)) break;
+	if (!(mask & RECTGTRACKMASK)) break;
       }
 
       flashrect(ix, iy, iw, ih, 0);                /* turn off rect */
@@ -276,57 +292,63 @@
 	iw = abs(rx - x1);  ih = abs(ry - y1);
 	x2 = rx;  y2 = ry;
       }
-      
+
       if (iw>1 && ih>1) flashrect(ix,iy,iw,ih,1);  /* turn on rect */
     }
 
     flashrect(ix, iy, iw, ih, 0);                  /* turn off rect */
+
+#ifdef DO_GRABFLASH
+    /* flash the rectangle a bit... */
+    for (i=0; i<5; i++) {
+      flashrect(ix, iy, iw, ih, 1);
+      XFlush(theDisp);  Timer(100);
+      flashrect(ix, iy, iw, ih, 0);
+      XFlush(theDisp);  Timer(100);
+    }
+#endif
+
     endflash();
-    
-    XUngrabServer(theDisp);
-    
-    
-    if (origcW == cW) {  /* maybe it's entirely in one window??? */
-      if (cW) {    /* will be 0 if clicked in rootW */
-	Window stwin, enwin, stwin1, enwin1;
-	if (DEBUG) fprintf(stderr,"origcW=%x cW=%x   ", 
-			   (u_int) origcW, (u_int) cW);
-	XTranslateCoordinates(theDisp,rootW,cW, origrx,origry,&x,&y,&stwin);
-	XTranslateCoordinates(theDisp,rootW,cW, rx,    ry,    &x,&y,&enwin);
-	
-	if (DEBUG) fprintf(stderr,"stwin=%x enwin=%x   ", 
-			   (u_int) stwin, (u_int) enwin);
-	if (stwin == enwin && stwin != None) {
-	  stwin1 = xvClientWindow(theDisp, stwin);
-	  enwin1 = xvClientWindow(theDisp, enwin);
-	  if (DEBUG) fprintf(stderr,"stwin1=%x enwin1=%x   ", 
-			     (u_int) stwin1, (u_int) enwin1);
-	  
-	  if (stwin1 == enwin1 && stwin1) clickWin = stwin1;
-	  else clickWin = stwin;
-	}
-	if (DEBUG) fprintf(stderr,"\n");
-      }
-      else clickWin = rootW;
+
+    /* if rectangle has zero width or height, search for child window JPD */
+    if (iw==0 && ih==0) {
+       int xr, yr;
+       Window childW = 0;
+       if (rW && cW)
+          XTranslateCoordinates(theDisp, rW, cW, rx, ry, &xr, &yr, &childW);
+       if (childW)
+          cW = childW;
+       goto grabwin;
     }
+
+    XUngrabServer(theDisp);
   }
-  
 
   /***
-   ***  now that clickWin,ix,iy,iw,ih are known, try to grab the bits...
+   ***  now that clickWin,ix,iy,iw,ih are known, try to grab the bits :
+   ***  grab screen area (ix,iy,iw,ih)
    ***/
 
 
+  if (DEBUG>1) printWinTree(clickWin, 0);
+
   WaitCursor();
 
   if (!autograb) XGrabServer(theDisp);	 /* until we've done the grabImage */
-  rv = grabImage(clickWin,ix,iy,iw,ih);  /* ungrabs the server & button */
+  rv = grabRootRegion(ix, iy, iw, ih);   /* ungrabs the server & button */
 
   SetCursors(-1);
 
-
  exit:
 
+  XUngrabPointer(theDisp, CurrentTime);
+  XUngrabServer(theDisp);
+
+  if (startGrab) {
+    startGrab = 0;
+    if (cancelled) Quit(0);
+  }
+
   if (hidewins) {                   /* remap XV windows */
     autoclose += 2;                 /* force it on once */
     if (mainW && dispMode == RMB_WINDOW) {
@@ -337,25 +359,25 @@
 
       if (DEBUG) fprintf(stderr,"==remapped mainW.  waiting for Config.\n");
 
-      /* sit here until we see a MapNotify on mainW followed by a 
+      /* sit here until we see a MapNotify on mainW followed by a
 	 ConfigureNotify on mainW */
 
       state = 0;
-      while (1) {
+      while (state != 3) {
 	XEvent event;
 	XNextEvent(theDisp, &event);
 	HandleEvent(&event, &i);
 
-	if (state==0 && event.type == MapNotify &&
-	    event.xmap.window == mainW) state = 1;
+	if (!(state&1) && event.type == MapNotify &&
+	    event.xmap.window == mainW) state |= 1;
 
-	if (state==1 && event.type == ConfigureNotify && 
-	    event.xconfigure.window == mainW) break;
+	if (!(state&2) && event.type == ConfigureNotify &&
+	    event.xconfigure.window == mainW) state |= 2;
       }
 
       if (DEBUG) fprintf(stderr,"==after remapping mainW, GOT Config.\n");
     }
-      
+
     else if (ctrlW) CtrlBox(1);
   }
 
@@ -364,6 +386,45 @@
 
 
 /***********************************/
+int LoadGrab(pinfo)
+     PICINFO *pinfo;
+{
+  /* loads up (into XV structures) last image successfully grabbed.
+     returns '0' on failure, '1' on success */
+
+  int   i;
+
+  if (!grabPic) return 0;   /* no image to use */
+
+  pinfo->type = gptype;
+  if (pinfo->type == PIC8) {
+    for (i=0; i<256; i++) {
+      pinfo->r[i] = grabmapR[i];
+      pinfo->g[i] = grabmapG[i];
+      pinfo->b[i] = grabmapB[i];
+    }
+  }
+
+  pinfo->pic     = grabPic;
+  pinfo->normw   = pinfo->w   = gWIDE;
+  pinfo->normh   = pinfo->h   = gHIGH;
+  pinfo->frmType = -1;
+  pinfo->colType = -1;
+
+  sprintf(pinfo->fullInfo,"<%s internal>",
+	  (pinfo->type == PIC8) ? "8-bit" : "24-bit");
+
+  sprintf(pinfo->shrtInfo,"%dx%d image.",gWIDE, gHIGH);
+
+  pinfo->comment = (char *) NULL;
+
+  grabPic = (byte *) NULL;
+
+  return 1;
+}
+
+
+/***********************************/
 static void flashrect(x,y,w,h,show)
      int x,y,w,h,show;
 {
@@ -373,7 +434,7 @@
   XSetPlaneMask(theDisp, rootGC, xorMasks[maskno]);
 
   if (!show) {     /* turn off rectangle */
-    if (isvis) 
+    if (isvis)
       XDrawRectangle(theDisp, rootW, rootGC, x, y, (u_int) w-1, (u_int) h-1);
 
     isvis = 0;
@@ -391,15 +452,16 @@
 
 /***********************************/
 static void startflash()
-{  
+{
   /* set up for drawing a flashing rectangle */
   XSetFunction(theDisp, rootGC, GXinvert);
   XSetSubwindowMode(theDisp, rootGC, IncludeInferiors);
 }
 
+
 /***********************************/
 static void endflash()
-{  
+{
   XSetFunction(theDisp, rootGC, GXcopy);
   XSetSubwindowMode(theDisp, rootGC, ClipByChildren);
   XSetPlaneMask(theDisp, rootGC, AllPlanes);
@@ -408,21 +470,157 @@
 
 
 /***********************************/
-static int grabImage(clickWin, x, y, w, h)
-     Window clickWin;
+static void ungrabX()
+{
+  XUngrabServer(theDisp);
+  XUngrabButton(theDisp, (u_int) AnyButton, 0, rootW);
+}
+
+
+/**************************************/
+static int lowbitnum(ul)
+     unsigned long ul;
+{
+  /* returns position of lowest set bit in 'ul' as an integer (0-31),
+   or -1 if none */
+
+  int i;
+  for (i=0; ((ul&1) == 0) && i<32;  i++, ul>>=1);
+  if (i==32) i = -1;
+  return i;
+}
+
+
+
+/**********************************************/
+/* getxcolors() function snarfed from 'xwd.c' */
+/**********************************************/
+
+#define lowbit(x) ((x) & (~(x) + 1))
+
+static int getxcolors(win_info, colors)
+     XWindowAttributes *win_info;
+     XColor **colors;
+{
+  int i, ncolors;
+
+  *colors = (XColor *) NULL;
+
+  if (win_info->visual->class == TrueColor) {
+    if (DEBUG>1) fprintf(stderr,"TrueColor visual:  no colormap needed\n");
+    return 0;
+  }
+
+  else if (!win_info->colormap) {
+    if (DEBUG>1) fprintf(stderr,"no colormap associated with window\n");
+    return 0;
+  }
+
+  ncolors = win_info->visual->map_entries;
+  if (DEBUG>1) fprintf(stderr,"%d entries in colormap\n", ncolors);
+
+  if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors)))
+    FatalError("malloc failed in getxcolors()");
+
+
+  if (win_info->visual->class == DirectColor) {
+    Pixel red, green, blue, red1, green1, blue1;
+
+    if (DEBUG>1) fprintf(stderr,"DirectColor visual\n");
+
+    red = green = blue = 0;
+    red1   = lowbit(win_info->visual->red_mask);
+    green1 = lowbit(win_info->visual->green_mask);
+    blue1  = lowbit(win_info->visual->blue_mask);
+    for (i=0; i<ncolors; i++) {
+      (*colors)[i].pixel = red|green|blue;
+      (*colors)[i].pad = 0;
+      red += red1;
+      if (red > win_info->visual->red_mask)     red = 0;
+      green += green1;
+      if (green > win_info->visual->green_mask) green = 0;
+      blue += blue1;
+      if (blue > win_info->visual->blue_mask)   blue = 0;
+    }
+  }
+  else {
+    for (i=0; i<ncolors; i++) {
+      (*colors)[i].pixel = i;
+      (*colors)[i].pad = 0;
+    }
+  }
+
+  XQueryColors(theDisp, win_info->colormap, *colors, ncolors);
+
+  return(ncolors);
+}
+
+
+
+/*******************************************/
+static void printWinTree(win,tab)
+     Window win;
+     int    tab;
+{
+  u_int             i, nchildren;
+  Window            root, parent, *children, chwin;
+  XWindowAttributes xwa;
+  int               xr, yr;
+
+  if (!XGetWindowAttributes(theDisp, win, &xwa)) {
+    errSpace(tab);
+    fprintf(stderr,"pWT: can't XGetWindowAttributes(%08x)\n", (u_int) win);
+    return;
+  }
+
+  XTranslateCoordinates(theDisp, win, rootW, 0,0, &xr,&yr, &chwin);
+  if (xwa.map_state==IsViewable) {
+    errSpace(tab);
+    fprintf(stderr,"%08x: %4d,%4d %4dx%4d vis: %02x  cm=%x  %s\n",
+	    (u_int) win, xr,yr, xwa.width, xwa.height,
+	    (u_int) XVisualIDFromVisual(xwa.visual),
+	    (u_int) xwa.colormap,
+	    ((xwa.map_state==IsUnmapped)      ? "unmapped  "  :
+	     (xwa.map_state==IsUnviewable)    ? "unviewable"  :
+	     (xwa.map_state==IsViewable)      ? "viewable  "  :
+	     "<unknown> ")       );
+
+    if (!XQueryTree(theDisp, win, &root, &parent, &children, &nchildren)) {
+      errSpace(tab);
+      fprintf(stderr,"pWT: XQueryTree(%08x) failed\n", (u_int) win);
+      if (children) XFree((char *)children);
+      return;
+    }
+
+    for (i=0; i<nchildren; i++) printWinTree(children[i], tab+1);
+    if (children) XFree((char *)children);
+  }
+
+  return;
+}
+
+
+/***********************************/
+static void errSpace(n)
+     int n;
+{
+  for ( ; n>0; n--) putc(' ', stderr);
+}
+
+
+
+
+/***********************************/
+static int grabRootRegion(x, y, w, h)
      int    x, y, w, h;
 {
   /* attempts to grab the specified rectangle of the root window
-     returns '1' on success.  clickWin is used to figure out the depth
-     and colormap to use */
+     returns '1' on success */
 
-  XImage *image;
-  XWindowAttributes xwa;
-  XColor *colors;
-  int ncolors, i, ix, iy;
-  char str[256];
-  Window win;
+  XWindowAttributes  xwa;
+  int                i;
 
+  regrabList = (struct rectlist *) NULL;
 
   /* range checking */
   if (x<0) { w += x;  x = 0; }
@@ -430,86 +628,246 @@
   if (x+w>dispWIDE) w = dispWIDE-x;
   if (y+h>dispHIGH) h = dispHIGH-y;
 
-  if (w==0 || h==0) {  /* selected nothing */
+  if (w<=0 || h<=0) {  /* selected nothing */
     ungrabX();
     return 0;
   }
 
-  if (!XGetWindowAttributes(theDisp, clickWin, &xwa)) {
-    sprintf(str,"Unable to get window attributes for clicked-on window\n");
+
+  /* grab this region, using the default (root's) visual */
+
+  /* now for all top-level windows (children of root), in bottom->top order
+     if they intersect the grabregion
+       are they drawn entirely (including children) using default visual+cmap?
+       yes: if they intersect 'regrab' list, grab'em - else skip'em
+       no:  grab them, add their rectangle to 'regrab' list
+   */
+
+
+  /* make a 24bit grabPic */
+  gptype = PIC24;
+  gXOFF = x;  gYOFF = y;  gWIDE = w;  gHIGH = h;
+  grabPic = (byte *) malloc((size_t) gWIDE * gHIGH * 3);
+  if (!grabPic) {
     ungrabX();
-    ErrPopUp(str, "\nThat Sucks!");
+    ErrPopUp("Unable to malloc() space for grabbed image!", "\nBite Me!");
     return 0;
   }
 
-
-  XTranslateCoordinates(theDisp, rootW, clickWin, x, y, &ix, &iy, &win);
-
-  xerrcode = 0;
-  image = XGetImage(theDisp, clickWin, ix, iy, (u_int) w, (u_int) h, 
-		    AllPlanes, ZPixmap);
-  if (xerrcode || !image || !image->data) {
-    sprintf(str, "Unable to get image (%d,%d %dx%d) from display", ix,iy,w,h);
+  if (!XGetWindowAttributes(theDisp, rootW, &xwa)) {
     ungrabX();
-    ErrPopUp(str, "\nThat Sucks!");
+    ErrPopUp("Can't get window attributes for root window!", "\nBite Me!");
     return 0;
   }
 
-  ncolors = getxcolors(&xwa, &colors);
+  i = grabWinImage(rootW, XVisualIDFromVisual(xwa.visual), xwa.colormap,0);
 
   ungrabX();
 
-  if (ncolors && DEBUG) {
-    fprintf(stderr, "Colormap:\n");
-    for (i=0; i<ncolors; i++)
-      fprintf(stderr,"%02x%02x%02x  ",colors[i].red>>8, colors[i].green>>8,
-	      colors[i].blue>>8);
-    fprintf(stderr,"\n");
-  }
-
-
   XBell(theDisp, 0);    /* beep twice at end of grab */
   XBell(theDisp, 0);
 
-  i = convertImage(image, colors, ncolors, &xwa);
+  { /* free regrabList */
+    struct rectlist *rr, *tmprr;
+    rr = regrabList;
+    while (rr) {
+      tmprr = rr->next;
+      free((char *) rr);
+      rr = tmprr;
+    }
+    regrabList = (struct rectlist *) NULL;
+  }
 
-  /* DO *NOT* use xvDestroyImage(), as the 'data' field was alloc'd by X, not
-     necessarily through 'malloc() / free()' */
-  XDestroyImage(image);   
-  
-  if (colors) free((char *) colors);
+  if (i) {
+    ErrPopUp("Warning: Problems occurred during grab.","\nWYSInWYG!");
+    return 0;
+  }
 
-  return i;
+
+  /* if 256 or fewer colors in grabPic, make it a PIC8 */
+  i = CountColors24(grabPic, gWIDE, gHIGH, 0,0,gWIDE,gHIGH);
+  if (i<=256) {
+    byte *pic8;
+    pic8 = (byte *) malloc((size_t) (gWIDE * gHIGH));
+    if (pic8) {
+      if (Trivial24to8(grabPic, gWIDE,gHIGH, pic8,
+		       grabmapR,grabmapG,grabmapB,256)) {
+	free((char *) grabPic);
+	grabPic = pic8;
+	gptype = PIC8;
+      }
+    }
+  }
+
+  return 1;  /* full success */
 }
 
 
-static void ungrabX()
+/***********************************/
+static int grabWinImage(win, parentVid, parentCmap, toplevel)
+     Window win;
+     VisualID           parentVid;
+     Colormap           parentCmap;
+     int                toplevel;
 {
-  XUngrabServer(theDisp);
-  XUngrabButton(theDisp, (u_int) AnyButton, 0, rootW);
-}
+  /* grabs area of window (and its children) that intersects
+   * grab region (root coords: gXOFF,gYOFF,gWIDE,gHIGH), and stuffs
+   * relevant bits into the grabPic (a gWIDE*gHIGH PIC24)
+   *
+   * Note: special kludge for toplevel windows (children of root):
+   * since that's the only case where a window can be obscuring something
+   * that isn't its parent
+   *
+   * returns 0 if okay, 1 if problems occurred
+   */
+
+
+  int               i, rv, dograb;
+  int               wx, wy, ww, wh;      /* root coords of window */
+  int               gx, gy, gw, gh;      /* root coords of grab region of win*/
+  Window            chwin;               /* unused */
+  u_int             nchildren;
+  Window            root, parent, *children;
+  XWindowAttributes xwa;
 
+  /* first, quick checks to avoid recursing down useless branches */
 
+  if (!XGetWindowAttributes(theDisp, win, &xwa)) {
+    if (DEBUG) fprintf(stderr,"gWI: can't get win attr (%08x)\n", (u_int) win);
+    return 1;
+  }
 
+  if (xwa.class == InputOnly || xwa.map_state != IsViewable) return 0;
 
+  rv     = 0;
+  dograb = 1;
+  wx = 0;  wy = 0;  ww = (int) xwa.width;  wh = (int) xwa.height;
+
+  /* if this window doesn't intersect, none of its children will, either */
+  XTranslateCoordinates(theDisp, win, rootW, 0,0, &wx, &wy, &chwin);
+  if (!RectIntersect(wx,wy,ww,wh, gXOFF,gYOFF,gWIDE,gHIGH)) return 0;
+
+  gx = wx;  gy = wy;  gw = ww;  gh = wh;
+  CropRect2Rect(&gx,&gy,&gw,&gh, gXOFF,gYOFF,gWIDE,gHIGH);
+
+  if (win==rootW) {
+    /* always grab */
+  }
+
+  else if (XVisualIDFromVisual(xwa.visual) == parentVid &&
+	   ((xwa.visual->class==TrueColor) || xwa.colormap == parentCmap)) {
+
+    /* note: if both visuals are TrueColor, don't compare cmaps */
+
+    /* normally, if the vis/cmap info of a window is the same as its parent,
+       no need to regrab window.  special case if this is a toplevel
+       window, as it can be obscuring windows that *aren't* its parent */
+
+    if (toplevel) {
+      /* we probably already have this region.  Check it against regrabList
+	 If it intersects none, no need to grab.
+	 If it intersects one,  crop to that rectangle and grab
+	 if it intersects >1,   don't crop, just grab gx,gy,gw,gh */
+
+      struct rectlist *rr, *cr;
+
+      i=0; cr=rr=regrabList;
+      while (rr) {
+	if (RectIntersect(gx,gy,gw,gh, rr->x,rr->y,rr->w,rr->h)) {
+	  i++;  cr = rr;
+	}
+	rr = rr->next;
+      }
+
+      if (i==0) dograb=0;   /* no need to grab */
+
+      if (i==1) CropRect2Rect(&gx,&gy,&gw,&gh, cr->x,cr->y,cr->w,cr->h);
+    }
+    else dograb = 0;
+  }
+
+  else {
+    /* different vis/cmap from parent:
+       add to regrab list, if not already fully contained in list */
+    struct rectlist *rr;
+
+    /* check to see if fully contained... */
+    rr=regrabList;
+    while (rr && RectIntersect(gx,gy,gw,gh, rr->x,rr->y,rr->w,rr->h)!=2)
+      rr = rr->next;
+
+    if (!rr) {   /* add to list */
+      if (DEBUG)
+	fprintf(stderr,"added to regrabList: %d,%d %dx%d\n",gx,gy,gw,gh);
+
+      rr = (struct rectlist *) malloc(sizeof(struct rectlist));
+      if (!rr) return 1;
+      else {
+	rr->x = gx;  rr->y = gy;  rr->w = gw;  rr->h = gh;
+	rr->next = regrabList;
+	regrabList = rr;
+      }
+    }
+  }
+
+  /* at this point, we have to grab gx,gy,gw,gh from 'win' */
+
+  if (dograb) {
+    int     ix, iy, ncolors;
+    XColor *colors;
+    XImage *image;
+
+    XTranslateCoordinates(theDisp, rootW, win, gx, gy, &ix, &iy, &chwin);
+
+    if (DEBUG)
+      fprintf(stderr,"Grabbing win (%08x) %d,%d %dx%d\n",
+	      (u_int) win, gx,gy,gw,gh);
+
+    WaitCursor();
+
+    xerrcode = 0;
+    image = XGetImage(theDisp, win, ix, iy, (u_int) gw, (u_int) gh,
+		      AllPlanes, ZPixmap);
+    if (xerrcode || !image || !image->data) return 1;
+
+    ncolors = getxcolors(&xwa, &colors);
+    rv = convertImageAndStuff(image, colors, ncolors, &xwa,
+			      gx - gXOFF, gy - gYOFF, gw, gh);
+    XDestroyImage(image);   /* can't use xvDestroyImage: alloc'd by X! */
+    if (colors) free((char *) colors);
+  }
+
+
+  /* recurse into children to see if any of them are 'different'... */
+
+  if (!XQueryTree(theDisp, win, &root, &parent, &children, &nchildren)) {
+    if (DEBUG) fprintf(stderr,"XQueryTree(%08x) failed\n", (u_int) win);
+    if (children) XFree((char *)children);
+    return rv+1;
+  }
+
+  for (i=0; i<nchildren; i++) {
+    rv += grabWinImage(children[i], XVisualIDFromVisual(xwa.visual),
+		       xwa.colormap, (win==rootW));
+  }
+  if (children) XFree((char *)children);
+
+  return rv;
+}
 
-union swapun {
-  CARD32 l;
-  CARD16 s;
-  CARD8  b[sizeof(CARD32)];
-};
 
 
 /**************************************/
-static int convertImage(image, colors, ncolors, xwap)
+static int convertImageAndStuff(image, colors, ncolors, xwap, gx,gy,gw,gh)
      XImage *image;
      XColor *colors;
      int     ncolors;
      XWindowAttributes *xwap;
+     int     gx,gy,gw,gh;      /* position within grabPic (guaranteed OK) */
 {
-  /* attempts to conver the image from whatever weird-ass format it might
-     be in into something E-Z to deal with (either an 8-bit colormapped
-     image, or a 24-bit image).  Returns '1' on success. */
+  /* attempts to convert the image from whatever weird-ass format it might
+     be in into a 24-bit RGB image, and stuff it into grabPic
+     Returns 0 on success, 1 on failure */
 
   /* this code owes a lot to 'xwdtopnm.c', part of the pbmplus package,
      written by Jef Poskanzer */
@@ -528,7 +886,6 @@
   int            isLsbMachine, flipBytes;
   Visual         *visual;
   char            errstr[256];
-  static char    *foo[] = { "\nThat Sucks!" };
 
 
   /* quiet compiler warnings */
@@ -538,20 +895,20 @@
   pixvalue  = 0;
   rmask  = gmask  = bmask = 0;
   rshift = gshift = bshift = 0;
-
+  r8shift = g8shift = b8shift = 0;
 
   /* determine byte order of the machine we're running on */
   sw.l = 1;
   isLsbMachine = (sw.b[0]) ? 1 : 0;
 
-  if (xwap && xwap->visual) visual = xwap->visual;
-                       else visual = theVisual;
+  visual = xwap->visual;
+
 
-  if (DEBUG) {
+  if (DEBUG>1) {
     fprintf(stderr,"convertImage:\n");
     fprintf(stderr,"  %dx%d (offset %d), %s\n",
-	    image->width, image->height, image->xoffset, 
-	    (image->format == XYBitmap || image->format == XYPixmap) 
+	    image->width, image->height, image->xoffset,
+	    (image->format == XYBitmap || image->format == XYPixmap)
 	    ? "XYPixmap" : "ZPixmap");
 
     fprintf(stderr,"byte_order = %s, bitmap_bit_order = %s, unit=%d, pad=%d\n",
@@ -575,41 +932,17 @@
     sprintf(errstr, "%s\nReturned image bitmap_unit (%d) non-standard.",
 	    "Can't deal with this display.", image->bitmap_unit);
     ErrPopUp(errstr, "\nThat Sucks!");
-    return 0;
+    return 1;
   }
 
   if (!ncolors && visual->class != TrueColor) {
     sprintf(errstr, "%s\nOnly TrueColor displays can have no colormap.",
 	    "Can't deal with this display.");
     ErrPopUp(errstr, "\nThat Sucks!");
-    return 0;
+    return 1;
   }
 
 
-  /* build the 'global' grabPic stuff */
-  gWIDE = image->width;  gHIGH = image->height;
-
-  if (visual->class == TrueColor || visual->class == DirectColor ||
-      ncolors > 256) {
-    grabPic = (byte *) malloc((size_t) gWIDE * gHIGH * 3);
-    gbits = 24;
-  }
-  else {
-    grabPic = (byte *) malloc((size_t) gWIDE * gHIGH);
-    gbits = 8;
-
-    /* load up the colormap */
-    for (i=0; i<ncolors; i++) {
-      grabmapR[i] = colors[i].red   >> 8;
-      grabmapG[i] = colors[i].green >> 8;
-      grabmapB[i] = colors[i].blue  >> 8;
-    }
-  }
-  
-  if (!grabPic) FatalError("unable to malloc grabPic in convertImage()");
-  pptr = grabPic;
-
-
   if (visual->class == TrueColor || visual->class == DirectColor) {
     unsigned int tmp;
 
@@ -634,16 +967,35 @@
     while (tmp >= 256) { tmp >>= 1;  b8shift -= 1; }
     while (tmp < 128)  { tmp <<= 1;  b8shift += 1; }
 
-    if (DEBUG)
+    if (DEBUG>1)
       fprintf(stderr,"True/DirectColor: shifts=%d,%d,%d  8shifts=%d,%d,%d\n",
 	      rshift, gshift, bshift, r8shift, g8shift, b8shift);
   }
 
 
-  bits_per_item = image->bitmap_unit;
-  bits_used = bits_per_item;
+  bits_per_item  = image->bitmap_unit;
   bits_per_pixel = image->bits_per_pixel;
 
+
+  /* add code for freako 'exceed' server, where bitmapunit = 8
+     and bitsperpix = 32 (and depth=24)... */
+
+  if (bits_per_item < bits_per_pixel) {
+    bits_per_item = bits_per_pixel;
+
+    /* round bits_per_item up to next legal value, if necc */
+    if      (bits_per_item <  8) bits_per_item = 8;
+    else if (bits_per_item < 16) bits_per_item = 16;
+    else                         bits_per_item = 32;
+  }
+
+
+  /* which raises the question:  how (can?) you ever have a 24 bits per pix,
+     (ie, 3 bytes, no alpha/padding) */
+
+
+  bits_used = bits_per_item;  /* so it will get a new item first time */
+
   if (bits_per_pixel == 32) pixmask = 0xffffffff;
   else pixmask = (((CARD32) 1) << bits_per_pixel) - 1;
 
@@ -652,14 +1004,15 @@
 
   /* if we're on an lsbfirst machine, or the image came from an lsbfirst
      machine, we should flip the bytes around.  NOTE:  if we're on an
-     lsbfirst machine *and* the image came from an lsbfirst machine, 
+     lsbfirst machine *and* the image came from an lsbfirst machine,
      *don't* flip bytes, as it should work out */
 
-  /* pity we don't have a logical exclusive-or */
   flipBytes = ( isLsbMachine && byte_order != LSBFirst) ||
               (!isLsbMachine && byte_order == LSBFirst);
 
   for (i=0; i<image->height; i++) {
+    pptr = grabPic + ((i+gy) * gWIDE + gx) * 3;
+
     lineptr = (byte *) image->data + (i * image->bytes_per_line);
     bptr = ((CARD8  *) lineptr) - 1;
     sptr = ((CARD16 *) lineptr) - 1;
@@ -667,35 +1020,39 @@
     bits_used = bits_per_item;
 
     for (j=0; j<image->width; j++) {
-      
       /* get the next pixel value from the image data */
 
       if (bits_used == bits_per_item) {  /* time to move on to next b/s/l */
 	switch (bits_per_item) {
-	case 8:  bptr++;  break;
-	case 16: sptr++;  sval = *sptr;
-	         if (flipBytes) {   /* swap CARD16 */
-		   sw.s = sval;
-		   tmpbyte = sw.b[0];
-		   sw.b[0] = sw.b[1];
-		   sw.b[1] = tmpbyte;
-		   sval = sw.s;
-		 }
-	         break;
-	case 32: lptr++;  lval = *lptr;
-	         if (flipBytes) {   /* swap CARD32 */
-		   sw.l = lval;
-		   tmpbyte = sw.b[0];
-		   sw.b[0] = sw.b[3];
-		   sw.b[3] = tmpbyte;
-		   tmpbyte = sw.b[1];
-		   sw.b[1] = sw.b[2];
-		   sw.b[2] = tmpbyte;
-		   lval = sw.l;
-		 }
-	         break;
+	case 8:
+	  bptr++;  break;
+
+	case 16:
+	  sptr++;  sval = *sptr;
+	  if (flipBytes) {   /* swap CARD16 */
+	    sw.s = sval;
+	    tmpbyte = sw.b[0];
+	    sw.b[0] = sw.b[1];
+	    sw.b[1] = tmpbyte;
+	    sval = sw.s;
+	  }
+	  break;
+
+	case 32:
+	  lptr++;  lval = *lptr;
+	  if (flipBytes) {   /* swap CARD32 */
+	    sw.l = lval;
+	    tmpbyte = sw.b[0];
+	    sw.b[0] = sw.b[3];
+	    sw.b[3] = tmpbyte;
+	    tmpbyte = sw.b[1];
+	    sw.b[1] = sw.b[2];
+	    sw.b[2] = tmpbyte;
+	    lval = sw.l;
+	  }
+	  break;
 	}
-		   
+
 	bits_used = 0;
 	if (bit_order == MSBFirst) bit_shift = bits_per_item - bits_per_pixel;
 	                      else bit_shift = 0;
@@ -711,11 +1068,11 @@
                             else bit_shift += bits_per_pixel;
       bits_used += bits_per_pixel;
 
-      
+
       /* okay, we've got the next pixel value in 'pixvalue' */
-      
+
       if (visual->class == TrueColor || visual->class == DirectColor) {
-	/* in either case, we have to take the pixvalue and 
+	/* in either case, we have to take the pixvalue and
 	   break it out into individual r,g,b components */
 	rval = (pixvalue & rmask) >> rshift;
 	gval = (pixvalue & gmask) >> gshift;
@@ -741,212 +1098,165 @@
 	/* use pixel value as an index into colors array */
 
 	if (pixvalue >= ncolors) {
-	  FatalError("convertImage(): pixvalue >= ncolors");
+	  fprintf(stderr, "WARNING: convertImage(): pixvalue >= ncolors\n");
+	  return 1;
 	}
 
-	if (gbits == 24) {   /* too many colors for 8-bit colormap */
-	  *pptr++ = (colors[pixvalue].red)   >> 8;
-	  *pptr++ = (colors[pixvalue].green) >> 8;
-	  *pptr++ = (colors[pixvalue].blue)  >> 8;
-	}
-	else *pptr++ = pixvalue & 0xff;
-
+	*pptr++ = (colors[pixvalue].red)   >> 8;
+	*pptr++ = (colors[pixvalue].green) >> 8;
+	*pptr++ = (colors[pixvalue].blue)  >> 8;
       }
     }
   }
 
-  return 1;
+  return 0;
 }
 
 
 
-/**************************************/
-static int lowbitnum(ul)
-     unsigned long ul;
+/***********************************/
+static int RectIntersect(ax,ay,aw,ah, bx,by,bw,bh)
+     int ax,ay,aw,ah, bx,by,bw,bh;
 {
-  /* returns position of lowest set bit in 'ul' as an integer (0-31),
-   or -1 if none */
+  /* returns 0 if rectangles A and B do not intersect
+     returns 1 if A partially intersects B
+     returns 2 if rectangle A is fully enclosed by B */
 
-  int i;
-  for (i=0; ((ul&1) == 0) && i<32;  i++, ul>>=1);
-  if (i==32) i = -1;
-  return i;
-}
+  int ax1,ay1, bx1,by1;
 
+  ax1 = ax+aw-1;  ay1 = ay+ah-1;
+  bx1 = bx+bw-1;  by1 = by+bh-1;
 
+  if (ax1<bx || ax>bx1 || ay1<by || ay>by1) return 0;
 
-/**************************************/
-/* following code snarfed from 'xwd.c' */
-/**************************************/
+  if (ax>=bx && ax1<=bx1 && ay>=by && ay1<=by) return 2;
 
-#define lowbit(x) ((x) & (~(x) + 1))
-
-
-static int getxcolors(win_info, colors)
-     XWindowAttributes *win_info;
-     XColor **colors;
-{
-  int i, ncolors;
-  Colormap cmap;
-
-  *colors = (XColor *) NULL;
+  return 1;
+}
 
-  if (win_info->visual->class == TrueColor) {
-    if (DEBUG) fprintf(stderr,"TrueColor visual:  no colormap needed\n");
-    return 0;
-  }
 
-  else if (!win_info->colormap) {
-    if (DEBUG) fprintf(stderr,"no colormap associated with window\n");
-    return 0;
-  }
 
-  ncolors = win_info->visual->map_entries;
-  if (DEBUG) fprintf(stderr,"%d entries in colormap\n", ncolors);
 
-  if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors)))
-    FatalError("malloc failed in getxcolors()");
 
+/** stuff needed to make new xvgrab work in 3.10a. **/
 
-  if (win_info->visual->class == DirectColor) {
-    Pixel red, green, blue, red1, green1, blue1;
+/********************************************/
+static int CountColors24(pic, pwide, phigh, x, y, w, h)
+     byte *pic;
+     int   pwide, phigh, x,y,w,h;
+{
+  /* counts the # of unique colors in a selected rect of a PIC24
+     returns '0-256' or >256 */
 
-    if (DEBUG) fprintf(stderr,"DirectColor visual\n");
+  int    i, j, nc;
+  int    low, high, mid;
+  u_int  colors[257], col;
+  byte   *pp;
+
+  nc = 0;
+
+  for (i=y; nc<257 && i<y+h; i++) {
+    pp = pic + (i*pwide + x)*3;
+
+    for (j=x; nc<257 && j<x+w; j++, pp+=3) {
+      col = (((u_int) pp[0])<<16) + (((u_int) pp[1])<<8) + pp[2];
+
+      /* binary search the 'colors' array to see if it's in there */
+      low = 0;  high = nc-1;
+      while (low <= high) {
+	mid = (low+high)/2;
+	if      (col < colors[mid]) high = mid - 1;
+	else if (col > colors[mid]) low  = mid + 1;
+	else break;
+      }
 
-    red = green = blue = 0;
-    red1   = lowbit(win_info->visual->red_mask);
-    green1 = lowbit(win_info->visual->green_mask);
-    blue1  = lowbit(win_info->visual->blue_mask);
-    for (i=0; i<ncolors; i++) {
-      (*colors)[i].pixel = red|green|blue;
-      (*colors)[i].pad = 0;
-      red += red1;
-      if (red > win_info->visual->red_mask)     red = 0;
-      green += green1;
-      if (green > win_info->visual->green_mask) green = 0;
-      blue += blue1;
-      if (blue > win_info->visual->blue_mask)   blue = 0;
-    }
-  }
-  else {
-    for (i=0; i<ncolors; i++) {
-      (*colors)[i].pixel = i;
-      (*colors)[i].pad = 0;
+      if (high < low) { /* didn't find color in list, add it. */
+	xvbcopy((char *) &colors[low], (char *) &colors[low+1],
+		(nc - low) * sizeof(u_int));
+	colors[low] = col;
+	nc++;
+      }
     }
   }
 
-  XQueryColors(theDisp, win_info->colormap, *colors, ncolors);
-
-  return(ncolors);
+  return nc;
 }
-    
-
 
 
-
-/***********************************/
-int LoadGrab(pinfo)
-     PICINFO *pinfo;
+/****************************/
+static int Trivial24to8(pic24, w,h, pic8, rmap,gmap,bmap, maxcol)
+     byte *pic24, *pic8, *rmap, *gmap, *bmap;
+     int   w,h,maxcol;
 {
-  /* loads up (into XV structures) last image successfully grabbed.
-     returns '0' on failure, '1' on success */
-
-  int   i;
-
-  if (!grabPic) return 0;   /* no image to use */
-
-  if (gbits == 24) pinfo->type = PIC24;
-  else {
-    pinfo->type = PIC8;
+  /* scans picture until it finds more than 'maxcol' different colors.  If it
+     finds more than 'maxcol' colors, it returns '0'.  If it DOESN'T, it does
+     the 24-to-8 conversion by simply sticking the colors it found into
+     a colormap, and changing instances of a color in pic24 into colormap
+     indicies (in pic8) */
+
+  unsigned long colors[256],col;
+  int           i, nc, low, high, mid;
+  byte         *p, *pix;
+
+  if (maxcol>256) maxcol = 256;
+
+  /* put the first color in the table by hand */
+  nc = 0;  mid = 0;
+
+  for (i=w*h,p=pic24; i; i--) {
+    col  = (((u_long) *p++) << 16);
+    col += (((u_long) *p++) << 8);
+    col +=  *p++;
+
+    /* binary search the 'colors' array to see if it's in there */
+    low = 0;  high = nc-1;
+    while (low <= high) {
+      mid = (low+high)/2;
+      if      (col < colors[mid]) high = mid - 1;
+      else if (col > colors[mid]) low  = mid + 1;
+      else break;
+    }
 
-    for (i=0; i<256; i++) {
-      pinfo->r[i] = grabmapR[i];
-      pinfo->g[i] = grabmapG[i];
-      pinfo->b[i] = grabmapB[i];
+    if (high < low) { /* didn't find color in list, add it. */
+      if (nc>=maxcol) return 0;
+      xvbcopy((char *) &colors[low], (char *) &colors[low+1],
+	      (nc - low) * sizeof(u_long));
+      colors[low] = col;
+      nc++;
     }
   }
 
-  pinfo->pic     = grabPic;
-  pinfo->normw   = pinfo->w   = gWIDE;
-  pinfo->normh   = pinfo->h   = gHIGH;
-  pinfo->frmType = -1;
-  pinfo->colType = -1;
 
-  sprintf(pinfo->fullInfo,"<%s internal>", 
-	  (pinfo->type == PIC8) ? "8-bit" : "24-bit");
-  
-  sprintf(pinfo->shrtInfo,"%dx%d image.",gWIDE, gHIGH);
-  
-  pinfo->comment = (char *) NULL;
+  /* run through the data a second time, this time mapping pixel values in
+     pic24 into colormap offsets into 'colors' */
 
-  grabPic = (byte *) NULL;
-
-  return 1;
-}
-
-
-
-
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
-static Window TryChildren PARM((Display *, Window, Atom));
-
-/* Find a window with WM_STATE, else return '0' */
-
-static Window xvClientWindow (dpy, win)
-    Display *dpy;
-    Window win;
-{
-    Atom WM_STATE;
-    Atom type = None;
-    int format;
-    unsigned long nitems, after;
-    unsigned char *data;
-    Window inf;
-
-    WM_STATE = XInternAtom(dpy, "WM_STATE", True);
-    if (!WM_STATE) return win;
-
-    XGetWindowProperty(dpy, win, WM_STATE, 0L, 0L, False, AnyPropertyType,
-		       &type, &format, &nitems, &after, &data);
-    if (type) return win;
-
-    inf = TryChildren(dpy, win, WM_STATE);
-
-    return inf;
-}
-
-static Window TryChildren (dpy, win, WM_STATE)
-    Display *dpy;
-    Window win;
-    Atom WM_STATE;
-{
-    Window root, parent;
-    Window *children;
-    unsigned int nchildren;
-    unsigned int i;
-    Atom type = None;
-    int format;
-    unsigned long nitems, after;
-    unsigned char *data;
-    Window inf = 0;
-
-    if (!XQueryTree(dpy, win, &root, &parent, &children, &nchildren))
-	return 0;
+  for (i=w*h,p=pic24, pix=pic8; i; i--,pix++) {
+    col  = (((u_long) *p++) << 16);
+    col += (((u_long) *p++) << 8);
+    col +=  *p++;
+
+    /* binary search the 'colors' array.  It *IS* in there */
+    low = 0;  high = nc-1;
+    while (low <= high) {
+      mid = (low+high)/2;
+      if      (col < colors[mid]) high = mid - 1;
+      else if (col > colors[mid]) low  = mid + 1;
+      else break;
+    }
 
-    for (i = 0; !inf && (i < nchildren); i++) {
-	XGetWindowProperty(dpy, children[i], WM_STATE, 0L, 0L, False,
-			   AnyPropertyType, &type, &format, &nitems,
-			   &after, &data);
-	if (type)
-	  inf = children[i];
+    if (high < low) {
+      fprintf(stderr,"Trivial24to8:  impossible situation!\n");
+      exit(1);
     }
+    *pix = mid;
+  }
 
-    for (i = 0; !inf && (i < nchildren); i++)
-      inf = TryChildren(dpy, children[i], WM_STATE);
+  /* and load up the 'desired colormap' */
+  for (i=0; i<nc; i++) {
+    rmap[i] =  colors[i]>>16;
+    gmap[i] = (colors[i]>>8) & 0xff;
+    bmap[i] =  colors[i]     & 0xff;
+  }
 
-    if (children) XFree((char *)children);
-    return inf;
+  return 1;
 }
diff -ru xv-3.10a/xvgraf.c xv-3.10a-enhancements/xvgraf.c
--- xv-3.10a/xvgraf.c	1994-12-22 14:34:42.000000000 -0800
+++ xv-3.10a-enhancements/xvgraf.c	2007-05-12 14:03:08.000000000 -0700
@@ -1,4 +1,4 @@
-/* 
+/*
  * xvgraf.c - GRAF window handling functions
  *
  * callable functions:
@@ -52,7 +52,7 @@
      Window parent;
      int x,y;
      unsigned long fg,bg;
-     char *title;
+     const char *title;
 {
   /* NOTE:  CreateGraf does not initialize hands[], nhands, or spline,
      as these could be initialized by X resources (or whatever),
@@ -88,7 +88,7 @@
   gp->win = XCreateSimpleWindow(theDisp, parent, x,y, GWIDE, GHIGH, 1, fg,bg);
   if (!gp->win) FatalError("can't create graph (main) window");
 
-  gp->gwin = XCreateSimpleWindow(theDisp, gp->win, 2, GHIGH-132, 
+  gp->gwin = XCreateSimpleWindow(theDisp, gp->win, 2, GHIGH-132,
 				 128, 128, 1, fg,bg);
   if (!gp->gwin) FatalError("can't create graph (sub) window");
 
@@ -96,7 +96,7 @@
     BTCreate(&gp->butts[i], gp->win, GWIDE-GBWIDE-2, 1+i * (GBHIGH + 1),
 	     GBWIDE, GBHIGH, (char *) NULL, fg, bg, hicol, locol);
     gp->butts[i].pix = gfbpix[i];
-    gp->butts[i].pw = PW;  
+    gp->butts[i].pw = PW;
     gp->butts[i].ph = PH;
   }
 
@@ -132,7 +132,7 @@
 
   gp->gammamode = 0;     gp->gamma = 1.0;
 }
-  
+
 
 /***************************************************/
 void RedrawGraf(gp, gwin)
@@ -148,7 +148,7 @@
   else {
     Draw3dRect(gp->win, 0,0, GWIDE-1, GHIGH-1, R3D_OUT, 1, hicol, locol,
 	       gp->bg);
-    
+
     XSetForeground(theDisp, theGC, gp->fg);
     XSetBackground(theDisp, theGC, gp->bg);
     DrawString(gp->win, 2, 1+ASCENT, gp->str);
@@ -165,11 +165,11 @@
 {
   int i,x,y;
   XPoint  pts[129], *pt;
-  
+
 
   if (gp->entergamma) {
-    char *str1 = "Enter gamma";
-    char *str2 = "value: ";
+    const char *str1 = "Enter gamma";
+    const char *str2 = "value: ";
 
     XSetForeground(theDisp, theGC, gp->fg);
     XSetBackground(theDisp, theGC, gp->bg);
@@ -181,15 +181,15 @@
     x = 10 + StringWidth(str2) + 8;
     y = 30 + ASCENT + CHIGH + 3;
     i = StringWidth(gp->gvstr);
-    if (gp->entergamma < 0 && strlen(gp->gvstr)) { 
+    if (gp->entergamma < 0 && strlen(gp->gvstr)) {
       /* show string highlited */
       XFillRectangle(theDisp, gp->gwin, theGC, x-1, y-ASCENT-1,
 		     (u_int) i+2, (u_int) CHIGH+2);
       XSetForeground(theDisp, theGC, gp->bg);
     }
-    else 
+    else
       XDrawLine(theDisp, gp->gwin, theGC, x+i, y-ASCENT, x+i, y+DESCENT);
-      
+
     DrawString(gp->gwin, x,y, gp->gvstr);
 
     return;
@@ -267,7 +267,7 @@
     if (i<N_GFB) {  /* found one */
       if (BTTrack(bp)) {  /* it was selected */
 	switch (i) {
-	case GFB_SPLINE: 
+	case GFB_SPLINE:
 	case GFB_LINE:
 	  gp->gammamode = 0;
 
@@ -312,7 +312,7 @@
 	  if (gp->nhands < MAX_GHANDS) {
 	    /* find largest x-gap in handles, put new handle in mid */
 	    int lgap, lpos, x, y;
-	    
+
 	    lgap = gp->hands[1].x - gp->hands[0].x;
 	    lpos = 1;
 	    for (j=1; j<gp->nhands-1; j++)
@@ -320,11 +320,11 @@
 		lgap = gp->hands[j+1].x - gp->hands[j].x;
 		lpos = j+1;
 	      }
-	  
+
 	    /* open up position in hands[] array */
-	    xvbcopy((char *) &gp->hands[lpos], (char *) &gp->hands[lpos+1], 
+	    xvbcopy((char *) &gp->hands[lpos], (char *) &gp->hands[lpos+1],
 		    (gp->nhands - lpos) * sizeof(XPoint));
-	  
+
 	    x = gp->hands[lpos-1].x + lgap/2;
 	    y = gp->func[x];
 	    gp->hands[lpos].x = x;
@@ -343,7 +343,7 @@
 	      BTSetActive(&gp->butts[GFB_DELH], 1);
 	  }
 	  break;
-		       
+
 	case GFB_DELH:
 	  if (gp->nhands > 2) {
 	    /* find (middle) point whose x-distance to previous
@@ -361,9 +361,9 @@
 		mdist = dist;  mpos = j;
 	      }
 	    }
-		       
+
 	    /* delete position 'mpos' in hands[] array */
-	    xvbcopy((char *) &gp->hands[mpos+1], (char *) &gp->hands[mpos], 
+	    xvbcopy((char *) &gp->hands[mpos+1], (char *) &gp->hands[mpos],
 		    (gp->nhands-mpos-1) * sizeof(XPoint));
 
 	    gp->nhands--;
@@ -408,16 +408,16 @@
 
 	/* keep original mouse position in 'mx,my', and warp mouse to center
 	   of screen */
-	grab = !XGrabPointer(theDisp, gp->gwin, False, 0, GrabModeAsync, 
+	grab = !XGrabPointer(theDisp, gp->gwin, False, 0, GrabModeAsync,
 			  GrabModeAsync, None, inviso, (Time) CurrentTime);
-	XWarpPointer(theDisp, None, rootW, 0,0,0,0, 
+	XWarpPointer(theDisp, None, rootW, 0,0,0,0,
 		     (int) dispWIDE/2, (int) dispHIGH/2);
 
-	origx = dispWIDE/2;  origy = dispHIGH/2;  
+	origx = dispWIDE/2;  origy = dispHIGH/2;
 	orighx = gp->hands[h].x;  orighy = gp->hands[h].y;
 
 	gp->gammamode = 0;
-	offx = gp->hands[h].x - origx;  
+	offx = gp->hands[h].x - origx;
 	offy = gp->hands[h].y - origy;
 
 	vertonly = (h==0 || h==(gp->nhands-1));
@@ -434,7 +434,7 @@
 
 	  dx = x - origx;  dy = origy - y;   /* flip y axis */
 
-	  /* new (virt) position of handle is (desired) 
+	  /* new (virt) position of handle is (desired)
 	     orighx + dx, orighy + dy */
 
 	  if (!vertonly) { /* keep this handle between its neighbors */
@@ -448,7 +448,7 @@
 	  if (newx != gp->hands[h].x || newy != gp->hands[h].y) {
 	    /* this handle has moved... */
 	    XSetForeground(theDisp, theGC, gp->bg);
-	    XFillRectangle(theDisp, gp->gwin, theGC, 
+	    XFillRectangle(theDisp, gp->gwin, theGC,
 		     (gp->hands[h].x/2)-3, ((255-gp->hands[h].y)/2)-3, 7,7);
 
 	    gp->hands[h].x = newx;  gp->hands[h].y = newy;
@@ -464,7 +464,7 @@
 	}
 
 	drawHandPos(gp, -1);
-	XWarpPointer(theDisp, None, gp->gwin, 0,0,0,0, 
+	XWarpPointer(theDisp, None, gp->gwin, 0,0,0,0,
 		     gp->hands[h].x/2, (255-gp->hands[h].y)/2);
 	if (grab) XUngrabPointer(theDisp, (Time) CurrentTime);
       }
@@ -480,24 +480,24 @@
      int   hnum;
 {
   int w;
-  char *tstr = "888,888";
-  
+  const char *tstr = "888,888";
+
   /* if hnum < 0, clears the text area */
-  
+
   XSetFont(theDisp, theGC, monofont);
   w = XTextWidth(monofinfo, tstr, (int) strlen(tstr));
 
-  if (hnum >= 0) sprintf(str,"%3d,%3d",gp->hands[hnum].x,gp->hands[hnum].y);
-            else sprintf(str,"       ");
+  if (hnum >= 0) sprintf(dummystr,"%3d,%3d",gp->hands[hnum].x,gp->hands[hnum].y);
+            else sprintf(dummystr,"       ");
 
   XSetForeground(theDisp, theGC, gp->fg);
   XSetBackground(theDisp, theGC, gp->bg);
-  XDrawImageString(theDisp, gp->win, theGC, 130-w, 1+ASCENT, 
-		   str, (int) strlen(str));
+  XDrawImageString(theDisp, gp->win, theGC, 130-w, 1+ASCENT,
+		   dummystr, (int) strlen(dummystr));
 
   XSetFont(theDisp, theGC, mfont);
 }
-  
+
 
 /***************************************************/
 int GrafKey(gp,str)
@@ -518,7 +518,7 @@
   }
 
   while (*str) {
-    if (gp->entergamma == -1 && 
+    if (gp->entergamma == -1 &&
 	(*str != '\012' && *str != '\015' && *str != '\033')) {
       gp->entergamma = 1;
       gp->gvstr[0] = '\0';
@@ -529,7 +529,7 @@
     len = strlen(gp->gvstr);
 
     if (*str>= '0' && *str <= '9') {
-      if (len < GVMAX) { 
+      if (len < GVMAX) {
 	gp->gvstr[len++] = *str;
   	gp->gvstr[len] = '\0';
 	ok = 1;
@@ -607,18 +607,18 @@
 
   /* do sanity check.  (x-coords must be sorted (strictly increasing)) */
 
-  for (i=0; i<gp->nhands; i++) { 
-    RANGE(gp->hands[i].x, 0, 255); 
+  for (i=0; i<gp->nhands; i++) {
+    RANGE(gp->hands[i].x, 0, 255);
     RANGE(gp->hands[i].y, 0, 255);
   }
 
   gp->hands[0].x = 0;  gp->hands[gp->nhands-1].x = 255;
   for (i=1; i<gp->nhands-1; i++) {
     if (gp->hands[i].x < i)  gp->hands[i].x = i;
-    if (gp->hands[i].x > 256-gp->nhands+i)  
+    if (gp->hands[i].x > 256-gp->nhands+i)
         gp->hands[i].x = 256-gp->nhands+i;
 
-    if (gp->hands[i].x <= gp->hands[i-1].x) 
+    if (gp->hands[i].x <= gp->hands[i-1].x)
       gp->hands[i].x = gp->hands[i-1].x + 1;
   }
 
@@ -647,17 +647,17 @@
     else {   /* gp->gamma == 0.0 */
       for (i=0; i<256; i++) gp->func[i] = 0;
     }
-      
-    
+
+
     for (i=0; i<gp->nhands; i++) {
       gp->hands[i].y = gp->func[gp->hands[i].x];
     }
   }
-   
+
   else if (!gp->spline) {  /* do linear interpolation */
       int y,x1,y1,x2,y2;
       double yd;
-      
+
       for (i=0; i<gp->nhands-1; i++) {
 	x1 = gp->hands[ i ].x;  y1 = gp->hands[ i ].y;
 	x2 = gp->hands[i+1].x;  y2 = gp->hands[i+1].y;
@@ -676,12 +676,12 @@
     double yf[MAX_GHANDS];
     double yd;
 
-    for (i=0; i<gp->nhands; i++) { 
+    for (i=0; i<gp->nhands; i++) {
       x[i] = gp->hands[i].x;  y[i] = gp->hands[i].y;
     }
-    
+
     InitSpline(x, y, gp->nhands, yf);
-  
+
     for (i=0; i<256; i++) {
       yd = EvalSpline(x, y, yf, gp->nhands, (double) i);
       j = (int) floor(yd + 0.5);
@@ -729,8 +729,8 @@
 
 /*********************/
 int Str2Graf(gp, str)
-GRAF_STATE *gp;
-char *str;
+     GRAF_STATE *gp;
+     const char *str;
 {
   /* parses strings of the form: "S 3 : 0,0 : 63,63 : 255,255",
      (meaning SPLINE, 3 points, and the 3 sets of handle coordinates)
@@ -744,14 +744,15 @@
      thing tends to break optimizers */
 
   char   tstr[256], tstr1[256], *sp, *dp;
+  const char *csp;
   XPoint coords[MAX_GHANDS];
   int    spline, nhands, i, x, y;
 
   if (!str) return 1;  /* NULL strings don't parse well! */
 
   /* first, strip all pesky whitespace from str */
-  for (sp=str, dp=tstr; *sp; sp++) 
-    if (*sp > ' ') { *dp = *sp;  dp++; }
+  for (csp=str, dp=tstr; *csp; csp++)
+    if (*csp > ' ') { *dp = *csp;  dp++; }
   *dp = '\0';
 
   /* check for 'gamma'-style str */
@@ -761,10 +762,10 @@
       gp->gammamode = 1;
       sprintf(gp->gvstr, "%.5g", gp->gamma);
       return 0;
-      }
+    }
     else return 1;
   }
-    
+
   /* read Spline, or Line (S/L) character */
   sp = tstr;
   if      (*sp == 'S' || *sp == 's') spline = 1;
@@ -784,7 +785,7 @@
     while (*sp && *sp != ':') {*dp = *sp;  dp++;  sp++; }
     *dp++ = '\0';
     if (sscanf(tstr1,"%d,%d",&x, &y) != 2) return 1;
-    if (x < 0 || x > 255 || 
+    if (x < 0 || x > 255 ||
 	y < 0 || y > 255) return 1;  /* out of range */
     coords[i].x = x;  coords[i].y = y;
   }
@@ -837,7 +838,7 @@
   IFSET(gp->gamma,      gsp->gamma);
   IFSET(gp->nhands,     gsp->nhands);
 
-  if (strcmp(gp->gvstr, gsp->gvstr)) 
+  if (strcmp(gp->gvstr, gsp->gvstr))
     { strcpy(gp->gvstr, gsp->gvstr);  rv++; }
 
   for (i=0; i<gp->nhands; i++) {
@@ -880,7 +881,7 @@
     sig = ((double) x[i]-x[i-1]) / ((double) x[i+1] - x[i-1]);
     p = sig * y2[i-1] + 2.0;
     y2[i] = (sig-1.0) / p;
-    u[i] = (((double) y[i+1]-y[i]) / (x[i+1]-x[i])) - 
+    u[i] = (((double) y[i+1]-y[i]) / (x[i+1]-x[i])) -
            (((double) y[i]-y[i-1]) / (x[i]-x[i-1]));
     u[i] = (6.0 * u[i]/(x[i+1]-x[i-1]) - sig*u[i-1]) / p;
   }
@@ -912,9 +913,9 @@
   if (h==0.0) FatalError("bad xvalues in splint\n");
   a = (xa[khi]-x)/h;
   b = (x-xa[klo])/h;
-  return (a*ya[klo] + b*ya[khi] + ((a*a*a-a)*y2a[klo] +(b*b*b-b)*y2a[khi]) 
+  return (a*ya[klo] + b*ya[khi] + ((a*a*a-a)*y2a[klo] +(b*b*b-b)*y2a[khi])
 	  * (h*h) / 6.0);
 }
-    
+
 
 
diff -ru xv-3.10a/xviff.c xv-3.10a-enhancements/xviff.c
--- xv-3.10a/xviff.c	1995-01-13 11:54:54.000000000 -0800
+++ xv-3.10a-enhancements/xviff.c	2007-05-13 17:50:59.000000000 -0700
@@ -39,14 +39,14 @@
 
 static long filesize;
 
-static int           readID       PARM((FILE *, char *));
-static int           iffError     PARM((char *, char *));
+/* static int           readID       PARM((FILE *, char *));  DOES NOT EXIST */
+static int           iffError     PARM((const char *, const char *));
 static void          decomprle    PARM((byte *, byte *, long, long));
 static unsigned int  iff_getword  PARM((byte *));
 static unsigned long iff_getlong  PARM((byte *));
 
 
-static char *bname;
+static const char *bname;
 
 
 /* Define internal ILBM types */
@@ -65,16 +65,16 @@
 /*******************************************/
 {
   /* returns '1' on success */
-  
+
   register byte bitmsk, rval, gval, bval;
   register long col, colbit;
   FILE          *fp;
   int           rv;
-  int           BMHDok, CMAPok, CAMGok, BODYok;
+  int           BMHDok, CMAPok, CAMGok;
   int           bmhd_width, bmhd_height, bmhd_bitplanes, bmhd_transcol;
   int           i, j, k, lineskip, colors, fmt;
   byte          bmhd_masking, bmhd_compression;
-  long          chunkLen, camg_viewmode, decomp_bufsize;
+  long          chunkLen, camg_viewmode;
   byte          *databuf, *dataptr, *cmapptr, *picptr, *pic, *bodyptr;
   byte          *workptr, *workptr2, *workptr3, *decomp_mem;
 
@@ -138,6 +138,7 @@
      BODY chunk was found or dataptr ran over end of file */
 
   while ((rv<0) && (dataptr < (databuf + filesize))) {
+    int npixels = 0;
     chunkLen = (iff_getlong(dataptr + 4) + 1) & 0xfffffffe; /* make even */
 
     if (strncmp((char *) dataptr, "BMHD", (size_t) 4)==0) { /* BMHD chunk? */
@@ -149,25 +150,30 @@
       bmhd_transcol    = iff_getword(dataptr + 8 + 12);
       BMHDok = 1;                                       /* got BMHD */
       dataptr += 8 + chunkLen;                          /* to next chunk */
+
+      npixels = bmhd_width * bmhd_height;  /* 65535*65535 max */
+      if (bmhd_width <= 0 || bmhd_height <= 0
+          || npixels/bmhd_width != bmhd_height)
+        return (iffError(bname, "xviff: image dimensions out of range"));
     }
 
 
     else if (strncmp((char *) dataptr, "CMAP", (size_t) 4)==0) { /* CMAP ? */
       cmapptr = dataptr + 8;
       colors = chunkLen / 3;                            /* calc no of colors */
-      
+
       /* copy colors to color map */
       for (i=0; i < colors; i++) {
 	pinfo->r[i] = *cmapptr++;
 	pinfo->g[i] = *cmapptr++;
 	pinfo->b[i] = *cmapptr++;
       }
-      
+
       CMAPok = 1;                                       /* got CMAP */
       dataptr += 8 + chunkLen;                          /* to next chunk */
     }
 
-    
+
     else if (strncmp((char *) dataptr, "CAMG", (size_t) 4)==0) {  /* CAMG ? */
       camg_viewmode = iff_getlong(dataptr + 8);             /* get viewmodes */
       CAMGok = 1;                                       /* got CAMG */
@@ -176,19 +182,28 @@
 
 
     else if (strncmp((char *) dataptr, "BODY", (size_t) 4)==0) { /* BODY ? */
+      int byte_width = (((bmhd_width + 15) >> 4) << 1);  /* 8192 max */
+
       bodyptr = dataptr + 8;                            /* -> BODY data */
-      
+
       if (BMHDok) {                                     /* BMHD found? */
 	/* if BODY is compressed, allocate buffer for decrunched BODY and
 	   decompress it (run length encoding) */
-	
+
 	if (bmhd_compression == 1) {
 	  /* calc size of decrunch buffer - (size of the actual picture
 	     decompressed in interleaved Amiga bitplane format) */
 
-	  decomp_bufsize = (((bmhd_width + 15) >> 4) << 1) 
-  	                       * bmhd_height * bmhd_bitplanes;
-	  
+	  int bytes_per_bitplane = byte_width * bmhd_height; /* 536862720 max */
+          long decomp_bufsize = bytes_per_bitplane * bmhd_bitplanes;
+
+	  if (byte_width <= 0 || bmhd_height <= 0 ||
+	      bytes_per_bitplane/byte_width != bmhd_height ||
+	      decomp_bufsize/bytes_per_bitplane != bmhd_bitplanes)
+	  {
+	    return (iffError(bname, "xviff: image dimensions out of range"));
+	  }
+
 	  if ((decomp_mem = (byte *)malloc((size_t) decomp_bufsize)) != NULL) {
 	    decomprle(dataptr + 8, decomp_mem, chunkLen, decomp_bufsize);
 	    bodyptr = decomp_mem;                 /* -> uncompressed BODY */
@@ -200,12 +215,13 @@
 	    FatalError("xviff: cannot malloc() decrunch buffer");
 	  }
 	}
-	
+
 
 	/* the following determines the type of the ILBM file.
 	   it's either NORMAL, EHB, HAM, HAM8 or 24BIT */
-	
+
 	fmt = ILBM_NORMAL;                        /* assume normal ILBM */
+	/* FIXME:  does ILBM_NORMAL really support up to 255 bitplanes? */
 
 	if      (bmhd_bitplanes == 24) fmt = ILBM_24BIT;
 	else if (bmhd_bitplanes == 8) {
@@ -216,7 +232,7 @@
 	  if (camg_viewmode & 0x80) fmt = ILBM_EHB;
 	  else if (camg_viewmode & 0x800) fmt = ILBM_HAM;
 	}
-	
+
 
 	if (DEBUG) {
 	  fprintf(stderr, "LoadIFF: %s %dx%d, planes=%d (%d cols), comp=%d\n",
@@ -225,9 +241,9 @@
 		  (fmt==ILBM_HAM8)   ? "HAM8 ILBM" :
 		  (fmt==ILBM_EHB)    ? "EHB ILBM" :
 		  (fmt==ILBM_24BIT)  ? "24BIT ILBM" : "unknown ILBM",
-		  bmhd_width, bmhd_height, bmhd_bitplanes, 
+		  bmhd_width, bmhd_height, bmhd_bitplanes,
 		  1<<bmhd_bitplanes, bmhd_compression);
-	}	  
+	}
 
 
 	if ((fmt==ILBM_NORMAL) || (fmt==ILBM_EHB) || (fmt==ILBM_HAM)) {
@@ -248,8 +264,14 @@
 
 
 	if ((fmt == ILBM_HAM) || (fmt == ILBM_HAM8) || (fmt == ILBM_24BIT)) {
-	  if ((picptr=(byte *) malloc((size_t)bmhd_width*bmhd_height*3))
-	      ==NULL) {
+	  int bufsize = 3 * npixels;
+
+	  if (bufsize/3 != npixels) {
+	    if (databuf)    free(databuf);
+	    if (decomp_mem) free(decomp_mem);
+	    return (iffError(bname, "xviff: image dimensions out of range"));
+	  }
+	  if ((picptr=(byte *) malloc((size_t) bufsize)) == NULL) {
 	    if (databuf)    free(databuf);
 	    if (decomp_mem) free(decomp_mem);
 	    return (iffError(bname, "xviff: no memory for decoded picture"));
@@ -258,8 +280,8 @@
 	  else {
 	    pic = picptr;
 	    workptr = bodyptr;
-	    lineskip = ((bmhd_width + 15) >> 4) << 1;
-	    
+	    lineskip = byte_width;
+
 	    for (i=0; i<bmhd_height; i++) {
 	      bitmsk = 0x80;
 	      workptr2 = workptr;
@@ -338,28 +360,28 @@
 
 
 	else if ((fmt == ILBM_NORMAL) || (fmt == ILBM_EHB)) {
-	  if ((picptr = (byte *) malloc((size_t) bmhd_width * bmhd_height))
-	      == NULL) {
+	  /* if bmhd_width and bmhd_height are OK (checked in BMHD block
+	   * above; guaranteed by BMHDok), then npixels is OK, too */
+	  if ((picptr = (byte *) malloc((size_t) npixels)) == NULL) {
 	    if (databuf) free(databuf);
 	    if (decomp_mem) free(decomp_mem);
 	    return (iffError(bname, "xviff: no memory for decoded picture"));
 	  }
-	  
+
 	  else if (fmt == ILBM_EHB) {
 	    if (DEBUG) fprintf(stderr,"Doubling CMAP for EHB mode\n");
-	    
+
 	    for (i=0; i<32; i++) {
 	      pinfo->r[i + colors] = pinfo->r[i] >> 1;
 	      pinfo->g[i + colors] = pinfo->g[i] >> 1;
 	      pinfo->b[i + colors] = pinfo->b[i] >> 1;
 	    }
 	  }
-	  
+
 	  pic = picptr;             /* ptr to chunky buffer */
 	  workptr = bodyptr;        /* ptr to uncmp'd pic, planar format */
-	  
-	  lineskip = ((bmhd_width + 15) >> 4) << 1;  /* # of bytes/line */
-	  
+	  lineskip = byte_width;
+
 	  for (i=0; i<bmhd_height; i++) {
 	    bitmsk = 0x80;                      /* left most bit (mask) */
 	    workptr2 = workptr;                 /* work ptr to source */
@@ -367,14 +389,14 @@
 	      col = 0;
 	      colbit = 1;
 	      workptr3 = workptr2;              /* ptr to byte in 1st pln */
-	      
+
 	      for (k=0; k<bmhd_bitplanes; k++) {
 		if (*workptr3 & bitmsk)          /* if bit set in this pln */
 		  col = col + colbit;           /* add bit to chunky byte */
 		workptr3 += lineskip;           /* go to next line */
 		colbit <<= 1;                   /* shift color bit */
 	      }
-	      
+
 	      *pic++ = col;                     /* write to chunky buffer */
 	      bitmsk = bitmsk >> 1;             /* shift mask to next bit */
 	      if (bitmsk == 0) {                /* if mask is zero */
@@ -382,7 +404,7 @@
 		workptr2++;                     /* mv ptr to next byte */
 	      }
 	    }  /* for j ... */
-	    
+
 	    workptr += lineskip * bmhd_bitplanes;  /* to next line */
 	  }  /* for i ... */
 
@@ -399,7 +421,7 @@
 	pinfo->colType = F_FULLCOLOR;
 	pinfo->frmType = -1;
 
-	sprintf(pinfo->fullInfo, "%s (%ld bytes)", 
+	sprintf(pinfo->fullInfo, "%s (%ld bytes)",
 		(fmt==ILBM_NORMAL) ? "IFF ILBM" :
 		(fmt==ILBM_HAM)    ? "HAM ILBM" :
 		(fmt==ILBM_HAM8)   ? "HAM8 ILBM" :
@@ -414,7 +436,8 @@
       }  /* if BMHDok */
 
       else rv = 0;                   /* didn't get BMHD header */
-    }
+
+    }  /* "BODY" chunk */
 
     else {
       if (DEBUG)
@@ -440,10 +463,10 @@
 
 /**************************************************************************
   void decomprle(source, destination, source length, buffer size)
-  
+
   Decompress run-length encoded data from source to destination. Terminates
   when source is decoded completely or destination buffer is full.
-  
+
   The decruncher is as optimized as I could make it, without risking
   safety in case of corrupt BODY chunks.
 ***************************************************************************/
@@ -455,12 +478,12 @@
      register long slen, dlen;
 {
   register byte codeByte, dataByte;
-  
+
   while ((slen > 0) && (dlen > 0)) {
-    
+
     /* read control byte */
     codeByte = *sptr++;
-    
+
     if (codeByte < 0x80) {
       codeByte++;
       if ((slen > (long) codeByte) && (dlen >= (long) codeByte)) {
@@ -522,7 +545,7 @@
 
 /*******************************************/
 static int iffError(fname, st)
-     char *fname, *st;
+     const char *fname, *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", fname, st);
   return 0;
diff -ru xv-3.10a/xvimage.c xv-3.10a-enhancements/xvimage.c
--- xv-3.10a/xvimage.c	1995-01-13 16:11:36.000000000 -0800
+++ xv-3.10a-enhancements/xvimage.c	2007-03-18 18:13:51.000000000 -0700
@@ -21,6 +21,16 @@
  *            int  LoadPad(pinfo, fname);
  */
 
+/* The following switch should better be provided at runtime for
+ * comparison purposes.
+ * At the moment it's only compile time, unfortunately.
+ * Who can make adaptions for use as a runtime switch by a menu option?
+ * [GRR 19980607:  now via do_fixpix_smooth global; macro renamed to ENABLE_]
+ * [see http://sylvana.net/fixpix/ for home page, further info]
+ */
+/* #define ENABLE_FIXPIX_SMOOTH */   /* GRR 19980607:  moved into xv.h */
+
+#define  NEEDSDIR             /* for S_IRUSR|S_IWUSR */
 #include "copyright.h"
 
 #include "xv.h"
@@ -34,9 +44,11 @@
 static void do_pan_calc       PARM((int, int, int *, int *));
 static void crop1             PARM((int, int, int, int, int));
 static int  doAutoCrop24      PARM((void));
-static void floydDitherize1   PARM((XImage *, byte *, int, int, int, 
+static void floydDitherize1   PARM((XImage *, byte *, int, int, int,
 				    byte *, byte *,byte *));
+#if 0 /* NOTUSED */
 static int  highbit           PARM((unsigned long));
+#endif
 
 static int  doPadSolid        PARM((char *, int, int, int, int));
 static int  doPadBggen        PARM((char *, int, int, int, int));
@@ -46,6 +58,267 @@
 static int  ReadImageFile1    PARM((char *, PICINFO *));
 
 
+/* The following array represents the pixel values for each shade
+ * of the primary color components.
+ * If 'p' is a pointer to a source image rgb-byte-triplet, we can
+ * construct the output pixel value simply by 'oring' together
+ * the corresponding components:
+ *
+ *	unsigned char *p;
+ *	unsigned long pixval;
+ *
+ *	pixval  = screen_rgb[0][*p++];
+ *	pixval |= screen_rgb[1][*p++];
+ *	pixval |= screen_rgb[2][*p++];
+ *
+ * This is both efficient and generic, since the only assumption
+ * is that the primary color components have separate bits.
+ * The order and distribution of bits does not matter, and we
+ * don't need additional variables and shifting/masking code.
+ * The array size is 3 KBytes total and thus very reasonable.
+ */
+
+static unsigned long screen_rgb[3][256];
+
+/* The following array holds the exact color representations
+ * reported by the system.
+ * This is useful for less than 24 bit deep displays as a base
+ * for additional dithering to get smoother output.
+ */
+
+static byte screen_set[3][256];
+
+/* The following routine initializes the screen_rgb and screen_set
+ * arrays.
+ * Since it is executed only once per program run, it does not need
+ * to be super-efficient.
+ *
+ * The method is to draw points in a pixmap with the specified shades
+ * of primary colors and then get the corresponding XImage pixel
+ * representation.
+ * Thus we can get away with any Bit-order/Byte-order dependencies.
+ *
+ * The routine uses some global X variables: theDisp, theScreen,
+ * and dispDEEP. Adapt these to your application as necessary.
+ * I've not passed them in as parameters, since for other platforms
+ * than X these may be different (see vfixpix.c), and so the
+ * screen_init() interface is unique.
+ *
+ * BUG: I've read in the "Xlib Programming Manual" from O'Reilly &
+ * Associates, that the DefaultColormap in TrueColor might not
+ * provide the full shade representation in XAllocColor.
+ * In this case one had to provide a 'best' colormap instead.
+ * However, my tests with Xaccel on a Linux-Box with a Mach64
+ * card were fully successful, so I leave that potential problem
+ * to you at the moment and would appreciate any suggestions...
+ */
+
+static void screen_init()
+{
+  static int init_flag; /* assume auto-init as 0 */
+  Pixmap check_map;
+  GC check_gc;
+  XColor check_col;
+  XImage *check_image;
+  int ci, i;
+
+  if (init_flag) return;
+  init_flag = 1;
+
+  check_map = XCreatePixmap(theDisp, RootWindow(theDisp,theScreen),
+			    1, 1, dispDEEP);
+  check_gc = XCreateGC(theDisp, check_map, 0, NULL);
+  for (ci = 0; ci < 3; ci++) {
+    for (i = 0; i < 256; i++) {
+      check_col.red = 0;
+      check_col.green = 0;
+      check_col.blue = 0;
+      /* Do proper upscaling from unsigned 8 bit (image data values)
+	 to unsigned 16 bit (X color representation). */
+      ((unsigned short *)&check_col.red)[ci] = (unsigned short)((i << 8) | i);
+      if (theVisual->class == TrueColor)
+	XAllocColor(theDisp, theCmap, &check_col);
+      else
+	xvAllocColor(theDisp, theCmap, &check_col);
+      screen_set[ci][i] =
+	(((unsigned short *)&check_col.red)[ci] >> 8) & 0xff;
+      XSetForeground(theDisp, check_gc, check_col.pixel);
+      XDrawPoint(theDisp, check_map, check_gc, 0, 0);
+      check_image = XGetImage(theDisp, check_map, 0, 0, 1, 1,
+			      AllPlanes, ZPixmap);
+      if (check_image) {
+	switch (check_image->bits_per_pixel) {
+	case 8:
+	  screen_rgb[ci][i] = *(CARD8 *)check_image->data;
+	  break;
+	case 16:
+	  screen_rgb[ci][i] = *(CARD16 *)check_image->data;
+	  break;
+	case 24:
+	  screen_rgb[ci][i] =
+	    ((unsigned long)*(CARD8 *)check_image->data << 16) |
+	    ((unsigned long)*(CARD8 *)(check_image->data + 1) << 8) |
+	    (unsigned long)*(CARD8 *)(check_image->data + 2);
+	  break;
+	case 32:
+	  screen_rgb[ci][i] = *(CARD32 *)check_image->data;
+	  break;
+	}
+	XDestroyImage(check_image);
+      }
+    }
+  }
+  XFreeGC(theDisp, check_gc);
+  XFreePixmap(theDisp, check_map);
+}
+
+
+#ifdef ENABLE_FIXPIX_SMOOTH
+
+/* The following code is based in part on:
+ *
+ * jquant1.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains 1-pass color quantization (color mapping) routines.
+ * These routines provide mapping to a fixed color map using equally spaced
+ * color values.  Optional Floyd-Steinberg or ordered dithering is available.
+ */
+
+/* Declarations for Floyd-Steinberg dithering.
+ *
+ * Errors are accumulated into the array fserrors[], at a resolution of
+ * 1/16th of a pixel count.  The error at a given pixel is propagated
+ * to its not-yet-processed neighbors using the standard F-S fractions,
+ *		...	(here)	7/16
+ *		3/16	5/16	1/16
+ * We work left-to-right on even rows, right-to-left on odd rows.
+ *
+ * We can get away with a single array (holding one row's worth of errors)
+ * by using it to store the current row's errors at pixel columns not yet
+ * processed, but the next row's errors at columns already processed.  We
+ * need only a few extra variables to hold the errors immediately around the
+ * current column.  (If we are lucky, those variables are in registers, but
+ * even if not, they're probably cheaper to access than array elements are.)
+ *
+ * We provide (#columns + 2) entries per component; the extra entry at each
+ * end saves us from special-casing the first and last pixels.
+ */
+
+typedef INT16 FSERROR;		/* 16 bits should be enough */
+typedef int LOCFSERROR;		/* use 'int' for calculation temps */
+
+typedef struct { byte    *colorset;
+		 FSERROR *fserrors;
+	       } FSBUF;
+
+/* Floyd-Steinberg initialization function.
+ *
+ * It is called 'fs2_init' since it's specialized for our purpose and
+ * could be embedded in a more general FS-package.
+ *
+ * Returns a malloced FSBUF pointer which has to be passed as first
+ * parameter to subsequent 'fs2_dither' calls.
+ * The FSBUF structure does not need to be referenced by the calling
+ * application, it can be treated from the app like a void pointer.
+ *
+ * The current implementation does only require to free() this returned
+ * pointer after processing.
+ *
+ * Returns NULL if malloc fails.
+ *
+ * NOTE: The FSBUF structure is designed to allow the 'fs2_dither'
+ * function to work with an *arbitrary* number of color components
+ * at runtime! This is an enhancement over the IJG code base :-).
+ * Only fs2_init() specifies the (maximum) number of components.
+ */
+
+static FSBUF *fs2_init(width)
+int width;
+{
+  FSBUF *fs;
+  FSERROR *p;
+
+  fs = (FSBUF *)
+    malloc(sizeof(FSBUF) * 3 + ((size_t)width + 2) * sizeof(FSERROR) * 3);
+  if (fs == 0) return fs;
+
+  fs[0].colorset = screen_set[0];
+  fs[1].colorset = screen_set[1];
+  fs[2].colorset = screen_set[2];
+
+  p = (FSERROR *)(fs + 3);
+  memset(p, 0, ((size_t)width + 2) * sizeof(FSERROR) * 3);
+
+  fs[0].fserrors = p;
+  fs[1].fserrors = p + 1;
+  fs[2].fserrors = p + 2;
+
+  return fs;
+}
+
+/* Floyd-Steinberg dithering function.
+ *
+ * NOTE:
+ * (1) The image data referenced by 'ptr' is *overwritten* (input *and*
+ *     output) to allow more efficient implementation.
+ * (2) Alternate FS dithering is provided by the sign of 'nc'. Pass in
+ *     a negative value for right-to-left processing. The return value
+ *     provides the right-signed value for subsequent calls!
+ * (3) This particular implementation assumes *no* padding between lines!
+ *     Adapt this if necessary.
+ */
+
+static int fs2_dither(fs, ptr, nc, num_rows, num_cols)
+FSBUF *fs;
+byte *ptr;
+int nc, num_rows, num_cols;
+{
+  int abs_nc, ci, row, col;
+  LOCFSERROR delta, cur, belowerr, bpreverr;
+  byte *dataptr, *colsetptr;
+  FSERROR *errorptr;
+
+  if ((abs_nc = nc) < 0) abs_nc = -abs_nc;
+  for (row = 0; row < num_rows; row++) {
+    for (ci = 0; ci < abs_nc; ci++, ptr++) {
+      dataptr = ptr;
+      colsetptr = fs[ci].colorset;
+      errorptr = fs[ci].fserrors;
+      if (nc < 0) {
+	dataptr += (num_cols - 1) * abs_nc;
+	errorptr += (num_cols + 1) * abs_nc;
+      }
+      cur = belowerr = bpreverr = 0;
+      for (col = 0; col < num_cols; col++) {
+	cur += errorptr[nc];
+	cur += 8; cur >>= 4;
+	if ((cur += *dataptr) < 0) cur = 0;
+	else if (cur > 255) cur = 255;
+	*dataptr = cur & 0xff;
+	cur -= colsetptr[cur];
+	delta = cur << 1; cur += delta;
+	bpreverr += cur; cur += delta;
+	belowerr += cur; cur += delta;
+	errorptr[0] = (FSERROR)bpreverr;
+	bpreverr = belowerr;
+	belowerr = delta >> 1;
+	dataptr += nc;
+	errorptr += nc;
+      }
+      errorptr[0] = (FSERROR)bpreverr;
+    }
+    ptr += (num_cols - 1) * abs_nc;
+    nc = -nc;
+  }
+  return nc;
+}
+
+#endif /* ENABLE_FIXPIX_SMOOTH */
+
 
 #define DO_CROP 0
 #define DO_ZOOM 1
@@ -74,7 +347,7 @@
   GenerateEpic(w,h);
   CreateXImage();
 }
-                
+
 
 
 /********************************************/
@@ -90,15 +363,15 @@
 
   cp = cpic;
   bperpix = (picType == PIC8) ? 1 : 3;
-  
+
   for (i=0; i<cHIGH; i++) {
     if ((i&63)==0) WaitCursor();
     pp = pic + (i+cYOFF) * (pWIDE*bperpix) + (cXOFF * bperpix);
-    for (j=0; j<cWIDE*bperpix; j++) 
+    for (j=0; j<cWIDE*bperpix; j++)
       *cp++ = *pp++;
   }
 }
-  
+
 
 
 /***********************************/
@@ -112,10 +385,10 @@
   clptr = NULL;  cxarrp = NULL;  cy = 0;  /* shut up compiler */
 
   SetISTR(ISTR_EXPAND, "%.5g%% x %.5g%%  (%d x %d)",
-	  100.0 * ((float) w) / cWIDE, 
+	  100.0 * ((float) w) / cWIDE,
 	  100.0 * ((float) h) / cHIGH, w, h);
 
-  if (DEBUG) 
+  if (DEBUG)
     fprintf(stderr,"GenerateEpic(%d,%d) eSIZE=%d,%d cSIZE=%d,%d epicode=%d\n",
 		     w,h,eWIDE,eHIGH,cWIDE,cHIGH, epicMode);
 
@@ -124,7 +397,7 @@
   eWIDE = w;  eHIGH = h;
 
 
-  if (epicMode == EM_SMOOTH) {  
+  if (epicMode == EM_SMOOTH) {
     if (picType == PIC8) {
       epic = SmoothResize(cpic, cWIDE, cHIGH, eWIDE, eHIGH,
 			  rMap,gMap,bMap, rdisp,gdisp,bdisp, numcols);
@@ -143,7 +416,7 @@
 
 
   /* generate a 'raw' epic, as we'll need it for ColorDither if EM_DITH */
-    
+
   if (eWIDE==cWIDE && eHIGH==cHIGH) {  /* 1:1 expansion.  point epic at cpic */
     epic = cpic;
   }
@@ -163,13 +436,13 @@
     /* the scaling routine.  not really all that scary after all... */
 
     /* OPTIMIZATON:  Malloc an eWIDE array of ints which will hold the
-       values of the equation px = (pWIDE * ex) / eWIDE.  Faster than doing 
+       values of the equation px = (pWIDE * ex) / eWIDE.  Faster than doing
        a mul and a div for every point in picture */
 
     cxarr = (int *) malloc(eWIDE * sizeof(int));
     if (!cxarr) FatalError("unable to allocate cxarr");
 
-    for (ex=0; ex<eWIDE; ex++) 
+    for (ex=0; ex<eWIDE; ex++)
       cxarr[ex] = bperpix * ((cWIDE * ex) / eWIDE);
 
     elptr = epptr = epic;
@@ -182,7 +455,7 @@
       clptr = cpic + (cy * cWIDE * bperpix);
 
       if (bperpix == 1) {
-	for (ex=0, cxarrp = cxarr;  ex<eWIDE;  ex++, epptr++) 
+	for (ex=0, cxarrp = cxarr;  ex<eWIDE;  ex++, epptr++)
 	  *epptr = clptr[*cxarrp++];
       }
       else {
@@ -190,7 +463,7 @@
 
 	for (ex=0, cxarrp = cxarr; ex<eWIDE; ex++,cxarrp++) {
 	  cp = clptr + *cxarrp;
-	  for (j=0; j<bperpix; j++) 
+	  for (j=0; j<bperpix; j++)
 	    *epptr++ = *cp++;
 	}
       }
@@ -203,7 +476,7 @@
   if (picType == PIC8 && epicMode == EM_DITH) {
     byte *tmp;
 
-    tmp = DoColorDither(NULL, epic, eWIDE, eHIGH, rMap,gMap,bMap, 
+    tmp = DoColorDither(NULL, epic, eWIDE, eHIGH, rMap,gMap,bMap,
 			rdisp,gdisp,bdisp, numcols);
     if (tmp) {  /* success */
       FreeEpic();
@@ -214,7 +487,7 @@
     }
   }
 }
-                
+
 
 
 /***********************************/
@@ -233,7 +506,7 @@
 static void do_zoom(mx,my)
      int mx,my;
 {
-  int i,w,h,x,y,x2,y2;
+  int i;
   int rx,ry,rx2,ry2, orx, ory, orw, orh;
   int px,py,pw,ph,opx,opy,opw,oph,m;
   Window rW, cW;  unsigned int mask;  int rtx, rty;
@@ -254,10 +527,10 @@
   while (1) {
     if (!XQueryPointer(theDisp,mainW,&rW,&cW,&rtx,&rty,
 		       &mx,&my,&mask)) continue;
-    
+
     if (!(mask & ControlMask)) break;
     if (!(mask & Button1Mask)) break;  /* button released */
-    
+
     compute_zoom_rect(mx, my, &px, &py, &pw, &ph);
     if (px!=opx || py!=opy) {
       XDrawRectangle(theDisp,mainW,theGC, orx,ory, (u_int)orw, (u_int)orh);
@@ -283,7 +556,7 @@
     XSetPlaneMask(theDisp, theGC, AllPlanes);
     return;
   }
-    
+
 
   for (i=0; i<4; i++) {
     XDrawRectangle(theDisp, mainW, theGC, orx, ory, (u_int) orw, (u_int) orh);
@@ -297,7 +570,7 @@
   /* if rectangle is *completely* outside epic, don't zoom */
   if (orx+orw<0 || ory+orh<0 || orx>=eWIDE || ory>=eHIGH) return;
 
-  
+
   crop1(opx, opy, opw, oph, DO_ZOOM);
 }
 
@@ -306,15 +579,15 @@
 static void compute_zoom_rect(x, y, px, py, pw, ph)
      int x, y, *px, *py, *pw, *ph;
 {
-  /* given a mouse pos (in epic coords), return x,y,w,h PIC coords for 
-     a 'zoom in by 2x' rectangle to be tracked.  The rectangle stays 
+  /* given a mouse pos (in epic coords), return x,y,w,h PIC coords for
+     a 'zoom in by 2x' rectangle to be tracked.  The rectangle stays
      completely within 'pic' boundaries, and moves in 'pic' increments */
 
   CoordE2P(x, y, px, py);
-  *pw = (cWIDE+1)/2;  
+  *pw = (cWIDE+1)/2;
   *ph = (cHIGH+1)/2;
 
-  *px = *px - (*pw)/2;  
+  *px = *px - (*pw)/2;
   *py = *py - (*ph)/2;
 
   RANGE(*px, 0, pWIDE - *pw);
@@ -327,7 +600,7 @@
 {
   int x,y,w,h, x2,y2, ex,ey,ew,eh;
 
-  /* compute a cropping rectangle (in pic coordinates) that's twice 
+  /* compute a cropping rectangle (in pic coordinates) that's twice
      the size of eWIDE,eHIGH, centered around eWIDE/2, eHIGH/2, but no
      larger than pWIDE,PHIGH */
 
@@ -362,7 +635,7 @@
   int i, ox,oy,offx,offy, rw,rh, px, py, dx, dy,m;
   Window rW, cW;  unsigned int mask;  int rx, ry;
 
-  offx = ox = mx;  
+  offx = ox = mx;
   offy = oy = my;
   rw = eWIDE-1;  rh = eHIGH-1;
   m = 0;
@@ -374,50 +647,50 @@
 
   /* track until Button2 is released */
   while (1) {
-    if (!XQueryPointer(theDisp, mainW, &rW, &cW, &rx, &ry, 
+    if (!XQueryPointer(theDisp, mainW, &rW, &cW, &rx, &ry,
 		       &mx, &my, &mask)) continue;
     if (!(mask & ControlMask)) break;  /* cancelled */
     if (!(mask & Button2Mask)) break;  /* button released */
-    
+
     if (mask & ShiftMask) {    /* constrain mx,my to horiz or vertical */
       if (abs(mx-offx) > abs(my-offy)) my = offy;
       else mx = offx;
     }
-    
+
     do_pan_calc(offx, offy, &mx, &my);
-    
+
     if (mx!=ox || my!=oy) {
-      XDrawRectangle(theDisp, mainW, theGC, ox-offx, oy-offy, 
+      XDrawRectangle(theDisp, mainW, theGC, ox-offx, oy-offy,
 		     (u_int) rw, (u_int) rh);
-      XDrawRectangle(theDisp, mainW, theGC, mx-offx, my-offy, 
+      XDrawRectangle(theDisp, mainW, theGC, mx-offx, my-offy,
 		     (u_int) rw, (u_int) rh);
       ox = mx;  oy = my;
     }
     else {
-      XDrawRectangle(theDisp, mainW, theGC, ox-offx, oy-offy, 
+      XDrawRectangle(theDisp, mainW, theGC, ox-offx, oy-offy,
 		     (u_int) rw, (u_int) rh);
       m = (m+1)&7;
       XSetPlaneMask(theDisp, theGC, xorMasks[m]);
-      XDrawRectangle(theDisp, mainW, theGC, ox-offx, oy-offy, 
+      XDrawRectangle(theDisp, mainW, theGC, ox-offx, oy-offy,
 		     (u_int) rw, (u_int) rh);
       XFlush(theDisp);
       Timer(100);
     }
   }
-      
+
   mx = ox;  my = oy;  /* in case mx,my changed on button release */
 
   if (!(mask & ControlMask)) {  /* cancelled */
-    XDrawRectangle(theDisp, mainW, theGC, mx-offx, my-offy, 
+    XDrawRectangle(theDisp, mainW, theGC, mx-offx, my-offy,
 		   (u_int) rw, (u_int) rh);
     XSetFunction(theDisp, theGC, GXcopy);
     XSetPlaneMask(theDisp, theGC, AllPlanes);
     return;
   }
-    
+
 
   for (i=0; i<4; i++) {
-    XDrawRectangle(theDisp, mainW, theGC, mx-offx, my-offy, 
+    XDrawRectangle(theDisp, mainW, theGC, mx-offx, my-offy,
 		   (u_int) rw, (u_int) rh);
     XFlush(theDisp);
     Timer(100);
@@ -430,7 +703,7 @@
   dx = px - cXOFF;  dy = py - cYOFF;
 
   if (dx==0 && dy==0) {  /* didn't pan anywhere */
-    XDrawRectangle(theDisp, mainW, theGC, mx-offx, my-offy, 
+    XDrawRectangle(theDisp, mainW, theGC, mx-offx, my-offy,
 		   (u_int) rw, (u_int) rh);
     XSetFunction(theDisp, theGC, GXcopy);
     XSetPlaneMask(theDisp, theGC, AllPlanes);
@@ -485,7 +758,7 @@
 /***********************************/
 void Crop()
 {
-  int i, x, y, w, h;
+  int x, y, w, h;
 
   if (!HaveSelection()) return;
 
@@ -499,8 +772,7 @@
 static void crop1(x,y,w,h,zm)
      int x,y,w,h,zm;
 {
-  int   i,j,oldew,oldeh,oldcx,oldcy;
-  byte *cp, *pp;
+  int   oldew,oldeh,oldcx,oldcy;
 
   oldcx = cXOFF;  oldcy = cYOFF;
   oldew = eWIDE;  oldeh = eHIGH;
@@ -529,7 +801,7 @@
   if (cpic == pic) return;     /* not cropped */
 
   BTSetActive(&but[BUNCROP],0);
-  
+
   if (epicMode == EM_SMOOTH) {   /* turn off smoothing */
     epicMode = EM_RAW;  SetEpicMode();
   }
@@ -538,7 +810,7 @@
   FreeEpic();
   if (cpic && cpic !=  pic) free(cpic);
   cpic = NULL;
-  
+
 
   w = (pWIDE * eWIDE) / cWIDE;   h = (pHIGH * eHIGH) / cHIGH;
   if (w>maxWIDE || h>maxHIGH) {
@@ -566,7 +838,7 @@
   WUnCrop();
   SetCropString();
 }
-  
+
 
 /***********************************/
 void AutoCrop()
@@ -583,7 +855,7 @@
       WCrop(eWIDE, eHIGH, cXOFF-oldcx, cYOFF-oldcy);
     }
   }
-  
+
   SetCursors(-1);
 }
 
@@ -650,7 +922,7 @@
 
   /* do the actual cropping */
   if (cleft || ctop || cbot || cright) {
-    DoCrop(cXOFF+cleft, cYOFF+ctop, 
+    DoCrop(cXOFF+cleft, cYOFF+ctop,
 	    cWIDE-(cleft+cright), cHIGH-(ctop+cbot));
     return 1;
   }
@@ -673,7 +945,7 @@
 # define NEIGHBOR 16		/* within 6% of neighboring pixels */
 # define MISSPCT 6		/* and up to 6% that don't match */
 # define inabsrange(a,n) ( (a) < n && (a) > -n )
-  
+
 
   if (cHIGH<3 || cWIDE<3) return 0;
 
@@ -739,7 +1011,7 @@
   while (cleft + 1 < cWIDE) {  /* see if we can delete this line */
     oldr = bgR; oldg = bgG; oldb = bgB;
 
-    for (i=0, misses=0, cp1=cp; i<cHIGH && misses<maxmiss; 
+    for (i=0, misses=0, cp1=cp; i<cHIGH && misses<maxmiss;
 	 i++, cp1 += (cWIDE * 3)) {
       r=cp1[0]-bgR;  g=cp1[1]-bgG;  b=cp1[2]-bgB;
       R=cp1[0]-oldr; G=cp1[1]-oldg; B=cp1[2]-oldb;
@@ -763,7 +1035,7 @@
   while (cleft + cright + 1 < cWIDE) {  /* see if we can delete this line */
     oldr = bgR; oldg = bgG; oldb = bgB;
 
-    for (i=0, misses=0, cp1=cp; i<cHIGH && misses<maxmiss; 
+    for (i=0, misses=0, cp1=cp; i<cHIGH && misses<maxmiss;
 	 i++, cp1 += (cWIDE*3)) {
       r=cp1[0]-bgR;  g=cp1[1]-bgG;  b=cp1[2]-bgB;
       R=cp1[0]-oldr; G=cp1[1]-oldg; B=cp1[2]-oldb;
@@ -784,8 +1056,8 @@
   if (cleft || ctop || cbot || cright) {
     if (cWIDE - (cleft + cright) < 1 ||
 	cHIGH - (ctop  + cbot  ) < 1) return 0;    /* sanity check */
-    
-    DoCrop(cXOFF+cleft, cYOFF+ctop, 
+
+    DoCrop(cXOFF+cleft, cYOFF+ctop,
 	   cWIDE-(cleft+cright), cHIGH-(ctop+cbot));
     return 1;
   }
@@ -802,7 +1074,7 @@
      and sticks likely values into eWIDE,eHIGH, assuming you wanted to
      crop.  epic is not regnerated (but is freed) */
 
-  int     i, j, k, bperpix;
+  int     i, j, bperpix;
   byte   *cp, *pp;
   double  expw, exph;
 
@@ -837,7 +1109,7 @@
   else {
     /* at this point, we want to generate cpic, which will contain a
        cWIDE*cHIGH subsection of 'pic', top-left at cXOFF,cYOFF */
-    
+
     cpic = (byte *) malloc((size_t) (cWIDE * cHIGH * bperpix));
 
     if (cpic == NULL) {
@@ -852,7 +1124,7 @@
     cp = cpic;
     for (i=0; i<cHIGH; i++) {
       pp = pic + (i+cYOFF) * (pWIDE*bperpix) + (cXOFF * bperpix);
-      for (j=0; j<cWIDE*bperpix; j++) 
+      for (j=0; j<cWIDE*bperpix; j++)
 	*cp++ = *pp++;
     }
   }
@@ -861,7 +1133,7 @@
   SetCropString();
   BTSetActive(&but[BUNCROP], (cpic!=pic));
 
-  eWIDE = (int) (cWIDE * expw);  
+  eWIDE = (int) (cWIDE * expw);
   eHIGH = (int) (cHIGH * exph);
 
   if (eWIDE>maxWIDE || eHIGH>maxHIGH) {  /* make 'normal' size */
@@ -869,7 +1141,7 @@
       double r,wr,hr;
       wr = ((double) cWIDE) / maxWIDE;
       hr = ((double) cHIGH) / maxHIGH;
-      
+
       r = (wr>hr) ? wr : hr;   /* r is the max(wr,hr) */
       eWIDE = (int) ((cWIDE / r) + 0.5);
       eHIGH = (int) ((cHIGH / r) + 0.5);
@@ -906,12 +1178,12 @@
      int dir;
 {
   int i;
-  
+
   /* dir=0: 90 degrees clockwise, else 90 degrees counter-clockwise */
   WaitCursor();
-  
+
   RotatePic(pic, picType, &pWIDE, &pHIGH, dir);
-  
+
   /* rotate clipped version and modify 'clip' coords */
   if (cpic != pic && cpic != NULL) {
     if (!dir) {
@@ -928,7 +1200,7 @@
     RotatePic(cpic, picType, &cWIDE, &cHIGH,dir);
   }
   else { cWIDE = pWIDE;  cHIGH = pHIGH; }
-  
+
   /* rotate expanded version */
   if (epic != cpic && epic != NULL) {
     WaitCursor();
@@ -940,7 +1212,7 @@
   SetISTR(ISTR_RES,"%d x %d",pWIDE,pHIGH);
 
   SetISTR(ISTR_EXPAND, "%.5g%% x %.5g%%  (%d x %d)",
-	  100.0 * ((float) eWIDE) / cWIDE, 
+	  100.0 * ((float) eWIDE) / cWIDE,
 	  100.0 * ((float) eHIGH) / cHIGH, eWIDE, eHIGH);
 }
 
@@ -951,7 +1223,7 @@
      int  *wp, *hp;
      int   ptype, dir;
 {
-  /* rotates a w*h array of bytes 90 deg clockwise (dir=0) 
+  /* rotates a w*h array of bytes 90 deg clockwise (dir=0)
      or counter-clockwise (dir != 0).  swaps w and h */
 
   byte        *pic1, *pix1, *pix;
@@ -960,7 +1232,7 @@
 
   bperpix = (ptype == PIC8) ? 1 : 3;
 
-  w = *wp;  h = *hp;  
+  w = *wp;  h = *hp;
   pix1 = pic1 = (byte *) malloc((size_t) (w*h*bperpix));
   if (!pic1) FatalError("Not enough memory to rotate!");
 
@@ -968,15 +1240,15 @@
   if (dir==0) {
     for (i=0; i<w; i++) {       /* CW */
       if (bperpix == 1) {
-	for (j=h-1, pix=pic+(h-1)*w + i;  j>=0;  j--, pix1++, pix-=w) 
+	for (j=h-1, pix=pic+(h-1)*w + i;  j>=0;  j--, pix1++, pix-=w)
 	  *pix1 = *pix;
       }
       else {
 	int bperlin = w*bperpix;
 	int k;
-	
-	for (j=h-1, pix=pic+(h-1)*w*bperpix + i*bperpix;  
-	     j>=0;  j--, pix -= bperlin) 
+
+	for (j=h-1, pix=pic+(h-1)*w*bperpix + i*bperpix;
+	     j>=0;  j--, pix -= bperlin)
 	  for (k=0; k<bperpix; k++) *pix1++ = pix[k];
       }
     }
@@ -984,25 +1256,25 @@
   else {
     for (i=w-1; i>=0; i--) {    /* CCW */
       if (bperpix == 1) {
-	for (j=0, pix=pic+i; j<h; j++, pix1++, pix+=w) 
+	for (j=0, pix=pic+i; j<h; j++, pix1++, pix+=w)
 	  *pix1 = *pix;
       }
       else {
 	int k;
 	int bperlin = w*bperpix;
-	
-	for (j=0, pix=pic+i*bperpix; j<h; j++, pix+=bperlin) 
+
+	for (j=0, pix=pic+i*bperpix; j<h; j++, pix+=bperlin)
 	  for (k=0; k<bperpix; k++) *pix1++ = pix[k];
       }
     }
   }
-  
-  
+
+
   /* copy the rotated buffer into the original buffer */
   xvbcopy((char *) pic1, (char *) pic, (size_t) (w*h*bperpix));
-  
+
   free(pic1);
-  
+
   /* swap w and h */
   *wp = h;  *hp = w;
 }
@@ -1017,7 +1289,7 @@
    *
    * Note:  flips pic, cpic, and epic.  Doesn't touch Ximage, nor does it draw
    */
-  
+
   WaitCursor();
 
   if (HaveSelection()) {            /* only flip selection region */
@@ -1026,7 +1298,7 @@
   }
 
   FlipPic(pic, pWIDE, pHIGH, dir);
-  
+
   /* flip clipped version */
   if (cpic && cpic != pic) {
     WaitCursor();
@@ -1048,21 +1320,21 @@
      int dir;
 {
   /* flips a w*h array of bytes horizontally (dir=0) or vertically (dir!=0) */
-  
+
   byte *plin;
   int   i,j,k,l,bperpix,bperlin;
-  
+
   bperpix = (picType == PIC8) ? 1 : 3;
   bperlin = w * bperpix;
-  
+
   if (dir==0) {                /* horizontal flip */
     byte *leftp, *rightp;
-    
+
     for (i=0; i<h; i++) {
       plin   = pic + i*bperlin;
       leftp  = plin;
       rightp = plin + (w-1)*bperpix;
-      
+
       for (j=0; j<w/2; j++, rightp -= (2*bperpix)) {
 	for (l=0; l<bperpix; l++, leftp++, rightp++) {
 	  k = *leftp;  *leftp = *rightp;  *rightp = k;
@@ -1070,14 +1342,14 @@
       }
     }
   }
-  
+
   else {                      /* vertical flip */
     byte *topp, *botp;
-    
+
     for (i=0; i<w; i++) {
       topp = pic + i*bperpix;
       botp = pic + (h-1)*bperlin + i*bperpix;
-      
+
       for (j=0; j<h/2; j++, topp+=(w-1)*bperpix, botp-=(w+1)*bperpix) {
 	for (l=0; l<bperpix; l++, topp++, botp++) {
 	  k = *topp;  *topp = *botp;  *botp = k;
@@ -1093,26 +1365,26 @@
      int dir;
 {
   /* flips selected area in 'pic', regens cpic and epic appropriately */
-  
+
   int   x,y,w,h;
   byte *plin;
   int   i,j,k,l,bperpix;
-  
+
   GetSelRCoords(&x,&y,&w,&h);
   CropRect2Rect(&x,&y,&w,&h, 0,0,pWIDE,pHIGH);
   if (w<1) w=1;
   if (h<1) h=1;
-  
+
   bperpix = (picType == PIC8) ? 1 : 3;
-  
+
   if (dir==0) {                /* horizontal flip */
     byte *leftp, *rightp;
-    
+
     for (i=y; i<y+h; i++) {
       plin   = pic + (i*pWIDE + x) * bperpix;
       leftp  = plin;
       rightp = plin + (w-1)*bperpix;
-      
+
       for (j=0; j<w/2; j++, rightp -= (2*bperpix)) {
 	for (l=0; l<bperpix; l++, leftp++, rightp++) {
 	  k = *leftp;  *leftp = *rightp;  *rightp = k;
@@ -1120,14 +1392,14 @@
       }
     }
   }
-  
+
   else {                      /* vertical flip */
     byte *topp, *botp;
-    
+
     for (i=x; i<x+w; i++) {
       topp = pic + ( y      * pWIDE + i) * bperpix;
       botp = pic + ((y+h-1) * pWIDE + i) * bperpix;
-      
+
       for (j=0; j<h/2; j++, topp+=(pWIDE-1)*bperpix, botp-=(pWIDE+1)*bperpix) {
 	for (l=0; l<bperpix; l++, topp++, botp++) {
 	  k = *topp;  *topp = *botp;  *botp = k;
@@ -1139,22 +1411,22 @@
   GenerateCpic();
   GenerateEpic(eWIDE,eHIGH);
 }
-    
+
 
 /************************/
 void InstallNewPic()
 {
   /* given a new pic and colormap, (or new 24-bit pic) installs everything,
      regens cpic and epic, and redraws image */
-  
+
   /* toss old cpic and epic, if any */
   FreeEpic();
   if (cpic && cpic != pic) free(cpic);
   cpic = NULL;
-  
+
   /* toss old colors, and allocate new ones */
   NewPicGetColors(0,0);
-  
+
   /* generate cpic,epic,theImage from new 'pic' */
   crop1(cXOFF, cYOFF, cWIDE, cHIGH, DO_ZOOM);
   HandleDispMode();
@@ -1166,15 +1438,15 @@
 void DrawEpic()
 {
   /* given an 'epic', builds a new Ximage, and draws it.  Basically
-     called whenever epic is changed, or whenever color allocation 
-     changes (ie, the created X image will look different for the 
+     called whenever epic is changed, or whenever color allocation
+     changes (ie, the created X image will look different for the
      same epic) */
-  
+
   CreateXImage();
 
   if (useroot) MakeRootPic();
   else DrawWindow(0,0,eWIDE,eHIGH);
-  
+
   if (HaveSelection()) DrawSelection(0);
 }
 
@@ -1189,7 +1461,7 @@
   if (pic) free(pic);
   xvDestroyImage(theImage);   theImage = NULL;
   pic = egampic = epic = cpic = NULL;
-  
+
   if (picComments) free(picComments);
   picComments = (char *) NULL;
   ChangeCommentText();
@@ -1203,7 +1475,7 @@
      byte   *pic824, *rmap, *gmap, *bmap;
      int     ptype, wide, high;
 {
-  /* does floyd-steinberg ditherizing algorithm.  
+  /* does floyd-steinberg ditherizing algorithm.
    *
    * takes a wide*high input image, of type 'ptype' (PIC8, PIC24)
    *     (if PIC8, colormap is specified by rmap,gmap,bmap)
@@ -1212,14 +1484,14 @@
    *
    * Note: this algorithm is *only* used when running on a 1-bit display
    */
-  
+
   register byte   pix8, bit;
   int            *thisline, *nextline;
   int            *thisptr, *nextptr, *tmpptr;
   int             i, j, err, bperpix, bperln, order;
   byte           *pp, *image, w1, b1, w8, b8, rgb[256];
-  
-  
+
+
   if (ptype == PIC8) {   /* monoify colormap */
     for (i=0; i<256; i++)
       rgb[i] = MONO(rmap[i], gmap[i], bmap[i]);
@@ -1234,7 +1506,7 @@
 
   thisline = (int *) malloc(wide * sizeof(int));
   nextline = (int *) malloc(wide * sizeof(int));
-  if (!thisline || !nextline) 
+  if (!thisline || !nextline)
     FatalError("ran out of memory in floydDitherize1()\n");
 
 
@@ -1249,10 +1521,10 @@
       *tmpptr++ = fsgamcr[rgb[*pp]];
   }
 
-      
+
   w1 = white&0x1;  b1=black&0x1;
   w8 = w1<<7;  b8 = b1<<7;        /* b/w bit in high bit */
-  
+
 
   for (i=0; i<high; i++) {
     if ((i&0x3f) == 0) WaitCursor();
@@ -1326,7 +1598,7 @@
 
 
 /************************/
-byte *FSDither(inpic, intype, w, h, rmap, gmap, bmap, 
+byte *FSDither(inpic, intype, w, h, rmap, gmap, bmap,
 	      bval, wval)
      byte *inpic, *rmap, *gmap, *bmap;
      int   w,h, intype, bval, wval;
@@ -1338,14 +1610,21 @@
    * and 'wval' as the 'black' and 'white' pixel values, respectively
    */
 
-  int    i, j, err, w1, h1;
+  int    i, j, err, w1, h1, npixels, linebufsize;
   byte  *pp, *outpic, rgb[256];
   int   *thisline, *nextline, *thisptr, *nextptr, *tmpptr;
 
 
-  outpic = (byte *) malloc((size_t) (w * h));
+  npixels = w * h;
+  linebufsize = w * sizeof(int);
+  if (w <= 0 || h <= 0 || npixels/w != h || linebufsize/w != sizeof(int)) {
+    SetISTR(ISTR_WARNING, "Invalid image dimensions for dithering");
+    return (byte *)NULL;
+  }
+
+  outpic = (byte *) malloc((size_t) npixels);
   if (!outpic) return outpic;
-    
+
 
   if (intype == PIC8) {       /* monoify colormap */
     for (i=0; i<256; i++)
@@ -1353,9 +1632,9 @@
   }
 
 
-  thisline = (int *) malloc(w * sizeof(int));
-  nextline = (int *) malloc(w * sizeof(int));
-  if (!thisline || !nextline) 
+  thisline = (int *) malloc(linebufsize);
+  nextline = (int *) malloc(linebufsize);
+  if (!thisline || !nextline)
     FatalError("ran out of memory in FSDither()\n");
 
 
@@ -1394,13 +1673,13 @@
     pp  = outpic + i * w;
     thisptr = thisline;  nextptr = nextline;
 
-    if (i&1 == 0) {  /* go right */
+    if ((i&1) == 0) {  /* go right */
       for (j=0; j<w; j++, pp++, thisptr++, nextptr++) {
 	if (*thisptr<128) { err = *thisptr;     *pp = (byte) bval; }
 	             else { err = *thisptr-255; *pp = (byte) wval; }
-	
+
 	if (j<w1) thisptr[1] += ((err*7)/16);
-	
+
 	if (i<h1) {
 	  nextptr[0] += ((err*5)/16);
 	  if (j>0)  nextptr[-1] += ((err*3)/16);
@@ -1414,9 +1693,9 @@
       for (j=w-1; j>=0; j--, pp--, thisptr--, nextptr--) {
 	if (*thisptr<128) { err = *thisptr;     *pp = (byte) bval; }
 	             else { err = *thisptr-255; *pp = (byte) wval; }
-	
+
 	if (j>0) thisptr[-1] += ((err*7)/16);
-	
+
 	if (i<h1) {
 	  nextptr[0] += ((err*5)/16);
 	  if (j>0)  nextptr[-1] += (err/16);
@@ -1449,8 +1728,8 @@
   }
 
 
-  if (picType == PIC8) 
-    theImage = Pic8ToXImage(epic,     (u_int) eWIDE, (u_int) eHIGH, 
+  if (picType == PIC8)
+    theImage = Pic8ToXImage(epic,     (u_int) eWIDE, (u_int) eHIGH,
 			    cols, rMap, gMap, bMap);
   else if (picType == PIC24)
     theImage = Pic24ToXImage(egampic, (u_int) eWIDE, (u_int) eHIGH);
@@ -1482,7 +1761,7 @@
 
   if (!pic8) return xim;  /* shouldn't happen */
 
-  if (DEBUG > 1) 
+  if (DEBUG > 1)
     fprintf(stderr,"Pic8ToXImage(): creating a %dx%d Ximage, %d bits deep\n",
 	    wide, high, dispDEEP);
 
@@ -1491,7 +1770,7 @@
   if (dispDEEP == 1) {
     byte  *imagedata;
 
-    xim = XCreateImage(theDisp, theVisual, dispDEEP, XYPixmap, 0, NULL, 
+    xim = XCreateImage(theDisp, theVisual, dispDEEP, XYPixmap, 0, NULL,
 		       wide, high, 32, 0);
     if (!xim) FatalError("couldn't create xim!");
 
@@ -1506,11 +1785,11 @@
 
   /* if ncols==0, do a 'black' and 'white' dither */
   if (ncols == 0) {
-    /* note that if dispDEEP > 8, dithpic will just have '0' and '1' instead 
+    /* note that if dispDEEP > 8, dithpic will just have '0' and '1' instead
        of 'black' and 'white' */
 
     dithpic = FSDither(pic8, PIC8, (int) wide, (int) high, rmap, gmap, bmap,
-		       (int) ((dispDEEP <= 8) ? black : 0), 
+		       (int) ((dispDEEP <= 8) ? black : 0),
 		       (int) ((dispDEEP <= 8) ? white : 1));
   }
 
@@ -1521,14 +1800,14 @@
   case 8: {
     byte  *imagedata, *ip, *pp;
     int   j, imWIDE, nullCount;
-  
+
     nullCount = (4 - (wide % 4)) & 0x03;  /* # of padding bytes per line */
     imWIDE = wide + nullCount;
- 
+
     /* Now create the image data - pad each scanline as necessary */
     imagedata = (byte *) malloc((size_t) (imWIDE * high));
     if (!imagedata) FatalError("couldn't malloc imagedata");
-    
+
     pp = (dithpic) ? dithpic : pic8;
 
     for (i=0, ip=imagedata; i<high; i++) {
@@ -1543,9 +1822,9 @@
 
       for (j=0; j<nullCount; j++, ip++) *ip = 0;
     }
-      
+
     xim = XCreateImage(theDisp,theVisual,dispDEEP,ZPixmap,0,
-		       (char *) imagedata,  wide,  high, 
+		       (char *) imagedata,  wide,  high,
 		       32, imWIDE);
     if (!xim) FatalError("couldn't create xim!");
   }
@@ -1554,13 +1833,13 @@
 
 
     /*********************************/
-      
+
   case 4: {
     byte  *imagedata, *ip, *pp;
     byte *lip;
     int  bperline, half, j;
 
-    xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL, 
+    xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL,
 		        wide,  high, 8, 0);
     if (!xim) FatalError("couldn't create xim!");
 
@@ -1569,7 +1848,7 @@
     if (!imagedata) FatalError("couldn't malloc imagedata");
     xim->data = (char *) imagedata;
 
-    
+
     pp = (dithpic) ? dithpic : pic8;
 
     if (xim->bits_per_pixel == 4) {
@@ -1601,20 +1880,20 @@
     else FatalError("This display's too bizarre.  Can't create XImage.");
   }
     break;
-      
+
 
     /*********************************/
-      
+
   case 2: {  /* by M.Kossa@frec.bull.fr (Marc Kossa) */
              /* MSBFirst mods added by dale@ntg.com (Dale Luck) */
-             /* additional fixes by  evol@infko.uni-koblenz.de 
+             /* additional fixes by  evol@infko.uni-koblenz.de
 		(Randolf Werner) for NeXT 2bit grayscale with MouseX */
 
     byte  *imagedata, *ip, *pp;
     byte *lip;
     int  bperline, half, j;
 
-    xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL, 
+    xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL,
 		        wide,  high, 8, 0);
     if (!xim) FatalError("couldn't create xim!");
 
@@ -1674,11 +1953,11 @@
 	*ip = (dithpic) ? *pp : (byte) xcolors[*pp];
       }
     }
-      
+
     else FatalError("This display's too bizarre.  Can't create XImage.");
   }
     break;
-      
+
 
   /*********************************/
 
@@ -1686,8 +1965,8 @@
   case 6: {
     byte  *imagedata, *ip, *pp;
     int  bperline;
-    
-    xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL, 
+
+    xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL,
 		        wide,  high, 8, 0);
     if (!xim) FatalError("couldn't create xim!");
 
@@ -1707,17 +1986,16 @@
     }
   }
     break;
-      
+
 
   /*********************************/
 
   case 12:
   case 15:
   case 16: {
-    unsigned short  *imagedata, *ip;
-    byte  *pp;
+    byte  *imagedata, *ip, *pp;
 
-    imagedata = (unsigned short *) malloc((size_t) (2*wide*high));
+    imagedata = (byte *) malloc((size_t) (2*wide*high));
     if (!imagedata) FatalError("couldn't malloc imagedata");
 
     xim = XCreateImage(theDisp,theVisual,dispDEEP,ZPixmap,0,
@@ -1736,10 +2014,12 @@
     if (xim->byte_order == MSBFirst) {
       for (i=wide*high, ip=imagedata; i>0; i--,pp++) {
 	if (((i+1)&0x1ffff) == 0) WaitCursor();
-	if (dithpic) {
-	  *ip++ = ((*pp) ? white : black) & 0xffff;
-	}
-	else *ip++ = xcolors[*pp] & 0xffff;
+
+	if (dithpic) xcol = ((*pp) ? white : black) & 0xffff;
+		else xcol = xcolors[*pp] & 0xffff;
+
+	*ip++ = (xcol>>8) & 0xff;
+	*ip++ = (xcol) & 0xff;
       }
     }
     else {   /* LSBFirst */
@@ -1749,14 +2029,14 @@
 	if (dithpic) xcol = ((*pp) ? white : black) & 0xffff;
 	        else xcol = xcolors[*pp];
 
-	/*  WAS *ip++ = ((xcol>>8) & 0xff) | ((xcol&0xff) << 8);  */
-	*ip++ = (unsigned short) (xcol);
+	*ip++ = (xcol) & 0xff;
+	*ip++ = (xcol>>8) & 0xff;
       }
     }
   }
     break;
 
-      
+
     /*********************************/
 
   case 24:
@@ -1766,7 +2046,7 @@
 
     imagedata = (byte *) malloc((size_t) (4*wide*high));
     if (!imagedata) FatalError("couldn't malloc imagedata");
-      
+
     xim = XCreateImage(theDisp,theVisual,dispDEEP,ZPixmap,0,
 		       (char *) imagedata,  wide,  high, 32, 0);
     if (!xim) FatalError("couldn't create xim!");
@@ -1774,7 +2054,7 @@
     do32 = (xim->bits_per_pixel == 32);
 
     pp = (dithpic) ? dithpic : pic8;
-      
+
     if (xim->byte_order == MSBFirst) {
       for (i=0, ip=imagedata; i<high; i++) {
 	if (((i+1)&0x7f) == 0) WaitCursor();
@@ -1809,11 +2089,11 @@
 
 
     /*********************************/
-    
-  default: 
-    sprintf(str,"no code to handle this display type (%d bits deep)",
+
+  default:
+    sprintf(dummystr,"no code to handle this display type (%d bits deep)",
 	    dispDEEP);
-    FatalError(str);
+    FatalError(dummystr);
     break;
   }
 
@@ -1823,7 +2103,7 @@
   return(xim);
 }
 
-static int foo = 0;
+
 
 /***********************************/
 XImage *Pic24ToXImage(pic24, wide, high)
@@ -1831,7 +2111,7 @@
      unsigned int   wide, high;
 {
   /*
-   * this has to do the none-to-simple bit of converting the data in 'pic24'
+   * This has to do the none-too-simple bit of converting the data in 'pic24'
    * into something usable by X.
    *
    * There are two major approaches:  if we're displaying on a TrueColor
@@ -1840,12 +2120,12 @@
    * variation of RGB the X device in question wants.  No color allocation
    * is involved.
    *
-   * Alternately, if we're on a PseudoColor, GrayScale, StaticColor or 
-   * StaticGray display, we're going to continue to operate in an 8-bit 
+   * Alternately, if we're on a PseudoColor, GrayScale, StaticColor or
+   * StaticGray display, we're going to continue to operate in an 8-bit
    * mode.  (In that by this point, a 3/3/2 standard colormap has been
    * created for our use (though all 256 colors may not be unique...), and
    * we're just going to display the 24-bit picture by dithering with those
-   * colors
+   * colors.)
    *
    */
 
@@ -1861,7 +2141,7 @@
   if (dispDEEP == 1) {
     byte  *imagedata;
 
-    xim = XCreateImage(theDisp, theVisual, dispDEEP, XYPixmap, 0, NULL, 
+    xim = XCreateImage(theDisp, theVisual, dispDEEP, XYPixmap, 0, NULL,
 		        wide,  high, 32, 0);
     if (!xim) FatalError("couldn't create xim!");
 
@@ -1883,33 +2163,17 @@
     /* Non-ColorMapped Visuals:  TrueColor, DirectColor                     */
     /************************************************************************/
 
-    unsigned long r, g, b, rmask, gmask, bmask, xcol;
-    int           rshift, gshift, bshift, bperpix, bperline, border, cshift;
-    int           maplen;
+    unsigned long xcol;
+    int           bperpix, bperline;
     byte         *imagedata, *lip, *ip, *pp;
 
 
-    /* compute various shifting constants that we'll need... */
-
-    rmask = theVisual->red_mask;
-    gmask = theVisual->green_mask;
-    bmask = theVisual->blue_mask;
-
-    rshift = 7 - highbit(rmask);
-    gshift = 7 - highbit(gmask);
-    bshift = 7 - highbit(bmask);
-
-    maplen = theVisual->map_entries;
-    if (maplen>256) maplen=256;
-    cshift = 7 - highbit((u_long) (maplen-1));
-
     xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL,
 		        wide,  high, 32, 0);
     if (!xim) FatalError("couldn't create X image!");
 
     bperline = xim->bytes_per_line;
     bperpix  = xim->bits_per_pixel;
-    border   = xim->byte_order;
 
     imagedata = (byte *) malloc((size_t) (high * bperline));
     if (!imagedata) FatalError("couldn't malloc imagedata");
@@ -1923,85 +2187,141 @@
       FatalError(buf);
     }
 
+    screen_init();
 
-    lip = imagedata;  pp = pic24;
-    for (i=0; i<high; i++, lip+=bperline) {
-      for (j=0, ip=lip; j<wide; j++) {
-	r = *pp++;  g = *pp++;  b = *pp++;
-
-	/* shift r,g,b so that high bit of 8-bit color specification is 
-	 * aligned with high bit of r,g,b-mask in visual, 
-	 * AND each component with its mask,
-	 * and OR the three components together
-	 */
-
-	if (theVisual->class == DirectColor) {
-	  r = (u_long) directConv[(r>>cshift) & 0xff] << cshift;
-	  g = (u_long) directConv[(g>>cshift) & 0xff] << cshift;
-	  b = (u_long) directConv[(b>>cshift) & 0xff] << cshift;
-	}
-
-
-	/* shift the bits around */
-	if (rshift<0) r = r << (-rshift);
-	         else r = r >> rshift;
-	
-	if (gshift<0) g = g << (-gshift);
-	         else g = g >> gshift;
-
-	if (bshift<0) b = b << (-bshift);
-	         else b = b >> bshift;
-
-	r = r & rmask;
-	g = g & gmask;
-	b = b & bmask;
-
-	xcol = r | g | b;
-
-	if (bperpix == 32) {
-	  if (border == MSBFirst) {
-	    *ip++ = (xcol>>24) & 0xff;
-	    *ip++ = (xcol>>16) & 0xff;
-	    *ip++ = (xcol>>8)  & 0xff;
-	    *ip++ =  xcol      & 0xff;
-	  }
-	  else {  /* LSBFirst */
-	    *ip++ =  xcol      & 0xff;
-	    *ip++ = (xcol>>8)  & 0xff;
-	    *ip++ = (xcol>>16) & 0xff;
-	    *ip++ = (xcol>>24) & 0xff;
-	  }
-	}
-
-	else if (bperpix == 24) {
-	  if (border == MSBFirst) {
-	    *ip++ = (xcol>>16) & 0xff;
-	    *ip++ = (xcol>>8)  & 0xff;
-	    *ip++ =  xcol      & 0xff;
-	  }
-	  else {  /* LSBFirst */
-	    *ip++ =  xcol      & 0xff;
-	    *ip++ = (xcol>>8)  & 0xff;
-	    *ip++ = (xcol>>16) & 0xff;
-	  }
-	}
+#ifdef ENABLE_FIXPIX_SMOOTH
+    if (do_fixpix_smooth) {
+#if 0
+      /* If we wouldn't have to save the original pic24 image data,
+       * the following code would do the dither job by overwriting
+       * the image data, and the normal render code would then work
+       * without any change on that data.
+       * Unfortunately, this approach would hurt the xv assumptions...
+       */
+      if (bperpix < 24) {
+        FSBUF *fs = fs2_init(wide);
+        if (fs) {
+	  fs2_dither(fs, pic24, 3, high, wide);
+	  free(fs);
+        }
+      }
+#else
+      /* ...so we have to take a different approach with linewise
+       * dithering/rendering in a loop using a temporary line buffer.
+       */
+      if (bperpix < 24) {
+        FSBUF *fs = fs2_init(wide);
+        if (fs) {
+	  byte *row_buf = malloc((size_t)wide * 3);
+	  if (row_buf) {
+	    int nc = 3;
+	    byte *picp = pic24;  lip = imagedata;
+
+	    switch (bperpix) {
+	      case 8:
+	        for (i=0; i<high; i++, lip+=bperline, picp+=(size_t)wide*3) {
+	          memcpy(row_buf, picp, (size_t)wide * 3);
+	          nc = fs2_dither(fs, row_buf, nc, 1, wide);
+	          for (j=0, ip=lip, pp=row_buf; j<wide; j++) {
+	            xcol  = screen_rgb[0][*pp++];
+	            xcol |= screen_rgb[1][*pp++];
+	            xcol |= screen_rgb[2][*pp++];
+		    *ip++ = xcol & 0xff;
+	          }
+	        }
+		break;
+
+	      case 16:
+	        for (i=0; i<high; i++, lip+=bperline, picp+=(size_t)wide*3) {
+	          CARD16 *ip16 = (CARD16 *)lip;
+	          memcpy(row_buf, picp, (size_t)wide * 3);
+	          nc = fs2_dither(fs, row_buf, nc, 1, wide);
+	          for (j=0, pp=row_buf; j<wide; j++) {
+	            xcol  = screen_rgb[0][*pp++];
+	            xcol |= screen_rgb[1][*pp++];
+	            xcol |= screen_rgb[2][*pp++];
+		    *ip16++ = (CARD16)xcol;
+	          }
+	        }
+		break;
+	    } /* end switch */
+
+	    free(row_buf);
+	    free(fs);
 
-	else if (bperpix == 16) {
-	  if (border == MSBFirst) {
-	    *ip++ = (xcol>>8)  & 0xff;
-	    *ip++ =  xcol      & 0xff;
-	  }
-	  else {  /* LSBFirst */
-	    *ip++ =  xcol      & 0xff;
-	    *ip++ = (xcol>>8)  & 0xff;
+	    return xim;
 	  }
-	}
-
-	else if (bperpix == 8) {
-	  *ip++ =  xcol      & 0xff;
-	}
+	  free(fs);
+        }
       }
+#endif /* 0? */
     }
+#endif /* ENABLE_FIXPIX_SMOOTH */
+
+    lip = imagedata;  pp = pic24;
+
+    switch (bperpix) {
+      case 8:
+        for (i=0; i<high; i++, lip+=bperline) {
+          for (j=0, ip=lip; j<wide; j++) {
+	    xcol  = screen_rgb[0][*pp++];
+	    xcol |= screen_rgb[1][*pp++];
+	    xcol |= screen_rgb[2][*pp++];
+	    *ip++ = xcol & 0xff;
+          }
+        }
+        break;
+
+      case 16:
+        for (i=0; i<high; i++, lip+=bperline) {
+          CARD16 *ip16 = (CARD16 *)lip;
+          for (j=0; j<wide; j++) {
+	    xcol  = screen_rgb[0][*pp++];
+	    xcol |= screen_rgb[1][*pp++];
+	    xcol |= screen_rgb[2][*pp++];
+	    *ip16++ = (CARD16)xcol;
+          }
+        }
+        break;
+
+      case 24:
+        for (i=0; i<high; i++, lip+=bperline) {
+          for (j=0, ip=lip; j<wide; j++) {
+	    xcol  = screen_rgb[0][*pp++];
+	    xcol |= screen_rgb[1][*pp++];
+	    xcol |= screen_rgb[2][*pp++];
+#ifdef USE_24BIT_ENDIAN_FIX
+	    if (border == MSBFirst) {
+	      *ip++ = (xcol>>16) & 0xff;
+	      *ip++ = (xcol>>8)  & 0xff;
+	      *ip++ =  xcol      & 0xff;
+	    }
+	    else {  /* LSBFirst */
+	      *ip++ =  xcol      & 0xff;
+	      *ip++ = (xcol>>8)  & 0xff;
+	      *ip++ = (xcol>>16) & 0xff;
+	    }
+#else /* GRR:  this came with the FixPix patch, but I don't think it's right */
+	    *ip++ = (xcol >> 16) & 0xff;    /* (no way to test, however, so  */
+	    *ip++ = (xcol >> 8)  & 0xff;    /* it's left enabled by default) */
+	    *ip++ =  xcol        & 0xff;
+#endif
+          }
+        }
+        break;
+
+      case 32:
+        for (i=0; i<high; i++, lip+=bperline) {
+          CARD32 *ip32 = (CARD32 *)lip;
+          for (j=0; j<wide; j++) {
+	    xcol  = screen_rgb[0][*pp++];
+	    xcol |= screen_rgb[1][*pp++];
+	    xcol |= screen_rgb[2][*pp++];
+	    *ip32++ = (CARD32)xcol;
+          }
+        }
+        break;
+    } /* end switch */
   }
 
   else {
@@ -2019,17 +2339,17 @@
     bwdith = 0;
 
     if (ncols == 0 && dispDEEP != 1) {   /* do 'black' and 'white' dither */
-      /* note that if dispDEEP > 8, pic8 will just have '0' and '1' instead 
+      /* note that if dispDEEP > 8, pic8 will just have '0' and '1' instead
 	 of 'black' and 'white' */
 
-      pic8 = FSDither(pic24, PIC24, (int) wide, (int) high, NULL, NULL, NULL, 
-		      (int) ((dispDEEP <= 8) ? black : 0), 
+      pic8 = FSDither(pic24, PIC24, (int) wide, (int) high, NULL, NULL, NULL,
+		      (int) ((dispDEEP <= 8) ? black : 0),
 		      (int) ((dispDEEP <= 8) ? white : 1));
       bwdith = 1;
     }
 
     else {                               /* do color dither using stdcmap */
-      pic8 = Do332ColorDither(pic24, NULL, (int) wide, (int) high, 
+      pic8 = Do332ColorDither(pic24, NULL, (int) wide, (int) high,
 			      NULL, NULL, NULL,
 			      stdrdisp, stdgdisp, stdbdisp, 256);
     }
@@ -2046,14 +2366,14 @@
     case 8: {
       byte  *imagedata, *ip, *pp;
       int   j, imWIDE, nullCount;
-  
+
       nullCount = (4 - (wide % 4)) & 0x03;  /* # of padding bytes per line */
       imWIDE = wide + nullCount;
- 
+
       /* Now create the image data - pad each scanline as necessary */
       imagedata = (byte *) malloc((size_t) (imWIDE * high));
       if (!imagedata) FatalError("couldn't malloc imagedata");
-      
+
       for (i=0, pp=pic8, ip=imagedata; i<high; i++) {
 	if (((i+1)&0x7f) == 0) WaitCursor();
 
@@ -2066,7 +2386,7 @@
       }
 
       xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0,
-			 (char *) imagedata,  wide,  high, 
+			 (char *) imagedata,  wide,  high,
 			 32, imWIDE);
       if (!xim) FatalError("couldn't create xim!");
     }
@@ -2074,14 +2394,14 @@
 
 
       /*********************************/
-      
+
     case 4: {
       byte         *imagedata, *ip, *pp;
       byte         *lip;
       int           bperline, half, j;
       unsigned long xcol;
-      
-      xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL, 
+
+      xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL,
 			  wide,  high, 32, 0);
       if (!xim) FatalError("couldn't create xim!");
 
@@ -2123,14 +2443,14 @@
       else FatalError("This display's too bizarre.  Can't create XImage.");
     }
       break;
-      
+
 
 
       /*********************************/
-      
+
     case 2: {  /* by M.Kossa@frec.bull.fr (Marc Kossa) */
                /* MSBFirst mods added by dale@ntg.com (Dale Luck) */
-               /* additional fixes by  evol@infko.uni-koblenz.de 
+               /* additional fixes by  evol@infko.uni-koblenz.de
 		  (Randolf Werner) for NeXT 2bit grayscale with MouseX */
 
       byte  *imagedata, *ip, *pp;
@@ -2138,7 +2458,7 @@
       int  bperline, half, j;
       unsigned long xcol;
 
-      xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL, 
+      xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL,
 			  wide,  high, 32, 0);
       if (!xim) FatalError("couldn't create xim!");
 
@@ -2201,22 +2521,22 @@
 	  }
 	}
       }
-      
+
       else FatalError("This display's too bizarre.  Can't create XImage.");
     }
       break;
-      
+
 
       /*********************************/
-    
+
     case 6: {
       byte  *imagedata, *lip, *ip, *pp;
       int  bperline;
-    
-      xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL, 
+
+      xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL,
 			  wide,  high, 32, 0);
       if (!xim) FatalError("couldn't create xim!");
-      
+
       if (xim->bits_per_pixel != 8)
 	FatalError("This display's too bizarre.  Can't create XImage.");
 
@@ -2238,7 +2558,7 @@
     }
       break;
 
-      
+
       /*********************************/
 
     case 15:
@@ -2282,7 +2602,7 @@
     }
       break;
 
-      
+
       /*********************************/
 
       /* this wouldn't seem likely to happen, but what the heck... */
@@ -2295,7 +2615,7 @@
 
       imagedata = (byte *) malloc((size_t) (4*wide*high));
       if (!imagedata) FatalError("couldn't malloc imagedata");
-      
+
       xim = XCreateImage(theDisp,theVisual,dispDEEP,ZPixmap,0,
 			 (char *) imagedata, wide, high, 32, 0);
       if (!xim) FatalError("couldn't create xim!");
@@ -2303,7 +2623,7 @@
       bperpix = xim->bits_per_pixel;
 
       pp = pic8;
-      
+
       if (xim->byte_order == MSBFirst) {
 	for (i=wide*high, ip=imagedata; i>0; i--,pp++) {
 	  if (((i+1)&0x1ffff) == 0) WaitCursor();
@@ -2327,7 +2647,7 @@
 	  if (bperpix == 32) *ip++ = 0;
 	}
       }
-    }     
+    }
       break;
 
     }   /* end of the switch */
@@ -2346,7 +2666,7 @@
      int mode;
 {
   /* move checkmark */
-  conv24MB.flags[CONV24_8BIT]  = (mode==PIC8);  
+  conv24MB.flags[CONV24_8BIT]  = (mode==PIC8);
   conv24MB.flags[CONV24_24BIT] = (mode==PIC24);
 
   if (mode == PIC24) {
@@ -2383,15 +2703,13 @@
 void Change824Mode(mode)
      int mode;
 {
-  static int oldcmapmode = -1;
-
   if (mode == picType) return;   /* same mode, do nothing */
 
   Set824Menus(mode);
 
   if (!pic) {  /* done all we wanna do when there's no pic */
     picType = mode;
-    return;  
+    return;
   }
 
   /* should probably actually *do* something involving colors, regenrating
@@ -2453,6 +2771,7 @@
 
 
 /***********************/
+#if 0 /* NOTUSED */
 static int highbit(ul)
 unsigned long ul;
 {
@@ -2465,6 +2784,7 @@
   for (i=31; ((ul & hb) == 0) && i>=0;  i--, ul<<=1);
   return i;
 }
+#endif /* 0 - NOTUSED */
 
 
 
@@ -2474,7 +2794,7 @@
      int   ptype, w,h, sx,sy,sw,sh;
 {
   /* mallocs and returns the selected subimage (sx,sy,sw,sh) of pic.
-     selection is guaranteed to be within pic boundaries.  
+     selection is guaranteed to be within pic boundaries.
      NEVER RETURNS NULL */
 
   byte *rpic, *sp, *dp;
@@ -2520,7 +2840,6 @@
      installs the new pic and all that...  Returns '0' on failure */
 
   int   rv;
-  char  loadName[256];
 
   if (padPic)      free(padPic);
   if (holdcomment) free(holdcomment);
@@ -2530,8 +2849,8 @@
 
   rv = 1;
 
-  if ((mode != PAD_LOAD) && (wide == pWIDE && high == pHIGH && opaque==100)) {
-    ErrPopUp("Padding to same size as pic while fully opaque has no effect.", 
+  if ((mode != PAD_LOAD) && (wide == cWIDE && high == cHIGH && opaque==100)) {
+    ErrPopUp("Padding to same size as pic while fully opaque has no effect.",
 	     "\nI see");
     return 0;
   }
@@ -2539,8 +2858,8 @@
   WaitCursor();
 
   if      (mode == PAD_SOLID) rv = doPadSolid(str, wide, high, opaque,omode);
-  else if (mode == PAD_BGGEN) rv = doPadBggen(str, wide, high, opaque,omode); 
-  else if (mode == PAD_LOAD)  rv = doPadLoad (str, wide, high, opaque,omode); 
+  else if (mode == PAD_BGGEN) rv = doPadBggen(str, wide, high, opaque,omode);
+  else if (mode == PAD_LOAD)  rv = doPadLoad (str, wide, high, opaque,omode);
 
   SetCursors(-1);
 
@@ -2556,7 +2875,7 @@
 
   return 1;
 }
-	      
+
 
 /***********************************/
 int LoadPad(pinfo, fname)
@@ -2645,7 +2964,7 @@
       return 0;
     }
   }
-  
+
 
 
   pic24 = (byte *) malloc(wide * high * 3 * sizeof(byte));
@@ -2656,7 +2975,7 @@
     return 0;
   }
 
-  
+
   /* fill pic24 with solidRGB */
   for (i=0,pp=pic24; i<wide*high; i++, pp+=3) {
     pp[0] = (solidRGB>>16) & 0xff;
@@ -2676,6 +2995,9 @@
      char *str;
      int   wide, high, opaque,omode;
 {
+#ifndef USE_MKSTEMP
+  int tmpfd;
+#endif
   int i;
   byte *bgpic24;
   char syscmd[512], fname[128], errstr[512];
@@ -2697,7 +3019,18 @@
 #else
   strcpy(fname, "Sys$Disk:[]xvuXXXXXX");
 #endif
+#ifdef USE_MKSTEMP
+  close(mkstemp(fname));
+#else
   mktemp(fname);
+  tmpfd = open(fname, O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR);
+  if (tmpfd < 0) {
+    sprintf(errstr, "Error: can't create temporary file %s", fname);
+    ErrPopUp(errstr, "\nDoh!");
+    return 0;
+  }
+  close(tmpfd);
+#endif
 
   /* run bggen to generate the background */
   sprintf(syscmd, "bggen -g %dx%d %s > %s", wide, high, str, fname);
@@ -2713,7 +3046,7 @@
     ErrPopUp(errstr, "\nDoh!");
     return 0;
   }
-    
+
 
   /* read the file that's been created */
   if (!ReadImageFile1(fname, &pinfo)) {
@@ -2791,7 +3124,7 @@
      int   wide, high, opaque,omode;
 {
   /* copies 'pic' onto the given 24-bit background image, converts back to
-     8-bit (if necessary), and loads up pad* variables.  
+     8-bit (if necessary), and loads up pad* variables.
      frees pic24 if necessary */
 
   byte *pp, *p24;
@@ -2806,30 +3139,30 @@
 
   /* copy 'pic' centered onto pic24.  */
 
-  sx = (wide - pWIDE) / 2;
-  sy = (high - pHIGH) / 2;
-  
-  for (py = 0; py<pHIGH; py++) {
-    ProgressMeter(0, pHIGH-1, py, "Pad");
+  sx = (wide - cWIDE) / 2;
+  sy = (high - cHIGH) / 2;
+
+  for (py = 0; py<cHIGH; py++) {
+    ProgressMeter(0, cHIGH-1, py, "Pad");
     if ((py & 0x1f)==0) WaitCursor();
 
     p24y = sy + py;
     if (p24y >= 0 && p24y < high) {
-      for (px=0; px<pWIDE; px++) {
+      for (px=0; px<cWIDE; px++) {
 	p24x = sx + px;
 	if (p24x >= 0 && p24x < wide) {
 	  p24 = pic24 + (p24y*wide  + p24x)*3;
-	  
-	  
+
+
 	  if (picType == PIC24) {                       /* src is PIC24 */
-	    pp  = pic + (py * pWIDE + px)  *3;
+	    pp  = cpic + (py * cWIDE + px)  *3;
 	    r = pp[0];  g = pp[1];  b = pp[2];
 	  }
 	  else {                                        /* src is PIC8 */
-	    pp  = pic + (py*pWIDE + px);
+	    pp  = cpic + (py*cWIDE + px);
 	    r = rMap[*pp];  g = gMap[*pp];  b = bMap[*pp];
 	  }
-	  
+
 	  if (omode == PAD_ORGB) {
 	    rval = (r * fg) / 100 + ((int) p24[0] * bg) / 100;
 	    gval = (g * fg) / 100 + ((int) p24[1] * bg) / 100;
@@ -2845,7 +3178,7 @@
 
 	    if (omode == PAD_OINT) {
 	      h = fh;
-	      s = fs;  
+	      s = fs;
 	      /* v = (fv * fg) / 100.0 + (bv * bg) / 100.0; */
 	      v = (fv * bv * bw) + (fv * fw);
 	    }
@@ -2855,18 +3188,18 @@
 	      h = fh;
 	      /* s = (fs * fg) / 100.0 + (bs * bg) / 100.0; */
 	      s = (fs * bs * bw) + (fs * fw);
-	      v = fv;  
+	      v = fv;
 	    }
 	    else if (omode == PAD_OHUE) {   /* the hard one! */
-	      int fdeg,bdeg,len1,len2;
-		
+	      int fdeg,bdeg;
+
 	      fdeg = (fh<0) ? -1 : (int) floor(fh + 0.5);
 	      bdeg = (bh<0) ? -1 : (int) floor(bh + 0.5);
 
 	      if (fdeg>=0 && bdeg>=0) {           /* both are colors */
 		/* convert H,S onto x,y coordinates on the colorwheel for
 		   constant V */
-		
+
 		double fx,fy, bx,by, ox,oy;
 
 		if (fg == 100 || bg == 100) {   /* E-Z special case */
@@ -2874,17 +3207,17 @@
 		  else         { h = bh;  s = fs;  v=fv; }
 		}
 		else {  /* general case */
-		  
+
 		  fh *= (3.14159 / 180.0);    /* -> radians */
 		  bh *= (3.14159 / 180.0);
-		  
+
 		  fx = fs * cos(fh);  fy = fs * sin(fh);
 		  bx = bs * cos(bh);  by = bs * sin(bh);
-		  
+
 		  /* compute pt. on line between fx,fy and bx,by */
 		  ox = (fx * (fg/100.0)) + (bx * (bg/100.0));
 		  oy = (fy * (fg/100.0)) + (by * (bg/100.0));
-		  
+
 		  /* convert ox,oy back into hue,sat */
 		  s = sqrt((ox * ox) + (oy * oy));
 		  if (ox == 0.0) {
@@ -2897,7 +3230,7 @@
 		    while (h<0.0) h += 360.0;
 		    while (h>=360.0) h -= 360.0;
 		  }
-		  
+
 		  v = fv;
 		}
 	      }
@@ -2924,7 +3257,7 @@
 	    v = (fv * bv * bw) + (fv * fw);
 	    hsv2rgb(h,s,v, &rval,&gval,&bval);
 	  }
-	  
+
 	  RANGE(rval, 0, 255);  RANGE(gval, 0, 255);  RANGE(bval, 0, 255);
 	  *p24++ = rval;  *p24++ = gval;  *p24++ = bval;
 	}
@@ -2958,16 +3291,19 @@
 
 
 /*******************************/
-static int ReadImageFile1(name, pinfo) 
+static int ReadImageFile1(name, pinfo)
      char    *name;
      PICINFO *pinfo;
 {
   int  i, ftype;
-  char basefname[128], uncompname[128], errstr[256], *uncName, *readname;
+  char uncompname[128], errstr[256], *uncName, *readname;
+#ifdef VMS
+  char basefname[128];
+#endif
 
   ftype = ReadFileType(name);
 
-  if (ftype == RFT_COMPRESS) {    /* handle compressed/gzipped files */
+  if ((ftype == RFT_COMPRESS) || (ftype == RFT_BZIP2)) {  /* handle .Z,gz,bz2 */
 #ifdef VMS
     basefname[0] = '\0';
     strcpy(basefname, name);     /* remove trailing .Z */
@@ -2976,8 +3312,8 @@
 #else
     uncName = name;
 #endif
-    
-    if (UncompressFile(uncName, uncompname)) {
+
+    if (UncompressFile(uncName, uncompname, ftype)) {
       ftype = ReadFileType(uncompname);
       readname = uncompname;
     }
@@ -3004,7 +3340,7 @@
     KillPageFiles(pinfo->pagebname, pinfo->numpages);
 
     if (!i || (i && (pinfo->w<=0 || pinfo->h<=0))) {
-      if (i) { 
+      if (i) {
 	if (pinfo->pic)     free(pinfo->pic);
 	if (pinfo->comment) free(pinfo->comment);
       }
@@ -3018,9 +3354,3 @@
 
   return 1;
 }
-
-
-
-    
-
-
diff -ru xv-3.10a/xvinfo.c xv-3.10a-enhancements/xvinfo.c
--- xv-3.10a/xvinfo.c	1994-12-22 14:34:41.000000000 -0800
+++ xv-3.10a-enhancements/xvinfo.c	2007-05-13 14:11:03.000000000 -0700
@@ -1,4 +1,4 @@
-/* 
+/*
  * xvinfo.c - 'Info' box handling functions
  *
  * callable functions:
@@ -8,8 +8,8 @@
  *                             maps/unmaps window, etc.
  *   RedrawInfo(x,y,w,h)    -  called by 'expose' events
  *   SetInfoMode(mode)      -  changes amount of info Info window shows
- *   SetISTR(st, fmt, args) - sprintf's into ISTR #st.  Redraws it in window 
- *   char *GetISTR(st)      - returns pointer to ISTR #st, or NULL if st bogus
+ *   SetISTR(st, fmt, args) -  sprintf's into ISTR #st.  Redraws it in window
+ *   char *GetISTR(st)      -  returns pointer to ISTR #st, or NULL if st bogus
  */
 
 #include "copyright.h"
@@ -43,20 +43,20 @@
 
 /***************************************************/
 void CreateInfo(geom)
-char *geom;
+     const char *geom;
 {
-  infoW = CreateWindow("xv info", "XVinfo", geom, INFOWIDE, INFOHIGH, 
+  infoW = CreateWindow("xv info", "XVinfo", geom, INFOWIDE, INFOHIGH,
 		       infofg, infobg, 0);
   if (!infoW) FatalError("can't create info window!");
-  
-  pennPix = XCreatePixmapFromBitmapData(theDisp, infoW, 
+
+  pennPix = XCreatePixmapFromBitmapData(theDisp, infoW,
 	(char *) penn_bits, penn_width, penn_height, infofg, infobg, dispDEEP);
 
   pnetPix = XCreatePixmapFromBitmapData(theDisp,infoW,
-	(char *) pennnet_bits, pennnet_width, pennnet_height, 
+	(char *) pennnet_bits, pennnet_width, pennnet_height,
 	infofg, infobg, dispDEEP);
 }
-  
+
 
 /***************************************************/
 void InfoBox(vis)
@@ -64,7 +64,7 @@
 {
   if (vis) XMapRaised(theDisp, infoW);
   else     XUnmapWindow(theDisp, infoW);
-  
+
   infoUp = vis;
 }
 
@@ -74,23 +74,23 @@
      int x,y,w,h;
 {
   int  i;
-  
+
   XSetForeground(theDisp, theGC, infofg);
   XSetBackground(theDisp, theGC, infobg);
 
   /* draw the two icons */
   XCopyArea(theDisp, pennPix, infoW, theGC, 0, 0, penn_width, penn_height,
 	    36 - penn_width/2, 36 - penn_height/2);
-  XCopyArea(theDisp, pnetPix, infoW, theGC, 0, 0, pennnet_width, 
-	    pennnet_height, INFOWIDE - 36 - pennnet_width/2, 
+  XCopyArea(theDisp, pnetPix, infoW, theGC, 0, 0, pennnet_width,
+	    pennnet_height, INFOWIDE - 36 - pennnet_width/2,
 	    36 - pennnet_height/2);
 
   /* draw the credits */
-  sprintf(str,"XV   -   %s",REVDATE);
-  CenterString(infoW, INFOWIDE/2, 36-LINEHIGH, str);
+  snprintf(dummystr, sizeof(dummystr), "XV   -   %s", REVDATE);
+  CenterString(infoW, INFOWIDE/2, 36-LINEHIGH, dummystr);
   CenterString(infoW, INFOWIDE/2, 36,
 	       "by John Bradley  (bradley@dccs.upenn.edu)");
-  CenterString(infoW, INFOWIDE/2, 36+LINEHIGH, 
+  CenterString(infoW, INFOWIDE/2, 36+LINEHIGH,
 	       "Copyright 1994, John Bradley  -  All Rights Reserved");
 
 
@@ -131,16 +131,16 @@
 static void drawFieldName(fnum)
      int fnum;
 {
-  static char *fname[7] = { "Filename:", "Format:", "Resolution:", "Cropping:",
-			    "Expansion:", "Selection:", "Colors:" };
+  static const char *fname[7] = { "Filename:", "Format:", "Resolution:",
+	"Cropping:", "Expansion:", "Selection:", "Colors:" };
 
   XSetForeground(theDisp, theGC, infofg);
   XSetBackground(theDisp, theGC, infobg);
 
   if (infoMode == INF_NONE || infoMode == INF_STR) return;
   if (infoMode == INF_PART && fnum>=3) return;
-  
-  XDrawString(theDisp, infoW, theGC, 10, TOPBASE + fnum*LINEHIGH, 
+
+  XDrawString(theDisp, infoW, theGC, 10, TOPBASE + fnum*LINEHIGH,
 	      fname[fnum], (int) strlen(fname[fnum]));
 }
 
@@ -150,7 +150,7 @@
      int st;
 {
   /* erase area of string, and draw it with new contents */
-  
+
   if (infoMode == INF_NONE) return;
   if (infoMode == INF_STR && st > ISTR_WARNING) return;
   if (infoMode == INF_PART && st > ISTR_RES) return;
@@ -170,12 +170,12 @@
   }
   else {
     XSetForeground(theDisp, theGC, infobg);
-    XFillRectangle(theDisp, infoW, theGC, 
-		   STLEFT, TOPBASE - ASCENT + (st-ISTR_FILENAME)*LINEHIGH, 
+    XFillRectangle(theDisp, infoW, theGC,
+		   STLEFT, TOPBASE - ASCENT + (st-ISTR_FILENAME)*LINEHIGH,
 		   (u_int) INFOWIDE-STLEFT, (u_int) LINEHIGH);
     XSetForeground(theDisp, theGC, infofg);
     XDrawString(theDisp, infoW, theGC, STLEFT,
-		TOPBASE	+ (st-ISTR_FILENAME)*LINEHIGH,	istrs[st], 
+		TOPBASE + (st-ISTR_FILENAME)*LINEHIGH, istrs[st],
 		(int) strlen(istrs[st]));
   }
 }
@@ -187,21 +187,21 @@
      int mode;
 {
   int y1, y2;
-  
+
   infoMode = mode;
   if (infoUp) {   /* only do this if window is mapped */
     y1 = TOPBASE - ASCENT;
     y2 = INFOHIGH-43;
-    
+
     XSetForeground(theDisp, theGC, infobg);
-    
-    XFillRectangle(theDisp,infoW,theGC,0,y1, 
+
+    XFillRectangle(theDisp,infoW,theGC,0,y1,
 		   (u_int) INFOWIDE, (u_int) y2-y1);
-    XFillRectangle(theDisp,infoW,theGC,0,INFOHIGH-39, 
+    XFillRectangle(theDisp,infoW,theGC,0,INFOHIGH-39,
 		   (u_int) INFOWIDE, (u_int) 17);
-    XFillRectangle(theDisp,infoW,theGC,0,INFOHIGH-19, 
+    XFillRectangle(theDisp,infoW,theGC,0,INFOHIGH-19,
 		   (u_int) INFOWIDE, (u_int) 17);
-    
+
     drawStrings();
   }
 }
@@ -233,14 +233,14 @@
 
   if (stnum>=0 && stnum < NISTR) {
     fmt = va_arg(args, char *);
-    if (fmt) vsprintf(istrs[stnum], fmt, args);
+    if (fmt) vsnprintf(istrs[stnum], sizeof(istrs[stnum]), fmt, args);
     else istrs[stnum][0] = '\0';
   }
   va_end(args);
-  
+
   if (stnum == ISTR_COLOR) {
-    sprintf(istrs[ISTR_INFO], "%s  %s  %s", formatStr, 
-	    (picType==PIC8) ? "8-bit mode." : "24-bit mode.",
+    snprintf(istrs[ISTR_INFO], sizeof(istrs[ISTR_INFO]), "%s  %s  %s",
+	    formatStr, (picType==PIC8) ? "8-bit mode." : "24-bit mode.",
 	    istrs[ISTR_COLOR]);
   }
 
@@ -250,22 +250,22 @@
     XFlush(theDisp);
   }
 
-  if (ctrlUp && (stnum == ISTR_INFO || stnum == ISTR_WARNING || 
+  if (ctrlUp && (stnum == ISTR_INFO || stnum == ISTR_WARNING ||
 		 stnum == ISTR_COLOR)) {
     DrawCtrlStr();
     XFlush(theDisp);
   }
 
-  if (anyBrowUp && (stnum == ISTR_WARNING || stnum == ISTR_INFO) 
+  if (anyBrowUp && (stnum == ISTR_WARNING || stnum == ISTR_INFO)
       && strlen(istrs[stnum])) {
     SetBrowStr(istrs[stnum]);
     XFlush(theDisp);
   }
 
-  if (stnum == ISTR_WARNING && !ctrlUp && !infoUp && !anyBrowUp && 
+  if (stnum == ISTR_WARNING && !ctrlUp && !infoUp && !anyBrowUp &&
       strlen(istrs[stnum])) {
     OpenAlert(istrs[stnum]);
-    sleep(3);
+    sleep(1);  /* was 3, but _really_ slow for TIFFs with unknown tags... */
     CloseAlert();
   }
 }
diff -ru xv-3.10a/xviris.c xv-3.10a-enhancements/xviris.c
--- xv-3.10a/xviris.c	1994-12-22 14:34:47.000000000 -0800
+++ xv-3.10a-enhancements/xviris.c	2007-05-13 17:49:50.000000000 -0700
@@ -14,7 +14,7 @@
  *
  *      This code should work on machines with any byte order.
  *
- *	Could someone make this run real fast using multiple processors 
+ *	Could someone make this run real fast using multiple processors
  *	or how about using memory mapped files to speed it up?
  *
  *				Paul Haeberli - 1991
@@ -44,7 +44,7 @@
     u_short 	zsize;
     u_long 	min;
     u_long 	max;
-    u_long	wastebytes;	
+    u_long	wastebytes;
     char 	name[80];
     u_long	colormap;
 
@@ -80,7 +80,7 @@
 #define CHANOFFSET(z)	(3-(z))	/* this is byte order dependent */
 
 
-static int      irisError     PARM((char *, char *));
+static int      irisError     PARM((const char *, const char *));
 static byte    *getimagedata  PARM((FILE *, IMAGE *));
 static void     interleaverow PARM((byte *, byte *, int, int));
 static void     expandrow     PARM((byte *, byte *, int));
@@ -97,8 +97,8 @@
 static void     putlong       PARM((FILE *, u_long));
 
 
-static char *loaderr;
-static char *bname;
+static const char *loaderr;
+static const char *bname;
 
 /*****************************************************/
 int LoadIRIS(fname, pinfo)
@@ -112,7 +112,8 @@
   IMAGE   img;
   byte   *rawdata, *rptr;
   byte   *pic824,  *bptr;
-  int     trunc, i, j;
+  int     trunc, i, npixels, bufsize;
+  u_short ii, jj;
   long    filesize;
 
   trunc = 0;
@@ -133,11 +134,11 @@
   img.imagic = getshort(fp);
   img.type   = getshort(fp);
   img.dim    = getshort(fp);
-  img.xsize  = getshort(fp);
+  img.xsize  = getshort(fp);  /* u_short */
   img.ysize  = getshort(fp);
   img.zsize  = getshort(fp);
 
-  if (FERROR(fp)) {
+  if (FERROR(fp) || img.xsize == 0 || img.ysize == 0 || img.zsize == 0) {
     fclose(fp);
     return irisError(bname, "error in header info");
   }
@@ -148,7 +149,7 @@
   }
 
   rawdata = getimagedata(fp, &img);
-  if (!rawdata) {   
+  if (!rawdata) {
     fclose(fp);
     if (loaderr) irisError(bname, loaderr);
     return 0;
@@ -162,18 +163,22 @@
   /* got the raw image data.  Convert to an XV image (1,3 bytes / pix) */
 
 
+  npixels = img.xsize * img.ysize;  /* 65535*65535 = (2^32 - 131071) max */
+  if (npixels/img.xsize != img.ysize)
+    return irisError(bname, "IRIS image dimensions out of range");
+
   if (img.zsize < 3) {  /* grayscale */
-    pic824 = (byte *) malloc((size_t) img.xsize * img.ysize);
+    pic824 = (byte *) malloc((size_t) npixels);
     if (!pic824) FatalError("couldn't malloc pic824 in LoadIRIS()");
 
     /* copy plane 3 from rawdata into pic824, inverting pic vertically */
-    for (i=0, bptr=pic824; i<(int) img.ysize; i++) {
-      rptr = rawdata + 3 + ((img.ysize - 1) - i) * (img.xsize * 4);
-      for (j=0; j<(int) img.xsize; j++, bptr++, rptr+=4) *bptr = *rptr;
+    for (ii=0, bptr=pic824; ii<img.ysize; ii++) {
+      rptr = rawdata + 3 + ((img.ysize - 1) - ii) * (img.xsize * 4);
+      for (jj=0; jj<img.xsize; jj++, bptr++, rptr+=4) *bptr = *rptr;
     }
 
 
-    for (i=0; i<256; i++) 
+    for (i=0; i<256; i++)
       pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;
 
     pinfo->pic  = pic824;
@@ -188,13 +193,17 @@
   }
 
   else {  /* truecolor */
-    pic824 = (byte *) malloc((size_t) img.xsize * img.ysize * 3);
+    bufsize = 3 * npixels;
+    if (npixels/img.xsize != img.ysize || bufsize/3 != npixels) {
+      return irisError(bname, "IRIS image dimensions out of range");
+    }
+    pic824 = (byte *) malloc((size_t) bufsize);
     if (!pic824) FatalError("couldn't malloc pic824 in LoadIRIS()");
-    
+
     /* copy plane 3 from rawdata into pic824, inverting pic vertically */
-    for (i=0, bptr=pic824; i<(int) img.ysize; i++) {
-      rptr = rawdata + ((img.ysize - 1) - i) * (img.xsize * 4);
-      for (j=0; j<(int) img.xsize; j++, rptr+=4) {
+    for (ii=0, bptr=pic824; ii<img.ysize; ii++) {
+      rptr = rawdata + ((img.ysize - 1) - ii) * (img.xsize * 4);
+      for (jj=0; jj<img.xsize; jj++, rptr+=4) {
 	*bptr++ = rptr[3];
 	*bptr++ = rptr[2];
 	*bptr++ = rptr[1];
@@ -220,12 +229,12 @@
   pinfo->comment = (char *) NULL;
 
   return 1;
-}     
+}
 
 
 /*******************************************/
 static int irisError(name, st)
-  char *name, *st;
+  const char *name, *st;
 {
   SetISTR(ISTR_WARNING,"%s: %s", name, st);
   return 0;
@@ -237,41 +246,53 @@
      FILE  *fp;
      IMAGE *img;
 {
-  /* read in a B/W RGB or RGBA iris image file and return a 
+  /* read in a B/W RGB or RGBA iris image file and return a
      pointer to an array of 4-byte pixels, arranged ABGR, NULL on error */
 
   byte   *base, *lptr;
   byte   *verdat;
-  int     y, z, pos, len, tablen;
+  int     y, z, tablen;
   int     xsize, ysize, zsize;
   int     bpp, rle, cur, badorder;
-  int     rlebuflen;
+  int     rlebuflen, npixels, bufsize;
 
 
   rle     = ISRLE(img->type);
   bpp     = BPP(img->type);
-  loaderr = (char *) NULL;
+  loaderr = (const char *) NULL;
 
   if (bpp != 1) {
     loaderr = "image must have 1 byte per pix chan";
     return (byte *) NULL;
   }
 
-  xsize = img->xsize;
+  xsize = img->xsize;   /* all three are > 0 (checked by caller), <= 65535 */
   ysize = img->ysize;
   zsize = img->zsize;
+  npixels = xsize * ysize;  /* 65535*65535 = (2^32 - 131071) max */
+  if (npixels/xsize != ysize) {
+    loaderr = "IRIS image dimensions out of range";
+    return (byte *) NULL;
+  }
 
   if (rle) {
     byte *rledat;
     u_long *starttab, *lengthtab;
 
-    rlebuflen = 2 * xsize + 10;
+    rlebuflen = 2 * xsize + 10;  /* 10 <= rlebuflen <= 131080 */
     tablen    = ysize * zsize;
-    starttab  = (u_long *) malloc((size_t) tablen * sizeof(long));
-    lengthtab = (u_long *) malloc((size_t) tablen * sizeof(long));
+    bufsize   = tablen * sizeof(long);
+
+    if (tablen/ysize != zsize || bufsize/tablen != sizeof(long)) {
+      loaderr = "IRIS image dimensions out of range";
+      return (byte *)NULL;
+    }
+
+    starttab  = (u_long *) malloc((size_t) bufsize);
+    lengthtab = (u_long *) malloc((size_t) bufsize);
     rledat    = (byte *)   malloc((size_t) rlebuflen);
 
-    if (!starttab || !lengthtab || !rledat) 
+    if (!starttab || !lengthtab || !rledat)
       FatalError("out of memory in LoadIRIS()");
 
     fseek(fp, 512L, 0);
@@ -298,7 +319,13 @@
     fseek(fp, (long) (512 + 2*tablen*4), 0);
     cur = 512 + 2*tablen*4;
 
-    base = (byte *) malloc((size_t) (xsize*ysize+TAGLEN) * 4);
+    bufsize = 4 * (npixels+TAGLEN);
+    if (bufsize/4 != (npixels+TAGLEN)) {
+      loaderr = "Bogus IRIS File!";
+      free(starttab);  free(lengthtab);  free(rledat);
+      return (byte *)NULL;
+    }
+    base = (byte *) malloc((size_t) bufsize);
     if (!base) FatalError("out of memory in LoadIRIS()");
 
     addimgtag(base,xsize,ysize);
@@ -349,12 +376,17 @@
   }      /* end of RLE case */
 
   else {  /* not RLE */
+    bufsize = 4 * (npixels+TAGLEN);
+    if (bufsize/4 != (npixels+TAGLEN)) {
+      loaderr = "Bogus IRIS File!";
+      return (byte *)NULL;
+    }
+    base   = (byte *) malloc((size_t) bufsize);
     verdat = (byte *) malloc((size_t) xsize);
-    base   = (byte *) malloc((size_t) (xsize*ysize+TAGLEN) * 4);
     if (!base || !verdat) FatalError("out of memory in LoadIRIS()");
 
     addimgtag(base,xsize,ysize);
-    
+
     fseek(fp,512L,0);
 
     for (z=0; z<zsize; z++) {
@@ -457,7 +489,7 @@
      byte *dptr;
      int   xsize, ysize;
 {
-  /* this is used to extract image data from core dumps. 
+  /* this is used to extract image data from core dumps.
      I doubt this is necessary...  --jhb */
 
   dptr    = dptr + (xsize * ysize * 4);
@@ -499,26 +531,31 @@
      int   ptype, w, h, numcols, colorstyle;
 {
   /* writes a greyscale or 24-bit RGB IRIS file to the already open
-     stream, rle compressed */
+     stream, RLE-compressed; returns 0 on success, -1 on minor error */
 
   IMAGE img;
-  int     i, j, pos, len, tablen, rlebuflen, zsize;
+  int     i, j, pos, len, tablen, rlebuflen, zsize, npixels, bufsize;
   u_long *starttab, *lengthtab;
   byte   *rlebuf, *pptr;
   byte   *lumbuf, *lptr, *longpic;
 
   xvbzero((char *) &img, sizeof(IMAGE));
-  
+
   /* write header information */
   fwrite(&img, sizeof(IMAGE), (size_t) 1, fp);
   fseek(fp, 0L, 0);
 
+  if (w <= 0 || h <= 0 || w > 65535 || h > 65535) {
+    SetISTR(ISTR_WARNING, "image dimensions too large for IRIS format");
+    return -1;
+  }
+
   /* load up header */
   img.imagic = IMAGIC;
   img.type   = ITYPE_RLE | (1 & BPPMASK);   /* RLE, 1 byteperpix */
   img.dim    = (colorstyle == F_FULLCOLOR) ? 3 : 2;
-  img.xsize  = w;
-  img.ysize  = h;
+  img.xsize  = (u_short)w;
+  img.ysize  = (u_short)h;
   img.zsize  = zsize = (colorstyle == F_FULLCOLOR) ? 3 : 1;
   img.min    = 0;
   img.max    = 255;
@@ -537,22 +574,33 @@
   if (ferror(fp)) { fclose(fp);  return -1; }
 
   /* allocate RLE compression tables & stuff */
-  rlebuflen = 2*w + 10;
-  tablen    = h * zsize;
+  rlebuflen = 2*w + 10;   /* 10 <= rlebuflen <= 131080 */
+  tablen    = h * zsize;  /*  1 <= tablen    <= 196605 */
 
+  /* no overflow is possible with any of these (given check on w,h above): */
   starttab  = (u_long *) malloc((size_t) tablen * sizeof(long));
   lengthtab = (u_long *) malloc((size_t) tablen * sizeof(long));
   rlebuf    = (byte *)   malloc((size_t) rlebuflen);
-  lumbuf    = (byte *)   malloc((size_t) w * 4);
+  lumbuf    = (byte *)   malloc((size_t) w * 4);   /* 262140 max */
 
-  if (!starttab || !lengthtab || !rlebuf || !lumbuf) 
+  if (!starttab || !lengthtab || !rlebuf || !lumbuf)
     FatalError("out of memory in WriteIRIS()");
 
   pos = 512 + 2 * (tablen * 4);
   fseek(fp, (long) pos, 0);
 
   /* convert image into 4-byte per pix image that the compress routines want */
-  longpic = (byte *) malloc((size_t) w * h * 4);
+  npixels = w * h;
+  bufsize = 4 * npixels;
+  if (npixels/w != h || bufsize/4 != npixels) {
+    SetISTR(ISTR_WARNING, "can't malloc longpic in WriteIRIS()");
+    free(starttab);
+    free(lengthtab);
+    free(rlebuf);
+    free(lumbuf);
+    return -1;
+  }
+  longpic = (byte *) malloc((size_t) bufsize);
   if (!longpic) FatalError("couldn't malloc longpic in WriteIRIS()");
 
   for (i=0, pptr=pic; i<h; i++) {
@@ -574,7 +622,7 @@
       }
     }
   }
-      
+
 
 
   /* compress and write the data */
@@ -584,12 +632,13 @@
       if (zsize == 1) {
 	lumrow(lptr, lumbuf, w);
 	len = compressrow(lumbuf, rlebuf, CHANOFFSET(j), w);
-      } 
+      }
       else {
 	len = compressrow(lptr, rlebuf, CHANOFFSET(j), w);
       }
 
       if (len > rlebuflen) {
+	/* this condition shouldn't kill XV, just abort writing the image */
 	FatalError("WriteIRIS: rlebuf is too small");
 	exit(1);
       }
@@ -618,10 +667,10 @@
 
   return 0;
 }
-  
+
 
 /*************************************/
-static void lumrow(rgbptr, lumptr, n) 
+static void lumrow(rgbptr, lumptr, n)
      byte *rgbptr, *lumptr;
      int n;
 {
@@ -640,7 +689,7 @@
      int   z, cnt;
 {
   byte *iptr, *ibufend, *sptr, *optr;
-  short todo, cc;							
+  short todo, cc;
   long  count;
 
   lbuf    += z;
@@ -685,7 +734,7 @@
     cc = *iptr;
     iptr += 4;
     while ((iptr<ibufend) && (*iptr == cc))  iptr += 4;
-    
+
     count = (iptr-sptr)/4;
     while (count) {
       todo = count>126 ? 126:count;
@@ -694,7 +743,7 @@
       *optr++ = cc;
     }
   }
-  
+
   *optr++ = 0;
   return (optr - rlebuf);
 }
diff -ru xv-3.10a/xvjpeg.c xv-3.10a-enhancements/xvjpeg.c
--- xv-3.10a/xvjpeg.c	1995-01-05 00:17:13.000000000 -0800
+++ xv-3.10a-enhancements/xvjpeg.c	2007-05-13 17:47:11.000000000 -0700
@@ -12,13 +12,17 @@
 
 #include <setjmp.h>
 
-#include "jpeglib.h"
+#include "jpeglib.h"   /* currently defines JPEG_APP0 but not JPEG_APP1 */
 #include "jerror.h"
 
+#ifndef JPEG_APP1
+#  define JPEG_APP1 (JPEG_APP0 + 1)   /* EXIF marker */
+#endif
+
 #define CREATOR_STR "CREATOR: "
 
 #if BITS_IN_JSAMPLE != 8
-  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
+  Sorry, this code copes only with 8-bit JSAMPLEs. /* deliberate syntax err */
 #endif
 
 
@@ -30,12 +34,12 @@
 #define J_BCANC  1
 #define BUTTH    24
 
-/* minimum size compression when doing a 'quick' image load.  (of course, if
-   the image *is* smaller than this, you'll get whatever size it actually is.
+/* Minimum size compression when doing a 'quick' image load.  (Of course, if
+   the image *is* smaller than this, you'll get whatever size it actually is.)
    This is currently hardcoded to be twice the size of a schnauzer icon, as
    the schnauzer's the only thing that does a quick load... */
 
-#define QUICKWIDE 160    
+#define QUICKWIDE 160
 #define QUICKHIGH 120
 
 struct my_error_mgr {
@@ -51,19 +55,33 @@
 static    void         clickJD            PARM((int, int));
 static    void         doCmd              PARM((int));
 static    void         writeJPEG          PARM((void));
+#if JPEG_LIB_VERSION > 60
+METHODDEF(void)        xv_error_exit      PARM((j_common_ptr));
+METHODDEF(void)        xv_error_output    PARM((j_common_ptr));
+METHODDEF(void)        xv_prog_meter      PARM((j_common_ptr));
+#else
 METHODDEF void         xv_error_exit      PARM((j_common_ptr));
 METHODDEF void         xv_error_output    PARM((j_common_ptr));
 METHODDEF void         xv_prog_meter      PARM((j_common_ptr));
+#endif
 static    unsigned int j_getc             PARM((j_decompress_ptr));
+#if JPEG_LIB_VERSION > 60
+METHODDEF(boolean)     xv_process_comment PARM((j_decompress_ptr));
+METHODDEF(boolean)     xv_process_app1    PARM((j_decompress_ptr));
+#else
 METHODDEF boolean      xv_process_comment PARM((j_decompress_ptr));
+METHODDEF boolean      xv_process_app1    PARM((j_decompress_ptr));
+#endif
 static    int          writeJFIF          PARM((FILE *, byte *, int,int,int));
 
 
 
 /*** local variables ***/
 static char *filename;
-static char *fbasename;
+static const char *fbasename;
 static char *comment;
+static byte *exifInfo;
+static int   exifInfoSize;   /* not a string => must track size explicitly */
 static int   colorType;
 
 static DIAL  qDial, smDial;
@@ -80,28 +98,26 @@
 /***************************************************/
 void CreateJPEGW()
 {
-  XClassHint classh;
-
   jpegW = CreateWindow("xv jpeg","XVjpeg",NULL,JWIDE,JHIGH,infofg,infobg,0);
   if (!jpegW) FatalError("can't create jpeg window!");
-  
+
   XSelectInput(theDisp, jpegW, ExposureMask | ButtonPressMask | KeyPressMask);
-  
-  DCreate(&qDial, jpegW, 10, 10, 80, 100, 1, 100, 75, 5, 
+
+  DCreate(&qDial, jpegW, 10, 10, 80, 100, 1.0, 100.0, 75.0, 1.0, 5.0,
 	  infofg, infobg, hicol, locol, "Quality", "%");
-  
-  DCreate(&smDial, jpegW, 120, 10, 80, 100, 0, 100, 0, 5, 
+
+  DCreate(&smDial, jpegW, 120, 10, 80, 100, 0.0, 100.0, 0.0, 1.0, 5.0,
 	  infofg, infobg, hicol, locol, "Smoothing", "%");
-  
-  BTCreate(&jbut[J_BOK], jpegW, JWIDE-180-1, JHIGH-10-BUTTH-1, 80, BUTTH, 
+
+  BTCreate(&jbut[J_BOK], jpegW, JWIDE-180-1, JHIGH-10-BUTTH-1, 80, BUTTH,
 	   "Ok", infofg, infobg, hicol, locol);
-  
-  BTCreate(&jbut[J_BCANC], jpegW, JWIDE-90-1, JHIGH-10-BUTTH-1, 80, BUTTH, 
+
+  BTCreate(&jbut[J_BCANC], jpegW, JWIDE-90-1, JHIGH-10-BUTTH-1, 80, BUTTH,
 	   "Cancel", infofg, infobg, hicol, locol);
-  
+
   XMapSubwindows(theDisp, jpegW);
 }
-  
+
 
 /***************************************************/
 void JPEGDialog(vis)
@@ -122,32 +138,32 @@
 {
   /* check event to see if it's for one of our subwindows.  If it is,
      deal accordingly, and return '1'.  Otherwise, return '0' */
-  
+
   int rv;
   rv = 1;
-  
+
   if (!jpegUp) return 0;
-  
+
   if (xev->type == Expose) {
     int x,y,w,h;
     XExposeEvent *e = (XExposeEvent *) xev;
     x = e->x;  y = e->y;  w = e->width;  h = e->height;
-    
+
     /* throw away excess expose events for 'dumb' windows */
-    if (e->count > 0 && (e->window == qDial.win || 
+    if (e->count > 0 && (e->window == qDial.win ||
 			 e->window == smDial.win)) {}
-    
+
     else if (e->window == jpegW)       drawJD(x, y, w, h);
     else if (e->window == qDial.win)   DRedraw(&qDial);
     else if (e->window == smDial.win)  DRedraw(&smDial);
     else rv = 0;
   }
-  
+
   else if (xev->type == ButtonPress) {
     XButtonEvent *e = (XButtonEvent *) xev;
     int x,y;
     x = e->x;  y = e->y;
-    
+
     if (e->button == Button1) {
       if      (e->window == jpegW)      clickJD(x,y);
       else if (e->window == qDial.win)  DTrack(&qDial,  x,y);
@@ -156,18 +172,18 @@
     }  /* button1 */
     else rv = 0;
   }  /* button press */
-  
-  
+
+
   else if (xev->type == KeyPress) {
     XKeyEvent *e = (XKeyEvent *) xev;
     char buf[128];  KeySym ks;
     int stlen;
-    
+
     stlen = XLookupString(e,buf,128,&ks,(XComposeStatus *) NULL);
     buf[stlen] = '\0';
-    
+
     RemapKeyCheck(ks, buf, &stlen);
-    
+
     if (e->window == jpegW) {
       if (stlen) {
 	if (buf[0] == '\r' || buf[0] == '\n') { /* enter */
@@ -181,12 +197,12 @@
     else rv = 0;
   }
   else rv = 0;
-  
+
   if (rv==0 && (xev->type == ButtonPress || xev->type == KeyPress)) {
     XBell(theDisp, 50);
     rv = 1;   /* eat it */
   }
-  
+
   return rv;
 }
 
@@ -205,23 +221,24 @@
 static void drawJD(x,y,w,h)
      int x,y,w,h;
 {
-  char *title  = "Save JPEG file...";
-  char *title1 = "Quality value determines";
-  char *title2 = "compression rate: higher";
-  char *title3 = "quality = bigger file.";
-  char *title4 = "Use smoothing if saving";
-  char *title5 = "an 8-bit image (eg, a GIF).";
-  
-  char *qtitle1 = "Default = 75.";
-  char *qtitle2 = "Useful range";
-  char *qtitle3 = "is 5-95.";
-  char *smtitle1 = "Default = 0 (none).";
-  char *smtitle2 = "10-30 is enough";
-  char *smtitle3 = "for typical GIFs.";
-  
+  const char *title  = "Save JPEG file...";
+  const char *title1 = "Quality value determines";
+  const char *title2 = "compression rate: higher";
+  const char *title3 = "quality = bigger file.";
+  const char *title4 = "Use smoothing if saving";
+  const char *title5 = "an 8-bit image (eg, a GIF).";
+
+  const char *qtitle1 = "Default = 75.";
+  const char *qtitle2 = "Useful range";
+  const char *qtitle3 = "is 5-95.";
+
+  const char *smtitle1 = "Default = 0 (none).";
+  const char *smtitle2 = "10-30 is enough";
+  const char *smtitle3 = "for typical GIFs.";
+
   int  i;
   XRectangle xr;
-  
+
   xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
   XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
 
@@ -240,11 +257,11 @@
   DrawString(jpegW,  15, 10+100+10+ASCENT,            qtitle1);
   DrawString(jpegW,  15, 10+100+10+ASCENT+LINEHIGH,   qtitle2);
   DrawString(jpegW,  15, 10+100+10+ASCENT+LINEHIGH*2, qtitle3);
-  
+
   DrawString(jpegW, 115, 10+100+10+ASCENT+LINEHIGH*0, smtitle1);
   DrawString(jpegW, 115, 10+100+10+ASCENT+LINEHIGH*1, smtitle2);
   DrawString(jpegW, 115, 10+100+10+ASCENT+LINEHIGH*2, smtitle3);
-  
+
   XSetClipMask(theDisp, theGC, None);
 }
 
@@ -255,14 +272,14 @@
 {
   int i;
   BUTT *bp;
-  
+
   /* check BUTTs */
-  
+
   for (i=0; i<J_NBUTTS; i++) {
     bp = &jbut[i];
     if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
   }
-  
+
   if (i<J_NBUTTS) {  /* found one */
     if (BTTrack(bp)) doCmd(i);
   }
@@ -281,7 +298,7 @@
 
     writeJPEG();
     JPEGDialog(0);
-    
+
     fullname = GetDirFullName();
     if (!ISPIPE(fullname[0])) {
       XVCreatedFile(fullname);
@@ -304,7 +321,7 @@
 static void writeJPEG()
 {
   FILE          *fp;
-  int            i, nc, rv, w, h, ptype, pfree;
+  int            i, nc, rv, w, h, npixels, ptype, pfree;
   register byte *ip, *ep;
   byte          *inpix, *rmap, *gmap, *bmap;
   byte          *image8, *image24;
@@ -322,6 +339,14 @@
   WaitCursor();
   inpix = GenSavePic(&ptype, &w, &h, &pfree, &nc, &rmap, &gmap, &bmap);
 
+  /* this case may not be possible to trigger, but not totally clear, so... */
+  npixels = w*h;
+  if (w <= 0 || h <= 0 || npixels/w < h) {
+    SetISTR(ISTR_WARNING, "%s:  image dimensions too large (%dx%d)",
+            fbasename, w, h);
+    return;
+  }
+
   image8 = image24 = (byte *) NULL;
 
 
@@ -332,37 +357,46 @@
       if (i==nc) colorType = F_GREYSCALE;    /* made it all the way through */
     }
     else {  /* PIC24 */
-      for (i=0,ip=inpix; i<w*h && ip[0]==ip[1] && ip[1]==ip[2]; i++,ip+=3);
-      if (i==w*h) colorType = F_GREYSCALE;  /* all the way through */
+      for (i=0,ip=inpix; i<npixels && ip[0]==ip[1] && ip[1]==ip[2]; i++,ip+=3);
+      if (i==npixels) colorType = F_GREYSCALE;  /* all the way through */
     }
   }
-  
-  
+
+
   /* first thing to do is build an 8/24-bit Greyscale/TrueColor image
      (meaning: non-colormapped) */
-  
+
   if (colorType == F_GREYSCALE) {   /* build an 8-bit Greyscale image */
-    image8 = (byte *) malloc((size_t) w * h);
+    image8 = (byte *) malloc((size_t) npixels);
     if (!image8) FatalError("writeJPEG: unable to malloc image8\n");
-    
+
     if (ptype == PIC8) {
-      for (i=0,ip=image8,ep=inpix; i<w * h; i++, ip++, ep++)
+      for (i=0,ip=image8,ep=inpix; i<npixels; i++, ip++, ep++)
 	*ip = MONO(rmap[*ep], gmap[*ep], bmap[*ep]);
     }
     else {  /* PIC24 */
-      for (i=0,ip=image8,ep=inpix; i<w*h; i++, ip++, ep+=3)
+      for (i=0,ip=image8,ep=inpix; i<npixels; i++, ip++, ep+=3)
 	*ip = MONO(ep[0],ep[1],ep[2]);
     }
   }
 
   else {    /* *not* F_GREYSCALE */
     if (ptype == PIC8) {
-      image24 = (byte *) malloc((size_t) w * h * 3);
+      int count = 3*npixels;
+
+      /* already know npixels > 0 (above) */
+      if (count/3 < npixels) {
+        SetISTR(ISTR_WARNING, "%s:  image dimensions too large (%dx%d)",
+                fbasename, w, h);
+        return;
+      }
+
+      image24 = (byte *) malloc((size_t) count);
       if (!image24) {  /* this simply isn't going to work */
 	FatalError("writeJPEG: unable to malloc image24\n");
       }
 
-      for (i=0, ip=image24, ep=inpix; i<w*h; i++, ep++) {
+      for (i=0, ip=image24, ep=inpix; i<npixels; i++, ep++) {
 	*ip++ = rmap[*ep];
 	*ip++ = gmap[*ep];
 	*ip++ = bmap[*ep];
@@ -374,16 +408,16 @@
     }
   }
 
-  
+
   /* in any event, we've got some valid image.  Do the JPEG Thing */
   rv = writeJFIF(fp, (colorType==F_GREYSCALE) ? image8 : image24,
 		 w, h, colorType);
-  
+
   if      (colorType == F_GREYSCALE) free(image8);
   else if (ptype == PIC8)            free(image24);
 
   if (pfree) free(inpix);
-  
+
   if (CloseOutFile(fp, filename, rv) == 0) DirBox(0);
   SetCursors(-1);
 }
@@ -400,7 +434,11 @@
 
 
 /**************************************************/
-METHODDEF void xv_error_exit(cinfo) 
+#if JPEG_LIB_VERSION > 60
+METHODDEF(void) xv_error_exit(cinfo)
+#else
+METHODDEF void  xv_error_exit(cinfo)
+#endif
      j_common_ptr cinfo;
 {
   my_error_ptr myerr;
@@ -412,7 +450,11 @@
 
 
 /**************************************************/
-METHODDEF void xv_error_output(cinfo) 
+#if JPEG_LIB_VERSION > 60
+METHODDEF(void) xv_error_output(cinfo)
+#else
+METHODDEF void  xv_error_output(cinfo)
+#endif
      j_common_ptr cinfo;
 {
   my_error_ptr myerr;
@@ -426,7 +468,11 @@
 
 
 /**************************************************/
-METHODDEF void xv_prog_meter(cinfo)
+#if JPEG_LIB_VERSION > 60
+METHODDEF(void) xv_prog_meter(cinfo)
+#else
+METHODDEF void  xv_prog_meter(cinfo)
+#endif
      j_common_ptr cinfo;
 {
   struct jpeg_progress_mgr *prog;
@@ -462,14 +508,16 @@
   struct my_error_mgr              jerr;
   JSAMPROW                         rowptr[1];
   FILE                            *fp;
-  static byte                     *pic;
+  const char                      *colorspace_name = "Color";
+  byte                            *pic, *pic_end;
   long                             filesize;
-  int                              i,w,h,bperpix;
+  int                              i,w,h,bperpix,bperline,count;
 
 
   fbasename = BaseName(fname);
   pic       = (byte *) NULL;
   comment   = (char *) NULL;
+  exifInfo  = (byte *) NULL;
 
   pinfo->type  = PIC8;
 
@@ -485,14 +533,22 @@
   jerr.pub.output_message = xv_error_output;
 
   if (setjmp(jerr.setjmp_buffer)) {
+L1:
     /* if we're here, it blowed up... */
     jpeg_destroy_decompress(&cinfo);
     fclose(fp);
-    if (pic)     free(pic);
-    if (comment) free(comment);
-
-    pinfo->pic = (byte *) NULL;
-    pinfo->comment = (char *) NULL;
+    if (pic)      free(pic);
+    if (comment)  free(comment);
+    if (exifInfo) free(exifInfo);
+
+    pinfo->pic      = (byte *) NULL;
+    pinfo->comment  = (char *) NULL;
+    pinfo->exifInfo = (byte *) NULL;
+    pinfo->exifInfoSize = 0;
+
+    comment  = (char *) NULL;
+    exifInfo = (byte *) NULL;
+    exifInfoSize = 0;
 
     return 0;
   }
@@ -500,6 +556,7 @@
 
   jpeg_create_decompress(&cinfo);
   jpeg_set_marker_processor(&cinfo, JPEG_COM, xv_process_comment);
+  jpeg_set_marker_processor(&cinfo, JPEG_APP1, xv_process_app1);
 
   /* hook up progress meter */
   prog.progress_monitor = xv_prog_meter;
@@ -515,9 +572,8 @@
 
 
   jpeg_calc_output_dimensions(&cinfo);
-  w = cinfo.output_width;
-  h = cinfo.output_height;
-  pinfo->normw = w;  pinfo->normh = h;
+  pinfo->normw = w = cinfo.output_width;
+  pinfo->normh = h = cinfo.output_height;
 
   if (quick) {
     int wfac, hfac, fac;
@@ -543,75 +599,120 @@
   }
 
 
-  if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
-    cinfo.out_color_space = JCS_GRAYSCALE;
-    cinfo.quantize_colors = FALSE;
-    
-    SetISTR(ISTR_INFO,"Loading %dx%d Greyscale JPEG (%ld bytes)...",
-	    w,h,filesize);
-    
-    for (i=0; i<256; i++) pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;
-  }
-  else {
-    cinfo.out_color_space = JCS_RGB;
-    cinfo.quantize_colors = FALSE;     /* default: give 24-bit image to XV */
-    
-    if (!quick && picType==PIC8 && conv24MB.flags[CONV24_LOCK] == 1) {
-      /*
-       * we're locked into 8-bit mode:
-       *   if CONV24_FAST, use JPEG's one-pass quantizer
-       *   if CONV24_SLOW, use JPEG's two-pass quantizer
-       *   if CONV24_BEST, or other, ask for 24-bit image and hand it to XV
-       */
-      
-      cinfo.desired_number_of_colors = 256;
-      
-      if (conv24 == CONV24_FAST || conv24 == CONV24_SLOW) {
-	cinfo.quantize_colors = TRUE;
-	state824=1;              /* image was converted from 24 to 8 bits */
-	
-	cinfo.two_pass_quantize = (conv24 == CONV24_SLOW);
+  cinfo.quantize_colors = FALSE;     /* default: give 24-bit image to XV */
+  switch (cinfo.num_components) {
+    case 1:
+      cinfo.out_color_space = JCS_GRAYSCALE;
+      colorspace_name = "Greyscale";
+      for (i=0; i<256; i++) pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;
+      break;
+
+    case 3:
+      cinfo.out_color_space = JCS_RGB;
+      goto L2;
+
+    case 4:
+      cinfo.out_color_space = JCS_CMYK;
+      colorspace_name = "4-Plane Color";
+L2:
+      if (!quick && picType == PIC8 && conv24MB.flags[CONV24_LOCK] == 1) {
+        /*
+         * we're locked into 8-bit mode:
+         *   if CONV24_FAST, use JPEG's one-pass quantizer
+         *   if CONV24_SLOW, use JPEG's two-pass quantizer
+         *   if CONV24_BEST, or other, ask for 24-bit image and hand it to XV
+         */
+        cinfo.desired_number_of_colors = 256;
+
+        if (conv24 == CONV24_FAST || conv24 == CONV24_SLOW) {
+          cinfo.quantize_colors = TRUE;
+          state824 = 1; /* image was converted from 24 to 8 bits */
+          cinfo.two_pass_quantize = (conv24 == CONV24_SLOW);
+        }
       }
-    }
-    
-    SetISTR(ISTR_INFO,"Loading %dx%d Color JPEG (%ld bytes)...",
-	    w,h,filesize);
-  }
-  
-  jpeg_calc_output_dimensions(&cinfo);   /* note colorspace changes... */
-    
+      break;
 
-  if (cinfo.output_components != 1 && cinfo.output_components != 3) {
-    SetISTR(ISTR_WARNING, "%s:  can't read %d-plane JPEG file!",
-	    fbasename, cinfo.output_components);
-    jpeg_destroy_decompress(&cinfo);
-    fclose(fp);
-    if (comment) free(comment);
-    return 0;
+    default:
+      SetISTR(ISTR_WARNING, "%s:  can't read %d-plane JPEG file!",
+              fbasename, cinfo.output_components);
+      goto L1;
   }
+  SetISTR(ISTR_INFO, "Loading %dx%d %s JPEG (%ld bytes)...", w, h,
+          colorspace_name, filesize);
+
+  jpeg_calc_output_dimensions(&cinfo);   /* note colorspace changes... */
 
 
   bperpix = cinfo.output_components;
   pinfo->type = (bperpix == 1) ? PIC8 : PIC24;
 
-  pic = (byte *) malloc((size_t) (w * h * bperpix));
+  bperline = w * bperpix;
+  count = h * bperline;
+  if (w <= 0 || h <= 0 || bperline/w < bperpix || count/h < bperline) {
+    SetISTR(ISTR_WARNING, "%s:  image dimensions too large (%dx%d)",
+            fbasename, w, h);
+    goto L1;
+  }
+
+  pic = (byte *) malloc((size_t) count);
   if (!pic) {
     SetISTR(ISTR_WARNING, "%s:  can't read JPEG file - out of memory",
 	    fbasename);
-    jpeg_destroy_decompress(&cinfo);
-    fclose(fp);
-    if (comment) free(comment);
-    return 0;
+    goto L1;
   }
-  
+  pic_end = pic + count;
+
   jpeg_start_decompress(&cinfo);
 
   while (cinfo.output_scanline < cinfo.output_height) {
+    if (cinfo.output_scanline < 0) {   /* should never happen, but... */
+      SetISTR(ISTR_WARNING, "%s:  invalid negative scanline (%d)",
+              fbasename, cinfo.output_scanline);
+      goto L1;
+    }
     rowptr[0] = (JSAMPROW) &pic[cinfo.output_scanline * w * bperpix];
     (void) jpeg_read_scanlines(&cinfo, rowptr, (JDIMENSION) 1);
   }
 
-  
+
+  /* Convert CMYK to RGB color space */
+
+  if (bperpix > 3) {
+    register byte *p = pic;
+
+    /* According to documentation accompanying the IJG JPEG Library, it appears
+     * that some versions of Adobe Systems' "Photoshop" write inverted CMYK
+     * data, where Byte 0 represents 100% ink coverage instead of 0% ink as
+     * you'd expect.  The JPEG Library's implementors made a policy decision
+     * not to correct for this in the Library, but instead force applications
+     * to deal with it; so we try to do that here:
+     */
+    if (cinfo.saw_Adobe_marker) { /* assume inverted data */
+      register byte *q = pic;
+
+      do {
+        register int cmy, k = 255 - q[3];
+
+        if ((cmy = *q++ - k) < 0) cmy = 0; *p++ = cmy; /* R */
+        if ((cmy = *q++ - k) < 0) cmy = 0; *p++ = cmy; /* G */
+        if ((cmy = *q++ - k) < 0) cmy = 0; *p++ = cmy; /* B */
+      } while (++q <= pic_end);
+    }
+    else { /* assume normal data */
+      register byte *q = pic;
+
+      do {
+        register int cmy, k = 255 - q[3];
+
+        if ((cmy = k - *q++) < 0) cmy = 0; *p++ = cmy; /* R */
+        if ((cmy = k - *q++) < 0) cmy = 0; *p++ = cmy; /* G */
+        if ((cmy = k - *q++) < 0) cmy = 0; *p++ = cmy; /* B */
+      } while (++q <= pic_end);
+    }
+    pic = realloc(pic,p-pic); /* Release extra storage */
+  }
+
+
 
   /* return 'PICINFO' structure to XV */
 
@@ -621,38 +722,59 @@
   pinfo->frmType = F_JPEG;
 
   if (cinfo.out_color_space == JCS_GRAYSCALE) {
-    sprintf(pinfo->fullInfo, "Greyscale JPEG. (%ld bytes)", filesize);
     pinfo->colType = F_GREYSCALE;
-    
+
     for (i=0; i<256; i++) pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;
   }
   else {
-    sprintf(pinfo->fullInfo, "Color JPEG. (%ld bytes)", filesize);
     pinfo->colType = F_FULLCOLOR;
 
     if (cinfo.quantize_colors) {
-      for (i=0; i<cinfo.actual_number_of_colors; i++) {
-	pinfo->r[i] = cinfo.colormap[0][i];
-	pinfo->g[i] = cinfo.colormap[1][i];
-	pinfo->b[i] = cinfo.colormap[2][i];
+      switch (bperpix) {
+        case 3:
+          for (i = 0; i < cinfo.actual_number_of_colors; i++) {
+            pinfo->r[i] = cinfo.colormap[0][i];
+            pinfo->g[i] = cinfo.colormap[1][i];
+            pinfo->b[i] = cinfo.colormap[2][i];
+          }
+          break;
+
+        case 4:
+          for (i = 0; i < cinfo.actual_number_of_colors; i++) {
+            register int cmy, k = cinfo.colormap[3][i];
+
+            if ((cmy = 255 - cinfo.colormap[0][i] - k) < 0) cmy = 0;
+            pinfo->r[i] = cmy;
+            if ((cmy = 255 - cinfo.colormap[1][i] - k) < 0) cmy = 0;
+            pinfo->g[i] = cmy;
+            if ((cmy = 255 - cinfo.colormap[2][i] - k) < 0) cmy = 0;
+            pinfo->b[i] = cmy;
+          }
+          break;
       }
     }
   }
-  
-  sprintf(pinfo->shrtInfo, "%dx%d %s JPEG. ", w,h, 
-	  (cinfo.out_color_space == JCS_GRAYSCALE) ? "Greyscale " : "Color ");
-  
-  pinfo->comment = comment;
+
+  sprintf(pinfo->fullInfo, "%s JPEG. (%ld bytes)", colorspace_name, filesize);
+  sprintf(pinfo->shrtInfo, "%dx%d %s JPEG. ", w, h, colorspace_name);
+
+  pinfo->comment      = comment;
+  pinfo->exifInfo     = exifInfo;
+  pinfo->exifInfoSize = exifInfoSize;
 
   jpeg_finish_decompress(&cinfo);
   jpeg_destroy_decompress(&cinfo);
   fclose(fp);
 
-  comment = (char *) NULL;
+  /* ownership transferred to pinfo */
+  comment  = (char *) NULL;
+  exifInfo = (byte *) NULL;
+  exifInfoSize = 0;
+
   return 1;
 }
-  
-  
+
+
 
 
 /**************************************************/
@@ -660,7 +782,7 @@
      j_decompress_ptr cinfo;
 {
   struct jpeg_source_mgr *datasrc = cinfo->src;
-  
+
   if (datasrc->bytes_in_buffer == 0) {
     if (! (*datasrc->fill_input_buffer) (cinfo))
       ERREXIT(cinfo, JERR_CANT_SUSPEND);
@@ -671,7 +793,11 @@
 
 
 /**************************************************/
-METHODDEF boolean xv_process_comment(cinfo)
+#if JPEG_LIB_VERSION > 60
+METHODDEF(boolean) xv_process_comment(cinfo)
+#else
+METHODDEF boolean  xv_process_comment(cinfo)
+#endif
      j_decompress_ptr cinfo;
 {
   int          length, hasnull;
@@ -688,7 +814,7 @@
   }
   else comment = (char *) realloc(comment, strlen(comment) + length + 1);
   if (!comment) FatalError("out of memory in xv_process_comment");
-  
+
   oldsp = sp = comment + strlen(comment);
   hasnull = 0;
 
@@ -705,6 +831,41 @@
 }
 
 
+/**************************************************/
+#if JPEG_LIB_VERSION > 60
+METHODDEF(boolean) xv_process_app1(cinfo)   /* Geoff H. Kuenning 20030331 */
+#else
+METHODDEF boolean  xv_process_app1(cinfo)
+#endif
+     j_decompress_ptr cinfo;
+{
+  int          length;
+  unsigned int ch;
+  byte         *sp;
+
+  length  = j_getc(cinfo) << 8;
+  length += j_getc(cinfo);
+  length -= 2;                  /* discount the length word itself */
+
+  if (!exifInfo) {
+    exifInfo = (byte *) malloc((size_t) length);
+    exifInfoSize = 0;
+  }
+  else exifInfo = (byte *) realloc(exifInfo, exifInfoSize + length);
+  if (!exifInfo) FatalError("out of memory in xv_process_app1 (EXIF info)");
+  
+  sp = exifInfo + exifInfoSize;
+  exifInfoSize += length;
+
+  while (length-- > 0) {
+    ch = j_getc(cinfo);
+    *sp++ = (byte) ch;
+  }
+
+  return TRUE;
+}
+
+
 
 
 /***************************************************************************/
@@ -759,8 +920,8 @@
 
 
   jpeg_set_defaults(&cinfo);
-  jpeg_set_quality(&cinfo, qDial.val, TRUE);
-  cinfo.smoothing_factor = smDial.val;
+  jpeg_set_quality(&cinfo, (int)qDial.val, TRUE);
+  cinfo.smoothing_factor = (int)smDial.val;
 
 
   jpeg_start_compress(&cinfo, TRUE);
@@ -769,20 +930,20 @@
   /*** COMMENT HANDLING ***/
 
   sprintf(xvcmt, "%sXV %s  Quality = %d, Smoothing = %d\n",
-	  CREATOR_STR, REVDATE, qDial.val, smDial.val);
-  
+	  CREATOR_STR, REVDATE, (int)qDial.val, (int)smDial.val);
+
   if (picComments) {   /* append XV comment */
     char *sp, *sp1;  int done;
 
     i   = strlen(picComments);
     comment = (char *) malloc(i + strlen(xvcmt) + 2 + 1);
     if (!comment) FatalError("out of memory in writeJFIF()");
-    
+
     strcpy(comment, picComments);
-    
+
     /* see if there's a line that starts with 'CREATOR: ' in the
        comments.  If there is, rip it out. */
-    
+
     sp = comment;  done = 0;
     while (!done && *sp) {
       if (strncmp(sp, CREATOR_STR, strlen(CREATOR_STR)) == 0) {
@@ -801,7 +962,7 @@
       }
     }
 
-    /* count # of \n's at end of comment.  
+    /* count # of \n's at end of comment.
        If none, add 2.   If one, add 1.  If two or more, add none. */
 
     sp = comment + strlen(comment);
@@ -814,15 +975,18 @@
     strcat(comment, xvcmt);
   }
   else comment = xvcmt;
-  
-  
-  jpeg_write_marker(&cinfo,JPEG_COM,(byte *) comment,(u_int) strlen(comment));
-  
+
+
+  jpeg_write_marker(&cinfo, JPEG_COM, (byte *)comment, (u_int)strlen(comment));
+
+  if (picExifInfo) jpeg_write_marker(&cinfo, JPEG_APP1, (byte *)picExifInfo,
+                                     (u_int)picExifInfoSize);
+
   while (cinfo.next_scanline < cinfo.image_height) {
     rowptr[0] = (JSAMPROW) &pic[cinfo.next_scanline * w * bperpix];
     (void) jpeg_write_scanlines(&cinfo, rowptr, (JDIMENSION) 1);
   }
-  
+
   jpeg_finish_compress(&cinfo);
   jpeg_destroy_compress(&cinfo);
   return 0;
@@ -831,4 +995,27 @@
 
 
 
+
+/*******************************************/
+void
+VersionInfoJPEG()	/* GRR 19980605, 19980607 */
+{
+  int major = JPEG_LIB_VERSION / 10;
+  int minor = JPEG_LIB_VERSION % 10;
+  char minoralpha[2];
+
+  if (minor) {
+    minoralpha[0] = (char)(minor - 1 + 'a');
+    minoralpha[1] = '\0';
+  } else
+    minoralpha[0] = '\0';
+
+/* fprintf(stderr, "   Compiled with libjpeg %d.%d.\n", major, minor); */
+  fprintf(stderr, "   Compiled with libjpeg %d%s.\n", major, minoralpha);
+}
+
+
+
+
+
 #endif  /* HAVE_JPEG */
diff -ru xv-3.10a/xvmisc.c xv-3.10a-enhancements/xvmisc.c
--- xv-3.10a/xvmisc.c	1995-01-13 15:41:34.000000000 -0800
+++ xv-3.10a-enhancements/xvmisc.c	2007-05-13 17:32:59.000000000 -0700
@@ -21,13 +21,15 @@
  *     void   LoadFishCursors()
  *     void   WaitCursor()
  *     void   SetCursors(int)
- *     char  *BaseName(char *)
+ *     const char  *BaseName(const char *)
  *     void   DrawTempGauge(win, x,y,w,h, percent, fg,bg,hi,lo, str)
  *     void   ProgressMeter(min, max, val, str);
  *     void   xvbcopy(src, dst, length)
  *     int    xvbcmp (s1,  s2,  length)
  *     void   xvbzero(s, length)
  *     char  *xv_strstr(s1, s2)
+ *     FILE  *xv_fopen(str, str)
+ *     void   xv_mktemp(str)
  *     void   Timer(milliseconds)
  */
 
@@ -36,6 +38,10 @@
 #define NEEDSTIME
 #include "xv.h"
 
+#ifdef __linux__	/* probably others, too, but being conservative */
+#  include <unistd.h>	/* getwd() */
+#endif
+
 #include "bits/fc_left"
 #include "bits/fc_leftm"
 #include "bits/fc_left1"
@@ -61,21 +67,24 @@
 
   /* the following fakes 'XSetWMProtocols(theDisp, win, &atom_DELWIN, 1);' */
 
-  if (! atom_PROTOCOLS) 
+  if (! atom_PROTOCOLS)
     atom_PROTOCOLS = XInternAtom (theDisp, "WM_PROTOCOLS", False);
 
   if (atom_PROTOCOLS == None) return;
 
-  XChangeProperty(theDisp, win, atom_PROTOCOLS, XA_ATOM, 32, 
+  XChangeProperty(theDisp, win, atom_PROTOCOLS, XA_ATOM, 32,
 		  PropModeReplace, (unsigned char *) &atom_DELWIN, 1);
 }
 
 
 /***************************************************/
 Window CreateWindow(name,clname,geom,defw,defh,fg,bg,usesize)
-char         *name, *clname, *geom;
-int           defw,defh,usesize;
-unsigned long fg, bg;
+     const char   *name;
+     const char   *clname;
+     const char   *geom;
+     int           defw,defh;
+     unsigned long fg, bg;
+     int           usesize;
 {
   Window               win;
   XSetWindowAttributes xswa;
@@ -91,16 +100,24 @@
   x = y = 1;
   i = XParseGeometry(geom,&x,&y, (unsigned int *) &w, (unsigned int *) &h);
 
-  if ((i&XValue || i&YValue)) hints.flags = USPosition;  
+  if ((i&XValue || i&YValue)) hints.flags = USPosition;
                          else hints.flags = PPosition;
-  
+
   if (!usesize || !(i&WidthValue))  w = defw;
   if (!usesize || !(i&HeightValue)) h = defh;
 
-  hints.flags |= USSize;
+  hints.flags |= USSize | PWinGravity;
 
-  if (i&XValue && i&XNegative) x = dispWIDE - w - abs(x);
-  if (i&YValue && i&YNegative) y = dispHIGH - h - abs(y);
+  hints.win_gravity = NorthWestGravity;
+  if (i&XValue && i&XNegative) {
+    hints.win_gravity = NorthEastGravity;
+    x = dispWIDE - (w + 2 * bwidth) - abs(x);
+  }
+  if (i&YValue && i&YNegative) {
+    hints.win_gravity = (hints.win_gravity == NorthWestGravity) ?
+      SouthWestGravity : SouthEastGravity;
+    y = dispHIGH - (h + 2 * bwidth) - abs(y);
+  }
 
 
 #define VROOT_TRANS
@@ -130,77 +147,76 @@
   xswamask = CWBackPixel | CWBorderPixel | CWColormap;
   if (!usesize) xswamask |= CWBitGravity;
 
-  win = XCreateWindow(theDisp, rootW, x, y, (u_int) w, (u_int) h, 
+  win = XCreateWindow(theDisp, rootW, x, y, (u_int) w, (u_int) h,
 		      (u_int) bwidth, (int) dispDEEP, InputOutput,
 		      theVisual, xswamask, &xswa);
   if (!win) return(win);   /* leave immediately if couldn't create */
 
 
-  XSetStandardProperties(theDisp, win, name, name, None, NULL, 0, &hints);
-
   xwmh.input = True;
   xwmh.flags = InputHint;
   if (iconPix) { xwmh.icon_pixmap = iconPix;  xwmh.flags |= IconPixmapHint; }
-  XSetWMHints(theDisp, win, &xwmh);
 
   if (clname && strlen(clname)) {
     classh.res_name = "xv";
-    classh.res_class = clname;
-    XSetClassHint(theDisp, win, &classh);
+    classh.res_class = (char *) clname;
     StoreDeleteWindowProp(win);
   }
 
+  XmbSetWMProperties(theDisp, win, name, name, NULL, 0, &hints, &xwmh,
+      clname ? &classh : NULL);
+
   return(win);
 }
-  
+
 
 
 /**************************************************/
 void DrawString(win,x,y,str)
-     Window win;
-     int x,y;
-     char *str;
+     Window      win;
+     int         x,y;
+     const char *str;
 {
   XDrawString(theDisp, win, theGC, x, y, str, (int) strlen(str));
 }
 
-  
+
 /**************************************************/
 void CenterString(win,x,y,str)
-     Window win;
-     int x,y;
-     char *str;
+     Window      win;
+     int         x,y;
+     const char *str;
 {
   DrawString(win, CENTERX(mfinfo, x, str), CENTERY(mfinfo, y), str);
 }
 
-  
+
 /**************************************************/
 void ULineString(win,x,y,str)
-     Window win;
-     int x,y;
-     char *str;
+     Window      win;
+     int         x,y;
+     const char *str;
 {
   DrawString(win, x, y, str);
-  XDrawLine(theDisp, win, theGC, x, y+DESCENT-1, 
+  XDrawLine(theDisp, win, theGC, x, y+DESCENT-1,
 	    x+StringWidth(str), y+DESCENT-1);
 }
 
-  
+
 /**************************************************/
 int StringWidth(str)
-     char *str;
+     const char *str;
 {
   return(XTextWidth(mfinfo, str, (int) strlen(str)));
 }
 
-  
+
 /**************************************************/
 int CursorKey(ks, shift, dotrans)
      KeySym ks;
      int    shift, dotrans;
 {
-  /* called by the KeyPress/KeyRelease event handler to determine if a 
+  /* called by the KeyPress/KeyRelease event handler to determine if a
      given keypress is a cursor key.  More complex than you'd think, since
      certain Sun Keyboards generate a variety of odd keycodes, and not all
      keyboards *have* all these keys.  Note that 'shifted' arrow keys
@@ -225,29 +241,29 @@
 
   int  i = CK_NONE;
 
-  if      (ks==XK_Up    || ks==XK_KP_Up    || 
-	   ks==XK_KP_8  || ks==XK_F28)             i=CK_UP;
+  if      (ks==XK_Up    || ks==XK_KP_Up    ||
+			   ks==XK_F28)             i=CK_UP;
 
-  else if (ks==XK_Down  || ks==XK_KP_Down  || 
-	   ks==XK_KP_2  || ks==XK_F34)             i=CK_DOWN;
+  else if (ks==XK_Down  || ks==XK_KP_Down  ||
+			   ks==XK_F34)             i=CK_DOWN;
 
-  else if (ks==XK_Left  || ks==XK_KP_Left  || 
-	   ks==XK_KP_4  || ks==XK_F30)             i=CK_LEFT;
+  else if (ks==XK_Left  || ks==XK_KP_Left  ||
+			   ks==XK_F30)             i=CK_LEFT;
 
-  else if (ks==XK_Right || ks==XK_KP_Right || 
-	   ks==XK_KP_6  || ks==XK_F32)             i=CK_RIGHT;
+  else if (ks==XK_Right || ks==XK_KP_Right ||
+			   ks==XK_F32)             i=CK_RIGHT;
 
   else if (ks==XK_Prior || ks==XK_KP_Prior ||
-	   ks==XK_KP_9  || ks==XK_F29)             i=CK_PAGEUP;
+			   ks==XK_F29)             i=CK_PAGEUP;
 
   else if (ks==XK_Next  || ks==XK_KP_Next  ||
-	   ks==XK_KP_3  || ks==XK_F35)             i=CK_PAGEDOWN;
+			   ks==XK_F35)             i=CK_PAGEDOWN;
 
   else if (ks==XK_Home  || ks==XK_KP_Home  ||
-	   ks==XK_KP_7  || ks==XK_F27)             i=CK_HOME;
+			   ks==XK_F27)             i=CK_HOME;
 
   else if (ks==XK_End   || ks==XK_KP_End   ||
-	   ks==XK_KP_1  || ks==XK_F33)             i=CK_END;
+			   ks==XK_F33)             i=CK_END;
 
   else i = CK_NONE;
 
@@ -257,7 +273,7 @@
     else if (i==CK_UP)       i=CK_PAGEUP;
     else if (i==CK_DOWN)     i=CK_PAGEDOWN;
   }
-  
+
   return i;
 }
 
@@ -334,9 +350,9 @@
   ev.window = win;
   ev.x = x;  ev.y = y;  ev.width = w;  ev.height = h;
   ev.count = 0;
-  
+
   XSendEvent(theDisp, win, False, NoEventMask, (XEvent *) &ev);
-}    
+}
 
 
 /***********************************/
@@ -381,7 +397,7 @@
      u_int  w, h;
      u_long bg;
 {
-  /* stipple a rectangular region by drawing 'bg' where there's 1's 
+  /* stipple a rectangular region by drawing 'bg' where there's 1's
      in the stipple pattern */
 
   XSetFillStyle (theDisp, theGC, FillStippled);
@@ -400,7 +416,7 @@
      unsigned int  w,h;
      unsigned long hi, lo, bg;
 {
-  int i,r,x1,y1;
+  int i, x1, y1;
 
   x1 = x + (int) w;
   y1 = y + (int) h;
@@ -413,7 +429,7 @@
       XDrawLine(theDisp, win, theGC, x+i, y1-i, x+i,  y+i);
       XDrawLine(theDisp, win, theGC, x+i, y+i,  x1-i, y+i);
     }
-    
+
     /* draw bot-right */
     XSetForeground(theDisp, theGC, (inout==R3D_OUT) ? lo : hi);
 
@@ -431,18 +447,18 @@
     }
   }
 }
-    
+
 
 
 /**************************************************/
 void SetCropString()
 {
   /* sets the crop string in the info box to be correct.  should
-     be called whenever 'but[BCROP].active', cXOFF,cYOFF,cWIDE,cHIGH 
+     be called whenever 'but[BCROP].active', cXOFF,cYOFF,cWIDE,cHIGH
      are changed */
 
-  if (cpic != pic) 
-    SetISTR(ISTR_CROP, "%dx%d rectangle starting at %d,%d",  
+  if (cpic != pic)
+    SetISTR(ISTR_CROP, "%dx%d rectangle starting at %d,%d",
 	    cWIDE, cHIGH, cXOFF, cYOFF);
   else SetISTR(ISTR_CROP, "<none>");
 }
@@ -469,7 +485,7 @@
   char *st;
 
   /* give 'em time to read message */
-  if (infoUp || ctrlUp || anyBrowUp) sleep(3); 
+  if (infoUp || ctrlUp || anyBrowUp) sleep(3);
   else {
     st = GetISTR(ISTR_INFO);
     OpenAlert(st);
@@ -477,11 +493,11 @@
     CloseAlert();
   }
 }
-    
+
 
 /***********************************/
 void FatalError (identifier)
-      char *identifier;
+      const char *identifier;
 {
   fprintf(stderr, "%s: %s\n",cmd, identifier);
   Quit(-1);
@@ -491,12 +507,17 @@
 /***********************************/
 void Quit(i)
      int i;
-{ 
+{
   /* called when the program exits.  frees everything explictly created
      EXCEPT allocated colors.  This is used when 'useroot' is in operation,
      as we have to keep the alloc'd colors around, but we don't want anything
      else to stay */
 
+#ifdef AUTO_EXPAND
+  chdir(initdir);
+  Vdsettle();
+#endif
+
   if (!theDisp) exit(i);   /* called before connection opened */
 
   if (useroot && i==0) {   /* save the root info */
@@ -516,14 +537,38 @@
     if (jpegW) XDestroyWindow(theDisp, jpegW);
 #endif
 
+#ifdef HAVE_JP2K
+    if (jp2kW) XDestroyWindow(theDisp, jp2kW);
+#endif
+
 #ifdef HAVE_TIFF
     if (tiffW) XDestroyWindow(theDisp, tiffW);
 #endif
 
+#ifdef HAVE_PNG
+    if (pngW)  XDestroyWindow(theDisp, pngW);
+#endif
+
+#ifdef HAVE_PCD
+    if (pcdW)  XDestroyWindow(theDisp, pcdW);
+#endif
+
+#ifdef HAVE_PIC2
+    if (pic2W) XDestroyWindow(theDisp, pic2W);
+#endif
+
+#ifdef HAVE_MGCSFX
+    if (mgcsfxW) XDestroyWindow(theDisp, mgcsfxW);
+#endif
+
+#ifdef HAVE_PNG
+    if (pngW)  XDestroyWindow(theDisp, pngW);
+#endif
+
     /* if NOT using stdcmap for images, free stdcmap */
-    if (colorMapMode != CM_STDCMAP) { 
+    if (colorMapMode != CM_STDCMAP) {
       int j;
-      for (j=0; j<stdnfcols; j++) 
+      for (j=0; j<stdnfcols; j++)
 	xvFreeColors(theDisp, theCmap, &stdfreecols[j], 1, 0L);
     }
 
@@ -543,13 +588,13 @@
       if (origlist[j][0] != '/') {  /* relative path, prepend 'initdir' */
 	sprintf(str,"%s/%s", initdir, origlist[j]);
 	if (unlink(str)) {
-	  fprintf(stderr,"%s: can't delete '%s' - %s\n", 
+	  fprintf(stderr,"%s: can't delete '%s' - %s\n",
 		  cmd, str, ERRSTR(errno));
 	}
       }
       else {
 	if (unlink(origlist[j])) {
-	  fprintf(stderr,"%s: can't delete '%s' - %s\n", 
+	  fprintf(stderr,"%s: can't delete '%s' - %s\n",
 		  cmd, origlist[j], ERRSTR(errno));
 	}
       }
@@ -567,7 +612,7 @@
 void LoadFishCursors()
 {
 #define fc_w 16
-#define fc_h 16 
+#define fc_h 16
 
   Pixmap flpix,flmpix,fmpix,fmmpix,frpix,frmpix;
   Pixmap fl1pix, fl1mpix, fr1pix, fr1mpix;
@@ -592,7 +637,7 @@
 
   fr1pix = XCreatePixmapFromBitmapData(theDisp, ctrlW, (char *) fc_right1_bits,
 	     fc_w, fc_h, 1L, 0L, 1);
-  fr1mpix = XCreatePixmapFromBitmapData(theDisp, ctrlW, 
+  fr1mpix = XCreatePixmapFromBitmapData(theDisp, ctrlW,
 					(char *) fc_right1m_bits,
 	     fc_w, fc_h, 1L, 0L, 1);
 
@@ -613,7 +658,7 @@
   fr1curs= XCreatePixmapCursor(theDisp, fr1pix,fr1mpix,&fg, &bg, 8,8);
   frcurs = XCreatePixmapCursor(theDisp, frpix, frmpix, &fg, &bg, 8,8);
 
-  if (!flcurs || !fmcurs || !frcurs || !fl1curs || !fr1curs) 
+  if (!flcurs || !fmcurs || !frcurs || !fl1curs || !fr1curs)
     { flcurs = fmcurs = frcurs = (Cursor) NULL; }
 }
 
@@ -633,8 +678,8 @@
     time(&lastwaittime);
     waiting=1;
     xwmh.input       = True;
-    xwmh.icon_pixmap = riconPix;  
-    xwmh.icon_mask   = riconmask;  
+    xwmh.icon_pixmap = riconPix;
+    xwmh.icon_mask   = riconmask;
     xwmh.flags = (InputHint | IconPixmapHint | IconMaskHint) ;
     if (!useroot && mainW) XSetWMHints(theDisp, mainW, &xwmh);
     if ( useroot && ctrlW) XSetWMHints(theDisp, ctrlW, &xwmh);
@@ -665,8 +710,8 @@
     if (waiting) {
       waiting=0;
       xwmh.input       = True;
-      xwmh.icon_pixmap = iconPix;  
-      xwmh.icon_mask   = iconmask;  
+      xwmh.icon_pixmap = iconPix;
+      xwmh.icon_mask   = iconmask;
       xwmh.flags = (InputHint | IconPixmapHint | IconMaskHint) ;
       if (!useroot && mainW) XSetWMHints(theDisp, mainW, &xwmh);
       if ( useroot && ctrlW) XSetWMHints(theDisp, ctrlW, &xwmh);
@@ -694,11 +739,11 @@
 
   XFlush(theDisp);
 }
-  
+
 
 static void set_cursors(mainc, otherc)
      Cursor mainc, otherc;
-{    
+{
   if (!useroot && mainW) XDefineCursor(theDisp, mainW, mainc);
   if (infoW) XDefineCursor(theDisp, infoW, otherc);
   if (ctrlW) XDefineCursor(theDisp, ctrlW, otherc);
@@ -708,42 +753,63 @@
 
   SetBrowseCursor(otherc);
   SetTextCursor(otherc);
-  
+
 #ifdef HAVE_JPEG
   if (jpegW) XDefineCursor(theDisp, jpegW, otherc);
 #endif
-  
+
+#ifdef HAVE_JP2K
+  if (jp2kW) XDefineCursor(theDisp, jp2kW, otherc);
+#endif 
+
 #ifdef HAVE_TIFF
   if (tiffW) XDefineCursor(theDisp, tiffW, otherc);
 #endif
+
+#ifdef HAVE_PNG
+  if (pngW)  XDefineCursor(theDisp, pngW, otherc);
+#endif
+
+#ifdef HAVE_PNG
+  if (pngW)  XDefineCursor(theDisp, pngW, otherc);
+#endif
+
+#ifdef HAVE_PCD
+  if (pcdW)  XDefineCursor(theDisp, pcdW, otherc);
+#endif
+
+#ifdef HAVE_PIC2
+  if (pic2W) XDefineCursor(theDisp, pic2W, otherc);
+#endif
+
+#ifdef HAVE_MGCSFX
+  if (mgcsfxW) XDefineCursor(theDisp, mgcsfxW, otherc);
+#endif
 }
 
 
 /***************************************************/
-char *BaseName(fname)
-     char *fname;
+const char *BaseName(fname)
+     const char *fname;
 {
-  char *basname;
+  const char *basname;
 
-  /* given a complete path name ('/foo/bar/weenie.gif'), returns just the 
+  /* given a complete path name ('/foo/bar/weenie.gif'), returns just the
      'simple' name ('weenie.gif').  Note that it does not make a copy of
      the name, so don't be modifying it... */
 
-  basname = (char *) rindex(fname, '/');
-  if (!basname) basname = fname;
-  else basname++;
-
-  return basname;
+  basname = (const char *) rindex(fname, '/');
+  return basname? basname+1 : fname;
 }
 
-  
+
 /***************************************************/
 void DrawTempGauge(win, x,y,w,h, ratio, fg,bg,hi,lo, str)
-     Window win;
-     int    x,y,w,h;
-     double ratio;
-     u_long fg,bg,hi,lo;
-     char   *str;
+     Window      win;
+     int         x,y,w,h;
+     double      ratio;
+     u_long      fg,bg,hi,lo;
+     const char *str;
 {
   /* draws a 'temprature'-style horizontal progress meter in the specified
      window, at the specified location */
@@ -773,14 +839,14 @@
     if (numchars) {      /* do string */
       if (barwide < maxwide) {
 	XSetForeground(theDisp, theGC, bg);
-	XFillRectangle(theDisp, win, theGC, x+3+barwide, y+3, 
+	XFillRectangle(theDisp, win, theGC, x+3+barwide, y+3,
 		       (u_int) (maxwide-barwide), (u_int) (h-5));
       }
-	
+
       XSetFunction(theDisp, theGC, GXinvert);
       XSetPlaneMask(theDisp, theGC, fg ^ bg);
 
-      XDrawString(theDisp, win, theGC, CENTERX(mfinfo, (x+w/2), str), 
+      XDrawString(theDisp, win, theGC, CENTERX(mfinfo, (x+w/2), str),
 		  CENTERY(mfinfo, (y+h/2)), str, numchars);
 
       XSetFunction(theDisp, theGC, GXcopy);
@@ -789,18 +855,18 @@
 
     else if (barwide < maxwide) {
       XDrawLine(theDisp,win,theGC,x+3+barwide, y+h/2 + 0, x+w-3, y+h/2 + 0);
-      
+
       XSetForeground(theDisp, theGC, lo);
       XDrawLine(theDisp,win,theGC,x+3+barwide, y+h/2 + 1, x+w-3, y+h/2 + 1);
-      
+
       XSetForeground(theDisp, theGC, hi);
       XDrawLine(theDisp,win,theGC,x+3+barwide, y+h/2 + 2, x+w-3, y+h/2 + 2);
-      
+
       XSetForeground(theDisp, theGC, bg);
-      XFillRectangle(theDisp, win, theGC, x+3+barwide, y+3, 
+      XFillRectangle(theDisp, win, theGC, x+3+barwide, y+3,
 		     (u_int) (maxwide-barwide), (u_int) (h/2 - 3));
-      
-      XFillRectangle(theDisp, win, theGC, x+3+barwide, y+h/2 + 3, 
+
+      XFillRectangle(theDisp, win, theGC, x+3+barwide, y+h/2 + 3,
 		     (u_int) (maxwide-barwide),(u_int)((h-3) - (h/2+3)) + 1);
     }
   }
@@ -815,44 +881,44 @@
     if (numchars) {
       if (barwide < maxwide) {
 	XSetForeground(theDisp, theGC, bg);
-	XFillRectangle(theDisp, win, theGC, x+1+barwide, y+1, 
+	XFillRectangle(theDisp, win, theGC, x+1+barwide, y+1,
 		       (u_int) (maxwide-barwide), (u_int) (h-1));
       }
-      
+
       XSetFunction(theDisp, theGC, GXinvert);
       XSetPlaneMask(theDisp, theGC, fg ^ bg);
 
-      XDrawString(theDisp, win, theGC, CENTERX(mfinfo, (x+w/2), str), 
+      XDrawString(theDisp, win, theGC, CENTERX(mfinfo, (x+w/2), str),
 		  CENTERY(mfinfo, (y+h/2)), str, numchars);
 
       XSetFunction(theDisp, theGC, GXcopy);
       XSetPlaneMask(theDisp, theGC, AllPlanes);
     }
-    
+
     else if (barwide < maxwide) {
       XDrawLine(theDisp, win, theGC, x+1+barwide, y+h/2, x+w-1, y+h/2);
-      
+
       XSetForeground(theDisp, theGC, bg);
-      XFillRectangle(theDisp, win, theGC, x+1+barwide, y+1, 
+      XFillRectangle(theDisp, win, theGC, x+1+barwide, y+1,
 		     (u_int) (maxwide-barwide), (u_int) (h/2 - 1));
-      
-      XFillRectangle(theDisp, win, theGC, x+1+barwide, y+h/2 + 1, 
+
+      XFillRectangle(theDisp, win, theGC, x+1+barwide, y+h/2 + 1,
 		     (u_int)(maxwide-barwide),(u_int)(((h-1) - (h/2+1))+1));
     }
   }
 
   XFlush(theDisp);
 }
-    
+
 
 
 /***************************************************/
 void ProgressMeter(min, max, val, str)
-     int min, max, val;
-     char *str;
+     int         min, max, val;
+     const char *str;
 {
   /* called during 'long' operations (algorithms, smoothing, etc.) to
-     give some indication that the program will ever finish.  Draws a 
+     give some indication that the program will ever finish.  Draws a
      temperature gauge in either mainW (if not useRoot), or ctrlW.
      Tries to be clever:  only draws gauge if it looks like the operation is
      going to take more than a few seconds.  Calling with val == max removes
@@ -887,7 +953,7 @@
   if (!waiting) {     /* not waiting (or not waiting any longer) */
     if (nowTime == lastTime && val<max) return;  /* max one draw per second */
     lastTime = nowTime;
-    DrawTempGauge(win, xpos, ypos, 100,19, doneness, 
+    DrawTempGauge(win, xpos, ypos, 100,19, doneness,
 		    infofg,infobg,hicol,locol,str);
 
     if (val >= max) {            /* remove temp gauge */
@@ -915,7 +981,7 @@
 void XVCreatedFile(fullname)
      char *fullname;
 {
-  /* called whenever a file has been deleted.  Updates browser & dir windows,
+  /* called whenever a file has been created.  Updates browser & dir windows,
      if necessary */
 
   BRCreatedFile(fullname);
@@ -925,7 +991,8 @@
 
 /***************************************************/
 void xvbcopy(src, dst, len)
-     char *src, *dst;
+     const char *src;
+     char *dst;
      size_t  len;
 {
   /* Modern OS's (Solaris, etc.) frown upon the use of bcopy(),
@@ -945,7 +1012,7 @@
    */
 
   if (src==dst || len<=0) return;    /* nothin' to do */
-  
+
   if (src<dst && src+len>dst) {  /* do a backward copy */
     src = src + len - 1;
     dst = dst + len - 1;
@@ -957,11 +1024,11 @@
     for ( ; len>0; len--, src++, dst++) *dst = *src;
   }
 }
-    
+
 
 /***************************************************/
 int xvbcmp (s1, s2, len)
-     char   *s1, *s2;
+     const char   *s1, *s2;
      size_t  len;
 {
   for ( ; len>0; len--, s1++, s2++) {
@@ -985,28 +1052,31 @@
      char   *buf;
      size_t  buflen;
 {
-  /* gets the current working directory.  No trailing '/' */
+  /* Gets the current working directory and puts it in buf.  No trailing '/'. */
 
-  char *rv; 
+  const char *rv;
 
 #ifdef USE_GETCWD
-  rv = (char *) getcwd(buf, buflen);
+  rv = (const char *) getcwd(buf, buflen);
 #else
-  rv = (char *) getwd(buf);
+  rv = (const char *) getwd(buf);
 #endif
 
   if (!rv || strlen(rv)==0) {
-    if (((rv=(char *) getenv("PWD"))==NULL) && 
-	((rv=(char *) getenv("cwd"))==NULL)) rv = "./";
+    if (((rv=(const char *) getenv("PWD"))==NULL) &&
+	((rv=(const char *) getenv("cwd"))==NULL)) rv = "./";
     strcpy(buf, rv);
   }
+#ifdef AUTO_EXPAND
+  Vdtodir(buf);
+#endif
 }
 
 
 
 /***************************************************/
 
-/* 
+/*
  *	Source code for the "strstr" library routine.
  *
  * Copyright 1988 Regents of the University of California
@@ -1020,10 +1090,11 @@
  */
 
 char *xv_strstr(string, substring)
-     char *string;	        /* String to search. */
-     char *substring;		/* Substring to try to find in string. */
+     const char *string;        /* String to search. */
+     const char *substring;	/* Substring to try to find in string. */
 {
-  register char *a, *b;
+  const char *a;
+  const char *b;
 
   /* First scan quickly through the two strings looking for a
    * single-character match.  When it's found, then compare the
@@ -1031,14 +1102,14 @@
    */
 
   b = substring;
-  if (*b == 0) return string;
+  if (*b == 0) return (char *) string;
 
   for ( ; *string != 0; string += 1) {
     if (*string != *b) continue;
 
     a = string;
     while (1) {
-      if (*b == 0) return string;
+      if (*b == 0) return (char *) string;
       if (*a++ != *b++) break;
     }
     b = substring;
@@ -1052,7 +1123,8 @@
 
 /***************************************************/
 FILE *xv_fopen(fname, mode)
-     char *fname, *mode;
+     const char *fname;
+     const char *mode;
 {
   FILE *fp;
 
@@ -1066,72 +1138,90 @@
 }
 
 
+/***************************************************/
+/* GRR 20050320:  added actual mk[s]temp() call... */
+void xv_mktemp(buf, fname)
+     char       *buf;
+     const char *fname;
+{
+#ifndef VMS
+  sprintf(buf, "%s/%s", tmpdir, fname);
+#else
+  sprintf(buf, "Sys$Disk:[]%s", fname);
+#endif
+#ifdef USE_MKSTEMP
+  close(mkstemp(buf));
+#else
+  mktemp(buf);
+#endif
+}
 
 
-/*******/
+/***************************************************/
 void Timer(msec)   /* waits for 'n' milliseconds */
- int  msec;
-/*******/
+     int  msec;
 {
   long usec;
 
   if (msec <= 0) return;
+
   usec = (long) msec * 1000;
 
 
-#ifdef VMS
+#ifdef USLEEP
+  usleep(usec);
+  /* return */
+#endif
+
+
+#if defined(VMS) && !defined(USLEEP)
   {
     float ftime;
     ftime = msec / 1000.0;
     lib$wait(&ftime);
-    return;
+    /* return */
   }
 #endif
 
 
-#ifdef sgi
+#if defined(sgi) && !defined(USLEEP)
   {
     float ticks_per_msec;
     long ticks;
     ticks_per_msec = (float) CLK_TCK / 1000.0;
     ticks = (long) ((float) msec * ticks_per_msec);
     sginap(ticks);
-    return;
+    /* return */
   }
 #endif
 
 
-#if defined(SVR4) || defined(sco)
+/* does SGI define SVR4?  not sure... */
+#if (defined(SVR4) || defined(sco)) && !defined(sgi) && !defined(USLEEP)
   {
     struct pollfd dummy;
     poll(&dummy, 0, msec);
-    return;
+    /* return */
   }
 #endif
 
 
-#ifdef USLEEP
-  usleep(usec);  return;
-#endif
-
-
-#ifdef NOTIMER
-  return;
-#endif
-
-
-#ifndef VMS
+#if !defined(USLEEP) && !defined(VMS) && !defined(sgi) && !defined(SVR4) && !defined(sco) && !defined(NOTIMER)
   {
-    /* default Timer() method now uses 'select()', which probably works
-	on all systems *anyhow* (except for VMS...) */
-    
+    /* default/fall-through Timer() method now uses 'select()', which
+     * probably works on all systems *anyhow* (except for VMS...) */
+
     struct timeval time;
 
     time.tv_sec = usec / 1000000L;
     time.tv_usec = usec % 1000000L;
     select(0, XV_FDTYPE NULL, XV_FDTYPE NULL, XV_FDTYPE NULL, &time);
+    /* return */
   }
-#endif /* VMS */
-}
+#endif
 
 
+  /* NOTIMER case, fallthroughs, etc. ... but we return void, so who cares */
+  /* return */
+}
+
diff -ru xv-3.10a/xvpbm.c xv-3.10a-enhancements/xvpbm.c
--- xv-3.10a/xvpbm.c	1995-01-03 13:23:44.000000000 -0800
+++ xv-3.10a-enhancements/xvpbm.c	2007-05-13 17:44:03.000000000 -0700
@@ -23,6 +23,15 @@
  */
 
 
+typedef unsigned short  ush;
+typedef unsigned char   uch;
+
+#define alpha_composite(composite, fg, alpha, bg) {               \
+    ush temp = ((ush)(fg)*(ush)(alpha) +                          \
+                (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128);  \
+    (composite) = (uch)((temp + (temp >> 8)) >> 8);               \
+}
+
 #define TRUNCSTR "File appears to be truncated."
 
 static int garbage;
@@ -31,17 +40,91 @@
 static int loadpbm  PARM((FILE *, PICINFO *, int));
 static int loadpgm  PARM((FILE *, PICINFO *, int, int));
 static int loadppm  PARM((FILE *, PICINFO *, int, int));
+static int loadpam  PARM((FILE *, PICINFO *, int, int));
 static int getint   PARM((FILE *, PICINFO *));
 static int getbit   PARM((FILE *, PICINFO *));
 static int getshort PARM((FILE *));
-static int pbmError PARM((char *, char *));
+static int pbmError PARM((const char *, const char *));
+
+static const char *bname;
+
+
+#ifdef HAVE_MGCSFX
+/*
+ * When file read or file write is fail, probably it's caused by
+ * reading from pipe which has no data yet, or writing to pipe
+ * which is not ready yet.
+ * Then we can use system call select() on descriptor of pipe and wait.
+ * If you want, change 'undef' to 'define' in the following line.
+ * This feature is performance-killer.
+ */
+#undef FIX_PIPE_ERROR
+
+#ifdef __osf__
+#  ifdef __alpha
+#    define FIX_PIPE_ERROR
+#  endif
+#endif
+
+#endif /* HAVE_MGCSFX */
+
+
+#ifdef FIX_PIPE_ERROR
+
+int pipefdr;
+
+struct timeval timeout;
+int    width;
+fd_set fds;
+
+static void ready_read()
+{
+  if(pipefdr < 0) return; /* if file descriptor is not pipe, OK */
+  WaitCursor();
 
-static char *bname;
+reselect:
+  /* setting of timeout */
+  timeout.tv_sec = 1;  /* 1 sec */
+  timeout.tv_usec = 0; /* 0 usec */
+
+  FD_ZERO(&fds);     /* clear bits */
+  FD_SET(pipefdr, &fds); /* set bit of fd in fds */
+
+  /* number of file descriptor to want check (0 $B!A(B width-1) */
+  width = pipefdr + 1;
+
+  /* select returns number of file descriptors */
+  if (select(width, &fds, NULL, NULL, &timeout) < 0){
+    if(DEBUG){
+      fprintf(stderr, "No file descriptors can't selected, waiting...\n");
+    }
+    goto reselect;
+  }
+
+  if (FD_ISSET(pipefdr, &fds)){
+    /* Now, descriptor of pipe is ready to read */
+    return;
+  }else{
+    if(DEBUG){
+      fprintf(stderr, "Can't read from pipe yet, waiting...\n");
+    }
+    goto reselect;
+  }
+
+}
+#endif /* FIX_PIPE_ERROR */
 
 /*******************************************/
+#ifdef HAVE_MGCSFX
+int LoadPBM(fname, pinfo, fd)
+     char    *fname;
+     PICINFO *pinfo;
+     int      fd;
+#else
 int LoadPBM(fname, pinfo)
      char    *fname;
      PICINFO *pinfo;
+#endif /* HAVE_MGCSFX */
 /*******************************************/
 {
   /* returns '1' on success */
@@ -50,6 +133,10 @@
   int    c, c1;
   int    maxv, rv;
 
+#ifdef FIX_PIPE_ERROR
+  pipefdr = fd;
+#endif
+
   garbage = maxv = rv = 0;
   bname = BaseName(fname);
 
@@ -57,6 +144,22 @@
   pinfo->comment = (char *) NULL;
 
 
+#ifdef HAVE_MGCSFX
+  if(fd < 0){
+    /* open the file */
+    fp = xv_fopen(fname,"r");
+    if (!fp) return (pbmError(bname, "can't open file"));
+
+    /* compute file length */
+    fseek(fp, 0L, 2);
+    filesize = ftell(fp);
+    fseek(fp, 0L, 0);
+  }else{
+    fp = fdopen(fd, "r");
+    if (!fp) return (pbmError(bname, "can't open file"));
+    filesize = 0; /* dummy */
+  }
+#else
   /* open the file */
   fp = xv_fopen(fname,"r");
   if (!fp) return (pbmError(bname, "can't open file"));
@@ -65,6 +168,7 @@
   fseek(fp, 0L, 2);
   filesize = ftell(fp);
   fseek(fp, 0L, 0);
+#endif /* HAVE_MGCSFX */
 
 
   /* read the first two bytes of the file to determine which format
@@ -73,7 +177,8 @@
      "P6" = raw pixmap */
 
   c = getc(fp);  c1 = getc(fp);
-  if (c!='P' || c1<'1' || c1>'6') return(pbmError(bname, "unknown format"));
+  if (c!='P' || c1<'1' || (c1>'6' && c1!='8'))	/* GRR alpha */
+    return(pbmError(bname, "unknown format"));
 
   /* read in header information */
   pinfo->w = getint(fp, pinfo);  pinfo->h = getint(fp, pinfo);
@@ -104,6 +209,7 @@
   if      (c1=='1' || c1=='4') rv = loadpbm(fp, pinfo, c1=='4' ? 1 : 0);
   else if (c1=='2' || c1=='5') rv = loadpgm(fp, pinfo, c1=='5' ? 1 : 0, maxv);
   else if (c1=='3' || c1=='6') rv = loadppm(fp, pinfo, c1=='6' ? 1 : 0, maxv);
+  else if            (c1=='8') rv = loadpam(fp, pinfo,           1    , maxv);
 
   fclose(fp);
 
@@ -115,7 +221,7 @@
   }
 
   return rv;
-}  
+}
 
 
 
@@ -127,15 +233,21 @@
 {
   byte *pic8;
   byte *pix;
-  int   i,j,bit,w,h;
+  int   i,j,bit,w,h,npixels;
+
+  w = pinfo->w;
+  h = pinfo->h;
 
-  w = pinfo->w;  h = pinfo->h;
-  pic8 = (byte *) calloc((size_t) w * h, (size_t) 1);
-  if (!pic8) return pbmError(bname, "couldn't malloc 'pic8'");
+  npixels = w * h;
+  if (w <= 0 || h <= 0 || npixels/w != h)
+    return pbmError(bname, "image dimensions too large");
+
+  pic8 = (byte *) calloc((size_t) npixels, (size_t) 1);
+  if (!pic8) FatalError("couldn't malloc 'pic8' for PBM");
 
   pinfo->pic  = pic8;
   pinfo->type = PIC8;
-  sprintf(pinfo->fullInfo, "PBM, %s format.  (%ld bytes)", 
+  sprintf(pinfo->fullInfo, "PBM, %s format.  (%ld bytes)",
 	  (raw) ? "raw" : "ascii", filesize);
   sprintf(pinfo->shrtInfo, "%dx%d PBM.", w, h);
   pinfo->colType = F_BWDITHER;
@@ -153,7 +265,7 @@
       for (j=0; j<w; j++, pix++) *pix = getbit(fp, pinfo);
     }
 
-    if (numgot != w*h) pbmError(bname, TRUNCSTR);
+    if (numgot != npixels) pbmError(bname, TRUNCSTR);
     if (garbage) {
       return(pbmError(bname, "Garbage characters in image data."));
     }
@@ -192,17 +304,23 @@
      int      raw, maxv;
 {
   byte *pix, *pic8;
-  int   i,j,bitshift,w,h, holdmaxv;
+  int   i,j,bitshift,w,h,npixels, holdmaxv;
+
 
+  w = pinfo->w;
+  h = pinfo->h;
 
-  w = pinfo->w;  h = pinfo->h;
-  pic8 = (byte *) calloc((size_t) w*h, (size_t) 1);
-  if (!pic8) return(pbmError(bname, "couldn't malloc 'pic8'"));
+  npixels = w * h;
+  if (w <= 0 || h <= 0 || npixels/w != h)
+    return pbmError(bname, "image dimensions too large");
+
+  pic8 = (byte *) calloc((size_t) npixels, (size_t) 1);
+  if (!pic8) FatalError("couldn't malloc 'pic8' for PGM");
 
 
   pinfo->pic  = pic8;
   pinfo->type = PIC8;
-  sprintf(pinfo->fullInfo, "PGM, %s format.  (%ld bytes)", 
+  sprintf(pinfo->fullInfo, "PGM, %s format.  (%ld bytes)",
 	  (raw) ? "raw" : "ascii", filesize);
   sprintf(pinfo->shrtInfo, "%dx%d PGM.", pinfo->w, pinfo->h);
   pinfo->colType = F_GREYSCALE;
@@ -236,11 +354,24 @@
       }
     }
     else {
-      numgot = fread(pic8, (size_t) 1, (size_t) w*h, fp);  /* read raw data */
+#ifdef FIX_PIPE_ERROR
+  reread:
+      numgot += fread(pic8 + numgot, (size_t) 1, (size_t) w*h - numgot, fp); /* read raw data */
+      if(errno == EINTR){
+        if(DEBUG){
+	  fprintf(stderr,
+	  "Can't read all data from pipe, call select and waiting...\n");
+	}
+	ready_read();
+	goto reread;
+      }
+#else
+      numgot = fread(pic8, (size_t)1, (size_t)npixels, fp);  /* read raw data */
+#endif
     }
   }
 
-  if (numgot != w*h) pbmError(bname, TRUNCSTR);   /* warning only */
+  if (numgot != npixels) pbmError(bname, TRUNCSTR);   /* warning only */
 
   if (garbage) {
     return (pbmError(bname, "Garbage characters in image data."));
@@ -256,18 +387,24 @@
      PICINFO *pinfo;
      int      raw, maxv;
 {
-  byte *pix, *pic24, scale[256], *pic8;
-  int   i,j,bitshift, w, h, holdmaxv;
+  byte *pix, *pic24, scale[256];
+  int   i,j,bitshift, w, h, npixels, bufsize, holdmaxv;
+
+  w = pinfo->w;
+  h = pinfo->h;
 
-  w = pinfo->w;  h = pinfo->h;
+  npixels = w * h;
+  bufsize = 3*npixels;
+  if (w <= 0 || h <= 0 || npixels/w != h || bufsize/3 != npixels)
+    return pbmError(bname, "image dimensions too large");
 
   /* allocate 24-bit image */
-  pic24 = (byte *) calloc((size_t) w*h*3, (size_t) 1);
-  if (!pic24) FatalError("couldn't malloc 'pic24'");
+  pic24 = (byte *) calloc((size_t) bufsize, (size_t) 1);
+  if (!pic24) FatalError("couldn't malloc 'pic24' for PPM");
 
   pinfo->pic  = pic24;
   pinfo->type = PIC24;
-  sprintf(pinfo->fullInfo, "PPM, %s format.  (%ld bytes)", 
+  sprintf(pinfo->fullInfo, "PPM, %s format.  (%ld bytes)",
 	  (raw) ? "raw" : "ascii", filesize);
   sprintf(pinfo->shrtInfo, "%dx%d PPM.", w, h);
   pinfo->colType = F_FULLCOLOR;
@@ -297,20 +434,149 @@
       }
     }
     else {
-      numgot = fread(pic24, (size_t) 1, (size_t) w*h*3, fp);  /* read data */
+#ifdef FIX_PIPE_ERROR
+  reread:
+      numgot += fread(pic24 + numgot, (size_t) 1, (size_t) w*h*3 - numgot, fp);  /* read data */
+      if(errno == EINTR){
+        if(DEBUG){
+	  fprintf(stderr,
+	  "Can't read all data from pipe, call select and waiting...\n");
+	}
+	ready_read();
+	goto reread;
+      }
+#else
+      numgot = fread(pic24, (size_t) 1, (size_t) bufsize, fp);  /* read data */
+#endif
     }
   }
-  
-  if (numgot != w*h*3) pbmError(bname, TRUNCSTR);
+
+  if (numgot != bufsize) pbmError(bname, TRUNCSTR);
 
   if (garbage)
     return(pbmError(bname, "Garbage characters in image data."));
 
 
-  /* have to scale all RGB values up (Conv24to8 expects RGB values to
-     range from 0-255 */
+  /* have to scale up all RGB values (Conv24to8 expects RGB values to
+     range from 0-255) */
 
-  if (maxv<255) { 
+  if (maxv<255) {
+    for (i=0; i<=maxv; i++) scale[i] = (i * 255) / maxv;
+
+    for (i=0, pix=pic24; i<h; i++) {
+      if ((i&0x3f)==0) WaitCursor();
+      for (j=0; j<w*3; j++, pix++) *pix = scale[*pix];
+    }
+  }
+
+  return 1;
+}
+
+
+/*******************************************/
+static int loadpam(fp, pinfo, raw, maxv)	/* unofficial RGBA extension */
+     FILE    *fp;
+     PICINFO *pinfo;
+     int      raw, maxv;
+{
+  byte *p, *pix, *pic24, *linebuf, scale[256], bgR, bgG, bgB, r, g, b, a;
+  int   i, j, bitshift, w, h, npixels, bufsize, linebufsize, holdmaxv;
+
+  w = pinfo->w;
+  h = pinfo->h;
+
+  npixels = w * h;
+  bufsize = 3*npixels;
+  linebufsize = 4*w;
+  if (w <= 0 || h <= 0 || npixels/w != h || bufsize/3 != npixels ||
+      linebufsize/4 != w)
+    return pbmError(bname, "image dimensions too large");
+
+  /* allocate 24-bit image */
+  pic24 = (byte *) calloc((size_t) bufsize, (size_t) 1);
+  if (!pic24) FatalError("couldn't malloc 'pic24' for PAM");
+
+  /* allocate line buffer for pre-composited RGBA data */
+  linebuf = (byte *) malloc((size_t) linebufsize);
+  if (!linebuf) {
+    free(pic24);
+    FatalError("couldn't malloc 'linebuf' for PAM");
+  }
+
+  pinfo->pic  = pic24;
+  pinfo->type = PIC24;
+  sprintf(pinfo->fullInfo, "PAM, %s format.  (%ld bytes)",
+	  (raw) ? "raw" : "ascii", filesize);
+  sprintf(pinfo->shrtInfo, "%dx%d PAM.", w, h);
+  pinfo->colType = F_FULLCOLOR;
+
+
+  /* if maxv>255, keep dropping bits until it's reasonable */
+  holdmaxv = maxv;
+  bitshift = 0;
+  while (maxv>255) { maxv = maxv>>1;  bitshift++; }
+
+
+  numgot = 0;
+
+  if (!raw) {					/* GRR:  not alpha-ready */
+    return pbmError(bname, "can't handle non-raw PAM image");
+/*
+    for (i=0, pix=pic24; i<h; i++) {
+      if ((i&0x3f)==0) WaitCursor();
+      for (j=0; j<w*3; j++, pix++)
+	*pix = (byte) (getint(fp, pinfo) >> bitshift);
+    }
+ */
+  }
+  else { /* raw */
+    if (holdmaxv>255) {				/* GRR:  not alpha-ready */
+      return pbmError(bname, "can't handle PAM image with maxval > 255");
+/*
+      for (i=0, pix=pic24; i<h; i++) {
+	if ((i&0x3f)==0) WaitCursor();
+	for (j=0; j<w*3; j++,pix++)
+	  *pix = (byte) (getshort(fp) >> bitshift);
+      }
+ */
+    }
+    else {
+      if (have_imagebg) {			/* GRR:  alpha-ready */
+        bgR = (imagebgR >> 8);
+        bgG = (imagebgG >> 8);
+        bgB = (imagebgB >> 8);
+      } else {
+        bgR = bgG = bgB = 0;
+      }
+      for (i=0, pix=pic24; i<h; i++) {
+        numgot += fread(linebuf, (size_t) 1, (size_t) linebufsize, fp);  /* read data */
+	if ((i&0x3f)==0) WaitCursor();
+	for (j=0, p=linebuf; j<w; j++) {
+          r = *p++;
+          g = *p++;
+          b = *p++;
+          a = *p++;
+          alpha_composite(*pix++, r, a, bgR)
+          alpha_composite(*pix++, g, a, bgG)
+          alpha_composite(*pix++, b, a, bgB)
+	}
+      }
+    }
+  }
+
+  free(linebuf);
+
+  /* in principle this could overflow, but not critical */
+  if (numgot != w*h*4) pbmError(bname, TRUNCSTR);
+
+  if (garbage)
+    return(pbmError(bname, "Garbage characters in image data."));
+
+
+  /* have to scale up all RGB values (Conv24to8 expects RGB values to
+     range from 0-255) */
+
+  if (maxv<255) {
     for (i=0; i<=maxv; i++) scale[i] = (i * 255) / maxv;
 
     for (i=0, pix=pic24; i<h; i++) {
@@ -360,8 +626,8 @@
 	  pinfo->comment[0] = '\0';
 	}
 	else {
-	  tmpptr = (char *) realloc(pinfo->comment, 
-		      strlen(pinfo->comment) + strlen(cmt) + 1); 
+	  tmpptr = (char *) realloc(pinfo->comment,
+		      strlen(pinfo->comment) + strlen(cmt) + 1);
 	  if (!tmpptr) FatalError("realloc failure in xvpbm.c getint");
 	  pinfo->comment = tmpptr;
 	}
@@ -409,7 +675,18 @@
 
   numgot++;
 
+  /* Sometime after 1995, NetPBM's ppm(5) man page was changed to say, "Each
+   * sample is represented in pure binary by either 1 or 2 bytes.  If the
+   * Maxval is less than  256, it is 1 byte.  Otherwise, it is 2 bytes.  The
+   * most significant byte is first."  This change is incompatible with
+   * images created for viewing with all previous versions of XV, however,
+   * so both approaches are left available as a compile-time option.  (Could
+   * make it runtime-selectable, too, but unclear whether anybody cares.) */
+#ifdef ASSUME_RAW_PPM_LSB_FIRST  /* legacy approach */
   return (c2 << 8) | c1;
+#else /* MSB first */
+  return (c1 << 8) | c2;
+#endif
 }
 
 
@@ -445,8 +722,8 @@
 	  pinfo->comment[0] = '\0';
 	}
 	else {
-	  tmpptr = (char *) realloc(pinfo->comment, 
-		      strlen(pinfo->comment) + strlen(cmt) + 1); 
+	  tmpptr = (char *) realloc(pinfo->comment,
+		      strlen(pinfo->comment) + strlen(cmt) + 1);
 	  if (!tmpptr) FatalError("realloc failure in xvpbm.c getint");
 	  pinfo->comment = tmpptr;
 	}
@@ -470,7 +747,7 @@
 
 /*******************************************/
 static int pbmError(fname, st)
-     char *fname, *st;
+     const char *fname, *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", fname, st);
   return 0;
@@ -490,7 +767,7 @@
      char *comment;
 {
   /* writes a PBM/PGM/PPM file to the already open stream
-     if (raw), writes as RAW bytes, otherwise writes as ASCII 
+     if (raw), writes as RAW bytes, otherwise writes as ASCII
      'colorstyle' single-handedly determines the type of file written
      if colorstyle==0, (Full Color) a PPM file is written
      if colorstyle==1, (Greyscale)  a PGM file is written
@@ -546,7 +823,7 @@
 	  }
 	}
 	else {
-	  if (ptype==PIC8) 
+	  if (ptype==PIC8)
 	    fprintf(fp,"%3d %3d %3d ",rmap[*pix], gmap[*pix], bmap[*pix]);
 	  else
 	    fprintf(fp,"%3d %3d %3d ",pix[0], pix[1], pix[2]);
@@ -554,7 +831,7 @@
 	  len+=12;
 	  if (len>58) { fprintf(fp,"\n");  len=0; }
 	}
-	
+
 	pix += (ptype==PIC24) ? 3 : 1;
       }
     }
@@ -584,7 +861,7 @@
 
   else if (colorstyle==2) {             /* 1-bit B/W stipple */
     int bit,k,flipbw;
-    char *str0, *str1;
+    const char *str0, *str1;
 
     /* shouldn't happen */
     if (ptype == PIC24) FatalError("PIC24 and B/W Stipple in WritePBM()\n");
@@ -626,10 +903,3 @@
 
   return 0;
 }
-
-
-	  
-	  
-
-
-
diff -ru xv-3.10a/xvpcx.c xv-3.10a-enhancements/xvpcx.c
--- xv-3.10a/xvpcx.c	1995-01-10 15:06:37.000000000 -0800
+++ xv-3.10a-enhancements/xvpcx.c	2007-05-13 18:46:27.000000000 -0700
@@ -29,17 +29,17 @@
 #define PCX_YMAXH   11
                           /* hres (12,13) and vres (14,15) not used */
 #define PCX_CMAP    16    /* start of 16*3 colormap data */
-#define PCX_PLANES  65 
+#define PCX_PLANES  65
 #define PCX_BPRL    66
 #define PCX_BPRH    67
 
 #define PCX_MAPSTART 0x0c	/* Start of appended colormap	*/
 
 
-static int  pcxLoadImage8  PARM((char *, FILE *, PICINFO *, byte *));
-static int  pcxLoadImage24 PARM((char *, FILE *, PICINFO *, byte *));
+static int  pcxLoadImage8  PARM((const char *, FILE *, PICINFO *, byte *));
+static int  pcxLoadImage24 PARM((const char *, FILE *, PICINFO *, byte *));
 static void pcxLoadRaster  PARM((FILE *, byte *, int, byte *, int, int));
-static int  pcxError       PARM((char *, char *));
+static int  pcxError       PARM((const char *, const char *));
 
 
 
@@ -51,9 +51,9 @@
 {
   FILE  *fp;
   long   filesize;
-  char  *bname, *errstr;
-  byte   hdr[128], *image;
+  byte   hdr[128];
   int    i, colors, gray, fullcolor;
+  const char  *bname;
 
   pinfo->type = PIC8;
   pinfo->pic     = (byte *) NULL;
@@ -64,7 +64,7 @@
   /* open the stream */
   fp = xv_fopen(fname,"r");
   if (!fp) return (pcxError(bname, "unable to open file"));
-  
+
 
   /* figure out the file size */
   fseek(fp, 0L, 2);
@@ -84,10 +84,10 @@
     return pcxError(bname,"unrecognized magic number");
   }
 
-  pinfo->w = (hdr[PCX_XMAXL] + ((int) hdr[PCX_XMAXH]<<8)) 
+  pinfo->w = (hdr[PCX_XMAXL] + ((int) hdr[PCX_XMAXH]<<8))
            - (hdr[PCX_XMINL] + ((int) hdr[PCX_XMINH]<<8));
 
-  pinfo->h = (hdr[PCX_YMAXL] + ((int) hdr[PCX_YMAXH]<<8)) 
+  pinfo->h = (hdr[PCX_YMAXL] + ((int) hdr[PCX_YMAXH]<<8))
            - (hdr[PCX_YMINL] + ((int) hdr[PCX_YMINH]<<8));
 
   pinfo->w++;  pinfo->h++;
@@ -96,10 +96,10 @@
   fullcolor = (hdr[PCX_BPP] == 8 && hdr[PCX_PLANES] == 3);
 
   if (DEBUG) {
-    fprintf(stderr,"PCX: %dx%d image, version=%d, encoding=%d\n", 
+    fprintf(stderr,"PCX: %dx%d image, version=%d, encoding=%d\n",
 	    pinfo->w, pinfo->h, hdr[PCX_VER], hdr[PCX_ENC]);
     fprintf(stderr,"   BitsPerPixel=%d, planes=%d, BytePerRow=%d, colors=%d\n",
-	    hdr[PCX_BPP], hdr[PCX_PLANES], 
+	    hdr[PCX_BPP], hdr[PCX_PLANES],
 	    hdr[PCX_BPRL] + ((int) hdr[PCX_BPRH]<<8),
 	    colors);
   }
@@ -190,9 +190,9 @@
 
   if (colors > 2 || (colors==2 && !gray)) {  /* grayscale or PseudoColor */
     pinfo->colType = (gray) ? F_GREYSCALE : F_FULLCOLOR;
-    sprintf(pinfo->fullInfo, 
-	    "%s PCX, %d plane%s, %d bit%s per pixel.  (%ld bytes)", 
-	    (gray) ? "Greyscale" : "Color", 
+    sprintf(pinfo->fullInfo,
+	    "%s PCX, %d plane%s, %d bit%s per pixel.  (%ld bytes)",
+	    (gray) ? "Greyscale" : "Color",
 	    hdr[PCX_PLANES], (hdr[PCX_PLANES]==1) ? "" : "s",
 	    hdr[PCX_BPP],    (hdr[PCX_BPP]==1) ? "" : "s",
 	    filesize);
@@ -212,21 +212,27 @@
 
 /*****************************/
 static int pcxLoadImage8(fname, fp, pinfo, hdr)
-     char    *fname;
+     const char *fname;
      FILE    *fp;
      PICINFO *pinfo;
      byte    *hdr;
 {
   /* load an image with at most 8 bits per pixel */
-  
+
   byte *image;
-  
+  int count;
+
   /* note:  overallocation to make life easier... */
-  image = (byte *) malloc((size_t) (pinfo->h + 1) * pinfo->w + 16);
+  count = (pinfo->h + 1) * pinfo->w + 16;  /* up to 65537*65536+16 (~ 65552) */
+  if (pinfo->w <= 0 || pinfo->h <= 0 || count/pinfo->w < pinfo->h) {
+    pcxError(fname, "Bogus 8-bit PCX file!!");
+    return (0);
+  }
+  image = (byte *) malloc((size_t) count);
   if (!image) FatalError("Can't alloc 'image' in pcxLoadImage8()");
-  
-  xvbzero((char *) image, (size_t) ((pinfo->h+1) * pinfo->w + 16));
-  
+
+  xvbzero((char *) image, (size_t) count);
+
   switch (hdr[PCX_BPP]) {
   case 1:   pcxLoadRaster(fp, image, 1, hdr, pinfo->w, pinfo->h);   break;
   case 8:   pcxLoadRaster(fp, image, 8, hdr, pinfo->w, pinfo->h);   break;
@@ -243,31 +249,39 @@
 
 /*****************************/
 static int pcxLoadImage24(fname, fp, pinfo, hdr)
-     char *fname;
+     const char *fname;
      FILE *fp;
      PICINFO *pinfo;
      byte *hdr;
 {
   byte *pix, *pic24, scale[256];
-  int   c, i, j, w, h, maxv, cnt, planes, bperlin, nbytes;
-  
+  int   c, i, j, w, h, maxv, cnt, planes, bperlin, nbytes, count;
+
   w = pinfo->w;  h = pinfo->h;
-  
-  planes = (int) hdr[PCX_PLANES];
-  bperlin = hdr[PCX_BPRL] + ((int) hdr[PCX_BPRH]<<8);
-  
+
+  planes = (int) hdr[PCX_PLANES];  /* 255 max, but can't get here unless = 3 */
+  bperlin = hdr[PCX_BPRL] + ((int) hdr[PCX_BPRH]<<8);  /* 65535 max */
+
+  j = h*planes;          /* w and h are limited to 65536, planes to 3 */
+  count = w*j;           /* ...so this could wrap up to 3 times */
+  nbytes = bperlin*j;    /* ...and this almost 3 times */
+  if (w <= 0 || h <= 0 || planes <= 0 || bperlin <= 0 ||
+      j/h < planes || count/w < j || nbytes/bperlin < j) {
+    pcxError(fname, "Bogus 24-bit PCX file!!");
+    return (0);
+  }
+
   /* allocate 24-bit image */
-  pic24 = (byte *) malloc((size_t) w*h*planes);
-  if (!pic24) FatalError("couldn't malloc 'pic24'");
-  
-  xvbzero((char *) pic24, (size_t) w*h*planes);
-  
+  pic24 = (byte *) malloc((size_t) count);
+  if (!pic24) FatalError("Can't malloc 'pic24' in pcxLoadImage24()");
+
+  xvbzero((char *) pic24, (size_t) count);
+
   maxv = 0;
   pix = pinfo->pic = pic24;
   i = 0;      /* planes, in this while loop */
   j = 0;      /* bytes per line, in this while loop */
-  nbytes = bperlin*h*planes;
- 
+
   while (nbytes > 0 && (c = getc(fp)) != EOF) {
     if ((c & 0xC0) == 0xC0) {   /* have a rep. count */
       cnt = c & 0x3F;
@@ -275,9 +289,9 @@
       if (c == EOF) { getc(fp); break; }
     }
     else cnt = 1;
-    
+
     if (c > maxv)  maxv = c;
-    
+
     while (cnt-- > 0) {
       if (j < w) {
 	*pix = c;
@@ -297,19 +311,19 @@
       }
     }
   }
-  
-  
+
+
   /* scale all RGB to range 0-255, if they aren't */
 
-  if (maxv<255) { 
+  if (maxv<255) {
     for (i=0; i<=maxv; i++) scale[i] = (i * 255) / maxv;
-    
+
     for (i=0, pix=pic24; i<h; i++) {
       if ((i&0x3f)==0) WaitCursor();
       for (j=0; j<w*planes; j++, pix++) *pix = scale[*pix];
     }
   }
-  
+
   return 1;
 }
 
@@ -321,13 +335,13 @@
      byte    *image, *hdr;
      int      depth,w,h;
 {
-  /* supported:  8 bits per pixel, 1 plane, or 1 bit per pixel, 1-8 planes */
+  /* supported:  8 bits per pixel, 1 plane; or 1 bit per pixel, 1-8 planes */
 
   int row, bcnt, bperlin, pad;
   int i, j, b, cnt, mask, plane, pmask;
   byte *oldimage;
 
-  bperlin = hdr[PCX_BPRL] + ((int) hdr[PCX_BPRH]<<8);
+  bperlin = hdr[PCX_BPRL] + ((int) hdr[PCX_BPRH]<<8);  /* 65535 max */
   if (depth == 1) pad = (bperlin * 8) - w;
              else pad = bperlin - w;
 
@@ -342,7 +356,7 @@
       if (b == EOF) { getc(fp); return; }
     }
     else cnt = 1;
-    
+
     for (i=0; i<cnt; i++) {
       if (depth == 1) {
 	for (j=0, mask=0x80; j<8; j++) {
@@ -351,12 +365,12 @@
 	}
       }
       else *image++ = (byte) b;
-      
+
       bcnt++;
-	
+
       if (bcnt == bperlin) {     /* end of a line reached */
 	bcnt = 0;
-	plane++;  
+	plane++;
 
 	if (plane >= (int) hdr[PCX_PLANES]) {   /* moved to next row */
 	  plane = 0;
@@ -367,19 +381,19 @@
 	}
 	else {   /* next plane, same row */
 	  image = oldimage;
-	}	
+	}
 
 	pmask = 1 << plane;
       }
     }
   }
-}    
+}
 
 
 
 /*******************************************/
 static int pcxError(fname,st)
-     char *fname, *st;
+     const char *fname, *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", fname, st);
   return 0;
diff -ru xv-3.10a/xvpds.c xv-3.10a-enhancements/xvpds.c
--- xv-3.10a/xvpds.c	1995-01-03 13:25:52.000000000 -0800
+++ xv-3.10a-enhancements/xvpds.c	2007-05-12 14:08:47.000000000 -0700
@@ -22,23 +22,23 @@
    Choice of algorithm for 16->8 bit conversion--linear or histogram stretch.
     (adds CONV24_HIST item in "24/8 bit" pull-down menu.)
    Uses any "palette.tab" file in cwd to color PDS/VICAR image.
- 
+
  * 9-2-91    began integration.	 Much of this code is lifted from vicar.c,
  	     which I wrote for xloadimage.  This is a little simpler, though.
- 
+
  * 10-17-91  pdsuncomp is called with system(), which typically feeds the
  	     commandline to sh.  Make sure that your .profile adds wherever
  	     you have pdsuncomp to the PATH, like
- 
+
  		PATH=$PATH:/usr/local/bin
- 
+
  * 11-15-91  substituted vdcomp from Viking CD's for pdsuncomp. I added
              recognition of - and shut off various messages
- 
+
  * 1-5-92    merged into xv rel 2
- 
+
  * 3-11-92   cleaned up some comments
- 
+
  * 3-24-92   Got some new CD's from NASA of mosics and other processed Viking
              stuff.  There are actually records terminated with CRNLCR in
              these images, as well as ones that identify the spacecraft name
@@ -46,14 +46,14 @@
              yet further to deal with these.  There's a Sun 4 XView binary for
              an image display program on these discs, but it's nowhere near as
              neat as the good Mr. Bradley's XV.
- 
- 
+
+
  * Sources of these CD's:
  *
  *  National Space Science Data Center
  *  Goddard Space Flight Center
  *  Code 933.4
- *  Greenbelt, Maryland  
+ *  Greenbelt, Maryland
  *  (301) 286-6695
  *   or call
  *  (301) 286-9000 (300,1200,2400 bps)
@@ -77,8 +77,7 @@
  * Huffman-encoded, and the encoding histogram follows the ASCII headers.
  * To decode these, we use a slightly modified version of "vdcomp.c" from the
  * NASA Viking CD-ROMS.  For xv to work, you need to have vdcomp compiled
- * and in your search path.  vdcomp.c should be included with this
-distribution.
+ * and in your search path.  vdcomp.c should be included with this distribution.
  *
  * I've heard that newer discs have FITS images on them.  If they do, support
  * for them will be added when I get one.  Until then, you can use fitstopgm.
@@ -91,10 +90,10 @@
  * Copyright 1989, 1990 by Anthony A. Datri
  *
  * Permission to use, copy, and distribute for non-commercial purposes,
- * is hereby granted without fee, providing that the above copyright   
+ * is hereby granted without fee, providing that the above copyright
  * notice appear in all copies, that both the copyright notice and this
  * permission notice appear in supporting documentation.
- * 
+ *
  * In exception to the above, permission to John Bradley is hereby granted to
  * distribute this code as he sees fit within the context of his "xv" image
  * viewer.
@@ -102,7 +101,7 @@
  * This software is provided "as is" without any express or implied warranty.
  */
 
-
+#define  NEEDSDIR       /* for S_IRUSR|S_IWUSR */
 #include "xv.h"
 
 #ifdef HAVE_PDS
@@ -129,27 +128,32 @@
 
 /* This is arbitrary.  Everything I've seen so far fits in 50 chars */
 #define COMMENTSIZE	50
+#define INOTESIZE	1000
 
 
 static int	lastwasinote = FALSE;
-static char	scanbuff         [MAX_SIZE], 
-                rtbuff         [RTBUFFSIZE], 
-		inote	   [20*COMMENTSIZE],
-                infobuff      [COMMENTSIZE],
-		spacecraft    [COMMENTSIZE],
-		target        [COMMENTSIZE],
-		filtname      [COMMENTSIZE],
-		gainmode      [COMMENTSIZE],
-		editmode      [COMMENTSIZE],
-		scanmode      [COMMENTSIZE],
-		exposure      [COMMENTSIZE],
-		shuttermode   [COMMENTSIZE],
-		mphase        [COMMENTSIZE],
-		iname         [COMMENTSIZE],
-		itime         [COMMENTSIZE],
-                garbage       [1020],
+static char	scanbuff         [MAX_SIZE+1],
+                rtbuff         [RTBUFFSIZE+1],
+		inote	        [INOTESIZE+1],
+                infobuff      [COMMENTSIZE+1],
+		spacecraft    [COMMENTSIZE+1],
+		target        [COMMENTSIZE+1],
+		filtname      [COMMENTSIZE+1],
+		gainmode      [COMMENTSIZE+1],
+		editmode      [COMMENTSIZE+1],
+		scanmode      [COMMENTSIZE+1],
+		exposure      [COMMENTSIZE+1],
+		shuttermode   [COMMENTSIZE+1],
+		mphase        [COMMENTSIZE+1],
+		iname         [COMMENTSIZE+1],
+		itime         [COMMENTSIZE+1],
+                garbage       [1024],
 		*tmptmp,
 		pdsuncompfname[FNAMESIZE];
+
+#define SSTR(l)			"%" #l "s"
+#define S(l)			SSTR(l)
+
 byte *image;
 static int elaphe;
 
@@ -203,10 +207,10 @@
 		  }
                 return(count);
 
-    case EOF:	*bp='\0';  return(count);		    
-    
+    case EOF:	*bp='\0';  return(count);
+
     case '\0':  return(count);
-    
+
     default:	count++;  *bp++ = c;
     }
   }
@@ -242,7 +246,7 @@
  * disc seem to leave off the first two bytes.  Sigh.  This may sometimes be
  * a distinction between the fixed and variable-record files.
  */
-            
+
 /*******************************************/
 int LoadPDS(fname, pinfo)
      char    *fname;
@@ -250,13 +254,16 @@
 {
   /* returns '1' on success, '0' on failure */
 
-  int tempnum;
+  int tempnum, bytewidth, bufsize;
+#ifndef USE_MKSTEMP
+  int tmpfd;
+#endif
   FILE	*zf;
   static int isfixed,teco,i,j,itype,vaxbyte,
              recsize,hrecsize,irecsize,isimage,labelrecs,labelsofar,
-             x,y,lpsize,lssize,samplesize,returnp,labelsize,yy;
+             w,h,lpsize,lssize,samplesize,returnp,labelsize,yy;
   char	*tmp;
-  char  *ftypstr;
+  const char   *ftypstr;
   unsigned long filesize;
   char  sampletype[64];
 
@@ -265,7 +272,7 @@
   returnp = isimage = FALSE;
   itype   = PDSTRASH;
 
-  teco = i = j = recsize = hrecsize = irecsize = labelrecs = x = y = 0;
+  teco = i = j = recsize = hrecsize = irecsize = labelrecs = w = h = 0;
   lpsize = lssize = samplesize = labelsize = labelsofar = 0;
 
   (*pdsuncompfname) = (*iname) = (*target) = (*filtname) = (*garbage) = '\0';
@@ -363,7 +370,7 @@
 	 * length indicator. If the length indicator is odd, then a pad byte
 	 * is appended to the end of the record so that all records contain
 	 * an even number of bytes." */
-	                                                                    
+
 	i=getc(zf);
 	j=getc(zf);
 	if (j == EOF) {
@@ -371,7 +378,7 @@
 	  fclose(zf);
 	  return 0;
 	}
-	
+
 	teco = i + (j << 8);
 	if (teco % 2) teco++;
 
@@ -380,7 +387,7 @@
 	  fclose(zf);
 	  return 0;
 	}
-	
+
 	scanbuff[teco]='\0';
       }
 
@@ -397,7 +404,7 @@
 
       if (strcmp(scanbuff,"END") == 0) {
 	break;
-      } else if (sscanf(scanbuff," RECORD_TYPE = %s",rtbuff) == 1) {
+      } else if (sscanf(scanbuff, " RECORD_TYPE = " S(RTBUFFSIZE), rtbuff) == 1) {
 	if (strncmp(rtbuff,"VARIABLE_LENGTH", (size_t) 15) == 0) {
 	  /*		itype=PDSVARIABLE; */
 	} else if (strncmp(rtbuff,"FIXED_LENGTH", (size_t) 12) == 0) {
@@ -416,7 +423,7 @@
 	    if (irecsize == 0) irecsize=recsize;
 	lastwasinote=FALSE;
 	continue;
-      } else if (sscanf(scanbuff," FILE_TYPE = %s", rtbuff) != 0) {
+      } else if (sscanf(scanbuff, " FILE_TYPE = " S(RTBUFFSIZE), rtbuff) != 0) {
 	lastwasinote=FALSE;
 	if (strncmp(rtbuff,"IMAGE", (size_t) 5) == 0) {
 	  isimage=TRUE;
@@ -429,11 +436,11 @@
 		 (sscanf(scanbuff," LABEL_RECORDS = %d", &labelrecs) == 1)) {
 	lastwasinote=FALSE;
 	continue;
-      } else if (sscanf(scanbuff," IMAGE_LINES = %d",&y) == 1) {
+      } else if (sscanf(scanbuff," IMAGE_LINES = %d",&h) == 1) {
 	isimage=TRUE; lastwasinote=FALSE; continue;
-      } else if (sscanf(scanbuff," LINE_SAMPLES = %d",&x) == 1) {
+      } else if (sscanf(scanbuff," LINE_SAMPLES = %d",&w) == 1) {
 	lastwasinote=FALSE; continue;
-      } else if (sscanf(scanbuff," LINES = %d",&y) == 1) {
+      } else if (sscanf(scanbuff," LINES = %d",&h) == 1) {
 	isimage=TRUE; lastwasinote=FALSE; continue;
       } else if (sscanf(scanbuff," HEADER_RECORD_BYTES = %d",&hrecsize)==1) {
 	lastwasinote=FALSE; continue;
@@ -445,74 +452,74 @@
 	lastwasinote=FALSE; continue;
       } else if (sscanf(scanbuff," SAMPLE_BITS = %d", &samplesize) == 1) {
 	lastwasinote=FALSE; continue;
-      } else if (sscanf(scanbuff," SAMPLE_TYPE = %s", sampletype) == 1) {
+      } else if (sscanf(scanbuff, " SAMPLE_TYPE = " S(64), sampletype) == 1) {
 	lastwasinote=FALSE; continue;
-      } else if (sscanf(scanbuff," SPACECRAFT_NAME = %s %s",
+      } else if (sscanf(scanbuff," SPACECRAFT_NAME = " S(COMMENTSIZE) " " S(1023),
 			spacecraft,garbage) == 2 ) {
-	strcat(spacecraft,xv_strstr(scanbuff, spacecraft)+strlen(spacecraft));
+	const char *tmp = xv_strstr(scanbuff, spacecraft) + strlen(spacecraft);
+	strncat(spacecraft, tmp, COMMENTSIZE - strlen(spacecraft));
 	lastwasinote=FALSE;  continue;
-      } else if (sscanf(scanbuff," SPACECRAFT_NAME = %s", spacecraft) == 1) {
+      } else if (sscanf(scanbuff, " SPACECRAFT_NAME = " S(COMMENTSIZE), spacecraft) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," TARGET_NAME = %s", target) == 1) {
+      } else if (sscanf(scanbuff, " TARGET_NAME = " S(COMMENTSIZE), target) == 1) {
 	lastwasinote=FALSE; continue;
-      } else if (sscanf(scanbuff," TARGET_BODY = %s", target) == 1) {
+      } else if (sscanf(scanbuff, " TARGET_BODY = " S(COMMENTSIZE), target) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," MISSION_PHASE_NAME = %s", mphase) == 1) {
+      } else if (sscanf(scanbuff, " MISSION_PHASE_NAME = " S(COMMENTSIZE), mphase) == 1) {
 	lastwasinote=FALSE; continue;
-      } else if (sscanf(scanbuff," MISSION_PHASE = %s", mphase) == 1) {
+      } else if (sscanf(scanbuff, " MISSION_PHASE = " S(COMMENTSIZE), mphase) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," INSTRUMENT_NAME = %s", iname) == 1) {
+      } else if (sscanf(scanbuff, " INSTRUMENT_NAME = " S(COMMENTSIZE), iname) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," GAIN_MODE_ID = %s", gainmode) == 1) {
+      } else if (sscanf(scanbuff, " GAIN_MODE_ID = " S(COMMENTSIZE), gainmode) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," INSTRUMENT_GAIN_STATE = %s",gainmode)==1) {
+      } else if (sscanf(scanbuff, " INSTRUMENT_GAIN_STATE = " S(COMMENTSIZE), gainmode) ==1 ) {
 	lastwasinote=FALSE; continue;
-	
-      } else if (sscanf(scanbuff," EDIT_MODE_ID = %s", editmode) == 1) {
+
+      } else if (sscanf(scanbuff, " EDIT_MODE_ID = " S(COMMENTSIZE), editmode) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," INSTRUMENT_EDIT_MODE = %s", editmode)==1) {
+      } else if (sscanf(scanbuff, " INSTRUMENT_EDIT_MODE = " S(COMMENTSIZE), editmode) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," SCAN_MODE_ID = %s", scanmode) == 1) {
+      } else if (sscanf(scanbuff, " SCAN_MODE_ID = " S(COMMENTSIZE), scanmode) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," INSTRUMENT_SCAN_RATE = %s", scanmode)==1) {
+      } else if (sscanf(scanbuff, " INSTRUMENT_SCAN_RATE = " S(COMMENTSIZE), scanmode) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," SHUTTER_MODE_ID = %s", shuttermode) == 1) {
+      } else if (sscanf(scanbuff, " SHUTTER_MODE_ID = " S(COMMENTSIZE), shuttermode) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," INSTRUMENT_SHUTTER_MODE = %s",
-			shuttermode) == 1) {
+      } else if (sscanf(scanbuff, " INSTRUMENT_SHUTTER_MODE = " S(COMMENTSIZE), shuttermode) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," SCAN_MODE_ID = %s", scanmode) == 1) {
+      } else if (sscanf(scanbuff, " SCAN_MODE_ID = " S(COMMENTSIZE), scanmode) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," INSTRUMENT_SCAN_RATE = %s", scanmode)==1) {
+      } else if (sscanf(scanbuff, " INSTRUMENT_SCAN_RATE = " S(COMMENTSIZE), scanmode) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," SPACECRAFT_EVENT_TIME = %s", itime) == 1) {
+      } else if (sscanf(scanbuff, " SPACECRAFT_EVENT_TIME = " S(COMMENTSIZE), itime) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," IMAGE_TIME = %s", itime) == 1) {
+      } else if (sscanf(scanbuff, " IMAGE_TIME = " S(COMMENTSIZE), itime) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," FILTER_NAME = %s", filtname) == 1) {
+      } else if (sscanf(scanbuff, " FILTER_NAME = " S(COMMENTSIZE), filtname) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff," INSTRUMENT_FILTER_NAME = %s",filtname)==1) {
+      } else if (sscanf(scanbuff, " INSTRUMENT_FILTER_NAME = " S(COMMENTSIZE), filtname) == 1) {
 	lastwasinote=FALSE; continue;
 
-      } else if ((sscanf(scanbuff," EXPOSURE_DURATION = %s", exposure) == 1)
-	      || (sscanf(scanbuff," INSTRUMENT_EXPOSURE_DURATION = %s",
-			 exposure) == 1)) {
+      } else if ((sscanf(scanbuff, " EXPOSURE_DURATION = " S(COMMENTSIZE), exposure) == 1)
+	      || (sscanf(scanbuff, " INSTRUMENT_EXPOSURE_DURATION = " S(COMMENTSIZE),
+			 exposure)) == 1) {
 	tmptmp = (char *) index(scanbuff,'=');
 	tmptmp++;
 	while((*tmptmp) == ' ')
@@ -520,10 +527,10 @@
 	strcpy(exposure,tmptmp);
 	lastwasinote=FALSE; continue;
 
-      } else if (sscanf(scanbuff, "NOTE = %s", inote) == 1) {
+      } else if (sscanf(scanbuff, "NOTE = " S(INOTESIZE), inote) == 1) {
 	tmptmp = (char *) index(scanbuff,'='); tmptmp++;
 	while (((*tmptmp) == ' ') || ((*tmptmp)  == '"')) tmptmp++;
-	strcpy(inote,tmptmp);
+	strncpy(inote, tmptmp, INOTESIZE - 1);
 	strcat(inote," ");
 
 	/*   evil and somewhat risky:  A "note" (really, any textual
@@ -531,11 +538,11 @@
 	 *     get my hands on the clown who designed this format...
 	 *                             What we basically assume here
 	 *        is that a NOTE record that doesn't end with a " is
-	 *    followed by some number of continuations, one of which 
+	 *    followed by some number of continuations, one of which
 	 *   will have a " in it.  If this turns out to not be true,
 	 *          well, we'll segmentation fault real soon. We use
 	 * lastwasinote as a semaphore to indicate that the previous
-	 *       record was an unfinished NOTE record.  We clear the	  
+	 *       record was an unfinished NOTE record.  We clear the
 	 *      flag in each of the above record types for potential
 	 *   error recovery, although it really breaks up the beauty
 	 * of the cascading sscanfs.  Dykstra'd love me for this one */
@@ -548,7 +555,7 @@
       } else if (lastwasinote) {
 	tmptmp=scanbuff;
 	while (((*tmptmp) == ' ') || ((*tmptmp)  == '"')) tmptmp++;
-	strcat(inote,tmptmp);
+	strncat(inote, tmptmp, INOTESIZE - strlen(inote) - 1);
 	strcat(inote," ");
 	if (index(tmptmp,'"') != NULL)
 	    lastwasinote=FALSE;
@@ -568,10 +575,10 @@
       fclose(zf);
       return 0;
     }
-    
+
     vaxbyte = strncmp(sampletype, "VAX_", (size_t) 4) == 0 ||
       strncmp(sampletype, "LSB_", (size_t) 4) == 0;
-    
+
   } else if (itype == VICAR) {
     /* we've got a VICAR file.  Let's find out how big the puppy is */
     ungetc(' ', zf);
@@ -582,8 +589,8 @@
 	SetISTR(ISTR_WARNING,"LoadPDS: bad NL in VICAR\n");
 	returnp=TRUE;
       }
-      
-      if (sscanf(tmp," NL = %d",&y) != 1) {
+
+      if (sscanf(tmp," NL = %d",&h) != 1) {
 	SetISTR(ISTR_WARNING,"LoadPDS: bad scan NL in VICAR\n");
 	returnp=TRUE;
       }
@@ -593,7 +600,7 @@
 	returnp=TRUE;
       }
 
-      if (sscanf(tmp, " NS = %d",&x) != 1) {
+      if (sscanf(tmp, " NS = %d",&w) != 1) {
 	SetISTR(ISTR_WARNING,"LoadPDS: bad scan NS in VICAR\n");
 	returnp=TRUE;
       }
@@ -625,6 +632,13 @@
     returnp=TRUE;
   }
 
+  /* samplesize can be arbitrarily large (up to int limit) in non-VICAR files */
+  if (samplesize != 8 && samplesize != 16) {
+    SetISTR(ISTR_WARNING,"LoadPDS: %d bits per pixel not supported",
+      samplesize);
+    returnp=TRUE;
+  }
+
   if (returnp) {
     fclose(zf);
     return 0;
@@ -640,27 +654,27 @@
 
   *infobuff='\0';
   if (*spacecraft) {
-    strcat(infobuff,spacecraft);
+    strncat(infobuff, spacecraft, sizeof(infobuff) - 1);
   }
 
   if (*target) {
-    strcat(infobuff,", ");
-    strcat(infobuff,target);
+    strncat(infobuff, ", ", sizeof(infobuff) - strlen(infobuff) - 1);
+    strncat(infobuff, target, sizeof(infobuff) - strlen(infobuff) - 1);
   }
 
   if (*filtname) {
-    strcat(infobuff,", ");
-    strcat(infobuff,filtname);
+    strncat(infobuff, ", ", sizeof(infobuff) - strlen(infobuff) - 1);
+    strncat(infobuff, filtname, sizeof(infobuff) - strlen(infobuff) - 1);
   }
 
   if (*itime) {
-    strcat(infobuff,", ");
-    strcat(infobuff,itime);
+    strncat(infobuff, ", ", sizeof(infobuff) - strlen(infobuff) - 1);
+    strncat(infobuff, itime, sizeof(infobuff) - strlen(infobuff) - 1);
   }
 
-  SetISTR(ISTR_WARNING,infobuff);
+  SetISTR(ISTR_WARNING, "%s", infobuff);
 
-  strcpy(pdsuncompfname,fname);
+  strncpy(pdsuncompfname,fname,sizeof(pdsuncompfname) - 1);
   ftypstr = "";
 
   switch (itype) {
@@ -688,12 +702,26 @@
     fclose(zf);
 
 #ifndef VMS
-    sprintf(pdsuncompfname,"%s/xvhuffXXXXXX", tmpdir);
-    mktemp(pdsuncompfname);
-    sprintf(scanbuff,"%s %s - 4 >%s",PDSUNCOMP,fname,pdsuncompfname);
+    snprintf(pdsuncompfname, sizeof(pdsuncompfname) - 1, "%s/xvhuffXXXXXX", tmpdir);
 #else
     strcpy(pdsuncompfname,"sys$disk:[]xvhuffXXXXXX");
+#endif
+
+#ifdef USE_MKSTEMP
+    close(mkstemp(pdsuncompfname));
+#else
     mktemp(pdsuncompfname);
+    tmpfd = open(pdsuncompfname,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR);
+    if (tmpfd < 0) {
+      SetISTR(ISTR_WARNING,"Unable to create temporary file.");
+      return 0;
+    }
+    close(tmpfd);
+#endif
+
+#ifndef VMS
+    sprintf(scanbuff,"%s '%s' - 4 > %s", PDSUNCOMP, fname, pdsuncompfname);
+#else
     sprintf(scanbuff,"%s %s %s 4",PDSUNCOMP,fname,pdsuncompfname);
 #endif
 
@@ -727,63 +755,72 @@
     fread(scanbuff, (size_t) labelsize, (size_t) 1, zf);
   }
 
-  x *= samplesize/8;
+  /* samplesize is bits per pixel; guaranteed at this point to be 8 or 16 */
+  bytewidth = w * (samplesize/8);
+  bufsize = bytewidth * h;
+  if (w <= 0 || h <= 0 || bytewidth/w != (samplesize/8) ||
+      bufsize/bytewidth != h)
+  {
+    SetISTR(ISTR_WARNING,"LoadPDS: image dimensions out of range (%dx%dx%d)",
+      w, h, samplesize/8);
+    fclose(zf);
+    return 0;
+  }
 
-  image = (byte *) malloc((size_t) x*y);
+  image = (byte *) malloc((size_t) bufsize);
   if (image == NULL) {
-    SetISTR(ISTR_WARNING,"LoadPDS: couldn't malloc %d",x*y);
     fclose(zf);
     if (isfixed == FALSE)
       unlink(pdsuncompfname);
-    exit(1);
+    FatalError("LoadPDS: can't malloc image buffer");
   }
 
   if ((lssize || lpsize) &&
        ((itype == PDSFIXED) || (itype == VIKINGFIXED) || (itype == VICAR)) ) {
     /* ARrrrgh.  Some of these images have crud intermixed with the image, */
     /* preventing us from freading in one fell swoop */
-    /* (whatever a fell swoop is */
+    /* (whatever a fell swoop is) */
 
-    for (yy=0; yy<y; yy++) {
-      if (lpsize && 
-	  ((teco=(fread(scanbuff,(size_t) lpsize,(size_t) 1,zf))) != 1)) {
+    for (yy=0; yy<h; yy++) {
+      if (lpsize &&
+	  (teco=fread(scanbuff,(size_t) lpsize,(size_t) 1,zf)) != 1) {
 	SetISTR(ISTR_WARNING, "LoadPDS: unexpected EOF reading prefix");
 	fclose(zf);
 	return 0;
       }
-      
-      if ((teco=(fread(image+(yy*x), (size_t) x, (size_t) 1,zf))) != 1) {
+
+      teco = fread(image+(yy*bytewidth), (size_t) bytewidth, (size_t) 1,zf);
+      if (teco != 1) {
 	SetISTR(ISTR_WARNING, "LoadPDS: unexpected EOF reading line %d",yy);
 	fclose(zf);
 	return 0;
       }
 
-      if (lssize && 
-	  ((teco=(fread(scanbuff,(size_t) lssize,(size_t) 1,zf))) != 1)) {
+      if (lssize &&
+	  (teco=fread(scanbuff,(size_t) lssize,(size_t) 1,zf)) != 1) {
 	SetISTR(ISTR_WARNING, "LoadPDS: unexpected EOF reading suffix");
 	fclose(zf);
 	return 0;
       }
     }
 
-  } else if ((yy=fread(image, (size_t) x*y, (size_t) 1, zf)) != 1) {
+  } else if ((yy=fread(image, (size_t) bytewidth*h, (size_t) 1, zf)) != 1) {
     SetISTR(ISTR_WARNING,"LoadPDS: error reading image data");
     fclose(zf);
     if (itype==PDSVARIABLE || itype==VIKINGVARIABLE)
       unlink(pdsuncompfname);
-
     return 0;
   }
 
-    fclose(zf);
+  fclose(zf);
 
 
   if (isfixed == FALSE)
     unlink(pdsuncompfname);
 
   pinfo->pic = image;
-  pinfo->w   = x;
-  pinfo->h    = y;
+  pinfo->w   = w;   /* true pixel-width now (no longer bytewidth!) */
+  pinfo->h   = h;
 
   if (samplesize == 16)
      if (Convert16BitImage(fname, pinfo,
@@ -798,27 +835,27 @@
   if (pinfo->comment) {
     char tmp[256];
     *(pinfo->comment) = '\0';
-    
-    sprintf(tmp, "Spacecraft: %-28sTarget: %-32s\n", spacecraft, target);
-    strcat(pinfo->comment, tmp);
-    
-    sprintf(tmp, "Filter: %-32sMission phase: %-24s\n", filtname, mphase);
-    strcat(pinfo->comment, tmp);
-    
-    sprintf(tmp, "Image time: %-28sGain mode: %-29s\n", itime, gainmode);
-    strcat(pinfo->comment, tmp);
-    
-    sprintf(tmp, "Edit mode: %-29sScan mode: %-29s\n", editmode, scanmode);
-    strcat(pinfo->comment, tmp);
-    
-    sprintf(tmp, "Exposure: %-30sShutter mode: %-25s\n", exposure,shuttermode);
-    strcat(pinfo->comment, tmp);
-    
-    sprintf(tmp, "Instrument: %-28sImage time: %-28s\n", iname, itime);
-    strcat(pinfo->comment, tmp);
-    
-    sprintf(tmp, "Image Note: %-28s", inote);
-    strcat(pinfo->comment, tmp);
+
+    sprintf(tmp, "Spacecraft: %-28.28sTarget: %-32.32s\n", spacecraft, target);
+    strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1);
+
+    sprintf(tmp, "Filter: %-32.32sMission phase: %-24.24s\n", filtname, mphase);
+    strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1);
+
+    sprintf(tmp, "Image time: %-28.28sGain mode: %-29.29s\n", itime, gainmode);
+    strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1);
+
+    sprintf(tmp, "Edit mode: %-29.29sScan mode: %-29.29s\n", editmode, scanmode);
+    strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1);
+
+    sprintf(tmp, "Exposure: %-30.30sShutter mode: %-25.25s\n", exposure,shuttermode);
+    strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1);
+
+    sprintf(tmp, "Instrument: %-28.28sImage time: %-28.28s\n", iname, itime);
+    strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1);
+
+    sprintf(tmp, "Image Note: %-28.28s", inote);
+    strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1);
   }
 
   if (LoadPDSPalette(fname, pinfo))  return 1;
@@ -868,23 +905,20 @@
   m = 65536 * sizeof(byte);
   lut = (byte *) malloc(m);
   if (lut == NULL) {
-    SetISTR(ISTR_WARNING,"LoadPDS: couldn't malloc %d", m);
-    return 0;
+    FatalError("LoadPDS: can't malloc LUT buffer");
   }
-  pinfo->w /= 2;
 
   /* allocate histogram table */
   m = 65536 * sizeof(long);
   hist = (long *) malloc(m);
   if (hist == NULL) {
-    SetISTR(ISTR_WARNING,"LoadPDS: couldn't malloc %d", m);
     free(lut);
-    return 0;
+    FatalError("LoadPDS: can't malloc histogram buffer");
   }
 
   /* check whether histogram file exists */
 #ifdef VMS
-  c = (char *) rindex(strcpy(name, 
+  c = (char *) rindex(strcpy(name,
 			     (c = (char *) rindex(fname, ':')) ? c+1 : fname),
 		      ']');
 #else
@@ -947,14 +981,20 @@
     }
   }
 
-  /* allocate new 8-bit image */
   free(hist);
+
+  /* allocate new 8-bit image */
   n = pinfo->w * pinfo->h;
+  if (pinfo->w <= 0 || pinfo->h <= 0 || n/pinfo->w != pinfo->h) {
+    SetISTR(ISTR_WARNING,"LoadPDS: image dimensions out of range (%dx%d)",
+      pinfo->w, pinfo->h);
+    free(lut);
+    return 0;
+  }
   pPix8 = (byte *)malloc(n*sizeof(byte));
   if (pPix8 == NULL) {
-    SetISTR(ISTR_WARNING,"LoadPDS: couldn't malloc %d", n*sizeof(byte));
     free(lut);
-    return 0;
+    FatalError("LoadPDS: can't malloc 16-to-8-bit conversion buffer");
   }
 
   /* convert the 16-bit image to 8-bit */
@@ -979,16 +1019,16 @@
   FILE    *fp;
   char    name[1024], buf[256], *c;
   int     i, n, r, g, b;
-  
+
 #ifdef VMS
-  c = (char *) rindex(strcpy(name, 
+  c = (char *) rindex(strcpy(name,
 			     (c = (char *) rindex(fname, ':')) ? c+1 : fname),
 		      ']');
 #else
   c = (char *) rindex(strcpy(name, fname), '/');
 #endif /* VMS */
   (void)strcpy(c ? c+1 : name, "palette.tab");
-  
+
   if ((fp = xv_fopen(name, "r")) == NULL)
     return 0;
   for (i = 0; i < 256; i++) {
@@ -1014,7 +1054,3 @@
 
 
 #endif /* HAVE_PDS */
-
-
-
-
diff -ru xv-3.10a/xvpictoppm.c xv-3.10a-enhancements/xvpictoppm.c
--- xv-3.10a/xvpictoppm.c	1995-01-13 11:57:14.000000000 -0800
+++ xv-3.10a-enhancements/xvpictoppm.c	2005-04-10 09:36:04.000000000 -0700
@@ -77,7 +77,7 @@
   FILE *fp;
   byte  *icon8, *pic24, *ip, *pp;
   char  buf[256];
-  int   i, builtin, w, h, mv;
+  int   i, builtin, w, h, maxval, npixels, p24sz;
 
   fp = stdin;
   builtin = 0;
@@ -88,42 +88,45 @@
   /* read comments until we see '#END_OF_COMMENTS', or hit EOF */
   while (1) {
     if (!fgets(buf, 256, fp)) errexit();
-    
+
     if (!strncmp(buf, "#END_OF_COMMENTS", (size_t) 16)) break;
 
     else if (!strncmp(buf, "#BUILTIN:",   (size_t)  9)) {
       builtin = 1;
-      fprintf(stderr,"Built-In icon:  no image to convert!\n");
+      fprintf(stderr, "Built-in icon:  no image to convert\n");
       exit(1);
     }
   }
 
 
   /* read width, height, maxval */
-  if (!fgets(buf, 256, fp) || sscanf(buf, "%d %d %d", &w, &h, &mv) != 3) 
+  if (!fgets(buf, 256, fp) || sscanf(buf, "%d %d %d", &w, &h, &maxval) != 3)
     errexit();
 
+  npixels = w * h;
+  p24sz = 3 * npixels;
 
-  if (w<1 || h<1 || mv != 255) {
-    fprintf(stderr,"Bogus thumbnail file!\n");
+  if (w <= 0 || h <= 0 || maxval != 255 || npixels/w != h || p24sz/3 != npixels)
+  {
+    fprintf(stderr, "Thumbnail dimensions out of range\n");
     exit(1);
   }
 
 
   /* read binary data */
-  icon8 = (byte *) malloc((size_t) w * h);
+  icon8 = (byte *) malloc((size_t) npixels);
   if (!icon8) errexit();
 
-  i = fread(icon8, (size_t) 1, (size_t) w*h, fp);
-  if (i != w*h) errexit();
+  i = fread(icon8, (size_t) 1, (size_t) npixels, fp);
+  if (i != npixels) errexit();
+
 
-  
   /* make 24-bit version of icon */
-  pic24 = (byte *) malloc((size_t) w * h * 3);
+  pic24 = (byte *) malloc((size_t) p24sz);
   if (!pic24) errexit();
 
   /* convert icon from 332 to 24-bit image */
-  for (i=0, ip=icon8, pp=pic24;  i<w*h;  i++, ip++, pp+=3) {
+  for (i=0, ip=icon8, pp=pic24;  i<npixels;  i++, ip++, pp+=3) {
     pp[0] = ( ((int) ((*ip >> 5) & 0x07)) * 255) / 7;
     pp[1] = ( ((int) ((*ip >> 2) & 0x07)) * 255) / 7;
     pp[2] = ( ((int) ((*ip >> 0) & 0x03)) * 255) / 3;
@@ -160,10 +163,3 @@
 
   if (ferror(fp)) errexit();
 }
-
-
-	  
-	  
-
-
-
diff -ru xv-3.10a/xvpm.c xv-3.10a-enhancements/xvpm.c
--- xv-3.10a/xvpm.c	1994-12-22 14:34:40.000000000 -0800
+++ xv-3.10a-enhancements/xvpm.c	2007-05-13 17:34:04.000000000 -0700
@@ -42,9 +42,9 @@
 /***** end PM.H *****/
 
 
-pmpic  thePic;
+static pmpic thePic;
 
-static int  pmError  PARM((char *, char *));
+static int  pmError  PARM((const char *, const char *));
 static int  flip4    PARM((int));
 static int  getint32 PARM((FILE *));
 static void putint32 PARM((int, FILE *));
@@ -60,8 +60,8 @@
 
   FILE  *fp;
   byte  *pic8;
-  int    isize,i,flipit,w,h;
-  char  *bname;
+  int    isize,i,flipit,w,h,npixels,nRGBbytes;
+  const char  *bname;
 
   bname = BaseName(fname);
   thePic.pm_image = (char *) NULL;
@@ -103,10 +103,11 @@
     thePic.pm_cmtsize = flip4(thePic.pm_cmtsize);
     }
 
-  w = thePic.pm_ncol;  h = thePic.pm_nrow;
+  w = thePic.pm_ncol;
+  h = thePic.pm_nrow;
 
   /* make sure that the input picture can be dealt with */
-  if ( thePic.pm_nband!=1 || 
+  if ( thePic.pm_nband!=1 ||
       (thePic.pm_form!=PM_I && thePic.pm_form!=PM_C) ||
       (thePic.pm_form==PM_I && thePic.pm_np>1) ||
       (thePic.pm_form==PM_C && (thePic.pm_np==2 || thePic.pm_np>4)) ) {
@@ -114,20 +115,27 @@
     fprintf(stderr,"(ie, 1-plane PM_I, or 1-, 3-, or 4-plane PM_C)\n");
 
     return pmError(bname, "PM file in unsupported format");
-  }	
+  }
 
 
   isize = pm_isize(&thePic);
+  npixels = w*h;
+  nRGBbytes = 3*npixels;
+
+  /* make sure image is more-or-less valid (and no overflows) */
+  if (isize <= 0 || w <= 0 || h <= 0 || npixels/w < h ||
+      nRGBbytes/3 < npixels || thePic.pm_cmtsize < 0)
+    return pmError(bname, "Bogus PM file!!");
 
-  if (DEBUG) 
+  if (DEBUG)
     fprintf(stderr,"%s: LoadPM() - loading a %dx%d %s pic, %d planes\n",
-	    cmd, w, h, (thePic.pm_form==PM_I) ? "PM_I" : "PM_C", 
+	    cmd, w, h, (thePic.pm_form==PM_I) ? "PM_I" : "PM_C",
 	    thePic.pm_np);
 
-	      
+
   /* allocate memory for picture and read it in */
   thePic.pm_image = (char *) malloc((size_t) isize);
-  if (thePic.pm_image == NULL) 
+  if (thePic.pm_image == NULL)
     return( pmError(bname, "unable to malloc PM picture") );
 
   if (fread(thePic.pm_image, (size_t) isize, (size_t) 1, fp) != 1)   {
@@ -147,7 +155,7 @@
       }
     }
   }
-   
+
   fclose(fp);
 
 
@@ -155,11 +163,11 @@
     int  *intptr;
     byte *pic24, *picptr;
 
-    if ((pic24 = (byte *) malloc((size_t) w*h*3))==NULL) {
+    if ((pic24 = (byte *) malloc((size_t) nRGBbytes))==NULL) {
       if (thePic.pm_cmt) free(thePic.pm_cmt);
       return( pmError(bname, "unable to malloc 24-bit picture") );
     }
-      
+
     intptr = (int *) thePic.pm_image;
     picptr = pic24;
 
@@ -190,7 +198,7 @@
   else if (thePic.pm_form == PM_C && thePic.pm_np>1) {
     byte *pic24, *picptr, *rptr, *gptr, *bptr;
 
-    if ((pic24 = (byte *) malloc((size_t) w*h*3))==NULL) {
+    if ((pic24 = (byte *) malloc((size_t) nRGBbytes))==NULL) {
       if (thePic.pm_cmt) free(thePic.pm_cmt);
       return( pmError(bname, "unable to malloc 24-bit picture") );
     }
@@ -210,12 +218,12 @@
     pinfo->pic  = pic24;
     pinfo->type = PIC24;
   }
-  
+
 
   else if (thePic.pm_form == PM_C && thePic.pm_np==1) {
     /* don't have to convert, just point pic at thePic.pm_image */
     pic8 = (byte *) thePic.pm_image;
-    for (i=0; i<256; i++) 
+    for (i=0; i<256; i++)
       pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;  /* build mono cmap */
 
     pinfo->pic  = pic8;
@@ -228,13 +236,13 @@
   pinfo->normw = pinfo->w;   pinfo->normh = pinfo->h;
 
   pinfo->frmType = F_PM;
-  pinfo->colType = (thePic.pm_form==PM_I || thePic.pm_np>1) 
+  pinfo->colType = (thePic.pm_form==PM_I || thePic.pm_np>1)
                          ? F_FULLCOLOR : F_GREYSCALE;
-  sprintf(pinfo->fullInfo,"PM, %s.  (%d plane %s)  (%ld bytes)",
-	  (thePic.pm_form==PM_I || thePic.pm_np>1) 
+  sprintf(pinfo->fullInfo,"PM, %s.  (%d plane %s)  (%d bytes)",
+	  (thePic.pm_form==PM_I || thePic.pm_np>1)
 	        ? "24-bit color" : "8-bit greyscale",
 	  thePic.pm_np, (thePic.pm_form==PM_I) ? "PM_I" : "PM_C",
-	  isize + PM_IOHDR_SIZE + thePic.pm_cmtsize);
+	  isize + (int)PM_IOHDR_SIZE + thePic.pm_cmtsize);
 
   sprintf(pinfo->shrtInfo, "%dx%d PM.", w,h);
   pinfo->comment = thePic.pm_cmt;
@@ -313,7 +321,7 @@
 
   else if (colorstyle == 1) {    /* GreyScale: 8 bits per pixel */
     byte rgb[256];
-    
+
     if (ptype == PIC8) {
       for (i=0; i<numcols; i++) rgb[i] = MONO(rmap[i],gmap[i],bmap[i]);
       for (i=0, p=pic; i<w*h; i++, p++) {
@@ -351,7 +359,7 @@
 
 /*****************************/
 static int pmError(fname, st)
-     char *fname, *st;
+     const char *fname, *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", fname, st);
   if (thePic.pm_image != NULL) free(thePic.pm_image);
diff -ru xv-3.10a/xvpopup.c xv-3.10a-enhancements/xvpopup.c
--- xv-3.10a/xvpopup.c	1995-01-19 10:09:31.000000000 -0800
+++ xv-3.10a-enhancements/xvpopup.c	2007-04-15 15:02:32.000000000 -0700
@@ -1,5 +1,5 @@
-/* 
- * xvpopup.c - popup "Are you sure?  Yes/No/Maybe" sort of dialog box
+/*
+ * xvpopup.c - pop up "Are you sure?  Yes/No/Maybe" sort of dialog box
  *
  * callable functions:
  *
@@ -13,16 +13,16 @@
  *   OpenAlert(str)        -  maps a button-less window
  *   CloseAlert()          -  closes a button-less window
  *   PUCheckEvent(event)   -  called by event handler
- *   TextRect()            -  draws semi-complex strings in a rectangle
  */
 
 #include "copyright.h"
 
 #include "xv.h"
 
-#include "bits/icon"
+#define OMIT_ICON_BITS
+#include "bits/icon"   /* icon_bits[] not used, but icon_width/height are */
 
-#define PUWIDE 400
+#define PUWIDE 480
 #define PUHIGH 170
 
 #define PAD_PUWIDE 480
@@ -30,8 +30,9 @@
 
 #define BUTTH   24
 
-static int  doPopUp       PARM((char *, char **, int, int, char *));
+static int  doPopUp       PARM((const char *, const char **, int, int, const char *));
 static void attachPUD     PARM((void));
+static void TextRect      PARM((Window, const char *, int, int, int, int, u_long));
 static void createPUD     PARM((void));
 static void drawPUD       PARM((int, int, int, int));
 static void drawPadOMStr  PARM((void));
@@ -41,8 +42,8 @@
 static void changedGSBuf  PARM((void));
 static void drawGSBuf     PARM((void));
 static void buildPadLists PARM((void));
-static void build1PadList PARM((char *, char **, char **, int *,
-				char **, char **, int));
+static void build1PadList PARM((const char *, const char **, const char **, int *,
+				const char **, const char **, int));
 
 
 /* values 'popUp' can take */
@@ -57,20 +58,21 @@
 #define HIDESTR  "Hide XV windows"
 
 /* local variables */
-Window popW;
-int    nbts, selected, popUp=0, firsttime=1;
-int    puwide = PUWIDE;
-int    puhigh = PUHIGH;
-BUTT  *bts;
-char  *text;
-char   accel[8];
-
-char *gsBuf, *gsFilter;       /* stuff needed for GetStrPopUp() handling */
-int   gsBufLen, gsAllow, gsCurPos, gsStPos, gsEnPos;
-int   gsx, gsy, gsw, gsh;
+static Window      popW;
+static int         nbts, selected, popUp=0, firsttime=1;
+static int         puwide = PUWIDE;
+static int         puhigh = PUHIGH;
+static BUTT       *bts;
+static const char *text;
+static char        accel[8];
+
+static char       *gsBuf;       /* stuff needed for GetStrPopUp() handling */
+static const char *gsFilter;
+static int         gsBufLen, gsAllow, gsCurPos, gsStPos, gsEnPos;
+static int         gsx, gsy, gsw, gsh;
 
 /* stuff for GrabPopUp */
-CBUTT ahideCB;
+static CBUTT ahideCB;
 
 
 /*** stuff for PadPopUp ***/
@@ -82,48 +84,51 @@
 static int    padMode, padOMode;
 static DIAL   padWDial, padHDial, padODial;
 
-static int    padMthdLen=3;
-static char  *padMthdNames[] = { "Solid Fill", "Run 'bggen'", "Load Image" };
+static int         padMthdLen=3;
+static const char *padMthdNames[] = { "Solid Fill", "Run 'bggen'", "Load Image" };
 
-static int    padColDefLen = 9;
-static char  *padColDefNames[] = { "black", "red",  "yellow", "green", 
-				   "cyan",  "blue", "magenta", "white", 
-				   "50% gray" };
-
-static char  *padColDefVals[]  = { "black", "red", "yellow", "green",
-				   "cyan",  "blue", "magenta", "white",
-                                   "gray50" };
-
-static int    padBgDefLen = 8;
-static char  *padBgDefNames[] = {
-  "Black->White",
-  "Blue Gradient",
-  "RGB Rainbow",
-  "Full Rainbow",
-  "Color Assortment",
-  "Green Tiles",
-  "Red Balls",
-  "Red+Yellow Diamonds" };
-
-static char  *padBgDefVals[]  = { 
-  "black white", 
-  "100 100 255  50 50 150",
-  "red green blue",
-  "black red yellow green blue purple black",
-  "black white red black yellow white green black cyan white blue black magenta white red yellow green cyan blue magenta red",
-  "green black -r 30 -G 32x32",
-  "red black -r 45 -G 32x32",
-  "red yellow -r 45 -G 32x32" };
+static int         padColDefLen = 9;
+static const char *padColDefNames[] = { "black", "red",  "yellow", "green",
+					"cyan",  "blue", "magenta", "white",
+					"50% gray" };
+
+static const char *padColDefVals[]  = { "black", "red", "yellow", "green",
+					"cyan",  "blue", "magenta", "white",
+					"gray50" };
+
+static int         padBgDefLen = 8;
+static const char *padBgDefNames[] = { "Black->White",
+				       "Blue Gradient",
+				       "RGB Rainbow",
+				       "Full Rainbow",
+				       "Color Assortment",
+				       "Green Tiles",
+				       "Red Balls",
+				       "Red+Yellow Diamonds" };
+
+static const char *padBgDefVals[] = { "black white",
+				      "100 100 255  50 50 150",
+				      "red green blue",
+				      "black red yellow green blue purple black",
+				      "black white red black yellow white green black cyan white blue black magenta white red yellow green cyan blue magenta red",
+				      "green black -r 30 -G 32x32",
+				      "red black -r 45 -G 32x32",
+				      "red yellow -r 45 -G 32x32" };
 
 
 /* this should match with PAD_O* defs in xv.h */
-static char *padOMStr[] = { "RGB", "Int.", "Hue", "Sat." };
+static const char *padOMStr[] = { "RGB", "Int.", "Hue", "Sat." };
 
 #define PAD_MAXDEFLEN 10
-static int    padColLen = 0, padBgLen = 0, padLoadLen = 0;
-static char  *padColNames [PAD_MAXDEFLEN], *padColVals [PAD_MAXDEFLEN];
-static char  *padBgNames  [PAD_MAXDEFLEN], *padBgVals  [PAD_MAXDEFLEN];
-static char  *padLoadNames[PAD_MAXDEFLEN], *padLoadVals[PAD_MAXDEFLEN];
+static int         padColLen = 0;
+static const char *padColNames [PAD_MAXDEFLEN];
+static const char *padColVals  [PAD_MAXDEFLEN];
+static int         padBgLen = 0;
+static const char *padBgNames  [PAD_MAXDEFLEN];
+static const char *padBgVals   [PAD_MAXDEFLEN];
+static int         padLoadLen = 0;
+static const char *padLoadNames[PAD_MAXDEFLEN];
+static const char *padLoadVals [PAD_MAXDEFLEN];
 
 
 /***************************************************/
@@ -150,11 +155,11 @@
     if (wy + h > dispHIGH) wy = dispHIGH - h;
   }
 
-  
+
   if (winCtrPosKludge) {
     wx -= (p_offx + ch_offx);
     wy -= (p_offy + ch_offy);
-  } 
+  }
   else {
     wx -= (ch_offx);
     wy -= (ch_offy);
@@ -174,16 +179,20 @@
 
 /***************************************************/
 int PopUp(txt, labels, n)
-     char *txt, *labels[];
-     int   n;
+     const char *txt;
+     const char *labels[];
+     int         n;
 {
   return doPopUp(txt, labels, n, ISPOPUP, "xv confirm");
 }
 
+
 /***************************************************/
 static int doPopUp(txt, labels, n, poptyp, wname)
-     char *txt, *labels[], *wname;
-     int   n, poptyp;
+     const char *txt;
+     const char *labels[];
+     int         n, poptyp;
+     const char *wname;
 {
   int    i;
   XEvent event;
@@ -197,17 +206,17 @@
   /* attach controls to popW, now that it exists */
   if      (poptyp==ISGRAB) ahideCB.win = popW;
   else if (poptyp == ISPAD) {
-    
+
     if (!padHaveDooDads) {
       DCreate(&padWDial, popW, 16,      puhigh-16-100-1,75,100,
-	      1, 2048, pWIDE, 10,
+	      1.0, 2048.0, (double)pWIDE, 1.0, 10.0,
 	      infofg, infobg, hicol, locol, "Width", NULL);
       DCreate(&padHDial, popW, 16+1+75, puhigh-16-100-1,75,100,
-	      1, 2048, pHIGH, 10,
+	      1.0, 2048.0, (double)pHIGH, 1.0, 10.0,
 	      infofg, infobg, hicol, locol, "Height", NULL);
 
       DCreate(&padODial, popW, 16+1+75+75+9, puhigh-16-100-1,75,100,
-	      0, 100, 100, 10,
+	      0.0, 100.0, 100.0, 1.0, 10.0,
 	      infofg, infobg, hicol, locol, "Opaque", NULL);
 
       MBCreate(&padMthdMB, popW, 100-2+44, 10, 140, 19, NULL,
@@ -230,8 +239,8 @@
     XMapWindow(theDisp, padWDial.win);
     XMapWindow(theDisp, padHDial.win);
     XMapWindow(theDisp, padODial.win);
-  }      
-  
+  }
+
 
   XResizeWindow(theDisp, popW, (u_int) puwide, (u_int) puhigh);
   XStoreName   (theDisp, popW, wname);
@@ -257,10 +266,10 @@
   }
   else if (poptyp == ISPAD) {
     BTSetActive(&bts[0], (int) strlen(gsBuf));
-    i = pWIDE * 3;  RANGE(i,2048,9999);  
-    DSetRange(&padWDial, 1, i, padWDial.val, 10);
-    i = pHIGH * 3;  RANGE(i,2048,9999);  
-    DSetRange(&padHDial, 1, i, padHDial.val, 10);
+    i = pWIDE * 3;  RANGE(i,2048,9999);
+    DSetRange(&padWDial, 1.0, (double)i, padWDial.val, 1.0, 10.0);
+    i = pHIGH * 3;  RANGE(i,2048,9999);
+    DSetRange(&padHDial, 1.0, (double)i, padHDial.val, 1.0, 10.0);
 
     DSetActive(&padWDial, (padMode!=PAD_LOAD));  /* DSetRange activates dial */
     DSetActive(&padHDial, (padMode!=PAD_LOAD));
@@ -283,18 +292,22 @@
     }
   }
 
-  /* center first button in window around mouse position, with constraint that 
+  /* center first button in window around mouse position, with constraint that
      window be fully on the screen */
 
-  CenterMapWindow(popW, 40 + bts[0].x, BUTTH/2 + bts[0].y, puwide, puhigh);
   popUp = poptyp;
+  if (startGrab == 2)
+    startGrab = 4;
+  else {
+    CenterMapWindow(popW, 40 + bts[0].x, BUTTH/2 + bts[0].y, puwide, puhigh);
 
-  /* MUST wait for VisibilityNotify event to come in, else we run the risk
-     of UnMapping the window *before* the Map request completed.  This 
-     appears to be bad, (It leaves an empty window frame up.) though it
-     generally only happens on slow servers.  Better safe than screwed... */
+    /* MUST wait for VisibilityNotify event to come in, else we run the risk
+       of UnMapping the window *before* the Map request completed.  This
+       appears to be bad, (It leaves an empty window frame up.) though it
+       generally only happens on slow servers.  Better safe than screwed... */
 
-  XWindowEvent(theDisp, popW, VisibilityChangeMask, &event);
+    XWindowEvent(theDisp, popW, VisibilityChangeMask, &event);
+  }
 
   /* block until this window gets closed */
   while (popUp) {
@@ -312,7 +325,8 @@
 
 /***************************************************/
 void ErrPopUp(txt, label)
-     char *txt, *label;
+     const char *txt;
+     const char *label;
 {
   /* simplified interface to PopUp.  Takes a string and the label for the
      (one) button */
@@ -323,7 +337,10 @@
 
 /***************************************************/
 int GetStrPopUp(txt, labels, n, buf, buflen, filstr, allow)
-     char *txt, *labels[], *buf, *filstr;
+     const char *txt;
+     const char *labels[];
+     char *buf;
+     const char *filstr;
      int   n, buflen, allow;
 {
   /* pops up a window with a prompt string, a 1-line editable
@@ -338,10 +355,10 @@
      button labels have 1-character accellerators at the front, same
      as in PopUp().  Note that it would be suboptimal to make any
      of the 1-character accellerators be the same character as one of
-     the edit-text command keys 
+     the edit-text command keys
 
      Also note that the filter string should only contain normal printable
-     characters (' ' through '\177'), as ctrl chars are pre-filtered 
+     characters (' ' through '\177'), as ctrl chars are pre-filtered
      (ie, interpreted as emacs-like commands) */
 
   gsBuf = buf;        gsBufLen = buflen;
@@ -358,7 +375,7 @@
     gsy = PUHIGH - 10 - BUTTH - 10 - gsh - 20;
 
   gsw = PUWIDE - gsx - 10;
-  
+
   changedGSBuf();      /* careful!  popW doesn't exist yet! */
 
   return doPopUp(txt, labels, n, ISGETSTR, "xv prompt");
@@ -371,9 +388,9 @@
 {
   /* pops up Grab options dialog box */
 
-  int  rv;
-  char delaybuf[32], grabTxt[1024];
-  static char *grabLabels[] = { "\nGrab", "aAutoGrab", "\033Cancel" };
+  int                rv;
+  char               delaybuf[32], grabTxt[1024];
+  static const char *grabLabels[] = { "\nGrab", "aAutoGrab", "\033Cancel" };
 
   sprintf(delaybuf,"%d", *pDelay);
   gsBuf = delaybuf;          gsBufLen = 3;
@@ -390,7 +407,7 @@
   changedGSBuf();      /* careful!  popW doesn't exist yet! */
 
   /* window value gets filled in in doPopUp() */
-  CBCreate(&ahideCB, (Window) NULL, 
+  CBCreate(&ahideCB, (Window) NULL,
 	   PUWIDE-10-18-StringWidth(HIDESTR),
 	   gsy+2, HIDESTR, infofg, infobg, hicol, locol);
   ahideCB.val = *pHide;
@@ -417,9 +434,9 @@
 {
   /* pops up 'Pad' options dialog box */
 
-  int         rv, oldW, oldH, oldO;
-  static int  firsttime=1;
-  static char *labels[] = { "\nOk", "\033Cancel" };
+  int                rv, oldW, oldH, oldO;
+  static int         firsttime=1;
+  static const char *labels[] = { "\nOk", "\033Cancel" };
 
   if (firsttime) {
     padSbuf[0] = '\0';
@@ -464,10 +481,10 @@
 
   changedGSBuf();      /* careful!  popW doesn't exist yet! */
 
-  if (padHaveDooDads) { 
-    oldW = padWDial.val;  
-    oldH = padHDial.val;
-    oldO = padODial.val;
+  if (padHaveDooDads) {
+    oldW = (int)padWDial.val;
+    oldH = (int)padHDial.val;
+    oldO = (int)padODial.val;
   }
   else { oldW = pWIDE;  oldH = pHIGH;  oldO = 100; }
 
@@ -486,9 +503,9 @@
   }
 
   if (rv == 1) {   /* cancelled:  restore normal values */
-    DSetVal(&padWDial, oldW);
-    DSetVal(&padHDial, oldH);
-    DSetVal(&padODial, oldO);
+    DSetVal(&padWDial, (double)oldW);
+    DSetVal(&padHDial, (double)oldH);
+    DSetVal(&padODial, (double)oldO);
   }
 
   XUnmapWindow(theDisp, padWDial.win);
@@ -496,11 +513,11 @@
   XUnmapWindow(theDisp, padODial.win);
 
   /* load up return values */
-  *pMode   = padMode;  
-  *pStr    = padBuf;  
-  *pWide   = padWDial.val;
-  *pHigh   = padHDial.val;
-  *pOpaque = padODial.val;
+  *pMode   = padMode;
+  *pStr    = padBuf;
+  *pWide   = (int)padWDial.val;
+  *pHigh   = (int)padHDial.val;
+  *pOpaque = (int)padODial.val;
   *pOmode  = padOMode;
 
   return rv;
@@ -513,8 +530,6 @@
   /* generates padCol* and padBg* lists used in 'Defaults' MBUTT.  Grabs
      all the X resources values it can, and adds appropriate defaults */
 
-  int  i;
-
   rd_str_cl("foo", "", 1);                    /* rebuild database */
 
   build1PadList("color", padColVals, padColNames, &padColLen,
@@ -524,49 +539,52 @@
 		padBgDefVals, padBgDefNames, padBgDefLen);
 
   build1PadList("load", padLoadVals, padLoadNames, &padLoadLen,
-		(char **) NULL, (char **) NULL, 0);
+		(const char **) NULL, (const char **) NULL, 0);
 }
-	
-      
+
+
 /***************************************************/
 static void build1PadList(typstr, vals, nams, lenp, dvals, dnams, dlen)
-     char *typstr, **vals, **nams, **dvals, **dnams;
-     int  *lenp, dlen;
-{
-  int i;
-  char resname[128], name[256], value[256];
+     const char  *typstr;
+     const char **vals, **nams;
+     const char **dvals, **dnams;
+     int         *lenp, dlen;
+{
+  int   i;
+  char  resname[128];
+  char *copy;
 
   for (i=0; i<*lenp; i++) {   /* kill old lists */
-    free(nams[i]);
-    free(vals[i]);
+    free((char *) nams[i]);
+    free((char *) vals[i]);
   }
   *lenp = 0;
 
   for (i=0; i<10; i++) {
     sprintf(resname, "pad.%s.val%d", typstr, i);
     if (rd_str_cl(resname, "Dialog.Menu.Slot",0)) {    /* got one! */
-      vals[*lenp] = (char *) malloc(strlen(def_str)+1);
-      if (!vals[*lenp]) continue;
-      strcpy(vals[*lenp], def_str);
-      
+      copy = strdup(def_str);
+      if (!copy) continue;
+      vals[*lenp] = copy;
+
       sprintf(resname, "pad.%s.name%d", typstr, i);
       if (rd_str_cl(resname, "Dialog.Menu.Slot",0)) {  /* and it has a name! */
-	nams[*lenp] = (char *) malloc(strlen(def_str)+1);
-	if (!nams[*lenp]) { free(vals[*lenp]); continue; }
-	strcpy(nams[*lenp], def_str);
-
+        copy = strdup(def_str);
+	if (!copy) { free((char *) vals[*lenp]); continue; }
       }
       else {  /* it doesn't have a name.  fabricate one */
-	nams[*lenp] = (char *) malloc((size_t) 32);
-	if (!nams[*lenp]) { free(vals[*lenp]); continue; }
-	strncpy(nams[*lenp], vals[*lenp], (size_t) 31);
+	copy = malloc((size_t) 32);
+	if (!copy) { free((char *) vals[*lenp]); continue; }
+	strncpy(copy, vals[*lenp], (size_t) 31);
+	copy[31] = '\0';
       }
-      
-      if (strlen(nams[*lenp]) > (size_t) 20) {   /* fix long names */
-	char *sp = nams[*lenp] + 18;
+      if (strlen(copy) > (size_t) 20) {   /* fix long names */
+	char *sp = copy + 18;
+
 	*sp++ = '.';  *sp++ = '.';  *sp++ = '.';  *sp++ = '\0';
       }
-	
+      nams[*lenp] = copy;
+
       *lenp = (*lenp) + 1;
     }
   }
@@ -574,16 +592,17 @@
 
   /* add 'built-in' defaults to the lists */
   for (i=0; i<dlen && *lenp<PAD_MAXDEFLEN; i++) {
-    vals[*lenp] = (char *) malloc(strlen(dvals[i])+1);
-    if (!vals[*lenp]) break;
-    strcpy(vals[*lenp], dvals[i]);
-
-    nams[*lenp] = (char *) malloc(strlen(dnams[i])+1);
-    if (!nams[*lenp]) { free(vals[*lenp]); break; }
-    strcpy(nams[*lenp], dnams[i]);
+    copy = strdup(dvals[i]);
+    if (!copy) break;
+    vals[*lenp] = copy;
+
+    copy = strdup(dnams[i]);
+    if (!copy) { free((char *) vals[*lenp]); break; }
+    nams[*lenp] = copy;
+
     *lenp = (*lenp) + 1;
   }
-}    
+}
 
 
 
@@ -603,9 +622,9 @@
 
 /***************************************************/
 void OpenAlert(txt)
-     char *txt;
+     const char *txt;
 {
-  /* pops up a window with txt displayed in it (*no buttons*).  
+  /* pops up a window with txt displayed in it (*no buttons*).
      returns immediately.  window is closed by 'CloseAlert()'.
      No 'PopUp()' calls are allowed while an Alert is displayed. */
 
@@ -624,14 +643,14 @@
   puwide = PUWIDE;  puhigh = PUHIGH;
   XResizeWindow(theDisp, popW, (u_int) puwide, (u_int) puhigh);
 
-  /* center last button in window around mouse position, with constraint that 
+  /* center last button in window around mouse position, with constraint that
      window be fully on the screen */
 
   CenterMapWindow(popW, puwide/2, puhigh/2, puwide, puhigh);
   popUp = ISALERT;
 
   /* MUST wait for VisibilityNotify event to come in, else we run the risk
-     of UnMapping the window *before* the Map request completed.  This 
+     of UnMapping the window *before* the Map request completed.  This
      appears to be bad, (It leaves an empty window frame up.) though it
      generally only happens on slow servers.  Better safe than screwed... */
 
@@ -695,7 +714,7 @@
     XKeyEvent *e = (XKeyEvent *) xev;
     char buf[128];  KeySym ks;
     int stlen, i, shift, ck;
-	
+
     stlen = XLookupString(e,buf,128,&ks,(XComposeStatus *) NULL);
     shift = e->state & ShiftMask;
     ck = CursorKey(ks, shift, 0);
@@ -725,7 +744,7 @@
 	rv = 1;
       }
 
-      if (!rv && (popUp==ISGETSTR || popUp==ISGRAB || popUp==ISPAD)) { 
+      if (!rv && (popUp==ISGETSTR || popUp==ISGRAB || popUp==ISPAD)) {
 	if (e->window == popW) { doGetStrKey(buf[0]);  rv = 1; }
       }
     }
@@ -765,26 +784,31 @@
 #define TR_MAXLN 10
 
 /***************************************************/
-void TextRect(win, txt, x, y, w, h, fg)
-     Window  win;
-     char   *txt;
-     int     x,y,w,h;
-     u_long  fg;
-{
-  char *sp, *ep, *oldep, *start[TR_MAXLN];
-  int   i, inbreak, lineno, top, hardcr, maxln, len[TR_MAXLN];
+static void TextRect(win, txt, x, y, w, h, fg)
+     Window      win;
+     const char *txt;
+     int         x,y,w,h;
+     u_long      fg;
+{
+  /* draws semi-complex strings in a rectangle */
+
+  const char *sp;
+  const char *ep;
+  const char *oldep;
+  const char *start[TR_MAXLN];
+  int         i, inbreak, lineno, top, hardcr, maxln, len[TR_MAXLN];
 
   XSetForeground(theDisp, theGC, fg);
-  
+
   sp = txt;  lineno = hardcr = 0;
 
-  maxln = h / LINEHIGH;  
+  maxln = h / LINEHIGH;
   RANGE(maxln,0,TR_MAXLN);
   while (*sp && lineno<maxln) {
 
     /* drop off any leading spaces (except on first line or after \n) */
     if (sp!=txt && !hardcr) {
-      while(*sp==' ') sp++;
+      while (*sp==' ') sp++;
     }
 
     hardcr = 0;   ep = sp;
@@ -797,7 +821,7 @@
     while (XTextWidth(mfinfo, sp, (int)(ep-sp))<= w && *ep && *ep!='\n') ep++;
     if (*ep=='\n') { ep++;  hardcr=1; }   /* eat newline */
 
-    /* if we got too wide, back off until we find a break position 
+    /* if we got too wide, back off until we find a break position
        (last char before a space or a '/') */
 
     if (XTextWidth(mfinfo, sp, (int)(ep-sp)) > w) {
@@ -812,7 +836,7 @@
     }
 
     start[lineno] = sp;  len[lineno] = ep-sp;
-    
+
     /* make sure we don't print a trailing '\n' character! */
     if (len[lineno] > 0) {
       while (sp[len[lineno]-1] == '\n') len[lineno] = len[lineno] - 1;
@@ -835,7 +859,7 @@
 /***************************************************/
 static void createPUD()
 {
-  popW = CreateWindow("xv confirm", "XVconfirm", "+0+0", 
+  popW = CreateWindow("xv confirm", "XVconfirm", "+0+0",
 		      PUWIDE, PUHIGH, infofg, infobg, 0);
   if (!popW) FatalError("can't create popup window!");
 
@@ -847,7 +871,7 @@
   bts = (BUTT *) NULL;
   nbts = selected = firsttime = 0;
 }
-  
+
 
 /***************************************************/
 static void attachPUD()
@@ -913,24 +937,24 @@
       XDrawLine(theDisp, popW, theGC, 16+1+75+75+5, puhigh-140 + 6+8,
 		16+1+75+75+5, puhigh-10-4);
     }
-      
+
 
     XSetForeground(theDisp, theGC, infofg);
-    XDrawRectangle(theDisp, popW, theGC, 268, puhigh-140, 
+    XDrawRectangle(theDisp, popW, theGC, 268, puhigh-140,
 		   (u_int) puwide - 10 - 268, 130-BUTTH-10);
-    Draw3dRect(popW, 268+1, puhigh-140+1, (u_int) puwide -10-268-2, 
+    Draw3dRect(popW, 268+1, puhigh-140+1, (u_int) puwide -10-268-2,
 	       130-2 - BUTTH-10, R3D_IN,2,hicol,locol,infobg);
-    
-    TextRect(popW,padInst,268+5, puhigh-140+3, puwide-10-268-10, 
+
+    TextRect(popW,padInst,268+5, puhigh-140+3, puwide-10-268-10,
 	     130-6 - BUTTH-10, infofg);
   }
 
   else {
     XCopyPlane(theDisp, iconPix, popW, theGC, 0,0, icon_width, icon_height,
 	       10,10+(puhigh-30-BUTTH-icon_height)/2, 1L);
-    
+
     xt = 10+icon_width+20;  yt = 10;
-    
+
     if (popUp == ISGETSTR) {
       TextRect(popW, text, xt, yt, puwide-10-xt, gsy-20, infofg);
       drawGSBuf();
@@ -947,23 +971,23 @@
 /***************************************************/
 static void drawPadOMStr()
 {
-  CenterString(popW, padODial.x + (padODial.w - 13)/2, 
+  CenterString(popW, padODial.x + (padODial.w - 13)/2,
 	       puhigh-16-100-12, padOMStr[padOMode]);
 }
-  
+
 /***************************************************/
 static void clickPUD(x,y)
      int x,y;
 {
   int i;
-  BUTT *bp;
-  
+  BUTT *bp = NULL;
+
   for (i=0; i<nbts; i++) {
     bp = &bts[i];
     if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
   }
-  
-  if (i<nbts && BTTrack(bp)) {
+
+  if (i<nbts && bp && BTTrack(bp)) {
     popUp = 0;  selected = i;  return;
   }
 
@@ -972,8 +996,8 @@
   else if (popUp == ISPAD) {
     if (PTINRECT(x, y, padDButt.x, padDButt.y, padDButt.w, padDButt.h)) {
       if (BTTrack(&padDButt)) {
-	DSetVal(&padWDial, pWIDE);
-	DSetVal(&padHDial, pHIGH);
+	DSetVal(&padWDial, (double)pWIDE);
+	DSetVal(&padHDial, (double)pHIGH);
       }
     }
 
@@ -1017,11 +1041,11 @@
       gsCurPos = strlen(gsBuf);
       gsStPos = gsEnPos = 0;
       changedGSBuf();
-      if (ctrlColor) 
-	XClearArea(theDisp, popW, gsx+3,gsy+3, 
+      if (ctrlColor)
+	XClearArea(theDisp, popW, gsx+3,gsy+3,
 		   (u_int)gsw-5, (u_int)gsh-5, False);
       else
-	XClearArea(theDisp, popW, gsx+1,gsy+1, 
+	XClearArea(theDisp, popW, gsx+1,gsy+1,
 		   (u_int)gsw-1, (u_int)gsh-1, False);
       drawGSBuf();
 
@@ -1032,7 +1056,7 @@
       DSetActive (&padWDial,  (i!=PAD_LOAD));
       DSetActive (&padHDial,  (i!=PAD_LOAD));
 
-      XClearArea(theDisp, popW, 184+5, puhigh-140+3, 
+      XClearArea(theDisp, popW, 184+5, puhigh-140+3,
 		 (u_int) puwide-10-184-10, 130-6 - BUTTH-10, True);
 
       padMode = i;
@@ -1049,11 +1073,11 @@
       gsCurPos = strlen(gsBuf);
       gsStPos = gsEnPos = 0;
       changedGSBuf();
-      if (ctrlColor) 
-	XClearArea(theDisp, popW, gsx+3,gsy+3, 
+      if (ctrlColor)
+	XClearArea(theDisp, popW, gsx+3,gsy+3,
 		   (u_int)gsw-5, (u_int)gsh-5, False);
       else
-	XClearArea(theDisp, popW, gsx+1,gsy+1, 
+	XClearArea(theDisp, popW, gsx+1,gsy+1,
 		   (u_int)gsw-1, (u_int)gsh-1, False);
       drawGSBuf();
 
@@ -1079,8 +1103,8 @@
   /* handle characters typed at GetStrPopUp window.  Button accel. keys
      have already been checked for elsewhere.  Practical upshot is that
      we don't have to do anything with ESC or Return (as these will normally
-     be Cancel and Ok buttons) 
- 
+     be Cancel and Ok buttons)
+
      Normally returns '0'.  Returns '1' if character wasn't accepted, for
      whatever reason. */
 
@@ -1089,7 +1113,7 @@
   len = strlen(gsBuf);
   if (gsFilter) flen = strlen(gsFilter);
            else flen = 0;
-  
+
 
   if (c>=' ' && c<'\177') {              /* 'NORMAL' CHARACTERS */
     if (flen) {                          /* check filter string */
@@ -1097,7 +1121,7 @@
       if (!gsAllow && i< flen) return 1;    /* found in 'disallow' filter */
       if ( gsAllow && i==flen) return 1;    /* not found in 'allow' filter */
     }
-    
+
     if (len >= gsBufLen-1) return 1;     /* at max length */
 
     xvbcopy(&gsBuf[gsCurPos], &gsBuf[gsCurPos+1], (size_t) len-gsCurPos+1);
@@ -1105,7 +1129,7 @@
   }
 
 
-  else if (c=='\010' || c=='\177') {    /* BS or DEL */
+  else if (c=='\010') {                 /* BS */
     if (gsCurPos==0) return 1;                     /* at beginning of str */
     xvbcopy(&gsBuf[gsCurPos], &gsBuf[gsCurPos-1], (size_t) len-gsCurPos+1);
     gsCurPos--;
@@ -1128,7 +1152,7 @@
     gsCurPos = len;
   }
 
-  else if (c=='\004') {                 /* ^D: delete character at gsCurPos */
+  else if (c=='\004' || c=='\177') {    /* ^D or DEL: delete character at gsCurPos */
     if (gsCurPos==len) return 1;
     xvbcopy(&gsBuf[gsCurPos+1], &gsBuf[gsCurPos], (size_t) len-gsCurPos);
   }
@@ -1147,7 +1171,7 @@
 
   changedGSBuf();      /* compute gsEnPos, gsStPos */
 
-  if (ctrlColor) 
+  if (ctrlColor)
     XClearArea(theDisp, popW, gsx+3,gsy+3, (u_int)gsw-5, (u_int)gsh-5, False);
   else
     XClearArea(theDisp, popW, gsx+1,gsy+1, (u_int)gsw-1, (u_int)gsh-1, False);
@@ -1175,7 +1199,7 @@
 /***************************************************/
 static void changedGSBuf()
 {
-  /* cursor position (or whatever) may have changed.  adjust displayed 
+  /* cursor position (or whatever) may have changed.  adjust displayed
      portion of gsBuf */
 
   int len;
@@ -1212,7 +1236,7 @@
 
   XSetForeground(theDisp, theGC, infofg);
   XDrawRectangle(theDisp, popW, theGC, gsx, gsy, (u_int) gsw, (u_int) gsh);
-  Draw3dRect(popW, gsx+1, gsy+1, (u_int) gsw-2, (u_int) gsh-2, 
+  Draw3dRect(popW, gsx+1, gsy+1, (u_int) gsw-2, (u_int) gsh-2,
 	     R3D_IN, 2, hicol,locol,infobg);
 
   XSetForeground(theDisp, theGC, infofg);
diff -ru xv-3.10a/xvps.c xv-3.10a-enhancements/xvps.c
--- xv-3.10a/xvps.c	1994-12-22 14:34:42.000000000 -0800
+++ xv-3.10a-enhancements/xvps.c	2007-05-12 15:25:59.000000000 -0700
@@ -1,4 +1,4 @@
-/* 
+/*
  * xvps.c - Postscript dialog box, file output functions
  *
  * callable functions:
@@ -71,10 +71,13 @@
 static void psColorImage   PARM((FILE *));
 static void psColorMap     PARM((FILE *fp, int, int, byte *, byte *, byte *));
 static void psRleCmapImage PARM((FILE *, int));
-static void epsPreview     PARM((FILE *, byte *, int, int, int, int, 
+static void epsPreview     PARM((FILE *, byte *, int, int, int, int,
 				 byte *, byte *, byte *, int));
-static int  writeBWStip    PARM((FILE *, byte *, char *, int, int, int));
+static int  writeBWStip    PARM((FILE *, byte *, const char *, int, int, int));
 
+#ifdef GS_PATH
+static void buildCmdStr    PARM((char *, char *, char *, int, int));
+#endif
 
 
 /* local variables */
@@ -123,7 +126,7 @@
 void CreatePSD(geom)
 char *geom;
 {
-  psW = CreateWindow("xv postscript", "XVps", geom, 
+  psW = CreateWindow("xv postscript", "XVps", geom,
 		     PSWIDE, PSHIGH, infofg, infobg, 0);
   if (!psW) FatalError("can't create postscript window!");
 
@@ -139,9 +142,9 @@
   CBCreate(&encapsCB, psW, 240, 7, "preview", infofg, infobg, hicol, locol);
   CBCreate(&pscompCB, psW, 331, 7, "compress", infofg, infobg, hicol, locol);
 
-  DCreate(&xsDial, psW, 240, 30, 80, 100, 10, 800, 100, 5, 
+  DCreate(&xsDial, psW, 240, 30, 80, 100, 10.0, 800.0, 100.0, 0.5, 5.0,
 	  infofg, infobg, hicol, locol, "Width", "%");
-  DCreate(&ysDial, psW, 331, 30, 80, 100, 10, 800, 100, 5, 
+  DCreate(&ysDial, psW, 331, 30, 80, 100, 10.0, 800.0, 100.0, 0.5, 5.0,
 	  infofg, infobg, hicol, locol, "Height", "%");
   xsDial.drawobj = changedScale;
   ysDial.drawobj = changedScale;
@@ -154,38 +157,38 @@
   RBCreate(orientRB, psW, 36+80, 240+18, "Landscape", infofg, infobg,
 	   hicol, locol);
 
-  paperRB = RBCreate(NULL, psW,36, 240+18+36, "8.5\"x11\"", 
+  paperRB = RBCreate(NULL, psW,36, 240+18+36, "8.5\"x11\"",
 		     infofg, infobg, hicol, locol);
   RBCreate(paperRB, psW, 36+80,    240+18+36, "A4",
 	   infofg, infobg, hicol, locol);
-  RBCreate(paperRB, psW, 36+122,   240+18+36, "B5",         
+  RBCreate(paperRB, psW, 36+122,   240+18+36, "B5",
 	   infofg, infobg, hicol, locol);
-  RBCreate(paperRB, psW, 36+164,   240+18+36, "A3",         
+  RBCreate(paperRB, psW, 36+164,   240+18+36, "A3",
 	   infofg, infobg, hicol, locol);
   RBCreate(paperRB, psW, 36,       240+36+36, "8.5\"x14\"",
 	   infofg, infobg, hicol, locol);
-  RBCreate(paperRB, psW, 36+80,    240+36+36, "11\"x17\"",  
+  RBCreate(paperRB, psW, 36+80,    240+36+36, "11\"x17\"",
 	   infofg, infobg, hicol, locol);
-  RBCreate(paperRB, psW, 36,       240+54+36, "4\"x5\"",    
+  RBCreate(paperRB, psW, 36,       240+54+36, "4\"x5\"",
 	   infofg, infobg, hicol, locol);
-  RBCreate(paperRB, psW, 36+80,    240+54+36, "35mm slide", 
+  RBCreate(paperRB, psW, 36+80,    240+54+36, "35mm slide",
 	   infofg, infobg, hicol, locol);
 
-  BTCreate(&psbut[PS_BOK], psW, PSWIDE-180, PSHIGH-10-BUTTH, 80, BUTTH, 
+  BTCreate(&psbut[PS_BOK], psW, PSWIDE-180, PSHIGH-10-BUTTH, 80, BUTTH,
 	   "Ok", infofg, infobg, hicol, locol);
-  BTCreate(&psbut[PS_BCANC], psW, PSWIDE-90, PSHIGH-10-BUTTH, 80, BUTTH, 
+  BTCreate(&psbut[PS_BCANC], psW, PSWIDE-90, PSHIGH-10-BUTTH, 80, BUTTH,
 	   "Cancel", infofg, infobg, hicol, locol);
 
-  BTCreate(&psbut[PS_BCENT], psW, 240, 154, 55, BUTTH-2, 
+  BTCreate(&psbut[PS_BCENT], psW, 240, 154, 55, BUTTH-2,
 	   "Center", infofg, infobg, hicol, locol);
-  BTCreate(&psbut[PS_BORG], psW,  298, 154, 55, BUTTH-2, 
+  BTCreate(&psbut[PS_BORG], psW,  298, 154, 55, BUTTH-2,
 	   "Origin", infofg, infobg, hicol, locol);
-  BTCreate(&psbut[PS_BMAX], psW,  356, 154, 55, BUTTH-2, 
+  BTCreate(&psbut[PS_BMAX], psW,  356, 154, 55, BUTTH-2,
 	   "Max",    infofg, infobg, hicol, locol);
 
-  BTCreate(&psbut[PS_BPOSX], psW, 256-14, 190+13-8, 8,8, "", 
+  BTCreate(&psbut[PS_BPOSX], psW, 256-14, 190+13-8, 8,8, "",
 	   infofg, infobg, hicol, locol);
-  BTCreate(&psbut[PS_BPOSY], psW, 256-14, 190+26-8, 8,8, "", 
+  BTCreate(&psbut[PS_BPOSY], psW, 256-14, 190+26-8, 8,8, "",
 	   infofg, infobg, hicol, locol);
 
   posxType = posyType = 0;
@@ -236,17 +239,17 @@
 
   if (rd_int("psres")) {             /* xv.psres:  default paper resolution */
     if (def_int >= 10 && def_int <= 720) {
-      int i = (int) ((PIX2INCH * 100) / def_int);
+      double v = (PIX2INCH * 100) / def_int;
 
-      DSetVal(&xsDial, i);
-      DSetVal(&ysDial, i);
+      DSetVal(&xsDial, v);
+      DSetVal(&ysDial, v);
     }
   }
 
 
   XMapSubwindows(theDisp, psW);
 }
-  
+
 
 /***************************************************/
 void PSDialog(vis)
@@ -289,7 +292,7 @@
     x = e->x;  y = e->y;  w = e->width;  h = e->height;
 
     /* throw away excess expose events for 'dumb' windows */
-    if (e->count > 0 && 
+    if (e->count > 0 &&
 	(e->window == xsDial.win || e->window == ysDial.win ||
 	 e->window == pageF)) {}
 
@@ -332,7 +335,7 @@
     XKeyEvent *e = (XKeyEvent *) xev;
     char buf[128];  KeySym ks;
     int  stlen, shift, ck;
-	
+
     stlen = XLookupString(e,buf,128,&ks,(XComposeStatus *) NULL);
     shift = e->state & ShiftMask;
     ck    = CursorKey(ks, shift, 0);
@@ -403,7 +406,7 @@
 static void drawPSD(x,y,w,h)
 int x,y,w,h;
 {
-  char *title = "Save PostScript File...";
+  const char *title = "Save PostScript File...";
   int  i,cx;
   XRectangle xr;
 
@@ -463,12 +466,14 @@
 /***************************************************/
 static void drawPosStr()
 {
-  int x,y;
-  double cmx, cmy, inx, iny;
-  char   str[64], str1[64], *xst, *yst;
+  int         x,y;
+  double      cmx, cmy, inx, iny;
+  char        str[64], str1[64];
+  const char *xst, *yst;
 
   x = 256;  y = 190 + 13;
-  inx = iny = 0;  xst = yst = (char *) NULL;
+  inx = iny = 0;
+  xst = yst = (const char *) NULL;
 
   switch (posxType) {
   case 0:  xst = "Left: ";  inx = pos_inx;                      break;
@@ -497,7 +502,7 @@
   XSetFont(theDisp, theGC, mfont);
 }
 
-  
+
 /***************************************************/
 static void drawSizeStr()
 {
@@ -522,7 +527,7 @@
   XSetFont(theDisp, theGC, mfont);
 }
 
-  
+
 /***************************************************/
 static void drawResStr()
 {
@@ -540,9 +545,9 @@
   XSetFont(theDisp, theGC, mfont);
 }
 
-  
-  
-  
+
+
+
 /***************************************************/
 static void drawPage()
 {
@@ -554,7 +559,7 @@
   XSetForeground(theDisp, theGC, infofg);
   XDrawRectangle(theDisp, pageF, theGC, pageRect.x, pageRect.y,
 		 (u_int) pageRect.width, (u_int) pageRect.height);
-  
+
   drawIRect(1);
 }
 
@@ -611,7 +616,7 @@
   unsigned int mask;
   double       offx, offy, newx, newy;
 
-  /* compute offset (in inches) between 'drag point' and 
+  /* compute offset (in inches) between 'drag point' and
      the top-left corner of the image */
 
   offx = ((mx - pageRect.x) / in2pix) - pos_inx;
@@ -642,7 +647,7 @@
   char *fullname;
 
   switch (cmd) {
-  case PS_BOK:    writePS();    
+  case PS_BOK:    writePS();
                   PSDialog(0);
                   fullname = GetDirFullName();
                   if (!ISPIPE(fullname[0])) {
@@ -721,15 +726,15 @@
 
   GetSaveSize(&w, &h);
 
-  sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);  
-  sz_iny = (double) h / PIX2INCH * (ysDial.val / 100.0);  
+  sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);
+  sz_iny = (double) h / PIX2INCH * (ysDial.val / 100.0);
 
   /* round to integer .001ths of an inch */
   sz_inx = floor(sz_inx * 1000.0 + 0.5) / 1000.0;
   sz_iny = floor(sz_iny * 1000.0 + 0.5) / 1000.0;
 
-  dpix = (int) (PIX2INCH / (xsDial.val / 100.0));  
-  dpiy = (int) (PIX2INCH / (ysDial.val / 100.0));  
+  dpix = (int) (PIX2INCH / (xsDial.val / 100.0));
+  dpiy = (int) (PIX2INCH / (ysDial.val / 100.0));
 
   /* make sure 'center' of image is still on page */
   hsx = sz_inx/2;  hsy = sz_iny/2;
@@ -783,20 +788,20 @@
 {
   int x,y,w,h;
   XRectangle xr;
-  
+
   x = pageRect.x + (int) (pos_inx * in2pix);
   y = pageRect.y + (int) (pos_iny * in2pix);
   w = sz_inx * in2pix;
   h = sz_iny * in2pix;
-  
+
   xr.x = pageRect.x + 1;
   xr.y = pageRect.y + 1;
   xr.width  = pageRect.width - 1;
   xr.height = pageRect.height - 1;
-  
+
   if (draw) XSetForeground(theDisp, theGC, infofg);
        else XSetForeground(theDisp, theGC, infobg);
-  
+
   XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
   XDrawRectangle(theDisp, pageF, theGC, x, y, (u_int) w, (u_int) h);
   XDrawLine(theDisp, pageF, theGC, x, y, x+w, y+h);
@@ -836,18 +841,18 @@
   if (scx < scy) { sz_iny = h * scx; }
             else { sz_inx = w * scy; }
 
-  DSetVal(&xsDial, (int) ((100 * (sz_inx * PIX2INCH) / w) + .5));
+  DSetVal(&xsDial, 100 * (sz_inx * PIX2INCH) / w);
   DSetVal(&ysDial, xsDial.val);
 
-  sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);  
-  sz_iny = (double) h / PIX2INCH * (ysDial.val / 100.0);  
+  sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);
+  sz_iny = (double) h / PIX2INCH * (ysDial.val / 100.0);
 
   /* round to integer .001ths of an inch */
   sz_inx = floor(sz_inx * 1000.0 + 0.5) / 1000.0;
   sz_iny = floor(sz_iny * 1000.0 + 0.5) / 1000.0;
 
-  dpix = (int) (PIX2INCH / (xsDial.val / 100.0));  
-  dpiy = (int) (PIX2INCH / (ysDial.val / 100.0));  
+  dpix = (int) (PIX2INCH / (xsDial.val / 100.0));
+  dpiy = (int) (PIX2INCH / (ysDial.val / 100.0));
 
   pos_inx = psizex/2 - sz_inx/2;
   pos_iny = psizey/2 - sz_iny/2;
@@ -888,7 +893,7 @@
 static void writePS()
 {
   FILE *fp;
-  int   i, j, q, err, rpix, gpix, bpix, nc, ptype;
+  int   i, j, err, rpix, gpix, bpix, nc, ptype;
   int   iw, ih, ox, oy, slen, lwidth, bits, colorps, w, h, pfree;
   double iwf, ihf;
   byte *inpix, *rmap, *gmap, *bmap;
@@ -900,13 +905,19 @@
   if (!fp) return;
 
   WaitCursor();
-  
+
   inpix = GenSavePic(&ptype, &w, &h, &pfree, &nc, &rmap, &gmap, &bmap);
 
-    
+  if (w <= 0 || h <= 0 || w*2 < w) {
+    SetISTR(ISTR_WARNING,"%s:  Image dimensions out of range", filename);
+    CloseOutFile(fp, filename, 1);
+    return;
+  }
+
+
   /* printed image will have size iw,ih (in picas) */
   iw = (int) (sz_inx * 72.0 + 0.5);
-  ih = (int) (sz_iny * 72.0 + 0.5);   
+  ih = (int) (sz_iny * 72.0 + 0.5);
   iwf = sz_inx * 72.0;
   ihf = sz_iny * 72.0;
 
@@ -923,12 +934,12 @@
   fprintf(fp,"%%%%Creator: XV %s  -  by John Bradley\n",REVDATE);
 
   if (RBWhich(orientRB)==ORNT_LAND)   /* Landscape mode */
-    fprintf(fp,"%%%%BoundingBox: %d %d %d %d\n", 
+    fprintf(fp,"%%%%BoundingBox: %d %d %d %d\n",
 	    (int) (pos_iny * 72.0 + 0.5),
 	    (int) (pos_inx * 72.0 + 0.5),
 	    (int) (pos_iny * 72.0 + 0.5) + ih,
 	    (int) (pos_inx * 72.0 + 0.5) + iw);
-  else 
+  else
     fprintf(fp,"%%%%BoundingBox: %d %d %d %d\n", ox, oy, ox+iw, oy+ih);
 
   fprintf(fp,"%%%%Pages: 1\n");
@@ -943,9 +954,9 @@
   case F_BWDITHER:  slen = (w+7)/8;  bits = 1;  colorps = 0;  break;
   default:  FatalError("unknown colorType in writePS()");   break;
   }
-  
+
   if (encapsCB.val) epsPreview(fp, inpix, ptype, colorType, w, h,
-			       rmap,gmap,bmap, 
+			       rmap,gmap,bmap,
 			       (RBWhich(orientRB)==ORNT_LAND) );
 
   fprintf(fp,"%%%%EndProlog\n\n");
@@ -978,7 +989,7 @@
     fprintf(fp,"%% print in landscape mode\n");
     fprintf(fp,"90 rotate 0 %d translate\n\n",(int) (-psizey*72.0));
   }
-    
+
   if (RBWhich(paperRB) == PSZ_4BY5 ||
       RBWhich(paperRB) == PSZ_35MM) {
     fprintf(fp,"%% we're going to a 4x5 or a 35mm film recorder.\n");
@@ -1083,12 +1094,12 @@
 	    gpix = inpix[1];
 	    bpix = inpix[2];
 	  }
-	  
-	  if (colorps) { 
+
+	  if (colorps) {
 	    err = fprintf(fp,"%02x%02x%02x",rpix,gpix,bpix);
 	    lwidth+=6;
 	  }
-      
+
 	  else {  /* greyscale */
 	    err = fprintf(fp,"%02x", MONO(rpix,gpix,bpix));
 	    lwidth+=2;
@@ -1106,7 +1117,7 @@
       fprintf(fp,"\n\n");
       fprintf(fp,"%%\n");
       fprintf(fp,"%% Compression made this file %.2f%% %s\n",
-	      100.0 * ((double) outbytes) / 
+	      100.0 * ((double) outbytes) /
 	      ((double) eWIDE * eHIGH * ((colorps) ? 3 : 1)),
 	      "of the uncompressed size.");
       fprintf(fp,"%%\n");
@@ -1147,10 +1158,10 @@
    *
    * returns length of the rleline vector
    */
-  
+
   int  i, j, blocklen, isrun, rlen;
   byte block[256], pix;
-  
+
   blocklen = isrun = rlen = 0;
 
   for (i=0; i<wide; i++) {
@@ -1186,7 +1197,7 @@
 	}
       }
     }
-	
+
     else {   /* not a run */
       if (pix == block[blocklen-1]) {   /* case 3:  non-run, prev==cur */
 	if (blocklen>1) {               /*  have a non-run block to flush */
@@ -1215,7 +1226,7 @@
 
       else {
 	rleline[rlen++] = (blocklen-1) | 0x80;
-	for (j=0; j<blocklen; j++) 
+	for (j=0; j<blocklen; j++)
 	  rleline[rlen++] = block[j];
       }
 
@@ -1231,15 +1242,15 @@
 
     else {
       rleline[rlen++] = (blocklen-1) | 0x80;
-      for (j=0; j<blocklen; j++) 
+      for (j=0; j<blocklen; j++)
 	rleline[rlen++] = block[j];
     }
   }
 
   return rlen;
 }
-	  
-	    
+
+
 /**********************************************/
 static void psColorImage(fp)
 FILE *fp;
@@ -1276,7 +1287,7 @@
   fprintf(fp,"    %% Utility procedure for colorimage operator.\n");
   fprintf(fp,"    %% This procedure takes two procedures off the\n");
   fprintf(fp,"    %% stack and merges them into a single procedure.\n\n");
-  
+
   fprintf(fp,"    /mergeprocs { %% def\n");
   fprintf(fp,"      dup length\n");
   fprintf(fp,"      3 -1 roll\n");
@@ -1326,12 +1337,12 @@
   for (i=0; i<nc; i++) {
     if (color) fprintf(fp,"%02x%02x%02x ", rmap[i],gmap[i],bmap[i]);
     else fprintf(fp,"%02x ", MONO(rmap[i],gmap[i],bmap[i]));
-    
+
     if ((i%10) == 9) fprintf(fp,"\n");
   }
   if (i%10) fprintf(fp,"\n");
   fprintf(fp,"pop pop   %% lose return values from readhexstring\n\n\n");
-		 
+
 }
 
 
@@ -1407,7 +1418,7 @@
 
 
 /**********************************************/
-static void epsPreview(fp, pic, ptype, colorType, w, h, rmap,gmap,bmap, 
+static void epsPreview(fp, pic, ptype, colorType, w, h, rmap,gmap,bmap,
 		       landscape)
      FILE *fp;
      byte *pic;
@@ -1420,21 +1431,37 @@
 
 
   if (landscape) {  /* generate a rotated version of the pic */
-    int bperpix;
+    int npixels, bufsize;
     byte *lpic;
 
-    bperpix = (ptype == PIC8) ? 1 : 3;
-    lpic = (byte *) malloc((size_t) w * h * bperpix);
+    npixels = w * h;
+    if (w <= 0 || h <= 0 || npixels/w != h) {
+      SetISTR(ISTR_WARNING,"%s:  Image dimensions out of range", filename);
+/*    CloseOutFile(fp, filename, 1);  can't do since caller still writing */
+      return;
+    }
+    if (ptype == PIC8)
+      bufsize = npixels;
+    else {
+      bufsize = 3*npixels;
+      if (bufsize/3 != npixels) {
+        SetISTR(ISTR_WARNING,"%s:  Image dimensions out of range", filename);
+/*      CloseOutFile(fp, filename, 1);  can't do since caller still writing */
+        return;
+      }
+    }
+
+    lpic = (byte *) malloc((size_t) bufsize);
     if (!lpic) FatalError("can't alloc mem to rotate image in epsPreview");
 
-    xvbcopy((char *) pic, (char *) lpic, (size_t) w * h * bperpix);
+    xvbcopy((char *) pic, (char *) lpic, (size_t) bufsize);
     RotatePic(lpic, ptype, &w, &h, 0);
     pic = lpic;
   }
-    
+
 
   /* put in an EPSI preview */
-  
+
   if (colorType != F_BWDITHER) { /* have to generate a preview */
     prev = FSDither(pic, ptype, w, h, rmap,gmap,bmap, 0, 1);
 
@@ -1451,8 +1478,8 @@
     flipbw = (MONO(rmap[0],gmap[0],bmap[0]) > MONO(rmap[1],gmap[1],bmap[1]));
   }
 
- 
-  fprintf(fp,"%%%%BeginPreview: %d %d %d %d\n", w, h, 1, 
+
+  fprintf(fp,"%%%%BeginPreview: %d %d %d %d\n", w, h, 1,
 	  (w/(72*4) + 1) * h);
 
   writeBWStip(fp, prev, "% ", w, h, !flipbw);
@@ -1468,10 +1495,10 @@
 static int writeBWStip(fp, pic, prompt, w, h, flipbw)
      FILE *fp;
      byte *pic;
-     char *prompt;
+     const char *prompt;
      int  w, h, flipbw;
 {
-  /* write the given 'pic' (B/W stippled, 1 byte per pixel, 0=blk,1=wht) 
+  /* write the given 'pic' (B/W stippled, 1 byte per pixel, 0=blk,1=wht)
      out as hexadecimal, max of 72 hex chars per line.
 
      if 'flipbw', then 0=white, 1=black
@@ -1535,39 +1562,46 @@
      document is multiple pages, a series of PNM files are created, and
      the first one is loaded (but not deleted) */
 
-
-  char tmp[512], tmp1[512], tmpname[64];
-  int  gsresult, nump, i, filetype;
-  char *rld;
+#ifdef GS_PATH
+  #define CMDSIZE	1024
+  char tmp[512], gscmd[512], cmdstr[CMDSIZE], tmpname[64];
+  int  gsresult, nump, i, filetype, doalert, epsf;
+#endif
 
   pinfo->pic     = (byte *) NULL;
   pinfo->comment = (char *) NULL;
 
-
 #ifdef GS_PATH
 
+  doalert = (!quick && !ctrlUp && !infoUp);  /* open alert if no info wins */
+  epsf    = 0;
+
 #ifndef VMS
   sprintf(tmpname, "%s/xvpgXXXXXX", tmpdir);
 #else
   sprintf(tmpname, "Sys$Scratch:xvpgXXXXXX");
 #endif
 
+#ifdef USE_MKSTEMP
+  close(mkstemp(tmpname));
+#else
   mktemp(tmpname);
-  if (tmpname[0] == '\0') {   /* mktemp() blew up */
-    sprintf(str,"LoadPS: Unable to create temporary filename???");
-    ErrPopUp(str, "\nHow unlikely!");
+#endif
+  if (tmpname[0] == '\0') {   /* mktemp() or mkstemp() blew up */
+    sprintf(dummystr,"LoadPS: Unable to create temporary filename???");
+    ErrPopUp(dummystr, "\nHow unlikely!");
     return 0;
   }
   strcat(tmpname,".");
 
 
-  /* build command string */
+  /* build 'gscmd' string */
 
 #ifndef VMS  /* VMS needs quotes around mixed case command lines */
-  sprintf(tmp, "%s -sDEVICE=%s -r%d -q -dNOPAUSE -sOutputFile=%s%%d ",
+  sprintf(gscmd, "%s -sDEVICE=%s -r%d -q -dSAFER -dNOPAUSE -sOutputFile=%s%%d ",
 	  GS_PATH, gsDev, gsRes, tmpname);
 #else
-  sprintf(tmp, 
+  sprintf(gscmd,
 	  "%s \"-sDEVICE=%s\" -r%d -q \"-dNOPAUSE\" \"-sOutputFile=%s%%d\" ",
 	  GS_PATH, gsDev, gsRes, tmpname);
 #endif
@@ -1575,74 +1609,60 @@
 
 #ifdef GS_LIB
 #  ifndef VMS
-     sprintf(tmp1, "-I%s ", GS_LIB);
+     sprintf(tmp, "-I%s ", GS_LIB);
 #  else
-     sprintf(tmp1, "\"-I%s\"", GS_LIB);
+     sprintf(tmp, "\"-I%s\" ", GS_LIB);
 #  endif
-   strcat(tmp, tmp1);
+   strcat(gscmd, tmp);
 #endif
 
-  if (gsGeomStr) {
-    sprintf(tmp1, "-g%s ", gsGeomStr);
-    strcat(tmp, tmp1);
-  }
-
-  /* if 'quick' is set, stop processing after first page by tacking
-     some PostScript commands that break the 'showpage' operator onto
-     the front of the stream passed to the ghostscript interpreter */
 
+   /* prevent some potential naughtiness... */
 #ifndef VMS
-  if (quick) {
-    sprintf(tmp1, "echo '%s' | cat - %s | %s -",
-	    "/showpage { showpage quit } bind def",   /* mk showpage exit */
-	    fname,  tmp);
-    strcpy(tmp, tmp1);
-  }
-  else {
-    strcat(tmp, " -- ");
-    strcat(tmp, fname);
-  }
-#else /* VMS */
-  /* VMS doesn't have pipes or an 'echo' command and GS doesn't like
-     Unix-style file names as input files in the VMS version */
-  strcat(tmp, " -- ");
-  rld = strrchr(fname, '/');     /* Pointer to last '/' */
-  if (rld) rld++;                /* Pointer to filename */
-      else rld = fname;          /* No path - use original string */
-  strcat(tmp, rld);
+   strcat(gscmd, "-dSAFER ");
+#else
+   strcat(gscmd, "\"-dSAFER\" ");
 #endif
 
 
+  if (gsGeomStr) {
+    sprintf(tmp, "-g%s ", gsGeomStr);
+    strcat(gscmd, tmp);
+  }
 
 
-  WaitCursor();
-
-  if (DEBUG) fprintf(stderr,"LoadPS:  executing command '%s'\n", tmp);
-  SetISTR(ISTR_INFO, "Running '%s'...", GS_PATH);
+  do {
+    buildCmdStr(cmdstr, gscmd, fname, quick, epsf);
 
-  sprintf(tmp1, "Running %s", tmp);
-  if (!quick && !ctrlUp && !infoUp) OpenAlert(tmp1);
+    if (DEBUG) fprintf(stderr,"LoadPS:  executing command '%s'\n", cmdstr);
+    SetISTR(ISTR_INFO, "Running '%s'...", GS_PATH);
+    sprintf(tmp, "Running %s", cmdstr);
+    if (doalert && epsf==0) OpenAlert(tmp);  /* open alert first time only */
 
-#ifndef VMS
-  gsresult = system(tmp);
-#else
-  gsresult = !system(tmp);
+    WaitCursor();
+    gsresult = system(cmdstr);
+    WaitCursor();
+#ifdef VMS
+    gsresult = !gsresult;   /* VMS returns non-zero if OK */
 #endif
 
-  WaitCursor();
+    /* count # of files produced... */
+    for (i=1; i<1000; i++) {
+      struct stat st;
+      sprintf(tmp, "%s%d", tmpname, i);
+      if (stat(tmp, &st)!=0) break;
+    }
+    nump = i-1;
+    WaitCursor();
 
-  if (!quick && !ctrlUp && !infoUp) CloseAlert();
+    /* EPSF hack:  if gsresult==0 (OK) and 0 pages produced,
+       try tacking a 'showpage' onto the end of the file, do it again... */
+
+    if (!gsresult && !nump && !epsf) epsf++;
+  } while (!gsresult && !nump && epsf<2);
+
+  if (doalert) CloseAlert();
 
-  /* figure out how many page files were created, by stating files. 
-     breaks out on first failure, assuming there won't be any more after
-     that, and it would complicate matters too much anyhow... */
-
-  for (i=1; i<1000; i++) {
-    struct stat st;
-    sprintf(tmp, "%s%d", tmpname, i);
-    if (stat(tmp, &st)!=0) break;
-  }
-  nump = i-1;
 
   WaitCursor();
 
@@ -1664,7 +1684,7 @@
       return 0;
     }
 
-    SetISTR(ISTR_INFO, "Running '%s'...  Done.  (%d page%s)", 
+    SetISTR(ISTR_INFO, "Running '%s'...  Done.  (%d page%s)",
 	    GS_PATH, nump, (nump==1) ? "" : "s");
   }
 
@@ -1677,8 +1697,8 @@
 
   sprintf(tmp, "%s%d", tmpname, 1);
   filetype = ReadFileType(tmp);
-  
-  if (filetype == RFT_ERROR || filetype == RFT_UNKNOWN || 
+
+  if (filetype == RFT_ERROR || filetype == RFT_UNKNOWN ||
       filetype == RFT_COMPRESS) {  /* shouldn't happen */
     SetISTR(ISTR_WARNING, "Couldn't load first page '%s'", tmp);
     KillPageFiles(tmpname, nump);
@@ -1695,7 +1715,7 @@
     KillPageFiles(tmpname, nump);
     SetCursors(-1);
     return 0;
-  }    
+  }
 
 
   /* SUCCESS! */
@@ -1712,3 +1732,54 @@
 		 we don't have 'gs' package */
 }
 
+
+
+/******************************************************************/
+#ifdef GS_PATH
+void buildCmdStr(str, gscmd, xname, quick, epsf)
+     char *str, *gscmd, *xname;
+     int   quick, epsf;
+{
+  /* note 'epsf' set only on files that don't have a showpage cmd */
+  char *x, *y, *fname;
+
+  x = (char *) malloc((5 * strlen(xname))+3);
+  if (!x)
+	FatalError("malloc failure in xvps.c buildCmdStr");
+  fname = x;
+  *x++ = 0x27;
+
+  for (y = xname; *y; ++y) {
+     if (0x27 == *y) {
+       strcpy(x, "'\"'\"'");
+       x += strlen(x);
+     } else *x++ = *y;
+  }
+  strcpy (x, "'");
+
+#ifndef VMS
+
+  if      (epsf)  snprintf(str, CMDSIZE, "echo '\n showpage ' | cat %s - | %s -",
+			  fname, gscmd);
+
+  else if (quick) snprintf(str, CMDSIZE, "echo %s | cat - %s | %s -",
+			  "/showpage { showpage quit } bind def",
+			  fname,  gscmd);
+
+  else            snprintf(str, CMDSIZE, "%s -- %s", gscmd, fname);
+
+#else /* VMS */
+  /* VMS doesn't have pipes or an 'echo' command and GS doesn't like
+     Unix-style filenames as input files in the VMS version */
+  strcat(tmp, " -- ");
+  rld = strrchr(fname, '/');     /* Pointer to last '/' */
+  if (rld) rld++;                /* Pointer to filename */
+  else rld = fname;              /* No path - use original string */
+  strcat(tmp, rld);
+#endif  /* VMS */
+  free(fname);
+}
+#endif  /* GS_PATH */
+
+
+
diff -ru xv-3.10a/xvrle.c xv-3.10a-enhancements/xvrle.c
--- xv-3.10a/xvrle.c	1995-01-19 09:27:47.000000000 -0800
+++ xv-3.10a-enhancements/xvrle.c	2007-05-13 17:49:34.000000000 -0700
@@ -28,7 +28,7 @@
 #define GETINT(fp) (c=getc(fp), c1=getc(fp), (c1<<8) + c )
 
 static void read_rle PARM((FILE *, byte *, int, int, int, int));
-static int  rleError PARM((char *, char *));
+static int  rleError PARM((const char *, const char *));
 
 
 
@@ -44,9 +44,10 @@
   byte   maps[3][256];
   int    xpos, ypos, w, h, flags, ncolors, pixelbits, ncmap, cmaplen;
   int    cmtlen;
-  byte  *img, *pic8;
+  byte  *img;
   long filesize;
-  char  *bname, *errstr;
+  const char *bname;
+  const char *errstr;
 
   pinfo->type = PIC8;
   pinfo->pic     = (byte *) NULL;
@@ -57,7 +58,7 @@
   /* open the stream */
   fp = xv_fopen(fname,"r");
   if (!fp) return (rleError(bname, "unable to open file"));
-  
+
 
   /* figure out the file size */
   fseek(fp, 0L, 2);
@@ -85,7 +86,7 @@
   if (DEBUG) {
     fprintf(stderr,"RLE: %dx%d image at %d,%d\n", w, h, xpos, ypos);
     fprintf(stderr,"flags: 0x%02x  (%s%s%s%s)\n",
-	    flags, 
+	    flags,
 	    (flags & H_CLEARFIRST)    ? "CLEARFIRST " : "",
 	    (flags & H_NO_BACKGROUND) ? "NO_BG " : "",
 	    (flags & H_ALPHA)         ? "ALPHA " : "",
@@ -93,7 +94,7 @@
 
     fprintf(stderr, "%d bands, %d pixelbits, %d cmap bands, %d cmap entries\n",
 	    ncolors, pixelbits, ncmap, cmaplen);
-  }  
+  }
 
   if (!(flags & H_NO_BACKGROUND)) {
     if (DEBUG) fprintf(stderr, "background value: ");
@@ -212,7 +213,7 @@
       for (i=0, ip=img; i<w*h; i++, ip++) *ip = bgcol[0];
     }
     else {
-      for (i=0, ip=img; i<w*h; i++) 
+      for (i=0, ip=img; i<w*h; i++)
 	for (j=0; j<3; j++, ip++) *ip = bgcol[j];
     }
   }
@@ -250,7 +251,7 @@
   /* finally, convert into XV internal format */
 
   pinfo->pic = img;
-  pinfo->w   = w;  
+  pinfo->w   = w;
   pinfo->h   = h;
   pinfo->normw = pinfo->w;   pinfo->normh = pinfo->h;
   pinfo->frmType = -1;    /* no default format to save in */
@@ -260,7 +261,7 @@
     if (ncmap == 0 || ncmap == 1) {   /* grey, or grey with gamma curve */
       pinfo->colType = F_GREYSCALE;
       sprintf(pinfo->fullInfo, "Greyscale RLE.  (%ld bytes)", filesize);
-      for (i=0; i<256; i++) 
+      for (i=0; i<256; i++)
 	pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;
     }
     else {
@@ -272,7 +273,7 @@
 	pinfo->b[i] = maps[2][i];
       }
     }
-    
+
     sprintf(pinfo->shrtInfo, "%dx%d RLE.",w, h);
   }
 
@@ -294,7 +295,7 @@
      int   w, h, ncolors, ncmap;
 {
   int posx, posy, plane, bperpix, i, pixval, skipcalls;
-  int opcode, operand, done, c, c1;    
+  int opcode, operand, done, c, c1;
   byte *ip;
 
   posx = posy = plane = done = skipcalls = 0;
@@ -324,7 +325,7 @@
     case RSkipPixelsOp:
       if (opcode & LONG_OP) { getc(fp);  operand = GETINT(fp); }
       else operand = getc(fp);
-      
+
       posx += operand;
       break;
 
@@ -340,7 +341,7 @@
 	c = getc(fp);
 	if (plane<ncolors && posy<h && (posx+i < w)) *ip = c;
       }
-      
+
       if (operand & 1) getc(fp);  /* word boundary */
       posx += operand;
       break;
@@ -358,7 +359,7 @@
       for (i=0; i<operand; i++, ip+=bperpix) {
 	if (plane<ncolors && posy<h && (posx+i < w)) *ip = pixval;
       }
-      
+
       /*  if (operand & 1) getc(fp); */  /* word boundary */
       posx += operand;
       break;
@@ -373,7 +374,7 @@
 
 /*******************************************/
 static int rleError(fname,st)
-     char *fname, *st;
+     const char *fname, *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", fname, st);
   return 0;
diff -ru xv-3.10a/xvroot.c xv-3.10a-enhancements/xvroot.c
--- xv-3.10a/xvroot.c	1994-12-22 14:34:42.000000000 -0800
+++ xv-3.10a-enhancements/xvroot.c	2004-05-16 18:07:52.000000000 -0700
@@ -22,7 +22,7 @@
 /***********************************/
 void MakeRootPic()
 {
-  /* called after 'epic' has been generated (if we're using root).  
+  /* called after 'epic' has been generated (if we're using root).
      creates the XImage and the pixmap, sets the root to the new
      pixmap, and refreshes the display */
 
@@ -44,6 +44,7 @@
   case RM_MIRROR:
   case RM_IMIRROR: rpixw = 2*eWIDE;  rpixh = 2*eHIGH;  break;
   case RM_CSOLID:
+  case RM_UPLEFT:
   case RM_CWARP:
   case RM_CBRICK:  rpixw = dispWIDE; rpixh = dispHIGH; break;
 
@@ -67,32 +68,32 @@
 
 
   if (rmode == RM_NORMAL || rmode == RM_TILE) {
-    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0, 
+    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0,
 	      (u_int) eWIDE, (u_int) eHIGH);
   }
 
   else if (rmode == RM_MIRROR || rmode == RM_IMIRROR) {
     /* quadrant 2 */
-    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0, 
+    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0,
 	      (u_int) eWIDE, (u_int) eHIGH);
     if (epic == NULL) FatalError("epic == NULL in RM_MIRROR code...\n");
 
     /* quadrant 1 */
     FlipPic(epic, eWIDE, eHIGH, 0);   /* flip horizontally */
     CreateXImage();
-    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, eWIDE,0, 
+    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, eWIDE,0,
 	      (u_int) eWIDE, (u_int) eHIGH);
 
     /* quadrant 4 */
     FlipPic(epic, eWIDE, eHIGH, 1);   /* flip vertically */
     CreateXImage();
-    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, eWIDE,eHIGH, 
+    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, eWIDE,eHIGH,
 	      (u_int) eWIDE, (u_int) eHIGH);
 
     /* quadrant 3 */
     FlipPic(epic, eWIDE, eHIGH, 0);   /* flip horizontally */
     CreateXImage();
-    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,eHIGH, 
+    XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,eHIGH,
 	      (u_int) eWIDE, (u_int) eHIGH);
 
     FlipPic(epic, eWIDE, eHIGH, 1);   /* flip vertically  (back to orig) */
@@ -101,7 +102,7 @@
 
 
   else if (rmode == RM_CENTER || rmode == RM_CENTILE || rmode == RM_CSOLID ||
-	   rmode == RM_CWARP || rmode == RM_CBRICK) {
+	   rmode == RM_CWARP || rmode == RM_CBRICK || rmode == RM_UPLEFT) {
     /* do some stuff to set up the border around the picture */
 
     if (rmode != RM_CENTILE) {
@@ -122,15 +123,15 @@
       for (i=ay; i < (int) eHIGH; i+=h) {
 	for (j=ax; j < (int) eWIDE; j+=w) {
 	  /* if image goes off tmpPix, only draw subimage */
-	  
+
 	  x = j;  y = i;  w1 = w;  h1 = h;  offx = offy = 0;
 	  if (x<0)           { offx = -x;  w1 -= offx;  x = 0; }
 	  if (x+w1>eWIDE) { w1 = (eWIDE-x); }
 
 	  if (y<0)           { offy = -y;  h1 -= offy;  y = 0; }
 	  if (y+h1>eHIGH)    { h1 = (eHIGH-y); }
-	  
-	  XPutImage(theDisp, tmpPix, theGC, theImage, offx, offy, 
+
+	  XPutImage(theDisp, tmpPix, theGC, theImage, offx, offy,
 		    x, y, (u_int) w1, (u_int) h1);
 	}
       }
@@ -138,9 +139,15 @@
 
     else if (rmode == RM_CSOLID) { }
 
+    else if (rmode == RM_UPLEFT) {
+
+      XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0,
+		(u_int) eWIDE, (u_int) eHIGH);
+    }
+
     else if (rmode == RM_CWARP) {          /* warp effect */
       XSetForeground(theDisp, theGC, rootfg);
-      for (i=0; i<=dispWIDE; i+=8) 
+      for (i=0; i<=dispWIDE; i+=8)
 	XDrawLine(theDisp,tmpPix,theGC, i,0, (int) dispWIDE-i,(int) dispHIGH);
       for (i=0; i<=dispHIGH; i+=8)
 	XDrawLine(theDisp,tmpPix,theGC, 0,i, (int) dispWIDE, (int) dispHIGH-i);
@@ -150,16 +157,16 @@
       XSetForeground(theDisp, theGC, rootfg);
       for (i=k=0; i<dispHIGH; i+=20,k++) {
 	XDrawLine(theDisp, tmpPix, theGC, 0, i, (int) dispWIDE, i);
-	for (j=(k&1) * 20 + 10; j<dispWIDE; j+=40) 
+	for (j=(k&1) * 20 + 10; j<dispWIDE; j+=40)
 	  XDrawLine(theDisp, tmpPix, theGC, j,i,j,i+20);
       }
     }
 
 
     /* draw the image centered on top of the background */
-    if (rmode != RM_CENTILE) 
-      XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 
-		((int) dispWIDE-eWIDE)/2, ((int) dispHIGH-eHIGH)/2, 
+    if ((rmode != RM_CENTILE) && (rmode != RM_UPLEFT))
+      XPutImage(theDisp, tmpPix, theGC, theImage, 0,0,
+		((int) dispWIDE-eWIDE)/2, ((int) dispHIGH-eHIGH)/2,
 		(u_int) eWIDE, (u_int) eHIGH);
   }
 
@@ -172,7 +179,7 @@
     if (dispWIDE == eWIDE) {
       /* horizontal center line */
       int y, ay;
-      
+
       y = eHIGH - ((dispHIGH/2)%eHIGH); /* Starting point in picture to copy */
       ay = 0;    /* Vertical anchor point */
       while (ay < dispHIGH) {
@@ -189,7 +196,7 @@
     else if (dispHIGH == eHIGH) {
       /* vertical centerline */
       int x, ax;
-      
+
       x = eWIDE - ((dispWIDE/2)%eWIDE); /* Starting point in picture to copy */
       ax = 0;    /* Horizontal anchor point */
       while (ax < dispWIDE) {
@@ -206,10 +213,10 @@
     else {
       /* vertical and horizontal centerlines */
       int x,y, ax,ay;
-      
+
       y = eHIGH - ((dispHIGH/2)%eHIGH); /* Starting point in picture to copy */
       ay = 0;    /* Vertical anchor point */
-      
+
       while (ay < dispHIGH) {
 	x = eWIDE - ((dispWIDE/2)%eWIDE);/* Starting point in picture to cpy */
 	ax = 0;    /* Horizontal anchor point */
@@ -276,8 +283,8 @@
     gc_init.foreground = BlackPixel(theDisp, theScreen);
     gc_init.background = WhitePixel(theDisp, theScreen);
     gc = XCreateGC(theDisp, vrootW, GCForeground|GCBackground, &gc_init);
-    pix = XCreatePixmap(theDisp, vrootW, root_weave_width, 
-			root_weave_height, 
+    pix = XCreatePixmap(theDisp, vrootW, root_weave_width,
+			root_weave_height,
 			(unsigned int) DefaultDepth(theDisp, theScreen));
 
     XCopyPlane(theDisp, bitmap, pix, gc, 0,0, root_weave_width,
@@ -333,8 +340,8 @@
   prop = XInternAtom(theDisp, "_XSETROOT_ID", True);
   if (prop == None) return;    /* no old pixmap to kill */
 
-  if (XGetWindowProperty(theDisp, vrootW, prop, 0L, 1L, True, 
-			 AnyPropertyType, &type, &format, &length, 
+  if (XGetWindowProperty(theDisp, vrootW, prop, 0L, 1L, True,
+			 AnyPropertyType, &type, &format, &length,
 			 &after, &data) == Success) {
 
     if (type==XA_PIXMAP && format==32 && length==1 && after==0 && data) {
@@ -348,4 +355,4 @@
 
 
 
-    
+
diff -ru xv-3.10a/xvscrl.c xv-3.10a-enhancements/xvscrl.c
--- xv-3.10a/xvscrl.c	1994-12-22 14:34:41.000000000 -0800
+++ xv-3.10a-enhancements/xvscrl.c	2004-05-16 18:07:56.000000000 -0700
@@ -1,4 +1,4 @@
-/* 
+/*
  * xvscrl.c - Scroll Bar handling functions
  *
  * callable functions:
@@ -6,7 +6,7 @@
  *   SCCreate()   -  creates the Scroll Bar window.
  *   SCChange()   -  resize/repositions the Scroll Bar window.
  *   SCSetRange() -  sets min/max/current values of control
- *   SCSetVal()   -  sets value of control 
+ *   SCSetVal()   -  sets value of control
  *   SCRedraw()   -  redraws scroll bar
  *   SCTrack()    -  called when clicked.  Operates control 'til mouseup
  */
@@ -50,7 +50,7 @@
 
 
 /***************************************************/
-void SCCreate(sp, parent, x, y, vert, len, minv, maxv, curv, page, 
+void SCCreate(sp, parent, x, y, vert, len, minv, maxv, curv, page,
 	          fg, bg, hi, lo, func)
 SCRL         *sp;
 Window        parent;
@@ -71,7 +71,7 @@
     downhPix = MakePix1(parent, downh_bits,  downh_width,  downh_height);
     uph1Pix  = MakePix1(parent, uph1_bits,   uph1_width,   uph1_height);
     downh1Pix= MakePix1(parent, downh1_bits, downh1_width, downh1_height);
-    
+
     sgray    = XCreatePixmapFromBitmapData(theDisp, parent,
 		(char *) scrlgray_bits, scrlgray_width, scrlgray_height,
 					   fg,bg,dispDEEP);
@@ -124,7 +124,7 @@
   sp->len  = len;
   sp->uplit = sp->dnlit = 0;
 
-  if (vert) XMoveResizeWindow(theDisp, sp->win, x,y, 
+  if (vert) XMoveResizeWindow(theDisp, sp->win, x,y,
 			      (u_int) sp->tsize,(u_int) len);
   else      XMoveResizeWindow(theDisp, sp->win, x,y,
 			      (u_int) len, (u_int) sp->tsize);
@@ -144,7 +144,7 @@
   if (maxv<minv) maxv=minv;
   sp->min = minv;    sp->max = maxv;    sp->page = page;
   sp->active =  (minv < maxv);
-  
+
   /* adjust scroll bar background */
   if (sp->active) {
     if (ctrlColor) XSetWindowBackground(theDisp, sp->win, sp->lo);
@@ -174,7 +174,7 @@
 
   sp->val = curv;
 
-  if (sp->active) 
+  if (sp->active)
     sp->tpos = sp->tmin + ((sp->tmax - sp->tmin)*(curv - sp->min))
                / (sp->max - sp->min);
 
@@ -194,20 +194,20 @@
   XSetBackground(theDisp, theGC, sp->bg);
 
   XClearWindow(theDisp, sp->win);
-  
+
   drawArrow(sp,UPLINE);      /* draw up/down arrows */
   drawArrow(sp,DNLINE);
 
   XSetForeground(theDisp, theGC, sp->fg);
 
-  if (sp->vert) {    
+  if (sp->vert) {
     XDrawLine(theDisp, sp->win, theGC, 0, sp->tsize, sp->tsize, sp->tsize);
-    XDrawLine(theDisp, sp->win, theGC, 0, sp->len-sp->tsize-1, 
+    XDrawLine(theDisp, sp->win, theGC, 0, sp->len-sp->tsize-1,
 	      sp->tsize, sp->len-sp->tsize-1);
   }
   else {                       /* horizontal version */
     XDrawLine(theDisp, sp->win, theGC, sp->tsize, 0, sp->tsize, sp->tsize);
-    XDrawLine(theDisp, sp->win, theGC, sp->len - sp->tsize-1, 0, 
+    XDrawLine(theDisp, sp->win, theGC, sp->len - sp->tsize-1, 0,
 	      sp->len - sp->tsize-1, sp->tsize);
   }
 
@@ -225,7 +225,7 @@
 
   if (arr == UPLINE) {
     XSetForeground(theDisp, theGC, sp->bg);
-    XFillRectangle(theDisp, sp->win, theGC, 0, 0, 
+    XFillRectangle(theDisp, sp->win, theGC, 0, 0,
 		   (u_int) sp->tsize, (u_int) sp->tsize);
 
     if (sp->vert) butpix = (sp->uplit) ? up1Pix  : upPix;
@@ -235,14 +235,14 @@
     XSetBackground(theDisp, theGC, sp->bg);
     XCopyPlane(theDisp, butpix, sp->win, theGC, 0, 0, up_width,up_height,
 	       3,3, 1L);
-    Draw3dRect(sp->win, 0,0, (u_int) sp->tsize-1, (u_int) sp->tsize-1, 
+    Draw3dRect(sp->win, 0,0, (u_int) sp->tsize-1, (u_int) sp->tsize-1,
 	       (sp->uplit) ? R3D_IN : R3D_OUT, 2, sp->hi, sp->lo, sp->bg);
   }
 
   else if (arr == DNLINE) {
     if (sp->vert) {
       XSetForeground(theDisp, theGC, sp->bg);
-      XFillRectangle(theDisp, sp->win, theGC, 0, sp->len - sp->tsize, 
+      XFillRectangle(theDisp, sp->win, theGC, 0, sp->len - sp->tsize,
 		     (u_int) sp->tsize, (u_int) sp->tsize);
       butpix = (sp->dnlit) ? down1Pix : downPix;
 
@@ -251,8 +251,8 @@
       XCopyPlane(theDisp, butpix, sp->win, theGC, 0, 0, up_width,up_height,
 		 3, sp->len - 3 - up_height, 1L);
 
-      Draw3dRect(sp->win, 0, sp->len - sp->tsize, 
-		 (u_int) sp->tsize-1, (u_int) sp->tsize-1, 
+      Draw3dRect(sp->win, 0, sp->len - sp->tsize,
+		 (u_int) sp->tsize-1, (u_int) sp->tsize-1,
 		 (sp->dnlit) ? R3D_IN : R3D_OUT, 2, sp->hi, sp->lo, sp->bg);
     }
 
@@ -267,8 +267,8 @@
       XCopyPlane(theDisp, butpix, sp->win, theGC, 0, 0, up_width,up_height,
 		 sp->len - 3 - up_width, 3, 1L);
 
-      Draw3dRect(sp->win, sp->len - sp->tsize, 0, 
-		 (u_int) sp->tsize-1, (u_int) sp->tsize-1, 
+      Draw3dRect(sp->win, sp->len - sp->tsize, 0,
+		 (u_int) sp->tsize-1, (u_int) sp->tsize-1,
 		 (sp->dnlit) ? R3D_IN : R3D_OUT, 2, sp->hi, sp->lo, sp->bg);
     }
   }
@@ -283,17 +283,17 @@
 {
   if (sp->vert) {
     /* clear out thumb area with background color */
-    XClearArea(theDisp, sp->win, 0, sp->tsize+1, (u_int) sp->tsize, 
+    XClearArea(theDisp, sp->win, 0, sp->tsize+1, (u_int) sp->tsize,
 	       (u_int) ((sp->len-sp->tsize-1)-(sp->tsize+1)), False);
 
     if (sp->active) {  /* a thumb is necessary */
 
       XSetForeground(theDisp, theGC, sp->bg);
-      XFillRectangle(theDisp, sp->win, theGC, 1, sp->tpos+1, 
+      XFillRectangle(theDisp, sp->win, theGC, 1, sp->tpos+1,
 		     (u_int) (sp->tsize-2), (u_int) (sp->tsize-2));
 
       XSetForeground(theDisp, theGC, sp->fg);
-      XDrawRectangle(theDisp, sp->win, theGC, 0, sp->tpos, 
+      XDrawRectangle(theDisp, sp->win, theGC, 0, sp->tpos,
 		     (u_int) (sp->tsize-1), (u_int) (sp->tsize-1));
 
       XDrawLine(theDisp, sp->win, theGC, 9-3, sp->tpos+6, 9+3, sp->tpos+6);
@@ -301,7 +301,7 @@
       XDrawLine(theDisp, sp->win, theGC, 9-3, sp->tpos+10,9+3, sp->tpos+10);
       XDrawLine(theDisp, sp->win, theGC, 9-3, sp->tpos+12,9+3, sp->tpos+12);
 
-      Draw3dRect(sp->win, 1, sp->tpos+1, 
+      Draw3dRect(sp->win, 1, sp->tpos+1,
 		 (u_int) sp->tsize-3, (u_int) sp->tsize-3, R3D_OUT,2,
 		 sp->hi, sp->lo, sp->bg);
     }
@@ -309,17 +309,17 @@
 
   else {   /* horizontal */
     /* clear out thumb area with background color */
-    XClearArea(theDisp, sp->win, sp->tsize+1, 0, 
-	       (u_int) ((sp->len-sp->tsize-1)-(sp->tsize+1)), 
+    XClearArea(theDisp, sp->win, sp->tsize+1, 0,
+	       (u_int) ((sp->len-sp->tsize-1)-(sp->tsize+1)),
 	       (u_int) sp->tsize, False);
 
     if (sp->active) {  /* a thumb is necessary */
       XSetForeground(theDisp, theGC, sp->bg);
-      XFillRectangle(theDisp, sp->win, theGC, sp->tpos+1, 1, 
+      XFillRectangle(theDisp, sp->win, theGC, sp->tpos+1, 1,
 		     (u_int) (sp->tsize-2), (u_int) (sp->tsize-2));
 
       XSetForeground(theDisp, theGC, sp->fg);
-      XDrawRectangle(theDisp, sp->win, theGC, sp->tpos, 0, 
+      XDrawRectangle(theDisp, sp->win, theGC, sp->tpos, 0,
 		     (u_int) (sp->tsize-1), (u_int) (sp->tsize-1));
 
       XDrawLine(theDisp, sp->win, theGC, sp->tpos+6, 9-3, sp->tpos+6, 9+3);
@@ -327,7 +327,7 @@
       XDrawLine(theDisp, sp->win, theGC, sp->tpos+10,9-3, sp->tpos+10,9+3);
       XDrawLine(theDisp, sp->win, theGC, sp->tpos+12,9-3, sp->tpos+12,9+3);
 
-      Draw3dRect(sp->win, sp->tpos+1, 1, 
+      Draw3dRect(sp->win, sp->tpos+1, 1,
 		 (u_int) sp->tsize-3, (u_int) sp->tsize-3, R3D_OUT,2,
 		 sp->hi, sp->lo, sp->bg);
     }
@@ -450,8 +450,8 @@
     case DNLINE:                     /* arrows */
       pos = whereInScrl(sp,x,y);
       if (pos == ipos) {
-	if (!lit) { 
-	  lit = 1; 
+	if (!lit) {
+	  lit = 1;
 	  if (ipos == UPLINE) { sp->uplit = 1;  drawArrow(sp,UPLINE); }
 	                 else { sp->dnlit = 1;  drawArrow(sp,DNLINE); }
 	}
@@ -467,16 +467,16 @@
 	  }
 	}
       }
-      
+
       else {
-	if (lit) { 
-	  lit = 0; 
+	if (lit) {
+	  lit = 0;
 	  if (ipos == UPLINE) { sp->uplit = 0;  drawArrow(sp,UPLINE); }
 	                 else { sp->dnlit = 0;  drawArrow(sp,DNLINE); }
 	}
       }
       break;
-      
+
     }
   }
 
diff -ru xv-3.10a/xvsmooth.c xv-3.10a-enhancements/xvsmooth.c
--- xv-3.10a/xvsmooth.c	1994-12-22 14:34:42.000000000 -0800
+++ xv-3.10a-enhancements/xvsmooth.c	2004-05-16 18:07:59.000000000 -0700
@@ -4,11 +4,11 @@
  *  Contains:
  *            byte *SmoothResize(src8, swide, shigh, dwide, dhigh,
  *                               rmap, gmap, bmap, rdmap, gdmap, bdmap, maplen)
- *            byte *Smooth24(pic824, is24, swide, shigh, dwide, dhigh, 
+ *            byte *Smooth24(pic824, is24, swide, shigh, dwide, dhigh,
  *                               rmap, gmap, bmap)
- *            byte *DoColorDither(pic24, pic8, w, h, rmap,gmap,bmap, 
+ *            byte *DoColorDither(pic24, pic8, w, h, rmap,gmap,bmap,
  *                                rdisp, gdisp, bdisp, maplen)
- *            byte *Do332ColorDither(pic24, pic8, w, h, rmap,gmap,bmap, 
+ *            byte *Do332ColorDither(pic24, pic8, w, h, rmap,gmap,bmap,
  *                                rdisp, gdisp, bdisp, maplen)
  */
 
@@ -18,21 +18,21 @@
 
 static int smoothX  PARM((byte *, byte *, int, int, int, int, int,
 			  byte *, byte *, byte *));
-static int smoothY  PARM((byte *, byte *, int, int, int, int, int, 
+static int smoothY  PARM((byte *, byte *, int, int, int, int, int,
 			  byte *, byte *, byte *));
 static int smoothXY PARM((byte *, byte *, int, int, int, int, int,
 			  byte *, byte *, byte *));
 
 
 /***************************************************/
-byte *SmoothResize(srcpic8, swide, shigh, dwide, dhigh, 
+byte *SmoothResize(srcpic8, swide, shigh, dwide, dhigh,
 		   rmap, gmap, bmap, rdmap, gdmap, bdmap, maplen)
      byte *srcpic8, *rmap, *gmap, *bmap, *rdmap, *gdmap, *bdmap;
      int   swide, shigh, dwide, dhigh, maplen;
 {
-  /* generic interface to Smooth and ColorDither code.  
-     given an 8-bit-per, swide * shigh image with colormap rmap,gmap,bmap, 
-     will generate a new 8-bit-per, dwide * dhigh image, which is dithered 
+  /* generic interface to Smooth and ColorDither code.
+     given an 8-bit-per, swide * shigh image with colormap rmap,gmap,bmap,
+     will generate a new 8-bit-per, dwide * dhigh image, which is dithered
      using colors found in rdmap, gdmap, bdmap arrays */
 
   /* returns ptr to a dwide*dhigh array of bytes, or NULL on failure */
@@ -50,7 +50,7 @@
 
   return (byte *) NULL;
 }
-    
+
 
 
 /***************************************************/
@@ -83,29 +83,29 @@
   bperpix = (is24) ? 3 : 1;
 
   /* decide which smoothing routine to use based on type of expansion */
-  if      (dwide <  swide && dhigh <  shigh) 
+  if      (dwide <  swide && dhigh <  shigh)
     retval = smoothXY(pic24, pic824, is24, swide, shigh, dwide, dhigh,
 		      rmap, gmap, bmap);
 
-  else if (dwide <  swide && dhigh >= shigh) 
+  else if (dwide <  swide && dhigh >= shigh)
     retval = smoothX (pic24, pic824, is24, swide, shigh, dwide, dhigh,
 		      rmap, gmap, bmap);
 
-  else if (dwide >= swide && dhigh <  shigh) 
+  else if (dwide >= swide && dhigh <  shigh)
     retval = smoothY (pic24, pic824, is24, swide, shigh, dwide, dhigh,
 		      rmap, gmap, bmap);
 
   else {
     /* dwide >= swide && dhigh >= shigh */
 
-    /* cx,cy = original pixel in pic824.  px,py = relative position 
-       of pixel ex,ey inside of cx,cy as percentages +-50%, +-50%.  
+    /* cx,cy = original pixel in pic824.  px,py = relative position
+       of pixel ex,ey inside of cx,cy as percentages +-50%, +-50%.
        0,0 = middle of pixel */
 
     /* we can save a lot of time by precomputing cxtab[] and pxtab[], both
        dwide arrays of ints that contain values for the equations:
          cx = (ex * swide) / dwide;
-         px = ((ex * swide * 100) / dwide) - (cx * 100) - 50; */
+         px = ((ex * swide * 128) / dwide) - (cx * 128) - 64; */
 
     cxtab = (int *) malloc(dwide * sizeof(int));
     if (!cxtab) { free(pic24);  return NULL; }
@@ -115,17 +115,17 @@
 
     for (ex=0; ex<dwide; ex++) {
       cxtab[ex] = (ex * swide) / dwide;
-      pxtab[ex] = (((ex * swide)* 100) / dwide) 
-	           - (cxtab[ex] * 100) - 50;
+      pxtab[ex] = (((ex * swide)* 128) / dwide)
+	           - (cxtab[ex] * 128) - 64;
     }
-    
+
     for (ey=0; ey<dhigh; ey++) {
       byte *pptr, rA, gA, bA, rB, gB, bB, rC, gC, bC, rD, gD, bD;
 
       ProgressMeter(0, (dhigh)-1, ey, "Smooth");
 
       cy = (ey * shigh) / dhigh;
-      py = (((ey * shigh) * 100) / dhigh) - (cy * 100) - 50;
+      py = (((ey * shigh) * 128) / dhigh) - (cy * 128) - 64;
       if (py<0) { y1 = cy-1;  if (y1<0) y1=0; }
            else { y1 = cy+1;  if (y1>shigh-1) y1=shigh-1; }
 
@@ -162,7 +162,7 @@
 	  cC = pic824[cyOff + x1];   /* left/right center pixel */
 	  cD = pic824[cyOff + cx];   /* center pixel */
 	}
-	 
+
 	/* quick check */
 	if (!is24 && cA == cB && cB == cC && cC == cD) {
 	  /* set this pixel to the same color as in pic8 */
@@ -172,36 +172,36 @@
 	else {
 	  /* compute weighting factors */
 	  apx = abs(px);  apy = abs(py);
-	  pA = (apx * apy) / 100;
-	  pB = (apy * (100 - apx)) / 100;
-	  pC = (apx * (100 - apy)) / 100;
-	  pD = 100 - (pA + pB + pC);
+	  pA = (apx * apy) >> 7; /* div 128 */
+	  pB = (apy * (128 - apx)) >> 7; /* div 128 */
+	  pC = (apx * (128 - apy)) >> 7; /* div 128 */
+	  pD = 128 - (pA + pB + pC);
 
 	  if (is24) {
-	    *pp++ = ((int) (pA * rA))/100 + ((int) (pB * rB))/100 + 
-	            ((int) (pC * rC))/100 + ((int) (pD * rD))/100;
+	    *pp++ = (((int) (pA * rA))>>7) + (((int) (pB * rB))>>7) +
+	            (((int) (pC * rC))>>7) + (((int) (pD * rD))>>7);
 
-	    *pp++ = ((int) (pA * gA))/100 + ((int) (pB * gB))/100 + 
-	            ((int) (pC * gC))/100 + ((int) (pD * gD))/100;
+	    *pp++ = (((int) (pA * gA))>>7) + (((int) (pB * gB))>>7) +
+	            (((int) (pC * gC))>>7) + (((int) (pD * gD))>>7);
 
-	    *pp++ = ((int) (pA * bA))/100 + ((int) (pB * bB))/100 + 
-	            ((int) (pC * bC))/100 + ((int) (pD * bD))/100;
+	    *pp++ = (((int) (pA * bA))>>7) + (((int) (pB * bB))>>7) +
+	            (((int) (pC * bC))>>7) + (((int) (pD * bD))>>7);
 	  }
 	  else {  /* 8-bit pic */
-	    *pp++ = ((int) (pA * rmap[cA]))/100 + ((int)(pB * rmap[cB]))/100 + 
-	            ((int) (pC * rmap[cC]))/100 + ((int)(pD * rmap[cD]))/100;
+	    *pp++ = (((int)(pA * rmap[cA]))>>7) + (((int)(pB * rmap[cB]))>>7) +
+	            (((int)(pC * rmap[cC]))>>7) + (((int)(pD * rmap[cD]))>>7);
 
-	    *pp++ = ((int) (pA * gmap[cA]))/100 + ((int)(pB * gmap[cB]))/100 + 
-	            ((int) (pC * gmap[cC]))/100 + ((int)(pD * gmap[cD]))/100;
+	    *pp++ = (((int)(pA * gmap[cA]))>>7) + (((int)(pB * gmap[cB]))>>7) +
+	            (((int)(pC * gmap[cC]))>>7) + (((int)(pD * gmap[cD]))>>7);
 
-	    *pp++ = ((int)(pA * bmap[cA]))/100 + ((int)(pB * bmap[cB]))/100 + 
-  	            ((int)(pC * bmap[cC]))/100 + ((int)(pD * bmap[cD]))/100;
+	    *pp++ = (((int)(pA * bmap[cA]))>>7) + (((int)(pB * bmap[cB]))>>7) +
+  	            (((int)(pC * bmap[cC]))>>7) + (((int)(pD * bmap[cD]))>>7);
 	  }
 	}
       }
     }
 
-    free(cxtab);  
+    free(cxtab);
     free(pxtab);
     retval = 0;    /* okay */
   }
@@ -218,7 +218,7 @@
 
 
 /***************************************************/
-static int smoothX(pic24, pic824, is24, swide, shigh, dwide, dhigh, 
+static int smoothX(pic24, pic824, is24, swide, shigh, dwide, dhigh,
 		   rmap, gmap, bmap)
 byte *pic24, *pic824, *rmap, *gmap, *bmap;
 int   is24, swide, shigh, dwide, dhigh;
@@ -253,7 +253,7 @@
 
   bperpix = (is24) ? 3 : 1;
 
-  for (j=0; j<=swide; j++) 
+  for (j=0; j<=swide; j++)
     pixarr[j] = (j*dwide + (15*swide)/16) / swide;
 
   cptr = pic824;  cptr1 = cptr + swide * bperpix;
@@ -280,7 +280,7 @@
 	lbufG[j] = ((int) ((*cptr++ * pcnt0) + (*cptr1++ * pcnt1))) >> 6;
 	lbufB[j] = ((int) ((*cptr++ * pcnt0) + (*cptr1++ * pcnt1))) >> 6;
       }
-    } 
+    }
     else {  /* 8-bit input pic */
       for (j=0; j<swide; j++, cptr++, cptr1++) {
 	lbufR[j] = ((int)((rmap[*cptr]* pcnt0) + (rmap[*cptr1]* pcnt1))) >> 6;
@@ -314,8 +314,8 @@
   return 0;
 }
 
-	
-      
+
+
 
 
 
@@ -405,7 +405,7 @@
 	lbufB[j] += ((int)((bmap[*cptr]*pct0[j])+(bmap[*cptr1]*pct1[j]))) >> 6;
       }
     }
-   
+
     linecnt++;
   }
 
@@ -421,13 +421,13 @@
   return retval;
 }
 
-	
-      
+
+
 
 
 
 /***************************************************/
-static int smoothXY(pic24, pic824, is24, swide, shigh, dwide, dhigh, 
+static int smoothXY(pic24, pic824, is24, swide, shigh, dwide, dhigh,
 		    rmap, gmap, bmap)
 byte *pic24, *pic824, *rmap, *gmap, *bmap;
 int   is24, swide, shigh, dwide, dhigh;
@@ -462,7 +462,7 @@
 
   bperpix = (is24) ? 3 : 1;
 
-  for (j=0; j<=swide; j++) 
+  for (j=0; j<=swide; j++)
     pixarr[j] = (j*dwide + (15*swide)/16) / swide;
 
   lastline = linecnt = pixR = pixG = pixB = 0;
@@ -526,20 +526,20 @@
   return 0;
 }
 
-	
-      
+
+
 
 /********************************************/
-byte *DoColorDither(pic24, pic8, w, h, rmap, gmap, bmap, 
+byte *DoColorDither(pic24, pic8, w, h, rmap, gmap, bmap,
 		    rdisp, gdisp, bdisp, maplen)
      byte *pic24, *pic8, *rmap, *gmap, *bmap, *rdisp, *gdisp, *bdisp;
      int   w, h, maplen;
 {
   /* takes a 24 bit picture, of size w*h, dithers with the colors in
      rdisp, gdisp, bdisp (which have already been allocated),
-     and generates an 8-bit w*h image, which it returns.  
+     and generates an 8-bit w*h image, which it returns.
      ignores input value 'pic8'
-     returns NULL on error 
+     returns NULL on error
 
      note: the rdisp,gdisp,bdisp arrays should be the 'displayed' colors,
      not the 'desired' colors
@@ -547,7 +547,7 @@
      if pic24 is NULL, uses the passed-in pic8 (an 8-bit image) as
      the source, and the rmap,gmap,bmap arrays as the desired colors */
 
-  byte *np, *ep, *newpic; 
+  byte *np, *ep, *newpic;
   short *cache;
   int r2, g2, b2;
   int *thisline, *nextline, *thisptr, *nextptr, *tmpptr;
@@ -558,11 +558,11 @@
   int fserrmap[512];   /* -255 .. 0 .. +255 */
 
   /* compute somewhat non-linear floyd-steinberg error mapping table */
-  for (i=j=0; i<=0x40; i++,j++) 
+  for (i=j=0; i<=0x40; i++,j++)
     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }
-  for (     ; i<0x80; i++, j += !(i&1) ? 1 : 0) 
+  for (     ; i<0x80; i++, j += !(i&1) ? 1 : 0)
     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }
-  for (     ; i<=0xff; i++) 
+  for (     ; i<=0xff; i++)
     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }
 
 
@@ -575,7 +575,7 @@
   cache  = (short *) calloc((size_t) (2<<14), sizeof(short));
   thisline = (int *) malloc(pwide3 * sizeof(int));
   nextline = (int *) malloc(pwide3 * sizeof(int));
-  if (!cache || !newpic || !thisline || !nextline) { 
+  if (!cache || !newpic || !thisline || !nextline) {
     if (newpic)   free(newpic);
     if (cache)    free(cache);
     if (thisline) free(thisline);
@@ -624,30 +624,30 @@
 
       r2 = *thisptr++;  g2 = *thisptr++;  b2 = *thisptr++;
 
-      /* map r2,g2,b2 components (could be outside 0..255 range) 
+      /* map r2,g2,b2 components (could be outside 0..255 range)
 	 into 0..255 range */
-      
+
       if (r2<0 || g2<0 || b2<0) {   /* are there any negatives in RGB? */
 	if (r2<g2) { if (r2<b2) k = 0; else k = 2; }
 	else { if (g2<b2) k = 1; else k = 2; }
 
 	switch (k) {
 	case 0:  g2 -= r2;  b2 -= r2;  d = (abs(r2) * 3) / 2;    /* RED */
-	         r2 = 0;  
+	         r2 = 0;
 	         g2 = (g2>d) ? g2 - d : 0;
 	         b2 = (b2>d) ? b2 - d : 0;
 	         break;
 
 	case 1:  r2 -= g2;  b2 -= g2;  d = (abs(g2) * 3) / 2;    /* GREEN */
 	         r2 = (r2>d) ? r2 - d : 0;
-	         g2 = 0;  
+	         g2 = 0;
 	         b2 = (b2>d) ? b2 - d : 0;
 	         break;
 
 	case 2:  r2 -= b2;  g2 -= b2;  d = (abs(b2) * 3) / 2;    /* BLUE */
 	         r2 = (r2>d) ? r2 - d : 0;
 	         g2 = (g2>d) ? g2 - d : 0;
-	         b2 = 0;  
+	         b2 = 0;
 	         break;
 	}
       }
@@ -674,7 +674,7 @@
         mind = 10000;
 	for (k=closest=0; k<maplen && mind>7; k++) {
 	  d = abs(r2 - rdisp[k])
-	    + abs(g2 - gdisp[k]) 
+	    + abs(g2 - gdisp[k])
 	    + abs(b2 - bdisp[k]);
 	  if (d<mind) { mind = d;  closest = k; }
 	}
@@ -703,7 +703,7 @@
 	thisptr[1] += (gerr*7)/16;
 	thisptr[2] += (berr*7)/16;
       }
-      
+
       if (i!=imax) {	/* do BOTTOM pixel */
 	nextptr[0] += (rerr*5)/16;
 	nextptr[1] += (gerr*5)/16;
@@ -735,7 +735,7 @@
 
 
 /********************************************/
-byte *Do332ColorDither(pic24, pic8, w, h, rmap, gmap, bmap, 
+byte *Do332ColorDither(pic24, pic8, w, h, rmap, gmap, bmap,
 		    rdisp, gdisp, bdisp, maplen)
      byte *pic24, *pic8, *rmap, *gmap, *bmap, *rdisp, *gdisp, *bdisp;
      int   w, h, maplen;
@@ -744,9 +744,9 @@
 
   /* takes a 24 bit picture, of size w*h, dithers with the colors in
      rdisp, gdisp, bdisp (which have already been allocated),
-     and generates an 8-bit w*h image, which it returns.  
+     and generates an 8-bit w*h image, which it returns.
      ignores input value 'pic8'
-     returns NULL on error 
+     returns NULL on error
 
      note: the rdisp,gdisp,bdisp arrays should be the 'displayed' colors,
      not the 'desired' colors
@@ -754,7 +754,7 @@
      if pic24 is NULL, uses the passed-in pic8 (an 8-bit image) as
      the source, and the rmap,gmap,bmap arrays as the desired colors */
 
-  byte *np, *ep, *newpic; 
+  byte *np, *ep, *newpic;
   int r2, g2, b2;
   int *thisline, *nextline, *thisptr, *nextptr, *tmpptr;
   int  i, j, rerr, gerr, berr, pwide3;
@@ -763,11 +763,11 @@
   int  fserrmap[512];   /* -255 .. 0 .. +255 */
 
   /* compute somewhat non-linear floyd-steinberg error mapping table */
-  for (i=j=0; i<=0x40; i++,j++) 
+  for (i=j=0; i<=0x40; i++,j++)
     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }
-  for (     ; i<0x80; i++, j += !(i&1) ? 1 : 0) 
+  for (     ; i<0x80; i++, j += !(i&1) ? 1 : 0)
     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }
-  for (     ; i<=0xff; i++) 
+  for (     ; i<=0xff; i++)
     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }
 
 
@@ -778,7 +778,7 @@
   newpic   = (byte *) malloc((size_t) (w * h));
   thisline = (int *)  malloc(pwide3 * sizeof(int));
   nextline = (int *)  malloc(pwide3 * sizeof(int));
-  if (!newpic || !thisline || !nextline) { 
+  if (!newpic || !thisline || !nextline) {
     if (newpic)   free(newpic);
     if (thisline) free(thisline);
     if (nextline) free(nextline);
@@ -830,7 +830,7 @@
 
 
     for (j=0; j<w; j++) {
-      int k, d, mind, closest, rb,gb,bb;
+      int rb,gb,bb;
 
       r2 = *thisptr++;  g2 = *thisptr++;  b2 = *thisptr++;
       if (i&1) thisptr -= 6;  /* move left */
@@ -846,7 +846,7 @@
       bb = (b2 + 0x20);    /* round 2 bits */
       RANGE(bb,0,255);
       bb = bb & 0xc0;
-      
+
 
       *np = rb | (gb>>3) | (bb>>6);
 
diff -ru xv-3.10a/xvsunras.c xv-3.10a-enhancements/xvsunras.c
--- xv-3.10a/xvsunras.c	1994-12-22 14:34:42.000000000 -0800
+++ xv-3.10a-enhancements/xvsunras.c	2007-05-13 17:46:42.000000000 -0700
@@ -39,7 +39,7 @@
 #define RAS_RLE 0x80
 
 
-static int  sunRasError    PARM((char *, char *));
+static int  sunRasError    PARM((const char *, const char *));
 static int  rle_read       PARM((byte *, int, int, FILE *, int));
 static void sunRas1to8     PARM((byte *, byte *, int));
 static void sunRas8to1     PARM((byte *, byte *, int, int));
@@ -54,10 +54,10 @@
      PICINFO *pinfo;
 {
   FILE	*fp;
-  int	 linesize,lsize,csize,isize,i,w,h,d;
-  byte	 *image, *line, *pic8;
+  int	 linesize,lsize,csize,isize,i,w,h,d,npixels,nbytes;
+  byte	 *image, *line;
   struct rasterfile sunheader;
-  char   *bname;
+  const char *bname;
 
   bname = BaseName(fname);
 
@@ -85,7 +85,7 @@
       sunheader.ras_depth != 8 &&
       sunheader.ras_depth != 24 &&
       sunheader.ras_depth != 32) {
-    fprintf (stderr, "Sun rasterfile image has depth %d\n", 
+    fprintf (stderr, "Sun rasterfile image has depth %d\n",
 	     sunheader.ras_depth);
     fprintf (stderr, "Depths supported are 1, 8, 24, and 32\n");
     fclose(fp);
@@ -115,26 +115,59 @@
 
   w = sunheader.ras_width;
   h = sunheader.ras_height;
-  d = sunheader.ras_depth;
-  isize = sunheader.ras_length ?
-	  sunheader.ras_length :
-	  (w * h * d) / 8;
+  d = sunheader.ras_depth;  /* 1, 8, 24, or 32 (above) */
+  npixels = w * h;
+  if (w <= 0 || h <= 0 || npixels/w != h) {
+    fprintf (stderr, "Sun rasterfile image has invalid dimensions (%dx%d)\n",
+	     w, h);
+    fclose(fp);
+    return 0;
+  }
+  if (d == 1)
+    nbytes = npixels/8;     /* should round up here, but used only for printf */
+  else {
+    nbytes = npixels * (d/8);
+/*
+    [nbytes (isize) used only in printfs; don't really care about overflows]
+    if (nbytes/npixels != (d/8)) {
+      fprintf (stderr, "Sun rasterfile has invalid dimensions (%dx%dx%d)\n",
+	       w, h, d);
+      fclose(fp);
+      return 0;
+    }
+ */
+  }
+  isize = sunheader.ras_length ? sunheader.ras_length : nbytes;
   csize = (sunheader.ras_maptype == RMT_NONE) ? 0 : sunheader.ras_maplength;
 
 
-  /* compute length of the output (xv-format) image */
-  lsize = w * h;     
-  if (d == 24 || d == 32) lsize = lsize * 3;
+  /* length of the output (xv-format) image */
+  lsize = npixels;
+  if (d == 24 || d == 32) {
+    lsize *= 3;
+    if (lsize/3 != npixels) {
+      fprintf (stderr, "Sun rasterfile has invalid dimensions (%dx%dx%d)\n",
+	       w, h, d);
+      fclose(fp);
+      return 0;
+    }
+  }
 
 
   linesize = w * d;
+  if (linesize/w != d || linesize + 15 < linesize) {
+    fprintf (stderr, "Sun rasterfile has invalid dimensions (%dx%dx%d)\n",
+	     w, h, d);
+    fclose(fp);
+    return 0;
+  }
   if (linesize % 16) linesize += (16 - (linesize % 16));
   linesize /= 8;
 
   if (DEBUG) {
     fprintf(stderr,"%s: LoadSunRas() - loading a %dx%d pic, %d planes\n",
 	    cmd, w, h, d);
-    fprintf (stderr, 
+    fprintf (stderr,
 	  "type %d, maptype %d, isize %d, csize %d, lsize %d, linesize %d\n",
 	     sunheader.ras_type, sunheader.ras_maptype,
 	     isize, csize, lsize, linesize);
@@ -188,13 +221,13 @@
     }
 
     switch (d) {
-    case 1:  sunRas1to8 (image + w * i, line, w);	                
+    case 1:  sunRas1to8 (image + w * i, line, w);
              break;
     case 8:  xvbcopy((char *) line, (char *) image + w * i, (size_t) w);
              break;
     case 24: xvbcopy((char *) line, (char *) image + w * i * 3, (size_t) w*3);
              break;
-      
+
     case 32:
       {
 	int k;
@@ -202,7 +235,7 @@
 	ip = line;
 	op = (byte *) (image + w * i * 3);
 	for (k = 0; k<w; k++) {
-	  *ip++;           /* skip 'alpha' */
+	  ip++;            /* skip 'alpha' */
 	  *op++ = *ip++;   /* red   */
 	  *op++ = *ip++;   /* green */
 	  *op++ = *ip++;   /* blue  */
@@ -210,9 +243,9 @@
       }
     }
   }
-  
+
   free(line);
-  
+
   if (DEBUG) fprintf(stderr,"Sun ras: image loaded!\n");
 
 
@@ -224,7 +257,7 @@
   else pinfo->type = PIC8;
 
   pinfo->pic = image;
-  pinfo->w = w;  
+  pinfo->w = w;
   pinfo->h = h;
   pinfo->normw = pinfo->w;   pinfo->normh = pinfo->h;
   pinfo->frmType = F_SUNRAS;
@@ -285,7 +318,7 @@
 
 /*****************************/
 static int sunRasError(fname, st)
-     char *fname, *st;
+     const char *fname, *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", fname, st);
   return 0;
@@ -364,10 +397,15 @@
 
   /* special case: if PIC24 and writing GREYSCALE, write 8-bit file */
   if (ptype == PIC24  && colorstyle == F_GREYSCALE) {
-    graypic = (byte *) malloc((size_t) w*h);
+    int npixels = w * h;
+    if (w <= 0 || h <= 0 || npixels/w != h) {
+      SetISTR(ISTR_WARNING, "Image is too large (%dx%d)", w, h);
+      return (2);
+    }
+    graypic = (byte *) malloc((size_t) npixels);
     if (!graypic) FatalError("unable to malloc in WriteSunRas()");
-    
-    for (i=0,sp=pic,dp=graypic; i<w*h; i++,sp+=3,dp++) {
+
+    for (i=0,sp=pic,dp=graypic; i<npixels; i++,sp+=3,dp++) {
       *dp = MONO(sp[0],sp[1],sp[2]);
     }
 
@@ -379,9 +417,18 @@
   }
 
 
-  if      (ptype==PIC24)    { d = 24;  linesize = w * 3; }
-  else if (colorstyle != F_BWDITHER) { d = 8;   linesize = w;     }
-  else { 
+  if (ptype==PIC24) {
+    d = 24;
+    linesize = w * 3;
+    if (linesize/w != 3) {
+      SetISTR(ISTR_WARNING, "Image is too wide (%d)", w);
+      if (graypic) free(graypic);
+      return (2);
+    }
+  } else if (colorstyle != F_BWDITHER) {
+    d = 8;
+    linesize = w;
+  } else {
     d = 1;
     linesize = w;
     if (linesize % 8) linesize += (8 - linesize % 8);
@@ -391,6 +438,11 @@
 
 
   if (linesize % 2) linesize++;
+  if (linesize == 0) {
+    SetISTR(ISTR_WARNING, "Image is too wide (%d)", w);
+    if (graypic) free(graypic);
+    return (2);
+  }
   line = (byte *) malloc((size_t) linesize);
   if (!line) {
     SetISTR(ISTR_WARNING, "Can't allocate memory for save!\n");
@@ -428,7 +480,7 @@
   write_sun_long (sunheader.ras_maplength, fp);
 
   /* write the colormap */
-  if (d == 8)
+  if (d == 8) {
     if (colorstyle == 1)  /* grayscale */
       for (color=0; color<3; color++)
 	for (i=0; i<numcols; i++)
@@ -438,6 +490,7 @@
       fwrite (gmap, sizeof(byte), (size_t) numcols, fp);
       fwrite (bmap, sizeof(byte), (size_t) numcols, fp);
     }
+  }
 
 
   /* write the image */
diff -ru xv-3.10a/xvtarga.c xv-3.10a-enhancements/xvtarga.c
--- xv-3.10a/xvtarga.c	1994-12-22 14:34:55.000000000 -0800
+++ xv-3.10a-enhancements/xvtarga.c	2007-05-13 17:51:18.000000000 -0700
@@ -17,8 +17,8 @@
  *   0:
  *   1: colormap type
  *   2: image type  (1=colmap RGB, 2=uncomp RGB, 3=uncomp gray)
- *   3: 
- *   4: 
+ *   3:
+ *   4:
  *   5: colormap_length, low byte
  *   6: colormap_length, high byte
  *   7: bits per cmap entry     (8, 24, 32)
@@ -28,7 +28,7 @@
  *  14: height, low byte
  *  15: height, high byte
  *  16: bits per pixel (8, 24)
- *  17: flags  
+ *  17: flags
  */
 
 
@@ -36,7 +36,7 @@
 #include "xv.h"
 
 static long filesize;
-static char *bname;
+static const char *bname;
 
 
 /*******************************************/
@@ -48,7 +48,7 @@
   /* returns '1' on success */
 
   FILE  *fp;
-  int    i, row, c, c1, w, h, r, g, b, flags, intlace, topleft, trunc;
+  int    i, row, c, c1, w, h, npixels, bufsize, flags, intlace, topleft, trunc;
   byte *pic24, *pp;
 
   bname = BaseName(fname);
@@ -88,7 +88,9 @@
   c=getc(fp); c1=getc(fp);
   h = c1*256 + c;
 
-  if (w<1 || h<1) {
+  npixels = w * h;
+  bufsize = 3 * npixels;
+  if (w <= 0 || h <= 0 || npixels/w != h || bufsize/3 != npixels) {
     fclose(fp);
     SetISTR(ISTR_WARNING,"%s:  error in Targa header (bad image size)", bname);
     return 0;
@@ -115,7 +117,7 @@
 #endif
 
 
-  pic24 = (byte *) calloc((size_t) w*h*3, (size_t) 1);
+  pic24 = (byte *) calloc((size_t) bufsize, (size_t) 1);
   if (!pic24) FatalError("couldn't malloc 'pic24'");
 
 
@@ -134,7 +136,7 @@
       if      (i < h / 2) row = 2 * i;
       else                row = 2 * (i - h/2) + 1;
     }
-    
+
     else row = i;              /* no interlace */
 
 
@@ -150,7 +152,7 @@
 
 
   /* swap R,B values (file is in BGR, pic24 should be in RGB) */
-  for (i=0, pp=pic24; i<w*h; i++, pp+=3) {
+  for (i=0, pp=pic24; i<npixels; i++, pp+=3) {
     c = pp[0];  pp[0] = pp[2];  pp[2] = c;
   }
 
@@ -185,7 +187,7 @@
 
   /* write the header */
   for (i=0; i<12; i++) putc( (i==2) ? 2 : 0, fp);
-  
+
   putc(w&0xff,     fp);
   putc((w>>8)&0xff,fp);
   putc(h&0xff,     fp);
diff -ru xv-3.10a/xvtext.c xv-3.10a-enhancements/xvtext.c
--- xv-3.10a/xvtext.c	1995-01-13 15:46:28.000000000 -0800
+++ xv-3.10a-enhancements/xvtext.c	2007-05-13 14:25:59.000000000 -0700
@@ -1,6 +1,6 @@
 /*
  *  xvtext.c  -  text file display window routines
- * 
+ *
  *  includes:
  *      void CreateTextWins(geom, cmtgeom);
  *      void OpenTextView(text, textlen, title, freeonclose);
@@ -19,9 +19,13 @@
 #include "copyright.h"
 
 #include "xv.h"
+#ifdef TV_MULTILINGUAL
+#include "xvml.h"
+#endif
 
-
-#define BUTTW 80
+#define BUTTW1 80
+#define BUTTW2 60
+#define BUTTW3 110
 #define BUTTH 24
 
 #define TOPMARGIN 30       /* from top of window to top of text window */
@@ -36,19 +40,36 @@
 #define TV_ASCII    0
 #define TV_HEX      1
 #define TV_CLOSE    2
-#define TV_NBUTTS   3
 
+#define TV_E_NBUTTS 3
+
+#ifdef TV_L10N
+#  define TV_RESCAN   3
+#  define TV_USASCII  4
+#  define TV_JIS      5
+#  define TV_EUCJ     6
+#  define TV_MSCODE   7
+
+#  define TV_J_NBUTTS 8
+#endif
 
 #define TITLELEN 128
 
+#ifdef TV_MULTILINGUAL
+struct coding_spec {
+    struct coding_system coding_system;
+    char *(*converter)PARM((char *, int, int *));
+};
+#endif
+
 /* data needed per text window */
 typedef struct {  Window win, textW;
 		  int    vis, wasvis;
-		  char  *text;             /* text to be displayed */
+		  const char  *text;       /* text to be displayed */
 		  int    freeonclose;      /* free text when closing win */
 		  int    textlen;          /* length of text */
 		  char   title[TITLELEN];  /* name of file being displayed */
-		  char **lines;            /* ptr to array of line ptrs */
+		  const char **lines;     /* ptr to array of line ptrs */
 		  int    numlines;         /* # of lines in text */
 		  int    hexlines;         /* # of lines in HEX mode */
 		  int    maxwide;          /* length of longest line (ascii) */
@@ -57,16 +78,89 @@
 		  int    chwide, chhigh;   /* size of textW, in chars */
 		  int    hexmode;          /* true if disp Hex, else Ascii */
 		  SCRL   vscrl, hscrl;
-		  BUTT   but[TV_NBUTTS], nopBut;
+#ifdef TV_L10N
+		  int    code;         /* current character code */
+		  BUTT   but[TV_J_NBUTTS], nopBut;
+#else
+		  BUTT   but[TV_E_NBUTTS], nopBut;
+#endif
+#ifdef TV_MULTILINGUAL
+/*		  int    codeset; */
+		  struct coding_spec ccs;	/* current coding_spec */
+		  BUTT   csbut;
+		  char *cv_text;
+		  int cv_len;
+		  struct context *ctx;
+		  struct ml_text *txt;
+		  struct csinfo_t *cs;
+#endif
 		} TVINFO;
 
 
 static TVINFO   tinfo[MAXTVWIN];
 static int      hasBeenSized = 0;
 static int      haveWindows  = 0;
+static int      nbutts;		/* # of buttons */
 static int      mfwide, mfhigh, mfascent;   /* size of chars in mono font */
 static int     *event_retP, *event_doneP;   /* used in tvChkEvent() */
-
+#ifdef TV_MULTILINGUAL
+# define TV_PLAIN          0
+# define TV_ISO_8859_1     1
+# define TV_ISO_2022_JP    2
+# define TV_EUC_JAPAN      3
+# define TV_ISO_2022_INT_1 4
+# define TV_ISO_2022_KR    5
+# define TV_EUC_KOREA      6
+# define TV_ISO_2022_SS2_8 7
+# define TV_ISO_2022_SS2_7 8
+# define TV_SHIFT_JIS      9
+# define TV_NCSS          10
+static char *codeSetNames[TV_NCSS] = {
+    "plain",
+    "iso-8859-1",
+    "iso-2022-jp",
+    "euc-japan",
+    "iso-2022-int-1",
+    "iso-2022-kr",
+    "euc-korea",
+    "iso-2022-ss2-8",
+    "iso-2022-ss2-7",
+    "Shift JIS",
+};
+static struct coding_spec coding_spec[TV_NCSS] = {
+    /* --- G0 ---   --- G1 ---   --- G2 ---   --- G3 ---  GL GR EOL SF LS */
+    /* plain */
+    {{{{ 1,94,'B'}, { 1,94,'B'}, { 1,94,'B'}, { 1,94,'B'}}, 0, 0,  0, 1, 1},
+     NULL},
+    /* iso-8859-1 */
+    {{{{ 1,94,'B'}, { 1,96,'A'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 1,  0, 0, 0},
+     NULL},
+    /* iso-2022-jp */
+    {{{{ 1,94,'B'}, {-1,94,'B'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 0,  0, 1, 0},
+     NULL},
+    /* euc-japan */
+    {{{{ 1,94,'B'}, { 2,94,'B'}, { 1,94,'J'}, { 2,94,'D'}}, 0, 1,  0, 1, 0},
+     NULL},
+    /* iso-2022-int-1 */
+    {{{{ 1,94,'B'}, { 2,94,'C'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 1,  0, 1, 1},
+     NULL},
+    /* iso-2022-kr */
+    {{{{ 1,94,'B'}, { 2,94,'C'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 1,  0, 0, 1},
+     NULL},
+    /* euc-korea */
+    {{{{ 1,94,'B'}, { 2,94,'C'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 1,  0, 0, 0},
+     NULL},
+    /* iso-2022-ss2-8 */
+    {{{{ 1,94,'B'}, {-1,94,'C'}, { 0,94,'B'}, {-1,94,'B'}}, 0, 1,  0, 0, 0},
+     NULL},
+    /* iso-2022-ss2-7 */
+    {{{{ 1,94,'B'}, {-1,94,'C'}, { 0,94,'B'}, {-1,94,'B'}}, 0, 1,  0, 1, 0},
+     NULL},
+    /* shift jis */
+    {{{{ 1,94,'B'}, { 2,94,'B'}, { 1,94,'J'}, { 2,94,'D'}}, 0, 1,  1, 1, 0},
+     sjis_to_jis},
+};
+#endif
 
 static void closeText       PARM((TVINFO *));
 static int  tvChkEvent      PARM((TVINFO *, XEvent *));
@@ -82,7 +176,15 @@
 static void textKey         PARM((TVINFO *, int));
 static void doHexAsciiCmd   PARM((TVINFO *, int));
 static void computeText     PARM((TVINFO *));
-
+#ifdef TV_L10N
+static int  selectCodeset         PARM((TVINFO *));
+#endif
+#ifdef TV_MULTILINGUAL
+static void setCodingSpec   PARM((TVINFO *, struct coding_spec *));
+static void createCsWins    PARM((char *));
+static void openCsWin       PARM((TVINFO *));
+static void closeCsWin      PARM((TVINFO *));
+#endif
 
 /* HEXMODE output looks like this:
 0x00000000: 00 11 22 33 44 55 66 77 - 88 99 aa bb cc dd ee ff  0123456789abcdef
@@ -92,19 +194,57 @@
 
 /***************************************************************/
 void CreateTextWins(geom, cmtgeom)
-     char *geom, *cmtgeom;
+     const char *geom, *cmtgeom;
 {
   int                   i, defwide, defhigh, cmthigh;
   XSizeHints            hints;
   XSetWindowAttributes  xswa;
   TVINFO               *tv;
-  int                   gx,gy,gw,gh,gset,gx1,gy1;
-  
+#ifdef TV_MULTILINGUAL
+  int			default_codeset;
+#endif
+
+#ifdef TV_L10N
+  if (!xlocale) {
+#endif
+      mfwide = monofinfo->max_bounds.width;
+      mfhigh = monofinfo->ascent + monofinfo->descent;
+      mfascent = monofinfo->ascent;
+
+      nbutts = TV_E_NBUTTS;	/* # of buttons */
+#ifdef TV_L10N
+  }
+  else {
+      mfwide = monofsetinfo->max_logical_extent.width / 2;	/* shit! */
+      mfhigh = monofsetinfo->max_logical_extent.height + 1;
+      mfascent = mfhigh;
 
-  mfwide = monofinfo->max_bounds.width;
-  mfhigh = monofinfo->ascent + monofinfo->descent;
-  mfascent = monofinfo->ascent;
+      nbutts = TV_J_NBUTTS;	/* # of buttons */
+  }
+#endif
 
+#ifdef TV_MULTILINGUAL
+  {
+    char *dc = XGetDefault(theDisp, "xv", "codeSet");
+    if (dc == NULL)
+      default_codeset = TV_DEFAULT_CODESET;
+    else {
+      for (i = 0; i < TV_NCSS; i++) {
+	if (strcmp(dc, codeSetNames[i]) == 0)
+	  break;
+      }
+      if (i >= TV_NCSS) {
+        if (strcmp(dc, "iso-2022") == 0)
+	  default_codeset = TV_PLAIN;
+	else {
+	  SetISTR(ISTR_WARNING, "%s: unknown codeset.", dc);
+	  default_codeset = TV_PLAIN;
+	}
+      } else
+	default_codeset = i;
+    }
+  }
+#endif
   /* compute default size of textview windows.  should be big enough to
      hold an 80x24 text window */
 
@@ -119,11 +259,19 @@
   for (i=0; i<MAXTVWIN; i++) {
     tv = &tinfo[i];
 
+#ifdef TV_MULTILINGUAL
+    tv->ctx = ml_create_context(ScreenOfDisplay(theDisp, theScreen));
+    tv->txt = NULL;
+    tv->cv_text = NULL;
+    tv->cv_len = 0;
+    ml_set_charsets(tv->ctx, &coding_spec[TV_PLAIN].coding_system);
+#endif
+
     tv->win = CreateWindow((i<CMTWIN) ? "xv text viewer" : "xv image comments",
-			   "XVtextview", 
-			   (i<CMTWIN) ? geom : cmtgeom, 
-			   defwide, 
-			   (i<CMTWIN) ? defhigh : cmthigh, 
+			   "XVtextview",
+			   (i<CMTWIN) ? geom : cmtgeom,
+			   defwide,
+			   (i<CMTWIN) ? defhigh : cmthigh,
 			   infofg, infobg, 1);
     if (!tv->win) FatalError("can't create textview window!");
 
@@ -135,17 +283,17 @@
 
     /* note: everything is sized and positioned in resizeText() */
 
-    tv->textW = XCreateSimpleWindow(theDisp, tv->win, 1,1, 100,100, 
+    tv->textW = XCreateSimpleWindow(theDisp, tv->win, 1,1, 100,100,
 				     1,infofg,infobg);
     if (!tv->textW) FatalError("can't create textview text window!");
 
-    SCCreate(&(tv->vscrl), tv->win, 0,0, 1,100, 0,0,0,0, 
+    SCCreate(&(tv->vscrl), tv->win, 0,0, 1,100, 0,0,0,0,
 	     infofg, infobg, hicol, locol, drawTextW);
 
-    SCCreate(&(tv->hscrl), tv->win, 0,0, 0,100, 0,0,0,0, 
+    SCCreate(&(tv->hscrl), tv->win, 0,0, 0,100, 0,0,0,0,
 	     infofg, infobg, hicol, locol, drawTextW);
 
-    if (XGetNormalHints(theDisp, tv->win, &hints)) 
+    if (XGetNormalHints(theDisp, tv->win, &hints))
       hints.flags |= PMinSize;
     else
       hints.flags = PMinSize;
@@ -162,74 +310,115 @@
 
     XSelectInput(theDisp, tv->textW, ExposureMask | ButtonPressMask);
 
-    
-    BTCreate(&(tv->but[TV_ASCII]), tv->win, 0,0,BUTTW,BUTTH,
+
+    BTCreate(&(tv->but[TV_ASCII]), tv->win, 0,0,BUTTW1,BUTTH,
 	     "Ascii",infofg,infobg,hicol,locol);
-    BTCreate(&(tv->but[TV_HEX]), tv->win, 0,0,BUTTW,BUTTH,
+    BTCreate(&(tv->but[TV_HEX]), tv->win, 0,0,BUTTW1,BUTTH,
 	     "Hex",infofg,infobg,hicol,locol);
-    BTCreate(&(tv->but[TV_CLOSE]), tv->win, 0,0,BUTTW,BUTTH,
+    BTCreate(&(tv->but[TV_CLOSE]), tv->win, 0,0,BUTTW1,BUTTH,
 	     "Close",infofg,infobg,hicol,locol);
 
+#ifdef TV_L10N
+    if (xlocale) {
+	BTCreate(&(tv->but[TV_RESCAN]), tv->win, 0,0,BUTTW2,BUTTH,
+		 "RESCAN",infofg,infobg,hicol,locol);
+	BTCreate(&(tv->but[TV_USASCII]), tv->win, 0,0,BUTTW2,BUTTH,
+		 "ASCII",infofg,infobg,hicol,locol);
+	BTCreate(&(tv->but[TV_JIS]), tv->win, 0,0,BUTTW2,BUTTH,
+		 "JIS",infofg,infobg,hicol,locol);
+	BTCreate(&(tv->but[TV_EUCJ]), tv->win, 0,0,BUTTW2,BUTTH,
+		 "EUC-j",infofg,infobg,hicol,locol);
+	BTCreate(&(tv->but[TV_MSCODE]), tv->win, 0,0,BUTTW2,BUTTH,
+		 "MS Kanji",infofg,infobg,hicol,locol);
+    }
+#endif
+
     BTCreate(&(tv->nopBut), tv->win, 0,0, (u_int) tv->vscrl.tsize+1,
 	     (u_int) tv->vscrl.tsize+1, "", infofg, infobg, hicol, locol);
     tv->nopBut.active = 0;
 
     XMapSubwindows(theDisp, tv->win);
 
+#ifdef TV_MULTILINGUAL
+    BTCreate(&tv->csbut, tv->win, 0, 0, BUTTW1, BUTTH, "Code Sets",
+	     infofg, infobg, hicol, locol);
+#endif
+
     tv->text = (char *) NULL;
     tv->textlen = 0;
     tv->title[0] = '\0';
+#ifdef TV_L10N
+    tv->code = (xlocale ? LOCALE_DEFAULT : 0);
+#endif
+#ifdef TV_MULTILINGUAL
+    tv->ccs = coding_spec[default_codeset];
+#endif
   }
-
+#ifdef TV_MULTILINGUAL
+  get_monofont_size(&mfwide, &mfhigh);
+  /* recalculate sizes. */
+  defwide = 80 * mfwide + 2*LRMARGINS + 8 + 20;   /* -ish */
+  defhigh = 24 * mfhigh + TOPMARGIN + BOTMARGIN + 8 + 20;   /* ish */
+  cmthigh = 6  * mfhigh + TOPMARGIN + BOTMARGIN + 8 + 20;   /* ish */
+#endif
 
   for (i=0; i<MAXTVWIN; i++) {
     resizeText(&tinfo[i], defwide, (i<CMTWIN) ? defhigh : cmthigh);
 
-    XSelectInput(theDisp, tinfo[i].win, ExposureMask | ButtonPressMask | 
+    XSelectInput(theDisp, tinfo[i].win, ExposureMask | ButtonPressMask |
 		 KeyPressMask | StructureNotifyMask);
   }
 
   hasBeenSized = 1;  /* we can now start looking at textview events */
 
+#ifdef TV_MULTILINGUAL
+  createCsWins("+100+100");
+#endif
 }
 
 
 /***************************************************************/
-void TextView(fname)
-     char *fname;
+int TextView(fname)
+     const char *fname;
 {
   /* given a filename, attempts to read in the file and open a textview win */
 
-  int   i;
+  int   filetype;
   long  textlen;
   char *text, buf[512], title[128], rfname[MAXPATHLEN+1];
   char *basefname[128];  /* just current fname, no path */
   FILE *fp;
+  char filename[MAXPATHLEN+1];
+
+  strncpy(filename, fname, sizeof(filename) - 1);
+#ifdef AUTO_EXPAND
+  Mkvdir(filename);
+  Dirtovd(filename);
+#endif
 
   basefname[0] = '\0';
-  strcpy(rfname, fname);
+  strncpy(rfname, filename, sizeof(rfname) - 1);
 
   /* see if this file is compressed.  if it is, uncompress it, and view
      the uncompressed version */
 
-  if (ReadFileType(fname) == RFT_COMPRESS) {
+  filetype = ReadFileType(filename);
+  if ((filetype == RFT_COMPRESS) || (filetype == RFT_BZIP2)) {
 #ifndef VMS
-    if (!UncompressFile(fname, rfname)) return;    /* failed to uncompress */
+    if (!UncompressFile(filename, rfname, filetype)) return FALSE;
 #else
     /* chop off trailing '.Z' from friendly displayed basefname, if any */
-    strcpy (basefname, fname);
+    strncpy (basefname, filename, 128 - 1);
     *rindex (basefname, '.') = '\0';
-    if (!UncompressFile(basefname, rfname)) return;/* failed to uncompress */
+    if (!UncompressFile(basefname, rfname, filetype)) return FALSE;
 #endif
   }
-      
-
 
   fp = fopen(rfname, "r");
   if (!fp) {
     sprintf(buf,"Couldn't open '%s':  %s", rfname, ERRSTR(errno));
     ErrPopUp(buf,"\nOh well");
-    return;
+    return FALSE;
   }
 
 
@@ -241,16 +430,16 @@
     sprintf(buf, "File '%s' contains no data.  (Zero length file.)", rfname);
     ErrPopUp(buf, "\nOk");
     fclose(fp);
-    return;
+    return FALSE;
   }
 
-  text = (char *) malloc((size_t) textlen);
+  text = (char *) malloc((size_t) textlen + 1);
   if (!text) {
-    sprintf(buf, "Couldn't malloc %ld bytes to read file '%s'", 
+    sprintf(buf, "Couldn't malloc %ld bytes to read file '%s'",
 	    textlen, rfname);
     ErrPopUp(buf, "\nSo what!");
     fclose(fp);
-    return;
+    return FALSE;
   }
 
   if (fread(text, (size_t) 1, (size_t) textlen, fp) != textlen) {
@@ -258,6 +447,9 @@
 	    rfname);
     ErrPopUp(buf, "\nHmm...");
   }
+#ifdef TV_MULTILINGUAL
+  text[textlen] = '\0';
+#endif
 
   fclose(fp);
 
@@ -265,27 +457,28 @@
   OpenTextView(text, (int) textlen, title, 1);
 
   /* note:  text gets freed when window gets closed */
+  return TRUE;
 }
 
-    
-    
+
+
 /***************************************************************/
 void OpenTextView(text, len, title, freeonclose)
-     char *text, *title;
-     int   len,   freeonclose;
+     const char *text, *title;
+     int   len, freeonclose;
 {
   /* opens up a textview window */
 
-  int     i, oldone;
   TVINFO *tv;
 
   tv = &tinfo[0];
 
   /* kill off old text info */
-  if (tv->freeonclose && tv->text) free(tv->text);
+  if (tv->freeonclose && tv->text) free((void *)tv->text);
   if (tv->lines) free(tv->lines);
-  tv->text = (char *) NULL;
-  tv->lines = (char **) NULL;
+
+  tv->text = (const char *) NULL;
+  tv->lines = (const char **) NULL;
   tv->numlines = tv->textlen = tv->hexmode = 0;
 
 
@@ -293,6 +486,7 @@
   tv->textlen     = len;
   tv->freeonclose = freeonclose;
   strncpy(tv->title, title, (size_t) TITLELEN-1);
+  tv->title[TITLELEN-1] = '\0';
 
   computeText(tv);      /* compute # lines and linestarts array */
 
@@ -316,7 +510,6 @@
 {
   /* opens up the reserved 'comment' textview window */
 
-  int     i;
   TVINFO *tv;
 
   tv = &tinfo[CMTWIN];
@@ -351,9 +544,9 @@
   tv->textlen     = (tv->text) ? strlen(tv->text) : 0;
   tv->freeonclose = 0;
 
-  if (strlen(fullfname)) 
+  if (strlen(fullfname))
     sprintf(tv->title, "File: '%s'", BaseName(fullfname));
-  else 
+  else
     sprintf(tv->title, "<no file loaded>");
 
   computeText(tv);      /* compute # lines and linestarts array */
@@ -501,12 +694,16 @@
   if (i==MAXTEXTWIN) anyTextUp = 0;
 
   /* free all info for this textview window */
-  if (tv->freeonclose && tv->text)  free(tv->text);
+  if (tv->freeonclose && tv->text)  free((void *)tv->text);
   if (tv->lines) free(tv->lines);
 
-  tv->text  = (char *) NULL;  
-  tv->lines = (char **) NULL;
+  tv->text  = (const char *) NULL;
+  tv->lines = (const char **) NULL;
   tv->numlines = tv->textlen = tv->hexmode = 0;
+
+#ifdef TV_MULTILINGUAL
+  closeCsWin(tv);
+#endif
 }
 
 
@@ -518,7 +715,7 @@
   /* checks event to see if it's a text-window related thing.  If it
      is, it eats the event and returns '1', otherwise '0'. */
 
-  int i, rv;
+  int rv;
 
   rv = 1;
 
@@ -560,7 +757,7 @@
 	count++;
       } while (XCheckWindowEvent(theDisp, evt.xexpose.window,
 				 ExposureMask, &evt));
-      
+
       XClipBox(reg, &rect);  /* bounding box of region */
       XSetRegion(theDisp, theGC, reg);
 
@@ -570,7 +767,7 @@
 	fprintf(stderr,"grouped %d expose events into %d,%d %dx%d rect\n",
 		count, rect.x, rect.y, rect.width, rect.height);
       }
-      
+
       if      (e->window == tv->win)   drawTextView(tv);
       else if (e->window == tv->textW) drawTextW(0, &(tv->vscrl));
 
@@ -584,7 +781,7 @@
 
   else if (xev->type == ButtonPress) {
     XButtonEvent *e = (XButtonEvent *) xev;
-    int i,x,y;
+    int x,y;
     x = e->x;  y = e->y;
 
     if (e->button == Button1) {
@@ -594,6 +791,40 @@
       else if (e->window == tv->textW) { }
       else rv = 0;
     }
+    else if (e->button == Button4) {   /* note min vs. max, + vs. - */
+      /* scroll regardless of where we are in the text window */
+      if (e->window == tv->win ||
+	 e->window == tv->vscrl.win ||
+	 e->window == tv->hscrl.win ||
+	 e->window == tv->textW)
+      {
+	SCRL *sp=&(tv->vscrl);
+	int  halfpage=sp->page/2;
+
+	if (sp->val > sp->min+halfpage)
+	  SCSetVal(sp,sp->val-halfpage);
+	else
+	  SCSetVal(sp,sp->min);
+      }
+      else rv = 0;
+    }
+    else if (e->button == Button5) {   /* note max vs. min, - vs. + */
+      /* scroll regardless of where we are in the text window */
+      if (e->window == tv->win ||
+	 e->window == tv->vscrl.win ||
+	 e->window == tv->hscrl.win ||
+	 e->window == tv->textW)
+      {
+	SCRL *sp=&(tv->vscrl);
+	int  halfpage=sp->page/2;
+
+	if (sp->val < sp->max-halfpage)
+	  SCSetVal(sp,sp->val+halfpage);
+	else
+	  SCSetVal(sp,sp->max);
+      }
+      else rv = 0;
+    }
     else rv = 0;
   }
 
@@ -615,7 +846,7 @@
 
       if (tv->wide != e->width || tv->high != e->height) {
 	if (DEBUG) fprintf(stderr,"Forcing a redraw!  (from configure)\n");
-	XClearArea(theDisp, tv->win, 0, 0, 
+	XClearArea(theDisp, tv->win, 0, 0,
 		   (u_int) e->width, (u_int) e->height, True);
 	resizeText(tv, e->width, e->height);
       }
@@ -633,10 +864,12 @@
      TVINFO *tv;
      int     w,h;
 {
-  int        i, maxw, maxh, hmax, hpage, vmax, vpage;
+  int        i, maxw, maxh;
   XSizeHints hints;
 
+#ifndef TV_MULTILINGUAL
   if (tv->wide == w && tv->high == h) return;  /* no change in size */
+#endif
 
   if (XGetNormalHints(theDisp, tv->win, &hints)) {
     hints.width  = w;
@@ -657,13 +890,26 @@
   tv->twWide = tv->chwide * mfwide + 6;
   tv->twHigh = tv->chhigh * mfhigh + 6;
 
-  XMoveResizeWindow(theDisp, tv->textW, LRMARGINS, TOPMARGIN, 
+  XMoveResizeWindow(theDisp, tv->textW, LRMARGINS, TOPMARGIN,
 		    (u_int) tv->twWide, (u_int) tv->twHigh);
 
-  for (i=0; i<TV_NBUTTS; i++) {
-    tv->but[i].x = tv->wide - (TV_NBUTTS-i) * (BUTTW+5);
+  for (i=0; i<TV_E_NBUTTS; i++) {
+    tv->but[i].x = tv->wide - (TV_E_NBUTTS-i) * (BUTTW1+5);
     tv->but[i].y = tv->high - BUTTH - 5;
   }
+#ifdef TV_MULTILINGUAL
+  tv->csbut.x = 5;
+  tv->csbut.y = tv->high - BUTTH - 5;
+#endif
+
+#ifdef TV_L10N
+  if (xlocale) {
+    for (; i<TV_J_NBUTTS; i++) {
+      tv->but[i].x = 5 + (i-TV_E_NBUTTS) * (BUTTW2+5);
+      tv->but[i].y = tv->high - BUTTH - 5;
+    }
+  }
+#endif
 
   computeScrlVals(tv);
 
@@ -692,8 +938,8 @@
   hpag = tv->chwide / 4;
   vpag = tv->chhigh - 1;
 
-  
-  SCChange(&tv->vscrl, LRMARGINS + tv->twWide+1, TOPMARGIN, 
+
+  SCChange(&tv->vscrl, LRMARGINS + tv->twWide+1, TOPMARGIN,
 	   1, tv->twHigh, 0, vmax, tv->vscrl.val, vpag);
 
   SCChange(&tv->hscrl, LRMARGINS, TOPMARGIN + tv->twHigh + 1,
@@ -714,6 +960,29 @@
   case TV_CLOSE:   if (tv == &tinfo[CMTWIN]) CloseCommentText();
                    else closeText(tv);
                    break;
+
+#ifdef TV_L10N
+  case TV_RESCAN:
+    tv->code = selectCodeset(tv);
+    drawTextW(0, &tv->vscrl);
+    break;
+  case TV_USASCII:
+    tv->code = LOCALE_USASCII;
+    drawTextW(0, &tv->vscrl);
+    break;
+  case TV_JIS:
+    tv->code = LOCALE_JIS;
+    drawTextW(0, &tv->vscrl);
+    break;
+  case TV_EUCJ:
+    tv->code = LOCALE_EUCJ;
+    drawTextW(0, &tv->vscrl);
+    break;
+  case TV_MSCODE:
+    tv->code = LOCALE_MSCODE;
+    drawTextW(0, &tv->vscrl);
+    break;
+#endif	/* TV_L10N */
   }
 }
 
@@ -731,11 +1000,11 @@
     y = 5;
 
     XSetForeground(theDisp, theGC, infobg);
-    XFillRectangle(theDisp, tv->win, theGC, 5+1, y+1, 
+    XFillRectangle(theDisp, tv->win, theGC, 5+1, y+1,
 		   (u_int) StringWidth(tv->title)+6, (u_int) CHIGH+4);
 
     XSetForeground(theDisp, theGC, infofg);
-    XDrawRectangle(theDisp, tv->win, theGC, 5, y, 
+    XDrawRectangle(theDisp, tv->win, theGC, 5, y,
 		   (u_int) StringWidth(tv->title)+7, (u_int) CHIGH+5);
 
     Draw3dRect(tv->win, 5+1, y+1, (u_int) StringWidth(tv->title)+5,
@@ -748,8 +1017,10 @@
   drawNumLines(tv);
 
   /* draw the buttons */
-  for (i=0; i<TV_NBUTTS; i++) BTRedraw(&(tv->but[i]));
-
+  for (i=0; i<nbutts; i++) BTRedraw(&(tv->but[i]));
+#ifdef TV_MULTILINGUAL
+  BTRedraw(&tv->csbut);
+#endif
   BTRedraw(&tv->nopBut);
 }
 
@@ -763,15 +1034,15 @@
 
   if (tv->hexmode) nl = tv->hexlines;
   else {
-    if (tv->numlines>0 && 
-	tv->lines[tv->numlines-1] - tv->lines[tv->numlines-2] == 1) 
+    if (tv->numlines>0 &&
+	tv->lines[tv->numlines-1] - tv->lines[tv->numlines-2] == 1)
       nl = tv->numlines - 2;      /* line after last \n has zero length */
     else nl = tv->numlines - 1;
   }
   if (nl<0) nl = 0;
 
-  sprintf(tmpstr, "%d byte%s, %d line%s", 
-	  tv->textlen, (tv->textlen!=1) ? "s" : "", 
+  sprintf(tmpstr, "%d byte%s, %d line%s",
+	  tv->textlen, (tv->textlen!=1) ? "s" : "",
 	  nl, (nl!=1) ? "s" : "");
 
   w = StringWidth(tmpstr) + 7;  /* width of frame */
@@ -779,13 +1050,13 @@
   y = 6;
 
   XSetForeground(theDisp, theGC, infobg);
-  XFillRectangle(theDisp, tv->win, theGC, (x-w)+1, y+1, 
+  XFillRectangle(theDisp, tv->win, theGC, (x-w)+1, y+1,
 		 (u_int) (w-1), (u_int) CHIGH+4);
 
   XSetForeground(theDisp, theGC, infofg);
   XDrawRectangle(theDisp, tv->win, theGC, x-w, y, (u_int) w, (u_int) CHIGH+5);
 
-  Draw3dRect(tv->win, (x-w)+1, y+1, (u_int) (w-2), (u_int) CHIGH+3, 
+  Draw3dRect(tv->win, (x-w)+1, y+1, (u_int) (w-2), (u_int) CHIGH+3,
 	     R3D_IN,2,hicol,locol,infobg);
 
   XSetForeground(theDisp, theGC, infofg);
@@ -800,10 +1071,10 @@
   int x, y, w, nl;
   char tmpstr[64];
 
-  nl = (tv->hexmode) ? tv->hexlines : tv->numlines-1;                 
+  nl = (tv->hexmode) ? tv->hexlines : tv->numlines-1;
 
-  sprintf(tmpstr, "%d byte%s, %d line%s", 
-	  tv->textlen, (tv->textlen>1) ? "s" : "", 
+  sprintf(tmpstr, "%d byte%s, %d line%s",
+	  tv->textlen, (tv->textlen>1) ? "s" : "",
 	  nl, (nl>1) ? "s" : "");
 
   w = StringWidth(tmpstr) + 7;  /* width of frame */
@@ -819,20 +1090,28 @@
      int   delta;
      SCRL *sptr;
 {
-  int     i, j, lnum, hpos, cpos, extrach, lwide;
+  int     i, j, lnum, hpos, vpos, cpos, lwide;
+#ifndef TV_MULTILINGUAL
+  int     extrach;
+#endif
+#ifdef TV_L10N
+  int     desig_stat;	/* for ISO 2022-JP */
+	      /* 0: ASCII,  1: JIS X 0208,  2: GL is JIS X 0201 kana */
+#endif
   TVINFO *tv;
   char    linestr[512];
-  u_char  *sp, *ep, *lp;
+  byte   *lp;
+  const byte  *sp, *ep;
 
   /* figure out TVINFO pointer from SCRL pointer */
-  for (i=0; i<MAXTVWIN && sptr != &tinfo[i].vscrl 
+  for (i=0; i<MAXTVWIN && sptr != &tinfo[i].vscrl
        && sptr != &tinfo[i].hscrl; i++);
   if (i==MAXTVWIN) return;   /* didn't find one */
 
   tv = &tinfo[i];
 
   /* make sure we've been sized.  Necessary, as creating/modifying the
-     scrollbar calls this routine directly, rather than through 
+     scrollbar calls this routine directly, rather than through
      TextCheckEvent() */
 
   if (!hasBeenSized) return;
@@ -842,14 +1121,40 @@
   XSetFont(theDisp, theGC, monofont);
 
   hpos = tv->hscrl.val;
+  vpos = tv->vscrl.val;
   lwide = (tv->chwide < 500) ? tv->chwide : 500;
 
   /* draw text */
   if (!tv->hexmode) {     /* ASCII mode */
+#ifdef TV_MULTILINGUAL
+    XClearArea(theDisp, tv->textW, 0, 0,
+	       (u_int) tv->twWide, (u_int) tv->twHigh, False);
+    if(tv->txt == NULL)
+      return;
+    else {
+	int i;
+	int y;
+	struct ml_text *tp = tv->txt;
+	struct ml_line *lp2;
+
+	XSetFunction(theDisp, theGC, GXcopy);
+	XSetClipMask(theDisp, theGC, None);
+	y = 3;
+	for (lp2 = &tp->lines[vpos], i = tp->nlines - vpos;
+		i > 0; lp2++, i--) {
+	    XDrawText16(theDisp, tv->textW, theGC,
+			-mfwide * hpos + 3, y + lp2->ascent,
+			lp2->items, lp2->nitems);
+	    y += lp2->ascent + lp2->descent;
+	    if (y > tv->twHigh)
+		break;
+	}
+    }
+#else
     for (i=0; i<tv->chhigh; i++) {    /* draw each line */
-      lnum = i + tv->vscrl.val;
+      lnum = i + vpos;
       if (lnum < tv->numlines-1) {
-	
+
 	/* find start of displayed portion of line.  This is *wildly*
 	   complicated by the ctrl-character and tab expansion... */
 
@@ -868,7 +1173,13 @@
 	      cpos--;  sp++;
 	    }
 	    else if (*sp < 32) extrach = 1;
+
+#ifdef TV_L10N
+	    else if (!tv->code && *sp > 127) extrach = 3;
+#else
 	    else if (*sp > 127) extrach = 3;
+#endif
+
 	    else sp++;
 	  }
 	  else {
@@ -884,6 +1195,10 @@
 
 	/* build up the linestr buffer, which is the current line, padded
 	   with blanks to a width of exactly tv->chwide chars */
+#ifdef TV_L10N
+	desig_stat = 0;		/* for ISO 2022-JP */
+	      /* 0: ASCII,  1: JIS X 0208,  2: GL is JIS X 0201 kana */
+#endif
 	for (cpos=0, lp=(byte *) linestr; cpos<lwide; cpos++, lp++) {
 	  if (sp>=ep) *lp = ' ';
 	  else {
@@ -897,13 +1212,117 @@
 	      cpos--;  lp--;  sp++;
 	    }
 
+#ifdef TV_L10N
+	    else if (*sp < 32 && !(tv->code == LOCALE_JIS && *sp == 0x1b)) {
+#else
 	    else if (*sp < 32) {
+#endif
 	      if (!extrach) extrach = 2;
 	      if      (extrach == 2) *lp = '^';
 	      else if (extrach == 1) *lp = *sp + 64;
 	    }
-      
+
+#ifdef TV_L10N
+	    /* convert to EUC-Japan */
+	    else if (tv->code == LOCALE_JIS) {
+	      if (*sp == 0x1b) {	/* ESC */
+		if (*(sp+1) == '$') {
+		  if (*(sp+2) == 'B' || *(sp+2) == 'A' || *(sp+2) == '@') {
+		    /* ESC $ B,  ESC $ A,  ESC $ @ */
+		    desig_stat = 1;
+		    sp += 3;  cpos--;  lp--;
+		  }
+		  else if (*(sp+2) == '(' && *(sp+3) == 'B') {
+		    /* ESC $ ( B */
+		    desig_stat = 1;
+		    sp += 4;  cpos--;  lp--;
+		  }
+		}
+		else if (*(sp+1) == '(') {
+		  if (*(sp+2) == 'B' || *(sp+2) == 'J' || *(sp+2) == 'H') {
+		    /* ESC ( B,  ESC ( J,  ESC ( H */
+		    desig_stat = 0;
+		    sp += 3;  cpos--;  lp--;
+		  }
+		  else if (*(sp+2) == 'I') {
+		    /* ESC ( I */
+		    desig_stat = 2;
+		    sp += 3;  cpos--;  lp--;
+		  }
+		}
+		else if (*(sp+1) == ')' && *(sp+2) == 'I') {
+		  /* ESC ) I */
+		  desig_stat = 2;
+		  sp += 3;  cpos--;  lp--;
+		}
+		else {	/* error */
+		  *lp = ' ';  sp++;
+		}
+	      }
+
+	      else {
+		switch (desig_stat) {
+		case 0:		/* ASCII */
+		  *lp = *sp++;
+		  break;
+		case 1:		/* JIS X 0208 */
+		  *lp++ = *sp++ | 0x80;
+		  *lp   = *sp++ | 0x80;
+		  cpos++;
+		  break;
+		case 2:		/* JIS X 0201 kana */
+#if defined(__osf__) && !defined(X_LOCALE)
+		  *lp   = '=';  sp++;
+#else
+		  *lp++ = 0x8e;	/* ^N | 0x80 */
+		  *lp   = *sp++ | 0x80;
+#endif
+		  break;
+		default:	/* error */
+		  *lp = *sp++;
+		  break;
+		}
+	      }
+	    }
+
+	    else if (tv->code == LOCALE_MSCODE) {
+	      if ((*sp >= 0x81 && *sp <= 0x9f)
+			 || (*sp >= 0xe0 && *sp <= 0xef)) {
+		static u_char c1, c2;
+
+/*fprintf(stderr, "(%x,%x)->", *sp, *(sp+1));*/
+		c1 = ((*sp - ((*sp>=0xe0) ? 0xb0 : 0x70)) << 1)
+			- ((*(sp+1)<=0x9e) ? 1 : 0);
+		c2 = *(sp+1);
+		if      (c2 >= 0x9f)  c2 -= 0x7e;	/* 0x9F - 0xFC */
+		else if (c2 >= 0x80)  c2 -= 0x20;	/* 0x80 - 0x9E */
+		else		      c2 -= 0x1f;	/* 0x40 - 0x7E */
+
+		*lp++ = c1 | 0x80;
+		*lp   = c2 | 0x80;
+		sp += 2;
+/*fprintf(stderr, "(%x %x) ", c1 | 0x80, c2 | 0x80);*/
+		cpos++;
+	      }
+
+	      else if (*sp >= 0xa1 && *sp <= 0xdf) {	/* JIS X 0201 kana */
+#if defined(__osf__) && !defined(X_LOCALE)
+		*lp   = '=';  sp++;
+#else
+		*lp++ = 0x8e;	/* ^N | 0x80 */
+		*lp   = *sp++;
+#endif
+	      }
+
+	      else *lp = *sp++;
+	    }
+#endif	/* TV_L10N */
+
+#ifdef TV_L10N
+	    else if (!tv->code && *sp > 127) {
+#else
 	    else if (*sp > 127) {
+#endif
 	      if (!extrach) extrach = 4;
 	      if      (extrach == 4) *lp = '\\';
 	      else if (extrach == 3) *lp = ((u_char)(*sp & 0700) >> 6) + '0';
@@ -919,6 +1338,9 @@
 	    }
 	  }
 	}
+#ifdef TV_L10N
+	*lp = '\0';	/* terminate linestr */
+#endif
       }
 
       else {  /* below bottom of file.  Just build a blank str */
@@ -926,24 +1348,31 @@
       }
 
       /* draw the line */
-      XDrawImageString(theDisp, tv->textW, theGC, 
-		       3, i*mfhigh + 3 + mfascent, linestr, lwide);
+#ifdef TV_L10N
+      if (xlocale)
+	XmbDrawImageString(theDisp, tv->textW, monofset, theGC,
+		3, i*mfhigh + 1 + mfascent, linestr, strlen(linestr));
+      else
+#endif
+	XDrawImageString(theDisp, tv->textW, theGC,
+		3, i*mfhigh + 3 + mfascent, linestr, lwide);
     }  /* for i ... */
+#endif /* TV_MULTILINGUAL */
   }  /* if hexmode */
 
 
   else { /* HEX MODE */
     for (i=0; i<tv->chhigh; i++) {    /* draw each line */
-      lnum = i + tv->vscrl.val;
+      lnum = i + vpos;
       if (lnum < tv->hexlines) {
-	
+
 	char hexstr[80], tmpstr[16];
 
 	/* generate hex for this line */
 	sprintf(hexstr, "0x%08x: ", lnum * 0x10);
 
-	sp = (byte *) tv->text + lnum * 0x10;
-	ep = (byte *) tv->text + tv->textlen;      /* ptr to end of buffer */
+	sp = (const byte *) tv->text + lnum * 0x10;
+	ep = (const byte *) tv->text + tv->textlen;      /* ptr to end of buffer */
 
 	for (j=0; j<16; j++) {
 	  if (sp+j < ep) sprintf(tmpstr,"%02x ", sp[j]);
@@ -960,7 +1389,11 @@
 
 	for (j=0; j<16; j++) {
 	  if (sp+j < ep) {
+#ifdef TV_L10N
+	    if (sp[j] >= 32 && (sp[j] <= 127 || tv->code)) *lp++ = sp[j];
+#else
 	    if (sp[j] >= 32 && sp[j] <= 127) *lp++ = sp[j];
+#endif
 	    else *lp++ = '.';
 	  }
 	  else *lp++ = ' ';
@@ -972,7 +1405,7 @@
 	   now build 'linestr', which is going to have hexstr shifted
 	   and/or padded with blanks  (ie, the displayed portion or hexstr) */
 
-	/* skip obscured beginning of line, if any */ 
+	/* skip obscured beginning of line, if any */
 	for (cpos=0, sp=(byte *) hexstr; cpos<hpos && *sp;  cpos++, sp++);
 
 	for (cpos=0, lp=(byte *)linestr;  cpos<lwide; cpos++, lp++) {
@@ -985,16 +1418,16 @@
       }
 
       /* draw the line */
-      XDrawImageString(theDisp, tv->textW, theGC, 
+      XDrawImageString(theDisp, tv->textW, theGC,
 		       3, i*mfhigh + 3 + mfascent, linestr, lwide);
     }  /* for i ... */
   }  /* else hexmode */
-    
+
 
 
   XSetFont(theDisp, theGC, mfont);
 
-  Draw3dRect(tv->textW, 0, 0, (u_int) (tv->twWide-1), (u_int) (tv->twHigh-1), 
+  Draw3dRect(tv->textW, 0, 0, (u_int) (tv->twWide-1), (u_int) (tv->twHigh-1),
 	     R3D_IN, 2, hicol, locol, infobg);
 }
 
@@ -1008,14 +1441,21 @@
   int   i;
   BUTT *bp;
 
-  for (i=0, bp=tv->but; i<TV_NBUTTS; i++, bp++) {
+  for (i=0, bp=tv->but; i<nbutts; i++, bp++) {
     if (PTINRECT(x,y,bp->x,bp->y,bp->w,bp->h)) break;
   }
 
-  if (i<TV_NBUTTS) {
+  if (i<nbutts) {
     if (BTTrack(bp)) doCmd(tv, i);
     return;
   }
+
+#ifdef TV_MULTILINGUAL
+  if (PTINRECT(x, y, tv->csbut.x, tv->csbut.y, tv->csbut.w, tv->csbut.h)) {
+    if (BTTrack(&tv->csbut))
+      openCsWin(tv);
+  }
+#endif
 }
 
 
@@ -1033,7 +1473,7 @@
   stlen = XLookupString(kevt, buf, 128, &ks, (XComposeStatus *) NULL);
   shift = kevt->state & ShiftMask;
   ck    = CursorKey(ks, shift, 1);
-  dealt = 1;  
+  dealt = 1;
 
   RemapKeyCheck(ks, buf, &stlen);
 
@@ -1045,13 +1485,38 @@
 
   /* keyboard equivalents */
   switch (buf[0]) {
-  case '\001': doCmd(tv, TV_ASCII);   break;      /* ^A = Ascii */
-  case '\010': doCmd(tv, TV_HEX);     break;      /* ^H = Hex   */
-
-  case '\033': doCmd(tv, TV_CLOSE);   break;      /* ESC = Close window */
+  case '\001':  case 'a':  case 'A':
+    doCmd(tv, TV_ASCII);   break;      /* ^A = Ascii */
+  case '\010':  case 'h':  case 'H':
+    doCmd(tv, TV_HEX);     break;      /* ^H = Hex   */
+
+  case '\021':  case 'q':  case 'Q':
+  case '\003':  case 'c':  case 'C':
+  case '\033':
+    doCmd(tv, TV_CLOSE);   break;      /* ESC = Close window */
 
   default:     break;
   }
+
+#ifdef TV_L10N
+  if (xlocale) {
+    switch (buf[0]) {
+    case '\022':  case 'r':  case 'R':
+      doCmd(tv, TV_RESCAN);   break;
+    case '\012':  case 'j':  case 'J':
+      doCmd(tv, TV_JIS);      break;
+    case '\005':  case 'e':  case 'E':
+    case '\025':  case 'u':  case 'U':
+      doCmd(tv, TV_EUCJ);     break;
+    case '\015':  case 'm':  case 'M':
+    case '\023':  case 's':  case 'S':
+      doCmd(tv, TV_MSCODE);  break;
+
+    default:  break;
+    }
+  }
+#endif	/* TV_L10N */
+
 }
 
 
@@ -1060,8 +1525,6 @@
      TVINFO *tv;
      int     key;
 {
-  int i,j;
-
   if (!tv->textlen) return;
 
   /* an arrow key (or something like that) was pressed in icon window.
@@ -1108,13 +1571,26 @@
   else {  /* switch to ascii mode */
     pos = oldvscrl * 16;
     for (i=0; i<tv->numlines-1; i++) {
-      if (tv->lines[i+1] - tv->text > pos && 
+      if (tv->lines[i+1] - tv->text > pos &&
 	  tv->lines[i]   - tv->text <= pos) break;
     }
     if (i<tv->numlines-1) SCSetVal(&tv->vscrl, i);
   }
 
+#ifdef TV_L10N
+  /* redraw text */
+  if (xlocale) {
+    XClearArea(theDisp, tv->textW, 0, 0,
+	       (u_int) tv->twWide, (u_int) tv->twHigh, False);
+
+    drawTextW(0, &tv->vscrl);
+  }
+#endif
+#ifdef TV_MULTILINGUAL
+  XClearArea(theDisp, tv->textW, 0, 0,
+	     (u_int) tv->twWide, (u_int) tv->twHigh, False);
   drawTextW(0, &tv->vscrl);
+#endif
 }
 
 
@@ -1125,16 +1601,29 @@
   /* compute # of lines and linestarts array for given text */
 
   int   i,j,wide,maxwide,space;
-  byte *sp;
+  const byte *sp;
 
-  if (!tv->text) { 
-    tv->numlines = tv->hexlines = 0;  
-    tv->lines = (char **) NULL; 
+#ifdef TV_L10N
+  /* select code-set */
+  if (xlocale)
+    tv->code = selectCodeset(tv);
+#endif	/* TV_L10N */
+
+  if (!tv->text) {
+    tv->numlines = tv->hexlines = 0;
+    tv->lines = (const char **) NULL;
+#ifdef TV_MULTILINGUAL
+    if (tv->cv_text != NULL) {
+	free(tv->cv_text);
+	tv->cv_text = NULL;
+    }
+    tv->txt = NULL;
+#endif
     return;
   }
 
   /* count the # of newline characters in text */
-  for (i=0, sp=(byte *) tv->text, tv->numlines=0; i<tv->textlen; i++, sp++) {
+  for (i=0, sp=(const byte *) tv->text, tv->numlines=0; i<tv->textlen; i++, sp++) {
     if (*sp == '\n') tv->numlines++;
   }
 
@@ -1142,19 +1631,19 @@
   tv->numlines += 2;
 
   /* build lines array */
-  tv->lines = (char **) malloc(tv->numlines * sizeof(char *));
+  tv->lines = (const char **) malloc(tv->numlines * sizeof(char *));
   if (!tv->lines) FatalError("out of memory in computeText()");
 
   j = 0;
   tv->lines[j++] = tv->text;
-  for (i=0, sp=(byte *) tv->text; i<tv->textlen; i++, sp++) {
+  for (i=0, sp=(const byte *) tv->text; i<tv->textlen; i++, sp++) {
     if (*sp == '\n') tv->lines[j++] = (char *) (sp + 1);
   }
 
   tv->lines[tv->numlines - 1] = tv->text + tv->textlen + 1;
 
-  /* each line has a trailing '\n' character, except for the last line, 
-     which has a trailing '\0' character.  In any case, all lines can 
+  /* each line has a trailing '\n' character, except for the last line,
+     which has a trailing '\0' character.  In any case, all lines can
      be printed by printing ((lines[n+1] - lines[n]) - 1) characters,
      starting with lines[n].
 
@@ -1164,30 +1653,142 @@
 
   /* compute length of longest line, when shown in 'ascii' mode.  Takes
      into account the fact that non-printing chars (<32 or >127) will be
-     shown in an 'expanded' form.  (<32 chars will be shown as '^A' 
+     shown in an 'expanded' form.  (<32 chars will be shown as '^A'
      (or whatever), and >127 chars will be shown as octal '\275') */
 
   maxwide = 0;
   for (i=0; i<tv->numlines-1; i++) {
     /* compute displayed width of line #i */
-    for (sp=(byte *) tv->lines[i], wide=0; sp<(byte *) tv->lines[i+1]-1; 
+    for (sp=(const byte *) tv->lines[i], wide=0; sp<(const byte *) tv->lines[i+1]-1;
 	 sp++) {
       if (*sp == '\011') {   /* tab to next multiple of 8 */
 	space = ((wide+8) & (~7)) - wide;
 	wide += space;
       }
       else if (*sp <  32) wide += 2;
+#ifdef TV_L10N
+      else if (*sp > 127 && !tv->code) wide += 4;
+#else
       else if (*sp > 127) wide += 4;
+#endif
       else wide++;
     }
     if (wide > maxwide) maxwide = wide;
   }
   tv->maxwide = maxwide;
 
+#ifdef TV_MULTILINGUAL
+  ml_set_charsets(tv->ctx, &tv->ccs.coding_system);
+  if (tv->cv_text != NULL) {
+      free(tv->cv_text);
+      tv->cv_text = NULL;
+  }
+  if (tv->ccs.converter == NULL) {
+      tv->txt = ml_draw_text(tv->ctx, tv->text, tv->textlen);
+  } else {
+      tv->cv_text = (*tv->ccs.converter)(tv->text, tv->textlen, &tv->cv_len);
+      tv->txt = ml_draw_text(tv->ctx, tv->cv_text, tv->cv_len);
+  }
+  tv->maxwide = tv->txt->width / mfwide;
+  tv->numlines = tv->txt->height / mfhigh + 1;
+#endif
+
   tv->hexlines = (tv->textlen + 15) / 16;
 }
 
 
+/***************************************************/
+#ifdef TV_L10N
+static int selectCodeset(tv)
+     TVINFO *tv;
+{
+  const byte *sp;
+  int i, len;
+  int code = LOCALE_USASCII;	/* == 0 */
+
+
+  len = tv->textlen;
+
+  /* select code-set */
+  if (xlocale) {
+    sp = (const byte *) tv->text;  i = 0;
+    while (i < len - 1) {
+      if (*sp == 0x1b &&
+	  (*(sp+1) == '$' || *(sp+1) == '(' || *(sp+1) == ')')) {
+	code = LOCALE_JIS;
+	break;
+      }
+
+      else if (*sp >= 0xa1 && *sp <= 0xdf) {
+	if (*(sp+1) >= 0xf0 && *(sp+1) <= 0xfe) {
+	  code = LOCALE_EUCJ;
+	  break;
+	}
+#  if (LOCALE_DEFAULT == LOCALE_EUCJ)
+	else {
+	  sp++;  i++;
+	}
+#  endif
+      }
+
+      else if ((*sp >= 0x81 && *sp <= 0x9f) || (*sp >= 0xe0 && *sp <= 0xef)) {
+	if ((*(sp+1) >= 0x40 && *(sp+1) <= 0x7e) || *(sp+1) == 0x80) {
+	  code = LOCALE_MSCODE;
+	  break;
+	}
+	else if (*(sp+1) == 0xfd || *(sp+1) == 0xfe) {
+	  code = LOCALE_EUCJ;
+	  break;
+	}
+	else {
+	  sp++;  i++;
+	}
+      }
+
+      else if (*sp >= 0xf0 && *sp <= 0xfe) {
+	code = LOCALE_EUCJ;
+	break;
+      }
+
+      sp++;  i++;
+    }
+    if (!code)  code = LOCALE_DEFAULT;
+  }
+
+  return code;
+}
+#endif	/* TV_L10N */
+
+#ifdef TV_MULTILINGUAL
+static void setCodingSpec(tv, cs)
+    TVINFO *tv;
+    struct coding_spec *cs;
+{
+  if (xvbcmp((char *) &tv->ccs, (char *) cs, sizeof *cs) == 0)
+    return;
+
+  tv->ccs = *cs;
+#if 0
+  ml_set_charsets(tv->ctx, &tv->ccs.coding_system);
+  if (tv->cv_text != NULL) {
+      free(tv->cv_text);
+      tv->cv_text = NULL;
+  }
+  if (tv->ccs.converter == NULL) {
+      tv->txt = ml_draw_text(tv->ctx, tv->text, tv->textlen);
+  } else {
+      tv->cv_text = (*tv->ccs.converter)(tv->text, tv->textlen, &tv->cv_len);
+      tv->txt = ml_draw_text(tv->ctx, tv->cv_text, tv->cv_len);
+  }
+#else
+  computeText(tv);
+  computeScrlVals(tv);
+#endif
+  /* drawTextW(0, &tv->vscrl); */
+}
+#endif
+
+
 /**********************************************************************/
 /* BUILT-IN TEXT FILES ************************************************/
 /**********************************************************************/
@@ -1203,9 +1804,13 @@
 
   /* build the license text */
 #ifdef LC
-#undef LC
+#  undef LC
+#endif
+#ifdef __STDC__  /* since "x" is always a static string, this works: */
+#  define LC(x) (strcat(license, x "\n"))
+#else
+#  define LC(x) (strcat(license, x), strcat(license, "\n"))
 #endif
-#define LC(x) (strcat(license, x), strcat(license, "\n"))
 
   LC("(Note: This has been changed, and hopefully clarified, from the 3.00");
   LC("version of this info.  Please read it.)");
@@ -1220,7 +1825,12 @@
   LC("the xv distribution.  Do *not* send mail unless absolutely necessary");
   LC("(ie, you don't have ftp capability).");
   LC("");
-  LC("Note:  The docs (xvdocs.ps) may be installed in '/usr/local/lib'.");
+  LC("Note:  The documentation (README.jumbo, xvdocs.ps, and/or xvdocs.pdf)");
+#ifdef __STDC__
+  LC("may be installed in '" DOCDIR "'.");
+#else
+  LC("may be installed in '/usr/local/share/doc/xv'.");
+#endif
   LC("");
   LC("If you're viewing this information via the 'About XV' command, and");
   LC("you'd like to print it out, a copy of this info can be found in the ");
@@ -1230,7 +1840,7 @@
   LC("");
   LC("XV Licensing Information");
   LC("------------------------");
-  LC("XV IS SHAREWARE FOR PERSONAL USE ONLY.  ");
+  LC("XV IS SHAREWARE FOR PERSONAL USE ONLY.");
   LC("");
   LC("You may use XV for your own amusement, and if you find it nifty,");
   LC("useful, generally cool, or of some value to you, your registration fee");
@@ -1279,7 +1889,7 @@
   LC("are not.  All forms of payment must be payable in US Funds.  Checks");
   LC("must be payable through a US bank (or a US branch of a non-US bank).");
   LC("Purchase orders for less than $50, while still accepted, are not");
-  LC("encouraged. ");
+  LC("encouraged.");
   LC("");
   LC("All payments should be payable to 'John Bradley', and mailed to:");
   LC("        John Bradley");
@@ -1382,7 +1992,11 @@
   keyhelp[0] = '\0';
 
 #undef LC
-#define LC(x) (strcat(keyhelp, x), strcat(keyhelp, "\n"))
+#ifdef __STDC__  /* since "x" is always a static string, this works: */
+#  define LC(x) (strcat(keyhelp, x "\n"))
+#else
+#  define LC(x) (strcat(keyhelp, x), strcat(keyhelp, "\n"))
+#endif
 
   LC("XV Mouse and Keyboard Usage");
   LC("===========================");
@@ -1415,16 +2029,16 @@
   LC("");
   LC("Part 2:  Normal Keyboard Equivalents");
   LC("------------------------------------");
-  LC("The following keys can be used in most xv windows, including the ");
-  LC("image, controls, and color editor windows, but *not* in the visual");
-  LC("schnauzer windows.");
+  LC("The following keys can be used in most xv windows, including the");
+  LC("image, controls, and color editor windows, but *not* in the Visual");
+  LC("Schnauzer windows.");
   LC("");
-  LC("  Tab or ");
+  LC("  Tab or");
   LC("  Space         - 'Next' command");
   LC("");
   LC("  Return        - reload currently displayed image file");
   LC("");
-  LC("  Del or ");
+  LC("  Del or");
   LC("  Backspace     - 'Prev' command");
   LC("");
   LC("  ctrl+'l'      - 'Load' command");
@@ -1432,7 +2046,7 @@
   LC("  ctrl+'p'      - 'Print' command");
   LC("  ctrl+'d'      - 'Delete' command");
   LC("");
-  LC("  'q' or ");
+  LC("  'q' or");
   LC("  ctrl+'q'      - 'Quit' command");
   LC("");
   LC("  meta+'x'      - 'cut' command");
@@ -1468,7 +2082,7 @@
   LC("  's'           - smooth mode");
   LC("  meta+'8'      - toggle 8/24 bit mode");
   LC("");
-  LC("  'V' or ");
+  LC("  'V' or");
   LC("  ctrl+'v'      - Visual Schnauzer");
   LC("  'e'           - Color Editor");
   LC("  'i'           - Image Info");
@@ -1490,7 +2104,7 @@
   LC("  meta+'S'      - Spread algorithm");
   LC("");
   LC("  'R' or");
-  LC("  meta+'r' or ");
+  LC("  meta+'r' or");
   LC("  meta+'0'      - 'Reset' command in color editor");
   LC("");
   LC("  meta+'1'      - select preset 1 in color editor");
@@ -1503,7 +2117,7 @@
   LC("");
   LC("Part 2a:  Image Window Keys");
   LC("---------------------------");
-  LC("The following keys can *only* be used inside the image window.");
+  LC("The following keys can be used *only* inside the image window.");
   LC("");
   LC("  ctrl + Up     - crops 1 pixel off the bottom of the image");
   LC("  ctrl + Down   - crops 1 pixel off the top of the image");
@@ -1514,11 +2128,11 @@
   LC("  'p'           -  opens a 'go to page #' dialog box");
   LC("");
   LC("  PageUp, or");
-  LC("  Prev, or ");
+  LC("  Prev, or");
   LC("  shift+Up      - previous page");
   LC("");
   LC("  PageDown, or");
-  LC("  Next, or ");
+  LC("  Next, or");
   LC("  shift+Down    - next page");
   LC("");
   LC("");
@@ -1535,7 +2149,7 @@
   LC("");
   LC("Part 2b:  Visual Schnauzer Keys");
   LC("-------------------------------");
-  LC("The following keys can only be used in the visual schnauzer windows.");
+  LC("The following keys can be used only in the Visual Schnauzer windows.");
   LC("");
   LC("  ctrl+'d'      - delete file(s)");
   LC("  ctrl+'n'      - create new directory");
@@ -1560,8 +2174,509 @@
   OpenTextView(keyhelp, (int) strlen(keyhelp), "XV Help", 0);
 }
 
+#ifdef TV_MULTILINGUAL
 
+#define TV_ML_ACCEPT TV_NCSS
+#define TV_ML_CLOSE  (TV_ML_ACCEPT + 1)
+#define TV_ML_NBUTTS (TV_ML_CLOSE + 1)
+
+#define TV_ML_RETCODE	0
+#	define TV_ML_RET_LF	0
+#	define TV_ML_RET_CRLF	1
+#	define TV_ML_RET_CR	2
+#	define TV_ML_RET_ANY	3
+#define TV_ML_GL	1
+#define TV_ML_GR	2
+#define TV_ML_CVTR	3
+#define TV_ML_NRBUTTS	4
+
+#define TV_ML_SHORT	0
+#define TV_ML_LOCK	1
+#define TV_ML_NCBUTTS	2
+
+#define TV_ML_NLISTS	4
+
+#define CSWIDE (BUTTW3 * 5 + 5 * 6)
+#define CSHIGH 450
+
+typedef struct csinfo_t {
+    TVINFO *tv;
+    RBUTT *rbt[TV_ML_NRBUTTS];
+    CBUTT cbt[TV_ML_NCBUTTS];
+    LIST ls[TV_ML_NLISTS];
+    BUTT bt[TV_ML_NBUTTS];
+    int up;
+    Window win;
+    struct coding_spec tcs;	/* temporary coding_spec */
+} CSINFO;
+CSINFO csinfo[MAXTVWIN];
+static char **regs;
+static int nregs;
+
+static int  csCheckEvent           PARM((CSINFO *, XEvent *));
+static void csReflect              PARM((CSINFO *));
+static void csRedraw               PARM((CSINFO *));
+static void csListRedraw           PARM((LIST *));
+static void csLsRedraw             PARM((int, SCRL *));
+static void create_registry_list   PARM((void));
+
+static char *(*cvtrtab[])PARM((char *, int, int *)) = {
+    NULL,
+    sjis_to_jis,
+};
 
+static void createCsWins(geom)
+    const char *geom;
+{
+    XSetWindowAttributes xswa;
+    int i, j;
+
+    create_registry_list();
+
+    xswa.backing_store = WhenMapped;
+    for (i = 0; i < MAXTVWIN; i++) {
+	char nam[8];
+	TVINFO *tv = &tinfo[i];
+	CSINFO *cs = &csinfo[i];
+	tv->cs = cs;
+	cs->tv = tv;
+	sprintf(nam, "XVcs%d", i);
+	cs->win = CreateWindow("xv codeset", nam, geom,
+			       CSWIDE, CSHIGH, infofg, infobg, 0);
+	if (!cs->win) FatalError("couldn't create 'charset' window!");
+#ifdef BACKING_STORE
+	XChangeWindowAttributes(theDisp, cs->win, CWBackingStore, &xswa);
+#endif
+	XSelectInput(theDisp, cs->win, ExposureMask | ButtonPressMask);
+
+	DrawString(cs->win, 5, 5 + ASCENT, "Initial States");
+	for (i = 0; i < TV_ML_NLISTS; i++) {
+	    int x, y;
+	    char buf[80];
+
+	    if (i / 2 == 0)
+		x = 15;
+	    else
+		x = 280;
+	    if (i % 2 == 0)
+		y = 5 + LINEHIGH * 1;
+	    else
+		y = 5 + LINEHIGH * 7 + SPACING * 3;
+
+	    sprintf(buf, "Designation for G%d:", i + 1);
+	    DrawString(cs->win, x, y + ASCENT, buf);
+
+	    LSCreate(&cs->ls[i], cs->win, x + 15, y + LINEHIGH,
+			200, LINEHIGH * 5, 5,
+			regs, nregs + 2,
+			infofg, infobg, hicol, locol, csLsRedraw, 0, 0);
+	    cs->ls[i].selected = 0;
+	}
 
+	for (i = 0; i < 2; i++) {
+	    char *p;
+	    int n;
+	    int x, y;
+
+	    if ((p = (char *) malloc(3 * 4)) == NULL)
+		FatalError("out of memory in createCsWins().");
+	    strcpy(p, "G1 G2 G3 G4");
+	    p[2] = p[5] = p[8] = '\0';
+	    n = (i == 0 ? TV_ML_GL : TV_ML_GR);
+	    x = (i == 0 ? 15 : 280);
+	    y = 235;
+	    DrawString(cs->win, x, y + ASCENT, "Assignment for GL:");
+	    x += 15;
+	    y += LINEHIGH;
+	    cs->rbt[n] = RBCreate(NULL, cs->win,
+				  x, y, p, infofg, infobg, hicol, locol);
+	    for (j = 1; j < 4; j++) {
+		p += 3;
+		x += 50;
+		RBCreate(cs->rbt[n], cs->win,
+			 x, y, p, infofg, infobg, hicol, locol);
+	    }
+	}
+
+	DrawString(cs->win, 5, 280 + ASCENT, "Ret Code:");
+	cs->rbt[TV_ML_RETCODE] =
+	    RBCreate(NULL, cs->win, 20, 300, "LF", infofg,infobg, hicol,locol);
+	RBCreate(cs->rbt[TV_ML_RETCODE], cs->win, 20, 300 + 20, "CR+LF",
+		 infofg, infobg, hicol, locol);
+	RBCreate(cs->rbt[TV_ML_RETCODE], cs->win, 90, 300, "CR",
+		 infofg, infobg, hicol, locol);
+	RBCreate(cs->rbt[TV_ML_RETCODE], cs->win, 90, 300 + 20, "Any",
+		 infofg, infobg, hicol, locol);
+
+	DrawString(cs->win, 350, 280 + ASCENT, "Converter:");
+	cs->rbt[TV_ML_CVTR] =
+	    RBCreate(NULL, cs->win, 365, 300, "Nothing",
+		     infofg, infobg, hicol, locol);
+	RBCreate(cs->rbt[TV_ML_CVTR], cs->win, 365, 300 + 20, "Shift JIS",
+		 infofg, infobg, hicol, locol);
+
+	CBCreate(&cs->cbt[TV_ML_SHORT], cs->win, 200, 300, "Short Form",
+		 infofg, infobg, hicol, locol);
+	CBCreate(&cs->cbt[TV_ML_LOCK], cs->win, 200, 320, "Locking Shift",
+		 infofg, infobg, hicol, locol);
+
+	for (j = 0; j < TV_NCSS; j++) {
+	    BTCreate(&cs->bt[j], cs->win,
+		     5 + (BUTTW3 + 5) * (j % 5),
+		     350 + 5 + (BUTTH + 5) * (j / 5),
+		     BUTTW3, BUTTH, codeSetNames[j],
+		     infofg, infobg, hicol, locol);
+	}
+	BTCreate(&cs->bt[TV_ML_ACCEPT], cs->win,
+		 CSWIDE - 10 - BUTTW3 * 2, CSHIGH - 5 - BUTTH, BUTTW3, BUTTH,
+		 "Accept", infofg, infobg, hicol, locol);
+	BTCreate(&cs->bt[TV_ML_CLOSE], cs->win,
+		 CSWIDE - 5 - BUTTW3, CSHIGH - 5 - BUTTH, BUTTW3, BUTTH,
+		 "Close", infofg, infobg, hicol, locol);
+
+	XMapSubwindows(theDisp, cs->win);
+	cs->up = 0;
+    }
+}
 
+static void openCsWin(tv)
+    TVINFO *tv;
+{
+    CSINFO *cs = tv->cs;
+    if (cs->up)
+	return;
+
+    XMapRaised(theDisp, cs->win);
+    cs->up = 1;
+    cs->tcs = cs->tv->ccs;
+    csReflect(cs);
+}
+
+static void closeCsWin(tv)
+    TVINFO *tv;
+{
+    CSINFO *cs = tv->cs;
+    if (!cs->up)
+	return;
+    cs->up = 0;
+    XUnmapWindow(theDisp, cs->win);
+}
+
+int CharsetCheckEvent(xev)
+    XEvent *xev;
+{
+    int i;
+    CSINFO *cs;
+
+    for (cs = csinfo, i = 0; i < MAXTVWIN; cs++, i++) {
+	if (!cs->up)
+	    continue;
+	if (csCheckEvent(cs, xev))
+	    break;
+    }
+    if (i < MAXTVWIN)
+	return 1;
+    return 0;
+}
+
+static int csCheckEvent(cs, xev)
+    CSINFO *cs;
+    XEvent *xev;
+{
+    RBUTT **rbp;
+    CBUTT *cbp;
+    LIST *ls;
+    BUTT *bp;
+    int i, n;
+
+    if (xev->type == Expose) {
+	int x, y, w, h;
+	XExposeEvent *e = (XExposeEvent *) xev;
+	x = e->x; y = e->y; w = e->width; h = e->height;
+
+	if (cs->win == e->window){
+	    csRedraw(cs);
+	    return 1;
+	} else {
+	    for (i = 0; i < TV_ML_NLISTS; i++) {
+		if (cs->ls[i].win == e->window) {
+		    LSRedraw(&cs->ls[i], 0);
+		    return 1;
+		}
+	    }
+	   for (i = 0; i < TV_ML_NLISTS; i++) {
+		if (cs->ls[i].scrl.win == e->window) {
+		    SCRedraw(&cs->ls[i].scrl);
+		    return 1;
+		}
+	   }
+	}
+    } else if (xev->type == ButtonPress) {
+	int x, y;
+	XButtonEvent *e = (XButtonEvent *) xev;
+	x = e->x; y = e->y;
+	if (cs->win == e->window) {
+	    for (bp = cs->bt, i = 0; i < TV_ML_NBUTTS; bp++, i++) {
+		if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h))
+		    break;
+	    }
+	    if (i < TV_ML_NBUTTS) {
+		if (BTTrack(bp)) {
+		    if (i < TV_NCSS) {
+			cs->tcs = coding_spec[i];
+			csReflect(cs);
+		    } else {
+			switch (i) {
+			case TV_ML_ACCEPT:
+			    setCodingSpec(cs->tv, &cs->tcs);
+			    break;
+			case TV_ML_CLOSE:
+			    closeCsWin(cs->tv);
+			    break;
+			}
+		    }
+		}
+		return 1;
+	    }
+	    for (cbp = cs->cbt, i = 0; i < TV_ML_NCBUTTS; cbp++, i++) {
+		if (CBClick(cbp, x, y) && CBTrack(cbp))
+		    break;
+	    }
+	    if (i < TV_ML_NCBUTTS) {
+		switch (i) {
+		case TV_ML_SHORT:
+		    cs->tcs.coding_system.short_form = cbp->val;
+		    break;
+		case TV_ML_LOCK:
+		    cs->tcs.coding_system.lock_shift = cbp->val;
+		    break;
+		}
+		return 1;
+	    }
+	    for (rbp = cs->rbt, i = 0; i < TV_ML_NRBUTTS; rbp++, i++) {
+		if ((n = RBClick(*rbp, x, y)) >= 0 && RBTrack(*rbp, n)) {
+		    break;
+		}
+	    }
+	    if (i < TV_ML_NRBUTTS) {
+		switch (i) {
+		case TV_ML_RETCODE:
+		    cs->tcs.coding_system.eol = n;
+		    break;
+		case TV_ML_GL:
+		    cs->tcs.coding_system.gl = n;
+		    break;
+		case TV_ML_GR:
+		    cs->tcs.coding_system.gr = n;
+		    break;
+		case TV_ML_CVTR:
+		    cs->tcs.converter = cvtrtab[n];
+		    break;
+		}
+		return 1;
+	    }
+	} else {
+	    for (ls = cs->ls, i = 0; i < TV_ML_NLISTS; ls++, i++) {
+		if (ls->win == e->window) {
+		    LSClick(ls, e);
+		    n = ls->selected;
+		    if (n < nregs) {
+			char r[32], *p = r;
+			int b7;
+			strcpy(r, regs[n]);
+			if ((p = strrchr(r, '/')) != NULL) {
+			    *p = '\0';
+			    b7 = (*(p + 1) == 'R' ? 1 : 0);
+			} else
+			    b7 = 0;	/* shouldn't occur */
+			cs->tcs.coding_system.design[i] = lookup_design(r, b7);
+		    } else if (n == nregs)    /* initially none is designed. */
+			cs->tcs.coding_system.design[i].bpc = 0;
+		    else
+			cs->tcs.coding_system.design[i].bpc = -1;
+		    return 1;
+		}
+	    }
+	    for (ls = cs->ls, i = 0; i < TV_ML_NLISTS; ls++, i++) {
+		if (ls->scrl.win == e->window) {
+		    SCTrack(&ls->scrl, x, y);
+		    return 1;
+		}
+	    }
+	}
+    }
+    return 0;
+}
+
+static void csReflect(cs)
+    CSINFO *cs;
+{
+    int i;
+
+    RBSelect(cs->rbt[TV_ML_RETCODE], cs->tcs.coding_system.eol);
+    RBSelect(cs->rbt[TV_ML_GL], cs->tcs.coding_system.gl);
+    RBSelect(cs->rbt[TV_ML_GR], cs->tcs.coding_system.gr);
+    for (i = 0; i < sizeof cvtrtab / sizeof cvtrtab[0]; i++) {
+	if (cs->tcs.converter == cvtrtab[i])
+	    break;
+    }
+    if (i >= sizeof cvtrtab / sizeof cvtrtab[0])
+	FatalError("program error in csReflect().");
+    RBSelect(cs->rbt[TV_ML_CVTR], i);
+
+    cs->cbt[TV_ML_SHORT].val = cs->tcs.coding_system.short_form;
+    cs->cbt[TV_ML_LOCK].val = cs->tcs.coding_system.lock_shift;
+    for (i = 0; i < TV_ML_NLISTS; i++) {
+	struct design design = cs->tcs.coding_system.design[i];
+	char *reg, r[32];
+	int b7;
+	int n = 0;
+	switch (design.bpc) {
+	case -1:
+	    n = nregs + 1;
+	    break;
+	case 0:
+	    n = nregs;
+	    break;
+	case 1:
+	case 2:
+	    if ((reg = lookup_registry(design, &b7)) == NULL)
+		FatalError("internal error in csReflect.");
+	    sprintf(r, "%s/%s", reg, b7 ? "Right" : "Left");
+	    for (n = 0; n < nregs; n++) {
+		if (strcmp(regs[n], r) == 0)
+		    break;
+	    }
+	}
+	cs->ls[i].selected = n;
+	ScrollToCurrent(&cs->ls[i]);
+    }
+    csRedraw(cs);
+    for (i = 0; i < TV_ML_NLISTS; i++)
+	csListRedraw(&cs->ls[i]);
+}
+
+static void csRedraw(cs)
+    CSINFO *cs;
+{
+    int i;
+
+    XSetForeground(theDisp, theGC, infofg);
+    DrawString(cs->win,  5,5 + ASCENT, "Initial States");
+    for (i = 0; i < TV_ML_NLISTS; i++) {
+	int x, y;
+	char buf[80];
+
+	if (i / 2 == 0)
+	    x = 15;
+	else
+	    x = 280;
+	if (i % 2 == 0)
+	    y = 5 + LINEHIGH * 1;
+	else
+	    y = 5 + LINEHIGH * 7 + SPACING * 3;
+
+	sprintf(buf, "Designation for G%d:", i);
+	DrawString(cs->win, x, y + ASCENT, buf);
+    }
+
+    DrawString(cs->win,  15, 235 + ASCENT, "Invocation for GL:");
+    DrawString(cs->win, 280, 235 + ASCENT, "Invocation for GR:");
+    DrawString(cs->win,   5, 280 + ASCENT, "Ret Code:");
+    DrawString(cs->win, 350, 280 + ASCENT, "Converter:");
+
+    for (i = 0; i < TV_ML_NBUTTS; i++)
+	BTRedraw(&cs->bt[i]);
+    for (i = 0; i < TV_ML_NCBUTTS; i++)
+	CBRedraw(&cs->cbt[i]);
+    for (i = 0; i < TV_ML_NRBUTTS; i++)
+	RBRedraw(cs->rbt[i], -1);
+}
+
+static void csListRedraw(ls)
+    LIST *ls;
+{
+    int i;
+    for (i = 0; i < TV_ML_NLISTS; i++) {
+	LSRedraw(ls, 0);
+	SCRedraw(&ls->scrl);
+    }
+}
+
+static void csLsRedraw(delta, sptr)
+    int delta;
+    SCRL *sptr;
+{
+    int i, j;
+    for (i = 0; i < MAXTVWIN; i++) {
+	for (j = 0; j < TV_ML_NLISTS; j++) {
+	    if (sptr == &csinfo[i].ls[j].scrl) {
+		LSRedraw(&csinfo[i].ls[j], delta);
+		return;
+	    }
+	}
+    }
+}
+
+int CharsetDelWin(win)
+    Window win;
+{
+    CSINFO *cs;
+    int i;
+
+    for (cs = csinfo, i = 0; i < TV_NCSS; cs++, i++) {
+	if (cs->win == win) {
+	    if (cs->up) {
+		XUnmapWindow(theDisp, cs->win);
+		cs->up = 0;
+	    }
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+static int reg_comp PARM((const void *, const void *));
+static void create_registry_list()
+{
+    struct design d;
+    char *names, *p;
+    int i;
+
+    if ((p = names = (char *) malloc(32 * 0x80 * 2 * 2)) == NULL)
+	FatalError("out of memory in create_name_list#1.");
+    nregs = 0;
+    for (d.bpc = 1; d.bpc <=2; d.bpc++) {
+	for (d.noc = 94; d.noc <= 96; d.noc += 2) {
+	    for (d.des = ' '; (unsigned char) d.des < 0x80; d.des++) {
+		int b7;
+		char *r;
+		if ((r = lookup_registry(d, &b7)) != NULL) {
+		    sprintf(p, "%s/%s", r, b7 ? "Right" : "Left");
+		    p += strlen(p) + 1;
+		    nregs++;
+		}
+	    }
+	}
+    }
+    if ((names = (char *) realloc(names, (size_t) (p - names))) == NULL)
+	FatalError("out of memory in create_name_list#2.");
+    if ((regs = (char **) malloc(sizeof(char *) * (nregs + 3))) == NULL)
+	FatalError("out of memory in create_name_list#3.");
+    p = names;
+    for (i = 0; i < nregs; i++) {
+	regs[i] = p;
+	p += strlen(p) + 1;
+    }
+    qsort(regs, (size_t) nregs, sizeof(char *), reg_comp);
+    regs[i++] = "nothing";
+    regs[i++] = "unused";
+    regs[i++] = NULL;
+}
+static int reg_comp(dst, src)
+    const void *dst, *src;
+{
+    return strcmp(*(char **) dst, *(char **) src);
+}
 
+#endif /* TV_MULTILINGUAL */
diff -ru xv-3.10a/xvtiff.c xv-3.10a-enhancements/xvtiff.c
--- xv-3.10a/xvtiff.c	1995-01-13 11:53:34.000000000 -0800
+++ xv-3.10a-enhancements/xvtiff.c	2007-05-20 10:32:31.000000000 -0700
@@ -1,11 +1,11 @@
 /*
  * xvtiff.c - load routine for 'TIFF' format pictures
  *
- * LoadTIFF(fname, numcols)  -  load a TIFF file
+ * LoadTIFF(fname, numcols, quick)  -  load a TIFF file
  */
 
 #ifndef va_start
-# define NEEDSARGS
+#  define NEEDSARGS
 #endif
 
 #include "xv.h"
@@ -15,6 +15,35 @@
 #include "tiffio.h"     /* has to be after xv.h, as it needs varargs/stdarg */
 
 
+/* Portions fall under the following copyright:
+ *
+ * Copyright (c) 1992, 1993, 1994 Sam Leffler
+ * Copyright (c) 1992, 1993, 1994 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+
+static int   copyTiff    PARM((TIFF *, char *));
+static int   cpStrips    PARM((TIFF *, TIFF *));
+static int   cpTiles     PARM((TIFF *, TIFF *));
 static byte *loadPalette PARM((TIFF *, uint32, uint32, int, int, PICINFO *));
 static byte *loadColor   PARM((TIFF *, uint32, uint32, int, int, PICINFO *));
 static int   loadImage   PARM((TIFF *, uint32, uint32, byte *, int));
@@ -23,24 +52,29 @@
 
 static long  filesize;
 static byte *rmap, *gmap, *bmap;
-static char *filename;
+static const char *filename;
 
 static int   error_occurred;
 
+
 /*******************************************/
-int LoadTIFF(fname, pinfo)
-     char *fname;
+int LoadTIFF(fname, pinfo, quick)
+     char    *fname;
      PICINFO *pinfo;
+     int      quick;
 /*******************************************/
 {
   /* returns '1' on success, '0' on failure */
 
   TIFF  *tif;
   uint32 w, h;
+  float  xres, yres;
   short	 bps, spp, photo, orient;
   FILE  *fp;
   byte  *pic8;
   char  *desc, oldpath[MAXPATHLEN+1], tmppath[MAXPATHLEN+1], *sp;
+  char   tmp[256], tmpname[256];
+  int    i, nump;
 
   error_occurred = 0;
 
@@ -60,6 +94,8 @@
   filesize = ftell(fp);
   fclose(fp);
 
+
+
   rmap = pinfo->r;  gmap = pinfo->g;  bmap = pinfo->b;
 
   /* a kludge:  temporarily cd to the directory that the file is in (if
@@ -71,7 +107,7 @@
   if (fname[0] == '/') {
     xv_getwd(oldpath, sizeof(oldpath));
     strcpy(tmppath, fname);
-    sp = BaseName(tmppath);
+    sp = (char *) BaseName(tmppath);  /* intentionally losing constness */
     if (sp != tmppath) {
       sp[-1] = '\0';     /* truncate before last '/' char */
       if (chdir(tmppath)) {
@@ -80,10 +116,65 @@
       else filename = BaseName(fname);
     }
   }
-      
-    
 
-  tif=TIFFOpen(filename,"r");
+
+  nump = 1;
+
+  if (!quick) {
+    /* see if there's more than 1 image in tiff file, to determine if we
+       should do multi-page thing... */
+
+    tif = TIFFOpen(filename, "r");
+    if (!tif) return 0;
+    while (TIFFReadDirectory(tif)) ++nump;
+    TIFFClose(tif);
+    if (DEBUG)
+      fprintf(stderr,"LoadTIFF: %d page%s found\n", nump, nump==1 ? "" : "s");
+
+
+    /* if there are multiple images, copy them out to multiple tmp files,
+       and load the first one... */
+
+    if (nump>1) {
+      TIFF *in;
+
+      /* GRR 20050320:  converted this fake mktemp() to use mktemp()/mkstemp()
+         internally (formerly it simply prepended tmpdir to the string and
+         returned immediately) */
+      xv_mktemp(tmpname, "xvpgXXXXXX");
+
+      if (tmpname[0] == '\0') {   /* mktemp() or mkstemp() blew up */
+        sprintf(dummystr,"LoadTIFF: Unable to create temporary filename???");
+        ErrPopUp(dummystr, "\nHow unlikely!");
+        return 0;
+      }
+
+      /* GRR 20070506:  could clean up unappended tmpname-file here (Linux
+         bug?), but "cleaner" (more general) to do so in KillPageFiles() */
+
+      in = TIFFOpen(filename, "r");
+      if (!in) return 0;
+      for (i=1; i<=nump; i++) {
+	sprintf(tmp, "%s%d", tmpname, i);
+	if (!copyTiff(in, tmp)) {
+	  SetISTR(ISTR_WARNING, "LoadTIFF:  Error writing page files!");
+	  break;
+	}
+
+	if (!TIFFReadDirectory(in)) break;
+      }
+      TIFFClose(in);
+      if (DEBUG)
+	fprintf(stderr,"LoadTIFF: %d page%s written\n",
+		i-1, (i-1)==1 ? "" : "s");
+
+      sprintf(tmp, "%s%d", tmpname, 1);           /* start with page #1 */
+      filename = tmp;
+    }
+  }  /* if (!quick) ... */
+
+
+  tif = TIFFOpen(filename, "r");
   if (!tif) return 0;
 
   /* flip orientation so that image comes in X order */
@@ -107,6 +198,11 @@
   TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps);
   TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photo);
   TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
+  if ((TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) == 1) &&
+      (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) == 1)) {
+    normaspect = yres / xres;
+    if (DEBUG) fprintf(stderr,"TIFF aspect = %f\n", normaspect);
+  }
 
   if (spp == 1) {
       pic8 = loadPalette(tif, w, h, photo, bps, pinfo);
@@ -116,19 +212,19 @@
 
   /* try to get comments, if any */
   pinfo->comment = (char *) NULL;
-  
+
   desc = (char *) NULL;
 
   TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &desc);
   if (desc && strlen(desc) > (size_t) 0) {
     /* kludge:  tiff library seems to return bizarre comments */
-    if (strlen(desc)==4 && strcmp(desc, "\367\377\353\370")==0) {} 
+    if (strlen(desc)==4 && strcmp(desc, "\367\377\353\370")==0) {}
     else {
       pinfo->comment = (char *) malloc(strlen(desc) + 1);
       if (pinfo->comment) strcpy(pinfo->comment, desc);
     }
   }
-    
+
   TIFFClose(tif);
 
   /* un-kludge */
@@ -139,6 +235,8 @@
     if (pic8) free(pic8);
     if (pinfo->comment) free(pinfo->comment);
     pinfo->comment = (char *) NULL;
+    if (!quick && nump>1) KillPageFiles(tmpname, nump);
+    SetCursors(-1);
     return 0;
   }
 
@@ -148,15 +246,178 @@
   pinfo->normw = pinfo->w;   pinfo->normh = pinfo->h;
   pinfo->frmType = F_TIFF;
 
+  if (nump>1) strcpy(pinfo->pagebname, tmpname);
+  pinfo->numpages = nump;
 
   if (pinfo->pic) return 1;
 
+
   /* failed.  if we malloc'd a comment, free it */
   if (pinfo->comment) free(pinfo->comment);
   pinfo->comment = (char *) NULL;
 
+  if (!quick && nump>1) KillPageFiles(tmpname, nump);
+  SetCursors(-1);
+
   return 0;
-}  
+}
+
+
+
+
+/*******************************************/
+
+#define CopyField(tag, v) \
+  if (TIFFGetField(in, tag, &v))            TIFFSetField(out, tag, v)
+#define CopyField2(tag, v1, v2) \
+  if (TIFFGetField(in, tag, &v1, &v2))      TIFFSetField(out, tag, v1, v2)
+#define CopyField3(tag, v1, v2, v3) \
+  if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
+
+
+/*******************************************/
+static int copyTiff(in, fname)
+     TIFF *in;
+     char *fname;
+{
+  /* copies tiff (sub)image to given filename.  (Used only for multipage
+     images.)  Returns 0 on error */
+
+  TIFF   *out;
+  short   bitspersample, samplesperpixel, shortv, *shortav;
+  uint32  w, l;
+  float   floatv, *floatav;
+  char   *stringv;
+  uint32  longv;
+  uint16 *red, *green, *blue, shortv2;
+  int     rv;
+
+  out = TIFFOpen(fname, "w");
+  if (!out) return 0;
+
+  if (TIFFGetField(in, TIFFTAG_COMPRESSION, &shortv)){
+    /* Currently, the TIFF Library cannot correctly copy TIFF version 6.0 (or
+     * earlier) files that use "old" JPEG compression, so don't even try. */
+    if (shortv == COMPRESSION_OJPEG) return 0;
+    TIFFSetField(out, TIFFTAG_COMPRESSION, shortv);
+  }
+  CopyField (TIFFTAG_SUBFILETYPE,         longv);
+  CopyField (TIFFTAG_TILEWIDTH,           w);
+  CopyField (TIFFTAG_TILELENGTH,          l);
+  CopyField (TIFFTAG_IMAGEWIDTH,          w);
+  CopyField (TIFFTAG_IMAGELENGTH,         l);
+  CopyField (TIFFTAG_BITSPERSAMPLE,       bitspersample);
+  CopyField (TIFFTAG_PREDICTOR,           shortv);
+  CopyField (TIFFTAG_PHOTOMETRIC,         shortv);
+  CopyField (TIFFTAG_THRESHHOLDING,       shortv);
+  CopyField (TIFFTAG_FILLORDER,           shortv);
+  CopyField (TIFFTAG_ORIENTATION,         shortv);
+  CopyField (TIFFTAG_SAMPLESPERPIXEL,     samplesperpixel);
+  CopyField (TIFFTAG_MINSAMPLEVALUE,      shortv);
+  CopyField (TIFFTAG_MAXSAMPLEVALUE,      shortv);
+  CopyField (TIFFTAG_XRESOLUTION,         floatv);
+  CopyField (TIFFTAG_YRESOLUTION,         floatv);
+  CopyField (TIFFTAG_GROUP3OPTIONS,       longv);
+  CopyField (TIFFTAG_GROUP4OPTIONS,       longv);
+  CopyField (TIFFTAG_RESOLUTIONUNIT,      shortv);
+  CopyField (TIFFTAG_PLANARCONFIG,        shortv);
+  CopyField (TIFFTAG_ROWSPERSTRIP,        longv);
+  CopyField (TIFFTAG_XPOSITION,           floatv);
+  CopyField (TIFFTAG_YPOSITION,           floatv);
+  CopyField (TIFFTAG_IMAGEDEPTH,          longv);
+  CopyField (TIFFTAG_TILEDEPTH,           longv);
+  CopyField2(TIFFTAG_EXTRASAMPLES,        shortv, shortav);
+  CopyField3(TIFFTAG_COLORMAP,            red, green, blue);
+  CopyField2(TIFFTAG_PAGENUMBER,          shortv, shortv2);
+  CopyField (TIFFTAG_ARTIST,              stringv);
+  CopyField (TIFFTAG_IMAGEDESCRIPTION,    stringv);
+  CopyField (TIFFTAG_MAKE,                stringv);
+  CopyField (TIFFTAG_MODEL,               stringv);
+  CopyField (TIFFTAG_SOFTWARE,            stringv);
+  CopyField (TIFFTAG_DATETIME,            stringv);
+  CopyField (TIFFTAG_HOSTCOMPUTER,        stringv);
+  CopyField (TIFFTAG_PAGENAME,            stringv);
+  CopyField (TIFFTAG_DOCUMENTNAME,        stringv);
+  CopyField2(TIFFTAG_JPEGTABLES,          longv, stringv);
+  CopyField (TIFFTAG_YCBCRCOEFFICIENTS,   floatav);
+  CopyField2(TIFFTAG_YCBCRSUBSAMPLING,    shortv,shortv2);
+  CopyField (TIFFTAG_YCBCRPOSITIONING,    shortv);
+  CopyField (TIFFTAG_REFERENCEBLACKWHITE, floatav);
+
+  if (TIFFIsTiled(in)) rv = cpTiles (in, out);
+                  else rv = cpStrips(in, out);
+
+  TIFFClose(out);
+  return rv;
+}
+
+
+/*******************************************/
+static int cpStrips(in, out)
+     TIFF *in, *out;
+{
+  tsize_t bufsize;
+  byte *buf;
+
+  bufsize = TIFFStripSize(in);
+  if (bufsize <= 0) return 0;  /* tsize_t is signed */
+  buf = (byte *) malloc((size_t) bufsize);
+  if (buf) {
+    tstrip_t s, ns = TIFFNumberOfStrips(in);
+    uint32 *bytecounts;
+
+    TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts);
+    for (s = 0; s < ns; s++) {
+      if (bytecounts[s] > bufsize) {
+	buf = (unsigned char *) realloc(buf, (size_t) bytecounts[s]);
+	if (!buf) return (0);
+	bufsize = bytecounts[s];
+      }
+      if (TIFFReadRawStrip (in,  s, buf, (tsize_t) bytecounts[s]) < 0 ||
+	  TIFFWriteRawStrip(out, s, buf, (tsize_t) bytecounts[s]) < 0) {
+	free(buf);
+	return 0;
+      }
+    }
+    free(buf);
+    return 1;
+  }
+  return 0;
+}
+
+
+/*******************************/
+static int cpTiles(in, out)
+     TIFF *in, *out;
+{
+  tsize_t bufsize;
+  byte   *buf;
+
+  bufsize = TIFFTileSize(in);
+  if (bufsize <= 0) return 0;  /* tsize_t is signed */
+  buf = (unsigned char *) malloc((size_t) bufsize);
+  if (buf) {
+    ttile_t t, nt = TIFFNumberOfTiles(in);
+    uint32 *bytecounts;
+
+    TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts);
+    for (t = 0; t < nt; t++) {
+      if (bytecounts[t] > bufsize) {
+	buf = (unsigned char *)realloc(buf, (size_t) bytecounts[t]);
+	if (!buf) return (0);
+	bufsize = bytecounts[t];
+      }
+      if (TIFFReadRawTile (in,  t, buf, (tsize_t) bytecounts[t]) < 0 ||
+	  TIFFWriteRawTile(out, t, buf, (tsize_t) bytecounts[t]) < 0) {
+	free(buf);
+	return 0;
+      }
+    }
+    free(buf);
+    return 1;
+  }
+  return 0;
+}
 
 
 /*******************************************/
@@ -167,6 +428,7 @@
      PICINFO *pinfo;
 {
   byte *pic8;
+  uint32 npixels;
 
   switch (photo) {
   case PHOTOMETRIC_PALETTE:
@@ -178,7 +440,7 @@
   case PHOTOMETRIC_MINISWHITE:
   case PHOTOMETRIC_MINISBLACK:
     pinfo->colType = (bps==1) ? F_BWDITHER : F_GREYSCALE;
-    sprintf(pinfo->fullInfo,"TIFF, %u-bit, %s format.  (%ld bytes)", 
+    sprintf(pinfo->fullInfo,"TIFF, %u-bit, %s format.  (%ld bytes)",
 	    bps,
 	    photo == PHOTOMETRIC_MINISWHITE ? "min-is-white" :
 	    "min-is-black",
@@ -186,9 +448,16 @@
     break;
   }
 
-  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",w,h);
+  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",(u_int) w, (u_int) h);
+
+  npixels = w*h;
+  if (npixels/w != h) {
+    /* SetISTR(ISTR_WARNING, "loadPalette() - image dimensions too large"); */
+    TIFFError(filename, "Image dimensions too large");
+    return (byte *) NULL;
+  }
 
-  pic8 = (byte *) malloc((size_t) w*h);
+  pic8 = (byte *) malloc((size_t) npixels);
   if (!pic8) FatalError("loadPalette() - couldn't malloc 'pic8'");
 
   if (loadImage(tif, w, h, pic8, 0)) return pic8;
@@ -205,19 +474,28 @@
      PICINFO *pinfo;
 {
   byte *pic24, *pic8;
+  uint32 npixels, count;
 
   pinfo->colType = F_FULLCOLOR;
-  sprintf(pinfo->fullInfo, "TIFF, %u-bit, %s format.  (%ld bytes)", 
+  sprintf(pinfo->fullInfo, "TIFF, %u-bit, %s format.  (%ld bytes)",
 	  bps,
 	  (photo == PHOTOMETRIC_RGB ?	"RGB" :
 	   photo == PHOTOMETRIC_YCBCR ?	"YCbCr" :
 	   "???"),
 	  filesize);
 
-  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",w,h);
+  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",(u_int) w, (u_int) h);
+
+  npixels = w*h;
+  count = 3*npixels;
+  if (npixels/w != h || count/3 != npixels) {
+    /* SetISTR(ISTR_WARNING, "loadPalette() - image dimensions too large"); */
+    TIFFError(filename, "Image dimensions too large");
+    return (byte *) NULL;
+  }
 
   /* allocate 24-bit image */
-  pic24 = (byte *) malloc((size_t) w*h*3);
+  pic24 = (byte *) malloc((size_t) count);
   if (!pic24) FatalError("loadColor() - couldn't malloc 'pic24'");
 
   pic8 = (byte *) NULL;
@@ -249,7 +527,7 @@
   vsprintf(cp, fmt, ap);
   strcat(cp, ".");
 
-  SetISTR(ISTR_WARNING,buf);
+  SetISTR(ISTR_WARNING, "%s", buf);
 
   error_occurred = 1;
 }
@@ -273,7 +551,7 @@
   vsprintf(cp, fmt, ap);
   strcat(cp, ".");
 
-  SetISTR(ISTR_WARNING,buf);
+  SetISTR(ISTR_WARNING, "%s", buf);
 }
 
 
@@ -301,10 +579,14 @@
 static	byte **BWmap;
 static	byte **PALmap;
 
-typedef void (*tileContigRoutine)   PARM((byte*, u_char*, RGBvalue*, 
+/* XXX Work around some collisions with the new library. */
+#define tileContigRoutine _tileContigRoutine
+#define tileSeparateRoutine _tileSeparateRoutine
+
+typedef void (*tileContigRoutine)   PARM((byte*, u_char*, RGBvalue*,
 					  uint32, uint32, int, int));
 
-typedef void (*tileSeparateRoutine) PARM((byte*, u_char*, u_char*, u_char*, 
+typedef void (*tileSeparateRoutine) PARM((byte*, u_char*, u_char*, u_char*,
                                          RGBvalue*, uint32, uint32, int, int));
 
 
@@ -312,13 +594,13 @@
 
 static int    gt                       PARM((TIFF *, uint32, uint32, byte *));
 static uint32 setorientation           PARM((TIFF *, uint32));
-static int    gtTileContig             PARM((TIFF *, byte *, RGBvalue *, 
+static int    gtTileContig             PARM((TIFF *, byte *, RGBvalue *,
 					     uint32, uint32, int));
-static int    gtTileSeparate           PARM((TIFF *, byte *, RGBvalue *, 
+static int    gtTileSeparate           PARM((TIFF *, byte *, RGBvalue *,
 					     uint32, uint32, int));
-static int    gtStripContig            PARM((TIFF *, byte *, RGBvalue *, 
+static int    gtStripContig            PARM((TIFF *, byte *, RGBvalue *,
 					     uint32, uint32, int));
-static int    gtStripSeparate          PARM((TIFF *, byte *, RGBvalue *, 
+static int    gtStripSeparate          PARM((TIFF *, byte *, RGBvalue *,
 					     uint32, uint32, int));
 
 static int    makebwmap                PARM((void));
@@ -340,7 +622,7 @@
 					     uint32, uint32, int, int));
 static void   put4bitbwtile            PARM((byte *, u_char *, RGBvalue *,
 					     uint32, uint32, int, int));
-static void   put16bitbwtile           PARM((byte *, u_char *, RGBvalue *,
+static void   put16bitbwtile           PARM((byte *, u_short *, RGBvalue *,
 					     uint32, uint32, int, int));
 
 static void   putRGBcontig8bittile     PARM((byte *, u_char *, RGBvalue *,
@@ -349,22 +631,38 @@
 static void   putRGBcontig16bittile    PARM((byte *, u_short *, RGBvalue *,
 					     uint32, uint32, int, int));
 
-static void   putRGBseparate8bittile   PARM((byte *, u_char *, u_char *, 
-					     u_char *, RGBvalue *, 
+static void   putRGBseparate8bittile   PARM((byte *, u_char *, u_char *,
+					     u_char *, RGBvalue *,
 					     uint32, uint32, int, int));
 
-static void   putRGBseparate16bittile  PARM((byte *, u_short *, u_short *, 
-					    u_short *, RGBvalue *, 
+static void   putRGBseparate16bittile  PARM((byte *, u_short *, u_short *,
+					    u_short *, RGBvalue *,
 					    uint32, uint32, int, int));
 
 
-static void   initYCbCrConversion     PARM((void));
+static void   initYCbCrConversion      PARM((void));
 
-static void   putRGBContigYCbCrClump  PARM((byte *, u_char *, int, int, 
-					    uint32, int, int, int));
+static void   putRGBContigYCbCrClump   PARM((byte *, u_char *, int, int,
+					     uint32, int, int, int));
 
-static void   putcontig8bitYCbCrtile  PARM((byte *, u_char *, RGBvalue *,
-					  uint32, uint32, int, int));
+static void   putRGBSeparateYCbCrClump PARM((byte *, u_char *, u_char *,
+					     u_char *, int, int, uint32, int,
+					     int, int));
+  
+static void   putRGBSeparate16bitYCbCrClump PARM((byte *, u_short *, u_short *,
+						  u_short *, int, int, uint32,
+						  int, int, int));
+
+static void   putcontig8bitYCbCrtile   PARM((byte *, u_char *, RGBvalue *,
+					     uint32, uint32, int, int));
+
+static void   putYCbCrseparate8bittile PARM((byte *, u_char *, u_char *, 
+					     u_char *, RGBvalue *, 
+					     uint32, uint32, int, int));
+
+static void   putYCbCrseparate16bittile PARM((byte *, u_short *, u_short *, 
+					      u_short *, RGBvalue *, 
+					      uint32, uint32, int, int));
 
 static tileContigRoutine   pickTileContigCase   PARM((RGBvalue *));
 static tileSeparateRoutine pickTileSeparateCase PARM((RGBvalue *));
@@ -382,28 +680,28 @@
 
   TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
   switch (bitspersample) {
-  case 1: 
-  case 2: 
+  case 1:
+  case 2:
   case 4:
-  case 8: 
+  case 8:
   case 16:  break;
 
   default:
     TIFFError(TIFFFileName(tif),
-	      "Sorry, can not handle %d-bit pictures", bitspersample);
+	      "Sorry, cannot handle %d-bit pictures", bitspersample);
     return (0);
   }
 
 
   TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
   switch (samplesperpixel) {
-  case 1: 
-  case 3: 
+  case 1:
+  case 3:
   case 4:  break;
 
   default:
     TIFFError(TIFFFileName(tif),
-	      "Sorry, can not handle %d-channel images", samplesperpixel);
+	      "Sorry, cannot handle %d-channel images", samplesperpixel);
     return (0);
   }
 
@@ -462,39 +760,81 @@
      uint32 w, h;
      byte   *raster;
 {
+#ifdef USE_LIBJPEG_FOR_TIFF_YCbCr_RGB_CONVERSION
+  u_short compression;
+#endif
   u_short minsamplevalue, maxsamplevalue, planarconfig;
   RGBvalue *Map;
   int bpp = 1, e;
   int x, range;
 
+#ifdef USE_LIBJPEG_FOR_TIFF_YCbCr_RGB_CONVERSION
+  TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
+#endif
+  TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
   TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue);
   TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue);
   Map = NULL;
-  
+
   switch (photometric) {
   case PHOTOMETRIC_YCBCR:
-    TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS,
-			  &YCbCrCoeffs);
-    TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
-			  &YCbCrHorizSampling, &YCbCrVertSampling);
-    TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE,
-			  &refBlackWhite);
-    initYCbCrConversion();
+#ifdef USE_LIBJPEG_FOR_TIFF_YCbCr_RGB_CONVERSION
+    if (compression == COMPRESSION_JPEG
+#ifdef LIBTIFF_HAS_OLDJPEG_SUPPORT
+                                        || compression == COMPRESSION_OJPEG
+#endif
+                                                                            ) {
+      /* FIXME:  Remove the following test as soon as TIFF Library is fixed!
+       *   (Currently [June 2002] this requires supporting patches in both
+       *   tif_ojpeg.c and tif_jpeg.c in order to support subsampled YCbCr
+       *   images having separated color planes.) */
+      if (planarconfig == PLANARCONFIG_CONTIG) {
+        /* can rely on libjpeg to convert to RGB (assuming newer libtiff,
+         * compiled with appropriate forms of JPEG support) */
+        TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
+        photometric = PHOTOMETRIC_RGB;
+      } else {
+        TIFFError(filename, "Cannot handle format");
+        return (0);
+      }
+    } else
+#endif // USE_LIBJPEG_FOR_TIFF_YCbCr_RGB_CONVERSION
+    {
+      TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS, &YCbCrCoeffs);
+      TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
+			    &YCbCrHorizSampling, &YCbCrVertSampling);
+
+      /* According to the TIFF specification, if no "ReferenceBlackWhite"
+       * tag is present in the input file, "TIFFGetFieldDefaulted()" returns
+       * default reference black and white levels suitable for PHOTOMETRIC_RGB;
+       * namely:  <0,255,0,255,0,255>.  But for PHOTOMETRIC_YCBCR in JPEG
+       * images, the usual default (e.g., corresponding to the behavior of the
+       * IJG libjpeg) is:  <0,255,128,255,128,255>.  Since libtiff doesn't have
+       * a clean, standard interface for making this repair, the following
+       * slightly dirty code installs the default.  --Scott Marovich,
+       * Hewlett-Packard Labs, 9/2001.
+       */
+      if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite)) {
+        TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite);
+        refBlackWhite[4] = refBlackWhite[2] = 1 << (bitspersample - 1);
+      }
+      TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite);
+      initYCbCrConversion();
+    }
     /* fall thru... */
-	
+
   case PHOTOMETRIC_RGB:
     bpp *= 3;
     if (minsamplevalue == 0 && maxsamplevalue == 255)
       break;
-	
+
     /* fall thru... */
   case PHOTOMETRIC_MINISBLACK:
   case PHOTOMETRIC_MINISWHITE:
     range = maxsamplevalue - minsamplevalue;
     Map = (RGBvalue *)malloc((range + 1) * sizeof (RGBvalue));
     if (Map == NULL) {
-      TIFFError(filename,
-		"No space for photometric conversion table");
+      TIFFError(filename, "No space for photometric conversion table");
       return (0);
     }
 
@@ -509,7 +849,7 @@
     if (range<256) {
       for (x=0; x<=range; x++) rmap[x] = gmap[x] = bmap[x] = Map[x];
     } else {
-      for (x=0; x<256; x++) 
+      for (x=0; x<256; x++)
 	rmap[x] = gmap[x] = bmap[x] = Map[(range*x)/255];
     }
 
@@ -529,8 +869,7 @@
   case PHOTOMETRIC_PALETTE:
     if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
 		      &redcmap, &greencmap, &bluecmap)) {
-      TIFFError(filename,
-		"Missing required \"Colormap\" tag");
+      TIFFError(filename, "Missing required \"Colormap\" tag");
       return (0);
     }
 
@@ -571,7 +910,6 @@
     return (0);
   }
 
-  TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
   if (planarconfig == PLANARCONFIG_SEPARATE && samplesperpixel > 1) {
     e = TIFFIsTiled(tif) ? gtTileSeparate (tif, raster, Map, h, w, bpp) :
                            gtStripSeparate(tif, raster, Map, h, w, bpp);
@@ -590,6 +928,8 @@
      TIFF *tif;
      uint32 h;
 {
+  /* note that orientation was flipped in LoadTIFF() (near line 175) */
+
   uint32 y;
 
   TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation);
@@ -613,6 +953,11 @@
     orientation = ORIENTATION_TOPLEFT;
     /* fall thru... */
   case ORIENTATION_TOPLEFT:
+    /* GRR 20050319:  This may be wrong for tiled images (also stripped?);
+     *   looks like we want to return th-1 instead of h-1 in at least some
+     *   cases.  For now, just added quick hack (USE_TILED_TIFF_BOTLEFT_FIX)
+     *   to gtTileContig().  (Note that, as of libtiff 3.7.1, tiffcp still
+     *   has exactly the same bug.) */
     y = h-1;
     break;
   }
@@ -623,11 +968,11 @@
 
 
 /*
- * Get an tile-organized image that has
+ * Get a tile-organized image that has
  *	PlanarConfiguration contiguous if SamplesPerPixel > 1
  * or
  *	SamplesPerPixel == 1
- */	
+ */
 /*******************************************/
 static int gtTileContig(tif, raster, Map, h, w, bpp)
      TIFF *tif;
@@ -642,11 +987,14 @@
   int fromskew, toskew;
   u_int nrow;
   tileContigRoutine put;
+  tsize_t bufsize;
 
   put = pickTileContigCase(Map);
   if (put == 0) return (0);
 
-  buf = (u_char *) malloc((size_t) TIFFTileSize(tif));
+  bufsize = TIFFTileSize(tif);
+  if (bufsize <= 0) return 0;  /* tsize_t is signed */
+  buf = (u_char *) malloc((size_t) bufsize);
   if (buf == 0) {
     TIFFError(filename, "No space for tile buffer");
     return (0);
@@ -655,12 +1003,27 @@
   TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
   TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
   y = setorientation(tif, h);
+#ifdef USE_TILED_TIFF_BOTLEFT_FIX  /* image _originally_ ORIENTATION_BOTLEFT */
+  /* this fix causes tiles as a whole to be placed starting at the top,
+   * regardless of orientation; the only difference is what happens within
+   * a given tile (see toskew, below) */
+  /* GRR FIXME:  apply globally in setorientation()? */
+  if (orientation == ORIENTATION_TOPLEFT)
+    y = th-1;
+#endif
+  /* toskew causes individual tiles to copy from bottom to top for
+   * ORIENTATION_TOPLEFT and from top to bottom otherwise */
   toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
 
   for (row = 0; row < h; row += th) {
     nrow = (row + th > h ? h - row : th);
     for (col = 0; col < w; col += tw) {
-      if (TIFFReadTile(tif,buf,(uint32)col, (uint32)row, 0, 0) < 0
+      /*
+       * This reads the tile at (col,row) into buf.  "The data placed in buf
+       * are returned decompressed and, typically, in the native byte- and
+       * bit-ordering, but are otherwise packed."
+       */
+      if (TIFFReadTile(tif, buf, (uint32)col, (uint32)row, 0, 0) < 0
 	  && stoponerr) break;
 
       if (col + tw > w) {
@@ -670,14 +1033,18 @@
 	 */
 	uint32 npix = w - col;
 	fromskew = tw - npix;
-	(*put)(raster + (y*w + col)*bpp, buf, Map,   npix, (uint32) nrow,
-	       fromskew, (int) ((toskew + fromskew)*bpp));
+	(*put)(raster + (y*w + col)*bpp, buf, Map, npix, (uint32) nrow,
+	       fromskew, (int) ((toskew + fromskew)*bpp) );
       } else
-	(*put)(raster + (y*w + col)*bpp, buf, Map,   tw,   (uint32) nrow,
+	(*put)(raster + (y*w + col)*bpp, buf, Map, tw,   (uint32) nrow,
 	       0, (int) (toskew*bpp));
     }
 
+#ifdef USE_TILED_TIFF_BOTLEFT_FIX  /* image _originally_ ORIENTATION_BOTLEFT */
+    y += nrow;
+#else
     y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
+#endif
   }
   free(buf);
   return (1);
@@ -687,11 +1054,11 @@
 
 
 /*
- * Get an tile-organized image that has
+ * Get a tile-organized image that has
  *	 SamplesPerPixel > 1
  *	 PlanarConfiguration separated
  * We assume that all such images are RGB.
- */	
+ */
 
 /*******************************************/
 static int gtTileSeparate(tif, raster, Map, h, w, bpp)
@@ -701,20 +1068,26 @@
      uint32 h, w;
      int bpp;
 {
-  uint32 col, row, y;
   uint32 tw, th;
+  uint32 col, row, y;
   u_char *buf;
   u_char *r, *g, *b;
-  int tilesize;
+  tsize_t tilesize;
+  uint32 bufsize;
   int fromskew, toskew;
   u_int nrow;
   tileSeparateRoutine put;
-  
+
   put = pickTileSeparateCase(Map);
   if (put == 0) return (0);
 
   tilesize = TIFFTileSize(tif);
-  buf = (u_char *)malloc((size_t) (3*tilesize));
+  bufsize = 3*tilesize;
+  if (tilesize <= 0 || bufsize/3 != tilesize) {  /* tsize_t is signed */
+    TIFFError(filename, "Image dimensions too large");
+    return 0;
+  }
+  buf = (u_char *) malloc((size_t) bufsize);
   if (buf == 0) {
     TIFFError(filename, "No space for tile buffer");
     return (0);
@@ -751,10 +1124,10 @@
 	 */
 	uint32 npix = w - col;
 	fromskew = tw - npix;
-	(*put)(raster + (y*w + col)*bpp, r, g, b, Map, npix, (uint32) nrow, 
+	(*put)(raster + (y*w + col)*bpp, r, g, b, Map, npix, (uint32) nrow,
 	       fromskew, (int) ((toskew + fromskew)*bpp));
       } else
-	(*put)(raster + (y*w + col)*bpp, r, g, b, Map, tw, (uint32) nrow, 
+	(*put)(raster + (y*w + col)*bpp, r, g, b, Map, tw, (uint32) nrow,
 	       0, (int) (toskew*bpp));
     }
     y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
@@ -768,7 +1141,7 @@
  *	PlanarConfiguration contiguous if SamplesPerPixel > 1
  * or
  *	SamplesPerPixel == 1
- */	
+ */
 /*******************************************/
 static int gtStripContig(tif, raster, Map, h, w, bpp)
      TIFF *tif;
@@ -784,11 +1157,15 @@
   uint32 imagewidth;
   int scanline;
   int fromskew, toskew;
-  
+  tsize_t bufsize;
+
   put = pickTileContigCase(Map);
   if (put == 0)
     return (0);
-  buf = (u_char *) malloc((size_t) TIFFStripSize(tif));
+
+  bufsize = TIFFStripSize(tif);
+  if (bufsize <= 0) return 0;  /* tsize_t is signed */
+  buf = (u_char *) malloc((size_t) bufsize);
   if (buf == 0) {
     TIFFError(filename, "No space for strip buffer");
     return (0);
@@ -828,25 +1205,34 @@
      uint32 h, w;
      int bpp;
 {
+  uint32 nrow, row, y;
   u_char *buf;
   u_char *r, *g, *b;
-  uint32 row, y, nrow;
+  tsize_t stripsize;
+  uint32 bufsize;
+  int fromskew, toskew;
   int scanline;
   tileSeparateRoutine put;
   uint32 rowsperstrip;
   uint32 imagewidth;
-  u_int stripsize;
-  int fromskew, toskew;
-  
+
   stripsize = TIFFStripSize(tif);
-  r = buf = (u_char *) malloc((size_t) 3*stripsize);
-  if (buf == 0)
+  bufsize = 3*stripsize;
+  if (stripsize <= 0 || bufsize/3 != stripsize) {  /* tsize_t is signed */
+    TIFFError(filename, "Image dimensions too large");
+    return 0;
+  }
+  buf = (u_char *) malloc((size_t) bufsize);
+  if (buf == 0) {
+    TIFFError(filename, "No space for strip buffer");
     return (0);
+  }
+  r = buf;
   g = r + stripsize;
   b = g + stripsize;
   put = pickTileSeparateCase(Map);
   if (put == 0) {
-    TIFFError(filename, "Can not handle format");
+    TIFFError(filename, "Cannot handle format");
     return (0);
   }
   y = setorientation(tif, h);
@@ -861,7 +1247,7 @@
     nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
     band = 0;
     if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, (uint32) row, band),
-			     (tdata_t) r, (tsize_t)(nrow*scanline)) < 0 
+			     (tdata_t) r, (tsize_t)(nrow*scanline)) < 0
 	&& stoponerr) break;
 
     band = 1;
@@ -871,7 +1257,7 @@
 
     band = 2;
     if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, (uint32) row, band),
-			     (tdata_t) b, (tsize_t)(nrow*scanline)) < 0 
+			     (tdata_t) b, (tsize_t)(nrow*scanline)) < 0
 	&& stoponerr) break;
 
     (*put)(raster + y*w*bpp, r, g, b, Map, w, nrow, fromskew, toskew*bpp);
@@ -886,7 +1272,7 @@
 /*
  * Greyscale images with less than 8 bits/sample are handled
  * with a table to avoid lots of shifts and masks.  The table
- * is setup so that put*bwtile (below) can retrieve 8/bitspersample
+ * is set up so that put*bwtile (below) can retrieve 8/bitspersample
  * pixel values simply by indexing into the table with one
  * number.
  */
@@ -895,7 +1281,7 @@
   register int i;
   int nsamples = 8 / bitspersample;
   register byte *p;
-  
+
   BWmap = (byte **)malloc(
 			  256*sizeof (byte *)+(256*nsamples*sizeof(byte)));
   if (BWmap == NULL) {
@@ -938,18 +1324,18 @@
 
 
 /*
- * Palette images with <= 8 bits/sample are handled
- * with a table to avoid lots of shifts and masks.  The table
- * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
- * pixel values simply by indexing into the table with one
- * number.
+ * Palette images with <= 8 bits/sample are handled with
+ * a table to avoid lots of shifts and masks.  The table
+ * is set up so that put*cmaptile (below) can retrieve
+ * (8/bitspersample) pixel-values simply by indexing into
+ * the table with one number.
  */
 static int makecmap()
 {
   register int i;
   int nsamples = 8 / bitspersample;
   register byte *p;
-  
+
   PALmap = (byte **)malloc(
 			   256*sizeof (byte *)+(256*nsamples*sizeof(byte)));
   if (PALmap == NULL) {
@@ -994,7 +1380,7 @@
 /*
  * The following routines move decoded data returned
  * from the TIFF library into rasters filled with packed
- * ABGR pixels (i.e. suitable for passing to lrecwrite.)
+ * ABGR pixels (i.e., suitable for passing to lrecwrite.)
  *
  * The routines have been created according to the most
  * important cases and optimized.  pickTileContigCase and
@@ -1014,7 +1400,7 @@
 #define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }
 
 #define	UNROLL8(w, op1, op2) {		\
-	uint32 x;		        \
+	uint32 x;	                \
 	for (x = w; x >= 8; x -= 8) {	\
 		op1;			\
 		REPEAT8(op2);		\
@@ -1026,7 +1412,7 @@
 }
 
 #define	UNROLL4(w, op1, op2) {		\
-	register uint32 x;		\
+	uint32 x;		        \
 	for (x = w; x >= 4; x -= 4) {	\
 		op1;			\
 		REPEAT4(op2);		\
@@ -1038,7 +1424,7 @@
 }
 
 #define	UNROLL2(w, op1, op2) {		\
-	register uint32 x;		\
+	uint32 x;		        \
 	for (x = w; x >= 2; x -= 2) {	\
 		op1;			\
 		REPEAT2(op2);		\
@@ -1048,7 +1434,7 @@
 		op2;			\
 	}				\
 }
-			
+
 
 #define	SKEW(r,g,b,skew)	{ r += skew; g += skew; b += skew; }
 
@@ -1065,7 +1451,7 @@
      int fromskew, toskew;
 {
   while (h-- > 0) {
-    UNROLL8(w,0, *cp++ = PALmap[*pp++][0]);
+    UNROLL8(w, , *cp++ = PALmap[*pp++][0]);
     cp += toskew;
     pp += fromskew;
   }
@@ -1082,7 +1468,7 @@
      int       fromskew, toskew;
 {
   register byte *bw;
-  
+
   fromskew /= 2;
   while (h-- > 0) {
     UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
@@ -1103,7 +1489,7 @@
      int       fromskew, toskew;
 {
   register byte *bw;
-  
+
   fromskew /= 4;
   while (h-- > 0) {
     UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
@@ -1123,10 +1509,10 @@
 	int       fromskew, toskew;
 {
   register byte *bw;
-  
+
   fromskew /= 8;
   while (h-- > 0) {
-    UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
+    UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++)
     cp += toskew;
     pp += fromskew;
   }
@@ -1164,10 +1550,10 @@
      int fromskew, toskew;
 {
   register byte *bw;
-  
+
   fromskew /= 8;
   while (h-- > 0) {
-    UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
+    UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++)
     cp += toskew;
     pp += fromskew;
   }
@@ -1184,7 +1570,7 @@
      int fromskew, toskew;
 {
   register byte *bw;
-  
+
   fromskew /= 4;
   while (h-- > 0) {
     UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
@@ -1204,7 +1590,7 @@
      int fromskew, toskew;
 {
   register byte *bw;
-  
+
   fromskew /= 2;
   while (h-- > 0) {
     UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
@@ -1218,17 +1604,16 @@
  */
 static void put16bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
      byte  *cp;
-     u_char *pp;
+     u_short *pp;
      RGBvalue *Map;
      uint32 w, h;
      int fromskew, toskew;
 {
   register uint32   x;
-  
+
   while (h-- > 0) {
     for (x=w; x>0; x--) {
-      *cp++ = Map[(pp[0] << 8) + pp[1]];
-      pp += 2;
+      *cp++ = Map[*pp++];
     }
     cp += toskew;
     pp += fromskew;
@@ -1262,7 +1647,7 @@
     }
   } else {
     while (h-- > 0) {
-      UNROLL8(w,0,
+      UNROLL8(w, ,
 	      *cp++ = pp[0];
 	      *cp++ = pp[1];
 	      *cp++ = pp[2];
@@ -1284,7 +1669,7 @@
      int fromskew, toskew;
 {
   register u_int x;
-  
+
   fromskew *= samplesperpixel;
   if (Map) {
     while (h-- > 0) {
@@ -1320,7 +1705,7 @@
      RGBvalue *Map;
      uint32 w, h;
      int fromskew, toskew;
-     
+
 {
   if (Map) {
     while (h-- > 0) {
@@ -1335,7 +1720,7 @@
     }
   } else {
     while (h-- > 0) {
-      UNROLL8(w,0,
+      UNROLL8(w, ,
 	      *cp++ = *r++;
 	      *cp++ = *g++;
 	      *cp++ = *b++;
@@ -1357,7 +1742,7 @@
      int fromskew, toskew;
 {
   uint32 x;
-  
+
   if (Map) {
     while (h-- > 0) {
       for (x = w; x > 0; x--) {
@@ -1381,7 +1766,7 @@
   }
 }
 
-#define Code2V(c, RB, RW, CR)  ((((c)-(int)RB)*(float)CR)/(float)(RW-RB))
+#define Code2V(c, RB, RW, CR)  (((((int)c)-(int)RB)*(float)CR)/(float)(RW-RB))
 
 #define	CLAMP(f,min,max) \
     (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
@@ -1390,17 +1775,32 @@
 #define	LumaGreen	YCbCrCoeffs[1]
 #define	LumaBlue	YCbCrCoeffs[2]
 
-static	float D1, D2;
-static	float D3, D4, D5;
+static	float D1, D2, D3, D4 /*, D5 */;
 
 
 static void initYCbCrConversion()
 {
+  /*
+   * Old, broken version (goes back at least to 19920426; made worse 19941222):
+   *   YCbCrCoeffs[] = {0.299, 0.587, 0.114}
+   *     D1 = 1.402
+   *     D2 = 0.714136
+   *     D3 = 1.772
+   *     D4 = 0.138691  <-- bogus
+   *     D5 = 1.70358   <-- unnecessary
+   *
+   * New, fixed version (GRR 20050319):
+   *   YCbCrCoeffs[] = {0.299, 0.587, 0.114}
+   *     D1 = 1.402
+   *     D2 = 0.714136
+   *     D3 = 1.772
+   *     D4 = 0.344136
+   */
   D1 = 2 - 2*LumaRed;
   D2 = D1*LumaRed / LumaGreen;
   D3 = 2 - 2*LumaBlue;
-  D4 = D2*LumaBlue / LumaGreen;
-  D5 = 1.0 / LumaGreen;
+  D4 = D3*LumaBlue / LumaGreen;  /* ARGH, used to be D2*LumaBlue/LumaGreen ! */
+/* D5 = 1.0 / LumaGreen; */      /* unnecessary */
 }
 
 static void putRGBContigYCbCrClump(cp, pp, cw, ch, w, n, fromskew, toskew)
@@ -1412,7 +1812,7 @@
 {
   float Cb, Cr;
   int j, k;
-  
+
   Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
   Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
   for (j = 0; j < ch; j++) {
@@ -1421,8 +1821,24 @@
       Y = Code2V(*pp++,
 		 refBlackWhite[0], refBlackWhite[1], 255);
       R = Y + Cr*D1;
+/*    G = Y*D5 - Cb*D4 - Cr*D2;  highly bogus! */
+      G = Y - Cb*D4 - Cr*D2;
       B = Y + Cb*D3;
-      G = Y*D5 - Cb*D4 - Cr*D2;
+      /*
+       * These are what the JPEG/JFIF equations--which aren't _necessarily_
+       * what JPEG/TIFF uses but which seem close enough--are supposed to be,
+       * according to Avery Lee (e.g., see http://www.fourcc.org/fccyvrgb.php):
+       *
+       *     R = Y + 1.402 (Cr-128)
+       *     G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
+       *     B = Y + 1.772 (Cb-128)
+       *
+       * Translated into xvtiff.c notation:
+       *
+       *     R = Y + Cr*D1
+       *     G = Y - Cb*D4' - Cr*D2   (i.e., omit D5 and fix D4)
+       *     B = Y + Cb*D3
+       */
       cp[3*k+0] = CLAMP(R,0,255);
       cp[3*k+1] = CLAMP(G,0,255);
       cp[3*k+2] = CLAMP(B,0,255);
@@ -1432,6 +1848,62 @@
   }
 }
 
+static void putRGBSeparateYCbCrClump(cp, y, cb, cr, cw, ch, w, n, fromskew, toskew)
+     byte *cp;
+     u_char *y, *cb, *cr;
+     int cw, ch;
+     uint32 w;
+     int n, fromskew, toskew;
+{
+  float Cb, Cr;
+  int j, k;
+  
+  Cb = Code2V(cb[0], refBlackWhite[2], refBlackWhite[3], 127);
+  Cr = Code2V(cr[0], refBlackWhite[4], refBlackWhite[5], 127);
+  for (j = 0; j < ch; j++) {
+    for (k = 0; k < cw; k++) {
+      float Y, R, G, B;
+      Y = Code2V(y[k], refBlackWhite[0], refBlackWhite[1], 255);
+      R = Y + Cr*D1;
+      G = Y - Cb*D4 - Cr*D2;
+      B = Y + Cb*D3;
+      cp[3*k+0] = CLAMP(R,0,255);
+      cp[3*k+1] = CLAMP(G,0,255);
+      cp[3*k+2] = CLAMP(B,0,255);
+    }
+    cp += w*3 + toskew;
+    y  += w + ch*fromskew;
+  }
+}
+
+static void putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, cw, ch, w, n, fromskew, toskew)
+     byte *cp;
+     u_short *y, *cb, *cr;
+     int cw, ch;
+     uint32 w;
+     int n, fromskew, toskew;
+{
+  float Cb, Cr;
+  int j, k;
+  
+  Cb = Code2V(cb[0], refBlackWhite[2], refBlackWhite[3], 127);
+  Cr = Code2V(cr[0], refBlackWhite[4], refBlackWhite[5], 127);
+  for (j = 0; j < ch; j++) {
+    for (k = 0; k < cw; k++) {
+      float Y, R, G, B;
+      Y = Code2V(y[k], refBlackWhite[0], refBlackWhite[1], 255);
+      R = Y + Cr*D1;
+      G = Y - Cb*D4 - Cr*D2;
+      B = Y + Cb*D3;
+      cp[3*k+0] = CLAMP(R,0,255);
+      cp[3*k+1] = CLAMP(G,0,255);
+      cp[3*k+2] = CLAMP(B,0,255);
+    }
+    cp += w*3 + toskew;
+    y  += w + ch*fromskew;
+  }
+}
+
 #undef LumaBlue
 #undef LumaGreen
 #undef LumaRed
@@ -1452,7 +1924,7 @@
   u_int Coff = YCbCrVertSampling * YCbCrHorizSampling;
   byte *tp;
   uint32 x;
-  
+
   /* XXX adjust fromskew */
   while (h >= YCbCrVertSampling) {
     tp = cp;
@@ -1481,19 +1953,122 @@
       pp += Coff+2;
     }
     if (x > 0)
-      putRGBContigYCbCrClump(tp, pp, (int) x, (int) h, w, 
+      putRGBContigYCbCrClump(tp, pp, (int) x, (int) h, w,
 			     (int)Coff, (int)(YCbCrHorizSampling-x),toskew);
   }
 }
 
 /*
+ * 8-bit unpacked YCbCr samples => RGB
+ */
+static void putYCbCrseparate8bittile(cp, y, cb, cr, Map, w, h, fromskew, toskew)
+     byte *cp;
+     u_char *y, *cb, *cr;
+     RGBvalue *Map;
+     uint32 w, h;
+     int fromskew, toskew;
+{
+  uint32 x;
+  int fromskew2 = fromskew/YCbCrHorizSampling;
+  
+  while (h >= YCbCrVertSampling) {
+    for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
+      putRGBSeparateYCbCrClump(cp, y, cb, cr, YCbCrHorizSampling,
+			       YCbCrVertSampling, w, 0, 0, toskew);
+      cp += 3*YCbCrHorizSampling;
+      y += YCbCrHorizSampling;
+      ++cb;
+      ++cr;
+    }
+    if (x > 0) {
+      putRGBSeparateYCbCrClump(cp, y, cb, cr, (int) x, YCbCrVertSampling,
+			       w, 0, (int)(YCbCrHorizSampling - x), toskew);
+      cp += x*3;
+      y += YCbCrHorizSampling;
+      ++cb;
+      ++cr;
+    }
+    cp += (YCbCrVertSampling - 1)*w*3 + YCbCrVertSampling*toskew;
+    y  += (YCbCrVertSampling - 1)*w + YCbCrVertSampling*fromskew;
+    cb += fromskew2;
+    cr += fromskew2;
+    h -= YCbCrVertSampling;
+  }
+  if (h > 0) {
+    for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
+      putRGBSeparateYCbCrClump(cp, y, cb, cr, YCbCrHorizSampling, (int) h,
+			       w, 0, 0, toskew);
+      cp += 3*YCbCrHorizSampling;
+      y += YCbCrHorizSampling;
+      ++cb;
+      ++cr;
+    }
+    if (x > 0)
+      putRGBSeparateYCbCrClump(cp, y, cb, cr, (int) x, (int) h, w, 
+			       0, (int)(YCbCrHorizSampling-x),toskew);
+  }
+}
+
+/*
+ * 16-bit unpacked YCbCr samples => RGB
+ */
+static void putYCbCrseparate16bittile(cp, y, cb, cr, Map, w, h, fromskew, toskew)
+     byte *cp;
+     u_short *y, *cb, *cr;
+     RGBvalue *Map;
+     uint32 w, h;
+     int fromskew, toskew;
+{
+  uint32 x;
+  int fromskew2 = fromskew/YCbCrHorizSampling;
+  
+  while (h >= YCbCrVertSampling) {
+    for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
+      putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, YCbCrHorizSampling,
+		 		    YCbCrVertSampling, w, 0, 0, toskew);
+      cp += 3*YCbCrHorizSampling;
+      y += YCbCrHorizSampling;
+      ++cb;
+      ++cr;
+    }
+    if (x > 0) {
+      putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, (int) x, YCbCrVertSampling,
+				    w, 0, (int)(YCbCrHorizSampling - x),
+				    toskew);
+      cp += x*3;
+      y += YCbCrHorizSampling;
+      ++cb;
+      ++cr;
+    }
+    cp += (YCbCrVertSampling - 1)*w*3 + YCbCrVertSampling*toskew;
+    y  += (YCbCrVertSampling - 1)*w + YCbCrVertSampling*fromskew;
+    cb += fromskew2;
+    cr += fromskew2;
+    h -= YCbCrVertSampling;
+  }
+  if (h > 0) {
+    for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
+      putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, YCbCrHorizSampling, (int) h,
+				    w, 0, 0, toskew);
+      cp += 3*YCbCrHorizSampling;
+      y += YCbCrHorizSampling;
+      ++cb;
+      ++cr;
+    }
+    if (x > 0)
+      putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, (int) x, (int) h, w, 
+			 	    0, (int)(YCbCrHorizSampling-x),toskew);
+  }
+}
+
+/*
  * Select the appropriate conversion routine for packed data.
  */
 static tileContigRoutine pickTileContigCase(Map)
      RGBvalue* Map;
 {
   tileContigRoutine put = 0;
-  
+
   switch (photometric) {
   case PHOTOMETRIC_RGB:
     switch (bitspersample) {
@@ -1501,7 +2076,7 @@
     case 16: put = (tileContigRoutine) putRGBcontig16bittile;  break;
     }
     break;
-    
+
   case PHOTOMETRIC_PALETTE:
     switch (bitspersample) {
     case 8: put = put8bitcmaptile; break;
@@ -1514,7 +2089,7 @@
   case PHOTOMETRIC_MINISWHITE:
   case PHOTOMETRIC_MINISBLACK:
     switch (bitspersample) {
-    case 16: put = put16bitbwtile; break;
+    case 16: put = (tileContigRoutine) put16bitbwtile; break;
     case 8:  put = putgreytile;    break;
     case 4:  put = put4bitbwtile;  break;
     case 2:  put = put2bitbwtile;  break;
@@ -1529,7 +2104,7 @@
     break;
   }
 
-  if (put==0) TIFFError(filename, "Can not handle format");
+  if (put==0) TIFFError(filename, "Cannot handle format");
   return (put);
 }
 
@@ -1537,14 +2112,14 @@
 /*
  * Select the appropriate conversion routine for unpacked data.
  *
- * NB: we assume that unpacked single channel data is directed
- *	 to the "packed routines.
+ * NB: we assume that unpacked single-channel data is directed
+ *	 to the "packed" routines.
  */
 static tileSeparateRoutine pickTileSeparateCase(Map)
      RGBvalue* Map;
 {
   tileSeparateRoutine put = 0;
-  
+
   switch (photometric) {
   case PHOTOMETRIC_RGB:
     switch (bitspersample) {
@@ -1552,12 +2127,41 @@
     case 16: put = (tileSeparateRoutine) putRGBseparate16bittile; break;
     }
     break;
+
+  case PHOTOMETRIC_YCBCR:
+    switch (bitspersample) {
+    case  8: put = (tileSeparateRoutine) putYCbCrseparate8bittile;  break;
+    case 16: put = (tileSeparateRoutine) putYCbCrseparate16bittile; break;
+    }
+    break;
   }
 
-  if (put==0) TIFFError(filename, "Can not handle format");
+  if (put==0) TIFFError(filename, "Cannot handle format");
   return (put);
 }
 
 
 
+/*******************************************/
+void
+VersionInfoTIFF()      /* GRR 19980605 */
+{
+  char temp[1024], *p, *q;
+
+  strcpy(temp, TIFFGetVersion());
+  p = temp;
+  while (!isdigit(*p))
+    ++p;
+  if ((q = strchr(p, '\n')) != NULL)
+    *q = '\0';
+
+  fprintf(stderr, "   Compiled with libtiff %s", p);
+#ifdef TIFFLIB_VERSION
+  fprintf(stderr, " of %d", TIFFLIB_VERSION);    /* e.g., 19960307 */
+#endif
+  fprintf(stderr, ".\n");
+}
+
+
+
 #endif /* HAVE_TIFF */
diff -ru xv-3.10a/xvtiffwr.c xv-3.10a-enhancements/xvtiffwr.c
--- xv-3.10a/xvtiffwr.c	1995-01-03 13:28:13.000000000 -0800
+++ xv-3.10a-enhancements/xvtiffwr.c	2007-05-12 14:07:58.000000000 -0700
@@ -9,15 +9,15 @@
 
 #ifdef HAVE_TIFF
 
-#include "tiffio.h"    /* has to be after xv.h, as it needs varargs/stdarg */
+#include <tiffio.h>    /* has to be after xv.h, as it needs varargs/stdarg */
 
 
 #define ALLOW_JPEG 0  /* set to '1' to allow 'JPEG' choice in dialog box */
 
 
 static void setupColormap   PARM((TIFF *, byte *, byte *, byte *));
-static int  WriteTIFF       PARM((FILE *, byte *, int, int, int, 
-				  byte *, byte *, byte *, int, int, 
+static int  WriteTIFF       PARM((FILE *, byte *, int, int, int,
+				  byte *, byte *, byte *, int, int,
 				  char *, int, char *));
 
 
@@ -29,7 +29,7 @@
 {
   short red[256], green[256], blue[256];
   int i;
-  
+
   /* convert 8-bit colormap to 16-bit */
   for (i=0; i<256; i++) {
 #define	SCALE(x)	((((int)x)*((1L<<16)-1))/255)
@@ -43,6 +43,7 @@
 
 
 /*******************************************/
+/* Returns '0' if successful. */
 static int WriteTIFF(fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle,
 		     fname,comp,comment)
      FILE *fp;
@@ -55,6 +56,13 @@
   TIFF *tif;
   byte *pix;
   int   i,j;
+  int   npixels = w*h;
+
+  if (w <= 0 || h <= 0 || npixels/w != h) {
+    SetISTR(ISTR_WARNING, "%s: image dimensions too large", fname);
+    /* TIFFError(fname, "Image dimensions too large"); */
+    return -1;
+  }
 
 #ifndef VMS
   tif = TIFFOpen(fname, "w");
@@ -62,7 +70,7 @@
   tif = TIFFFdOpen(dup(fileno(fp)), fname, "w");
 #endif
 
-  if (!tif) return 0;
+  if (!tif) return -1;   /* GRR:  was 0 */
 
   WaitCursor();
 
@@ -78,25 +86,36 @@
       TIFFSetField(tif, TIFFTAG_GROUP3OPTIONS,
 	  GROUP3OPT_2DENCODING+GROUP3OPT_FILLBITS);
 
+  if (comp == COMPRESSION_LZW)
+      TIFFSetField(tif, TIFFTAG_PREDICTOR, 2);
+
   TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
   TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
   TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
   TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, h);
 
   TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (int)2);
-  TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)1200.0);
-  TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)1200.0);
+  TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float) 72.0);
+  TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float) 72.0);
 
 
   /* write the image data */
 
   if (ptype == PIC24) {  /* only have to deal with FULLCOLOR or GREYSCALE */
     if (colorstyle == F_FULLCOLOR) {
+      int count = 3*npixels;
+
+      if (count/3 != npixels) {  /* already know w, h, npixels > 0 */
+        /* SetISTR(ISTR_WARNING, "%s: image dimensions too large", fname); */
+        TIFFError(fname, "Image dimensions too large");
+        return -1;
+      }
+
       TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,   8);
       TIFFSetField(tif, TIFFTAG_PHOTOMETRIC,     PHOTOMETRIC_RGB);
-      
-      TIFFWriteEncodedStrip(tif, 0, pic, w*h*3);
+
+      TIFFWriteEncodedStrip(tif, 0, pic, count);
     }
 
     else {  /* colorstyle == F_GREYSCALE */
@@ -106,13 +125,13 @@
       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,   8);
       TIFFSetField(tif, TIFFTAG_PHOTOMETRIC,    PHOTOMETRIC_MINISBLACK);
 
-      tpic = (byte *) malloc((size_t) w*h);
+      tpic = (byte *) malloc((size_t) npixels);
       if (!tpic) FatalError("unable to malloc in WriteTIFF()");
 
-      for (i=0, tp=tpic, sp=pic; i<w*h; i++, sp+=3) 
+      for (i=0, tp=tpic, sp=pic; i<npixels; i++, sp+=3)
 	*tp++ = MONO(sp[0],sp[1],sp[2]);
-      
-      TIFFWriteEncodedStrip(tif, 0, tpic, w*h);
+
+      TIFFWriteEncodedStrip(tif, 0, tpic, npixels);
 
       free(tpic);
     }
@@ -123,32 +142,42 @@
       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
       TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
       setupColormap(tif, rmap, gmap, bmap);
-      TIFFWriteEncodedStrip(tif, 0, pic, w*h);
+      TIFFWriteEncodedStrip(tif, 0, pic, npixels);
     }
 
     else if (colorstyle == F_GREYSCALE) {             /* 8-bit greyscale */
       byte rgb[256];
-      byte *tpic = (byte *) malloc((size_t) w*h);
+      byte *tpic = (byte *) malloc((size_t) npixels);
       byte *tp = tpic;
       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
       TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
       for (i=0; i<numcols; i++) rgb[i] = MONO(rmap[i],gmap[i],bmap[i]);
-      for (i=0, pix=pic; i<w*h; i++,pix++) {
+      for (i=0, pix=pic; i<npixels; i++,pix++) {
 	if ((i&0x7fff)==0) WaitCursor();
 	*tp++ = rgb[*pix];
       }
-      TIFFWriteEncodedStrip(tif, 0, tpic, w*h);
+      TIFFWriteEncodedStrip(tif, 0, tpic, npixels);
       free(tpic);
     }
 
     else if (colorstyle == F_BWDITHER) {             /* 1-bit B/W stipple */
       int bit,k,flipbw;
       byte *tpic, *tp;
+      tsize_t stripsize;  /* signed */
 
       flipbw = (MONO(rmap[0],gmap[0],bmap[0]) > MONO(rmap[1],gmap[1],bmap[1]));
       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 1);
       TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
-      tpic = (byte *) malloc((size_t) TIFFStripSize(tif));
+      stripsize = TIFFStripSize(tif);
+      if (stripsize <= 0) {
+        TIFFError(fname, "Image dimensions too large");
+        return -1;
+      }
+      tpic = (byte *) malloc((size_t) stripsize);
+      if (tpic == 0) {
+        TIFFError(fname, "No space for strip buffer");
+        return -1;
+      }
       tp = tpic;
       for (i=0, pix=pic; i<h; i++) {
 	if ((i&15)==0) WaitCursor();
@@ -167,7 +196,7 @@
 	  *tp++ = (byte) (k & 0xff);
 	}
       }
-      TIFFWriteEncodedStrip(tif, 0, tpic, TIFFStripSize(tif));
+      TIFFWriteEncodedStrip(tif, 0, tpic, stripsize);
       free(tpic);
     }
   }
@@ -209,16 +238,16 @@
 {
   int	     y;
 
-  tiffW = CreateWindow("xv tiff", "XVtiff", NULL, 
+  tiffW = CreateWindow("xv tiff", "XVtiff", NULL,
 		       TWIDE, THIGH, infofg, infobg, 0);
   if (!tiffW) FatalError("can't create tiff window!");
 
   XSelectInput(theDisp, tiffW, ExposureMask | ButtonPressMask | KeyPressMask);
 
-  BTCreate(&tbut[T_BOK], tiffW, TWIDE-140-1, THIGH-10-BUTTH-1, 60, BUTTH, 
+  BTCreate(&tbut[T_BOK], tiffW, TWIDE-140-1, THIGH-10-BUTTH-1, 60, BUTTH,
 	   "Ok", infofg, infobg, hicol, locol);
 
-  BTCreate(&tbut[T_BCANC], tiffW, TWIDE-70-1, THIGH-10-BUTTH-1, 60, BUTTH, 
+  BTCreate(&tbut[T_BCANC], tiffW, TWIDE-70-1, THIGH-10-BUTTH-1, 60, BUTTH,
 	   "Cancel", infofg, infobg, hicol, locol);
 
   y = 55;
@@ -237,7 +266,7 @@
 
   XMapSubwindows(theDisp, tiffW);
 }
-  
+
 
 /***************************************************/
 void TIFFDialog(vis)
@@ -288,9 +317,9 @@
 
   else if (xev->type == KeyPress) {
     XKeyEvent *e = (XKeyEvent *) xev;
-    char buf[128];  KeySym ks;  XComposeStatus status;  
+    char buf[128];  KeySym ks;  XComposeStatus status;
     int stlen;
-	
+
     stlen = XLookupString(e,buf,128,&ks,&status);
     buf[stlen] = '\0';
 
@@ -350,7 +379,7 @@
 static void drawTD(x,y,w,h)
 int x,y,w,h;
 {
-  char *title  = "Save TIFF file...";
+  const char *title  = "Save TIFF file...";
   int  i;
   XRectangle xr;
 
@@ -381,7 +410,7 @@
   /* check BUTTs */
 
   /* check the RBUTTS first, since they don't DO anything */
-  if ( (i=RBClick(compRB, x,y)) >= 0) { 
+  if ( (i=RBClick(compRB, x,y)) >= 0) {
     (void) RBTrack(compRB, i);
     return;
   }
@@ -417,7 +446,7 @@
     }
   }
     break;
-    
+
   case T_BCANC:	TIFFDialog(0);   break;
 
   default:	break;
diff -ru xv-3.10a/xvxbm.c xv-3.10a-enhancements/xvxbm.c
--- xv-3.10a/xvxbm.c	1994-12-22 14:34:41.000000000 -0800
+++ xv-3.10a-enhancements/xvxbm.c	2007-05-13 17:45:48.000000000 -0700
@@ -25,9 +25,9 @@
  *   move forward to next occurence of '0x'
  *   repeat
  */
- 
 
-static int xbmError PARM((char *, char *));
+
+static int xbmError PARM((const char *, const char *));
 
 
 /*******************************************/
@@ -44,7 +44,7 @@
   long   filesize;
   char   line[256], name[256];
   byte   hex[256];
-  char  *bname;
+  const char  *bname;
 
   k = 0;
 
@@ -59,7 +59,7 @@
 
   /* read width:  skip lines until we hit a #define */
   while (1) {
-    if (!fgets(line,256,fp)) 
+    if (!fgets(line,256,fp))
       return(xbmError(bname, "EOF reached in header info."));
 
     if (strncmp(line,"#define",    (size_t) 7)==0 &&
@@ -70,9 +70,9 @@
 
   /* read height:  skip lines until we hit another #define */
   while (1) {
-    if (!fgets(line,256,fp)) 
+    if (!fgets(line,256,fp))
       return(xbmError(bname, "EOF reached in header info."));
-    
+
     if (strncmp(line,"#define",    (size_t) 7)==0 &&
 	sscanf(line,"#define %s %d", name, &h)==2 &&
 	xv_strstr(name, "_height") != NULL) break;
@@ -84,18 +84,18 @@
   c = getc(fp);  c1 = getc(fp);
   while (c1!=EOF && !(c=='0' && c1=='x') ) { c = c1;  c1 = getc(fp); }
 
-  if (c1==EOF) 
+  if (c1==EOF)
     return(xbmError(bname, "No bitmap data found"));
 
-  if (w<1 || h<1 || w>10000 || h>10000) 
+  if (w<1 || h<1 || w>10000 || h>10000)
     return(xbmError(bname, "not an XBM file"));
-  
-  pic8 = (byte *) calloc((size_t) w*h, (size_t) 1);
+
+  pic8 = (byte *) calloc((size_t) w*h, (size_t) 1);  /* safe (10^8 max) */
   if (!pic8) return(xbmError(bname, "couldn't malloc 'pic8'"));
 
   /* load up the pinfo structure */
   pinfo->pic = pic8;
-  pinfo->w = w;     
+  pinfo->w = w;
   pinfo->h = h;
   pinfo->normw = pinfo->w;   pinfo->normh = pinfo->h;
   pinfo->type = PIC8;
@@ -120,18 +120,18 @@
   /* read/convert the image data */
 
   for (i=0, pix=pic8; i<h; i++)
-    for (j=0,bit=0; j<w; j++, pix++, bit = (++bit)&7) {
+    for (j=0,bit=0; j<w; j++, pix++, bit = (bit+1)&7) {
 
       if (!bit) {
 	/* get next byte from file.  we're already positioned at it */
 	c = getc(fp);  c1 = getc(fp);
-	if (c<0 || c1<0) { 
-	  /* EOF: break out of loop */	  
+	if (c<0 || c1<0) {
+	  /* EOF: break out of loop */
 	  c=c1='0'; i=h; j=w;
 	  xbmError(bname, "The file would appear to be truncated.");
 	}
 
-	if (hex[c1] == 255) {  
+	if (hex[c1] == 255) {
 	  if (hex[c] == 255) k = 0;   /* no digits after the '0x' ... */
 	  else k = hex[c];
 	}
@@ -149,13 +149,13 @@
   fclose(fp);
 
   return 1;
-}  
+}
 
 
 
 /*******************************************/
 static int xbmError(fname, st)
-     char *fname, *st;
+     const char *fname, *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", fname, st);
   return 0;
@@ -172,7 +172,7 @@
 {
   /* pic is expected to be an array of w*h bytes, each of which is either
      '0' or '1'.
-     The 'darker' of {rmap,gmap,bmap}[0] and {rmap,gmap,bmap}[1] is 
+     The 'darker' of {rmap,gmap,bmap}[0] and {rmap,gmap,bmap}[1] is
      considered black, and the other one, white.
      Some sort of stippling algorithm should've
      been called already to produce pic, otherwise the output won't be at all
@@ -182,13 +182,12 @@
   byte *pix;
   char name[256], *foo;
 
-  foo = BaseName(fname);
-  strcpy(name, foo);
+  strcpy(name, BaseName(fname));
 
   foo = (char *) index(name,'.');
   if (foo) *foo='\0';                 /* truncated name at first '.' */
 
-  fprintf(fp,"#define %s_width %d\n",name,w);  
+  fprintf(fp,"#define %s_width %d\n",name,w);
   fprintf(fp,"#define %s_height %d\n",name,h);
   fprintf(fp,"static char %s_bits[] = {\n",name);
 
diff -ru xv-3.10a/xvxpm.c xv-3.10a-enhancements/xvxpm.c
--- xv-3.10a/xvxpm.c	1994-12-22 14:34:42.000000000 -0800
+++ xv-3.10a-enhancements/xvxpm.c	2007-05-13 17:52:21.000000000 -0700
@@ -10,7 +10,7 @@
  * format images.
  *
  * Thanks go to Sam Yates (syates@spam.maths.adelaide.edu.au) for
- * provideing inspiration.
+ * providing inspiration.
  */
 
 #define VALUES_LEN	80	/* Max length of values line */
@@ -48,8 +48,8 @@
                                 /*  a quoted string? */
 
 /* Local Functions */
-static int     XpmLoadError  PARM((char*, char*));
-static int     XpmGetc	     PARM((FILE*));
+static int     XpmLoadError  PARM((const char *, const char *));
+static int     XpmGetc	     PARM((FILE *));
 static int     hash          PARM((char *));
 static int     hash_init     PARM((int));
 static int     hash_insert   PARM((hentry *));
@@ -63,110 +63,128 @@
      PICINFO *pinfo;
 {
   /* returns '1' on success */
-  
+
   FILE    *fp;
   hentry   item;
   int      c;
-  char    *bname;
+  const char *bname;
   char     values[VALUES_LEN];
   byte    *pic;
   byte    *i_sptr;		/* image search pointer */
   long     filesize;
   int      w, h, nc, cpp, line_pos;
+  int      npixels;
   short    i, j, k;		/* for() loop indexes */
   hentry  *clmp;		/* colormap hash-table */
   hentry  *c_sptr;		/* cmap hash-table search pointer*/
   XColor   col;
-  
+
   bname = BaseName(fname);
   fp = fopen(fname, "r");
   if (!fp)
     return (XpmLoadError(bname, "couldn't open file"));
-  
+
   if (DEBUG)
     printf("LoadXPM(): Loading xpm from %s\n", fname);
-  
+
   fseek(fp, 0L, 2);
   filesize = ftell(fp);
   fseek(fp, 0L, 0);
-  
+
   bufchar = -2;
   in_quote = FALSE;
-  
+
   /* Read in the values line.  It is the first string in the
    * xpm, and contains four numbers.  w, h, num_colors, and
    * chars_per_pixel. */
-  
+
   /* First, get to the first string */
   while (((c = XpmGetc(fp))!=EOF) && (c != '"')) ;
   line_pos = 0;
-  
+
   /* Now, read in the string */
   while (((c = XpmGetc(fp))!=EOF) && (line_pos < VALUES_LEN) && (c != '"')) {
     values[line_pos++] = c;
   }
   if (c != '"')
     return (XpmLoadError(bname, "error parsing values line"));
-  
+
   values[line_pos] = '\0';
   sscanf(values, "%d%d%d%d", &w, &h, &nc, &cpp);
   if (nc <= 0 || cpp <= 0)
     return (XpmLoadError(bname, "No colours in Xpm?"));
-  
+
+  npixels = w * h;
+  if (w <= 0 || h <= 0 || npixels/w != h)
+    return (XpmLoadError(bname, "Image dimensions out of range"));
+
   if (nc > 256)
     pinfo->type = PIC24;
   else
     pinfo->type = PIC8;
-  
+
   if (DEBUG)
     printf("LoadXPM(): reading a %dx%d image (%d colors)\n", w, h, nc);
-  
+
   /* We got this far... */
   WaitCursor();
-  
+
   if (!hash_init(nc))
     return (XpmLoadError(bname, "Not enough memory to hash colormap"));
-  
+
   clmp = (hentry *) malloc(nc * sizeof(hentry)); /* Holds the colormap */
-  if (pinfo->type == PIC8) pic = (byte *) malloc((size_t) (w*h));
-                      else pic = (byte *) malloc((size_t) (w*h*3));
-  
+  if (pinfo->type == PIC8)
+    pic = (byte *) malloc((size_t) npixels);
+  else {
+    int bufsize = 3*npixels;
+    if (bufsize/3 != npixels)
+      return (XpmLoadError(bname, "Image dimensions out of range"));
+    pic = (byte *) malloc((size_t) bufsize);
+  }
+
   if (!clmp || !pic)
     return (XpmLoadError(bname, "Not enough memory to load pixmap"));
-  
+
   c_sptr = clmp;
   i_sptr = pic;
-  
+
   /* initialize the 'hex' array for zippy ASCII-hex -> int conversion */
-  
+
   for (i = 0 ; i < 256 ; i++)   hex[i] = 0;
   for (i = '0'; i <= '9' ; i++) hex[i] = i - '0';
   for (i = 'a'; i <= 'f' ; i++) hex[i] = i - 'a' + 10;
   for (i = 'A'; i <= 'F' ; i++) hex[i] = i - 'A' + 10;
-  
+
   /* Again, we've made progress. */
   WaitCursor();
-  
+
   /* Now, we need to read the colormap. */
   pinfo->colType = F_BWDITHER;
   for (i = 0 ; i < nc ; i++) {
     while (((c = XpmGetc(fp))!=EOF) && (c != '"')) ;
     if (c != '"')
       return (XpmLoadError(bname, "Error reading colormap"));
-    
+
     for (j = 0 ; j < cpp ; j++)
       c_sptr->token[j] = XpmGetc(fp);
     c_sptr->token[j] = '\0';
-    
+
     while (((c = XpmGetc(fp))!=EOF) && ((c == ' ') || (c == '\t'))) ;
     if (c == EOF)		/* The failure condition of getc() */
       return (XpmLoadError(bname, "Error parsing colormap line"));
-    
+
     do {
       char  key[3];
-      char  color[40];	/* Need to figure a good size for this... */
-      short hd;		/* Hex digits per R, G, or B */
-      
+      char  color[80];	/* Need to figure a good size for this... */
+
+/*
+ *  Problem with spaces in color names
+ *
+ *    X s Color Name m Other Name c Last Name
+ *
+ *  ... this parser doesn't find `Any Name'
+ */
+
       for (j=0; j<2 && (c != ' ') && (c != '\t') && (c != EOF); j++) {
 	key[j] = c;
 	c = XpmGetc(fp);
@@ -177,7 +195,7 @@
       if (c == EOF)	/* The failure condition of getc() */
 	return (XpmLoadError(bname, "Error parsing colormap line"));
 
-      for (j=0; j<39 && (c!=' ') && (c!='\t') && (c!='"') && c!=EOF; j++) {
+      for (j=0; j<79 && (c!=' ') && (c!='\t') && (c!='"') && c!=EOF; j++) {
 	color[j] = c;
 	c = XpmGetc(fp);
       }
@@ -185,14 +203,14 @@
 
       while ((c == ' ') || (c == '\t'))
 	c = XpmGetc(fp);
-      
+
       if (DEBUG > 1)
 	printf("LoadXPM(): Got color key '%s', color '%s'\n",
 	       key, color);
-      
+
       if (key[0] == 's')	/* Don't find a color for a symbolic name */
 	continue;
-      
+
       if (XParseColor(theDisp,theCmap,color,&col)) {
 	if (pinfo->type == PIC8) {
 	  pinfo->r[i] = col.red >> 8;
@@ -201,8 +219,8 @@
 	  c_sptr->cv_index = i;
 
 	  /* Is there a better way to do this? */
-	  if (pinfo->colType != F_FULLCOLOR)
-	    if (pinfo->colType == F_GREYSCALE)
+	  if (pinfo->colType != F_FULLCOLOR) {
+	    if (pinfo->colType == F_GREYSCALE) {
 	      if (pinfo->r[i] == pinfo->g[i] &&
 		  pinfo->g[i] == pinfo->b[i])
 		/* Still greyscale... */
@@ -210,9 +228,9 @@
 	      else
 		/* It's color */
 		pinfo->colType = F_FULLCOLOR;
-	    else
+	    } else {
 	      if (pinfo->r[i] == pinfo->g[i] &&
-		  pinfo->g[i] == pinfo->b[i])
+		  pinfo->g[i] == pinfo->b[i]) {
 		if ((pinfo->r[i] == 0 || pinfo->r[i] == 0xff) &&
 		    (pinfo->g[i] == 0 || pinfo->g[i] == 0xff) &&
 		    (pinfo->b[i] == 0 || pinfo->b[i] == 0xff))
@@ -221,10 +239,12 @@
 		else
 		  /* It's greyscale */
 		  pinfo->colType = F_GREYSCALE;
-	      else
+	      } else
 		/* It's color */
 		pinfo->colType = F_FULLCOLOR;
-	  
+	    }
+	  }
+
 	}
 	else {   /* PIC24 */
 	  c_sptr->cv_rgb[0] = col.red >> 8;
@@ -236,13 +256,13 @@
       else {      /* 'None' or unrecognized color spec */
 	int rgb;
 
-	if (strcmp(color, "None") == 0) rgb = 0xb2c0dc;  /* infobg */
+	if (strcasecmp(color, "None") == 0) rgb = 0xb2c0dc;  /* infobg */
 	else {
 	  SetISTR(ISTR_INFO, "%s:  unknown color spec '%s'", bname, color);
 	  Timer(1000);
 	  rgb = 0x808080;
 	}
-	
+
 	if (pinfo->type == PIC8) {
 	  pinfo->r[i] = (rgb>>16) & 0xff;
 	  pinfo->g[i] = (rgb>> 8) & 0xff;
@@ -256,39 +276,39 @@
 	}
       }
 
-      
+
       xvbcopy((char *) c_sptr, (char *) &item, sizeof(item));
       hash_insert(&item);
-      
-      if (DEBUG > 1) 
+
+      if (DEBUG > 1)
 	printf("LoadXPM():  Cmap entry %d, 0x%02x 0x%02x 0x%02x, token '%s'\n",
 	       i, pinfo->r[i], pinfo->g[i], pinfo->b[i], c_sptr->token);
-      
+
       if (*key == 'c') {	/* This is the color entry, keep it. */
 	while (c!='"' && c!=EOF) c = XpmGetc(fp);
 	break;
       }
-      
+
     } while (c != '"');
     c_sptr++;
 
     if (!(i%13)) WaitCursor();
   } /* for */
-  
+
 
   if (DEBUG)
     printf("LoadXPM(): Read and stored colormap.\n");
-  
+
   /* Now, read the pixmap. */
   for (i = 0 ; i < h ; i++) {
     while (((c = XpmGetc(fp))!=EOF) && (c != '"')) ;
     if (c != '"')
       return (XpmLoadError(bname, "Error reading colormap"));
-    
+
     for (j = 0 ; j < w ; j++) {
       char pixel[TOKEN_LEN];
       hentry *mapentry;
-      
+
       for (k = 0 ; k < cpp ; k++)
 	pixel[k] = XpmGetc(fp);
       pixel[k] = '\0';
@@ -300,7 +320,7 @@
 		 pixel);
 	return (XpmLoadError(bname, "Can't map resolve into colormap"));
       }
-      
+
       if (pinfo->type == PIC8)
 	*i_sptr++ = mapentry->cv_index;
       else {
@@ -309,35 +329,36 @@
 	*i_sptr++ = mapentry->cv_rgb[2];
       }
     }  /* for ( j < w ) */
-    (void)XpmGetc(fp);		/* Throw away the close " */
-  
+    while (((c = XpmGetc(fp))!=EOF) &&		/* Throw away the close " and */
+	(c != '"'));				/* erase all remaining pixels */
+
     if (!(i%7)) WaitCursor();
   }  /* for ( i < h ) */
-  
+
   pinfo->pic = pic;
   pinfo->normw = pinfo->w = w;
   pinfo->normh = pinfo->h = h;
   pinfo->frmType = F_XPM;
 
   if (DEBUG) printf("LoadXPM(): pinfo->colType is %d\n", pinfo->colType);
-  
+
   sprintf(pinfo->fullInfo, "Xpm v3 Pixmap (%ld bytes)", filesize);
   sprintf(pinfo->shrtInfo, "%dx%d Xpm.", w, h);
   pinfo->comment = (char *)NULL;
-  
+
   hash_destroy();
   free(clmp);
-  
+
   if (fp != stdin)
     fclose(fp);
-  
+
   return(1);
 }
 
 
 /***************************************/
 static int XpmLoadError(fname, st)
-     char *fname, *st;
+     const char *fname, *st;
 {
   SetISTR(ISTR_WARNING, "%s:  %s", fname, st);
   return 0;
@@ -349,17 +370,17 @@
      FILE *f;
 {
   int	c, d, lastc;
-  
+
   if (bufchar != -2) {
     /* The last invocation of this routine read the character... */
     c = bufchar;
     bufchar = -2;
     return(c);
   }
-  
+
   if ((c = getc(f)) == EOF)
     return(EOF);
-  
+
   if (c == '"')
     in_quote = !in_quote;
   else if (!in_quote && c == '/') {	/* might be a C-style comment */
@@ -389,14 +410,14 @@
 
 
 /***************************************/
-static int hash(token) 
+static int hash(token)
      char *token;
 {
   int i, sum;
 
   for (i=sum=0; token[i] != '\0'; i++)
     sum += token[i];
-  
+
   sum = sum % hash_len;
   return (sum);
 }
@@ -414,7 +435,7 @@
    */
 
   int i;
-  
+
   hash_len = 257;
 
   hashtab = (hentry **) malloc(sizeof(hentry *) * hash_len);
@@ -425,7 +446,7 @@
 
   for (i = 0 ; i < hash_len ; i++)
     hashtab[i] = NULL;
-  
+
   return 1;
 }
 
@@ -436,22 +457,22 @@
 {
   int     key;
   hentry *tmp;
-  
+
   key = hash(entry->token);
-  
+
   tmp = (hentry *) malloc(sizeof(hentry));
   if (!tmp) {
     SetISTR(ISTR_WARNING, "Couldn't malloc hash entry in LoadXPM()!\n");
     return 0;
   }
-  
+
   xvbcopy((char *)entry, (char *)tmp, sizeof(hentry));
-  
+
   if (hashtab[key]) tmp->next = hashtab[key];
                else tmp->next = NULL;
-  
+
   hashtab[key] = tmp;
-  
+
   return 1;
 }
 
@@ -462,9 +483,9 @@
 {
   int     key;
   hentry *tmp;
-  
+
   key = hash(token);
-  
+
   tmp = hashtab[key];
   while (tmp && strcmp(token, tmp->token)) {
     tmp = tmp->next;
@@ -479,7 +500,7 @@
 {
   int     i;
   hentry *tmp;
-  
+
   for (i=0; i<hash_len; i++) {
     while (hashtab[i]) {
       tmp = hashtab[i]->next;
@@ -487,7 +508,7 @@
       hashtab[i] = tmp;
     }
   }
-  
+
   free(hashtab);
   return;
 }
@@ -508,10 +529,10 @@
   /* Note here, that tokenchars is assumed to contain 64 valid token */
   /* characters.  It's hardcoded to assume this for benefit of generating */
   /* tokens, when there are more than 64^2 colors. */
-  
+
   short	i, imax, j;	/* for() loop indices */
   short	cpp = 0;
-  char	*tokenchars = 
+  const char *tokenchars =
             ".#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
   char	*tokens;
   char	image_name[256], *foo;
@@ -523,20 +544,20 @@
   long	li;		/* for() loop index */
   int	numcol;
 #endif
-  
-  if (DEBUG)
+
+  if (DEBUG) {
     if (ptype == PIC8)
       printf("WriteXPM(): Write a %d color, colortype %d, PIC8 image.\n",
 	     nc, col);
     else
       printf("WriteXPM(): Write a colortype %d, PIC24 image.\n", col);
-  
-  foo = BaseName(name);
-  strcpy(image_name, foo);
+  }
+
+  strcpy(image_name, BaseName(name));
   foo = (char *)strchr(image_name, '.');
   if (foo)
     *foo = '\0';		/* Truncate name at first '.' */
-  
+
 #ifdef USE_UNFINISHED_24BIT_WRITING_CODE
   if (ptype == PIC24)
     return -1;
@@ -547,15 +568,15 @@
   /* 'packed'.  Code in here to do that should be removed if       */
   /* Conv24to8 is "fixed" to do this...                            */
   /*    Chris P. Ross (cross@eng.umd.edu)  28-Sept-94              */
-  
+
   numcol = 0;
-  
+
   if (ptype == PIC24) {
     /* Reduce to an 8-bit image.  Would be nice to actually write */
     /* the 24-bit image.  I'll have to code that someday...       */
     pic8 = Conv24to8(pic, w, h, 256, rtemp, gtemp, btemp);
     if (!pic8) {
-      SetISTR(ISTR_WARNING, 
+      SetISTR(ISTR_WARNING,
 	      "%s:  Unable to convert to 8-bit image in WriteXPM()",
 	      image_name);
       return 1;
@@ -594,7 +615,7 @@
   }
 #endif
 
-  
+
 #ifdef USE_UNFINISHED_24BIT_WRITING_CODE
   if (ptype == PIC24) cpp = 4;
   else if (numcol > 64) cpp = 2;
@@ -609,7 +630,7 @@
   fprintf(fp, "/* width height num_colors chars_per_pixel */\n");
   fprintf(fp, "\"   %3d   %3d   %6d            %1d\",\n", w, h, numcol, cpp);
   fprintf(fp, "/* colors */\n");
-  
+
   switch (cpp) {
 
   case 1:			/* <= 64 colors; index into tokenchars */
@@ -681,12 +702,12 @@
 
   case 4:
     /* Generate a colormap */
-    
+
     break;
   default:
     break;
   }
-  
+
   if (fprintf(fp, "\"\n};\n") == EOF) {
     return 1;
   } else
diff -ru xv-3.10a/xvxwd.c xv-3.10a-enhancements/xvxwd.c
--- xv-3.10a/xvxwd.c	1994-12-22 14:34:40.000000000 -0800
+++ xv-3.10a-enhancements/xvxwd.c	2007-05-13 17:52:35.000000000 -0700
@@ -1,10 +1,10 @@
-/* 
+/*
  ** Based on xwdtopnm.c - read and write an X11 or X10 window dump file
  **
  ** Modified heavily by Markus Baur (mbaur@ira.uka.de) for use as a part
  ** of xv-2.21, 12/30/92
  **
- ** Hacked up again to support xv-3.00 and XWDs from 64bit machines 
+ ** Hacked up again to support xv-3.00 and XWDs from 64bit machines
  ** (e.g. DEC Alphas), 04/10/94
  **
  ** Copyright (C) 1989, 1991 by Jef Poskanzer.
@@ -24,42 +24,42 @@
 /***************************** x11wd.h *****************************/
 #define X11WD_FILE_VERSION 7
 typedef struct {
-    CARD32 header_size;         /* Size of the entire file header (bytes). */
-    CARD32 file_version;        /* X11WD_FILE_VERSION */
-    CARD32 pixmap_format;       /* Pixmap format */
-    CARD32 pixmap_depth;        /* Pixmap depth */
-    CARD32 pixmap_width;        /* Pixmap width */
-    CARD32 pixmap_height;       /* Pixmap height */
-    CARD32 xoffset;             /* Bitmap x offset */
-    CARD32 byte_order;          /* MSBFirst, LSBFirst */
-    CARD32 bitmap_unit;         /* Bitmap unit */
-    CARD32 bitmap_bit_order;    /* MSBFirst, LSBFirst */
-    CARD32 bitmap_pad;          /* Bitmap scanline pad */
-    CARD32 bits_per_pixel;      /* Bits per pixel */
-    CARD32 bytes_per_line;      /* Bytes per scanline */
-    CARD32 visual_class;        /* Class of colormap */
-    CARD32 red_mask;            /* Z red mask */
-    CARD32 green_mask;          /* Z green mask */
-    CARD32 blue_mask;           /* Z blue mask */
-    CARD32 bits_per_rgb;        /* Log base 2 of distinct color values */
-    CARD32 colormap_entries;    /* Number of entries in colormap */
-    CARD32 ncolors;             /* Number of Color structures */
-    CARD32 window_width;        /* Window width */
-    CARD32 window_height;       /* Window height */
-    CARD32 window_x;            /* Window upper left X coordinate */
-    CARD32 window_y;            /* Window upper left Y coordinate */
-    CARD32 window_bdrwidth;     /* Window border width */
+  CARD32 header_size;         /* Size of the entire file header (bytes). */
+  CARD32 file_version;        /* X11WD_FILE_VERSION */
+  CARD32 pixmap_format;       /* Pixmap format */
+  CARD32 pixmap_depth;        /* Pixmap depth */
+  CARD32 pixmap_width;        /* Pixmap width */
+  CARD32 pixmap_height;       /* Pixmap height */
+  CARD32 xoffset;             /* Bitmap x offset */
+  CARD32 byte_order;          /* MSBFirst, LSBFirst */
+  CARD32 bitmap_unit;         /* Bitmap unit */
+  CARD32 bitmap_bit_order;    /* MSBFirst, LSBFirst */
+  CARD32 bitmap_pad;          /* Bitmap scanline pad */
+  CARD32 bits_per_pixel;      /* Bits per pixel */
+  CARD32 bytes_per_line;      /* Bytes per scanline */
+  CARD32 visual_class;        /* Class of colormap */
+  CARD32 red_mask;            /* Z red mask */
+  CARD32 grn_mask;            /* Z green mask */
+  CARD32 blu_mask;            /* Z blue mask */
+  CARD32 bits_per_rgb;        /* Log base 2 of distinct color values */
+  CARD32 colormap_entries;    /* Number of entries in colormap */
+  CARD32 ncolors;             /* Number of Color structures */
+  CARD32 window_width;        /* Window width */
+  CARD32 window_height;       /* Window height */
+  CARD32 window_x;            /* Window upper left X coordinate */
+  CARD32 window_y;            /* Window upper left Y coordinate */
+  CARD32 window_bdrwidth;     /* Window border width */
 #ifdef WORD64
-    CARD32 header_pad;
+  CARD32 header_pad;
 #endif
-  } X11WDFileHeader;
+} X11WDFileHeader;
 
 typedef struct {
   CARD32 num;
   CARD16 red, green, blue;
-  CARD8  flags;                 /* do_red, do_green, do_blue */
+  CARD8  flags;               /* do_red, do_green, do_blue */
   CARD8  pad;
-  } X11XColor;
+} X11XColor;
 
 
 /*-------------------------------------------------------------------------*/
@@ -67,32 +67,35 @@
 typedef byte pixel;
 
 /* local functions */
-static int    getinit         PARM((FILE *, int*, int*, int*, CARD32 *, 
+static int    getinit         PARM((FILE *, int*, int*, int*, CARD32 *,
 			                          CARD32, PICINFO *));
 static CARD32 getpixnum       PARM((FILE *));
-static int    xwdError        PARM((char *));
-static void   xwdWarning      PARM((char *));
+static int    xwdError        PARM((const char *));
+static void   xwdWarning      PARM((const char *));
 static int    bs_short        PARM((int));
 static CARD32 bs_long         PARM((CARD32));
 static int    readbigshort    PARM((FILE *, CARD16 *));
 static int    readbiglong     PARM((FILE *, CARD32 *));
 static int    readlittleshort PARM((FILE *, CARD16 *));
 static int    readlittlelong  PARM((FILE *, CARD32 *));
+#if 0 /* NOTUSED */
 static int    writebigshort   PARM((FILE *, int));
 static int    writebiglong    PARM((FILE *, CARD32));
+#endif
 
 static byte  *pic8, *pic24;
 static CARD32 red_mask, green_mask, blue_mask;
-static int    bits_per_item, bits_used, bit_shift, bits_per_pixel;
+static int    red_shift, green_shift, blue_shift;
+static int    bits_per_item, bits_used, bit_shift,
+              bits_per_pixel, bits_per_rgb;
 static char   buf[4];
 static char   *byteP;
 static CARD16 *shortP;
 static CARD32 *longP;
 static CARD32 pixel_mask;
 static int    byte_swap, byte_order, bit_order, filesize;
-static byte   bw[2] = {0, 0xff};
 
-static char  *bname;
+static const char  *bname;
 
 
 
@@ -105,33 +108,38 @@
 
   pixel *xP;
   int    col;
-  int    rows, cols, padright, row;
-  CARD32 maxval, visualclass;
+  int    rows=0, cols=0, padright=0, row, npixels, bufsize;
+  CARD32 maxval=0, visualclass=0;
   FILE  *ifp;
 
   bname          = BaseName(fname);
   pinfo->pic     = (byte *) NULL;
   pinfo->comment = (char *) NULL;
-  maxval         = 0;
 
   ifp = xv_fopen(fname, "r");
   if (!ifp) return (xwdError("can't open file"));
-  
+
   /* figure out the file size (used to check colormap size) */
   fseek(ifp, 0L, 2);
   filesize = ftell(ifp);
   fseek(ifp, 0L, 0);
-  
+
 
   if (getinit(ifp, &cols, &rows, &padright, &visualclass, maxval, pinfo))
     return 0;
 
+  npixels = cols * rows;
+  if (cols <= 0 || rows <= 0 || npixels/cols != rows) {
+    xwdError("Image dimensions out of range");
+    return 0;
+  }
+
 
   switch (visualclass) {
   case StaticGray:
   case GrayScale:
     pinfo->colType = F_GREYSCALE;
-    pic8 = (byte *) calloc((size_t) cols*rows, (size_t) 1);
+    pic8 = (byte *) calloc((size_t) npixels, (size_t) 1);
     if (!pic8) {
       xwdError("couldn't malloc 'pic'");
       return 0;
@@ -140,18 +148,18 @@
     for (row=0; row<rows; row++) {
       for (col=0, xP=pic8+(row*cols); col<cols; col++, xP++)
 	*xP = getpixnum(ifp);
-      
+
       for (col=0; col<padright; col++) getpixnum(ifp);
     }
 
     pinfo->type = PIC8;
     pinfo->pic  = pic8;
-    break;      
+    break;
 
   case StaticColor:
   case PseudoColor:
     pinfo->colType = F_FULLCOLOR;
-    pic8 = (byte *) calloc((size_t) cols*rows, (size_t) 1);
+    pic8 = (byte *) calloc((size_t) npixels, (size_t) 1);
     if (!pic8) {
       xwdError("couldn't malloc 'pic'");
       return 0;
@@ -162,59 +170,70 @@
 	*xP = getpixnum(ifp);
       for (col=0; col<padright; col++) getpixnum(ifp);
     }
-    
+
     pinfo->type = PIC8;
     pinfo->pic  = pic8;
-    break;      
+    break;
 
   case TrueColor:
   case DirectColor:
     pinfo->colType = F_FULLCOLOR;
-    pic24 = (byte *) calloc((size_t) cols*rows*3, (size_t) 1);
+    bufsize = 3*npixels;
+    if (bufsize/3 != npixels) {
+      xwdError("Image dimensions out of range");
+      return 0;
+    }
+    pic24 = (byte *) calloc((size_t) bufsize, (size_t) 1);
     if (!pic24) {
       xwdError("couldn't malloc 'pic24'");
       return 0;
     }
 
-    for (row=0; row<rows; row++) {
-      for (col=0, xP=pic24+(row*cols*3); col<cols; col++) {
-	CARD32 ul;
-	
-	ul = getpixnum(ifp);
-	switch (bits_per_pixel) {
-	case 16:
-	  *xP++ = ((ul & red_mask)   >> 0);
-	  *xP++ = ((ul & green_mask) >> 5);
-	  *xP++ = ((ul & blue_mask)  >> 10);
-	  break;
-	  
-	case 24:
-	case 32:
-	  *xP++ = (ul    ) & 0xff;
-	  *xP++ = (ul>> 8) & 0xff;
-	  *xP++ = (ul>>16) & 0xff;
-	  break;
-	  
-	default:
-	  xwdError("True/Direct only supports 16, 24, and 32 bits");
-	  return 0;
-	}
-      }
+    switch (bits_per_pixel) {
+    case 16:
+    case 24:
+    case 32:
+      ;
+    default:
+      xwdError("True/Direct supports only 16, 24, and 32 bits");
+      return 0;
+    }
 
-      for (col=0; col<padright; col++) getpixnum(ifp);
+    if (byte_order == MSBFirst) {
+      for (row=0; row<rows; row++) {
+        for (col=0, xP=pic24+(row*cols*3); col<cols; col++) {
+          register CARD32 ul = getpixnum(ifp);
+
+          *xP++ = ul >> red_shift   & red_mask  ;
+          *xP++ = ul >> green_shift & green_mask;
+          *xP++ = ul >> blue_shift  & blue_mask ;
+        };
+        for (col=0; col<padright; col++) getpixnum(ifp);
+      }
+    } else {
+      for (row=0; row<rows; row++) {
+        for (col=0, xP=pic24+(row*cols*3); col<cols; col++) {
+          register CARD32 ul = getpixnum(ifp);
+
+          *xP++ = ul >> blue_shift  & blue_mask ;
+          *xP++ = ul >> green_shift & green_mask;
+          *xP++ = ul >> red_shift   & red_mask  ;
+        };
+        for (col=0; col<padright; col++) getpixnum(ifp);
+      }
     }
-    
+
     pinfo->type = PIC24;
     pinfo->pic  = pic24;
     break;
-    
+
   default:
     xwdError("unknown visual class");
     return 0;
   }
 
   sprintf(pinfo->fullInfo, "XWD, %d-bit %s.  (%d bytes)",
-	  bits_per_pixel, 
+	  bits_per_pixel,
 	  ((visualclass == StaticGray ) ? "StaticGray"  :
 	   (visualclass == GrayScale  ) ? "GrayScale"   :
 	   (visualclass == StaticColor) ? "StaticColor" :
@@ -258,10 +277,10 @@
   maxv = 255L;
 
   h11P = (X11WDFileHeader*) header;
-  
+
   if (fread(&header[0], sizeof(*h11P), (size_t) 1, file) != 1)
     return(xwdError("couldn't read X11 XWD file header"));
-  
+
   if (h11P->file_version != X11WD_FILE_VERSION) {
     byte_swap = 1;
     h11P->header_size      = bs_long(h11P->header_size);
@@ -279,8 +298,8 @@
     h11P->bytes_per_line   = bs_long(h11P->bytes_per_line);
     h11P->visual_class     = bs_long(h11P->visual_class);
     h11P->red_mask         = bs_long(h11P->red_mask);
-    h11P->green_mask       = bs_long(h11P->green_mask);
-    h11P->blue_mask        = bs_long(h11P->blue_mask);
+    h11P->grn_mask         = bs_long(h11P->grn_mask);
+    h11P->blu_mask         = bs_long(h11P->blu_mask);
     h11P->bits_per_rgb     = bs_long(h11P->bits_per_rgb);
     h11P->colormap_entries = bs_long(h11P->colormap_entries);
     h11P->ncolors          = bs_long(h11P->ncolors);
@@ -294,7 +313,7 @@
   for (i=0; i<h11P->header_size - sizeof(*h11P); i++)
     if (getc(file) == EOF)
       return(xwdError("couldn't read rest of X11 XWD file header"));
-      
+
   /* Check whether we can handle this dump. */
   if (h11P->pixmap_depth > 24)
     return(xwdError("can't handle X11 pixmap_depth > 24"));
@@ -303,27 +322,31 @@
     return(xwdError("can't handle X11 bits_per_rgb > 24"));
 
   if (h11P->pixmap_format != ZPixmap && h11P->pixmap_depth != 1)  {
-    sprintf(errstr, "can't handle X11 pixmap_format %d with depth != 1",
-	    h11P->pixmap_format);
+    sprintf(errstr, "can't handle X11 pixmap_format %ld with depth != 1",
+	    (long)h11P->pixmap_format);
     return(xwdError(errstr));
   }
 
   if (h11P->bitmap_unit != 8 && h11P->bitmap_unit != 16 &&
       h11P->bitmap_unit != 32)  {
-    sprintf(errstr, "X11 bitmap_unit (%d) is non-standard - can't handle",
-	    h11P->bitmap_unit);
+    sprintf(errstr, "X11 bitmap_unit (%ld) is non-standard - can't handle",
+	    (long)h11P->bitmap_unit);
     return(xwdError(errstr));
   }
-  
+
   grayscale = 1;
   if (h11P->ncolors > 0) {      /* Read X11 colormap. */
-    x11colors = (X11XColor*) malloc(h11P->ncolors * sizeof(X11XColor));
+    int bufsize = h11P->ncolors * sizeof(X11XColor);
+
+    if (bufsize/sizeof(X11XColor) != h11P->ncolors)
+      return(xwdError("too many colors"));
+    x11colors = (X11XColor*) malloc(bufsize);
     if (!x11colors) return(xwdError("out of memory"));
-    
-    if (h11P->header_size + h11P->ncolors * sizeof(X11XColor) 
+
+    if (h11P->header_size + bufsize
 	+ h11P->pixmap_height * h11P->bytes_per_line + h11P->ncolors * 4
 	== filesize ) word64 = 1;
-    
+
     if (word64) {
       for (i = 0; i < h11P->ncolors; ++i) {
 	if (fread(&pad, sizeof(pad), (size_t) 1, file ) != 1)
@@ -334,11 +357,11 @@
       }
     }
     else {
-      if (fread(x11colors, sizeof(X11XColor), (size_t) h11P->ncolors, file) 
+      if (fread(x11colors, sizeof(X11XColor), (size_t) h11P->ncolors, file)
 	  != h11P->ncolors)
 	return(xwdError("couldn't read X11 XWD colormap"));
     }
-    
+
     for (i = 0; i < h11P->ncolors; ++i) {
       if (byte_swap) {
 	x11colors[i].red   = (CARD16) bs_short(x11colors[i].red);
@@ -356,8 +379,11 @@
 	grayscale = 0;
     }
   }
-  
+
   *visualclassP = h11P->visual_class;
+  /* SJT: FIXME. If bits_per_pixel == 16, maxv could be either 31 or 63.
+     It doesn't matter, though, because maxv is never used beyond here.
+   */
   if (*visualclassP == TrueColor || *visualclassP == DirectColor) {
     if (h11P->bits_per_pixel == 16) maxv = 31;
     else maxv = 255;
@@ -389,24 +415,58 @@
       }
     }
   }
-      
+
   *colsP = h11P->pixmap_width;
   *rowsP = h11P->pixmap_height;
   *padrightP = h11P->bytes_per_line * 8 / h11P->bits_per_pixel -
     h11P->pixmap_width;
-  
+
   bits_per_item  = h11P->bitmap_unit;
-  bits_used      = bits_per_item;
   bits_per_pixel = h11P->bits_per_pixel;
   byte_order     = h11P->byte_order;
   bit_order      = h11P->bitmap_bit_order;
-  
+  bits_per_rgb   = h11P->bits_per_rgb;
+
+
+  /* add sanity-code for freako 'exceed' server, where bitmapunit = 8
+     and bitsperpix = 32 (and depth=24)... */
+
+  if (bits_per_item < bits_per_pixel) {
+    bits_per_item = bits_per_pixel;
+
+    /* round bits_per_item up to next legal value, if necc */
+    if      (bits_per_item <  8) bits_per_item = 8;
+    else if (bits_per_item < 16) bits_per_item = 16;
+    else                         bits_per_item = 32;
+  }
+
+
+  /* which raises the question:  how (can?) you ever have a 24 bits per pix,
+     (i.e., 3 bytes, no alpha/padding) */
+
+
+  bits_used      = bits_per_item;
+
   if (bits_per_pixel == sizeof(pixel_mask) * 8)  pixel_mask = (CARD32) -1;
   else pixel_mask = (1 << bits_per_pixel) - 1;
-  
+
   red_mask   = h11P->red_mask;
-  green_mask = h11P->green_mask;
-  blue_mask  = h11P->blue_mask;
+  green_mask = h11P->grn_mask;
+  blue_mask  = h11P->blu_mask;
+
+  red_shift = blue_shift = green_shift = 0;
+  while (!(red_mask & 1)) {
+    red_mask >>= 1;
+    ++red_shift;
+  }
+  while (!(blue_mask & 1)) {
+    blue_mask >>= 1;
+    ++blue_shift;
+  }
+  while (!(green_mask & 1)) {
+    green_mask >>= 1;
+    ++green_shift;
+  }
 
   byteP  = (char   *) buf;
   shortP = (CARD16 *) buf;
@@ -421,13 +481,13 @@
      FILE* file;
 {
   int n;
-  
+
   if (bits_used == bits_per_item) {
     switch (bits_per_item) {
     case 8:
       *byteP = getc(file);
       break;
-      
+
     case 16:
       if (byte_order == MSBFirst) {
 	if (readbigshort(file, shortP) == -1)
@@ -438,7 +498,7 @@
 	  xwdWarning("unexpected EOF");
       }
       break;
-      
+
     case 32:
       if (byte_order == MSBFirst) {
 	if (readbiglong(file, longP) == -1)
@@ -449,48 +509,48 @@
 	  xwdWarning("unexpected EOF");
       }
       break;
-      
+
     default:
       xwdWarning("can't happen");
     }
     bits_used = 0;
-    
+
     if (bit_order == MSBFirst)
       bit_shift = bits_per_item - bits_per_pixel;
     else
       bit_shift = 0;
   }
-  
+
   switch (bits_per_item) {
   case 8:
     n = (*byteP >> bit_shift) & pixel_mask;
     break;
-    
+
   case 16:
     n = (*shortP >> bit_shift) & pixel_mask;
     break;
-    
+
   case 32:
     n = (*longP >> bit_shift) & pixel_mask;
     break;
-    
+
   default:
     n = 0;
     xwdWarning("can't happen");
   }
-  
+
   if (bit_order == MSBFirst) bit_shift -= bits_per_pixel;
                         else bit_shift += bits_per_pixel;
 
   bits_used += bits_per_pixel;
-  
+
   return n;
 }
 
 
 /***************************/
 static int xwdError(st)
-     char *st;
+     const char *st;
 {
   if (pic8  != NULL) free(pic8);
   if (pic24 != NULL) free(pic24);
@@ -502,7 +562,7 @@
 
 /***************************/
 static void xwdWarning(st)
-     char *st;
+     const char *st;
 {
   SetISTR(ISTR_WARNING,"%s:  %s", bname, st);
 }
@@ -511,7 +571,7 @@
 
 
 
-/* 
+/*
  * Byte-swapping junk.
  */
 
@@ -537,7 +597,7 @@
 {
   union cheat u;
   unsigned char t;
-  
+
   u.l = l;
   t = u.c[0];  u.c[0] = u.c[3];  u.c[3] = t;
   t = u.c[1];  u.c[1] = u.c[2];  u.c[2] = t;
@@ -549,7 +609,7 @@
 
 
 
-/* 
+/*
  * Endian I/O.
  */
 
@@ -584,7 +644,7 @@
 {
   *sP  =  getc(in) & 0xff;
   *sP |= (getc(in) & 0xff) << 8;
-  
+
   if (ferror(in)) return -1;
   return 0;
 }
@@ -604,6 +664,7 @@
 }
 
 
+#if 0 /* NOTUSED */
 static int writebiglong(out, l)
      FILE* out;
      CARD32 l;
@@ -624,3 +685,4 @@
   putc(s&0xff, out);
   return 0;
 }
+#endif /* 0 (NOTUSED) */